Problems with writing CMakeLists.txt for a project

User avatar
Mephisto75
Posts: 4
Joined: Wed Aug 17, 2022 2:23 pm

Problems with writing CMakeLists.txt for a project

Postby Mephisto75 » Wed Aug 17, 2022 3:10 pm

Hey folks,

I am new to the esp world!
trying to setup a project I come across a problem, that can't solve and I'm freaking out.

I have the following project structure:
Image

main.c contains following code:
#include "Includes.h"
void app_main(void){
SpiffsInit();
}


CMakeList.txt in main folder:

idf_component_register(
SRCS "main.c"
REQUIRES FileServer // tried also "FileServer.c", "../components/FileServer.c", and full path -> all the same result
INCLUDE_DIRS "."
"../components/include"
)


FileServer.c contains following code:

#include "Includes.h"

static const char* TAG = "FileServer";

esp_err_t SpiffsInit(void){
ESP_LOGI(TAG, "Initializing SPIFFS");

esp_vfs_spiffs_conf_t conf = {
.base_path = NameOfFS,
.partition_label = NULL,
.max_files = 5, // number of files that can be opened at the same time
.format_if_mount_failed = true
};

esp_err_t ret = esp_vfs_spiffs_register(&conf);
if(ret != ESP_OK) {
if(ret == ESP_FAIL){
ESP_LOGE(TAG, "Failed to mount or format filesystem");
}
else if(ret == ESP_ERR_NOT_FOUND) {
ESP_LOGE(TAG, "Failed to find SPIFFS partition");
}
else {
ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
}
return ESP_FAIL;
}

size_t total = 0, used = 0;
ret = esp_spiffs_info(NULL, &total, &used);
if(ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
return ESP_FAIL;
}

ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
return ESP_OK;
}


CMakeList.txt in components folder :

idf_component_register(
SRCS "FileServer.c"


INCLUDE_DIRS "include"
"C:/Espressif/esp-idf/components/hal/include/hal"
"C:/Espressif/esp-idf/components/spi_flash/include/"
"C:/Espressif/esp-idf/components/nvs_flash/include/"
"C:/Espressif/esp-idf/components/esp_http_server/include/"
"C:/Espressif/esp-idf/components/nghttp/port/include/"

EMBED_FILES "../components/SPIFFsImage/favicon.png"
"../components/SPIFFsImage/IndexHTML.html"

)


FileServer.h :

#ifndef __FILESERVER_H
#define __FILESERVER_H

esp_err_t SpiffsInit(void);

#endif


Includes.h:

#ifndef __INCLUDES_H
#define __INCLUDES_H

#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#include <math.h>

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"

#include "esp_system.h"
#include "esp_log.h"
#include "esp_netif.h"
#include "esp_event.h"
#include "esp_wifi.h"

#include "C:/Espressif/esp-idf/components/spiffs/include/esp_spiffs.h"
#include "C:/Espressif/esp-idf/components/nvs_flash/include/nvs_flash.h"
#include "C:/Espressif/esp-idf/components/spi_flash/sim/stubs/vfs/include/esp_vfs.h"
#include "C:/Espressif/esp-idf/components/spi_flash/include/esp_partition.h"
#include "C:/Espressif/esp-idf/components/esp_http_server/include/esp_http_server.h"
#include "C:/Espressif/esp-idf/components/nghttp/port/include/http_parser.h"
#include "driver/gpio.h"


#include "FileServer.h"


#endif




Trying to build this ends up in following error:

[0/1] Re-running CMake...
-- Project is not inside a git repository, or git repository has no commits; will not use 'git describe' to determine PROJECT_VER.
-- Building ESP-IDF components for target esp32
CMake Error at C:/Espressif/esp-idf/tools/cmake/build.cmake:191 (message):
Failed to resolve component 'FileServer'.
Call Stack (most recent call first):
C:/Espressif/esp-idf/tools/cmake/build.cmake:217 (__build_resolve_and_add_req)
C:/Espressif/esp-idf/tools/cmake/build.cmake:441 (__build_expand_requirements)
C:/Espressif/esp-idf/tools/cmake/project.cmake:399 (idf_build_process)
CMakeLists.txt:6 (project)


