ld 命令是二进制工具集 GNU Binutils 的一员,是 GNU 链接器,用于将目标文件与库链接为可执行文件或库文件。
ld [OPTIONS] OBJFILES
ld 命令支持众多链接选项,但是大部分选项很少被使用,下面是 GNU ld 命令接受的选项。
-b
指定目标代码输入文件的格式
-Bstatic
只使用静态库
-Bdynamic
只使用动态库
-Bsymbolic
把引用捆绑到共享库中的全局符号
-c , --mri-script=
为与 MRI 链接器兼容,ld 接受由 MRI 命令语言编写的脚本文件
--cref
创建跨引用表
-d,-dc,-dp
即使指定了可重定位的输出文件(使用-r),也会为公共符号分配空间。脚本命令“FORCE_COMMON_ALLOCATION”具有相同的效果
-defsym
在输出文件中创建指定的全局符号
-demangle
在错误消息中还原符号名称
-e
使用指定的符号作为程序的初始执行点
-E,--export-dynamic
对于ELF格式文件,创建动态链接的可执行文件时,把所有符号添加到动态符号表
-f , --auxiliary=
对于 ELF 格式共享对象,设置 DT_AUXILIARY 名称
-F , --filter=
对于ELF格式共享对象,设置 DT_FILTER 名称。这告诉动态链接器,正在创建的共享对象的符号表应该用作共享对象名称的符号表的筛选器。
-g
被忽略。用于提供和其他工具的兼容性
-h
对于 ELF 格式共享对象,设置 DT_SONAME 名称
-I, -dynamic-linker , --dynamic-linker=
指定动态链接器。这仅在生成依赖动态链接库的 ELF 可执行文件时才有意义。默认的动态链接器通常是正确的,除非您知道正在做什么,否则不要使用该选项。
-l , --library=
把指定的库文件添加到要链接的文件清单
-L , --library-path=searchdir
把指定的路径添加添加到搜索库的目录清单
-M, --print-map
显示链接映射,用于诊断目的
-Map=:
将链接映射输出到指定的文件
-m
模拟指定的链接器
-N,--omagic
指定读取/写入文本和数据段
-n,--nmagic
关闭节的页面对齐,并禁用对共享库的链接。如果输出格式支持Unix样式的幻数,则将输出标记为"NMAGIC"
-noinhibit-exec
生成输出文件,即使出现非致命链接错误。通常,如果链接器在链接过程中遇到错误,它将不会生成输出文件。
-no-keep-memory
ld 通常在内存中缓存输入文件的符号表来优化内存使用速度。此选项告诉 ld 不要缓存符号表。当链接大型可执行文件时,如果ld耗尽内存空间,则可能需要使用该选项
-O
对于非零的优化等级,ld将优化输出。此操作会比较耗时,应该在生成最终的结果时使用。
-o
(1)链接目标文件生成可执行文件。给定C++目标文件test.o与main.o,生成可执行文件test.out。
ld /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib -lstdc++ -lm -lgcc_s -lc -lgcc main.o test.o -o test.out
因为生成一个C++可执行文件,需要依赖很多系统库和相关的目标文件,比如C语言库libc.a,所以使用ld进行链接时,需要注意添加较长的命令选项,不然会报链接错误。使用g++ -v命令可以查看最后一行collect2使用的命令选项,进而了解生成可执行文所需的相关依赖。
g++ -v main.o test.o
...
usr/libexec/gcc/x86_64-redhat-linux/4.8.5/collect2 --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o /usr/lib64/crti.o /usr/lib64/crtn.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib64 -L/usr/lib -lstdc++ -lm -lgcc_s -lc -lgcc main.o test.o
[1] ld manual
[2] GNU Binutils
[3] 使用ld命令链接目标文件生成可执行文件