EDIT: as of CMake 3.27, the SKIP_LINTING source file property is now an easier way to achieve this, as explained in the answer by @jpr42.
Original answer:
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.