如何让gcc或ld报告未定义的符号但不失败?

问题描述:

如果您使用GCC编译共享库并传递“-z defs”标志(我认为它只是盲目地传递给ld),那么您会得到一个很好的未定义符号的报告,并且ld失败(不。所以创建文件)。另一方面,如果你没有指定“-z defs”或者明确指定“-z nodefs”(缺省值),那么即使符号丢失,也会产生一个.so,但是你没有得到什么符号的报告如果有的话失踪。如何让gcc或ld报告未定义的符号但不失败?

我想都!我想要创建.so,但我还想要报告任何缺少的符号。到目前为止我所知道的唯一方法是运行两次,一次使用“-z defs”,一次没有。这意味着可能的长链接阶段会执行两次,这会使编译/测试周期变得更糟。

如果您想知道我的最终目标 - 编译库时,本地对象文件中的未定义符号表示未指定应该在我的构建环境中的依赖项,而如果符号在一个你链接的库,这不是一个错误(-l标志只给出立即依赖关系,而不是依赖关系,在这个系统下)。我需要报告中列出“在文件中引用”的部分,以便我可以查看符号是由本地对象还是正在链接的库引用的。 --allow-shlib-undefined选项几乎可以解决这个问题,但在与静态库链接时不起作用。

首选可与GNU和Solaris连接器兼容的解决方案。

从GNU LD 2.15 NEWS文件的问题:

  • 改进的链接器处理未解析的符号。交换机 --unresolved-symbols =已被添加以告知链接器何时它应该报告它们,并且交换机--warn-unresolved-symbols已被添加到 使得报告被发布为警告消息而不是错误。

而不是让ld在链接过程中报告未定义的符号,您可以在生成的.so文件上使用nm。例如:

nm --dynamic --undefined-only foo.so 

编辑:虽然我猜并不会给你哪些源文件的符号用于。对不起,我错过了你的问题的那一部分。

你仍然可以使用纳米的近似解,使用grep一起:

for sym in `nm --dynamic --undefined-only foo.so |cut -d' ' -f11 |c++filt -p` ; do 
    grep -o -e "\\<$sym\\>" *.cpp *.c *.h 
done 

这可能具有相同名字的局部符号等

+0

您可以使用C++ filt来取消名称 – fbrereto 2009-10-14 20:51:35

+0

好的建议,fbrereto;我已将其整合到我的答案中。 – wdebeaum 2009-10-14 21:22:11

+0

我将答案标记为解决方案,但应该指出,对于不使用GNU链接器的用户,您的答案仍然正确。 – 2011-08-18 20:33:31