Skip to content

Commit 219fae6

Browse files
AlexFabrenashif
authored andcommitted
sca: llvm: add support for clang static analyzer
This commit brings a convenient way to run clang static analyzer on a project with 'analyze-build' llvm utility. Signed-off-by: Alex Fabre <alex.fabre@rtone.fr>
1 parent 7e00170 commit 219fae6

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed

cmake/sca/clang/sca.cmake

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
#
3+
# Copyright (c) 2025 Alex Fabre
4+
5+
find_program(CLANG_SCA_EXE NAMES analyze-build REQUIRED)
6+
message(STATUS "Found SCA: clang static analyzer (${CLANG_SCA_EXE})")
7+
8+
# Get clang analyzer user options
9+
zephyr_get(CLANG_SCA_OPTS)
10+
zephyr_get(LLVM_TOOLCHAIN_PATH)
11+
12+
# Check analyzer extra options
13+
if(DEFINED CLANG_SCA_OPTS)
14+
foreach(analyzer_option IN LISTS CLANG_SCA_OPTS)
15+
list(APPEND CLANG_SCA_EXTRA_OPTS ${analyzer_option})
16+
endforeach()
17+
endif()
18+
19+
# clang analyzer uses the compile_commands.json as input
20+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
21+
22+
# Create an output directory for clang analyzer results
23+
set(output_dir ${CMAKE_BINARY_DIR}/sca/clang)
24+
file(MAKE_DIRECTORY ${output_dir})
25+
26+
# Use a dummy file to let clang static analyzer know we can start analyzing
27+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
28+
${CMAKE_COMMAND} -E touch ${output_dir}/clang-sca.ready)
29+
set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts
30+
${output_dir}/clang-sca.ready)
31+
32+
# Add a cmake target to run the analyzer after the build is done
33+
add_custom_target(clang-sca ALL
34+
COMMAND ${CLANG_SCA_EXE} --cdb ${CMAKE_BINARY_DIR}/compile_commands.json -o ${CMAKE_BINARY_DIR}/sca/clang/ --analyze-headers --use-analyzer ${LLVM_TOOLCHAIN_PATH}/bin/clang ${CLANG_SCA_EXTRA_OPTS}
35+
DEPENDS ${CMAKE_BINARY_DIR}/compile_commands.json ${output_dir}/clang-sca.ready
36+
)
37+
38+
# Cleanup dummy file
39+
add_custom_command(
40+
TARGET clang-sca POST_BUILD
41+
COMMAND ${CMAKE_COMMAND} -E rm ${output_dir}/clang-sca.ready
42+
)

doc/develop/sca/clang.rst

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
.. _clang:
2+
3+
Clang static analyzer support
4+
#############################
5+
6+
Clang Static Analyzer is built on top of Clang and LLVM.
7+
Strictly speaking, the analyzer is part of Clang, as Clang
8+
consists of a set of reusable C++ libraries for building
9+
powerful source-level tools. The static analysis engine used by the
10+
Clang Static Analyzer is a Clang library, and has the capability to
11+
be reused in different contexts and by different clients.
12+
13+
LLVM provides various methods to run the analyzer on a codebase,
14+
through either a dedicated set of tools (scan-build and analyze-build),
15+
or via command line arguments when running clang ('--analyze').
16+
17+
- 'scan-build' utility comes as the most convenient way for projects
18+
using a simple $CC makefile variables, as it will wraps and replace
19+
the compiler calls to perform it's analysis.
20+
21+
- 'analyze-build' utility is a sub-tool from 'scan-build', it only
22+
relies on a 'compile_commands.json' database to perform the analysis.
23+
24+
- clang option '--analyze' will run the analyzer alongside the build, but
25+
objects files are not generated, making any link stage impossible. In
26+
our case the first link stage will fail and stop the analysis.
27+
28+
Because of it's complexe build infrastructure, invoking clang analyzer with
29+
'analyze-build' is the most simple way to analyze a Zephyr project.
30+
31+
`Clang static analyzer documentation <https://clang.llvm.org/docs/ClangStaticAnalyzer.html>`__
32+
33+
Installing clang analyzer
34+
*************************
35+
36+
'scan-build' and its sub-tool 'analyze-build' come natively with llvm as part of the binaries.
37+
Make sure to have the binary directory accessible into your PATH.
38+
39+
'scan-build' is also available as a standalone python package available on `pypi <https://pypi.org/project/scan-build/>`__.
40+
41+
.. code-block:: shell
42+
43+
pip install scan-build
44+
45+
Run clang static analyzer
46+
*************************
47+
48+
.. note::
49+
50+
The analyser requires that the project builds with a LLVM toolchain, and
51+
produces a 'compile_commands.json' database.
52+
53+
To run clang static analyzer, :ref:`west build <west-building>` should be
54+
called with a ``-DZEPHYR_SCA_VARIANT=clang`` parameter, alongside the llvm
55+
toolchain parameters, e.g.
56+
57+
.. zephyr-app-commands::
58+
:zephyr-app: samples/userspace/hello_world_user
59+
:board: qemu_x86
60+
:gen-args: -DZEPHYR_TOOLCHAIN_VARIANT=llvm -DLLVM_TOOLCHAIN_PATH=... -DZEPHYR_SCA_VARIANT=clang
61+
:goals: build
62+
:compact:
63+
64+
.. note::
65+
66+
By default, clang static analyzer produces a html report, but various other
67+
outputs can be selected with options (sarif, plist, html)
68+
69+
Configuring clang static analyzer
70+
*********************************
71+
72+
Clang static analyzer can be controlled using specific options.
73+
To get an exaustive list of available options, report to the
74+
'analyze-build' helper and 'scan-build' helper.
75+
76+
.. code-block:: shell
77+
78+
analyze-build --help
79+
80+
Options already activated by default:
81+
82+
* --analyze-headers : Also analyze functions in #included files.
83+
84+
.. list-table::
85+
:header-rows: 1
86+
87+
* - Parameter
88+
- Description
89+
* - ``CLANG_SCA_OPTS``
90+
- A semicolon separated list of 'analyze-build' options.
91+
92+
These parameters can be passed on the command line, or be set as environment variables.
93+
94+
.. zephyr-app-commands::
95+
:zephyr-app: samples/hello_world
96+
:board: stm32h573i_dk
97+
:gen-args: -DZEPHYR_TOOLCHAIN_VARIANT=llvm -DLLVM_TOOLCHAIN_PATH=... -DZEPHYR_SCA_VARIANT=clang -DCLANG_SCA_OPTS="--sarif;--verbose"
98+
:goals: build
99+
:compact:

doc/develop/sca/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ The following is a list of SCA tools natively supported by Zephyr build system.
6464
codechecker
6565
sparse
6666
gcc
67+
clang
6768
cpptest
6869
eclair
6970
polyspace

0 commit comments

Comments
 (0)