CodeTools
Introduction
A couple of 'clang' tools are now available for the standardisation of code style and to sniff out bug-prone behaviour: clang-format and clang-tidy.
To use these tools on SLF7, please set them up like this:
setup mu2e # Or: source /cvmfs/fermilab.opensciencegrid.org/products/common/etc/setups setup clang v14_0_6c
clang and its tools can be installed on many systems:
# Debian, Ubuntu sudo apt-get install clang-format clang-tidy # MacOS (Homebrew) brew install clang-format # smaller package, just clang-format # or: # includes clang-format and clang-tidy - but takes up a lot more space brew install llvm ln -s "$(brew --prefix llvm)/bin/clang-format" "/usr/local/bin/clang-format" ln -s "$(brew --prefix llvm)/bin/clang-tidy" "/usr/local/bin/clang-tidy" # Arch Linux sudo pacman -S clang # Fedora sudo dnf install clang
clang-format
Clang-format re-formats code according to a configuration file. Having a consistent code style and format yields numerous benefits:
- Consistent formatting between revisions means cleaner diffs
- Consistently formatted code is on the whole easier to read
- Whitespace problems are ironed out (e.g. no trailing whitespace)
Basic Usage
To re-format a file in place:
clang-format -i <file(s)>
Glob patterns are also supported e.g. Analyses/src/*.cc
To see what it changed:
git diff
Setting up the entire clang product may introduce conflicts in the libraries used in gcc in the same process. To avoid setting the product, format can be used standalone:
alias format=/cvmfs/mu2e.opensciencegrid.org/artexternals/clang/v5_0_1/Linux64bit+3.10-2.17/bin/clang-format
IDE Integration
Clang-format is widely supported (see also Editors):
emacs
Here is one way to incorporate format in emacs without setting up clang, which may introduce conflicts with gcc.
(add-to-list 'exec-path "/cvmfs/mu2e.opensciencegrid.org/artexternals/clang/v5_0_1/Linux64bit+3.10-2.17/bin") (load "/cvmfs/mu2e.opensciencegrid.org/artexternals/clang/v5_0_1/Linux64bit+3.10-2.17/share/clang/clang-format.el") (global-set-key "\C-\M-f" 'clang-format-buffer )
XCode
Xcode: You can create a 'Text Service' and run clang-format from the shell script. See [4]
# Shell script for Xcode/apple 'Text Service' # Input (is entire selection +) receives all selected text # Select: output replaces selected text # You can select text in Xcode and run this 'Text Service' to format the selected text and replace it with formatted output. /usr/bin/local/clang-format # replace /usr/bin/local with the install location of clang-format
clang-tidy
Clang-tidy is a static code analyzer which can perform a number of checks, including but not limited to:
- Enforce variable naming conventions
- Enforce C++ core guidelines
- Sniff out bug-prone code
- Performance tips e.g. passing by const& instead of value.
What clang-tidy looks for will depend on the enabled checks. A list of available checks can be found at v14 checks
IDE Integration
Clang-tidy output is best served by an IDE or Text Editor.
Most editors will have support for clang-tidy and display warning messages as you update code.
- Clangd is a widely supported 'language server' interface to clang tools. Please see [5] for details and [6] for installation instructions. It works especially well for VS Code.
- XCode Clang-Analyzer [7]
To get this to work, you will need to copy over an up-to-date version of compile_commands.json for your editor to correctly run clang-tidy. If your editor environment is not SLF7, you may need to generate this with the above steps on a SLF7 machine (or docker container) that can set up and compile the Offline software. Make sure that when you move it to a different machine that the "directory" value on all JSON list entries point to the correct location. You can fix this quickly via a search-and-replace all operation.
In the editor environment you copy this to, you will need the correct CVMFS mounts (mu2e.opensciencegrid.org, fermilab.opensciencegrid.org) for clang-tidy to access the external headers.
Command Line Usage
Clang-tidy requires a compile_commands.json to run correctly, as it needs to know the compile flags for each build target. This can be generated by a script which scrapes these from SCons output [8]
To analyse <files>, and apply properly-formatted fixes in place:
cd Muse workDir setup mu2e muse setup # build, including the compilation db muse build --mu2eCBD ... # so the compilation db can be found by clang-tidy cp $MUSE_BUILD_DIR/compilation_db.json ./compile_commands.json setup codetools setup clang v14_0_6c CLANG_TIDY_ARGS="-extra-arg=-isystem$CLANG_FQ_DIR/include/c++/v1 -extra-arg=-isystem$CLANG_FQ_DIR/include/x86_64-unknown-linux-gnu/c++/v1 -p . -j 24" run-clang-tidy ${CLANG_TIDY_ARGS} Offline/...
N.B. Not all checks will provide fixes. Some warning messages will require manual review. This is where an IDE-based plugin may be more desirable.
Include What You Use (IWYU)
This utility will examine the include files in a piece of code and remove the ones that aren't needed and include the file defining the classes that are used. It requires the scons compilation database, which can be built:
muse build --mu2eCBD
the compilation database will be in $MUSE_BUILD_BASE
A typical iwyu command is
iwyu_tool.py -p $MUSE_BUILD_BASE/compilation_db.json Mu2eUtilities/src/*.cc -j 6 | fix_includes.py --comments --noreorder