Observation on compiler options


I’m new to CMake and I have started experimenting with it by converting my hand coded make files into CMakeLists.txt after having read the book Professional CMake: A Practical Guide.

I’m using CMake 3.17.3 that comes with Fedora 32 Linux and I’m building a C++20 executable using GCC 10.1.1. After running CMake, I tried to determine what compiler and linker options were used.

This is the value of CMAKE_CXX_FLAGS_RELEASE:


This is what I found in the file called flags.make:

CXX_FLAGS = -O2 -DNDEBUG -m64 -Wall -Werror -std=c++2a



And this is what I found in the file called link.txt:

/usr/bin/c++ -O2 -DNDEBUG -m64 -Wl,–no-undefined CMakeFiles/test_builtins.dir/src/test_builtins.cpp.o -o bin/test_builtins -Wl,-rpath,/usr/local/lib64 /usr/local/lib64/libboost_unit_test_framework.so.1.73.0

Based on the above observations, CMake appears to be re-using the compiler options in the linker command. I have been hand coding make files for a long time now and have never needed to re-use compiler options on the linker command for GCC. Note that some of the additional compiler and linker options I added using target_compile_definitions(), target_compile_options() and target_link_options().

Is this going to be the behavior of CMake for all Unix like platforms?

Kind regards,

Just found out that the same thing happens when building a shared library. The compile options contained in CMAKE_CXX_FLAGS_RELEASE are also used in the linker command.

This will only occur for flags that are set via the CMAKE_CXX_FLAGS and CMAKE_CXX_FLAGS_<CONFIG>.

Compiler flags and options that are provided via target_compile_definitions and target_compile_options will only passed when doing object compilation.

Linker flags provided by target_link_options will only be passed when doing a link step.

This behavior is consistent across all CMake supported platforms, generators, and compilers. The reasoning for this is historical and changing this behavior would break numerous projects.