If I got the example in https://docs.espressif.com/projects/esp ... cmakelists right, than this should work!
What am I doing wrong?

Leaving the 'REQUIRED "FileServer.c" ' part away and moving 'SpiffsInit()' into main.c works flawlessley.

ESP_Sprite
Posts: 9709
Joined: Thu Nov 26, 2015 4:08 am

Problems with writing CMakeLists.txt for a project

Postby ESP_Sprite » Thu Aug 18, 2022 12:52 am

I've changed your post title, if everyone would post under a title of 'Can please someone help me out !!!', we might as well do away with the concept of titles all together.

Now for your issue. I see a fair few things wrong with your setup:
- A component is a directory within the components/ folder. So if you want to make a component called 'FileServer', you would create the directory 'components/FileServer' in your project directory, and e.g. 'components/FileServer/CMakeLists.txt' as one of the files that live in that directory; your sources would also go there.
- You don't need to use 'INCLUDE_DIRS' to include paths from other components. The CMakeLists.txt of those components will take care of that for you.
- Instead of using EMBED_FILES to include files in a directory above yours, you could add a CMakeLists.txt file there to make that directory into a component without source, and embed the files that way.
- No need to #include absolute paths: the files you have there already are in your include paths (because the components that they belong to register those) and having absolute paths will break your project if you ever decide to share it or move directories around. So ' #include "C:/Espressif/esp-idf/components/spiffs/include/esp_spiffs.h"' -> '#include "esp_spiffs.h"'.

User avatar
Mephisto75
Posts: 4
Joined: Wed Aug 17, 2022 2:23 pm

Re: Problems with writing CMakeLists.txt for a project

Postby Mephisto75 » Thu Aug 18, 2022 8:10 am

Thank you for the review!

Following your suggestions I am ending up with following project structure:
  1. .vscode
  2. build
  3. components
  4.    CMakeLists.txt (components)
  5.    include
  6.       FileServer.h
  7.       Includes.h
  8.    FileServer
  9.       CMakeLists.txt (FileServer)
  10.       FileServer.c
  11.    SPIFFsImage
  12.       CMakeLists.txt (SPIFFsImage)
  13.       favicon.png
  14.       IndexHTML.html
  15. main
  16.    CMakeLists.txt (main)
  17.    main.c
  18. CMakeLists.txt
  19. Makefile
  20. partition.csv
  21. sdkconfig

Makefile
  1. #
  2. # This is a project Makefile. It is assumed the directory this Makefile resides in is a
  3. # project subdirectory.
  4. #
  5. PROJECT_NAME := testproject
  6.  
  7. include $(IDF_PATH)/make/project.mk
  8. SPIFFS_IMAGE_FLASH_IN_PROJECT := 1
  9. $(eval $(call spiffs_create_partition_image,storage,SPIFFsImage))
CMakeLists.txt (project)
  1. # The following five lines of boilerplate have to be in your project's
  2. # CMakeLists in this exact order for cmake to work correctly
  3. cmake_minimum_required(VERSION 3.5)
  4.  
  5. include($ENV{IDF_PATH}/tools/cmake/project.cmake)
  6. project(testproject)
CMakeLists.txt (main)
  1. idf_component_register(
  2.         SRCS            "main.c"
  3.  
  4.         INCLUDE_DIRS    "."
  5. )
  6.  
main.c
  1. #include "Includes.h"
  2.  
  3. void app_main(void){
  4.     SpiffsInit();
  5. }
CMakeLists.txt (components)
  1. idf_component_register(
  2.         INCLUDE_DIRS    "include"
  3. )

