The Kaese
The Kaese

Reputation: 488

CMakeLists - How to include a directory of source and header files?

I feel like this question has been asked a bunch of times, but none of the answers I have found seem to be working for me. I'm extremely new to CMake and C/C++ as I come from the world of Java, and am struggling to understand cmake and how it works.

Anyways, basically I have the folder structure below. This is an esp-idf project, so I don't know if that has anything to do with what I'm running into.

main
-CMakeLists.txt
-main.cpp
-wifi.cpp
Metriful
-CMakeLists.txt
-Metriful_sensor.cpp
-Metriful_sensor.h
-Wifi_functions.h
-Wifi_functions.cpp
CMakeLists.txt
Makefile

Now, all I want to do is include the Metriful subdirectory so I can use the functions provided by the "library". Right now my CMakeLists.txt in the root directory looks like this:

cmake_minimum_required(VERSION 3.5)

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

include_directories("Metriful")

This doesn't seem to work though as including "Metriful_sensor.h" in my main.cpp still fails:

cmake -G Ninja .. <

-- ccache will be used for faster recompilation
-- Building ESP-IDF components for target esp32
-- Project sdkconfig file C:/Users/User/PlatformIO/ESP32_WROOM32_Sensor_-_Metriful/sdkconfig
-- Could NOT find Perl (missing: PERL_EXECUTABLE) 
CMake Warning (dev) at C:/Users/User/esp/esp-idf/components/mbedtls/CMakeLists.txt:114 (target_sources):
  Policy CMP0076 is not set: target_sources() command converts relative paths
  to absolute.  Run "cmake --help-policy CMP0076" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

  A private source from a directory other than that of target "mbedcrypto"
  has a relative path.
This warning is for project developers.  Use -Wno-dev to suppress it.

