Provide a way of linking libgcc statically

b08b504
Opened by JP Sugarbroad at 2025-01-26 11:01:01

gcc et al provide "-static-libgcc" for platforms where a link to libgcc_s.so is undesirable. I need similar functionality in rustc because the cloud I'm deploying to doesn't have that in its runtime.

See issue #29482 for some background.

/cc @alexcrichton

  1. I'd personally be interested in just doing this unconditionally, I don't recall if there's a technical reason to link to the dynamic version beyond "just because", but there may be a good reason to!

    Alex Crichton at 2015-11-02 23:38:38

  2. I seem to remember that libgcc keeps some singleton state around, so there's questions of how dynlibs avoid getting their own state. I could be wrong.

    JP Sugarbroad at 2015-11-03 00:41:29

  3. Once upon a time, it was necessary to use libgcc_s in order to throw a C++ exception from one shared library to another. That is no longer true on systems that use the GNU linker or gold. See http://www.airs.com/blog/archives/166 for background.

    Ian Lance Taylor at 2015-11-04 02:30:04

  4. Triage: no changes i'm aware of

    Steve Klabnik at 2017-03-08 19:42:48

  5. @alexcrichton: Could you please assess how hard it would be to implement this / provide instructions if you prefer for others to pick it up? Thanks.

    Sander Maijers at 2018-03-02 12:10:00

  6. Sorry I don't think I understand enough about how this change would be done in Rust to write up such instructions or evaluate it.

    Alex Crichton at 2018-03-02 19:11:19

  7. After inspecting the output from ...

    $ diff <(echo 'int main() {}' | g++ -static-libgcc --verbose -xc++ - 2>&1 | tr ' ' '\n') \
           <(echo 'int main() {}' | g++ --verbose -xc++ - 2>&1 | tr ' ' '\n')
    ...
    269a270
    > -lgcc_s
    271d271
    < -lgcc_eh
    272a273
    > -lgcc_s
    274d274
    < -lgcc_eh
    277,278c277,278
    ...
    

    ... a plausible workaround for this issue (tested on Linux only) could be:

    $ cat linkerdriver.wrap 
    #!/bin/bash
    
    for arg do
      shift
      case $arg in
        (-lgcc_s) : ;;
           (*) set -- "$@" "$arg" ;;
      esac
    done
    
    # replace 'cc' with the linker driver you actually want to invoke (most likely $CC)
    exec cc "$@" -lgcc_eh -lc
    
    $ # Change linker env var according to your target
    $ CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=$PWD/linkerdriver.wrap cargo build --verbose --package <my-package>
    
    $ ldd target/debug/my-binary
    	linux-vdso.so.1 (0x00007ffcd291f000)
    	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f81c9656000)
    	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f81c9507000)
    	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f81c9501000)
    	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f81c930f000)
    	/lib64/ld-linux-x86-64.so.2 (0x00007f81ca741000)
    

    Nehal J Wani at 2021-10-01 03:55:40

  8. The current version of the Steam runtime provides a build of GCC 9 that does not include a dynamic libgcc at all, so this would be nice for being able to use a consistent, modern gcc build in that environment.

    @nehaljwani's workaround, slightly tweaked to replace -lgcc_eh -lc with -lgcc, got steam runtime gcc 9 working for me.

    Benjamin Saunders at 2021-10-21 00:15:47

  9. This looks like a general request for the binaries rustc generates, it's not specific to bootstrapping.

    @rustbot label -T-bootstrap

    jyn at 2023-05-24 21:03:03

  10. a plausible workaround for this issue (tested on Linux only) could be:

    Here's a (much) more simplified version of this workaround wrapper using well-known Bashisms:

    #!/bin/bash
    
    exec "${CC:-cc}" "${@/-lgcc_s/-lgcc_eh}"
    

    Echo J. at 2025-01-26 10:48:24