V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
kgdb00
V2EX  ›  C

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

  •  
  •   kgdb00 · 2022-01-17 17:10:22 +08:00 · 1573 次点击
    这是一个创建于 1044 天前的主题,其中的信息可能已经有所发展或是发生改变。
    《深入理解计算机系统》第 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 程序,要用那些参数?
    第 1 条附言  ·  2022-01-17 18:24:23 +08:00
    我是想用 ld 做到如下 gcc 命令的效果:

    gcc -static main.o

    得到的 a.out 文件不需要 gnu c 库就能运行。

    d@desktop:~/test$ ldd a.out
    not a dynamic executable
    10 条回复    2022-01-17 22:53:36 +08:00
    kgdb00
        1
    kgdb00  
    OP
       2022-01-17 18:27:43 +08:00
    ld 能静态链接一个普通的用户库,比如 foo.o 或 libfoo.a ,我想知道的是如何静态链接 gnu c 库。
    ysc3839
        2
    ysc3839  
       2022-01-17 19:12:28 +08:00
    @kgdb00 glibc 不支持静态链接,你需要换别的 c 库。
    secondwtq
        3
    secondwtq  
       2022-01-17 19:23:09 +08:00
    GCC 和 Clang 都可以通过使用 -### 参数显示编译过程中运行的命令
    kgdb00
        4
    kgdb00  
    OP
       2022-01-17 20:03:12 +08:00
    @ysc3839 可以静态链接的,fedora 上有一个 glibc-static 包,这个包有一个 /usr/lib64/libc.a 文件,就是 glibc 的静态库
    kgdb00
        5
    kgdb00  
    OP
       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
        6
    kgdb00  
    OP
       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
        7
    ysc3839  
       2022-01-17 20:25:15 +08:00 via Android
    @kgdb00 多谢指正。搜了一下是 discouraged 静态链接,而不是不支持
    lcdtyph
        8
    lcdtyph  
       2022-01-17 21:30:57 +08:00
    @kgdb00 #6
    生成 main.o 的时候加上 -nostdlib -nodefaultlib
    kgdb00
        9
    kgdb00  
    OP
       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
        10
    kgdb00  
    OP
       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'
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5484 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 18ms · UTC 07:40 · PVG 15:40 · LAX 23:40 · JFK 02:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.