Is there a way to get the build command line?

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 :wink:

And ninja clean && and ninja -nv show all you want to see.