msbuildcontinuous-integrationclang-tidy

Generate compile_commands.json from msbuild via command line -- no cmake


I'm looking for a way to integrate clang-tidy into a CI workflow, but the build system being used is MSBuild with dependencies managed by vcpkg in manisfest mode.

Is there some advanced command line that I can pass MSBuild (or some other tool that understands MSBuild process completely) to be able to generate compile_commands.json?

I'm sure I'm not the first one to try that, I've seen a couple of cases of success using SourceTrail and ClangPowerTools, but it has been specially painful in my case because the alternatives cannot detect the include paths exposed by vcpkg.


Solution

  • It turns out that msbuild has a builtin target for clang-tidy since Visual Studio started to support that linter.

    To invoke it one can run : msbuild /t:ClangTidy ....

    Unfortunately, very few command line options are exposed from the clang-tidy integration to msbuild CLI: the list of checks, the header-filter, additional compiler options, a flag for warnings in system headers and the tool path.

    If one wants to export the fixes file generated by clang-tidy, which was my case, it needs to do some extra work.

    I achieved my goal by adding one Directory.Build.props file in the project folder which overrides the path to the original clang-tidy.exe with a batch script (.bat), which does some preparation steps and forwards the msbuild target command line to a python script which can invoke clang-tidy with its full command line capabilities.

    The props file:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        
        <ClangTidyToolPath>$(where_I_saved_the_bat_file)\</ClangTidyToolPath>
        <ClangTidyToolExe>msbuild-clang-tidy-runner.bat</ClangTidyToolExe>
      </PropertyGroup>
    </Project>
    

    The batch file:

    SET PYTHONPATH=...
    REM and maybe other stuff
    python3 -m my_custom_clang_tidy_runner  %*
    

    Interestingly the batch file was the only way other than a real executable file that I could place in the Directory.Build.props that wouldn't result in msbuild compilation error. I tried python and powershell scripts and none were accepted as a suitable clang-tidy executable file. I experimented creating a C++ program which does the same as my Python script and it worked as expected as well.

    So, to summarize, the recipe is:

    1. Create the Directory.Build.props file in the root folder of the project you want to lint overriding the clang-tidy path.
    2. A custom .exe or .bat file to replace clang-tidy capable of forwarding the command line options passed by msbuild together with any customisation you wish.
    3. Invoke msbuild /t:ClangTidy ... and Bob's your uncle!