How to properly get FINAL compile arguments for file/target?

I have a custom clang-tool that generates additional headers for both my headers and source files when they contain certain information.

I basically need to define a custom command for each source/header file in a target, and run these before compilation, and the event version of add_custom_command(TARGET <target> PRE_BUILD ...) would work, but I can’t figure out how to get all of the compile arguments for the given target file.

So it seems Im stuck.
While my clang-tool can accept a “compile_commands.json”, which CMAKE can generate, it does not include compile commands for header files, nor can I find a way to make it do so ( I even tried a custom extension, .rpp, as a C++ source file ).

The clang-tool needs the proper include directories and compile definitions that the rest of the source files do in order to properly build the C++ AST.

I’ve tried adding a custom target with a CXX_COMPILER_LAUNCHER, but it does not launch on header files either.

Does no one preprocess header/source files to generate more code? I quickly browsed the source code for CMake and unfortunately there is not a uniform way even from there to get the final compile arguments for a target or file…

There are no compile commands for header files. Only .cpp files actually get compiled into object files.

You can access the “final” set of compile flags using generator expressions, but those will be evaluated after scripting, once the build system is actually being generated

I am aware that there are no compile commands generated for header files, as cmake doesn’t even generate the compile commands itself AFAIK, that is given to Make or Ninja to do. But even with a custom c++ source extension of rpp in an attempt to coax them to output compile commands for them, Ninja still refuses to ouptut them.

You can access the “final” set of compile flags using generator expressions, but those will be evaluated after scripting, once the build system is actually being generated

I’m not aware of any generator expressions that would give me the compile definitions, compile options, and include paths for the target/source file and all of its transitive dependencies.

Someone did request such a feature here: https://gitlab.kitware.com/cmake/cmake/-/issues/22057 a year ago…

that’s my point, it is not possible to create compile commands for header files. such a thing does not exist.

You can get compile definitions, include paths, etc by querying target properties, such as:

$<TARGET_PROPERTY:yourTarget,COMPILE_DEFINITIONS>
$<TARGET_PROPERTY:yourTarget,COMPILE_OPTIONS>
$<TARGET_PROPERTY:yourTarget,INCLUDE_DIRECTORIES>

Interesting, these DO seem to be transitive. I’ll try it out.

In addition, there is nothing in the spec for what such a thing even means. If this is wanted, please talk with those that maintain compile_commands.json (IIRC, the LLVM developers). I really don’t want CMake forging new extensions to widely-used specs like this.

I don’t think CMake delegates it to ninja. make has no mechanism for generating such files itself either.

1 Like