cmake: implement build infrastructure for supporting SCA tools.
Static code analyser (SCA) tools are important in software development. CMake offers built-in support for some tools, such as cppcheck and clang-tidy. Other tools, such as sparse, are not directly supported. This commit provides a uniform way for users to specify a supported SCA using `ZEPHYR_SCA_VARIANT=<tool>` which is consistent with how toolchains are specified. ZEPHYR_SCA_VARIANT can be set using `-D` or in environment. Support for an SCA tool is done in `cmake/sca/<tool>/sca.cmake`. SCA_ROOT can be used to specify additional search paths when looking up implementation for a tool. SCA_ROOT can also be specified in `zephyr/module.yml` as setting. This makes it possible to provide SCA tool implementation as part of a Zephyr module. Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
This commit is contained in:
parent
ac9510230b
commit
cb690ec56e
31
cmake/modules/FindScaTools.cmake
Normal file
31
cmake/modules/FindScaTools.cmake
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022, Nordic Semiconductor ASA
|
||||||
|
|
||||||
|
# 'SCA_ROOT' is a prioritized list of directories where SCA tools may
|
||||||
|
# be found. It always includes ${ZEPHYR_BASE} at the lowest priority.
|
||||||
|
list(APPEND SCA_ROOT ${ZEPHYR_BASE})
|
||||||
|
|
||||||
|
zephyr_get(ZEPHYR_SCA_VARIANT)
|
||||||
|
|
||||||
|
if(ScaTools_FIND_REQUIRED AND NOT DEFINED ZEPHYR_SCA_VARIANT)
|
||||||
|
message(FATAL_ERROR "ScaTools required but 'ZEPHYR_SCA_VARIANT' is not set. "
|
||||||
|
"Please set 'ZEPHYR_SCA_VARIANT' to desired tool."
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT DEFINED ZEPHYR_SCA_VARIANT)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
foreach(root ${SCA_ROOT})
|
||||||
|
if(EXISTS ${root}/cmake/sca/${ZEPHYR_SCA_VARIANT}/sca.cmake)
|
||||||
|
include(${root}/cmake/sca/${ZEPHYR_SCA_VARIANT}/sca.cmake)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
message(FATAL_ERROR "ZEPHYR_SCA_VARIANT set to '${ZEPHYR_SCA_VARIANT}' but no "
|
||||||
|
"implementation for '${ZEPHYR_SCA_VARIANT}' found. "
|
||||||
|
"SCA_ROOTs searched: ${SCA_ROOT}"
|
||||||
|
)
|
|
@ -23,6 +23,7 @@
|
||||||
include_guard(GLOBAL)
|
include_guard(GLOBAL)
|
||||||
|
|
||||||
find_package(TargetTools)
|
find_package(TargetTools)
|
||||||
|
find_package(ScaTools)
|
||||||
|
|
||||||
# As this module is not intended for direct loading, but should be loaded through
|
# As this module is not intended for direct loading, but should be loaded through
|
||||||
# find_package(Zephyr) then it won't be loading any Zephyr CMake modules by itself.
|
# find_package(Zephyr) then it won't be loading any Zephyr CMake modules by itself.
|
||||||
|
|
|
@ -33,6 +33,9 @@ zephyr_file(APPLICATION_ROOT SOC_ROOT)
|
||||||
# Convert paths to absolute, relative from APPLICATION_SOURCE_DIR
|
# Convert paths to absolute, relative from APPLICATION_SOURCE_DIR
|
||||||
zephyr_file(APPLICATION_ROOT ARCH_ROOT)
|
zephyr_file(APPLICATION_ROOT ARCH_ROOT)
|
||||||
|
|
||||||
|
# Convert paths to absolute, relative from APPLICATION_SOURCE_DIR
|
||||||
|
zephyr_file(APPLICATION_ROOT SCA_ROOT)
|
||||||
|
|
||||||
if(unittest IN_LIST Zephyr_FIND_COMPONENTS)
|
if(unittest IN_LIST Zephyr_FIND_COMPONENTS)
|
||||||
# Zephyr used in unittest mode, use dedicated unittest root.
|
# Zephyr used in unittest mode, use dedicated unittest root.
|
||||||
set(BOARD_ROOT ${ZEPHYR_BASE}/subsys/testsuite)
|
set(BOARD_ROOT ${ZEPHYR_BASE}/subsys/testsuite)
|
||||||
|
|
|
@ -81,6 +81,9 @@ mapping:
|
||||||
module_ext_root:
|
module_ext_root:
|
||||||
required: false
|
required: false
|
||||||
type: str
|
type: str
|
||||||
|
sca_root:
|
||||||
|
required: false
|
||||||
|
type: str
|
||||||
tests:
|
tests:
|
||||||
required: false
|
required: false
|
||||||
type: seq
|
type: seq
|
||||||
|
@ -219,7 +222,7 @@ def process_settings(module, meta):
|
||||||
out_text = ""
|
out_text = ""
|
||||||
|
|
||||||
if build_settings is not None:
|
if build_settings is not None:
|
||||||
for root in ['board', 'dts', 'soc', 'arch', 'module_ext']:
|
for root in ['board', 'dts', 'soc', 'arch', 'module_ext', 'sca']:
|
||||||
setting = build_settings.get(root+'_root', None)
|
setting = build_settings.get(root+'_root', None)
|
||||||
if setting is not None:
|
if setting is not None:
|
||||||
root_path = PurePath(module) / setting
|
root_path = PurePath(module) / setting
|
||||||
|
|
Loading…
Reference in a new issue