# How to remove compile flags

**URL:** https://discourse.cmake.org/t/how-to-remove-compile-flags/6693
**Category:** Code
**Created:** [October 19, 2022, 10:13am UTC](https://discourse.cmake.org/t/how-to-remove-compile-flags/6693 "2022-10-19T10:13:07Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [October 19, 2022, 10:13am UTC](https://discourse.cmake.org/t/how-to-remove-compile-flags/6693/1 "2022-10-19T10:13:07Z")

</div>

Hi all,

In the codebase in which I’m currently working, there are two scenarios where I might want to remove compile flags from a target:

1. Some targets want almost all the compile flags given by CMAKE\_CXX\_FLAGS and friends. However, I need to remove or disable certain flags for those targets,
2. Some targets require their own entirely custom set of build flags, and don’t want to use CMAKE\_CXX\_FLAGS (and friends) at all.

For (1), the best idea I have is to get CMAKE\_CXX\_FLAGS and friends, manually remove the flags I don’t want, and re-set those variables on a directory level. This is cumbersome, because the number of flags that need to be changed increases linearly with the number of CMAKE\_BUILD\_TYPEs. It’s also prone to break in future when new build types are added. Is there a cleaner way to achieve this?

(Side note - the scoping rules are also not clear to me. If I set CMAKE\_CXX\_FLAGS as a non-cache variable, does it apply to all targets in the current directory and below? If I have two targets in the same directory, declare one, then change CMAKE\_CXX\_FLAGS and declare the other, are my new CMAKE\_CXX\_FLAGS applied to just the second target?).

For (2) the same work-around applies, but I wonder if there’s some way to entirely exclude a target from CMAKE\_CXX\_FLAGS, CMAKE\_BUILD\_TYPE, etc.?

Thanks,  
Tom

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [October 20, 2022, 5:16pm UTC](https://discourse.cmake.org/t/how-to-remove-compile-flags/6693/2 "2022-10-20T17:16:13Z")

</div>

`CMAKE_CXX_FLAGS` apply to all targets. What it sounds like might work better for you is to have `CMAKE_CXX_FLAGS` be as small as possible and then you add flags through something like this:

```cmake
add_library(myflags INTERFACE)
target_compile_options(myflags
  INTERFACE
    -flag-for-all-targets
    "$<$<TARGET_PROPERTY:needs_a_flag>:-flag-for-specific-targets>")
# …
add_library(needs_more_flags …)
set_property(TARGET needs_more_flags PROPERTY needs_a_flag 1)

```

Instead of property-based flag selection, you can also use separate targets.

---

<div class="post-metadata">

### Author: ![tom](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/t/3d9bf3/32.png) [@tom](https://discourse.cmake.org/u/tom)
#### Post date: [October 21, 2022, 10:23am UTC](https://discourse.cmake.org/t/how-to-remove-compile-flags/6693/3 "2022-10-21T10:23:42Z")

</div>

I’m not sure how well whitelisting flags like that will work for me. If I’ve understood correctly, the process for removing a flag “foo” from the “frobnicator” target would be something like this:

1. Remove foo from the flags that are applied to all targets (CMAKE\_CXX\_FLAGS at the moment, or the myflags INTERFACE in your example),
2. Add the above generator expression for the foo flag,
3. Add the needs\_foo property to every target apart from frobnicator.

The trouble is my code base is very large, so step (3) would involve adding a property to thousands of targets. If we then ever wanted to re-instate the foo flag, we’d have to remove that property from thousands of targets.

Is there no blacklisting solution available? I’ve got a vague idea that we could write a function a bit like this, but it seems inelegant… I’m also not sure that CMAKE\_CXX\_FLAGS would actually populate those target properties.

```auto
function(remove_compiler_flag target flag)
  foreach(property IN COMPILE_DEFINITIONS COMPILE_FEATURES COMPILE_FLAGS COMPILE_OPTIONS etc)
    # Get the target property
    # If the specified flag is in that list, remove it and re-set the target property
  endforeach()
endfunction()

```

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [October 21, 2022, 11:42am UTC](https://discourse.cmake.org/t/how-to-remove-compile-flags/6693/4 "2022-10-21T11:42:44Z")

</div>

> [@tom](#):
>
> If we then ever wanted to re-instate the foo flag, we’d have to remove that property from thousands of targets.

You can use `$<NOT>` around the property (might need `$<NOT:$<BOOL:…>>`) to negate it if that makes more sense.

> [@tom](#):
>
> I’ve got a vague idea that we could write a function a bit like this, but it seems inelegant…

When you encounter a genex, you have no idea what to do in this loop; you’ll never get “just a flag” with such things in this loop. Also note that flags can be added to targets later than this loop too.
