GCC 链接顺序改变了? [英] GCC link order changed?

查看:11
本文介绍了GCC 链接顺序改变了?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 GCC 链接一个 C++ 模块,基本上是这样的:

I am trying to link a C++ module using GCC, essentially like this:

gcc -c hello.c
g++ -c world.cpp
gcc -ohello -lstdc++ hello.o world.o

请注意,我使用-lstdc++ 来链接C++ 模块,这样我就可以使用gcc 而不是g++.问题是我收到了错误:

Note that I use -lstdc++ to link the C++ module in, so that I can use gcc instead of g++. The problem is that I'm getting the error:

undefined reference to `operator new(unsigned long)'

(假设 world.cpp 包含至少一个对 new 的调用.)

(Assuming that world.cpp contains at least one call to new.)

如果我将 -lstdc++ 放在链接器行的末尾,则此错误已修复,如下所示:

This error is fixed if I put -lstdc++ at the end of the linker line, like this:

gcc -ohello hello.o world.o -lstdc++

我知道这个问题在这里已经被问过很多次了,但是我有一个特殊的要求.我没有直接打电话给 GCC.我正在使用代表我调用 GCC 的不同编程语言(Mercury)的构建系统,并且我无法轻松修改它调用 GCC 的方式(尽管我可以使用 LDFLAGS 环境变量指定其他库).所以我有两个额外的要求:

I am aware that this question has been asked many times here, but I have a special requirement. I am not directly calling GCC. I am using a build system for a different programming language (Mercury) which is calling GCC on my behalf, and I can't easily modify the way it calls GCC (though I can specify additional libraries using the LDFLAGS environment variable). So I have two additional requirements:

  • 我不能使用 g++ 来链接(只有 gcc)——这就是为什么我要使用上面的 -lstdc++ 技巧而不是简单地与 g++ 链接).
  • 我认为我无法控制链接器命令的顺序 -- Mercury 会将 .o 文件放在命令行任何库之后.
  • I cannot use g++ to link (only gcc) -- that is why I am doing the -lstdc++ trick above rather than simply linking with g++).
  • I don't think that I can control the order of the linker commands -- Mercury will put the .o files on the command-line after any libraries.

我明白顺序很重要的基本原因,但令我困惑的是为什么现在中断?我刚刚更新到 Ubuntu 11.10/GCC 4.6.1.多年来,我一直使用上述技术(将 -lstdc++ 放在首位)成功地编译了这个程序.直到现在才出现这个错误.我的一个不相关的程序使用 -lgl 链接到 OpenGL,当我升级时它也坏了,我不得不将 -lgl 移动到命令行的末尾.我可能会发现我的许多程序不再编译.为什么会发生这种变化?我的新系统有问题还是现在是这样?请注意,这些是普通的共享库,不是静态链接的.

I understand the basic reason why the order is important, but what is baffling me is why did this break now? I just updated to Ubuntu 11.10 / GCC 4.6.1. I have been successfully compiling this program for years using precisely the above technique (putting -lstdc++ first). Only now has this error come up. An unrelated program of mine links against OpenGL using -lgl and that too broke when I upgraded and I had to move -lgl to the end of the command-line. I'm probably going to discover that dozens of my programs no longer compile. Why did this change? Is there something wrong with my new system or is that the way it is now? Note that these are ordinary shared libraries, not statically linked.

我能做些什么来让 GCC 回到旧的方式,即库的顺序无关紧要吗?有没有其他方法可以说服 GCC 正确链接 libstdc++ 而无需在命令行上的 .o 文件之后移动它?

Is there anything I can do to make GCC go back to the old way, where the order of libraries doesn't matter? Is there any other way I can convince GCC to link libstdc++ properly without moving it after the .o files on the command-line?

推荐答案

如果 Mercury 将目标文件放在库之后,Mercury 就会损坏.库属于目标文件之后 - 总是.您有时可能会以相反的顺序侥幸逃脱,但并不可靠.(静态库必须跟踪引用静态库中符号的目标文件.有时,即使没有使用任何符号,链接器也会记录共享库定义的符号;有时,链接器只会记录共享库符号如果共享库提供了至少一个符号.)

If Mercury puts object files after libraries, Mercury is broken. Libraries belong after object files - always. You may sometimes get away with the reverse order, but not reliably. (Static libraries must go after the object files that reference symbols in the static library. Sometimes, a linker will note the symbols defined by a shared library even when none of the symbols are used; sometimes, the linker will only note the shared library symbols if the shared library provides at least one symbol.)

这篇关于GCC 链接顺序改变了?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