Here is main.cpp:
Code: Select all
#include <stdio.h>
extern "C"
{
void app_main(void);
}
void app_main(void)
{
puts("app_main() runs");
}
void appmain_ctor (void) __attribute__ ((constructor));
void appmain_ctor (void)
{
puts("appmain_ctor() runs");
}
All looks good. So, now add another file to the project, called extra.cpp:appmain_ctor() runs
app_main() runs
Code: Select all
#include <stdio.h>
void extra_ctor (void) __attribute__ ((constructor));
void extra_ctor (void)
{
puts("extra_ctor() runs");
}
Where is the "extra_ctor() runs"?appmain_ctor() runs
app_main() runs
When I do the same on a standard g++ build on my desktop, I get the correct output. But, then I'm just putting the main.cpp and extra.cpp on the same build command line.
The ESP32 IDF seems to put everything in the 'main' directory into a libmain.a static library:
$ xtensa-esp32-elf-nm build/main/libmain.a
But then that is linked together with all the framework components, to produce the resulting elf/bin firmware.extra.o:
00000000 T _Z10extra_ctorv
U puts
main.o:
00000000 T _Z12appmain_ctorv
00000000 T app_main
U puts
The issue is that as extra.cpp is not referenced, and not explicitly linked in on the command line like a normal straightforward build, it is just not included in the elf/bin firmware. It behaves like an unused component.
It seems that the gcc people have thought about this and have a '-Wl,--no-whole-archive' option to workaround this, but I can't find a simple way of getting that infront of the '-lmain' on the build command line. We'd only want to do this for libmain.
I know that I can probably work around this by making main.cpp require something from extra.cpp, but those extra.cpp modules are supposed to silently extend the system if they are added to the project, and having to change the main.cpp to reference them is messy.
Any ideas?