ESP-IDF CMake build flags are being ignored

I’m trying to put together a project that has two distinct target environments: the M5Stamp Fly unit, and the pair-able M5Stack Atom JoyStick.

These two will require a completely different firmware, but will share a number of structs and defines, and the project is meant to be used as one unit - you’d need both pieces of hardware, both firmwares flashed to the right hardware, and they will communicate with each other.

For this purpose I’ve been trying to put together the project the following way:

  • platformio.ini
  • src/
    • common/ for all common bits
    • common/CMakeLists.txt defining the common component
    • quadcopter/ for the sources of the quadcopter component/fw
    • quadcopter/CMakeLists.txt containing build instructions
    • remote/ for the sources of the remote component/fw
    • remote/CMakeLists.txt `containing build instructions
    • CMakeLists.txt basic build splitter depending on env

The idea was to include the appropriate subfolder of src through some basic logic in src/CMakeLists.txt and adding the appropriate build flags to each env in platformio.ini:

#platformio.ini
[platformio]
default_envs = quadcopter

[env:quadcopter]
platform = espressif32
board = m5stack-stamps3
framework = espidf
board_build.cmake_extra_args = 
    -DPRODUCT=quadcopter


[env:remote]
platform = espressif32
board = m5stack-atoms3
framework = espidf
board_build.cmake_extra_args = 
    -DPRODUCT=remote
#src/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)

include(${CMAKE_CURRENT_LIST_DIR}/common/CMakeLists.txt)

# Check for PRODUCT build flag
if(NOT DEFINED PRODUCT)
    message(FATAL_ERROR "PRODUCT build flag not set. Please define -DPRODUCT=quadcopter or -DPRODUCT=remote")
endif()

# Select subproject based on PRODUCT
if(PRODUCT STREQUAL "quadcopter")
    message(STATUS "Building Quadcopter firmware")
    include(${CMAKE_CURRENT_LIST_DIR}/quadcopter/CMakeLists.txt)
elseif(PRODUCT STREQUAL "remote")
    message(STATUS "Building Remote firmware")
    include(${CMAKE_CURRENT_LIST_DIR}/remote/CMakeLists.txt)
else()
    message(FATAL_ERROR "Unknown PRODUCT: ${PRODUCT}. Must be 'quadcopter' or 'remote'.")
endif()

As per my research (mainly #1 and #2 - had more links but couldn’t add them due to being a new user), using board_build.cmake_extra_args is the correct way of handling this, and by the time src/CMakeLists.txt is executed, the PRODUCT build flag should be set and available.

However for some reason, I’m running into the error defined on line 7 of said CMakeLists.txt:

  CMake Error at src/CMakeLists.txt:7 (message):

    PRODUCT build flag not set.  Please define -DPRODUCT=quadcopter or
    -DPRODUCT=remote

  Call Stack (most recent call first):

    /Users/xxx/.platformio/packages/framework-espidf@3.50400.0/tools/cmake/scripts/component_get_requirements.cmake:107 (include)
    /Users/xxx/.platformio/packages/framework-espidf@3.50400.0/tools/cmake/scripts/component_get_requirements.cmake:160 (__component_get_requirements)

  

  

Call Stack (most recent call first):
  /Users/xxx/.platformio/packages/framework-espidf@3.50400.0/tools/cmake/build.cmake:644 (__component_get_requirements)
  /Users/xxx/.platformio/packages/framework-espidf@3.50400.0/tools/cmake/project.cmake:710 (idf_build_process)
  CMakeLists.txt:6 (project)

The CMake extra flags are clearly set in platformio.ini, yet it seems to be ignored - .pio/build/quadcopter/build_properties.temp.cmake shows that EXTRA_CMAKE_ARGS actually ends up being empty:

set(PYTHON "/Users/xxx/.platformio/penv/.espidf-5.4.0/bin/python")
set(__BUILD_PROPERTIES "PYTHON;__BUILD_PROPERTIES;IDF_PATH;__PREFIX;__CHECK_PYTHON;IDF_COMPONENT_MANAGER;COMPILE_DEFINITIONS;COMPILE_OPTIONS;C_COMPILE_OPTIONS;CXX_COMPILE_OPTIONS;__COMPONENT_TARGETS;BUILD_COMPONENT_DIRS;BUILD_COMPONENT_TARGETS;__COMPONENT_REQUIRES_COMMON;IDF_VER;__ROOT_KCONFIG;__ROOT_SDKCONFIG_RENAME;__OUTPUT_SDKCONFIG;EXTRA_CMAKE_ARGS;__COMPONENT_MANAGER_INTERFACE_VERSION;BOOTLOADER_BUILD;NON_OS_BUILD;IDF_TOOLCHAIN;IDF_TARGET;IDF_TARGET_ARCH;PROJECT_DIR;PROJECT_NAME;PROJECT_VER;BUILD_DIR;SDKCONFIG;SDKCONFIG_DEFAULTS")
set(IDF_PATH "/Users/xxx/.platformio/packages/framework-espidf@3.50400.0")
set(__PREFIX "idf")
set(__CHECK_PYTHON "0")
set(IDF_COMPONENT_MANAGER "1")
set(COMPILE_DEFINITIONS "_GLIBCXX_USE_POSIX_SEMAPHORE;_GLIBCXX_HAVE_POSIX_SEMAPHORE;_GNU_SOURCE;IDF_VER="5.4.0"")
set(COMPILE_OPTIONS "-ffunction-sections;-fdata-sections;-Wall;-Werror;-Wno-error=unused-function;-Wno-error=unused-variable;-Wno-error=unused-but-set-variable;-Wno-error=deprecated-declarations;-Wextra;-Wno-error=extra;-Wno-unused-parameter;-Wno-sign-compare;-Wno-enum-conversion;-gdwarf-4;-ggdb")
set(C_COMPILE_OPTIONS "-std=gnu17")
set(CXX_COMPILE_OPTIONS "-std=gnu++2b")
set(__COMPONENT_TARGETS "___idf___pio_env;___idf_app_trace;___idf_app_update;___idf_bootloader;___idf_bootloader_support;___idf_bt;___idf_cmock;___idf_console;___idf_cxx;___idf_driver;___idf_efuse;___idf_esp-tls;___idf_esp_adc;___idf_esp_app_format;___idf_esp_bootloader_format;___idf_esp_coex;___idf_esp_common;___idf_esp_driver_ana_cmpr;___idf_esp_driver_cam;___idf_esp_driver_dac;___idf_esp_driver_gpio;___idf_esp_driver_gptimer;___idf_esp_driver_i2c;___idf_esp_driver_i2s;___idf_esp_driver_isp;___idf_esp_driver_jpeg;___idf_esp_driver_ledc;___idf_esp_driver_mcpwm;___idf_esp_driver_parlio;___idf_esp_driver_pcnt;___idf_esp_driver_ppa;___idf_esp_driver_rmt;___idf_esp_driver_sdio;___idf_esp_driver_sdm;___idf_esp_driver_sdmmc;___idf_esp_driver_sdspi;___idf_esp_driver_spi;___idf_esp_driver_touch_sens;___idf_esp_driver_tsens;___idf_esp_driver_uart;___idf_esp_driver_usb_serial_jtag;___idf_esp_eth;___idf_esp_event;___idf_esp_gdbstub;___idf_esp_hid;___idf_esp_http_client;___idf_esp_http_server;___idf_esp_https_ota;___idf_esp_https_server;___idf_esp_hw_support;___idf_esp_lcd;___idf_esp_local_ctrl;___idf_esp_mm;___idf_esp_netif;___idf_esp_netif_stack;___idf_esp_partition;___idf_esp_phy;___idf_esp_pm;___idf_esp_psram;___idf_esp_ringbuf;___idf_esp_rom;___idf_esp_security;___idf_esp_system;___idf_esp_timer;___idf_esp_vfs_console;___idf_esp_wifi;___idf_espcoredump;___idf_esptool_py;___idf_fatfs;___idf_freertos;___idf_hal;___idf_heap;___idf_http_parser;___idf_idf_test;___idf_ieee802154;___idf_json;___idf_linux;___idf_log;___idf_lwip;___idf_mbedtls;___idf_mqtt;___idf_newlib;___idf_nvs_flash;___idf_nvs_sec_provider;___idf_openthread;___idf_partition_table;___idf_perfmon;___idf_protobuf-c;___idf_protocomm;___idf_pthread;___idf_riscv;___idf_rt;___idf_sdmmc;___idf_soc;___idf_spi_flash;___idf_spiffs;___idf_tcp_transport;___idf_touch_element;___idf_ulp;___idf_unity;___idf_usb;___idf_vfs;___idf_wear_levelling;___idf_wifi_provisioning;___idf_wpa_supplicant;___idf_xtensa;___idf_src")
set(BUILD_COMPONENT_DIRS "/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/__pio_env;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/app_trace;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/app_update;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/bootloader;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/bootloader_support;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/bt;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/cmock;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/console;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/cxx;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/driver;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/efuse;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp-tls;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_adc;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_app_format;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_bootloader_format;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_coex;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_common;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_ana_cmpr;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_cam;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_dac;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_gpio;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_gptimer;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_i2c;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_i2s;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_isp;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_jpeg;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_ledc;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_mcpwm;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_parlio;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_pcnt;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_ppa;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_rmt;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_sdio;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_sdm;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_sdmmc;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_sdspi;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_spi;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_touch_sens;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_tsens;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_uart;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_driver_usb_serial_jtag;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_eth;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_event;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_gdbstub;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_hid;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_http_client;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_http_server;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_https_ota;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_https_server;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_hw_support;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_lcd;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_local_ctrl;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_mm;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_netif;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_netif_stack;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_partition;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_phy;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_pm;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_psram;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_ringbuf;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_rom;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_security;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_system;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_timer;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_vfs_console;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esp_wifi;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/espcoredump;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/esptool_py;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/fatfs;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/freertos;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/hal;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/heap;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/http_parser;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/idf_test;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/ieee802154;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/json;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/linux;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/log;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/lwip;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/mbedtls;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/mqtt;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/newlib;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/nvs_flash;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/nvs_sec_provider;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/openthread;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/partition_table;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/perfmon;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/protobuf-c;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/protocomm;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/pthread;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/riscv;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/rt;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/sdmmc;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/soc;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/spi_flash;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/spiffs;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/tcp_transport;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/touch_element;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/ulp;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/unity;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/usb;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/vfs;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/wear_levelling;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/wifi_provisioning;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/wpa_supplicant;/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/components/xtensa;/Users/xxx/Projects/DeltaFlyer/src")
set(BUILD_COMPONENT_TARGETS "___idf___pio_env;___idf_app_trace;___idf_app_update;___idf_bootloader;___idf_bootloader_support;___idf_bt;___idf_cmock;___idf_console;___idf_cxx;___idf_driver;___idf_efuse;___idf_esp-tls;___idf_esp_adc;___idf_esp_app_format;___idf_esp_bootloader_format;___idf_esp_coex;___idf_esp_common;___idf_esp_driver_ana_cmpr;___idf_esp_driver_cam;___idf_esp_driver_dac;___idf_esp_driver_gpio;___idf_esp_driver_gptimer;___idf_esp_driver_i2c;___idf_esp_driver_i2s;___idf_esp_driver_isp;___idf_esp_driver_jpeg;___idf_esp_driver_ledc;___idf_esp_driver_mcpwm;___idf_esp_driver_parlio;___idf_esp_driver_pcnt;___idf_esp_driver_ppa;___idf_esp_driver_rmt;___idf_esp_driver_sdio;___idf_esp_driver_sdm;___idf_esp_driver_sdmmc;___idf_esp_driver_sdspi;___idf_esp_driver_spi;___idf_esp_driver_touch_sens;___idf_esp_driver_tsens;___idf_esp_driver_uart;___idf_esp_driver_usb_serial_jtag;___idf_esp_eth;___idf_esp_event;___idf_esp_gdbstub;___idf_esp_hid;___idf_esp_http_client;___idf_esp_http_server;___idf_esp_https_ota;___idf_esp_https_server;___idf_esp_hw_support;___idf_esp_lcd;___idf_esp_local_ctrl;___idf_esp_mm;___idf_esp_netif;___idf_esp_netif_stack;___idf_esp_partition;___idf_esp_phy;___idf_esp_pm;___idf_esp_psram;___idf_esp_ringbuf;___idf_esp_rom;___idf_esp_security;___idf_esp_system;___idf_esp_timer;___idf_esp_vfs_console;___idf_esp_wifi;___idf_espcoredump;___idf_esptool_py;___idf_fatfs;___idf_freertos;___idf_hal;___idf_heap;___idf_http_parser;___idf_idf_test;___idf_ieee802154;___idf_json;___idf_linux;___idf_log;___idf_lwip;___idf_mbedtls;___idf_mqtt;___idf_newlib;___idf_nvs_flash;___idf_nvs_sec_provider;___idf_openthread;___idf_partition_table;___idf_perfmon;___idf_protobuf-c;___idf_protocomm;___idf_pthread;___idf_riscv;___idf_rt;___idf_sdmmc;___idf_soc;___idf_spi_flash;___idf_spiffs;___idf_tcp_transport;___idf_touch_element;___idf_ulp;___idf_unity;___idf_usb;___idf_vfs;___idf_wear_levelling;___idf_wifi_provisioning;___idf_wpa_supplicant;___idf_xtensa;___idf_src")
set(__COMPONENT_REQUIRES_COMMON "cxx;newlib;freertos;esp_hw_support;heap;log;soc;hal;esp_rom;esp_common;esp_system;xtensa")
set(IDF_VER "5.4.0")
set(__ROOT_KCONFIG "/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/Kconfig")
set(__ROOT_SDKCONFIG_RENAME "/Users/xxx/.platformio/packages/framework-espidf@3.50400.0/sdkconfig.rename")
set(__OUTPUT_SDKCONFIG "1")
-> set(EXTRA_CMAKE_ARGS "")
set(__COMPONENT_MANAGER_INTERFACE_VERSION "3")
set(BOOTLOADER_BUILD "")
set(NON_OS_BUILD "")
set(IDF_TOOLCHAIN "gcc")
set(IDF_TARGET "esp32s3")
set(IDF_TARGET_ARCH "xtensa")
set(PROJECT_DIR "/Users/xxx/Projects/DeltaFlyer")
set(PROJECT_NAME "DeltaFlyer")
set(PROJECT_VER "13d1c75-dirty")
set(BUILD_DIR "/Users/xxx/Projects/DeltaFlyer/.pio/build/quadcopter")
set(SDKCONFIG "/Users/xxx/Projects/DeltaFlyer/sdkconfig.quadcopter")
set(SDKCONFIG_DEFAULTS "")

What is going on?

  1. Try quoting the value as
board_build.cmake_extra_args = 
    -DPRODUCT="remote"
  1. Force a clean build by deleting the .pio folder.

I would not expect that argument to end up in “extra cmake options”, the builder script just appends it to the regular options (source).

So it should show up in that list as just

set(PRODUCT "quadcopter")

Unfortunately quotes did not help - I’ve actually tried that approach before (including the complete removal of .pio to avoid cache interfering with results).