Single-command compile and link fails, separate st

2019-01-20 16:27发布

问题:

While I was trying to solve a linker problem with g++, I found that trying to compile link a simple one-file program in one command was failing, due to undefined symbols.

g++ -lEGL -lGLESv2 -o test test.cpp

However, if I compiled test.cpp separately, and then linked as a second step, everything works OK.

g++ -c test.cpp
g++ -o test test.o -lGL -lGLESv2

What's the difference between the first command and the others, and why would one way fail and the other way work? I'm guessing it's something to do with the order of linking, but I get the feeling that this is a little buggy.

回答1:

When you compile and link in one go, as per:

g++ -lEGL -lGLESv2 -o test test.cpp

g++ obeys as if you did:

g++ -c -o deleteme.o test.cpp
g++ -lEGL -lGLESv2 -o test deleteme.o
rm deleteme.o

(If you run the command with the -v (verbose) option and scrutinize the goobledegook carefully, you'll be able to spot the distinct invocations of the compiler, assembler, and linker, with temporary files passed between).

So now do you see what's wrong? It's library search order. In the linkage:

g++ -lEGL -lGLESv2 -o test deleteme.o

You are telling the linker to search libEGL and libGLESv2 for unresolved symbols before reading the object file, deleteme.o that requires symbols from them, so those symbols will go unresolved. In your second linkage:

g++ -o test test.o -lGL -lGLESv2

You've got the linkage order right. There's nothing buggy here. From man ld

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.



标签: linker g++