With GCC, how do I export only certain functions in a static library?

Asked
Viewd10099

10

I've created a static library in GCC, but I'd like to hide most of the symbols.

For example, test1.c:

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

test2.c:

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

library_api.c:

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

Now compile with:

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

How do I get only the "library_api()" function to show up for:

nm libapi.a

instead of the functions "test1()", "test2()", and "library_api()"? In other words, how do I hide "test1()" and "test2()" from showing up and being callable to external users of libapi.a? I don't want external users to know anything about internal test functions.

10099

2 个答案

9

最简单的解决方案是将test1.c和test2.c包含到library_api.c中,然后仅编译该文件。然后可以将test1()和test2()设为静态。

或者,可以将目标文件与ld -r组合在一起,并在链接后使用objcopy --localize-symbols使测试功能静态。由于这样做可能很繁琐,因此我确实推荐第一种选择。

  • @Will: apparently, –retain-symbols-file doesn’t work for ld -r. I have edited my responsive to recommend objcopy instead. You can strip (some) static symbols with strip --strip-unneeded. This works as long as the symbols aren’t used for relocations, which works for calls that the assembler had resolved on x86.

    Martin v. LöwisOctober 04, 2009 05:12
  • Declaring symbol static doesn’t help with hiding it in static library either.

    P ShvedOctober 01, 2009 21:19
  • @Martin: what command could you use to “strip all static symbols after compilation” from libapi.a?

    WillOctober 03, 2009 15:09
  • I tried “ld -r –retain-symbols-file tmp.list test1.o test2.o library_api.o -o libapi.a” where tmp.list just contains “library_api” and “nm libapi.a” still shows the test1 and test2 symbols as global. Any ideas?

    WillOctober 03, 2009 15:07
  • @Pavel: it sure does. You cannot link against a static symbol; if desired, you can also strip all static symbols after compilation.

    Martin v. LöwisOctober 01, 2009 21:24
  • @Martin: I like the objcopy solution, except I just discovered “objcopy –localize-hidden” to localize all symbols with “attribute((visibility(“hidden”)))”. I can even tell GCC to set all functions hidden by default except the ones I mark visible. Thanks for the help finding this solution! (BTW - I steered away from including all functions in 1 file because the real project has tons of files with potentially overlapping static variable names in each file)

    WillOctober 13, 2009 04:24
2

ld可以选择

-retain-symbols-file FILE仅保留文件中列出的符号

允许您显式命名您想要的符号 保持。