Undefined reference for external function in pre-built library
Posted: Fri Jan 05, 2024 3:06 pm
I have a curious linker problem with an "extern" declared function in a prebuilt library which I don't really understand.
Short background: I got a prebuilt static library (.a) that requires some functions to be defined by the application to result in an executable. Let's call such a function prebuilt_ext_func().
I was able to break down my use case to the IDF example at build_system/cmake/import_prebuild. There, only the declaration and call of the prebuilt_ext_func() was added to the prebuilt.c file
prebuild.c:
The example trims the whole build process to only build the components without linking them to an executable resulting in a "libprebuilt.a" file.
The according lib is then copied into the actual application's "main" component directory and referenced in its CMakeLists.txt via add_prebuilt_library().
If I now define the prebuilt_ext_func() in the application's main component main.c file everything compiles and links (and actually runs on target). The symbol is also present in libmain.a:
But if I add an additional source file named prebuilt_ext_func.c to the main component instead (and include them in CMakeLists.txt file) I get an "undefined reference to `prebuilt_ext_func'" error from the linker.
The compiler actually runs through prebuilt_ext_func.c (validated via #error statement in code), performing an nm call to libmain.a also shows that the symbol prebuilt_ext_func() is present:
For a complete overview I attached the modified example project.
The simple question I have: Where is the error? From my thoughts both approaches should behave identical from linker's perspective. I would appreciate any hints...
Thanks,
André
Short background: I got a prebuilt static library (.a) that requires some functions to be defined by the application to result in an executable. Let's call such a function prebuilt_ext_func().
I was able to break down my use case to the IDF example at build_system/cmake/import_prebuild. There, only the declaration and call of the prebuilt_ext_func() was added to the prebuilt.c file
prebuild.c:
Code: Select all
#include "esp_ota_ops.h"
#include "esp_partition.h"
#include "esp_log.h"
extern void prebuilt_ext_func(const char *);
const char *TAG = "prebuilt";
void prebuilt_func(void)
{
const esp_partition_t* running_partition = esp_ota_get_running_partition();
ESP_LOGI(TAG, "The running partition is '%s'!", running_partition->label);
prebuilt_ext_func("Hello from prebuilt lib");
}
Code: Select all
CMakeLists.txt
...
# Since we're only interested in the prebuilt library, trim
# the build
set(COMPONENTS prebuilt main esptool_py)
...
If I now define the prebuilt_ext_func() in the application's main component main.c file everything compiles and links (and actually runs on target). The symbol is also present in libmain.a:
Code: Select all
$ nm -g -C build/esp-idf/main/libmain.a
main.c.obj:
00000000 T app_main
00000000 T prebuilt_ext_func
U prebuilt_func
U printf
The compiler actually runs through prebuilt_ext_func.c (validated via #error statement in code), performing an nm call to libmain.a also shows that the symbol prebuilt_ext_func() is present:
Code: Select all
$ nm -g -C build/esp-idf/main/libmain.a
main.c.obj:
00000000 T app_main
U prebuilt_func
prebuilt_ext_func.c.obj:
00000000 T prebuilt_ext_func
U printf
For a complete overview I attached the modified example project.
The simple question I have: Where is the error? From my thoughts both approaches should behave identical from linker's perspective. I would appreciate any hints...
Thanks,
André