GCC静态链接顺序

时间:2016-04-11 23:07:49

标签: gcc linker static-linking

我注意到我无法在命令末尾用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$

我已经阅读了一些解释herethere,但在编译源代码时,我仍然不太了解它,而不是库库依赖项。我原以为编译器总是首先编译代码,然后才调用链接器。在这种情况下,它应该知道,即使在开始链接过程之前,从main.cpp构建的目标文件也需要createDevice函数。我的错误在哪里?

P.S。 This问题,建议重复,根本不解释。

1 个答案:

答案 0 :(得分:1)

你可能会因为快捷方式而感到困惑(因为看起来很多人) 在一个命令中编译和链接。

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

在链接步骤中,g ++隐蔽地为主机添加了默认的C ++链接选项 系统到命令行,然后将其交给链接器。 C ++编译器是 没有参与。

默认情况下,链接器会在遇到库时最多检查一次库 在命令行链接序列中,它将仅检查库以查看 如果库可以解决前面提到的任何迄今未解析的符号 连锁序列。在链接序列的末尾,如果所有引用的符号都是 解决后,联系成功,否则失败。

联系:

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

将失败,因为所有库都出现在任何目标文件之前。当每个图书馆 到达时,链接器尚未发现任何未解析的符号,因此忽略了库。 当链接器最终到达尾随目标文件并发现一些未解决的 符号,它们仍然没有得到解决。

相反,

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
链接顺序正确的

,带有需要定义的符号 在提供它们的图书馆之前被发现。