-- App "ESP_32_WROOM32_SENSOR_-_Metrifu" version: 637cfde-dirty
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp_rom/esp32/ld/esp32.rom.ld
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp_rom/esp32/ld/esp32.rom.api.ld
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp_rom/esp32/ld/esp32.rom.libgcc.ld
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp_rom/esp32/ld/esp32.rom.newlib-data.ld
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp_rom/esp32/ld/esp32.rom.syscalls.ld
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp_rom/esp32/ld/esp32.rom.newlib-funcs.ld
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp_rom/esp32/ld/esp32.rom.newlib-time.ld
-- Adding linker script C:/Users/User/PlatformIO/ESP32_WROOM32_Sensor_-_Metriful/build/esp-idf/esp32/esp32_out.ld
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp32/ld/esp32.project.ld.in
-- Adding linker script C:/Users/User/esp/esp-idf/components/esp32/ld/esp32.peripherals.ld
-- Components: app_trace app_update asio bootloader bootloader_support bt cbor cmock coap console cxx driver efuse esp-tls esp32 esp_adc_cal esp_common esp_eth esp_event esp_gdbstub esp_hid esp_http_client esp_http_server esp_https_ota esp_https_server esp_hw_support esp_ipc esp_local_ctrl esp_netif esp_pm esp_ringbuf esp_rom esp_serial_slave_link esp_system esp_timer esp_websocket_client esp_wifi espcoredump esptool_py expat fatfs freemodbus freertos hal heap idf_test jsmn json libsodium log lwip main mbedtls mdns mqtt newlib nghttp nvs_flash openssl partition_table perfmon protobuf-c protocomm pthread sdmmc soc spi_flash spiffs tcp_transport tcpip_adapter tinyusb ulp unity vfs wear_levelling wifi_provisioning wpa_supplicant xtensa
-- Component paths: C:/Users/User/esp/esp-idf/components/app_trace C:/Users/User/esp/esp-idf/components/app_update C:/Users/User/esp/esp-idf/components/asio C:/Users/User/esp/esp-idf/components/bootloader C:/Users/User/esp/esp-idf/components/bootloader_support C:/Users/User/esp/esp-idf/components/bt C:/Users/User/esp/esp-idf/components/cbor C:/Users/User/esp/esp-idf/components/cmock C:/Users/User/esp/esp-idf/components/coap C:/Users/User/esp/esp-idf/components/console C:/Users/User/esp/esp-idf/components/cxx C:/Users/User/esp/esp-idf/components/driver C:/Users/User/esp/esp-idf/components/efuse C:/Users/User/esp/esp-idf/components/esp-tls C:/Users/User/esp/esp-idf/components/esp32 C:/Users/User/esp/esp-idf/components/esp_adc_cal C:/Users/User/esp/esp-idf/components/esp_common C:/Users/User/esp/esp-idf/components/esp_eth C:/Users/User/esp/esp-idf/components/esp_event C:/Users/User/esp/esp-idf/components/esp_gdbstub C:/Users/User/esp/esp-idf/components/esp_hid C:/Users/User/esp/esp-idf/components/esp_http_client C:/Users/User/esp/esp-idf/components/esp_http_server C:/Users/User/esp/esp-idf/components/esp_https_ota C:/Users/User/esp/esp-idf/components/esp_https_server C:/Users/User/esp/esp-idf/components/esp_hw_support C:/Users/User/esp/esp-idf/components/esp_ipc C:/Users/User/esp/esp-idf/components/esp_local_ctrl C:/Users/User/esp/esp-idf/components/esp_netif C:/Users/User/esp/esp-idf/components/esp_pm C:/Users/User/esp/esp-idf/components/esp_ringbuf C:/Users/User/esp/esp-idf/components/esp_rom C:/Users/User/esp/esp-idf/components/esp_serial_slave_link C:/Users/User/esp/esp-idf/components/esp_system C:/Users/User/esp/esp-idf/components/esp_timer C:/Users/User/esp/esp-idf/components/esp_websocket_client C:/Users/User/esp/esp-idf/components/esp_wifi C:/Users/User/esp/esp-idf/components/espcoredump C:/Users/User/esp/esp-idf/components/esptool_py C:/Users/User/esp/esp-idf/components/expat C:/Users/User/esp/esp-idf/components/fatfs C:/Users/User/esp/esp-idf/components/freemodbus C:/Users/User/esp/esp-idf/components/freertos C:/Users/User/esp/esp-idf/components/hal C:/Users/User/esp/esp-idf/components/heap C:/Users/User/esp/esp-idf/components/idf_test C:/Users/User/esp/esp-idf/components/jsmn C:/Users/User/esp/esp-idf/components/json C:/Users/User/esp/esp-idf/components/libsodium C:/Users/User/esp/esp-idf/components/log C:/Users/User/esp/esp-idf/components/lwip C:/Users/User/PlatformIO/ESP32_WROOM32_Sensor_-_Metriful/main C:/Users/User/esp/esp-idf/components/mbedtls C:/Users/User/esp/esp-idf/components/mdns C:/Users/User/esp/esp-idf/components/mqtt C:/Users/User/esp/esp-idf/components/newlib C:/Users/User/esp/esp-idf/components/nghttp C:/Users/User/esp/esp-idf/components/nvs_flash C:/Users/User/esp/esp-idf/components/openssl C:/Users/User/esp/esp-idf/components/partition_table C:/Users/User/esp/esp-idf/components/perfmon C:/Users/User/esp/esp-idf/components/protobuf-c 
C:/Users/User/esp/esp-idf/components/protocomm C:/Users/User/esp/esp-idf/components/pthread C:/Users/User/esp/esp-idf/components/sdmmc C:/Users/User/esp/esp-idf/components/soc C:/Users/User/esp/esp-idf/components/spi_flash C:/Users/User/esp/esp-idf/components/spiffs C:/Users/User/esp/esp-idf/components/tcp_transport C:/Users/User/esp/esp-idf/components/tcpip_adapter C:/Users/User/esp/esp-idf/components/tinyusb C:/Users/User/esp/esp-idf/components/ulp C:/Users/User/esp/esp-idf/components/unity C:/Users/User/esp/esp-idf/components/vfs C:/Users/User/esp/esp-idf/components/wear_levelling C:/Users/User/esp/esp-idf/components/wifi_provisioning C:/Users/User/esp/esp-idf/components/wpa_supplicant C:/Users/User/esp/esp-idf/components/xtensa
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/User/PlatformIO/ESP32_WROOM32_Sensor_-_Metriful/build

Terminal will be reused by tasks, press any key to close it.

