Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC link order changed?

Tags:

gcc

linker

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?

like image 210
mgiuca Avatar asked Dec 27 '11 02:12

mgiuca


People also ask

Does order of linking libraries matter?

Link order certainly does matter, at least on some platforms. I have seen crashes for applications linked with libraries in wrong order (where wrong means A linked before B but B depends on A).

Does order matter in GCC?

For the most part, the order you use doesn't matter. Order does matter when you use several options of the same kind; for example, if you specify -L more than once, the directories are searched in the order specified.

Does GCC do linking?

Linking is performed when the input file are object files " .o " (instead of source file " . cpp " or " . c "). GCC uses a separate linker program (called ld.exe ) to perform the linking.


1 Answers

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

like image 142
Jonathan Leffler Avatar answered Oct 05 '22 22:10

Jonathan Leffler