3

Lets say I want to compile all the code with /W4 for a project with three libs/targets.

A -> B -> C

What is the best practice to apply the flag project-wide?

I can think of two approaches:

  1. Set TARGET_COMPILE_OPTIONS(C PUBLIC "\W4") in C's CMake (which is a core library for the whole project) and every other library that depends on C will inherit the flag via: TARGET_LINK_LIBRARIES(B C)
    Pro: new libraries will inherit the flag automatically.
    Con: compile flags for a project are implicit.

  2. Specify compile options for every target/lib separately.
    Pro: the flags are explicitly specified and manageable separately for each lib.
    Con: the flags need to be (not forgotten to be) set for a new lib.

nVxx
  • 661
  • 7
  • 20
  • 1
    Does `TARGET_LINK_LIBRARIES` really propagate options set with `TARGET_COMPILE_OPTIONS`? – user7860670 Dec 14 '18 at 09:55
  • @VTT It propagates everything that is public and interface (I think), include directories, didn't know about the compiler flags though... Seems fragile to me. – Matthieu Brucher Dec 14 '18 at 09:57
  • I thought it works the other way. A needs a certain option, the other not. You Must propagate the options of A to B and C to be able to link. – Sandburg Dec 23 '20 at 08:00

1 Answers1

2

Third option, change the compiler flags.

For instance, when I want to activate address sanitizer on the whole project, I do:

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address -static-libasan")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address -static-libasan")

The current idiomatic way of setting flags for the current folder and subfolder is to use

add_compile_options(-fsanitize=address) 
Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62
  • but that contradicts with the modern CMake approach to structure everything through `target`s and `properties` – nVxx Dec 14 '18 at 11:55
  • Yes and no. You can always you the global property for compiler flags instead of each target. I'll look up the new equivalent. I agree that I should put the new style when possible. – Matthieu Brucher Dec 14 '18 at 11:58
  • Added the new policy – Matthieu Brucher Dec 14 '18 at 12:04
  • `add_compile_options` still operates on directory and not target level, basically it's just a cleaner syntax for calling separate `SET`s on flags. – nVxx Dec 14 '18 at 12:19
  • Yes, I agree, still works on directories and not on targets. But in this case, for global settings, you don't want to set on targets, but globally. And it doesn't modify the flags directly and handles generators, so I'd say it's the modern way compared to setting variables (see also https://stackoverflow.com/questions/39501481/difference-between-add-compile-options-and-setcmake-cxx-flags). – Matthieu Brucher Dec 14 '18 at 13:16