我注意到我无法在命令末尾用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和there,但在编译源代码时,我仍然不太了解它,而不是库库依赖项。我原以为编译器总是首先编译代码,然后才调用链接器。在这种情况下,它应该知道,即使在开始链接过程之前,从main.cpp构建的目标文件也需要createDevice
函数。我的错误在哪里?
P.S。 This问题,建议重复,根本不解释。
答案 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
链接顺序正确的,带有需要定义的符号 在提供它们的图书馆之前被发现。