c - 将静态库链接到动态库时删除死代码

标签 c gcc shared-libraries static-libraries dead-code

假设我有以下文件:

libmy_static_lib.c:

#include <stdio.h>
void func1(void){
    printf("func1() called from a static library\n");
}
void unused_func1(void){
    printf("printing from the unused function1\n");
}
void unused_func2(void){
    printf("printing from unused function2\n");
}

libmy_static_lib.h:

void func(void);
void unused_func1(void);
void unused_func2(void);

我的程序.c:

#include "libmy_static_lib.h"
#include <stdio.h>
void func_in_my_prog()
{
    printf("in my prog\n");
    func1();

}

这是我链接库的方式:

# build the static library libmy_static_lib.a
gcc -fPIC -c -fdata-sections --function-sections -c libmy_static_lib.c -o libmy_static_lib.o
ar rcs libmy_static_lib.a libmy_static_lib.o

# build libmy_static_lib.a into a new shared library
gcc -fPIC -c ./my_prog.c -o ./my_prog.o
gcc -Wl,--gc-sections -shared -m64 -o libmy_shared_lib.so ./my_prog.o -L. -l:libmy_static_lib.a

libmy_static_lib.c中有2个函数没有用到,来自this post , 我觉得

gcc fdata-sections --function-sections

应该为每个函数创建一个符号,并且

gcc -Wl,--gc-sections

应该在链接时删除未使用的符号

但是当我跑的时候

nm libmy_shared_lib.so

这表明这 2 个未使用的函数也被链接到共享库中。

关于如何让 gcc 自动删除未使用的函数有什么建议吗?

编辑: 如果我将静态库直接链接到可执行文件,我可以使用 gcc 的上述选项删除未使用的函数。但是,如果我将静态库链接到共享库,它不会删除未使用的函数。

最佳答案

您可以使用版本脚本结合-ffunction-sections 来标记入口点和 --gc-sections .

例如,考虑这个 C 文件 ( example.c ):

int
foo (void)
{
  return 17;
}

int
bar (void)
{
  return 251;
}

还有这个version script , 称为 version.script :

{
  global: foo;
  local: *;
};

像这样编译和链接源代码:

gcc -Wl,--gc-sections -shared -ffunction-sections -Wl,--version-script=version.script example.c

如果您查看 objdump -d --reloc a.out 的输出, 你会注意到只有 foo包含在共享对象中,但不包含 bar .

以这种方式删除函数时,链接器将考虑间接依赖性。例如,如果您转 foo进入这个:

void *
foo (void)
{
  extern int bar (void);
  return bar;
}

链接器会将foobar进入共享对象,因为两者都需要,即使只有 bar被导出。

(显然,这并不适用于所有平台,但 ELF 支持。)

关于c - 将静态库链接到动态库时删除死代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50881619/

相关文章:

c - 将指针与数组一起使用时遇到问题

c++ - 在 C++ 共享库中添加通用日志记录支持

c++ - 是什么决定了 Linux 上共享库的二进制兼容性?

java.lang.UnsatisfiedLinkError : no cplex122 in java. 库.path

c - 局部静态变量如何存储

c++ - GCC C/C++ 双重行为

python 调用 c dll 传递给 wchar**

C float 表示法

c - gcc (x64) 如何处理可变参数函数中的类型/大小?

c++ - 如何在 gcc 和 VS 中强制使用 cmov