单命令编译和 link 失败,单独的步骤工作

Single-command compile and link fails, separate steps work

当我试图用 g++ 解决 linker problem 问题时,我发现由于未定义的符号,试图在一条命令中编译 link 一个简单的单文件程序失败了。

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

但是,如果我单独编译 test.cpp,然后 link 作为第二步编译,一切正常。

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

第一个命令和其他命令有什么区别,为什么一个方法失败而另一个方法有效?我猜这与 linking 的顺序有关,但我觉得这有点问题。

当你一次编译和link时,按照:

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

g++ 服从,就像你服从一样:

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

(如果您 运行 使用 -v (详细)选项的命令并仔细检查 goobledegook 仔细,你将能够发现不同的调用 编译器、汇编器和 linker,临时文件在它们之间传递)。

那么现在你知道哪里出了问题吗?这是库搜索顺序。在link年龄:

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

您告诉 link 用户搜索 libEGLlibGLESv2 未解析的符号 在读取目标文件之前,deleteme.o 需要来自它们的符号,所以那些符号 将得不到解决。在您的第二 link 年龄:

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

您的link年龄顺序正确。这里没有任何问题。来自 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.