【问题标题】:With GCC, how do I export only certain functions in a static library?使用 GCC,如何仅导出静态库中的某些函数?
【发布时间】:2009-10-01 20:41:29
【问题描述】:

我在 GCC 中创建了一个静态库,但我想隐藏大部分符号。

例如test1.c:

extern void test2(void);
void test1(void) {
  printf("test1: ");
  test2();
}

test2.c:

extern void test1(void);
void test2(void) {
  printf("test2\n");
}

库_api.c:

extern void test1(void);
extern void test2(void);
void library_api(void) {
  test1();
  test2();
}

现在编译:

gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc -c library_api.c -o library_api.o
ar rcs libapi.a test1.o test2.o library_api.o

如何只显示“library_api()”函数:

nm libapi.a

而不是函数“test1()”、“test2()”和“library_api()”?换句话说,我如何隐藏“test1()”和“test2()”,使其不显示并被 libapi.a 的外部用户调用?我不希望外部用户了解内部测试功能。

【问题讨论】:

    标签: c static


    【解决方案1】:

    最简单的解决方案是#include test1.c 和 test2.c 到library_api.c,并且只编译那个文件。然后你可以将 test1() 和 test2() 设为静态。

    或者,您可以将目标文件与ld -r 组合,并使用objcopy --localize-symbols 使链接后的测试功能静态。由于这可能会变得相当乏味,但我真的推荐第一个选项。

    【讨论】:

    • 声明符号 static 也无助于将其隐藏在静态库中。
    • @Pavel:确实如此。您不能链接到静态符号;如果需要,您还可以在编译后去除所有静态符号。
    • 我试过“ld -r --retain-symbols-file tmp.list test1.o test2.o library_api.o -o libapi.a”,其中 tmp.list 只包含“library_api”和“ nm libapi.a" 仍将 test1 和 test2 符号显示为全局。有什么想法吗?
    • @Martin:您可以使用什么命令从 libapi.a 中“删除编译后的所有静态符号”?
    • @Will:显然,--retain-symbols-file 不适用于 ld -r。我已经编辑了我的响应以推荐 objcopy。您可以使用strip --strip-unneeded 去除(一些)静态符号。只要符号不用于重定位,这适用于汇编程序在 x86 上解析的调用。
    【解决方案2】:

    ld 有选项

    --retain-symbols-file FILE 只保留 FILE 中列出的符号

    允许您明确命名您想要的符号 保留。

    【讨论】:

      猜你喜欢
      • 2010-11-04
      • 2021-01-30
      • 2011-03-24
      • 2018-12-01
      • 1970-01-01
      • 2012-10-17
      • 2018-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多