|  | # SPDX-License-Identifier: Apache-2.0 | 
|  | # | 
|  | # Copyright (c) 2023, Basalte bv | 
|  |  | 
|  | include(boards) | 
|  | include(git) | 
|  | include(extensions) | 
|  | include(west) | 
|  |  | 
|  | find_program(CODECHECKER_EXE NAMES CodeChecker codechecker REQUIRED) | 
|  | message(STATUS "Found SCA: CodeChecker (${CODECHECKER_EXE})") | 
|  |  | 
|  | # Get CodeChecker specific variables | 
|  | zephyr_get(CODECHECKER_ANALYZE_JOBS) | 
|  | zephyr_get(CODECHECKER_ANALYZE_OPTS) | 
|  | zephyr_get(CODECHECKER_CLEANUP) | 
|  | zephyr_get(CODECHECKER_CONFIG_FILE) | 
|  | zephyr_get(CODECHECKER_EXPORT) | 
|  | zephyr_get(CODECHECKER_NAME) | 
|  | zephyr_get(CODECHECKER_PARSE_EXIT_STATUS) | 
|  | zephyr_get(CODECHECKER_PARSE_OPTS) | 
|  | zephyr_get(CODECHECKER_PARSE_SKIP) | 
|  | zephyr_get(CODECHECKER_STORE) | 
|  | zephyr_get(CODECHECKER_STORE_OPTS) | 
|  | zephyr_get(CODECHECKER_STORE_TAG) | 
|  | zephyr_get(CODECHECKER_TRIM_PATH_PREFIX MERGE VAR CODECHECKER_TRIM_PATH_PREFIX WEST_TOPDIR) | 
|  |  | 
|  | # Get twister runner specific variables | 
|  | zephyr_get(TC_RUNID) | 
|  | zephyr_get(TC_NAME) | 
|  |  | 
|  | if(NOT CODECHECKER_NAME) | 
|  | if(TC_NAME) | 
|  | set(CODECHECKER_NAME "${BOARD}${BOARD_QUALIFIERS}:${TC_NAME}") | 
|  | else() | 
|  | set(CODECHECKER_NAME zephyr) | 
|  | endif() | 
|  | endif() | 
|  |  | 
|  | if(CODECHECKER_ANALYZE_JOBS) | 
|  | set(CODECHECKER_ANALYZE_JOBS "--jobs;${CODECHECKER_ANALYZE_JOBS}") | 
|  | elseif(TC_RUNID) | 
|  | set(CODECHECKER_ANALYZE_JOBS "--jobs;1") | 
|  | endif() | 
|  |  | 
|  | if(CODECHECKER_CONFIG_FILE) | 
|  | set(CODECHECKER_CONFIG_FILE "--config;${CODECHECKER_CONFIG_FILE}") | 
|  | endif() | 
|  |  | 
|  | if(CODECHECKER_STORE_TAG) | 
|  | set(CODECHECKER_STORE_TAG "--tag;${CODECHECKER_STORE_TAG}") | 
|  | else() | 
|  | git_describe(${APPLICATION_SOURCE_DIR} app_version) | 
|  | if(app_version) | 
|  | set(CODECHECKER_STORE_TAG "--tag;${app_version}") | 
|  | endif() | 
|  | endif() | 
|  |  | 
|  | if(CODECHECKER_TRIM_PATH_PREFIX) | 
|  | set(CODECHECKER_TRIM_PATH_PREFIX "--trim-path-prefix;${CODECHECKER_TRIM_PATH_PREFIX}") | 
|  | endif() | 
|  |  | 
|  | # 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 | 
|  | --name ${CODECHECKER_NAME} # Set a default metadata name | 
|  | ${CODECHECKER_CONFIG_FILE} | 
|  | ${CODECHECKER_ANALYZE_JOBS} | 
|  | ${CODECHECKER_ANALYZE_OPTS} | 
|  | ${CMAKE_BINARY_DIR}/compile_commands.json | 
|  | || ${CMAKE_COMMAND} -E true # allow to continue processing results | 
|  | DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json ${output_dir}/codechecker.ready | 
|  | 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_CLEANUP) | 
|  | add_custom_target(codechecker-cleanup ALL | 
|  | COMMAND ${CMAKE_COMMAND} -E rm -r ${output_dir}/codechecker.plist | 
|  | ) | 
|  | else() | 
|  | add_custom_target(codechecker-cleanup) | 
|  | endif() | 
|  |  | 
|  | add_dependencies(codechecker-cleanup codechecker) | 
|  |  | 
|  | # If 'codechecker parse' returns an exit status of '2', it means more than 0 | 
|  | # issues were detected. Suppress the exit status by default, but permit opting | 
|  | # in to the failure. | 
|  | if(NOT CODECHECKER_PARSE_EXIT_STATUS) | 
|  | set(CODECHECKER_PARSE_OPTS ${CODECHECKER_PARSE_OPTS} || ${CMAKE_COMMAND} -E true) | 
|  | endif() | 
|  |  | 
|  | if(DEFINED 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_target(codechecker-report-${export_item} ALL | 
|  | COMMAND ${CODECHECKER_EXE} parse | 
|  | ${output_dir}/codechecker.plist | 
|  | --export ${export_item} | 
|  | --output ${output_dir}/codechecker.${export_item} | 
|  | ${CODECHECKER_CONFIG_FILE} | 
|  | ${CODECHECKER_TRIM_PATH_PREFIX} | 
|  | ${CODECHECKER_PARSE_OPTS} | 
|  | BYPRODUCTS ${output_dir}/codechecker.${export_item} | 
|  | VERBATIM | 
|  | USES_TERMINAL | 
|  | COMMAND_EXPAND_LISTS | 
|  | ) | 
|  | add_dependencies(codechecker-report-${export_item} codechecker) | 
|  | add_dependencies(codechecker-cleanup codechecker-report-${export_item}) | 
|  | endforeach() | 
|  | elseif(NOT CODECHECKER_PARSE_SKIP) | 
|  | # Output parse results | 
|  | add_custom_target(codechecker-parse ALL | 
|  | COMMAND ${CODECHECKER_EXE} parse | 
|  | ${output_dir}/codechecker.plist | 
|  | ${CODECHECKER_CONFIG_FILE} | 
|  | ${CODECHECKER_TRIM_PATH_PREFIX} | 
|  | ${CODECHECKER_PARSE_OPTS} | 
|  | VERBATIM | 
|  | USES_TERMINAL | 
|  | COMMAND_EXPAND_LISTS | 
|  | ) | 
|  | add_dependencies(codechecker-parse codechecker) | 
|  | add_dependencies(codechecker-cleanup codechecker-parse) | 
|  | endif() | 
|  |  | 
|  | if(DEFINED CODECHECKER_STORE OR DEFINED CODECHECKER_STORE_OPTS) | 
|  | add_custom_target(codechecker-store ALL | 
|  | COMMAND ${CODECHECKER_EXE} store | 
|  | ${CODECHECKER_CONFIG_FILE} | 
|  | ${CODECHECKER_STORE_TAG} | 
|  | ${CODECHECKER_TRIM_PATH_PREFIX} | 
|  | ${CODECHECKER_STORE_OPTS} | 
|  | ${output_dir}/codechecker.plist | 
|  | VERBATIM | 
|  | USES_TERMINAL | 
|  | COMMAND_EXPAND_LISTS | 
|  | ) | 
|  | add_dependencies(codechecker-store codechecker) | 
|  | add_dependencies(codechecker-cleanup codechecker-store) | 
|  | endif() |