GCC 静态链接顺序

GCC static linking order

我注意到我无法在命令末尾使用 cpp 文件编译我的代码:

ars@Arsmint$ g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor main.cpp 
/tmp/ccxlyIri.o: In function `main':
main.cpp:(.text+0x10c): undefined reference to `createDevice'
collect2: error: ld returned 1 exit status

如果我把它们放在链接指令之前,它编译得很好:

ars@Arsmint$ g++ main.cpp -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
ars@Arsmint$

我已经阅读了一些解释 here and there,但是当涉及到已编译的源代码,而不是库-库依赖项时,我仍然不太明白。我原以为编译器总是先编译代码,然后才调用链接器。在那种情况下,它应该知道从 main.cpp 构建的目标文件甚至在链接过程开始之前就需要 createDevice 函数。我的错误在哪里?

P.S。 This 问题,作为重复提出,根本没有解释。

您可能会因为走捷径而感到困惑(似乎很多人都这样) 在一个命令中编译和 linking。

g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor main.cpp

是一个快捷方式,功能上等同于:

# g++ invokes the C++ compiler (cc1plus). The linkage options are ignored.
g++ -c -o deleteme.o main.cpp

# g++ invokes the system linker (ld). The linkage options are passed.
g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor -o a.out deleteme.o
rm deleteme.o

如果你明确地执行了这两个步骤,你会这样做,例如

# Compile step
g++ -c -o main.o main.cpp
# Link step.
g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor -o prog main.o

在 link 步骤中,g++ 暗中添加了主机的默认 C++ linkage 选项 系统到命令行,然后将其交给 linker。 C++编译器是 不涉及。

默认情况下,linker 在遇到一个库时最多检查一次 在命令行 linkage 序列中,它只会检查库以查看 库是否可以解析前面引用的任何迄今未解析的符号 link年龄顺序。在 linkage 序列的末尾,如果所有引用的符号都是 已解决,linkage 成功,否则失败。

link年龄:

g++ -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor -o a.out deleteme.o

将失败,因为所有库都出现在任何目标文件之前。当每个库 到达时,linker 尚未发现未解析的符号,因此库将被忽略。 当 linker 最终到达尾随的目标文件并发现一些未解决的问题时 符号,它们仍未解决。

反之,

g++ main.cpp -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor

相当于:

g++ -c -o deleteme.o main.cpp    
g++ -o a.out deleteme.o -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
rm deleteme.o

其中link年龄顺序正确,符号需要定义 在提供它们的图书馆之前被发现。