Difference between add_compile_options and SET(CMAKE_CXX_FLAGS...)
Asked Answered
I

1

44

This question is related to Instruct Cmake to use CXX and CXXFLAGS when driving link? In the former question, we are trying to instruct CMake to use CXXFLAGS when it invokes the linker.

add_compile_options

We found that the following code

if (CMAKE_VERSION VERSION_LESS 2.8.12)
    add_definitions(-foo)
else()
    add_compile_options(-foo)
endif()

message(STATUS, "CXXFLAGS: ${CMAKE_CXX_FLAGS}")

produces the output

CXXFLAGS:

SET CMAKE_CXX_FLAGS

We found that the following code

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -foo" )

message(STATUS, "CXXFLAGS: ${CMAKE_CXX_FLAGS}")

produces the output

CXXFLAGS: -foo

Questions

We found CMake would create object files using -foo in both cases. So -foo is definitely making its way into CXXFLAGS.

What is the difference between the first set of CMake code and the second set of CMake code?

Why is CMAKE_CXX_FLAGS unset in one instance, and set in the other instance?

Immobility answered 15/9, 2016 at 0:20 Comment(2)
In case versions matter: cmake --version returns cmake version 3.6.2.Immobility
@usr1234567 - Yeah, sorry about the questions. The folks who wanted CMake are not maintaining it, so the responsibility now falls on me. I know nearly nothing about CMake because I use GNUmake and write my own makefiles. I regret accepting those CMake patches... And yes, I will get the questions edited. Sorry about that.Immobility
C
49
  • CMAKE_CXX_FLAGS is used to add flags for all C++ targets. That's handy to pass general arguments like warning levels or to selected required C++ standards. It has no effect on C or Fortran targets and the user might pass additional flags.

  • add_compile_options adds the options to all targets within the directory and its sub-directories. This is handy if you have a library in a directory and you want to add options to all the targets related to the library, but unrelated to all other targets. Additionally, add_compile_options can handle arguments with generator expressions. The documentation explicitly states, that

This command can be used to add any options, but alternative commands exist to add preprocessor definitions (target_compile_definitions() and add_definitions()) or include directories (target_include_directories() and include_directories()).

  • add_definitions is intended to pass pre-processor values of the type -DFOO -DBAR=32 (/D on Windows) which defines and sets pre-processor variables. You could pass any flag, but the flags of the above form are detected and added to [COMPILE_DEFINITIONS][2] property, which you can later read and change. Here, you can use generator expressions, too. The documentation mentions scopes for directories, targets and source files.

For a given target, CMake will collect all flags from CMAKE_CXX_FLAGS, the target's and directory's COMPILE_DEFINITIONS and from all add_compile_options which affect the target.
CMAKE_CXX_FLAGS are not altered by the other commands or vice versa. This would violate the scope of these commands.

Changsha answered 15/9, 2016 at 7:41 Comment(5)
Thanks @usr1234567. At the call site, when CMAKE_CXX_FLAGS was printed with message(STAUS, ...), why did CMake not yield the values added with target_compile_definitions and add_definitions? Why were they not printed?Immobility
@jww: Because CMAKE_CXX_FLAGS doesn't accumulate values added with target_compile_definitions and add_definitions. It is generator who forms compiler call and collects all its options: from variables CMAKE_CXX_FLAGS, CMAKE_CXX_FLAGS_<CONFIG>, from target's property COMPILE_DEFINITION and so on.Cockalorum
@jww: I added a paragraph concerning your question.Changsha
Thanks again @usr1234567. One last question then with respect to Make variables and generators... If the generators won't yield the values, then how does one do things like instruct CMake to use accumulated flags during linking?Immobility
@jww: That's a question of it's own.Changsha

© 2022 - 2024 — McMap. All rights reserved.