> Executing task: cmake --build . <

[1/9] Performing build step for 'bootloader'
ninja: no work to do.
[2/7] Building CXX object esp-idf/main/CMakeFiles/__idf_main.dir/main.cpp.obj
FAILED: esp-idf/main/CMakeFiles/__idf_main.dir/main.cpp.obj 
ccache C:\Users\User\.espressif\tools\xtensa-esp32-elf\esp-2020r3-8.4.0\xtensa-esp32-elf\bin\xtensa-esp32-elf-g++.exe  -DHAVE_CONFIG_H -DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\" -DUNITY_INCLUDE_CONFIG_H -DWITH_POSIX -Iconfig -I../main -IC:/Users/User/esp/esp-idf/components/newlib/platform_include -IC:/Users/User/esp/esp-idf/components/freertos/include -IC:/Users/User/esp/esp-idf/components/freertos/port/xtensa/include -IC:/Users/User/esp/esp-idf/components/esp_hw_support/include -IC:/Users/User/esp/esp-idf/components/esp_hw_support/port/esp32/. -IC:/Users/User/esp/esp-idf/components/heap/include -IC:/Users/User/esp/esp-idf/components/log/include -IC:/Users/User/esp/esp-idf/components/lwip/include/apps -IC:/Users/User/esp/esp-idf/components/lwip/include/apps/sntp -IC:/Users/User/esp/esp-idf/components/lwip/lwip/src/include -IC:/Users/User/esp/esp-idf/components/lwip/port/esp32/include -IC:/Users/User/esp/esp-idf/components/lwip/port/esp32/include/arch -IC:/Users/User/esp/esp-idf/components/soc/include -IC:/Users/User/esp/esp-idf/components/soc/esp32/. -IC:/Users/User/esp/esp-idf/components/soc/esp32/include -IC:/Users/User/esp/esp-idf/components/hal/esp32/include -IC:/Users/User/esp/esp-idf/components/hal/include -IC:/Users/User/esp/esp-idf/components/esp_rom/include -IC:/Users/User/esp/esp-idf/components/esp_rom/esp32 -IC:/Users/User/esp/esp-idf/components/esp_common/include -IC:/Users/User/esp/esp-idf/components/esp_system/include -IC:/Users/User/esp/esp-idf/components/esp32/include -IC:/Users/User/esp/esp-idf/components/driver/include -IC:/Users/User/esp/esp-idf/components/driver/esp32/include -IC:/Users/User/esp/esp-idf/components/esp_ringbuf/include -IC:/Users/User/esp/esp-idf/components/efuse/include -IC:/Users/User/esp/esp-idf/components/efuse/esp32/include -IC:/Users/User/esp/esp-idf/components/xtensa/include -IC:/Users/User/esp/esp-idf/components/xtensa/esp32/include -IC:/Users/User/esp/esp-idf/components/espcoredump/include -IC:/Users/User/esp/esp-idf/components/esp_timer/include -IC:/Users/User/esp/esp-idf/components/esp_ipc/include -IC:/Users/User/esp/esp-idf/components/esp_pm/include -IC:/Users/User/esp/esp-idf/components/vfs/include -IC:/Users/User/esp/esp-idf/components/esp_wifi/include -IC:/Users/User/esp/esp-idf/components/esp_wifi/esp32/include -IC:/Users/User/esp/esp-idf/components/esp_event/include -IC:/Users/User/esp/esp-idf/components/esp_netif/include -IC:/Users/User/esp/esp-idf/components/esp_eth/include -IC:/Users/User/esp/esp-idf/components/tcpip_adapter/include -IC:/Users/User/esp/esp-idf/components/app_trace/include -IC:/Users/User/esp/esp-idf/components/mbedtls/port/include -IC:/Users/User/esp/esp-idf/components/mbedtls/mbedtls/include -IC:/Users/User/esp/esp-idf/components/mbedtls/esp_crt_bundle/include -IC:/Users/User/esp/esp-idf/components/app_update/include -IC:/Users/User/esp/esp-idf/components/spi_flash/include -IC:/Users/User/esp/esp-idf/components/bootloader_support/include -IC:/Users/User/esp/esp-idf/components/nvs_flash/include -IC:/Users/User/esp/esp-idf/components/pthread/include -IC:/Users/User/esp/esp-idf/components/esp_gdbstub/include -IC:/Users/User/esp/esp-idf/components/esp_gdbstub/xtensa -IC:/Users/User/esp/esp-idf/components/esp_gdbstub/esp32 -IC:/Users/User/esp/esp-idf/components/wpa_supplicant/include -IC:/Users/User/esp/esp-idf/components/wpa_supplicant/port/include -IC:/Users/User/esp/esp-idf/components/wpa_supplicant/include/esp_supplicant -IC:/Users/User/esp/esp-idf/components/perfmon/include -IC:/Users/User/esp/esp-idf/components/asio/asio/asio/include -IC:/Users/User/esp/esp-idf/components/asio/port/include -IC:/Users/User/esp/esp-idf/components/cbor/port/include -IC:/Users/User/esp/esp-idf/components/unity/include -IC:/Users/User/esp/esp-idf/components/unity/unity/src -IC:/Users/User/esp/esp-idf/components/cmock/CMock/src -IC:/Users/User/esp/esp-idf/components/coap/port/include -IC:/Users/User/esp/esp-idf/components/coap/port/include/coap -IC:/Users/User/esp/esp-idf/components/coap/libcoap/include -IC:/Users/User/esp/esp-idf/components/coap/libcoap/include/coap2 -IC:/Users/User/esp/esp-idf/components/console -IC:/Users/User/esp/esp-idf/components/nghttp/port/include -IC:/Users/User/esp/esp-idf/components/nghttp/nghttp2/lib/includes -IC:/Users/User/esp/esp-idf/components/esp-tls -IC:/Users/User/esp/esp-idf/components/esp-tls/esp-tls-crypto -IC:/Users/User/esp/esp-idf/components/esp_adc_cal/include -IC:/Users/User/esp/esp-idf/components/esp_hid/include -IC:/Users/User/esp/esp-idf/components/tcp_transport/include -IC:/Users/User/esp/esp-idf/components/esp_http_client/include -IC:/Users/User/esp/esp-idf/components/esp_http_server/include -IC:/Users/User/esp/esp-idf/components/esp_https_ota/include -IC:/Users/User/esp/esp-idf/components/protobuf-c/protobuf-c -IC:/Users/User/esp/esp-idf/components/protocomm/include/common -IC:/Users/User/esp/esp-idf/components/protocomm/include/security -IC:/Users/User/esp/esp-idf/components/protocomm/include/transports -IC:/Users/User/esp/esp-idf/components/mdns/include -IC:/Users/User/esp/esp-idf/components/esp_local_ctrl/include -IC:/Users/User/esp/esp-idf/components/sdmmc/include -IC:/Users/User/esp/esp-idf/components/esp_serial_slave_link/include -IC:/Users/User/esp/esp-idf/components/esp_websocket_client/include -IC:/Users/User/esp/esp-idf/components/expat/expat/expat/lib -IC:/Users/User/esp/esp-idf/components/expat/port/include -IC:/Users/User/esp/esp-idf/components/wear_levelling/include -IC:/Users/User/esp/esp-idf/components/fatfs/diskio -IC:/Users/User/esp/esp-idf/components/fatfs/vfs -IC:/Users/User/esp/esp-idf/components/fatfs/src -IC:/Users/User/esp/esp-idf/components/freemodbus/common/include -IC:/Users/User/esp/esp-idf/components/idf_test/include -IC:/Users/User/esp/esp-idf/components/idf_test/include/esp32 -IC:/Users/User/esp/esp-idf/components/jsmn/include -IC:/Users/User/esp/esp-idf/components/json/cJSON -IC:/Users/User/esp/esp-idf/components/libsodium/libsodium/src/libsodium/include -IC:/Users/User/esp/esp-idf/components/libsodium/port_include -IC:/Users/User/esp/esp-idf/components/mqtt/esp-mqtt/include -IC:/Users/User/esp/esp-idf/components/openssl/include -IC:/Users/User/esp/esp-idf/components/spiffs/include -IC:/Users/User/esp/esp-idf/components/ulp/include -IC:/Users/User/esp/esp-idf/components/wifi_provisioning/include -mlongcalls -Wno-frame-address   -ffunction-sections -fdata-sections -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wextra -Wno-unused-parameter -Wno-sign-compare -ggdb -Og -fstrict-volatile-bitfields -Wno-error=unused-but-set-variable -std=gnu++11 
-fno-exceptions -fno-rtti -D_GNU_SOURCE -DIDF_VER=\"v4.3-dirty\" -DESP_PLATFORM -MD -MT esp-idf/main/CMakeFiles/__idf_main.dir/main.cpp.obj -MF esp-idf\main\CMakeFiles\__idf_main.dir\main.cpp.obj.d -o esp-idf/main/CMakeFiles/__idf_main.dir/main.cpp.obj -c ../main/main.cpp
../main/main.cpp:3:10: fatal error: Metriful_sensor.h: No such file or directory
 #include "Metriful_sensor.h"
          ^~~~~~~~~~~~~~~~~~~
