如何使用 binutils 的 ld 程序手动静态链接一个 relocatable (.o) 文件?

2022-01-17 17:10:22 +08:00
 kgdb00
《深入理解计算机系统》第 7 章第 2 节讲 linux ld 程序是静态链接器,我感觉 ld 就是用来动态链接的,难道还能静态链接吗?

如果要手动动态链接,只需要执行:
ld -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib64/crt1.o -lc main.o

生成的文件:
d@desktop:~/test$ ldd a.out
linux-vdso.so.1 (0x00007ffc76151000)
libc.so.6 => /lib64/libc.so.6 (0x00007f9f2fed5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9f300ec000)

如果要手动静态链接一个 hello world 的 c 程序,要用那些参数?
1563 次点击
所在节点    C
10 条回复
kgdb00
2022-01-17 18:27:43 +08:00
ld 能静态链接一个普通的用户库,比如 foo.o 或 libfoo.a ,我想知道的是如何静态链接 gnu c 库。
ysc3839
2022-01-17 19:12:28 +08:00
@kgdb00 glibc 不支持静态链接,你需要换别的 c 库。
secondwtq
2022-01-17 19:23:09 +08:00
GCC 和 Clang 都可以通过使用 -### 参数显示编译过程中运行的命令
kgdb00
2022-01-17 20:03:12 +08:00
@ysc3839 可以静态链接的,fedora 上有一个 glibc-static 包,这个包有一个 /usr/lib64/libc.a 文件,就是 glibc 的静态库
kgdb00
2022-01-17 20:14:43 +08:00
@secondwtq
对,以下是精简过的 gcc 传给 ld 的参数,这条命令可以链接成功,不过我不想依赖 libgcc.a 和 libgcc_eh.a 这两个库,但去掉就链接不通过,难道 gnu c 库静态链接非得和编译器的库绑定在一起? 动态链接的时候是不需要 gcc 的库的。

/bin/ld -m elf_x86_64 -static /usr/lib64/crt1.o /usr/lib64/crti.o main.o \
--start-group \
/lib64/libc.a \
/usr/lib/gcc/x86_64-redhat-linux/11/libgcc.a \
/usr/lib/gcc/x86_64-redhat-linux/11/libgcc_eh.a \
--end-group \
/usr/lib64/crtn.o
kgdb00
2022-01-17 20:18:14 +08:00
@kgdb00 #5 "-m elf_x86_64 -static"这两个参数也不是必要的,以下命令就能完全静态链接一个 hello world 的 c 程序。

ld /usr/lib64/crt1.o /usr/lib64/crti.o main.o \
--start-group \
/lib64/libc.a \
/usr/lib/gcc/x86_64-redhat-linux/11/libgcc.a \
/usr/lib/gcc/x86_64-redhat-linux/11/libgcc_eh.a \
--end-group \
/usr/lib64/crtn.o
ysc3839
2022-01-17 20:25:15 +08:00
@kgdb00 多谢指正。搜了一下是 discouraged 静态链接,而不是不支持
lcdtyph
2022-01-17 21:30:57 +08:00
@kgdb00 #6
生成 main.o 的时候加上 -nostdlib -nodefaultlib
kgdb00
2022-01-17 22:50:49 +08:00
@lcdtyph 试了,不行,和没加这两个参数效果一样,去掉 /usr/lib/gcc/x86_64-redhat-linux/11/libgcc.a 和 /usr/lib/gcc/x86_64-redhat-linux/11/libgcc_eh.a 后报的错一样。
kgdb00
2022-01-17 22:53:36 +08:00
@kgdb00 报的错如下:
ld: /lib64/libc.a(iofclose.o): in function `_IO_new_fclose.cold':
(.text.unlikely[.text.unlikely.group]+0x33): undefined reference to `_Unwind_Resume'
ld: /lib64/libc.a(iofclose.o):(.data.rel.local.DW.ref.__gcc_personality_v0[DW.ref.__gcc_personality_v0]+0x0): undefined reference to `__gcc_personality_v0'
ld: /lib64/libc.a(iofflush.o): in function `_IO_fflush.cold':
(.text.unlikely[.text.unlikely.group]+0x32): undefined reference to `_Unwind_Resume'
ld: /lib64/libc.a(wfileops.o): in function `_IO_wfile_underflow.cold':
(.text.unlikely[.text.unlikely.group]+0x3d): undefined reference to `_Unwind_Resume'
ld: /lib64/libc.a(fileops.o): in function `_IO_new_file_underflow.cold':
(.text.unlikely[.text.unlikely.group]+0x33): undefined reference to `_Unwind_Resume'
ld: /lib64/libc.a(printf_fp.o): in function `__printf_fp_l':
(.text+0x53f): undefined reference to `__unordtf2'
ld: (.text+0x585): undefined reference to `__unordtf2'
ld: (.text+0x5ab): undefined reference to `__letf2'
ld: /lib64/libc.a(printf_fphex.o): in function `__printf_fphex':
(.text+0xa6): undefined reference to `__unordtf2'
ld: (.text+0xd9): undefined reference to `__unordtf2'
ld: (.text+0xf6): undefined reference to `__letf2'
ld: /lib64/libc.a(iofputs.o): in function `_IO_fputs.cold':
(.text.unlikely[.text.unlikely.group]+0x32): undefined reference to `_Unwind_Resume'
ld: /lib64/libc.a(iofwrite.o): in function `_IO_fwrite.cold':
(.text.unlikely[.text.unlikely.group]+0x32): undefined reference to `_Unwind_Resume'
ld: /lib64/libc.a(iogetdelim.o): in function `__getdelim.cold':
(.text.unlikely[.text.unlikely.group]+0x32): undefined reference to `_Unwind_Resume'
ld: /lib64/libc.a(pthread_once.o): in function `__pthread_once_slow.cold':
(.text.unlikely[.text.unlikely.group]+0x25): undefined reference to `_Unwind_Resume'

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/828815

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX