Change compiler based on the env selected?

Hello,

I am working with ESP32 devices and wanting to use both the Arduino and the esp-idf frameworks. I haven’t had any problems in setting up projects for one or the other, however I am facing an issue when trying to use both within the same project.

Details

I have a project whose purpose is mainly to run a series of Unit tests and I wanted to run tests in both Arduino and esp-idf frameworks. For this purpose, my platformio.ini file looks something like this (Simplified to omit irrelevant bits):


; Common options for all the environments

[env]

monitor_speed = 115200

monitor_echo = true

monitor_eol = LF

; Common options for all the esp32 arduino environments

[esp32_arduino_common]

platform = espressif32@5.0.0

board = m5stack-core2

framework = arduino

build_flags =

-DARDUINO_LOOP_STACK_SIZE=32768

-DACTIVE_FRAMEWORK=ARDUINO

test_framework = custom

lib_deps =

; here are some libs that I omitted

[env:arduino_esp32_blue]

extends = esp32_arduino_common

build_flags =

${esp32_arduino_common.build_flags}

-DCOLOUR=BLUE

; Common for all the esp-idf environments

[esp32_espidf_common]

platform = espressif32 @6.4.0 # Make sure it uses esp-idf = 5.1.0

board = m5stack-core2

framework = espidf

test_framework = custom

build_flags =

-DACTIVE_FRAMEWORK=ESPIDF

[env:espidf_blue]

extends = esp32_espidf_common

build_flags =

${esp32_espidf_common.build_flags}

-DCOLOUR=BLUE

Then within the test directory, I have a series of test_xyz.h files and a test_main.cpp that takes care of running the tests. The latter looks like this:


#include "test_functions.h"

#if (ACTIVE_FRAMEWORK == ARDUINO)

void setup() {

delay(2000);

run_test_functions();

}

void loop() {

}

#elif (ACTIVE_FRAMEWORK == ESPIDF)

void app_main() {

run_test_functions();

}

#endif

Where run_test_functions() takes care of calling unity begin/end.

Issue

If I run my tests with this configuration, arduino_esp32_blue works fine, espidf_blue fails to compile.

If I run my tests by renaming test_main.cpp to test_main.c, espidf_blue works fine, arduino_esp32_blue fails to compile.

It is clear that when using arduino as framework, a C++ compiler must be used (unsurprisingly I’d add), whereas when using esp-idf, a C compiler is preferable (in this specific situation).

The issue seems to be that both configurations can only be compiled for either C or C++.

I want to avoid adapting my C code, that runs perfectly for esp-idf, to C++ for the sake of the compiler.

Attempted solutions

I tried to define two different main files, one for each framework (test_main.cpp, test_main_c.c) and filter the files by adding either of the following options in the platformio.ini file:

  • build_src_filter = -<test/test_main.cpp>

  • test_ignore = test_main.cpp

With no success.

Question

Simply put, is there a way to tell platformio to “compile this env for C++, compile this other env for C”? Or alternatively “Use this main.cpp for this env and this other main.c for this other env”?

This function can still be defined in .cpp file, but then you just have to use C linkage so that it’s found as it’s originally declared symbol name.

I.e., simply write

extern "C" void app_main() {

instead.

This is documented.

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/cplusplus.html#defining-app-main-in-c

Thank you for the quick reply. I somehow missed that, however already tried adding extern "C" guards. Tried this solution too, but I still get a long list of C++ related warnings.
I ended up suppressing the warnings and it now compiles fine, although not the ideal solution as I wouldn’t normally compile my esp-idf projects for C++.

Thank you very much for your help!