diff --git a/cmake/sca/codechecker/sca.cmake b/cmake/sca/codechecker/sca.cmake new file mode 100644 index 00000000000..8607e136391 --- /dev/null +++ b/cmake/sca/codechecker/sca.cmake @@ -0,0 +1,73 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Copyright (c) 2023, Basalte bv + +find_program(CODECHECKER_EXE CodeChecker REQUIRED) +message(STATUS "Found CodeChecker: ${CODECHECKER_EXE}") + +# CodeChecker uses the compile_commands.json as input +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Create an output directory for our tool +set(output_dir ${CMAKE_BINARY_DIR}/sca/codechecker) +file(MAKE_DIRECTORY ${output_dir}) + +# Use a dummy file to let CodeChecker know we can start analyzing +set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND + ${CMAKE_COMMAND} -E touch ${output_dir}/codechecker.ready) +set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts + ${output_dir}/codechecker.ready) + +add_custom_target(codechecker ALL + COMMAND ${CODECHECKER_EXE} analyze + --keep-gcc-include-fixed + --keep-gcc-intrin + --output ${output_dir}/codechecker.plist + ${CODECHECKER_ANALYZE_OPTS} + ${CMAKE_BINARY_DIR}/compile_commands.json + DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json ${output_dir}/codechecker.ready + BYPRODUCTS ${output_dir}/codechecker.plist + VERBATIM + USES_TERMINAL + COMMAND_EXPAND_LISTS +) + +# Cleanup dummy file +add_custom_command( + TARGET codechecker POST_BUILD + COMMAND ${CMAKE_COMMAND} -E rm ${output_dir}/codechecker.ready +) + +if(CODECHECKER_EXPORT) + string(REPLACE "," ";" export_list ${CODECHECKER_EXPORT}) + + foreach(export_item IN LISTS export_list) + message(STATUS "CodeChecker export: ${CMAKE_BINARY_DIR}/codechecker.${export_item}") + + add_custom_command( + TARGET codechecker POST_BUILD + COMMAND ${CODECHECKER_EXE} parse + ${output_dir}/codechecker.plist + --export ${export_item} + --output ${output_dir}/codechecker.${export_item} + ${CODECHECKER_PARSE_OPTS} + || ${CMAKE_COMMAND} -E true # parse has exit code 2 if a report is emitted by an analyzer + BYPRODUCTS ${output_dir}/codechecker.${export_item} + VERBATIM + USES_TERMINAL + COMMAND_EXPAND_LISTS + ) + endforeach() +else() + # Output parse results + add_custom_command( + TARGET codechecker POST_BUILD + COMMAND ${CODECHECKER_EXE} parse + ${output_dir}/codechecker.plist + ${CODECHECKER_PARSE_OPTS} + || ${CMAKE_COMMAND} -E true # parse has exit code 2 if a report is emitted by an analyzer + VERBATIM + USES_TERMINAL + COMMAND_EXPAND_LISTS + ) +endif() diff --git a/doc/develop/sca/codechecker.rst b/doc/develop/sca/codechecker.rst new file mode 100644 index 00000000000..79c6854d505 --- /dev/null +++ b/doc/develop/sca/codechecker.rst @@ -0,0 +1,58 @@ +.. _codechecker: + +CodeChecker support +################### + +`CodeChecker `__ is a static analysis infrastructure. +It executes analysis tools available on the build system, such as +`Clang-Tidy `__, +`Clang Static Analyzer `__ and +`Cppcheck `__. Refer to the analyzer's websites for installation +instructions. + +Installing CodeChecker +********************** + +CodeChecker itself is a python package available on `pypi `__. + +.. code-block:: shell + + pip install codechecker + +Running with CodeChecker +************************ + +To run CodeChecker, :ref:`west build ` should be +called with a ``-DZEPHYR_SCA_VARIANT=codechecker`` parameter, e.g. + +.. code-block:: shell + + west build -b mimxrt1064_evk -s samples/basic/blinky -- -DZEPHYR_SCA_VARIANT=codechecker + + +Configuring CodeChecker +*********************** + +To configure CodeChecker or analyzers used, arguments can be passed using the +``CODECHECKER_ANALYZE_OPTS`` parameter, e.g. + +.. code-block:: shell + + west build -b mimxrt1064_evk -s samples/basic/blinky -- -DZEPHYR_SCA_VARIANT=codechecker \ + -DCODECHECKER_ANALYZE_OPTS="--config;$CODECHECKER_CONFIG_FILE;--timeout;60" + + +Exporting CodeChecker reports +***************************** + +Optional reports can be generated using the CodeChecker results, when passing a +``-DCODECHECKER_EXPORT=`` parameter. Allowed types are: ``html,json,codeclimate,gerrit,baseline``. +Multiple types can be passed as comma-separated arguments. + +Optional parser configuration arguments can be passed using the +``CODECHECKER_PARSE_OPTS`` parameter, e.g. + +.. code-block:: shell + + west build -b mimxrt1064_evk -s samples/basic/blinky -- -DZEPHYR_SCA_VARIANT=codechecker \ + -DCODECHECKER_EXPORT=html,json -DCODECHECKER_PARSE_OPTS="--trim-path-prefix;$PWD" diff --git a/doc/develop/sca/index.rst b/doc/develop/sca/index.rst index c71e754674b..08b9d96a0cc 100644 --- a/doc/develop/sca/index.rst +++ b/doc/develop/sca/index.rst @@ -61,4 +61,5 @@ The following is a list of SCA tools natively supported by Zephyr build system. .. toctree:: :maxdepth: 1 + codechecker sparse