compilation terminated.
ninja: build stopped: subcommand failed.

Upvotes: 3

Views: 11216

Answers (2)

Selali Adobor
Selali Adobor

Reputation: 2157

You're likely to get a lot of answers from CMake users but ESP-IDF is different enough that a lot of answers aren't compatible between the two

IDF uses a component model built on top of CMake, so most normal include commands don't do anything

You want to look at idf_component_register

You probably want to register Metriful as a new component, and since it depends on Arduino you might need some extra steps.

  1. If you want to keep your current directory structure, in your top level CMake (the one with cmake_minimum_required at the top) add the line:

    set(EXTRA_COMPONENT_DIRS "Metriful")
    

    Otherwise make a folder named components next to your main folder and put Metriful inside that folder:

    - main
       main.cpp 
       your.h
    - components
       -Metriful
           Metriful.cpp 
           Metriful.h
    
  2. Register Metriful as an IDF-Component if it isn't already.

    Check Metriful/CMakeList.txt for idf_component_register and if it doesn't contain it replace the contents with

    idf_component_register(
     SRCS "Metriful/MetrifulC.cpp" "Metriful/MetrifulA.cpp" 
     INCLUDE_DIRS "."
     REQUIRES arduino
    )
    

    Note: You need to add each .cpp in Metriful manually to this file, same with your main as you add new files to it

  3. Add Metriful as a requirement of your main. In main/CMakeList.txt add a line to your idf_component_register

     REQUIRES Metriful
    

    Note the name Metriful will be case-sensitive and must match the folder name for Metriful

