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