4

New to rust, trying to build a debug version for a binary in ubuntu which fails with below linking error:

linking with `cc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/home/my_home/.rustup/toolchains/nightly-2023-05-31-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/home/my_home/my_project-2-dev/bin:/home/my_home/.nvm/versions/node/v16.19.1/bin:/home/my_home/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" VSLANG="1033" "cc" "-m64" "/tmp/rustcsg0duh/symbols.o" "/home/my_home/my_project-2-dev/my_service/target/debug/deps/my_project_my_service_abc-8aad4b2b83ae80f6.10vvqzkopsquoi13.rcgu.o" "/home/my_home/my_project-2-dev/my_service/target/debug/deps/my_project_my_service_abc-8aad4b2b83ae80f6.11rgc8keoer74gis.rcgu.o" "/home/my_home/my_project-2-dev/my_service/target/debug/deps/my_project_my_service_abc-8aad4b2b83ae80f6.12a9dvufwkt6aflp.rcgu.o" "/home/my_home/my_project-2-dev/my_service/target/debug/deps/my_project_my_service_abc-8aad4b2b83ae80f6.14sl35u4afv70bhq.rcgu.o" "/home/my_home/my_project-2-dev/my_service/target/debug/deps/my_project_my_service_abc-8aad4b2b83ae80f6.15avg65pxqdjpcwx.rcgu.o"

  = note: /home/my_home/.rustup/toolchains/nightly-2023-05-31-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-a8a9ba95b1228749.rlib(std-a8a9ba95b1228749.std.97c55777bef24d10-cgu.0.rcgu.o):(.debug_info+0x12): relocation truncated to fit: R_X86_64_32 against `.debug_str'
          /home/my_home/.rustup/toolchains/nightly-2023-05-31-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-a8a9ba95b1228749.rlib(std-a8a9ba95b1228749.std.97c55777bef24d10-cgu.0.rcgu.o):(.debug_info+0x73): additional relocation overflows omitted from the output
          collect2: error: ld returned 1 exit status

my versions on ubuntu are:

cc --version
cc (Ubuntu 11.3.0-1ubuntu1~22.04.1) 11.3.0
ld --version
GNU ld (GNU Binutils for Ubuntu) 2.38

whereas on macos both the debug and the release build both passes.

cc --version
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.5.0

My suspicion is the issue is with the linker on ubuntu, not sure how to troubleshoot, any help is highly appreciated?

akram
  • 157
  • 1
  • 15
  • 2
    https://stackoverflow.com/questions/10486116/what-does-this-gcc-error-relocation-truncated-to-fit-mean and https://www.technovelty.org/c/relocation-truncated-to-fit-wtf.html ; Most likely `-fPIC` option is missing. But to be sure you need to explain how to reproduce your problem. I understand that [mcve](https://stackoverflow.com/help/minimal-reproducible-example) might be difficult in case of third-party libs compilation, but at least github link, version, and steps you follow. – pptaszni Jul 27 '23 at 09:02
  • Not sure to help you without being able to reproduce this. "A binary" is not very specific. – Finomnis Aug 19 '23 at 11:02
  • You could [try to link with `lld` (llvm linker)](https://nnethercote.github.io/perf-book/compile-times.html#linking). Start your `cargo` command with `RUSTFLAGS="-C link-arg=-fuse-ld=lld" cargo ...`. It's faster anyway, and it doesn't suffer from weird link order problems, so I personally enabled it by default for my projects. – Finomnis Aug 19 '23 at 11:07
  • Can you check your RAM usage? I've seen linker fails without giving much details if it goes out of memory. I assume your ubuntu is a VM. Try increasing the swap size – Pier-Yves Lessard Aug 20 '23 at 17:22

1 Answers1

1

By default, on x86-64, the compiler reserves 32 bits for a relocation, which is an address that can be used to find an object. However, in your case, the object is more than 4 GiB away, so a 32-bit relocation can't be used. This article explains the problem really well.

The likely reason you see this on Linux in debug mode and not release mode is because in release mode, (a) you don't have debugging information, which takes up space in the binary, and (b) typically the code is smaller because it's more optimized. The reason you don't see this on macOS is because you're using a different processor type, and arm64 allows different sizes of relocations (for example, 33-bit relocations, which might be large enough to not trigger the problem).

You can solve this problem by using -C code-model=large when compiling your Rust code. That can be done with the RUSTFLAGS environment variable. That tells the compiler that your binary is very large and you need it to reserve space for a large relocation when compiling, which should make this problem go away.

bk2204
  • 64,793
  • 6
  • 84
  • 100