No I started with #if 0
at the top of the library and in the sketch code removed all referenced to the library and it’s objects, then it compiled straight away. Then I slowly enabled parts of the library’s .cpp code again, moving the #if 0
more and more downwards, and enabling references to the objects again, until the compilation resulted in an error. The last thing I enabled then is the cause for the error.
I could recreate the problem in the most minimal way
[env:ut61e-wifi]
platform = espressif8266
board = d1_mini
framework = arduino
src\main.cpp:
#include <Arduino.h>
#include <math.h>
#include <tgmath.h>
#include <buggy_lib.h>
void setup() {
long double res = (long double) Serial.parseFloat();
res = ceill(res);
Serial.print("Result: ");
Serial.println((double) res);
//make use of the global variable, otherwise we don't get that error.
for(auto& x : RANGE_VOLTAGE) {
Serial.println(x.first);
}
}
void loop() {
}
lib\buggy_lib\buggy_lib.h:
#ifndef _BUGGY_LIB_H
#define _BUGGY_LIB_H
#include <cstdlib> // Needed for uint8_t
#include <string>
#include <unordered_map>
using std::unordered_map;
using std::string;
struct Range_Dict
{
float value_multiplier;
int dp_digit_position;
string display_unit;
};
typedef unordered_map<uint8_t, Range_Dict> range_dict_map_t;
extern range_dict_map_t RANGE_VOLTAGE;
#endif /* _BUGGY_LIB_H */
lib\buggy_lib\buggy_lib.cpp:
#include "buggy_lib.h"
range_dict_map_t RANGE_VOLTAGE = {
{0b0110000, {1e0, 4, "V"}}, //2.2000V
{0b0110001, {1e0, 3, "V"}}, //22.000V
{0b0110010, {1e0, 2, "V"}}, //220.00V
{0b0110011, {1e0, 1, "V"}}, //2200.0V
{0b0110100, {1e-3, 2,"mV"}} //220.00mV
};
Results in the same
c:/users/max/.platformio/packages/toolchain-xtensa@2.100300.0/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: C:\Users\Max\.platformio\packages\framework-arduinoespressif8266\tools\sdk\lib\libstdc++.a(math_stubs_long_double.o): in function `ceill':
/workdir/repo/gcc-gnu/libstdc++-v3/src/c++98/math_stubs_long_double.cc:76: multiple definition of `ceill'; c:/users/max/.platformio/packages/toolchain-xtensa@2.100300.0/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/lib\libm.a(lib_a-ceill.o):/workdir/repo/newlib/newlib/libm/common/ceill.c:38: first defined here
collect2.exe: error: ld returned 1 exit status
error.
I’ve also verified that this does indeed compile with the same library code and the Arduino IDE, using the same core version PlatformIO does (3.0.1, not the latest 3.0.2).
So now the problem is constricted to specifcally PlatformIO and a very small amount of code.
I’ll check whether copying the Arduino IDE’s compiler makes a difference, or whether I can spot a difference in the compiler commands between them.
An interesting thing is also that the error only occurrs when the call to ceill
is there, otherwise it’s gone.
Changing the float
to double
in the struct definition of the library does not make a difference – I thought since the struct does 1e0
which is a double and then has to be downconverted to an int
it would make a difference, but no.