CFLAGS and child CMakeFiles.txt

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.

You’ll want to look into target_compile_options to help you with that.

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 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.

1 Like

@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

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

I tried adding:

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

Output:

[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:


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. :slight_smile:

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_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 or walk through the tutorials to get a better grasp of how CMake does its magic.

1 Like

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…

@dnglaze …yeah… thought as much:

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:

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… :slight_smile:

Actually no… it didn’t work… Oh well

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).