17 Oct 2015
Tags: development,c++,cmake
Related posts:
FFXIV Astrologian guide
How to upload screenshots to S3 from linux
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.
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
.
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.
Here it is:
cppcheck --enable=warning,performance,portability,information,missingInclude \
--std=c++11 --library=qt.cfg --verbose --quiet \
--template="[{severity}][{id}] {message} {callstack} (On {file}:{line})" \
path/to/source/files/or/directory
--enable
says which notifications should be enabled. I’ve disabled style
(we will use clang-format
to do it), unusedFunction
which shows
false-positive for some methods.--std
says which standard should be used.--library=qt.cfg
a 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/
.--template
is notification template.---verbose --quiet
are two “conflicting” options. The first one enables more
verbose messages, the second one disables progress reports.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.
-I dir
option-i
path/to/file/or/directory
option.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.
clang-format -i -style=LLVM /path/to/source/files
(Unfortunately it could not work with directories recursive.)
-i
enables files auto replace (otherwise the result will be printed to
stdout).-style
is a style preset selection or from file (file
), see below.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.
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-format
Then edit generated file .clang-format
. To enable it you need set
-style=file
option, 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}"