I'm working on some embedded code that is shipped as a static library. We would like to remove all internal symbols from the library and keep only the API symbols visible.
Here's an example of what we want to do: imagine that you have a file called internal.c
and one called api.c
that look like that:
/* internal.c */
int fibonacci(int n)
{
/* Compute the nth Fibonacci number and return it */
}
/* api.c */
#include "internal.h"
#include <stdio.h>
void print_fibonacci(n)
{
printf("Fibonacci(%d): %d\n", n, fibonacci(n));
}
The user should only have access to the print_fibonacci
function while all internal symbols such as the fibonacci
function should be resolved before shipping. That means that the user should be able to define his own function called fibonacci
without having to worry about conflicts with the library.
We already tried internal linkage by using ld --relocatable
, but we can't seem to remove the symbols afterwards using objcopy. Is this feasible at all?
Thanks for the help!
Edit: The user-defined fibonacci
function should not replace the library-defined function, they should just be able to coexist. Basically I'm looking for a solution to solve naming conflicts.
Strip. If you still see symbols that shouldn't be in there in the file when checking your build product using nm , you may have to call strip -r -S -x on your library, which will remove debug symbols and “local” symbols.
A .o file inside a library might contain symbols (functions, variables etc.) that are not used by your program. At link time, a static library can have unresolved symbols in it, as long as you don't need the unresolved symbols, and you don't need any symbol that is in a .o file that contains an unresolved symbol.
Dynamic linking and Dynamic Libraries Dynamic Linking doesn't require the code to be copied, it is done by just placing name of the library in the binary file. The actual linking happens when the program is run, when both the binary file and the library are in memory.
Static libraries are essentially a bunch of object files. All object files in a static library are treated as if they were provided individually by the linker. Generally, it is not possible to make the linker treat some symbols as internal, the linker simply does not have enough information to do so.
Here are a couple of strategies to solve these issues:
Construct a separate name space for non-public functions in your library. For instance, your fibonacci
function can be placed in an internal name space libfoo_internal_fibonacci
. If you're desparate, you can use macros in your internal header files like this:
#define fibonacci INTERNAL_PREFIX ## fibonacci
This would allow you to change the prefix arbitrarily on compile time. I suggest to not do that as it makes debugging harder. If you can cope with longer internal names, this would be a good strategy.
Make all internal functions static
and merge translation units so that each internal function is only used by one translation unit. This might solve your problem but it makes the resulting programs larger: Most linkers can either take an object as a whole or not take it at all. You might end up with lots of dead code in the program if the linker has to include huge object files if you want to use just a single function.
Turn your library into a shared library and use mapfiles or a different mechanism to specify which symbols are supposed to be exported. This is the best option in my opinion but it's not totally portable and perhaps you really want your library to remain static.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With