You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am hitting the weirdest problem trying to use this package with the GCC ARM tools & Philhower RP2040 core. I just want to ask: is it possible to configure Arduino-CMake-Toolchain to build the final .elf/.uf2 file from separate object files, like arduino-cli does, instead of bundling them into libraries first? Because as far as I can tell, I'm hitting some kind of compiler bug or other problem when I link from libraries via cmake, but when I link from objects with arduino-cli everything is kosher.
So that's my question/issue for this repo. Below is a long, detailed description of the problem that maybe doesn't belong in this repo. I dunno yet if it's GCC's problem or Adafruit's problem or Earl Philhower's problem, but I just want to document it somewhere for the moment. Maybe the solution is obvious to other people.
I'm using an M1 Mac to compile an Arduino sketch for the RP2040 MCU. I'm using these GCC-ARM versions, provided by the Homebrew project:
» arm-none-eabi-gcc --version
arm-none-eabi-gcc (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 13.2.1 20231009
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
» arm-none-eabi-ld -v
GNU ld (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 2.41.0.20231009
This is an example sketch that shows the problem. It's just the basic Blink example, plus opening a USB serial connection and writing a message. I'm using the Adafruit-TinyUSB library option of the core (as opposed to the picousb option) so USE_TINYUSB is defined.
#ifdef USE_TINYUSB
#include <Adafruit_TinyUSB.h>
#endif
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
// initialize USB Serial
Serial.begin(115200);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
Serial.println("boop");
}
The code compiles and runs correctly with arduino-cli.
With the build-system generated by Arduino-CMake-Toolchain, the code compiles and runs, the blinking happens correctly, but the serial output does not.
Examining the build artifacts, it looks like the .elf output of the Arduino-CMake build is missing some symbols (TinyUSB_Device_Init for one) that initialize the Adafruit-TinyUSB library.
Here's the arduino-cli compiled .elf:
... and in fact, in the cmake-compiled version of the core main() routine, ld has actually replaced an unresolved link to <TinyUSB_Device_Init> with a nop instead of reporting any kind of link failure. Should ld ever do such a thing?
TinyUSB_Device_Init is called from main.cpp in the Philhower RP2040 Arduino core. This is the relevant code section with some undefined #ifdefs removed:
#ifdef USE_TINYUSB
TinyUSB_Device_Init(0);
#endif
Here's the relevant section from the (working) arduino-cli version, obtained with arm-none-eabi-objdump -D -S abuild/Blink.ino.elf > Blink.ino.asm:
That's all as you'd expect. But in the CMake-compiled version, obtained with arm-none-eabi-objdump -D -S cbuild/Blink.elf > Blink.asm, the same section is compiled like this:
... which means the call is just silently skipped. And the compiled code of <TinyUSB_Device_Init> is not present at all.
In both builds USE_TINYUSB was defined for every compile step. (I tried removing the #ifdef clause to force inclusion, with the same result.)
In both builds, main.cpp compiles correctly but unlinked. arduino-cli leaves it in make.cpp.o, while the cmake build places it in the library lib_arduino_lib_core.a, but the compiled code is the same:
In both builds, TinyUSB_Device_Init() compiles correctly but unlinked. cmake puts in in a library, lib_arduino_lib_Adafruit_TinyUSB.a, arduino-cli has it in Adafruit_TinyUSB_API.cpp.o, but the code is identical:
... and the other symbols all match as well. The code is all there, it's compiled, it's just not linked correctly.
Obviously both toolchains are eventually just calling arm-none-eabi-g++ and the other ARM-gcc tools. They appear to be calling them with all the same flags. This is the final link command with arduino-cli (super-long, gack, sorry):
The only significant difference i can find in the build output between the two processes is that the cmake process first bundles the objects into libraries, and then does the final link against those libraries, while the arduino-cli process compiles a zillion separate object files and then does the final link against the entire list of them.
That shouldn't make a difference in the compiled code, right?
The text was updated successfully, but these errors were encountered:
I am hitting the weirdest problem trying to use this package with the GCC ARM tools & Philhower RP2040 core. I just want to ask: is it possible to configure
Arduino-CMake-Toolchain
to build the final .elf/.uf2 file from separate object files, likearduino-cli
does, instead of bundling them into libraries first? Because as far as I can tell, I'm hitting some kind of compiler bug or other problem when I link from libraries viacmake
, but when I link from objects witharduino-cli
everything is kosher.So that's my question/issue for this repo. Below is a long, detailed description of the problem that maybe doesn't belong in this repo. I dunno yet if it's GCC's problem or Adafruit's problem or Earl Philhower's problem, but I just want to document it somewhere for the moment. Maybe the solution is obvious to other people.
I'm using an M1 Mac to compile an Arduino sketch for the RP2040 MCU. I'm using these GCC-ARM versions, provided by the Homebrew project:
This is an example sketch that shows the problem. It's just the basic Blink example, plus opening a USB serial connection and writing a message. I'm using the Adafruit-TinyUSB library option of the core (as opposed to the picousb option) so
USE_TINYUSB
is defined.The code compiles and runs correctly with
arduino-cli
.With the build-system generated by Arduino-CMake-Toolchain, the code compiles and runs, the blinking happens correctly, but the serial output does not.
Examining the build artifacts, it looks like the .elf output of the Arduino-CMake build is missing some symbols (
TinyUSB_Device_Init
for one) that initialize the Adafruit-TinyUSB library.Here's the
arduino-cli
compiled .elf:And here's the
cmake
-compiled .elf:... and in fact, in the
cmake
-compiled version of the coremain()
routine,ld
has actually replaced an unresolved link to<TinyUSB_Device_Init>
with anop
instead of reporting any kind of link failure. Shouldld
ever do such a thing?TinyUSB_Device_Init
is called frommain.cpp
in the Philhower RP2040 Arduino core. This is the relevant code section with some undefined#ifdef
s removed:Here's the relevant section from the (working) arduino-cli version, obtained with
arm-none-eabi-objdump -D -S abuild/Blink.ino.elf > Blink.ino.asm
:and the compiled code of
<TinyUSB_Device_Init>
is also present in that .elf file:That's all as you'd expect. But in the CMake-compiled version, obtained with
arm-none-eabi-objdump -D -S cbuild/Blink.elf > Blink.asm
, the same section is compiled like this:... which means the call is just silently skipped. And the compiled code of
<TinyUSB_Device_Init>
is not present at all.In both builds
USE_TINYUSB
was defined for every compile step. (I tried removing the#ifdef
clause to force inclusion, with the same result.)In both builds,
main.cpp
compiles correctly but unlinked.arduino-cli
leaves it inmake.cpp.o
, while thecmake
build places it in the librarylib_arduino_lib_core.a
, but the compiled code is the same:In both builds,
TinyUSB_Device_Init()
compiles correctly but unlinked.cmake
puts in in a library,lib_arduino_lib_Adafruit_TinyUSB.a
,arduino-cli
has it inAdafruit_TinyUSB_API.cpp.o
, but the code is identical:... and the other symbols all match as well. The code is all there, it's compiled, it's just not linked correctly.
Obviously both toolchains are eventually just calling
arm-none-eabi-g++
and the other ARM-gcc tools. They appear to be calling them with all the same flags. This is the final link command witharduino-cli
(super-long, gack, sorry):And here is the final link step with
cmake
(shorter but still horribly long):The only significant difference i can find in the build output between the two processes is that the
cmake
process first bundles the objects into libraries, and then does the final link against those libraries, while thearduino-cli
process compiles a zillion separate object files and then does the final link against the entire list of them.That shouldn't make a difference in the compiled code, right?
The text was updated successfully, but these errors were encountered: