gcc 中链接器标志的正确顺序是什么?

sta*_*anm 6 linker gcc

通常,我会编译一个需要特定库(例如数学)的程序,方法是在需要它的源之后传递链接器标志,如下所示:

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何时停止工作以及为什么?似乎不支持它会破坏旧包。

Mik*_*han 5

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)

现在情况更糟了。