Search code examples
c++cesp8266arduino-idearduino-esp8266

Undefined reference with xtensa-lx106-elf-gcc?


I'm using Arduino IDE and planning on later moving to a VSCode/Makefile solution.

I have a project that compiles and runs fine if all the code belongs in the main sketch. Once I separate the code, the linkage step fails.

I've boiled it down to a simple demonstration:

What works

Sketch file

#ifdef __cplusplus
extern "C" {
#endif
void methodCall();
#ifdef __cplusplus
}
#endif
void setup() {
  // put your setup code here, to run once:

}

void loop() {
 methodCall();
}

void methodCall() {
  random(0,1);
 }

What fails

Sketch file

#ifdef __cplusplus
extern "C" {
#endif
void methodCall();
#ifdef __cplusplus
}
#endif
void setup() {
  // put your setup code here, to run once:

}

void loop() {
 methodCall();
}

Methods.c file added to the Arduino IDE sketch via Sketch>'Add File'

void methodCall() {
  random(0,1);
 }

Platform.txt modification?

Some questions suggest adding -lstd++ to the compiler.c.elf.libs line in the ESP8266 folder's platform.txt file, but it doesn't seem to yield any result for me, and besides the earlier build.stdcpp_lib=-lstdc++ line seems to take care of that.

Note about headers

The errors are identical if the method declaration is externalized in a header file #included by the source files. The random function is declared in the esp8266/Arduino.h and defined here.

What am I doing wrong?


Solution

  • Arduino's Github

    According to https://github.com/esp8266/Arduino/issues/1283, where Links2004 states:

    random is a API function from Arduino not working on C

    the answer seems to be to replace calls to replace calls to random to calls to rand. Testing demonstrates that both in that demonstration source and the real source, replacing random() and randomSeed with rand and srand-based modifications compiles and runs correctly.

    Fixed?

    If someone has a better option that allows the use of the C++ random function from the C code, I'll gladly replace my "solution" with theirs. It frustrates me that C code disguised by Arduino as C++ compiles, but the same source cut into several files doesn't, and requires the source itself call different functions.