mirror of
https://github.com/ttroy50/cmake-examples.git
synced 2025-12-18 20:24:35 +03:00
196 lines
6.2 KiB
Plaintext
196 lines
6.2 KiB
Plaintext
= CppCheck Static Analysis using Compile Commands
|
|
:toc:
|
|
:toc-placement!:
|
|
|
|
toc::[]
|
|
|
|
# Introduction
|
|
|
|
This example shows how to call the
|
|
http://cppcheck.sourceforge.net/[CppCheck] tool to do static analysis.
|
|
This shows how to use projects and a compile database.
|
|
Projects are available from cppcheck v1.77
|
|
|
|
It includes code to
|
|
|
|
* Find the cppcheck binary
|
|
* Generate an overall `make cppcheck-analysis` target to do static
|
|
analysis on all sub-projects.
|
|
|
|
The files included in this example are:
|
|
|
|
```
|
|
$ tree
|
|
.
|
|
├── cmake
|
|
│ └── modules
|
|
│ └── FindCppCheck.cmake
|
|
├── CMakeLists.txt
|
|
├── subproject1
|
|
│ ├── CMakeLists.txt
|
|
│ └── main1.cpp
|
|
└── subproject2
|
|
├── CMakeLists.txt
|
|
└── main2.cpp
|
|
```
|
|
|
|
* link:CMakeLists.txt[] - Top level CMakeLists.txt
|
|
* link:cmake/modules/FindCppCheck.cmake[] - A custom package module to find CppCheck
|
|
* link:subproject1/CMakeLists.txt[] - CMake commands for subproject 1
|
|
* link:subproject1/main1.cpp[] - source for a subproject with no errors
|
|
* link:subproject2/CMakeLists.txt[] - CMake commands for subproject 2
|
|
* link:subproject2/main2.cpp[] - source for a subproject that includes errors
|
|
|
|
# Requirements
|
|
|
|
To run this example you must have CppCheck of at least v1.77 installed. This is not
|
|
available by default on Ubuntu but can be compiled using the following command.
|
|
|
|
[source,bash]
|
|
----
|
|
$ wget https://github.com/danmar/cppcheck/archive/1.79.tar.gz \
|
|
&& tar xvf 1.79.tar.gz \
|
|
&& cd cppcheck-1.79 \
|
|
&& mkdir build \
|
|
&& cd build \
|
|
&& cmake .. \
|
|
&& sudo make install
|
|
----
|
|
|
|
# Concepts
|
|
|
|
## Adding Custom Package Modules
|
|
|
|
As with the previous example I use a custom module to find CppCheck. This version is slightly different to the previous one and
|
|
will automatically add a `make cppcheck-analysis` target.
|
|
|
|
[source,cmake]
|
|
----
|
|
if(CPPCHECK_FOUND)
|
|
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/analysis/cppcheck)
|
|
add_custom_target(cppcheck-analysis
|
|
COMMAND ${CPPCHECK_COMMAND})
|
|
message("cppcheck found. Use cppccheck-analysis targets to run it")
|
|
else()
|
|
message("cppcheck not found. No cppccheck-analysis targets")
|
|
endif()
|
|
----
|
|
|
|
The variables available have also changed. For full details on the commands see the `FindCppCheck.cmake` module. Below are a subset of the available options:
|
|
|
|
### Suppressions
|
|
|
|
Adding a suppression file called `.cppcheck-suppressions` which must be in your +CMAKE_SOURCE_DIR+
|
|
|
|
### Error Exitcode
|
|
|
|
When cppcheck finds an error it can cause it to exit with a specific error. In this
|
|
example, by default, it will exit with `1`. To change this you can set the
|
|
+CPPCHECK_ERROR_EXITCODE_ARG+ argument when running CMake.
|
|
|
|
### Exitcode suppressions
|
|
|
|
Sometimes you wish to display an error in the log, but to not have that error cause a failed build. To do this you can create a file `.cppcheck_exitcode_suppressions` and add suppressions to it. This file must be in your +CMAKE_SOURCE_DIR+
|
|
|
|
### CppCheck arguments
|
|
|
|
The default enabled checks are `--enabled=warning`. To change this you can override the `CPPCHECK_CHECK_ARGS` variable before calling `find(cppcheck)`.
|
|
|
|
### Excluding files / folders
|
|
|
|
Many projects include some vendored 3rd party code. To exclude this from you check you can create a list `CPPCHECK_EXCLUDES` before calling the find module. This will add all files and folders in the list into the list of excluded folders.
|
|
|
|
### CppCheck build dir
|
|
|
|
In this example, we set +CPPCHECK_BUILD_DIR_ARG+, to `${PROJECT_BINARY_DIR}/analysis/cppcheck`. This will output details of the build to this folder and can be used to
|
|
increase the speed of rechecks if a file hasn't changed
|
|
|
|
## Compile Database
|
|
|
|
CMake allows you to export all https://cmake.org/cmake/help/v3.5/variable/CMAKE_EXPORT_COMPILE_COMMANDS.html[compile commands]
|
|
that are used to build the project into a file called `compile_commands.json`
|
|
|
|
This can be done by setting the +CMAKE_EXPORT_COMPILE_COMMANDS+ variable to +ON+
|
|
as below:
|
|
|
|
[source,cmake]
|
|
----
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
----
|
|
|
|
The JSON file will look like:
|
|
|
|
[source,json]
|
|
----
|
|
[
|
|
{
|
|
"directory": "/home/user/development/project",
|
|
"command": "/usr/bin/c++ ... -c ../foo/foo.cc",
|
|
"file": "../foo/foo.cc"
|
|
},
|
|
|
|
...
|
|
|
|
{
|
|
"directory": "/home/user/development/project",
|
|
"command": "/usr/bin/c++ ... -c ../foo/bar.cc",
|
|
"file": "../foo/bar.cc"
|
|
}
|
|
]
|
|
----
|
|
|
|
[NOTE]
|
|
====
|
|
This is only available for the `Makefile` and `ninja` generators.
|
|
====
|
|
|
|
## CppCheck Projects
|
|
|
|
Starting with CppCheck v1.77, you can pass the `--project` flag pointing to the
|
|
compile database. This will cause CppCheck to run on al your cpp files using the same
|
|
include directories and compiler flags as your normal build.
|
|
|
|
[source,bash]
|
|
----
|
|
cppcheck --project=compile_comands.json
|
|
----
|
|
|
|
This will check all files in your project and sub-projects. There will be no analysis target per sub-project as with our previous example.
|
|
|
|
# Building the example
|
|
|
|
[source,bash]
|
|
----
|
|
$ mkdir build
|
|
|
|
$ cd build/
|
|
|
|
$ cmake ..
|
|
-- The C compiler identification is GNU 4.8.4
|
|
-- The CXX compiler identification is GNU 4.8.4
|
|
-- Check for working C compiler: /usr/bin/cc
|
|
-- Check for working C compiler: /usr/bin/cc -- works
|
|
-- Detecting C compiler ABI info
|
|
-- Detecting C compiler ABI info - done
|
|
-- Detecting C compile features
|
|
-- Detecting C compile features - done
|
|
-- Check for working CXX compiler: /usr/bin/c++
|
|
-- Check for working CXX compiler: /usr/bin/c++ -- works
|
|
-- Detecting CXX compiler ABI info
|
|
-- Detecting CXX compiler ABI info - done
|
|
-- Detecting CXX compile features
|
|
-- Detecting CXX compile features - done
|
|
-- Found CPPCHECK: /usr/local/bin/cppcheck
|
|
cppcheck found. Use cppccheck-analysis targets to run it
|
|
-- Configuring done
|
|
-- Generating done
|
|
-- Build files have been written to: /data/code/04-static-analysis/cppcheck-compile-commands/build
|
|
|
|
$ make cppcheck-analysis
|
|
Scanning dependencies of target cppcheck-analysis
|
|
[/data/code/04-static-analysis/cppcheck-compile-commands/subproject2/main2.cpp:7]: (error) Array 'tmp[10]' accessed at index 11, which is out of bounds.
|
|
make[3]: *** [CMakeFiles/cppcheck-analysis] Error 1
|
|
make[2]: *** [CMakeFiles/cppcheck-analysis.dir/all] Error 2
|
|
make[1]: *** [CMakeFiles/cppcheck-analysis.dir/rule] Error 2
|
|
make: *** [cppcheck-analysis] Error 2
|