如何修改传递给 ld 的选项,而不重新编译 gcc

Posted

技术标签:

【中文标题】如何修改传递给 ld 的选项,而不重新编译 gcc【英文标题】:How to modify options being passed to ld , without recompiling gcc 【发布时间】:2009-07-01 11:39:44 【问题描述】:

我正在尝试使用 gcc 3.4.6 和 它链接到静态链接的 c .a 和 .o 文件。 请注意,它使用路径“/usr/ccs/bin/ld”中的 Sun ld

在链接时我得到一长串符号和以下错误

ld: fatal: relocations remain against allocatable but non-writable sections

collect2: ld returned 1 exit status

然后我尝试将 -z textoff 选项传递给 ld 来构建它。但我得到以下错误

ld: fatal: option -ztextoff and -ztext are incompatible

ld: fatal: Flags processing errors

有没有其他方法我不需要重新编译 gcc 并且仍然修改传递给 ld 的选项。

【问题讨论】:

我想,我刚刚找到了一种方法。 gcc 通常使用“specs”文件将传递给 gcc 通用接口的选项转换为底层汇编器和链接器的选项。在 gcc 3.4.6 中有一个选项,我们可以传递我们自己的“specs”文件。所以我所做的是,我复制了原始文件并对其进行了修改,而不是将 -ztext 选项传递给 sun 链接器。我怀疑这是正确的方法,但它解决了现在的目的,我可以继续我的工作,直到我得到正确配置的 gcc。查询仍然开放以获得更好或更正确的解决方案。 【参考方案1】:

错误是将位置相关代码链接到共享库的结果。此类代码将导致库不可共享,从而浪费 RAM。

如果您可以重新构建您尝试链接到共享库的所有对象,最简单(也是最正确)的解决方案是使用-fPIC 标志重新构建所有对象。

但是,有时您确实必须将无法重建的非 PIC 目标代码链接到共享库中,因此您需要摆脱 -ztext 选项。为此,请将-mimpure-text 选项添加到您的链接行。

【讨论】:

谢谢!!是的,我处于这种情况,我必须在共享对象中使用这个静态链接的代码。是的“-mimpure-text”选项对我有用。我检查并发现即使在规范文件中,我也修改了这个参数,但是使用这个 -mimpure-text 是正确的方法。再次感谢,它解决了我长期悬而未决的问题之一。【参考方案2】:

从命令行(不是通过 gcc)运行 ld 可执行文件 - 然后你可以传递你想要的任何参数。不过,我认为这不会解决您的潜在问题 - 您可能想发布有关它们的问题。

【讨论】:

@Neil:谢谢,我会试试的。可能有点困难,因为项目没有很好的文件。那么有没有办法可以修改 gcc 传递的选项,这样我就不需要手动调用 ld 了。 (当然不用重新编译)对不起,我没有明白你的意思“潜在问题” 这是一个糟糕的想法,而且几乎从来都不是正确的做法。【参考方案3】:

您是否使用 make 或其他构建系统来调用编译器?

如果您将构建系统中的选项更改为在链接阶段专门使用链接器而不是使用编译器。

第 1 步:查找 gcc 传递的标志

添加 -v 标志。它使 gcc 变得冗长。

CXXFLAGS += -v

第 2 步:修改链接阶段以明确使用 gcc 正在调用的工具。

【讨论】:

我们正在使用 gnu make。您的意思是在 Makefile 中我应该使用适当的链接器选项直接 ld 并传递目标文件吗?可以,但我必须非常仔细地准备需要传递给 ld 的选项列表。有没有一种简单的方法可以让我找出 gcc 传递给 ld 的所有选项。这样当我手动调用 ld 时,我可以通过所有这些删除 -ztext 选项。我尝试使用 -v 选项,但会打印传递给 collect2 实用程序的参数。正如我在 cmets 中提到的问题,在这种特殊情况下修改规范文件似乎更容易。 @Martin 正如我在评论中提到的那样,我将 -v 标志传递给 gcc ,它给了我传递给 collect2 实用程序而不是底层 sun 链接器的参数。您对使用专门的规范文件来实现这一点有何看法? 我更倾向于使用 coolect2 实用程序,而不是构建自己的规范文件。 直接调用底层链接器是一个糟糕的主意。如果 GCC 或新版本的操作系统,它会导致链接线对于下一个版本可能不正确。只是不要这样做(TM)。

以上是关于如何修改传递给 ld 的选项,而不重新编译 gcc的主要内容,如果未能解决你的问题,请参考以下文章

怎样用gcc或者ld链接.dll文件

gcc static静态编译选项提示错误:/usr/lib/ld:cannot find -lc

我如何知道哪些选项从 CMake 传递给 GCC?

如何在 AIX 中使用 GCC 编译器链接 *.so 文件

使用“共享”选项编译 OpenSSL?

cmake给gcc添加编译前缀