I have tried to enable the clang-tidy on cxx_module project using CMAKE_CLANG_TIDY. But it seems to fail and I don’t know if it is an issue in how cmake calls it or an issue on clang-tidy side. Here is a mwe:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.26)
project(clang-tidy-issue
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API 2182bf5c-ef0d-489a-91da-49dbc3090d2a)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP TRUE)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT clang)
set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-checks=*")
add_library(test_library)
target_sources(test_library PUBLIC
FILE_SET cxx_modules
TYPE CXX_MODULES
FILES
test_module.ixx
)
# First find clang-tidy, this also allows users to provide hints
find_program(CLANG_TIDY NAMES clang-tidy)
# Then I have this which is essentially calls clang-tidy with warnings as errors (For CI)
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY};")
clang-tidy then finds the .clang-tidy file in my build without issue. So I don’t have to list all the checks in the CMake code.
From the clang-tidy docs:
# clang-tidy attempts to read configuration for each source file from a
# .clang-tidy file located in the closest parent directory of the source
# file. The .clang-tidy file is specified in YAML format. If any configuration
# options have a corresponding command-line option, command-line option takes precedence.
The notes above are right, but it is a standalone working example only.
The real question is why does clang-tidy ends with an clang-diagnostic-error:
bash-3.2$ ninja -C build/
ninja: Entering directory `build/'
[0/1] Re-running CMake...
CMake Warning (dev) at CMakeLists.txt:70 (target_sources):
CMake's C++ module support is experimental. It is meant only for
experimentation and feedback to CMake developers.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring done (0.1s)
CMake Warning (dev):
C++20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
experimental. It is meant only for compiler developers to try.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Generating done (0.0s)
-- Build files have been written to: /Users/clausklein/Workspace/cpp/cxx20/test/build
[4/8] Building CXX object CMakeFiles/foo.dir/foo.cxx.o
/Users/clausklein/Workspace/cpp/cxx20/test/foo.cxx:8:14: warning: class 'foo' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions,hicpp-special-member-functions]
export class foo {
^
/Users/clausklein/Workspace/cpp/cxx20/test/foo.cxx:8:14: warning: invalid case style for class 'foo' [readability-identifier-naming]
export class foo {
^~~
Foo
/Users/clausklein/Workspace/cpp/cxx20/test/foo.cxx:15:11: warning: method 'helloworld' can be made static [readability-convert-member-functions-to-static]
void foo::helloworld() { std::cout << "hello world\n"; }
^
[7/8] Building CXX object CMakeFiles/hello.dir/main.cxx.o
FAILED: CMakeFiles/hello.dir/main.cxx.o
/usr/local/Cellar/cmake/3.26.3/bin/cmake -E __run_co_compile --tidy="clang-tidy;-checks=*,-llvmlibc-*,-fuchsia-*,-cppcoreguidelines-init-variables;--extra-arg-before=--driver-mode=g++" --source=/Users/clausklein/Workspace/cpp/cxx20/test/main.cxx -- /usr/local/opt/llvm/bin/clang++ -std=c++20 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.3.sdk -MD -MT CMakeFiles/hello.dir/main.cxx.o -MF CMakeFiles/hello.dir/main.cxx.o.d @CMakeFiles/hello.dir/main.cxx.o.modmap -o CMakeFiles/hello.dir/main.cxx.o -c /Users/clausklein/Workspace/cpp/cxx20/test/main.cxx
/Users/clausklein/Workspace/cpp/cxx20/test/main.cxx:1:8: error: module 'foo' not found [clang-diagnostic-error]
import foo;
~~~~~~~^~~
1 error generated.
Error while processing /Users/clausklein/Workspace/cpp/cxx20/test/main.cxx.
Found compiler error(s).
ninja: build stopped: subcommand failed.
bash-3.2$
-fprebuilt-module-path=CMakeFiles/foo.dir/ must be set:
bash-3.2$ pwd
/Users/clausklein/Workspace/cpp/cxx20/test/build
bash-3.2$ /usr/local/opt/llvm/bin/clang-tidy -extra-arg=-fprebuilt-module-path=CMakeFiles/foo.dir/ -p=/Users/clausklein/Workspace/cpp/cxx20/test/build /Users/clausklein/Workspace/cpp/cxx20/test/main.cxx
77759 warnings generated.
Suppressed 77759 warnings (77759 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
/usr/local/opt/llvm/bin/clang-tidy -extra-arg=-fprebuilt-module-path=CMakeFiles/foo.dir/ -p=/Users/clausklein/Workspace/cpp/cxx20/test/build /Users/clausklein/Workspace/cpp/cxx20/test/foo.cxx
/Users/clausklein/Workspace/cpp/cxx20/test/foo.cxx:15:11: warning: method 'helloworld' can be made static [readability-convert-member-functions-to-static]
void foo::helloworld() { std::cout << "hello world\n"; }
^
85168 warnings generated.
Suppressed 85167 warnings (85167 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
bash-3.2$
Yes, I have tested your cmakelists and it worked perfectly fine, which puzzled me. But I managed to systematically reproduce the issue when I use .ixx suffix.
It seems the extensions are not in clnag-tidy 16 yet: