Biswajit Banerjee

Auto-modernizing C++ code

Using clang-tidy with cmake

The Clang static analyzer tools come with a handy interface called clang-tidy.

I’ve been try to set up this tool in my cmake toolchain with varying levels of success. In particular I’d like to automate the conversion of old code into a version that uses C++11 and some C++14 constructs.

Attempt 1

In my first attempt I created a cmake directory at the top level of my source tree and added a clang-tidy.cmake file that contained the following:

  file(GLOB_RECURSE ALL_MY_SOURCE_FILES *.cpp *.hpp *.cc *.h)
        COMMAND /usr/bin/clang-tidy

At the bottom of my main CMakeList.txt file I added


When I ran cmake and then make clang-tidy, there were several complaints about header files not being found, but the suggested fixes were written to the file clang-tidy-fixes.dat. That file contained numerous suggested fixes in the format

    - FilePath:        /path/to/file/parser.h
      Offset:          9558
      Length:          52
      ReplacementText: '(const auto & token : tokens)'

Going through that file and then hand-coding the changes looked daunting, so I looked at automating the code change process.

Attempt 2

To make clang-tidy apply the fixes automatically, I replaced


in clang-tidy.cmake to


When I ran make clang-tidy after that change, fixes were automatically applied, but also applied multiple times. For example, I got


instead of


Attempt 3

Clearly, attempt 2 wasn’t solving the problem, and I went back to the clang-tidy manual and found that I could actually export the compile commands from by build using


That command created a compile_commands.json file which contained all the path and header information that a build could need.

I then located the python script for running clang-tidy from


and, from my build directory containing compile_commands.json, I ran ../src -checks=modernize* -fix

No more complaints about missing header files, and all fixes appeared to have been applied only once. It’s much easier to use this process than to try to create a custom target for cmake.