简介
- ld链接器相关理论基础
linux ld链接工具 详解
ld
是 GNU 链接器,用于将各种目标文件(object files)和库文件链接成一个可执行文件。ld
的功能非常强大,可以控制链接过程的各个方面。以下是 ld
的一些主要功能和选项的详解:
基本用法
1 | ld [options] file... |
常用选项
-o <file>
:指定输出文件的名称。-l<library>
:链接库文件,<library>
是库名而不是文件名。链接器会在库路径中搜索lib<library>.a
或lib<library>.so
。-L<dir>
:添加库搜索路径,告诉链接器到指定目录去查找库文件。-rpath <dir>
:添加运行时库路径,告诉动态链接器在运行时到指定目录去查找共享库。-static
:强制使用静态链接,即使存在动态库也不使用。-shared
:生成一个共享库。-T <script>
:指定链接脚本,用来控制链接过程的详细行为。
链接过程
链接过程分为以下几个步骤:
- 符号解析:将所有目标文件和库文件中的符号进行解析,确保每个符号都有一个定义。
- 重定位:调整目标文件中地址相关的内容,使其在最终的可执行文件中具有正确的地址。
- 段合并:将各个目标文件中的相同类型的段(如
.text
、.data
)合并在一起。 - 生成输出文件:将合并后的段写入到最终的输出文件中。
链接脚本
链接脚本是一种文本文件,用于控制链接器的行为。其基本结构如下:
1 | SECTIONS |
SECTIONS
:定义输出文件的段布局。.
:表示当前地址。*(.text)
:将所有输入文件中的.text
段合并到输出文件的.text
段中。
例子
假设有两个目标文件 main.o
和 utils.o
,以及一个库文件 libmath.a
,我们希望将它们链接成一个可执行文件 program
:
1 | ld -o program main.o utils.o -L/path/to/libs -lmath |
如果需要指定运行时库路径:
1 | ld -o program main.o utils.o -L/path/to/libs -lmath -rpath /path/to/libs |
使用链接脚本:
假设有一个链接脚本 linker.ld
,内容如下:
1 | SECTIONS |
可以这样使用:
1 | ld -o program main.o utils.o -T linker.ld |
通过以上的讲解,相信你对 ld
链接工具有了一个全面的了解。在实际使用中,可以根据具体的需求选择合适的选项和脚本来控制链接过程。
linux ld链接器 常用参数
ld
链接器是 GNU 工具链的一部分,用于将目标文件和库文件链接成一个可执行文件。以下是 ld
链接器的一些常用参数及其说明:
基本参数
-o <file>
:指定输出文件的名称。1
ld -o outputfile inputfile.o
-e <symbol>
:设置程序的入口点为<symbol>
。1
ld -e main inputfile.o
-L<dir>
:添加库搜索路径<dir>
。1
ld -L/path/to/libs inputfile.o -lmath
-l<library>
:链接库<library>
,ld
会在库路径中搜索lib<library>.a
或lib<library>.so
。1
ld inputfile.o -lmath
-rpath <dir>
:在运行时指定库搜索路径<dir>
。1
ld -rpath /path/to/libs inputfile.o -lmath
输出控制
-Map <file>
:生成链接映射文件<file>
,包含详细的链接信息。1
ld -Map output.map inputfile.o
-s
:去除所有符号信息,生成精简的可执行文件。1
ld -s -o outputfile inputfile.o
-S
:去除调试信息,但保留符号信息。1
ld -S -o outputfile inputfile.o
链接类型
-r
:生成可重定位的目标文件,通常用于分步链接。1
ld -r -o relocatable.o inputfile.o
-shared
:生成共享库。1
ld -shared -o libshared.so inputfile.o
-static
:强制使用静态链接,即使存在动态库也不使用。1
ld -static -o outputfile inputfile.o
脚本和配置
-T <script>
:使用指定的链接脚本<script>
。1
ld -T linker_script.ld inputfile.o
--verbose
:输出详细的链接过程信息。1
ld --verbose inputfile.o
其他
--start-group
和--end-group
:将一组库文件放在一起,解决循环依赖问题。1
ld --start-group file1.o file2.o -lfoo -lbar --end-group
--gc-sections
:删除未使用的段,减小输出文件的大小。1
ld --gc-sections -o outputfile inputfile.o
--no-undefined
:要求所有符号都必须定义,否则链接失败。1
ld --no-undefined -o outputfile inputfile.o
示例
假设有两个目标文件 main.o
和 utils.o
,以及一个库文件 libmath.a
,我们希望将它们链接成一个可执行文件 program
:
1 | ld -o program main.o utils.o -L/path/to/libs -lmath -rpath /path/to/libs |
使用链接脚本 linker_script.ld
:
1 | ld -o program main.o utils.o -T linker_script.ld |
通过以上参数的组合和使用,可以灵活地控制 ld
链接器的行为,以满足各种链接需求。