从C静态库中删除内部符号

Oli*_*ans 7 c linker binaryfiles static-libraries

我正在研究一些作为静态库提供的嵌入式代码.我们希望从库中删除所有内部符号,并仅保留API符号可见.

这是我们想要做的一个例子:假设你有一个被调用的文件internal.c和一个被调用的文件api.c:

/* 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));
}
Run Code Online (Sandbox Code Playgroud)

用户应该只能访问该print_fibonacci功能,而所有内部符号(如fibonacci功能)应在发货前解决.这意味着用户应该能够定义自己的函数,fibonacci而不必担心与库的冲突.

我们已经尝试使用内部链接ld --relocatable,但我们似乎无法使用objcopy删除符号.这有可行吗?

谢谢您的帮助!

编辑:用户定义的fibonacci函数不应该替换库定义的函数,它们应该只能共存.基本上我正在寻找解决命名冲突的解决方案.

fuz*_*fuz 4

静态库本质上是一堆目标文件。静态库中的所有目标文件都被视为由链接器单独提供。一般来说,不可能让链接器将某些符号视为内部符号,链接器根本没有足够的信息来这样做。

以下是解决这些问题的一些策略:

  • 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
    
    Run Code Online (Sandbox Code Playgroud)

    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.