espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.44k stars 7.25k forks source link

cmake -D settings are not passed to components (IDFGH-13793) #14651

Open KammutierSpule opened 1 day ago

KammutierSpule commented 1 day ago

Answers checklist.

IDF version.

5.3

Operating System used.

Linux

How did you build your project?

VS Code IDE

If you are using Windows, please specify command line type.

None

What is the expected behavior?

I expected that the defined option on main cmakefile or via command line, eg: cmake -DOPTION=ON to be passed to components and main component

What is the actual behavior?

At this moment, only the main CMakeLists.txt file receive this options (I test) but they don't appear on components or main

Steps to reproduce.

  1. on main root CMakeLists.txt add option(BUILD_OPTION "Set my option define" OFF)
  2. add something to verify that is is detected on main root, but not on components
  3. run the build of your project such way that it adds -DBUILD_OPTION=ON ...

Build or installation Logs.

No response

More Information.

No response

igrr commented 1 day ago

Could you please show the part of your component CMakeLists file which uses the BUILD_OPTION?

For example, modifying hello_world example with option(...) and the following works as expected:

idf_component_register(SRCS "hello_world_main.c"
                    PRIV_REQUIRES spi_flash
                    INCLUDE_DIRS "")

message(STATUS "BUILD_OPTION from main/CMakelists.txt: ${BUILD_OPTION}")
KammutierSpule commented 1 day ago
option(BUILD_OPTION "Set DEBUG define" OFF)
message(STATUS "BUILD_OPTION from root CMakelists.txt: ${BUILD_OPTION}")
message(STATUS "BUILD_OPTION from main/CMakelists.txt: ${BUILD_OPTION}")

I got:

-- BUILD_OPTION from root CMakelists.txt: ON
...
Processing 2 dependencies:
[1/2] espressif/esp_modem (1.1.0)
[2/2] idf (5.3.0)
-- BUILD_OPTION from main/CMakelists.txt: 
igrr commented 1 day ago

message(STATUS "BUILD_OPTION from main/CMakelists.txt: ${BUILD_OPTION}")

Is that the entire contents of your main/CMakeLists.txt? If no, could you please post the complete file?

I am guessing that the issue you are running into is that component CMakeLists files are evaluated twice: first time in script mode, to get the REQUIRES and PRIV_REQUIRES keyword arguments from idf_component_register, then second time normally via add_subdirectory. If your message(STATUS ...) occurs before idf_component_register, then it should be printed twice: first time with the option not defined (because we are in script mode) and the second time with the option defined.

KammutierSpule commented 1 day ago

I don't have a project to share at moment.

then it should be printed twice: first time with the option not defined (because we are in script mode) and the second time with the option defined.

I can confirm you:

[2/2] idf (5.3.0)
-- BUILD_OPTION from main/CMakelists.txt: 
...
-- BUILD_OPTION from main/CMakelists.txt: ON

So what does it mean?

Am I able to create a workspace project with cmake build options without create a new folder/repository with a new project for every option?

igrr commented 1 day ago

Am I able to create a workspace project with cmake build options without create a new folder/repository with a new project for every option?

I'm sorry, I don't understand what you mean. Could you show an example of how you actually use this BUILD_OPTION in main/CMakeLists.txt? Then I might be able to suggest a solution.

KammutierSpule commented 1 day ago

Am I able to create a workspace project with cmake build options without create a new folder/repository with a new project for every option?

I'm sorry, I don't understand what you mean. Could you show an example of how you actually use this BUILD_OPTION in main/CMakeLists.txt? Then I might be able to suggest a solution.

I have different uses cases: Debug/Release profiles, UnitTests profiles, different options that require different files to be included.. (different components/modules too)

igrr commented 1 day ago

Regarding different components, you can use the following in project CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)

option(COMPONENT_X_INCLUDED "Include feature X" OFF)
set(COMPONENTS main)
if(COMPONENT_X_INCLUDED)
  list(APPEND COMPONENTS component_x)
endif()

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

project(your-project)

For adding source files or compilation options, you can use the following in your component CMakeLists file:

idf_component_register(SRCS "hello_world_main.c"
                    PRIV_REQUIRES spi_flash
                    INCLUDE_DIRS "")

if(ENABLE_DEBUG)   # assuming you have defined ENABLE_DEBUG option in project CMakeLists file
  target_compile_definitions(${COMPONENT_LIB} PRIVATE ENABLE_DEBUG=1)
  target_sources(${COMPONENT_LIB} PRIVATE debug_helpers.c)
endif()

and so on.

KammutierSpule commented 1 day ago

Do you have more resources to read on how to fine control selected COMPONENTS to the build?

set(COMPONENTS main)
if(COMPONENT_X_INCLUDED)
  list(APPEND COMPONENTS component_x)
endif()

Does this mean if I use it, it will stop from autodetect main and components on the subfolders?

igrr commented 1 day ago

No, this way main component is still going to be found (it is listed in COMPONENTS list). Also any components that main depends on will be included into the build.

You can read about this in the docs: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#including-components-in-the-build and the nearby sections.

Edit: you may also check out the talk about IDF build system from the recent DevCon as well as the slides, this might answer some of your questions.