# CMAKE\_CXX\_FLAGS - removing defaults, yet allowing user-specified values

**URL:** <https://discourse.cmake.org/t/cmake-cxx-flags-removing-defaults-yet-allowing-user-specified-values/7238>\
**Category:** Code\
**Created:** [January 13, 2023, 9:13am UTC](https://discourse.cmake.org/t/cmake-cxx-flags-removing-defaults-yet-allowing-user-specified-values/7238 "2023-01-13T09:13:53Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![hainest](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hainest/32/2896_2.png) [@hainest](https://discourse.cmake.org/u/hainest)\
**Post date:** [January 13, 2023, 9:13am UTC](https://discourse.cmake.org/t/cmake-cxx-flags-removing-defaults-yet-allowing-user-specified-values/7238/1 "2023-01-13T09:13:53Z")

</div>

I would like to remove the default values from CMAKE\_CXX\_FLAGS while still allowing users to specify values in configuration mode (i.e., `cmake ... -DCMAKE_CXX_FLAGS="..."`).

Clearly, this could be done by just writing to CMAKE\_CXX\_FLAGS, but the general consensus is to never alter CMAKE\_\* variables from within a CMakeLists.txt- which I agree is a good practice.

```cmake
if(CMAKE_CXX_FLAGS)
  # Append user flags
  set(CMAKE_CXX_FLAGS "${MY_FLAGS} ${CMAKE_CXX_FLAGS}") # Booooo!
else()
  set(CMAKE_CXX_FLAGS ${MY_FLAGS})
endif()

```

Ideally, I’d like to do something like this

```cmake
list(APPEND MY_FLAGS "-fpie")
if(CMAKE_CXX_FLAGS)
  list(APPEND MY_FLAGS ${CMAKE_CXX_FLAGS})
  unset(CMAKE_CXX_FLAGS)
endif()
add_executable(test test.cpp)
target_compile_options(test PRIVATE $<$<CONFIG:RELWITHDEBINFO>:${MY_FLAGS}>)

```

But using this gives

```bash
$ cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_CXX_FLAGS="-g3"
  /usr/bin/c++ -g3 -O2 -g -DNDEBUG -fpie -g3 ...

```

I would expect it to generate

```bash
/usr/bin/c++ -fpie -g3 ...

```

From [Strictly appending to CMAKE\_\<LANG\>\_FLAGS](https://discourse.cmake.org/t/strictly-appending-to-cmake-lang-flags/6478/8), I understand that `CMAKE_CXX_FLAGS_RELWITHDEBINFO` is essentially being built using `set(CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_INIT} "-O2 -g -DNDEBUG")`. In the case above, `-g3` will override `-g` (at least on all compilers I’m aware of), so that’s not a problem. But I need to get rid of `-DNDEBUG`. I could do

```cmake
list(APPEND MY_FLAGS "-fpie -UDNDEBUG")

```

but then I’d need to know all of the possible defaults CMAKE uses. At this point, I gave up and just overwrote CMAKE\_CXX\_FLAGS\_RELWITHDEBINFO.

```cmake
list(APPEND MY_FLAGS "-fpie")
if(CMAKE_CXX_FLAGS)
  list(APPEND MY_FLAGS ${CMAKE_CXX_FLAGS})
  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO ${MY_FLAGS})
endif()
add_executable(test test.cpp)

```

but this gives

```bash
/usr/bin/c++ -g3 -fpie;-g3 -fpie -g3 ...

```

which is… neat. I manually convert the list to a spaced string

```cmake
list(APPEND MY_FLAGS "-fpie")
if(CMAKE_CXX_FLAGS)
  list(APPEND MY_FLAGS ${CMAKE_CXX_FLAGS})
  list(JOIN MY_FLAGS " " _f)
  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO ${_f})
endif()
add_executable(test test.cpp)

```

which gives what I expect

```bash
/usr/bin/c++ -g3 -fpie ...

```

Am I just left to overwrite `CMAKE_CXX_FLAGS_RELWITHDEBINFO`? I’d like to get around it, if at all possible.

---

<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:** [January 15, 2023, 2:50am UTC](https://discourse.cmake.org/t/cmake-cxx-flags-removing-defaults-yet-allowing-user-specified-values/7238/2 "2023-01-15T02:50:06Z")

</div>

> [@hainest](#):
>
> `list(APPEND MY_FLAGS "-fpie -UDNDEBUG")`

Flags are strings; options are list. Use `string(APPEND)` here (this resolves the `;` instance).

Otherwise, this behavior of CMake is very ancient and there have been efforts to help fix this (e.g., the MSVC runtime selection flags now being a target property). Other flags have yet to follow suit. For the `-fpie` flag specifically, there is already such a property: [`POSITION_INDEPENDENT_CODE`](https://cmake.org/cmake/help/latest/prop_tgt/POSITION_INDEPENDENT_CODE.html). The [`CheckPIESupported`](https://cmake.org/cmake/help/latest/module/CheckPIESupported.html) module is also relevant and has an example.

However, it doesn’t seem to support per-config management (i.e., genex support). That’s probably worth a feature request.