CMakeLists.txt (FileServer)
  1. idf_component_register(
  2.         SRCS            "FileServer.c"
  3.  
  4.         INCLUDE_DIRS    "."          
  5. )
FileServer.c
  1. #include "Includes.h"
  2.  
  3. esp_err_t SpiffsInit(void){
  4.   ...
  5.  
  6. }
FileServer.h
  1. #ifndef __FILESERVER_H
  2. #define __FILESERVER_H
  3.  
  4. esp_err_t SpiffsInit(void);
  5.  
  6. #endif
Includes.h
  1. #ifndef __INCLUDES_H
  2. #define __INCLUDES_H
  3.  
  4. #include <sys/param.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/param.h>
  9. #include <sys/unistd.h>
  10. #include <sys/stat.h>
  11. #include <dirent.h>
  12. #include <math.h>
  13.  
  14. #include "freertos/FreeRTOS.h"
  15. #include "freertos/task.h"
  16. #include "freertos/queue.h"
  17. #include "freertos/event_groups.h"
  18.  
  19. #include "esp_system.h"
  20. #include "esp_log.h"
  21. #include "esp_netif.h"
  22. #include "esp_event.h"
  23. #include "esp_wifi.h"
  24.  
  25. #include "esp_spiffs.h"
  26. #include "nvs_flash.h"
  27. #include "esp_vfs.h"
  28. #include "esp_partition.h"
  29. #include "esp_http_server.h"
  30. #include "http_parser.h"
  31. #include "driver/gpio.h"
  32.  
  33. #include "FileServer.h"
  34.  
  35. #endif
CMakeLists.txt (SPIFFsImage)
  1. idf_component_register(
  2.         INCLUDE_DIRS    "SPIFFsImage"          
  3. )

I've tried to implement your suggestions how I understood them but some how I am still missing a bit.
Trying to build the project leads to following error:
  1. FAILED: testproject.elf
  2. cmd.exe /C "cd . && C:\Espressif\.espressif\tools\xtensa-esp32-elf\esp-2021r2-8.4.0\xtensa-esp32-elf\bin\xtensa-esp32-elf-g++.exe  -mlongcalls -Wno-frame-address   @CMakeFiles\testproject.elf.rsp  -o testproject.elf  && cd ."
  3. c:/espressif/.espressif/tools/xtensa-esp32-elf/esp-2021r2-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: esp-idf/main/libmain.a(main.c.obj):(.literal.app_main+0x0): undefined reference to `SpiffsInit'
  4. c:/espressif/.espressif/tools/xtensa-esp32-elf/esp-2021r2-8.4.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: esp-idf/main/libmain.a(main.c.obj): in function `app_main':
  5. C:\Espressif\MyProjects\TestProject\build/../main/main.c:4: undefined reference to `SpiffsInit'
  6. collect2.exe: error: ld returned 1 exit status
  7. ninja: build stopped: subcommand failed.

ESP_Sprite
Posts: 9709
Joined: Thu Nov 26, 2015 4:08 am

Re: Problems with writing CMakeLists.txt for a project

Postby ESP_Sprite » Fri Aug 19, 2022 1:02 pm

You don't need a CMakeLists.txt in your component folder. Not sure if that's the source of the issue, but I'd try removing that first.

User avatar
Mephisto75
Posts: 4
Joined: Wed Aug 17, 2022 2:23 pm

Re: Problems with writing CMakeLists.txt for a project

Postby Mephisto75 » Tue Aug 23, 2022 7:58 am

Just for the record!

Adding these two lines to CMakeLists.txt (main) worked for me!!

Code: Select all

set(COMPONENT_SRCS "main.c" "../components/FileServer.c")
set(COMPONENT_ADD_INCLUDEDIRS "" "../components/")

register_component()
Everything else is as described in the previous post.

Who is online

Users browsing this forum: MicroController and 253 guests