# CFLAGS and child CMakeFiles.txt

**URL:** https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781
**Category:** Usage
**Created:** [January 6, 2024, 12:48am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781 "2024-01-06T00:48:40Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![SparkyNZ](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sparkynz/32/3930_2.png) [@SparkyNZ](https://discourse.cmake.org/u/SparkyNZ)
#### Post date: [January 6, 2024, 12:48am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/1 "2024-01-06T00:48:40Z")

</div>

Is this the correct way to add a compiler flag to CFLAGS:  
`list (APPEND CFLAGS "-Wdeprecated-copy")`

I have seen mention of using “CFLAGS+=” but I wasn’t sure upon the syntax for that.

The reason I ask is that in one of my sub-project source compilations, I’m still seeing:  
`warning: implicitly-declared 'constexpr fabgl::Rect& fabgl::Rect::operator=(const fabgl::Rect&)' is deprecated -Wdeprecated-copy`

If I’ve specified the “list” command above, shouldn’t CFLAGS contain -Wdeprecated-copy when accessed from child CMakeFiles.txt files? Or perhaps I haven’t specified the flag to remove the warning correctly?

In other words, do top-level CFLAGS definitions get handed down to sub-folder CMakeFiles.txt?

This is possibly a tricky one because I’m not explicitly including the child CMakeFiles.txt. It gets picked up automatically in the ESP32 IDF environment. I don’t know if CFLAGS get cascaded in that case or not. (I’m not using **include()** or **add\_subdirectory()** in the top CMakeFiles.txt)

Apologies if this is more of an ESP32 IDF environment question.

---

<div class="post-metadata">

### Author: ![dnglaze](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/d/74df32/32.png) [@dnglaze](https://discourse.cmake.org/u/dnglaze)
#### Post date: [January 6, 2024, 2:02am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/2 "2024-01-06T02:02:32Z")

</div>

You’ll want to look into [target\_compile\_options](https://cmake.org/cmake/help/latest/command/target_compile_options.html#command:target_compile_options) to help you with that.

```cmake
target_compile_options(MyTarget PRIVATE "-Wdeprecated-copy")

```

It should append by default to the list of current options. `CFLAGS`, I don’t think, is something that CMake pays attention to once in the CMake files. There’s an old variable called [`CMAKE_CXX_FLAGS` and `CMAKE_C_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html#variable:CMAKE_%3CLANG%3E_FLAGS) that can be used for directory inheritance, but that’s not the recommended practice for new projects. You’ll want to use `target_compile_options`.

---

<div class="post-metadata">

### Author: ![SparkyNZ](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sparkynz/32/3930_2.png) [@SparkyNZ](https://discourse.cmake.org/u/SparkyNZ)
#### Post date: [January 6, 2024, 3:36am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/3 "2024-01-06T03:36:31Z")

</div>

@dnglaze hmmm.. I’m not sure how I can do this with the IDF environment. The top level CMakeLists.txt only has a minimum of the below 3 commands:

# The following five lines of boilerplate have to be in your project’s

# CMakeLists in this exact order for cmake to work correctly

```auto
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(paul_fabgl)

```

I tried adding:

```auto
#target_compile_options(MyTarget PRIVATE "-Wdeprecated-copy")
target_compile_options(paul_fabgl PRIVATE "-Wdeprecated-copy")

```

Output:

```auto
[cmake] CMake Error at CMakeLists.txt:10 (target_compile_options):
[cmake] Cannot specify compile options for target "paul_fabgl" which is not built
[cmake] by this project.

```

..but it didn’t like either of those commands. I have no idea what the target is supposed to be. The docs for **target\_compile\_options** state that there needs to be an **add\_executable** command to define the target.

If I do add an **add\_executable** command, then CMake expects me to declare sources for the target etc

I’ve even tried:

```auto

set(CMAKE_CXX_FLAGS
    "-Wdeprecated-copy")

set(CMAKE_C_FLAGS
    "-Wdeprecated-copy")

```

..in both top level and lower-level CMakeLists.txt. I know they’re supposed to be deprecated but thought I’d give them a try anyway.

I should probably post something on the ESP-IDF forum.. Just getting conscious that I have more posts there than enough at the moment. 🙂

---

<div class="post-metadata">

### Author: ![dnglaze](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/d/74df32/32.png) [@dnglaze](https://discourse.cmake.org/u/dnglaze)
#### Post date: [January 6, 2024, 4:41am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/4 "2024-01-06T04:41:41Z")

</div>

Yeah, you’ll need to have the target declared, through something like `add_executable` for `target_compile_options` to work. Your top level CMake is a little odd. The order is usually

```cmake
cmake_minimum_required()
project()
add_executable()
include()

```

What CMake is telling you is that the target hasn’t been defined. Keep in mind that the project command doesn’t create any targets. You still need to define the target. You might consider running through some tutorials like [this one](https://cmake.org/cmake/help/latest/guide/tutorial/A%20Basic%20Starting%20Point.html) or walk through [the tutorials](https://cmake.org/cmake/help/latest/guide/tutorial/index.html) to get a better grasp of how CMake does its magic.

---

<div class="post-metadata">

### Author: ![SparkyNZ](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sparkynz/32/3930_2.png) [@SparkyNZ](https://discourse.cmake.org/u/SparkyNZ)
#### Post date: [January 6, 2024, 5:41am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/5 "2024-01-06T05:41:11Z")

</div>

I think the secret probably likes in the **idf.py** script. That’s supposed to be a wrapper to CMake… So maybe there’s a command-line option to specify the target so CMake. I’ll take a peek there…

---

<div class="post-metadata">

### Author: ![SparkyNZ](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sparkynz/32/3930_2.png) [@SparkyNZ](https://discourse.cmake.org/u/SparkyNZ)
#### Post date: [January 6, 2024, 5:57am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/6 "2024-01-06T05:57:24Z")

</div>

@dnglaze …yeah… thought as much:

```auto
def get_target(path: str, sdkconfig_filename: str='sdkconfig') -> Optional[str]:
    path = os.path.join(path, sdkconfig_filename)
    return get_sdkconfig_value(path, 'CONFIG_IDF_TARGET')

```

…and in my **sdkconfig** file I have:

`CONFIG_IDF_TARGET="esp32"`

So… I tried this and it seems happy as far as running CMake is concerned:

```auto
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(paul_fabgl)
add_executable(esp32)
target_compile_options(esp32 PRIVATE "-Wdeprecated-copy")

```

That’s one mystery solved - we now know what the target is. I still get the compiler warning though. Oh well… 🙂

---

<div class="post-metadata">

### Author: ![SparkyNZ](https://discourse.cmake.org/user_avatar/discourse.cmake.org/sparkynz/32/3930_2.png) [@SparkyNZ](https://discourse.cmake.org/u/SparkyNZ)
#### Post date: [January 6, 2024, 6:00am UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/7 "2024-01-06T06:00:28Z")

</div>

Actually no… it didn’t work… Oh well

---

<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 11, 2024, 1:38pm UTC](https://discourse.cmake.org/t/cflags-and-child-cmakefiles-txt/9781/8 "2024-01-11T13:38:21Z")

</div>

`CFLAGS` is an environment variable that is used to initialize `CMAKE_C_FLAGS`. This is done when the C language is enabled; not per-directory. It is also typically an end-user setting rather than something a project should be interfering with. Instead, set your own flags via `target_compile_options` (or `add_compile_options` for global ones, but `target_` variants are almost always preferred).
