CMake obviously knows what the command build line would be because it is executing it. Can I get what that build line would be through the CMake system so that I can interrogate it?
CMake does not know in all cases. In particular, IDEs are fields of properties that CMake sets and then the IDE creates the actual command line.
Even for non-IDE generators, CMake only knows at generation time, so CMakeLists.txt
code cannot use it. You can use CMAKE_EXPORT_COMPILE_COMMANDS
to create a compilation database which has the full command lines though.
If you’re able to programmatically run CMake twice, you can retrieve the compile command from the JSON array, iterating the array to compare “file” field vs target name.
This is roughly akin to how I use CMake file API.
cmake_minimum_required(VERSION 3.19)
project(Hello LANGUAGES C)
set(CMAKE_EXPORT_COMPILE_COMMANDS true)
if(EXISTS ${PROJECT_BINARY_DIR}/compile_commands.json)
file(READ ${PROJECT_BINARY_DIR}/compile_commands.json cmds)
string(JSON L LENGTH ${cmds})
math(EXPR L "${L} - 1")
foreach(i RANGE ${L})
string(JSON c GET ${cmds} ${i} "command")
message(STATUS "Command ${i}: ${c}")
endforeach()
endif()
if(NOT EXISTS main.c)
file(WRITE main.c "int main(void) { return 0; }")
endif()
if(NOT EXISTS main2.c)
file(WRITE main2.c "int main(void) { return 0; }")
endif()
add_executable(main main.c)
add_executable(main2 main2.c)
Note that as of CMake 3.26, the compile_commands.json
will have the output
field present to be able to tell apart different compilations of the same input file.
Yeah, unfortunately I don’t have access to CMAKE_EXPORT_COMPILE_COMMANDS
. I’m using Green Hills and Visual Studio.
Why is it not possible for cmake with e.g. Visual Studio generator to always generate the .json file? After all, cmake pretty much knows everything. Why does it matter if it outputs a ninja.build or a VS solution?
With Ninja
and Makefiles
generators, CMake is indeed making the final command line. With Xcode and VS, CMake is playing MadLibs with IDE property sheets to convince the IDE to make a suitable command line; it doesn’t know the exact line that will be made.
Is the exact line needed when running analysis tools like clang_tidy?
Generally, yes.
you may try bear (at least under linux
):
BEAR(1) BEAR(1)
NAME
Bear - a tool to generate compilation database for Clang tooling.
SYNOPSIS
bear [options] -- [build command]
DESCRIPTION
The JSON compilation database <http://clang.llvm.org/docs/JSONCompilationDatabase.html> is used in Clang project to provide information how a single compilation unit was
processed. When that is available then it is easy to re-run the compilation with different programs.
Bear executes the original build command and intercept the command executions issued by the build tool. From the log of command executions it tries to identify the compiler
calls and creates the final compilation database.
Seeing as Linux doesn’t support either of the IDEs in question, something else is likely necessary.
I would use GHS under Linux
with Ninja
.
And Microsoft cl
with Nina
under Windows
.
Both works fine
And ninja clean && and ninja -nv
show all you want to see.