0

I'm writing a CMakeLists.txt for a project of mine, and I need to add (under certain conditions which don't matter here) a compiler flag to $CMAKE_CXX_FLAGS (and it doesn't matter that it's C++, it could C, or Fortran or what-not). Now, I can do it this way:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_FLAG_HERE}") 

or, to be more modern:

string(APPEND CMAKE_CXX_FLAGS " ${EXTRA_FLAG_HERE}") 

but if the flag is already in there, I don't want to add it twice. Now, I could do

if(NOT string(FIND CMAKE_CXX_FLAGS "${EXTRA_FLAG_HERE}") string(APPEND CMAKE_CXX_FLAGS " ${EXTRA_FLAG_HERE}") endif() 

Edit: but as @Fred points out, this won't actually avoid duplicates if that flag is introduced by CMake otherwise than through $CMAKE_CXX_FLAGS.

I was hoping there's something "built-in" which adds a flag while assuring no duplication (including being more robust against occurrences of ${EXTRA_FLAG} which within the argument of another flag, e.g. in a -D flag).

So, what do I do?

11
  • Which compiler flag? Commented Dec 26, 2018 at 21:18
  • @CinderBiscuits: Not --std or one of those things you set with a special CMake variable. Commented Dec 26, 2018 at 21:46
  • 2
    Any reason you're avoiding target_compile_options? The modern approach to CMake is to model your requirements via properties, which can be scoped, and avoid variables. Commented Dec 26, 2018 at 21:57
  • 1
    You could add an INTERFACE with the given property added under your conditions, and link it to the given targets. In this way, the properties are propagated without having to manage a list of flags. Commented Dec 26, 2018 at 22:03
  • 1
    @einpoklum There is no built in way to prevent a flag being added twice. Your method won't work if it is a flag that is automatically added by CMake as a default flag. Commented Dec 27, 2018 at 4:18

1 Answer 1

1

There are many sources of flags in CMake, not all of which are exposed to the CMakeLists.txt author (e.g. the /SUBSYSTEM:... flags on MSVC).

Some sources, like the target properties are automatically de-duplicated, so there's no need to worry there. In the case of linker flags, de-duplication can actually be an issue, so there's a special syntax for preserving a flag when calling target_link_options: prefix FLAG with SHELL: as in target_link_options(tgt PRIVATE "SHELL:FLAG").

On the other hand, if you want to avoid adding a flag to CMAKE_<LANG>_FLAGS[_<CONFIG>], then you can just do a regex check before adding a flag; for example:

if (NOT CMAKE_CXX_FLAGS MATCHES "-flag") string(APPEND CMAKE_CXX_FLAGS " -flag") endif () 

But unfortunately, there's just no general way to inspect every flag CMake will add to a target's command line during configure time (due to lazily evaluated generator expressions, if for no other reason).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.