At this point everything will work if you already added Arduino to your ESP-IDF project. If you didn't follow these instructions: https://github.com/espressif/arduino-esp32/blob/master/docs/esp-idf_component.md


Also want to put this out there, Metriful seems to be an Arduino based library. If you're new to the ESP32, using ESP-IDF directly might be troublesome, since you'll likely be using a lot of Arduino based libraries.

The Arduino library works in ESP-IDF, but there are often incompatiblities that you need to work through when ESP-IDF updates.

Is there a specific reason you have for using ESP-IDF directly? Just remember Platform.IO lets you generate a compilation database, so you can use most coding environments if that's what you're after.

Upvotes: 7

Peter
Peter

Reputation: 14947

The ESP-IDF build system is built on top of CMake. This means you can use all the standard features of CMake in your files. However, the the ESP-IDF system predefines many functions, and makes many assumptions about the layout of your project, supposedly to make things "easier". Instead of reading CMake documentation, start by reading and understanding the ESP-IDF build system documentation:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html

It looks to me like there is a particular layout expected for subcomponents, including the format of the CMakeLists.txt file. Specifically, move Metriful under a new directory called components, or add Metriful to EXTRA_COMPONENT_DIRS near the top of your root CMakeLists.txt

If Metriful is not written as an esp-idf component, this may not work. However, the document also describes how to link to "pure CMake" components, which will look something like this (at the end of your root CMakeLists.txt).

# Create and import the library targets
add_subdirectory(Metriful)

# Publicly link `foo` to `main` component
target_link_libraries(main PUBLIC metriful)

The metriful argument in target_link_libraries must be the name of the library created in the subdirectory via add_library().

Upvotes: 1

Related Questions