16

Is there a sensible way to get a CMake variable containing the build command or all the compiler flags that CMake will associate with a target?

It doesn't seem practical to try to gather and maintain a list of all properties that could add flags. Besides, CMake must have this info somewhere, since it has to eventually generate a build system.

From the CMake docs it looks like this feature once existed and was provided by calling build_command() but this was replaced:

Note In CMake versions prior to 3.0 this command returned a command line that directly invokes the native build tool for the current generator.

Is there a new command that gives the old behavior of build_command()?

Praxeolitic
  • 22,455
  • 16
  • 75
  • 126
  • 3
    See e.g. [How to use CMAKE_EXPORT_COMPILE_COMMANDS?](https://stackoverflow.com/questions/20059670/how-to-use-cmake-export-compile-commands) or [Retrieve all link flags in CMake](https://stackoverflow.com/questions/34165365/retrieve-all-link-flags-in-cmake). Can you please be more specific what you want to do with the command line or all compiler flags? If you generate e.g. Visual Studio solutions and projects there might even not be something like a command line incl. compiler flags. – Florian Dec 30 '17 at 20:27
  • 1
    I don't think `build_command()` ever worked this way. It says it would be a command line that invokes the build tool i.e `make` not the compiler and its options to build target. – fdk1342 Dec 24 '18 at 19:25
  • 1
    The new CMake file API appears to support this, at least somewhat. See the [targets](https://cmake.org/cmake/help/git-stage/manual/cmake-file-api.7.html#codemodel-version-2-target-object) section of the API docs. – Kevin Oct 02 '19 at 16:30
  • 1
    Please tell me what are you trying to do? I did many experiments w/ this (trying to integrate ABI compliance checker to my builds ;-) and maybe I have an answer for you ) – zaufi Feb 21 '21 at 14:47

4 Answers4

1

Is there a sensible way to get a CMake variable containing the build command or all the compiler flags that CMake will associate with a target?

The answer is no (CMake 3.23 is latest at time of writing), not during the CMake configure step.

In general, such a thing is ill-defined, which is likely why it was removed from CMake and will likely not be re-added. The complications arising from generator expressions, multi-config generators, generators that don't construct command lines (like VS/msbuild), source-file-specific properties, and the simple fact that after the command is called, relevant state might change, all make such efforts quixotic.

Honestly, this is such an odd thing to want at configure time, I wonder if this isn't an XY problem. It's unlikely that one target depends on another in such a way that the entire eventual command line is needed (rather than a particular property) to create it.

I know this is many years later now, but what were you trying to do?

CMake provides many ways post-generation to get information about the compiler command lines.

  1. There's the CMake File API, meant for IDE integration,
  2. The CMAKE_EXPORT_COMPILE_COMMANDS option that creates a Clang-compatible compile_commands.json, and then there's
  3. The CMAKE_<LANG>_COMPILER_LAUNCHER variables that would let you instrument a full command line with a custom script while the build is running.

One of these might be useful. The latter is commonly used with ccache, but can be (ab)used with any arbitrary program as long as the output file is eventually generated.

Note that the latter two only work with the Makefile and Ninja generators.

Alex Reinking
  • 16,724
  • 5
  • 52
  • 86
0

If you want the final output of how the source files will actually be compiled you will want to look at the generated files. I don't really know a better way currently:

Example:

Here is an example output from Ninja Multi

build\CMakeFiles\impl-Release.ninja

This file will list all of the compile definitions, compiler flags, include directories, object directory, etc.

0

Under the path "cmake-build-debug/CMakeFiles/" you'll find a folder named as "TopFolderOfYourProject.dir", where the cmake generates all its build system files, including a file "build.make". In this file you can see something like this:

CMakeFiles/somepath/somesourcefile.c
    @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --progress-dir=xxx\cmake-build-debug\CMakeFiles --progress-num=$(CMAKE_PROGRESS_1) "Building C object CMakeFiles/somepath/somesourcefile.c.obj"

Besides this, you can find extra info about the flags in the file "flags.make", it contains all extra compiler flags specified by developers.

And in "includes_C.rsp/includes_CXX.rsp" you can see the including path.

Jason
  • 81
  • 1
  • 4
-1

Build flags are, actually, associated with source files, because you can have differrent flags for different files. On the other hand, for the most cases these flags are equivalent.

Anyways, to get all build flags for a source file you can use COMPILE_FLAGS property:

get_source_file_property(RESULT file.cpp COMPILE_FLAGS)
arrowd
  • 33,231
  • 8
  • 79
  • 110
  • 12
    The `COMPILE_FLAGS` property of either a target or a source used in that target doesn't evaluate to the full list of build flags that will be used. I just tried this out on a target to be sure and the `COMPILE_FLAGS` property isn't event set if properties like `INCLUDE_DIRECTORIES` and `COMPILE_DEFINITIONS` are set. The same was true for a random source file used in a target. Like the CMake docs say, it looks like `COMPILE_FLAGS` is for "additional" flags -- it doesn't evaluate to all flags that will be used. – Praxeolitic Jun 04 '16 at 08:20