在由几个静态链接的目标文件组成的项目中,我将使用单独的实现替换其中一个。我想在实现替换目标文件提供的每个符号之前测试我的代码,所以我使用-Wl,--unresolved-symbols=ignore-all
让链接器不要抱怨丢失的符号。
但是当我测试代码时,它只是在尝试使用其中一个未定义的符号时崩溃。因此,我正在寻找一种方法来告诉链接器“请在链接之前删除所有未引用的代码,然后告诉我,如果在从入口点可到达的代码中,仍然存在未引用的符号”。这可能吗?
答案 0 :(得分:3)
根据评论密切写出答案,因为我在自己的代码库中找到了这个用法,并检查该方法对我来说是否正常。
int do_things(void);
int application_main(void)
{
return do_things();
}
int test_main(void)
{
return 42;
}
int main(void)
{
return test_main();
}
布局大致反映了我的用例。给定的IR块可以有两个入口点,一个用于运行单元测试,另一个用于执行代码所用的任何操作。单元测试需要整个模块所需的符号子集。能够在不构建其他所有内容的情况下构建单元测试部件是有利的。
Deadstripping比我以前的-Wl,--unresolved-symbols=ignore-all
clang demo.c # undefined reference to `do_things'
clang -O3 demo.c # undefined reference to `do_things'
clang demo.c -c -emit-llvm -o demo.bc # OK
llvm-nm demo.bc
---------------- T application_main
U do_things
---------------- T main
---------------- T test_main
clang demo.bc # undefined reference to `do_things'
opt -o stripped.bc -internalize -internalize-public-api-list=main -globaldce demo.bc
llvm-nm stripped.bc
---------------- T main
---------------- t test_main
clang stripped.bc # OK
公共符号列表可以从ir文件派生(至少在我的情况下),因此opt调用实际上是
opt -internalize -internalize-public-api-list=`llvm-nm -extern-only -defined-only -just-symbol-name some-file.bc` -globaldce -O2