ttlappalainen / NMEA2000

NMEA2000 library for Arduino
507 stars 211 forks source link

Odd intermittent reoccurance of old ESP-IDF-related issue #407

Open nicklasb opened 1 week ago

nicklasb commented 1 week ago

I am having a weird issue in that i occationally get this old ESP-IDF-related problem again:

%HOME%/.platformio/packages/toolchain-xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/bin/ld.exe: .pio/build/Hat_Labs_SH-ESP32/esp-idf/NMEA2000/libNMEA2000.a(N2kMsg.cpp.o): in function `round':
%HOME%/\Projects\some_project/managed_components\NMEA2000\src/N2kMsg.cpp:52: multiple definition of `round'; %HOME%/.platformio/packages/toolchain-xtensa-esp-elf/bin/../lib/gcc/xtensa-esp-elf/13.2.0/../../../../xtensa-esp-elf/lib/esp32/no-rtti\libm.a(libm_a-s_round.o):/builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/newlib/newlib/libm/common/s_round.c:54: first defined here

Anyone else seeing this? As it is intermittent I am thinking that it might have something with build scripts running in parallell or something or some build thingy trying to be intelligent and thus ending up non-deterministic.

ttlappalainen commented 1 week ago

round has been originally declared by using define. Now if it is proper function, test #if !defined(round) does not help and it will be redeclared.

nicklasb commented 1 week ago

If I understand you correctly; Yes, that is the original problem. And I see that there already are in #if !defined(round) in the code, so basically, this shouldn't happen.

The thing I am thinking that might be happening is that in some cases, the NMEA2000 library is loaded before the extensa-esp-elf implementation. I am thinking that the "first defined here" doesn't perhaps reflect the order in which the libraries were loaded. I haven't had the issue for a day now, I will se if I will encounter it again and try to recreate it then.

Some Chatgpt-solutions included namespaces (nah), and basing it on __cplusplus (in C++) or _ISOC99_SOURCE (in C), but I am not sure how precise that is.

ttlappalainen commented 1 week ago

if it has been defined

define round(v) ...

test works. But if they have changed it as double round(double v) {... Test does not see it existing and declares it again.

nicklasb commented 1 week ago

Aha, I understand. I will try with different variants if and when I run into it again. Closing this for now.

nicklasb commented 1 week ago

Ok, so now for some reason it is suddently persistent, so now I have to fix it in some way. Wouldn't something like this cover the situation?

if !defined(round) && !defined(_ISOC99_SOURCE)

If it non-defined-defined && it is not having the ISO99 feature set, then declare the function. Who would declare the function and not set _ISOC99_SOURCE?

Obviously I do not have as many cases to test with as you do.

ttlappalainen commented 1 week ago

Maybe better solution would be to change it to N2kRound and if compiler >=99 inline it to round.