在 Linux 系统中,ld 命令是 GNU 链接器(GNU Linker) 的主要工具,它的主要作用是将多个目标文件(.o 文件)、库文件(.a 或 .so 文件)以及其他输入文件组合在一起,生成一个可执行文件或共享库。
虽然大多数开发者直接使用 gcc 或 g++ 进行编译链接,但了解 ld 对于深入理解程序构建过程、调试链接错误以及进行底层开发非常有用。
基本语法
ld [选项] 输入文件...
常用选项
| 选项 | 说明 |
|---|---|
-o <输出文件> |
指定输出文件的名称(默认通常为 a.out) |
-l<库名> |
链接指定的共享库或静态库(-lm 链接数学库) |
-L<路径> |
指定库文件的搜索路径 |
-T <脚本> |
使用指定的链接脚本(Linker Script) |
-r |
可重定位输出(用于生成中间目标文件) |
-s |
从输出文件中移除所有符号表信息 |
-static |
强制链接静态库 |
-shared |
创建共享库(.so 文件) |
--verbose |
显示链接过程中的详细信息 |
--help |
显示帮助信息 |
使用示例
示例 1:链接两个目标文件生成可执行文件
假设有两个源文件 main.c 和 utils.c:
# 1. 编译为目标文件 gcc -c main.c -o main.o gcc -c utils.c -o utils.o # 2. 使用 ld 链接 ld main.o utils.o -o myprogram
⚠️ 注意:直接使用
ld链接可能会缺少 C 运行时库(如crt0.o、libc等),导致运行时错误,通常推荐使用gcc来自动处理这些依赖。
示例 2:链接标准库(如数学库)
ld main.o -lm -o myprogram
这里 -lm 表示链接数学库 libm.so。
示例 3:创建共享库
# 编译为位置无关代码(PIC) gcc -c -fPIC utils.c -o utils.o # 链接为共享库 ld -shared utils.o -o libutils.so
示例 4:使用链接脚本
链接脚本允许开发者精确控制内存布局、段(section)分配等。
ld -T custom_linker_script.ld main.o -o myprogram
ld 与 gcc 的区别
| 特性 | ld |
gcc |
|---|---|---|
| 角色 | 纯链接器 | 编译器驱动(包含预处理、编译、汇编、链接) |
| 运行时库 | 不自动链接 C 标准库(libc) |
自动链接必要的运行时库(如 crt1.o, libc.so) |
| 易用性 | 需要手动指定所有依赖和入口点 | 自动处理大多数细节 |
| 适用场景 | 底层开发、嵌入式系统、自定义链接流程 | 日常 C/C++ 开发 |
常见问题与注意事项
❌ 错误:undefined reference to 'main'
- 原因:未指定入口点或目标文件未包含
main函数。 - 解决:确保有一个包含
int main()的目标文件,并使用-e main指定入口点(如果需要):ld -e main main.o utils.o -o myprogram
❌ 错误:

cannot find -lc
cannot find -lc
- 原因:
ld不知道去哪里找 C 标准库。 - 解决:使用
gcc代替ld,或手动指定库路径:ld main.o -lc -o myprogram
✅ 推荐做法
除非你有特殊需求(如嵌入式开发、操作系统内核开发),否则建议始终使用 gcc 或 g++ 进行链接,因为它们会自动处理 C 运行时环境、初始化代码和库依赖。
查看链接信息
你可以使用 readelf 或 objdump 查看 ld 生成的文件信息:
# 查看 ELF 文件头 readelf -h myprogram # 查看符号表 readelf -s myprogram # 查看段信息 readelf -l myprogram
ld是 GNU 链接器,用于将目标文件和库组合成可执行文件或共享库。- 它不提供 C 运行时支持,需手动处理依赖。
- 日常开发推荐使用
gcc/g++,它们在底层调用ld并自动处理复杂链接过程。 - 对于高级用户,
ld提供了强大的链接脚本和精细控制能力。
如需进一步了解,可运行 man ld 查看完整手册。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/478084.html



