Search code examples
ccmakeesp32git-submodules

CMake dynamically include required submodules


I am working on several projects using the ESP32 and VS Code. I have some components which have a few config options in the menuconfig/kconfig. I use the cmakelist to include the needed source files and include folders. That is working perfect. Now I need to do the same for the required submodules/components, because if parts of my software are not active in a special project, I don't need some of them. It is not working the same way as for sources and include directories.

That is what I tried so far. To append the source files and the include dirs is working, but to do the same for the REQUIRES fails. If I directly add the needed components to the REQUIRES it works.

if (CONFIG_COMPONENT_1_ENABLE)
  list(APPEND SOURCES
    "Driver1/driver1.cpp"
  )
  list(APPEND INCLUDES
    "Driver1"
  )
  list(APPEND REQUIRES_LIST
    "driver-SPI"
  )
endif()

if (CONFIG_COMPONENT_2_ENABLE)
  list(APPEND SOURCES
    "Driver2/driver2.cpp"
  )
  list(APPEND INCLUDES
    "Driver2"
  )
  list(APPEND REQUIRES_LIST
    "driver-UART"
  )
endif()


idf_component_register(
SRCS
  "messenger.cpp"
  ${SOURCES}
INCLUDE_DIRS
  "."
  "clients"
  ${INCLUDES}
REQUIRES
  "driver"
  ${REQUIRES_LIST}
)

Solution

  • In ESP-IDF's build system, the REQUIRES and PRIV_REQUIRES directives are processed during the initial parsing of the CMakeLists.txt files, before the project's configuration options (like those set in menuconfig) are applied. This means that attempting to conditionally modify the REQUIRES list based on configuration options CONFIG_* will not work as intended, because these configuration options are not yet defined at the time REQUIRES is evaluated. https://esp32.com/viewtopic.php?t=18524

    To manage component dependencies conditionally based on configuration options, you can use the idf_component_optional_requires function (on the previous site web). This function allows you to specify optional dependencies that are included only if certain conditions are met. Here's how you can modify your CMakeLists.txt to include optional components based on configuration options:

    idf_component_register(
        SRCS
            "messenger.cpp"
            ${SOURCES}
        INCLUDE_DIRS
            "."
            "clients"
            ${INCLUDES}
        REQUIRES
            driver
    )
    
    # Conditionally add optional dependencies
    if(CONFIG_COMPONENT_1_ENABLE)
        idf_component_optional_requires(PRIVATE driver-SPI)
    endif()
    
    if(CONFIG_COMPONENT_2_ENABLE)
        idf_component_optional_requires(PRIVATE driver-UART)
    endif()
    

    You can also will check this github: https://github.com/espressif/esp-idf/blob/master/components/esp_system/CMakeLists.txt