esp-open-sdk
esp-open-sdk copied to clipboard
Include C++ examples with and without standard library
Hi! First of all thanks a lot for the work you've done to make it easy to get a fully functional ESP8266 toolchain. There's already an example for building a small project with exclusively C source files. Making it build C++ source files is relatively easy working from this example, as it works out of the box with the specified compiler and linker flags. However, if you want to use the C++ standard library at all, things get more complicated.
This is as far as I've got so far:
CC = xtensa-lx106-elf-gcc
CXX = xtensa-lx106-elf-g++
CFLAGS = -I. -Os -g -O2 -Wall -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH
CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions -std=c++11
LDLIBS = -Wl,--start-group -lmain -lnet80211 -lwpa -llwip -lpp -lphy -lc -Wl,--end-group -lgcc -lstdc++
LDFLAGS = -Teagle.app.v6.ld
example-0x00000.bin: example
esptool.py elf2image $^
example: example.o
example.o: example.cpp
flash: example-0x00000.bin
esptool.py --port=/dev/tty.wchusbserial1420 write_flash --flash_mode dio 0 example-0x00000.bin 0x10000 example-0x10000.bin
clean:
rm -f example example.o example-0x00000.bin example-0x10000.bin
But the linker fails:
❯ make flash
xtensa-lx106-elf-gcc -Teagle.app.v6.ld example.o -Wl,--start-group -lmain -lnet80211 -lwpa -llwip -lpp -lphy -lc -Wl,--end-group -lgcc -lstdc++ -o example
/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/bin/ld: cannot find crt1-sim.o: No such file or directory
/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/bin/ld: cannot find _vectors.o: No such file or directory
collect2: error: ld returned 1 exit status
make: *** [example] Error 1
Googling shows some people hitting similar issues, but I haven't been able to find a solution.
ld: cannot find crt1-sim.o: No such file or directory ld: cannot find _vectors.o: No such file or directory
Having -nostdlib in LDLIBS should fix that. Or you can try changes from PR https://github.com/pfalcon/esp-open-sdk/pull/209
Having -nostdlib in LDLIBS was one of the things I tried, and it indeed did not work:
❯ make
xtensa-lx106-elf-gcc -Teagle.app.v6.ld -nostdlib example.o -Wl,--start-group -lmain -lnet80211 -lwpa -llwip -lpp -lphy -lc -Wl,--end-group -lgcc -lstdc++ -lsupc++ -nostdlib -o example
/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/lib/libstdc++.a(del_op.o):(.literal._ZdlPv+0x0): undefined reference to `free'
/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/lib/libstdc++.a(del_op.o): In function `operator delete(void*)':
/Volumes/case-sensitive/esp-open-sdk/crosstool-NG/.build/src/gcc-4.8.5/libstdc++-v3/libsupc++/del_op.cc:47: undefined reference to `free'
/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/lib/libstdc++.a(new_op.o):(.literal._Znwj+0x4): undefined reference to `abort'
/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/lib/libstdc++.a(new_op.o):(.literal._Znwj+0x8): undefined reference to `malloc'
/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/lib/gcc/xtensa-lx106-elf/4.8.5/../../../../xtensa-lx106-elf/lib/libstdc++.a(new_op.o): In function `operator new(unsigned int)':
/Volumes/case-sensitive/esp-open-sdk/crosstool-NG/.build/src/gcc-4.8.5/libstdc++-v3/libsupc++/new_op.cc:56: undefined reference to `abort'
/Volumes/case-sensitive/esp-open-sdk/crosstool-NG/.build/src/gcc-4.8.5/libstdc++-v3/libsupc++/new_op.cc:58: undefined reference to `malloc'
collect2: error: ld returned 1 exit status
make: *** [example] Error 1
So it looks like it's missing a few symbols that are defined in the system libraries?
I'll give that PR a shot later, thanks for your help!
del_op.cc:47: undefined reference to
free' new_op.cc:56: undefined reference toabort' new_op.cc:58: undefined reference to `malloc'
Oh, yes, right. You need something like the following in order to make libstdc++/libsupc++ happy:
void *operator new(size_t size)
{
return os_malloc(size);
}
void *operator new[](size_t size)
{
return os_malloc(size);
}
void operator delete(void * ptr)
{
os_free(ptr);
}
void operator delete[](void * ptr)
{
os_free(ptr);
}
extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
extern "C" void abort()
{
while(true); // enter an infinite loop and get reset by the WDT
}
void __cxa_pure_virtual(void)
{
abort();
}
void __cxa_deleted_virtual(void)
{
abort();
}
I'll give that PR a shot later
Never mind, it won't fix the above missing symbols.