This has not been worked on; clang-tidy may need to learn how to read the modmap file clang will use (though it should exist by the time we’re compiling…
The fact that it doesn’t work with compile_commands.json when the @modmap arguments are there tells me that clang-tidy is ignoring something…
Certainly not share as they are arch-dependent. I suspect where they go will be a Linux distro discussion in the FHS umbrella, Apple will just decree for itself, and Microsoft will do Windows things. ISO C++'s SG15 is also likely to discuss such things.
@ClausKlein, I have been experiencing this issue too, which gives clang-diagnostic-error with C++20 modules and clang-tidy.
FAILED: CMakeFiles/caldera_exe.dir/source/main.cpp.obj
"C:\Program Files\CMake\bin\cmake.exe" -E __run_co_compile --tidy="clang-tidy;--header-filter=^D:/Libraries/Documents/Repositories/caldera;-extra-arg=-fprebuilt-module-path=D:/Libraries/Documents/Repositories/caldera/build/CMakeFiles/caldera_lib.dir;--extra-arg-before=--driver-mode=cl" --source=D:\Libraries\Documents\Repositories\caldera\source\main.cpp -- C:\PROGRA~1\MIB055~1\2022\ENTERP~1\VC\Tools\MSVC\1436~1.325\bin\Hostx64\x64\cl.exe /nologo /TP -ID:\Libraries\Documents\Repositories\caldera\source -external:ID:\Libraries\Documents\Repositories\caldera\build\dev-win64\vcpkg_installed\x64-windows-static-md\include -external:W0 /sdl /guard:cf /utf-8 /diagnostics:caret /w14165 /w44242 /w44254 /w44263 /w34265 /w34287 /w44296 /w44365 /w44388 /w44464 /w14545 /w14546 /w14547 /w14549 /w14555 /w34619 /w34640 /w24826 /w14905 /w14906 /w14928 /w45038 /W4 /permissive- /volatile:iso /Zc:inline /Zc:preprocessor /Zc:enumTypes /Zc:lambda /Zc:__cplusplus /Zc:externConstexpr /Zc:throwingNew /EHsc /O2 /Ob1 /DNDEBUG -std:c++20 -MD -Zi /showIncludes @CMakeFiles\caldera_exe.dir\source\main.cpp.obj.modmap /FoCMakeFiles\caldera_exe.dir\source\main.cpp.obj /FdCMakeFiles\caldera_exe.dir\ /FS -c D:\Libraries\Documents\Repositories\caldera\source\main.cpp
warning: unknown argument ignored in clang-cl: '-fprebuilt-module-path=D:/Libraries/Documents/Repositories/caldera/build/CMakeFiles/caldera_lib.dir' [clang-diagnostic-unknown-argument]
D:\Libraries\Documents\Repositories\caldera\source\main.cpp:1:8: error: module 'caldera' not found [clang-diagnostic-error]
import caldera;
~~~~~~~^~~~~~~
132051 warnings and 1 error generated.
Error while processing D:\Libraries\Documents\Repositories\caldera\source\main.cpp.
Suppressed 132050 warnings (132050 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.
Found compiler error(s).
ninja: build stopped: subcommand failed.
I am running Windows 10, running Visual Studio 17.6.2 (cl.exe 19.36), CMake 3.26.4, Ninja 1.11.0, and clang-tidy 16.0.0 (so effectively everything is the newest possible).
When I tried preparing a minimal working example, all was fine, but in my own project, I didn’t realise I had previously set CMAKE_CXX_CLANG_TIDY, and it admittedly took me quite a bit of time to notice the problem.
Like you, I wonder if it has to do with the way CMake is calling clang-tidy, or if it’s a bug in clang-tidy itself.
CMake is generating modules for MSVC to use, If clang-tidy cannot consume the .ifc files (regardless of the extension), it will always fail to import things.
Sure. I don’t 100% know what to do with it at the moment right now. Getting modules working at all is higher priority than figuring out heterogeneous tooling. If you want to use clang-tidy with modules today, I’d recommend using a matching clang toolchain at least.
I changed line 14 of CMakePresets.json to clang.exe, but I still receive the same error. test.pcm is built in ${CMAKE_BINARY_DIR}/CMakeFiles/test_lib.dir/test.pcm. A full, verbose build log is below:
I think we should create a clean example because when I tried it, clang-tidy failed regardless of cmake configuration, most probably because it does not read module files.
I think so. Like I mentioned in the LLVM thread, running clang-tidy standalone with clang-only tools (i.e. manually pre-compiling) also failed. Which is why I posted the issue there, too.
> clang-tidy.exe -checks="-*,readability-*" --extra-arg=-Xclang=-fprebuilt-module-path=D:/Libraries/Desktop/test/build/CMakeFiles/test.dir/ -p=D:/Libraries/Desktop/test/build --extra-arg-before=--driver-mode=cl .\main.cpp
1 error generated.
Error while processing D:\Libraries\Desktop\test\.\main.cpp.
D:\Libraries\Desktop\test\main.cpp:1:8: error: module 'test' not found [clang-diagnostic-error]
import test;
~~~~~~~^~~~
Found compiler error(s).
> clang-tidy.exe -checks="-*,readability-*" --extra-arg=-Xclang=-fprebuilt-module-path=D:/Libraries/Desktop/test/build/CMakeFiles/test_lib.dir/ -p=D:/Libraries/Desktop/test/build --extra-arg-before=--driver-mode=cl .\main.cpp
1 error generated.
Error while processing D:\Libraries\Desktop\test\.\main.cpp.
D:\Libraries\Desktop\test\main.cpp:1:8: error: module 'test' not found [clang-diagnostic-error]
import test;
~~~~~~~^~~~
Found compiler error(s).
>
Hi, I am here after a lot of scouring the internet due to my own clang tool failing when CMake updated to 3.28. The root of the issue is related to the @foo.modmap files as discussed here, but I think the reasons discussed so far miss the cause.
The problem then is that CMake generates a @foo.modmap file during compilation for each .cc file that it builds. The file is not created as a result of configure, and it’s not left behind after compilation, only the .obj file is left behind.
So when I run a clang tool against the command line specified in compile_commands.json, it fails due to the @foo.modmap file not existing. AFAICT the command that CMake writes into the compile_commands.json is incorrect, since it’s pointing to a file (the modmap file) which does not actually exist (outside of cmake doing compilation which is not what compile_commands.json is for).
This renders the compile_commands.json broken, and requires tools to strip out the @foo.modmap argument in order to run the clang tool against the command line arguments in the compile_commands.json file. This will work until code actually uses modules at which point it will fall over again, as the root issue is unresolved: that the command line in the compile_commands.json file as generated by CMake is not able to independently reproduce the compilation step.
FTR, I am using CMake 3.28.1, and this issue occurs on Windows and Linux, targeting Clang and MSVC. If CMake is wedded to the idea of using a modmap file during compilation, it needs to write them all to disk at the same time that it generates the compile_commands.json.
Please read the Reddit comments on that blog post. I do need to write up docs on how CMake implements modules. It’s on my list.
Then it will need to wait until the build is complete. The .modmap files cannot be made at generate time without CMake having to regenerate the build on every.modmap-using source file. At that point, the file is the same as made during configure and the .modmap files are present for use by any compile_commands.json-using tool. Note that there is also no safe place in the graph to place a command to generate compile_commands.json because:
targets may be EXCLUDE_ALL and not build via the default target and still reference non-existent files
if it needs updated (e.g., after a re-configure, it is out-of-date until regenerated)
Note that this has always been an issue with build-generated sources or headers. There is a plan to solve this part of the problem in 2024 with something like a generated-sources target (name and details TBD) to generate all sources. A similar target to make .modmap files present would also be something that could be done at the same time.
If the projects do not actually use modules, they can set CMAKE_CXX_SCAN_FOR_MODULES to 0 to disable scanning (and therefore .modmap file usage).
Note that it will be the least of your worries as the BMIs that are made during the build will be compiler-specific and your tool will (likely) need to generate its own BMIs in order to perform the import statements in the analyzed. There are plans for generating enough information for tools to be able to generate their own BMIs in 2024 as well (future work can let CMake drive the tool to make these BMIs, but that is likely farther out).
Thanks, I hope that this can improve in 2024, glad to know it’s on your radar.
One note: I do not see any modmap files in my CMakefiles directories, even after I have done a compile. There’s no point at which the compile_commands.json command lines work for me. It seems that CMake generates them, does the compile, and then deletes them after the compilation is done.
That sounds promising. Basically it would call all configure_file, custom_command, and cmake native like the cxx module files generation? That would be useful for the cmake pre-commit.
Does this also solve the original issue with clang-tidy + compile_commands.json?
configure_file is configure-time; this would basically make sure any sources with the GENERATED property are up-to-date. Or similar; there are a lot of test cases to write and decide support for.
Ok, so the build doesn’t use modules, so we don’t actually do any modmap stuff. The compile_commands.json logic reimplements some flag detection; this needs reworked to match.