通常,我会编译一个需要特定库(例如数学)的程序,方法是在需要它的源之后传递链接器标志,如下所示:
gcc foo.c -lm
Run Code Online (Sandbox Code Playgroud)
然而,旧版本的 gcc 似乎在相反的顺序上同样工作得很好(我们称之为BAD ORDER):
gcc -lm foo.c
Run Code Online (Sandbox Code Playgroud)
如果我尝试编译的一些流行的开源项目没有使用后者,而我的版本gcc(或者这ld就是问题所在?)仅在前一种情况下工作(而且,正确的我认为之一)。
我的问题是: BAD ORDER何时停止工作以及为什么?似乎不支持它会破坏旧包。
BAD ORDER 何时停止工作?为什么?似乎不支持它会破坏旧包。
什么时候?
不太确定,但我认为是 GCC 4.5 之前的版本。很久以前。随后,该--as-needed选项默认对共享库有效,因此与静态库一样,它们在链接序列中的出现必须晚于它们为其提供定义的对象。gcc/g++/gfortran这是等工具驱动程序传递给的默认选项的更改ld。
为什么?
人们认为,对于不熟练的用户来说,静态库默认情况下必须晚于它们提供定义的对象出现,而共享库默认情况下则不会出现 - 两者之间的区别通常被-l<name>链接 或 的约定libname.a所隐藏libname.so。
这可能是一个不可预见的后果,那些以前很幸运的不熟练的用户错误地认为 GCC [编译和]链接命令符合正常的 Unix 模式:
command [OPTION...] FILE [FILE...]
Run Code Online (Sandbox Code Playgroud)
例如
gcc -lthis -lthat -o prog foo.o bar.o
Run Code Online (Sandbox Code Playgroud)
现在情况更糟了。