CMake project setup issues with AWS FreeRTOS for ESP32

Hi, apologies if this is similar to previous posts such as 12190, but I haven’t found an answer anywhere…

I have downloaded the AWS FreeRTOS repo and am trying to incorporate it into my project, as per the ‘Getting Started’ guide. Aiming for a project structure as follows:

  • freertos

  • components

    • bmp280

      • bmp280.c
      • bmp280.h
    • other components

  • include

    • main.h
    • other project header files
  • src

    • main.c
    • other project c files
  • CMakeLists.txt

Based on the guide, I currently have the following CMakeLists.txt:


cmake_minimum_required(VERSION 3.5)

project(csl_edge)

include_directories(include)

#add_executable(csl_edge src/main.c)

#Tell IDF build to link against this target.
set(IDF_PROJECT_EXECUTABLE csl_edge)
set(IDF_EXECUTABLE_SRCS ~/Projects/csl_edge/src/main.c)

#Add some extra components. IDF_EXTRA_COMPONENT_DIRS is a variable used by ESP-IDF
#to collect extra components.
get_filename_component(
EXTRA_COMPONENT_DIRS
“components/bmp280” ABSOLUTE
)
list(APPEND IDF_EXTRA_COMPONENT_DIRS ${EXTRA_COMPONENT_DIRS})

#Add FreeRTOS as a subdirectory. AFR_BOARD tells which board to target.
set(AFR_BOARD espressif.esp32_devkitc CACHE INTERNAL “”)
add_subdirectory(freertos)


and the following CMakeLists.txt in components/bm280:


set(COMPONENT_ADD_INCLUDEDIRS . )
set(COMPONENT_SRCDIRS . )
register_component()


I haven’t been able to build successfully - problems so far:

  1. If I leave in the line add_executable(csl_edge src/main.c) as per the guide I get the build error:

‘cannot create target “csl_edge” because another target with
the same name already exists’

I believe this is due to add_executable also being called by freertos/vendors/espressif/board/esp32/CMakeLists.txt, using the name set as IDF_PROJECT_EXECUTABLE. I can resolve the error by removing the ‘add_executable’ line and adding ‘set(IDF_EXECUTABLE_SRCS ~/Projects/csl_edge/src/main.c)’ as shown, which then allows freertos/vendors/espressif/board/esp32/CMakeLists.txt to correctly call add_executable with my main.c file. Does this approach sound correct?

  1. The build is currently not compiling bm280.c (or indeed any of my c files except for main.c), and is not finding bm280.h when trying to compile main.c. Should appending to IDF_EXTRA_COMPONENT_DIRS be sufficient to add the component and make it available? I’ve tried to follow what’s in the guide but am not sure how this works as I don’t see the IDF_EXTRA_COMPONENT_DIRS variable being read anywhere?

Any help much appreciated…

Hi @SimonCB,

Is your problem similar to this one?

Hi @gedeonag,

Thanks for replying. Same kind of setup but not the same problem - I’m pretty sure my toolchain is correct. Tried adjusting my top level CMakeLists.text to match your test for senfrost and confirmed I still get the same error :

‘CMake Error at freertos/vendors/espressif/boards/esp32/CMakeLists.txt:477 (add_executable):
add_executable cannot create target “csl_edge” because another target with
the same name already exists.’

Your approach looks correct to me

How are you calling the cmake command ?

From command prompt:

cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=freertos/tools/cmake/toolchains/xtensa-esp32.cmake -GNinja

you should not add

add_executable()

youself as the IDF does that for you.
what would be the error if you delete it.

Hi @gedeonag,

Thanks for the update - yes, I’d figured that was the case. I’m having more success - my main issue now is that my components aren’t getting compiled. I don’t believe that the entry in the top level CMakeLists.txt works:

#Add some extra components. IDF_EXTRA_COMPONENT_DIRS is a variable used by ESP-IDF
#to collect extra components.
get_filename_component(
EXTRA_COMPONENT_DIRS
“components/ssd1306” ABSOLUTE
)
list(APPEND IDF_EXTRA_COMPONENT_DIRS ${EXTRA_COMPONENT_DIRS})

I’ve done a search of the freertos tree and the IDF_EXTRA_COMPONENT_DIRS variable doesn’t seem to appear anywhere…

I can get the project to build successfully by adding an include_directories() entry for each component, and adding all the component c files to IDF_EXECUTABLE_SRCS - will get a bit messy as more components are added though.

as you mentioned, I don’t see “IDF_EXTRA_COMPONENT_DIRS” defined anywhere in our code base as well, so i doubt it would be of any use.
what I see is EXTRA_COMPONENT_DIRS defined and used as so:

set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/bluetooth/esp_ble_mesh/common_components/example_init   
                         $ENV{IDF_PATH}/examples/bluetooth/esp_ble_mesh/common_components/fast_provisioning) 

I followed the that variable and how it is used at : vendors/espressif/esp-idf/tools/cmake/component.cmake , and it boiled down to

add_library(${component_target} STATIC IMPORTED) 

but with lots of conditions (if else etc…).
I think it should work well for you, if you add a couple of prints around those condition to see if you are missing anything.

Thanks @gedeonag,

All good now. In case it helps anyone else, here’s a summary of where I’ve deviated from the ‘Getting Started’ guide (which does seem to be wrong):

  • Don’t use ‘add_executable’ in the top level CMakeLists.txt (as it will conflict with the existing ‘add_executable’ in the lower - level CMakeLists.txt)

  • Instead use:
    set(IDF_PROJECT_EXECUTABLE [your project name])
    set(IDF_EXECUTABLE_SRCS [your project sources])
    to let the lower level add_executable know what to add. IDF_EXECUTABLE_SRCS can contain multiple source code files, I have it set to all the files in my src folder.

  • Adding custom components via IDF_EXTRA_COMPONENT_DIRS also doesn’t work - I’ve added my components as follows:

  1. CMakeLists.txt in component folder:

add_library(ssd1306 STATIC ssd1306.c)
target_include_directories(ssd1306 PUBLIC .)
target_link_libraries(ssd1306 PRIVATE AFR::common_io)

Add anything the component depends on to the target_link_libraries call. ‘idf_component_register’ apparently won’t work due to the components being outside the esp-idf build tree.

  1. Top level CMakeLists.txt:

add_subdirectory(components/ssd1306)
target_link_libraries( [your project name] ssd1306)

1 Like