我想知道何时应该使用
ld
链接器而不是关闭 gcc
。
我刚刚用c++写了一个简单的hello world,当然我包含了
iostream
库。如果我想用 gcc
创建一个二进制文件,我只需使用: g++ hello hello.cpp
我就得到了我的二进制文件。
后来我尝试使用
ld
链接器。为了获取目标文件,我使用:
g++ -c hello.cpp
。好吧,这很简单,但是链接命令太长了:
ld -o hello.out hello.o \
-L /usr/lib/gcc/x86_64-linux-gnu/4.8.4/ \
/usr/lib/gcc/x86_64-linux-gnu/4.8.4/crtbegin.o \
/usr/lib/gcc/x86_64-linux-gnu/4.8.4/crtend.o \
/usr/lib/x86_64-linux-gnu/crti.o \
/usr/lib/x86_64-linux-gnu/crtn.o \
/usr/lib/x86_64-linux-gnu/crt1.o \
-dynamic-linker /lib64/ld-linux-x86-64.so.2 -lstdc++ -lc
我知道
gcc
使用ld
。
使用 gcc
在所有情况下都更好还是仅在大多数情况下更好?请告诉我一些 ld
链接器具有优势的情况。
正如您所提到的,gcc 仅在链接时充当 ld 的前端;它传递所有链接器指令(选项、默认/系统库等),并通过为您处理所有这些特定于工具链的细节来确保一切都很好地组合在一起。
我认为最好将 GNU 工具链视为一个完整的、紧密集成的环境(任何具有为某些奇异嵌入式平台构建工具链(例如,与 Dietlibc 集成)构建工具链的经验的人可能都会同意)。
除非您有一些非常具体的平台集成要求,或者有理由不使用 gcc,否则我几乎想不出直接调用
ld
进行链接有什么优势。您可能需要的任何额外的特定于链接器的选项都可以使用 gcc 命令行上的 -Wl,
前缀轻松指定(如果尚未作为普通 gcc 选项提供)。
这主要是一个品味问题:当命令行比使用
ld
更简单时,您可以直接使用 gcc
。那就是当您仅使用链接器来操作少量共享对象时,例如,创建一个具有很少依赖项的共享库。
因为您可以通过
ld
选项将选项传递给 -Wl
,所以人们通常会建议仅使用 gcc
来管理命令行。
gcc
作为链接器驱动程序gcc
驱动程序不仅调用ld
,还调用collect2
来收集正确的二进制/启动代码所需的信息。gcc
知道如何使用链接器并提供许多选项:链接哪个启动代码、哪个库、哪个模拟、哪个多库变体。今天,链接器通过带有所有直通选项的 LTO(链接时间优化)编译插件回调编译器,以便 LTO 编译器 (lto1
) 将按需要工作。您不想手动执行此操作。一个简单的 gcc
链接会将价值超过 1200 个字符的选项传递给 ld
。所有这些都取决于分析(-p
,-pg
)可重定位链接(-r
)等等。当您不想链接特定部分时,gcc
可能有适合您的选项:-nocrt0
、-nostartfiles
、-nostdlib
、-nolibc
、...ld
正如您所问:很少有极少数情况下您想直接致电
ld
。
您想要找到 Binutils 版本,例如
ld -v
。
您想了解链接器支持哪些选项,例如
ld --help
。然后使用这些选项通过 gcc
或 -Wl
来增强 -Xlinker
调用,例如生成地图文件并定义符号:
gcc ... -Wl,-Map,main.map -Wl,--defsym,my_symbol=0x42
您在
ld
中发现了错误,正在准备错误报告。尽可能保持最小化和独立,这样 Binutils 的人就不必猜测你的 gcc
添加了什么魔力。
您想了解
ld
的功能,例如在 configure
脚本中:ld
支持哪些选项、哪些功能等。例如,在 GCC 配置脚本中,您无法通过 gcc
调用链接器,因为您只是构建编译器(cc1
、cc1plus
)
、lto1
)和 gcc
司机。
您正在为链接器编写一个测试套件,例如 Binutils 测试套件。