我正在研究一些作为静态库提供的嵌入式代码。我们希望从库中删除所有内部符号,只保留 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));
}
用户应该只能访问print_fibonacci
功能,而所有内部符号,如fibonacci
功能应在发货前解决。这意味着用户应该能够定义自己的函数,称为fibonacci
不用担心与图书馆的冲突。
我们已经尝试使用内部链接ld --relocatable
,但之后我们似乎无法使用 objcopy 删除符号。这到底可行吗?
谢谢您的帮助!
Edit:用户定义的fibonacci
函数不应取代库定义的函数,它们应该能够共存。基本上我正在寻找解决命名冲突的解决方案。
静态库本质上是一堆目标文件。静态库中的所有目标文件都被视为由链接器单独提供。一般来说,不可能让链接器将某些符号视为内部符号,链接器根本没有足够的信息来这样做。
以下是解决这些问题的一些策略:
-
为库中的非公共函数构建单独的名称空间。例如,你的fibonacci
函数可以放置在内部名称空间中libfoo_internal_fibonacci
。如果您感到绝望,您可以在内部头文件中使用宏,如下所示:
#define fibonacci INTERNAL_PREFIX ## fibonacci
这将允许您在编译时任意更改前缀。我建议不要这样做,因为这会使调试变得更加困难。如果您可以处理更长的内部名称,这将是一个很好的策略。
使所有内部功能static
并合并翻译单元,使每个内部函数仅由一个翻译单元使用。这可能会解决您的问题,但它会使生成的程序变得更大:大多数链接器可以将对象作为一个整体,也可以根本不接受它。如果您只想使用单个函数,并且链接器必须包含巨大的目标文件,那么您最终可能会在程序中出现大量死代码。
将您的库变成共享库,并使用映射文件或不同的机制来指定应该导出哪些符号。在我看来,这是最好的选择,但它并不完全可移植,也许您确实希望您的库保持静态。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)