I’m having trouble getting some simple code to compile or link - I get different behavior with the online IDE compared to building on the command line. (I’m actually using NetBeans, configured to use the existing makefile. I managed to build the default tinker application no problem.)
Here’s the app code:
class A
{
public:
virtual int f()=0;
virtual ~A() {}
};
class B : A
{
public:
virtual int f() { return 1; }
};
B b;
void setup() {}
void loop() { }
When I compile this on the command line, I get these errors:
Building target: core-firmware.elf
Invoking: ARM GCC C++ Linker
r:/sdk/spark/tools/gcc/bin/arm-none-eabi-g++ -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -I../inc -I../../core-common-lib/CMSIS/Include -I../../core-common-lib/CMSIS/Device/ST/STM32F10x/Include -I../../core-common-lib/STM32F10x_StdPeriph_Driver/inc -I../../core-common-lib/STM32_USB-FS-Device_Driver/inc -I../../core-common-lib/CC3000_Host_Driver -I../../core-common-lib/SPARK_Firmware_Driver/inc -I../../core-communication-lib/lib/tropicssl/include -I../../core-communication-lib/src -I. -ffunction-sections -Wall -fmessage-length=0 -MD -MP -MF core-firmware.elf.d -DUSE_STDPERIPH_DRIVER -DSTM32F10X_MD -DDFU_BUILD_ENABLE obj/src/application.o obj/src/main.o obj/src/newlib_stubs.o obj/src/spark_utilities.o obj/src/spark_wiring.o obj/src/spark_wiring_i2c.o obj/src/spark_wiring_interrupts.o obj/src/spark_wiring_ipaddress.o obj/src/spark_wiring_network.o obj/src/spark_wiring_print.o obj/src/spark_wiring_servo.o obj/src/spark_wiring_spi.o obj/src/spark_wiring_stream.o obj/src/spark_wiring_string.o obj/src/spark_wiring_tcpclient.o obj/src/spark_wiring_tcpserver.o obj/src/spark_wiring_udp.o obj/src/spark_wiring_usartserial.o obj/src/spark_wiring_usbserial.o obj/src/spark_wlan.o obj/src/stm32_it.o obj/src/usb_desc.o obj/src/usb_endp.o obj/src/usb_istr.o obj/src/usb_prop.o obj/src/wifi_credentials_reader.o obj/startup/startup_stm32f10x_md.o --output core-firmware.elf -T../linker/linker_stm32f10x_md_dfu.ld -nostartfiles -Xlinker --gc-sections -L../../core-common-lib/build -lcore-common-lib -L../../core-communication-lib/build -lcore-communication-lib -Wl,-Map,core-firmware.map
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld.exe: core-firmware.elf section `.text' will not fit in region `FLASH'
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/bin/ld.exe: region `FLASH' overflowed by 34296 bytes
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
r:/sdk/spark/tools/gcc/bin/../lib/gcc/arm-none-eabi/4.8.3/../../../../arm-none-eabi/lib/armv7-m\libg.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
collect2.exe: error: ld returned 1 exit status
make: *** [core-firmware.elf] Error 1
In short
- the .text section won’t fit into flash - some 34K too large
- and lots of undefined stream functions (lseek, read, etc…)
I can make the error disappear by commenting out the virtual destructor,
// virtual ~A() {}
When I paste the same code in the online IDE and hit “verify”, I get
../786c930e31b1b7ebd0009388e661faed7df3ac721ec8fcb9d9b5f2de4ee1/the_user_app.cpp:3:15: error: 'virtual' outside class declaration
make: *** [../786c930e31b1b7ebd0009388e661faed7df3ac721ec8fcb9d9b5f2de4ee1/the_user_app.o] Error 1
I hit this problem when trying to port the Arduino-based fermentation controller brewpi onto the spark. I got the same error, because we use virtual descructors and pure virtual methods in a polymorphic class hierarchy. The arduino code compiles down to 25K, so I was surprised when the linker complained the code was 130K too big to fit into flash!
It looks like a bug to me - can anyone else reproduce this error?
My ARM gcc version is
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.8.3 20131129 (release) [ARM/embedded-4_8-branch revision 205641]
Thanks!
mat.