在链接可执行文件之前查找静态库未解析的依赖项

Find static library unresolved dependencies before linking executable

本文关键字:依赖 静态 可执行文件 链接 查找      更新时间:2023-10-16

假设我们有静态库mylib.a,其中包含编译的cpp文件。

文件1.cpp:

int do_stuff();
int func_unres()
{
int a = do_stuff();
return a;
}

文件2.cpp:

int do_other_stuff();
int func_res()
{
int a = do_other_stuff();
return a;
}

文件3.cpp:

int do_other_stuff()
{
return 42;
}

因此,正如我们在这里看到的,没有文件包含do_stuff函数的定义。 库以这种方式创建:

g++ -c file1.cpp -o file1.o

g++ -c file2.cpp -o file2.o

g++ -c file3.cpp -o file3.o

ar r mylib.a file1.o file2.o file3.o

现在我们尝试用这个库制作一些二进制文件。简单的示例主文件:

#include <iostream>
int func_res();
int main()
{
std::cout << func_res() << std::endl;
}

编译:

g++ main.cpp mylib.a -o my_bin

一切都很好。 现在考虑这样的主文件的情况:

#include <iostream>
int func_unres();
int main()
{
std::cout << func_unres() << std::endl;
}

在这种情况下,二进制不会链接,因为func_unres需要定义函数do_stuff

有没有办法找出静态库需要函数库中没有对象文件包含的符号,然后再将其与使用此类符号的可执行文件链接?

编辑: 问题不在于如何简单地列出这些符号,而在于获得带有链接器类似错误的输出。 就像我使用它应该包含的所有符号将此库与可执行文件链接一样。

似乎正如注释和如何强制 gcc 链接未使用的静态库中所述,链接器选项--whole-archive足以强制解析静态库中所有未解析符号的所有符号和输出链接器错误。因此,参考问题示例,以这种方式编译和链接第一个主文件,它不引用未定义的符号,无论如何都会输出链接器错误:

g++ main.cpp -wl,--whole-archive mylib.a -wl,--no-whole-archive

尽管 main 不使用func_unres,但链接失败:

mylib.a(file1.o(: 在函数 func_unres((: file1.cpp:(.text+0x9(: 对 do_stuff(( 的未定义引用

使用第二个选项--no-whole-archive,因此其余所需库的符号不会像这样强制解析。