6.8 KiB
category, type, hastr, layout, tags, title, short
| category | type | hastr | layout | tags | title | short |
|---|---|---|---|---|---|---|
| en | paper | true | paper | development, c++, cmake | Add cppcheck and clang-format for a cmake project | cppcheck-and-clang-format |
A small How-To which describes how to add automatic code style checking and
static analyser to a project on C++ which uses cmake as a build system.
Project
The project has the following structure:
sources/
|- CMakeLists.txt
|- 3rdparty/
|- first_component/
|- second_component/
3rdparty is a directory which contains additional libraries and which should
be excluded from checking (PROJECT_TRDPARTY_DIR cmake variable is used to
indicate path to this directory). Also let's assume that we have additional
files (e.g. *.qml) in addition to common source files (*.cpp, *.h).
In addition the described below commands may be inserted to pre-commit hook; it
allows us to troll colleagues which will be able to commit nothing till they
read CONTRIBUTING.md.
cppcheck
As far as there are no good (out-of-box) static analysers in open source we will
use it. Knowledgeable people say that cppcheck in case of good configuration it is better than the any
alternative, but its configuration is the same that the new project creation.
cppcheck shows obvious errors and recommend to fix them.
Example of run
Here it is:
cppcheck --enable=warning,performance,portability,information,missingInclude
--std=c++11 --library=qt.cfg --template="[{severity}][{id}] {message}
{callstack} (On {file}:{line})" --verbose --quiet
path/to/source/files/or/directory
--enablesays which notifications should be enabled. I've disabledstyle(we will useclang-formatto do it),unusedFunctionwhich shows false-positive for some methods.--stdsays which standard should be used.--library=qt.cfga configuration file, which describes how to check files. The developers recommend to read the following manual. I've used the ready template from/usr/share/cppcheck/cfg/.--templateis notification template.---verbose --quietare two "conflicting" options. The first one enables more verbose messages, the second one disables progress reports.
cmake integration
cppcheck.cmake file in the project root:
# additional target to perform cppcheck run, requires cppcheck
# get all project files
# HACK this workaround is required to avoid qml files checking ^_^
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h)
foreach (SOURCE_FILE ${ALL_SOURCE_FILES})
string(FIND ${SOURCE_FILE} ${PROJECT_TRDPARTY_DIR} PROJECT_TRDPARTY_DIR_FOUND)
if (NOT ${PROJECT_TRDPARTY_DIR_FOUND} EQUAL -1)
list(REMOVE_ITEM ALL_SOURCE_FILES ${SOURCE_FILE})
endif ()
endforeach ()
add_custom_target(
cppcheck
COMMAND /usr/bin/cppcheck
--enable=warning,performance,portability,information,missingInclude
--std=c++11
--library=qt.cfg
--template="[{severity}][{id}] {message} {callstack} \(On {file}:{line}\)"
--verbose
--quiet
${ALL_SOURCE_FILES}
)
cppcheck may work with directories recursive, but I need to skip qml-files
checking in my example, because this cppcheck will segfault on some of them.
To do it source files search is used followed by the ejection of unnecessary
files.
Include to the project (CMakeLists.txt)...
include(cppcheck.cmake)
...and run:
cmake
make cppcheck
Then edit files to avoid warnings in the future.
Adds
- You may add own directories to includes search, using
-I diroption - You may drop files and/or directories from checking by using
-i path/to/file/or/directoryoption.
clang-format
clang-format is used to automatic code style checking and correction. astyle, which has a very modest capabilities, and uncrustify, which on the contrary has too many options, should be mentioned from analogues.
Example of run
clang-format -i -style=LLVM /path/to/source/files
(Unfortunately it could not work with directories recursive.)
-ienables files auto replace (otherwise the result will be printed to stdout).-styleis a style preset selection or from file (file), see below.
cmake integration
clang-format.cmake file in the project root:
# additional target to perform clang-format run, requires clang-format
# get all project files
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h)
foreach (SOURCE_FILE ${ALL_SOURCE_FILES})
string(FIND ${SOURCE_FILE} ${PROJECT_TRDPARTY_DIR} PROJECT_TRDPARTY_DIR_FOUND)
if (NOT ${PROJECT_TRDPARTY_DIR_FOUND} EQUAL -1)
list(REMOVE_ITEM ALL_SOURCE_FILES ${SOURCE_FILE})
endif ()
endforeach ()
add_custom_target(
clangformat
COMMAND /usr/bin/clang-format
-style=LLVM
-i
${ALL_SOURCE_FILES}
)
There is the same method to get source files list as for cppcheck, because
clang-format doesn't support recursive directory search.
Include to the project (CMakeLists.txt)...
include(clang-format.cmake)
...and run:
cmake
make clangformat
No other actions required.
Adds
-
Configuration. You may see all options on the official site. Also you may use interactive tool to search for required options. To use the preset for your style use the following command:
clang-format -style=LLVM -dump-config > .clang-formatThen edit generated file
.clang-format. To enable it you need set-style=fileoption, file should be placed to the any parent directory of each source file (e.g., to the project root). Also you may send required options to the command line directly, e.g.-style="{BasedOnStyle: llvm, IndentWidth: 8}"