gcc检测静态库中的重复符号/函数

我们有什么方法可以让gcc检测静态库中的重复符号与主代码(或另一个静态库?)

这是情况:

main.c错误地包含一个函数定义,例如使用签名uint foohash(const char*)

foo.c还包含一个带有签名uint foohash(const char*)的函数定义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检测到这种情况吗?

确实如Simon Richter所说,– --whole-archive选项可能很有用。 尝试将命令行更改为:

  gcc -o main main.o util.o -L ./libs -Wl,--whole-archive -lfooutils -Wl,--no-whole-archive 

你会看到一个多重定义错误。

简答:不。

GCC实际上并没有对库做任何事情。 这是ld的任务,链接器(由GCC自动调用)从库中提取符号,这真的是一个相当愚蠢的工具。

链接器有很多复杂的jiggery pokery,用于组合来自不同源的不同类型的数据,支持不同的文件格式,以及二进制可执行文件的所有邪恶的小细节,但最后,它真正做的就是查找未定义的符号并查找定义。

您可以做的是链接跟踪(传递-t到gcc)以查看来自哪里的内容。 或者在系统中的所有目标文件和库上运行nm ,并编写脚本以检测重复项。

gcc调用ld程序进行链接。 相关的ld选项是:

 --no-define-common --traditional-format --warn-common 

请参阅ld的手册页。 这些应该是您需要尝试获取所需的警告。