Lets imagine the problem in the small. Imagine you have two C source files ... let us call one "idf.c" and the other "app.c". Now imagine inside idf.c you have the following:
Code: Select all
void myFunc() {
printf("Hello world!\n");
}
Code: Select all
void main() {
myFunc();
}
We can link idf.o to produce an executable. From that executable, we can ask it for the actual addresses of all the functions it exports ... this will include "myFunc". However, since we have produced an executable, this will be a relocated actual address. We can then flash the executable into the ESP32 and it will just "sit there".
Since we have the list of relocated actual addresses of all the functions from idf.o we can add those to a linker script. We can then link app.o with the linker script which will produce an executable for app. This works because there will be no unresolveds. The linker script satisfied the missing "myFunc". Since we knew the relocated address of myFunc, the code that is generated for the app executable will correctly call the correct address for myFunc on reference.
Scaling this up to the full ESP-IDF "just worked". We can compile the ESP-IDF, create an "app_main" entry point and ask the resulting ELF for ALL the symbols exported from it. We can then take all those symbols and add them to a linker script and compile/link a normal ESP-IDF application and it will just work.