13

I'm trying to integrate clang-tidy with cmake, but there are some files that belong to a particular target which I would like to ignore.

Is there any way to make clang-tidy to ignore files under certain directory or whose name matches a certain pattern?

Dan
  • 2,452
  • 20
  • 45

3 Answers3

2

In the directory you want to ignore, create a .clang-tidy config file, that disables all checks with:

Checks: '-*'

If there is no way of keeping such a file in a repository, the file can be easily generated before running clang-tidy with echo "Checks: '-*'" > $folder2ignore/.clang-tidy. (This will even overwrite existing .clang-tidy, effectively disabling clang-tidy for the folder)

Vojtěch Chvojka
  • 378
  • 1
  • 15
1

CMake 3.27

3.27 introduces the SKIP_LINTING file property to handle this nicely.

add_executable(MyApp main.cpp things.cpp generatedBindings.cpp)

set_source_files_properties(generatedBindings.cpp PROPERTIES
    SKIP_LINTING ON
)

Link to official CMake documentation: https://cmake.org/cmake/help/latest/prop_sf/SKIP_LINTING.html

Pre CMake 3.27

You could also just add comments to your code.

https://clang.llvm.org/extra/clang-tidy/#suppressing-undesired-diagnostics

// NOLINTBEGIN
...
// NOLINTEND
jpr42
  • 718
  • 3
  • 14
1

Unfortunately, CXX_CLANG_TIDY is a per-target property, so we can't achieve this using set_source_files_properties.

But if we want to disable clang-tidy for a specific target, its as simple as doing this:

set_target_properties(your_target_here PROPERTY CXX_CLANG_TIDY "")

If we need to control this per file, it gets more complicated. We have to add a separate OBJECT library target just for the files we don't want clang tidy'd, and then just link this one to the main target. Because object libraries are really just a handle to a bunch of .o files (no bundling archives/lib is created), this does not cause any build time overhead.

Here's a full example:

cmake_minimum_required(VERSION 3.12)
project(demo)

# default clang-tidy options, alternatively, you can specify this manually 
# using set_property for each target, then you don't need to disable it for others
set(CMAKE_CXX_CLANG_TIDY clang-tidy;-format-style='file') 

set(SOURCES main.cpp) # sources we want tidy'd
set(NO_CLANG_TIDY_SOURCES foo.cpp) # sources we don't want tidy'd

# add dummy target for no clang tidy sources
add_library(demo_no_clang_tidy OBJECT ${NO_CLANG_TIDY_SOURCES})
# disable clang tidy for this target
set_target_properties(demo_no_clang_tidy PROPERTY CXX_CLANG_TIDY "")

# add our real target
add_executable(demo ${SOURCES})
# link in the sources from our object library
target_link_libraries(demo demo_no_clang_tidy)
  • If you don't want to specify the sources manually (you mentioned that you want this per directory) you can use a glob (not really best practice though):
set(SOURCES main.cpp foo.cpp) # all sources
# specify glob expressions for files NOT to clang-tidy 
file(GLOB NO_CLANG_TIDY_SOURCES 
     LIST_DIRECTORIES false 
     RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" 
     "f*.cpp" "foo/*.cpp"
)

# remove these files from the main SOURCES list
list(REMOVE_ITEM SOURCES ${NO_CLANG_TIDY_SOURCES})
  • If you have custom target options (include paths, pp directives, etc) you obviously meed to set them for both targets.
ChrisB
  • 1,540
  • 6
  • 20