简介

  • ld链接器相关理论基础

linux ld链接工具 详解

ld 是 GNU 链接器,用于将各种目标文件(object files)和库文件链接成一个可执行文件。ld 的功能非常强大,可以控制链接过程的各个方面。以下是 ld 的一些主要功能和选项的详解:

基本用法

1
ld [options] file...

常用选项

  • -o <file>:指定输出文件的名称。
  • -l<library>:链接库文件,<library> 是库名而不是文件名。链接器会在库路径中搜索 lib<library>.alib<library>.so
  • -L<dir>:添加库搜索路径,告诉链接器到指定目录去查找库文件。
  • -rpath <dir>:添加运行时库路径,告诉动态链接器在运行时到指定目录去查找共享库。
  • -static:强制使用静态链接,即使存在动态库也不使用。
  • -shared:生成一个共享库。
  • -T <script>:指定链接脚本,用来控制链接过程的详细行为。

链接过程

链接过程分为以下几个步骤:

  1. 符号解析:将所有目标文件和库文件中的符号进行解析,确保每个符号都有一个定义。
  2. 重定位:调整目标文件中地址相关的内容,使其在最终的可执行文件中具有正确的地址。
  3. 段合并:将各个目标文件中的相同类型的段(如 .text.data)合并在一起。
  4. 生成输出文件:将合并后的段写入到最终的输出文件中。

链接脚本

链接脚本是一种文本文件,用于控制链接器的行为。其基本结构如下:

1
2
3
4
5
6
7
SECTIONS
{
  . = 0x10000;
  .text : { *(.text) }
  .data : { *(.data) }
  .bss  : { *(.bss) }
}
  • SECTIONS:定义输出文件的段布局。
  • .:表示当前地址。
  • *(.text):将所有输入文件中的 .text 段合并到输出文件的 .text 段中。

例子

假设有两个目标文件 main.outils.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
2
3
4
5
6
7
SECTIONS
{
  . = 0x10000;
  .text : { *(.text) }
  .data : { *(.data) }
  .bss  : { *(.bss) }
}

可以这样使用:

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>.alib<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.outils.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 链接器的行为,以满足各种链接需求。