Setting CPPFLAGS with CMake and idf.py

william.ferguson.au
Posts: 107
Joined: Wed Jan 02, 2019 8:55 am

Setting CPPFLAGS with CMake and idf.py

Postby william.ferguson.au » Sun Apr 28, 2019 11:45 am

I've included an external library (ArduinoWebSockets) as a component by including it as a git submodule.
The component define various macros depending upon the value of a compiler option that is normally set via CPPFLAGS.

This is building fine using make under MSYS32, but want to transition to CMake so I can use CLion as IDE.

Have read https://docs.espressif.com/projects/esp ... ompilation

But after trying many different combos, while I can convince the IDE that the compiler option has been set, building on the command line with "idf.py build" doesn't pass the option to the compiler.

The compiler option is "ESP32", I have tried all of the below in the CMakeLists.txt for both component and project:

Code: Select all

# Trying to configure CPPFLAGS with -DESP32 so that ArduinoWebSocket uses the correct macros.
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system-cmake.html#controlling-component-compilation
component_compile_options("-DESP32")
component_compile_definitions("-DESP32")
set_source_files_properties(src/WebSockets.h PROPERTIES COMPILE_FLAGS -DESP32)

# https://cmake.org/cmake/help/v3.5/command/target_compile_options.html
# https://cmake.org/cmake/help/v3.5/command/target_compile_definitions.html#command:target_compile_definitions
target_compile_definitions(arduinoWebsockets PRIVATE "-DESP32")

# https://cmake.org/cmake/help/v3.5/command/add_definitions.html#command:add_definitions
add_definitions(-DESP32)
How do I set CPPFLAGS for a component with idf.py and CMake?

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Setting CPPFLAGS with CMake and idf.py

Postby ESP_Angus » Mon Apr 29, 2019 12:00 am

You should be able to set this in the component CMakeLists.txt file.

I recommend using target_compile_definitions(${COMPONENT_TARGET} PRIVATE "-DESP32") if definition only needs to be set when building the source files in the component, not when including the headers. Or use target_compile_definitions(${COMPONENT_TARGET} PUBLIC "-DESP32") if this macro also needs to be defined when including the public headers, while compiling source files in another component.

If it's not working in the component CMakeLists.txt, it's probably due to the order that the statements are being placed in the CMakeLists.txt file. Any target___() lines have to be placed after the register_component() line in the CMakeLists.txt file.

It's recommended to use ${COMPONENT_TARGET} variable rather than guessing the component library name, which may change in the future.

If this is still not working, please post the full component CMakeLists.txt contents and we can take a look.

william.ferguson.au
Posts: 107
Joined: Wed Jan 02, 2019 8:55 am

Re: Setting CPPFLAGS with CMake and idf.py

Postby william.ferguson.au » Mon Aug 12, 2019 8:41 pm

Angus, I still can't seem to get this to work.

This is the CMakeLists.txt for the component:

Code: Select all

SET (COMPONENT_REQUIRES
        arduino-esp32
        lwip
)

SET (COMPONENT_ADD_INCLUDEDIRS src src/libb64 src/libsha1)
SET (COMPONENT_SRCS
        "src/libb64/cdecode.c"
        "src/libb64/cencode.c"
        "src/libsha1/libsha1.c"
#        "src/SocketIOclient.cpp"
        "src/WebSockets.cpp"
        "src/WebSocketsClient.cpp"
        "src/WebSocketsServer.cpp"
)


register_component()

# To pass in the ESP32 CPPFlag
target_compile_definitions(${COMPONENT_TARGET} PRIVATE "-DESP32")
NB this is the component https://github.com/Links2004/arduinoWebSockets

If I build with the above, then
#elif defined(ESP32)
on line 99 of WebSockets.h evaluates to false and it fails trying to include "Ethernet.h"

If I add
#define ESP32
to the top of WebSockets.h then it builds OK, but warns about ESP32 being redefined several times.

Code: Select all

[5/12] Building CXX object esp-idf/arduinoWebsockets/CMakeFiles/idf_component_arduinoWebsockets.dir/src/WebSocketsClient.cpp.obj
In file included from ../components/arduinoWebsockets/src/WebSocketsClient.cpp:25:0:
../components/arduinoWebsockets/src/WebSockets.h:30:0: warning: "ESP32" redefined
 #define ESP32
 ^
<command-line>:0:0: note: this is the location of the previous definition

william.ferguson.au
Posts: 107
Joined: Wed Jan 02, 2019 8:55 am

Re: Setting CPPFLAGS with CMake and idf.py

Postby william.ferguson.au » Mon Aug 12, 2019 8:44 pm

Scratch that - clearly need some sleep.

As you indicated above - this works.

Code: Select all

# To pass in the ESP32 CPPFlag
target_compile_definitions(${COMPONENT_TARGET} PUBLIC "-DESP32")

ammaree
Posts: 33
Joined: Tue Dec 27, 2016 2:10 am

Re: Setting CPPFLAGS with CMake and idf.py

Postby ammaree » Mon May 11, 2020 7:57 pm

Angus,

Any idea how this is achieved across a whole project. I need to pass a number of -Dxxxxxx definitions to a large number of components, effectively the whole project, but cannot identity what component name to use for the main component. Using IDF master

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: Setting CPPFLAGS with CMake and idf.py

Postby ESP_Angus » Tue May 12, 2020 3:32 am

ammaree wrote:
Mon May 11, 2020 7:57 pm
Any idea how this is achieved across a whole project. I need to pass a number of -Dxxxxxx definitions to a large number of components, effectively the whole project, but cannot identity what component name to use for the main component. Using IDF master
Hi Ammaree,

There's two ways to achieve this, the best probably depends on how you want to structure the components.

First way, component-focused

If you add a line like William did, target_compile_definitions(${COMPONENT_TARGET} PUBLIC "-Dxxxx") to one component's CMakeLists.txt file then every other component that can include the first component's header files will also have its source files compiled with this flag.

Note that in the CMake Build System components don't automatically all include each other, they have to declare which components they require. So any component whose source files should be built with these definitions need to REQUIRE the component that defines them (either publicly or privately, public requirements are recursive as well. The link to the docs has more info.)

This is useful for a compile definition which is associated with a particular component, but might need to be defined as part of that component's public interface to other components that include it, as well.

Second way, project-focused

You can use a more universal CMake add_compile_definitions in the top-level project CMakeLists.txt file, ie

Code: Select all

include($ENV{IDF_PATH}/tools/cmake/project.cmake)

add_compile_definitions(xxxxx)
add_compile_definitions(yyyyy=1)

project(hello-world)
These definitions will be set for the entire project (ie all source files in all components, including internal ESP-IDF components.)

Note that the lines adding the definitions need to be placed before the project() line.

Who is online

Users browsing this forum: No registered users and 124 guests