Incorrect log output during clang-tidy error with -p option

So, in continuation of issue 27160

TL;DR

Using the Ninja generator, I see an incorrect command for clang-tidy launch with the -p option in case of error. Is it a problem on the Ninja side or CMake? It appears that the command displayed during the build and the command that is actually executed are different.

Description

I want to add -fconcepts as a compile option for GCC and use clang-tidy. To hide the -fconcepts option in clang-tidy, I used the -p option as described here: - https://cmake.org/cmake/help/latest/prop_tgt/LANG_CLANG_TIDY.html
With the following code as an example

set_target_properties(main PROPERTIES CXX_CLANG_TIDY "clang-tidy;--warnings-as-errors=*;-checks=llvmlibc-implementation-in-namespace;-p;${CMAKE_BINARY_DIR}"

I got the following error and log:

FAILED: [code=1] HW_4/CMakeFiles/print_ip.dir/src/main.cpp.o 
/usr/local/bin/cmake -E __run_co_compile --tidy="/usr/bin/clang-tidy;--use-color;--warnings-as-errors=*;-checks=llvmlibc-implementation-in-namespace;-p;/home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/build;--extra-arg-before=--driver-mode=g++" --source=/home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/HW_4/src/main.cpp -- /usr/bin/c++  -I/home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/HW_4/include -std=c++26 -fdiagnostics-color=always -Wall -Wextra -pedantic -fconcepts -MD -MT HW_4/CMakeFiles/print_ip.dir/src/main.cpp.o -MF HW_4/CMakeFiles/print_ip.dir/src/main.cpp.o.d -o HW_4/CMakeFiles/print_ip.dir/src/main.cpp.o -c /home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/HW_4/src/main.cpp
/home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/HW_4/src/main.cpp:25:5: error: declaration must be enclosed within the 'LIBC_NAMESPACE' namespace [llvmlibc-implementation-in-namespace,-warnings-as-errors]
   25 | int main()

Link to the full log - Clang tidy part III · Detect1ve/CPlusPlus-Developer.-Professional@262c3e7 · GitHub

So, there is a -p option, but still I see the following -- /usr/bin/c++ -I/home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/HW_4/include -std=c++26 -fdiagnostics-color=always -Wall -Wextra -pedantic -fconcepts -MD -MT HW_4/CMakeFiles/print_ip.dir/src/main.cpp.o -MF
which is strange, because according to the documentation, the behaviour should be different:

If the specified `clang-tidy` command line includes the `-p` option, it will be invoked without `--` and the full compiler command line.

Also, I think the log output command can be used as a command to run in the terminal(with some changes, of course), and when I do that, I get a different output:

/usr/bin/clang-tidy --use-color --warnings-as-errors=* -checks=llvmlibc-implementation-in-namespace -p /home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/build /home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/HW_4/src/main.cpp -- --driver-mode=g++ -I/home/runner/work/CPlusPlus-Developer.-Professional/CPlusPlus-Developer.-Professional/HW_4/include -std=c++26 -fdiagnostics-color=always -Wall -Wextra -pedantic -fconcepts
error: unknown argument: '-fconcepts' [clang-diagnostic-error] <---- here the difference!!!
HW_4/src/main.cpp:25:5: error: declaration must be enclosed within the 'LIBC_NAMESPACE_DECL' namespace [llvmlibc-implementation-in-namespace,-warnings-as-errors]
   25 | int main()
      |     ^

Is this expected behavior?

When you use the -p option, CMake will tell clang-tidy to use the compile_commands.json file to get the full compiler command line instead of whatever follows after the --. If you’ve added -fconcepts to the compile command, it will be included in the compile_commands.json as well.

It’s worth mentioning here that I use a trick with changing compile_commands.json by removing -fconcepts from there so that clang-tidy can run successfully, so there is no mention of -fconcepts inside compile_commands.json, but there is in the log.

Okay, let’s clarify another point:
Are you saying that CMake will implicitly exclude everything that comes after --, but will still show the full compiler command line in the log in case of an analysis clang-tidy error?

Is this really a good solution/approach? I think it may not be very clear.

If I explained the situation poorly, I’m ready to try to explain it in another way :slight_smile:

It’s worth mentioning here that I use a trick with changing compile_commands.json

Welcome to the land of “unsupported, you’re on your own now”. :wink:

The documentation for <LANG>_CLANG_TIDY says the following:

Changed in version 3.25: If the specified clang-tidy command line includes the -p option, it will be invoked without -- and the full compiler command line. clang-tidy will look up the source file in the specified compiler commands database.

Maybe that could be worded better, but what it means is that clang-tidy is invoked with the compiler command from compile_comands.json, and everything from the -- and what comes after it in the log is ignored for clang-tidy. Note that what you see in the log is still what will be used for the actual compilation. The two should agree (command line and compile_commands.json), but this behavior was added to work around a bug in clang-tidy for special cases where it can sometimes make wrong decisions about the compiler if fed the compiler command line directly.