Open dmalenic opened 2 years ago
Thanks @dmalenic
In case it will be useful to the developers, I'll provide a minimal demo of the bug:
$ arduino-cli version
arduino-cli.exe Version: nightly-20220110 Commit: 60c1c98 Date: 2022-01-10T01:28:45Z
$ SKETCH_PATH="/tmp/ExternCBug"
$ mkdir "$SKETCH_PATH"
$ echo "#ifdef __cplusplus
extern \"C\" {
#endif
void dummy(void) {}
#ifdef __cplusplus
}
#endif
void setup() {}
void loop() {}
" > "$SKETCH_PATH"/ExternCBug.ino
$ arduino-cli compile --fqbn arduino:avr:uno --preprocess "$SKETCH_PATH"
#include <Arduino.h>
#line 1 "C:\\Users\\per\\AppData\\Local\\Temp\\ExternCBug\\ExternCBug.ino"
#ifdef __cplusplus
extern "C" {
#endif
#line 4 "C:\\Users\\per\\AppData\\Local\\Temp\\ExternCBug\\ExternCBug.ino"
extern "C" void dummy(void);
#line 8 "C:\\Users\\per\\AppData\\Local\\Temp\\ExternCBug\\ExternCBug.ino"
void setup();
#line 9 "C:\\Users\\per\\AppData\\Local\\Temp\\ExternCBug\\ExternCBug.ino"
void loop();
#line 4 "C:\\Users\\per\\AppData\\Local\\Temp\\ExternCBug\\ExternCBug.ino"
void dummy(void) {}
#ifdef __cplusplus
}
#endif
void setup() {}
void loop() {}
Vaguely related to https://github.com/arduino/arduino-cli/issues/1591
I think this is another case where the automatic prototype generation that arduino-cli does cannot cope with more complicated sketches. What I suspect happens, is that a prototype is generated for the loop() and setup() functions. IIRC prototypes are inserted directly before the first other function definition or declaration found in the .ino file (so they can end up after any initial type declarations when those are before all functions). In this case, that puts the prototypes inside the extern "C" blocks, which leads to conflicting declarations.
I'm not sure, but I suspect that this is going to be hard to fix (certainly with the ctags-based approached, but even for the clang-based parsing approach this probably needs some special casing). Also, if you're working with external C functions like this, chances are you're already a more advanced that does not really need the auto-generated prototypes at all.
Here's some things you could do/try to get your code working right now:
extern "C" void dummy(void) {}
) rather than a block. Note that .ino files are always compiled as C++, so you do not need the #ifdef __cplusplus
here (those are needed in .h files that might be included from C or C++ code).I've updated the issue title, as this is not an ESP32-specific issue.
Additional observation, that might be helpful. My original report was Arduino IDE
specific, and within Arduino IDE
the problem is limited to ESP32
boards (don't have ESP 8266
board to test). As @per1234 showed, if arduino-cli
is used the bug is not ESP32
specific.
I just tried script @per1234 provided and it breaks. But If I load the sketch his script created /tmp/ExternCBug/ExternCBug.ino
to Arduino IDE
, and select target Arduino UNO
(as in @per1234 example), it compiles and loads to the UNO board, as well as on MEGA 2560, Nano Every, DUE, MKR Vidor 4000, MKR WiFi 1010, Raspberry Pi Pico and Teensy 4.1. I tried arduino-cli
on all those platforms (except Teensy) and it breaks on all of them exactly as @per1234 noticed.
Hopefully this observation helps, at least with resolving the arduino-cli
problem for AVR and ARM boards. Maybe there are two separate but related issues - one with IDE and one with CLI.
Describe the problem
Compiling the following blink sketch for ESP32 board:
results in errors:
Arduino CLI version
Original report
Arduino IDE 1.8.19
Last verified with
60c1c98
Operating system
Operating system version
Additional context
If the
extern "C" { ... }
block does not define any function but only variables, or if the wholeextern "C" { ... }
block is moved after the definition ofsetup
andloop
functions, the code compiles successfully.If the
extern "C" { ... }
block only declares functions, and functions are defined in a separate module (file), everything compiles correctly.The files with
.cpp
extensions do not have this problem, and allow mixingC
linkage functions defined withinextern "C" { ... }
blocks.Looks like, when the compiler encounters a
C
linkage function definition in a sketch file (.ino
extension), it assumes that the rest of file defines onlyC
linkage functions.The error can not be reproduced when compiling for boards using AVR or ARM processors that I could test with.
Related
Issue checklist