14

I am trying to print compilation flags that are set for target. The best scenario is to print a line with current flags on configure and compilation times, but if it's impossible, then on configure time only (or compilation only) (acceptable solution).

This is my testing .c file:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}

And CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(cmake_gcc_options_try_c C)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

add_executable(cmake_gcc_options_try_c main.c)

target_compile_options(cmake_gcc_options_try_c 
                       PUBLIC -W -Wall -Wextra -pedantic -pedantic-errors)

# This fails
message("-- Current compiler flags CMAKE_C_FLAGS are: ${CMAKE_C_FLAGS}")
message("-- Current compiler flags C_FLAGS are: ${C_FLAGS}")

and

cmake . && make

Gives this output:

-- The C compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Current compiler flags CMAKE_C_FLAGS are: 
-- Current compiler flags C_FLAGS are: 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/Projects/cmake-gcc-options-try-c
Scanning dependencies of target cmake_gcc_options_try_c
[ 50%] Building C object CMakeFiles/cmake_gcc_options_try_c.dir/main.c.o
[100%] Linking C executable cmake_gcc_options_try_c
[100%] Built target cmake_gcc_options_try_c

Why CMAKE_C_FLAGS and C_FLAGS are printed as they were undefined?

How to achieve this print on make command:

[ 50%] Building C object CMakeFiles/cmake_gcc_options_try_c.dir/main.c.o
[ 50%] Current compiler flags are: -W -Wall -Wextra -pedantic -pedantic-errors -std=gnu11
[100%] Linking C executable cmake_gcc_options_try_c
[100%] Built target cmake_gcc_options_try_c

?

Update: Viktor Sergienko came with a working solution, but one problem with this it's not so pretty print: enter image description here Any thoughts how to make it to be in format of other prints? E. g. :

[ 50%] Building C object CMakeFiles/cmake_gcc_options_try_c.dir/main.c.o
[100%] Linking C executable cmake_gcc_options_try_c
[100%] Current compiler flags are: -W -Wall -Wextra -pedantic -pedantic-errors -std=gnu11
[100%] Built target cmake_gcc_options_try_c

Second problem is that -std=gnu11 is not printed (but it is enabled with set(CMAKE_C_STANDARD 11) and set(CMAKE_C_STANDARD_REQUIRED ON))

stackoverflower
  • 545
  • 1
  • 5
  • 21
  • 1
    "Why `CMAKE_C_FLAGS` and `C_FLAGS` are printed as they were undefined?" - Variable `CMAKE_C_FLAGS` is just **empty** in your case. It doesn't accumulate values added with `target_compile_options` - the latter options are come in form of target's **properties**. See that question for more info: https://stackoverflow.com/q/39501481/3440745. If you want extract the target's compile definitions (e.g. for print them), you need to extract corresponded properties, like in that answer: https://stackoverflow.com/a/24921921/3440745. – Tsyvarev May 13 '19 at 07:55

1 Answers1

10

Use:

This gave me a ;-list of the options both at configure and compile times:

cmake_minimum_required(VERSION 3.10)
project(cmake_gcc_options_try_c C)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

add_executable(cmake_gcc_options_try_c main.c)

target_compile_options(cmake_gcc_options_try_c 
                       PUBLIC -W -Wall -Wextra -pedantic -pedantic-errors)

get_target_property(MAIN_CFLAGS cmake_gcc_options_try_c COMPILE_OPTIONS)
# also see: COMPILE_DEFINITIONS INCLUDE_DIRECTORIES
message("-- Target compiler flags are: ${MAIN_CFLAGS}")

add_custom_command(TARGET cmake_gcc_options_try_c POST_BUILD
COMMAND echo built with the flags: ${MAIN_CFLAGS})

Update after question was updated: to get C/CXX standard, look up C_STANDARD. If you wonder why CMake sets -gnu variant of the flag, it's because of CXX_EXTENSIONS is ON by default.

Update2: To get the full compiler/linker commands for every source file as a JSON file, set CMAKE_EXPORT_COMPILE_COMMANDS to ON (only works in CMake 3.5+, make and ninja generators). Credit for this piece goes to Florian's comment in this question.

starball
  • 20,030
  • 7
  • 43
  • 238
Victor Sergienko
  • 13,115
  • 3
  • 57
  • 91
  • The update 1) is not set with `target_compile_options`, the update 2) is a different question added post factum; I'm afraid there's no way to access CMake compilation progress in compile time, or print messages through CMake. – Victor Sergienko May 16 '19 at 00:04
  • Yes, you are right, I didn't mentioned that I want all flags to be printed, but if you will take a look on history, in the first version there is a line `[ 50%] Current compiler flags are: -W -Wall -Wextra -pedantic -pedantic-errors -std=gnu11` (I meant it implicitly). Otherwise, what is the point of printing part of the flags? :) Btw, cmake creates a file `flags.make` and there are all flags somehow. – stackoverflower May 16 '19 at 00:13
  • 1
    If you want ALL of the compilation flags, then your question is a duplicate of https://stackoverflow.com/questions/37623354/get-build-command-or-all-compiler-flags-that-will-be-used-to-build-a-target. Printing format or lack of thereof is, though, completely out of scope of the question, especially that you have marked it canonical. `flags.make` is an implementation detail that is different in ninja, and doesn't exist in other generators. – Victor Sergienko May 16 '19 at 00:29
  • _"CMake only sets -gnu variant of the flag"_: that's not true, you can use the non-gnu variant with [CXX_EXTENSIONS](https://cmake.org/cmake/help/latest/prop_tgt/CXX_EXTENSIONS.html) – Tachi May 01 '21 at 11:07
  • Thank you! That's why it was always set. Updating the answer. – Victor Sergienko May 01 '21 at 18:24