# How do I replace the compiler options for one target?

**URL:** https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815
**Category:** Usage
**Created:** [April 3, 2023, 8:17pm UTC](https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815 "2023-04-03T20:17:31Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![RobN](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/r/e9bcb4/32.png) [@RobN](https://discourse.cmake.org/u/RobN)
#### Post date: [April 3, 2023, 8:17pm UTC](https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815/1 "2023-04-03T20:17:31Z")

</div>

I have a multi-directory project with a lot of CMakeLists.txt files. At the root file I have this:

```cmake
set(CMAKE_CXX_FLAGS "-Wall -Wimplicit-fallthrough -Werror=return-type")

```

I’d like to completely replace that in a subdirectory, for a certain target. I tried lines 1 or 2 here:

```auto
add_executable(foo foo.cc)
set_target_properties(foo PROPERTIES COMPILE_OPTIONS "-g") # 1
target_compile_options(foo PRIVATE "-g") # 2

```

Both of those led to a build where the `clang++` command has the `-g` appended to the previous flags. How to I _replace_, not append, to the flags? Am I not setting them in the right way to begin with?

thanks,  
Rob

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [April 3, 2023, 10:31pm UTC](https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815/2 "2023-04-03T22:31:13Z")

</div>

Don’t modify `CMAKE_CXX_FLAGS` in your project. Leave variables like those for the user to manipulate. If the project needs to add flags project-wide, it can use `add_compile_options()` from the top level `CMakeLists.txt` instead. If you need to leave out some of those options for a specific target, then that suggests those flags shouldn’t have been applied project-wide to begin with. That said, there may be scenarios where that is justified (and I have had to do this before myself). If you’ve set a common set of options at the top level, you could search for those specific options in the `COMPILE_OPTIONS` directory property in a particular target’s `CMakeLists.txt` and remove them from that property. This assumes you want to remove those options for all targets in that `CMakeLists.txt` file’s directory scope. That’s the tradeoff to using this approach. It’s also quite fragile, because you’re assuming contents of those directory properties. It gets much worse if you start mixing in generator expressions, etc. Consider very carefully if this is really what you want to do before you commit to this approach.

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [April 3, 2023, 10:33pm UTC](https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815/3 "2023-04-03T22:33:10Z")

</div>

I should point out that the `COMPILE_OPTIONS` directory property is only used to initialise the `COMPILE_OPTIONS` property of targets created in that directory scope or below. Rather than modifying the directory property, you could just modify the target property instead if you only wanted to adjust the flags for that one target.

---

<div class="post-metadata">

### Author: ![RobN](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/r/e9bcb4/32.png) [@RobN](https://discourse.cmake.org/u/RobN)
#### Post date: [April 3, 2023, 11:38pm UTC](https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815/4 "2023-04-03T23:38:54Z")

</div>

Thanks!

> [@craig.scott](#):
>
> Don’t modify `CMAKE_CXX_FLAGS` in your project. […]

Is that rule about vars starting with `CMAKE_`, or just that one? My top level file has some others as well.

Some of these seem like they should be in a “toolchain” file, but I’m using vcpkg and last I checked I’m supposed to point `-DCMAKE_TOOLCHAIN_FILE` at their `vcpkg.cmake` file.

```cmake
set(CMAKE_C_COMPILER ${MY_CLANG_DIR}/bin/clang)
set(CMAKE_CXX_COMPILER ${MY_CLANG_DIR}/bin/clang++)
set(CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS ${MY_CLANG_DIR}/bin/clang-scan-deps)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_EXE_LINKER_FLAGS "-L ${MY_CLANG_DIR}/lib -rpath ${MY_CLANG_DIR}/lib")

```

---

<div class="post-metadata">

### Author: ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)
#### Post date: [April 4, 2023, 9:46am UTC](https://discourse.cmake.org/t/how-do-i-replace-the-compiler-options-for-one-target/7815/5 "2023-04-04T09:46:20Z")

</div>

Avoid setting `CMAKE_<LANG>_FLAGS`, `CMAKE_<LANG>_FLAGS_<CONFIG>`, `CMAKE_<TYPE>_LINKER_FLAGS` or `CMAKE_<TYPE>_LINKER_FLAGS_<CONFIG>` variables in the project. These are for the user to manipulate. For those things, use either the directory or target property manipulation commands like `add_compile_options()`, `add_link_options()`, `target_compile_options()` or `target_link_options()`.

The `CMAKE_<LANG>_STANDARD` flag is more contentious. Personally, I see that as something the project should set, but some people hold strong views that it should be under the user’s control. I understand the arguments for and against. I think the project can and should set it, but that can be done in a way that the user can still override it if they need to build everything with a higher language standard.

Regarding the use vcpkg and wanting to use your own toolchain file, vcpkg provides the `VCPKG_CHAINLOAD_TOOLCHAIN_FILE` variable for that. Or you can just include their toolchain file at the bottom of yours. Both methods are supported by vcpkg.
