我们有没有办法让gcc检测静态库中的重复符号与主代码(或另一个静态库?)
情况如下:
main.c错误地包含一个函数定义,例如签名为uint foohash(const char*)
foo.c还包含一个带有签名uint foohash(const char*)
foo.c和其他源文件被编译为静态util库,主程序链接在其中,例如:
gcc -o main main.o util.o -L ./libs -lfooutils
所以,现在main.o和libs / libfooutils.a都包含一个foohash函数。据推测,链接器在main.o中找到了这个符号,并且不会在其他地方寻找它。
我们有什么方法可以让gcc检测到这种情况吗?
答案 0 :(得分:3)
正如Simon Richter所说,--whole-archive
选项可能很有用。尝试将命令行更改为:
gcc -o main main.o util.o -L ./libs -Wl,--whole-archive -lfooutils -Wl,--no-whole-archive
你会看到多重定义错误。
答案 1 :(得分:2)
简答:不。
GCC实际上并没有对库做任何事情。 ld
的任务,链接器(由GCC自动调用)从库中提取符号,这真是一个相当愚蠢的工具。
链接器有很多复杂的jiggery pokery,用于组合来自不同源的不同类型的数据,支持不同的文件格式,以及二进制可执行文件的所有邪恶的小细节,但最后,它真正做的就是寻找未定义的符号并找到定义。
您可以做的是链接跟踪(将-t
传递给gcc)以查看来自哪里的内容。或者对系统中的所有目标文件和库运行nm
,然后编写脚本来检测重复项。
答案 2 :(得分:2)
gcc
调用ld
程序进行链接。相关的ld
选项为:
--no-define-common
--traditional-format
--warn-common
请参阅ld
的手册页。这些应该是你需要尝试以获得所需的警告。