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

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

问题描述

  gcc -c hello.c $ b我试图用GCC链接一个C ++模块$ b g ++ -c world.cpp 
gcc -ohello -lstdc ++ hello.o world.o



<请注意,我使用 -lstdc ++ 来链接C ++模块,以便我可以使用 gcc 代替克++ 。问题是我收到错误:

$ p $ 未定义的引用'operator new(unsigned long)'

(假设 world.cpp 至少包含一次调用) new 。)



如果我把 -lstdc ++ 在链接器行末尾,如下所示:

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

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


  • 我不能使用 g ++ gcc ) - 这就是为什么我要做 -lstdc ++ 的技巧,而不是简单地链接 g ++ )。

  • 我不认为我可以控制链接器命令的顺序 - 水星会将.o文件放在命令中-line 在任何库之后。



我明白订单很重要的基本原因,让我感到困惑的是为什么现在这个中断了?我刚更新到Ubuntu 11.10 / GCC 4.6.1。我已经使用上述技术成功地编译了这个程序多年(首先将 -lstdc ++ >)。现在只有这个错误出现了。我使用 -lgl 与我的OpenGL无关的程序链接,当我升级时我的程序也崩溃了,我必须将 -lgl 到命令行的末尾。我可能会发现我的几十个程序不再编译。为什么这个改变?我的新系统有什么问题,或者是现在的样子?请注意,这些是普通的共享库,而不是静态链接。



有什么我可以做的,使GCC回到旧的方式,要紧吗?有什么其他方式可以说服GCC正确地链接 libstdc ++ ,而不必将它移动到命令中的 .o 文件之后如果Mercury在库之后放置了目标文件,Mercury被破坏了。库之后属于对象文件 - 始终。您有时可能会违背相反的顺序,但不可靠。 (静态库必须遵循静态库中引用符号的目标文件,有时,即使没有使用任何符号,链接器也会记录由共享库定义的符号;有时,链接器仅会记录共享库符号如果共享库提供至少一个符号。)


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

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)'

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

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

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

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:

  • 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.

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.

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?

解决方案

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天全站免登陆