rustup icon indicating copy to clipboard operation
rustup copied to clipboard

Rustup should warn if libgcc is not installed on Alpine

Open thedrow opened this issue 5 years ago • 35 comments

Describe the problem you are trying to solve

In Linux distributions which depend on musl libc, cargo crashes if libgcc is not present. This is the case in Alpine docker containers.

cargo
Error loading shared library libgcc_s.so.1: No such file or directory (needed by /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo)
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_GetIPInfo: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_GetDataRelBase: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_GetRegionStart: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_SetGR: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_FindEnclosingFunction: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_GetTextRelBase: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_Resume: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_DeleteException: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_RaiseException: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_GetIP: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_Backtrace: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_GetLanguageSpecificData: symbol not found
Error relocating /root/.rustup/toolchains/stable-x86_64-unknown-linux-musl/bin/cargo: _Unwind_SetIP: symbol not found

Unless you know what to install in order to resolve this issue, it is baffling. This problem will mainly affect beginners who want to learn rust.

Describe the solution you'd like

Rustup should warn on musl libc distributions (or maybe in any distribution) if it can't find libgcc.

Notes

thedrow avatar Jan 22 '20 14:01 thedrow

Currently we have only Windows-specific information about toolchains and the like because it's semi-assumed that Linux and Mac OS people will know what they're doing to get their particular local distro's toolchains. It might be interesting for us to smoke-test components after installation and warn, but I'm not sure we can properly detect and diagnose this kind of issue across all our Linuxy targets.

Does rustc work? Is it only cargo which is failing like this? If rustc similarly fails, then we could could possibly add a message if we can't get rustc's version after install/update.

kinnison avatar Jan 25 '20 08:01 kinnison

rustc does not work as well. In fact, all the executables installed by rustup do not work without libgcc on Alpine.

thedrow avatar Jan 26 '20 10:01 thedrow

What is the right way to install libgcc here? apk?

rbtcollins avatar Jan 27 '20 01:01 rbtcollins

What is the right way to install libgcc here? apk?

Indeed.

thedrow avatar Jan 27 '20 10:01 thedrow

Is this intended that cargo on musl target depend on libgcc dynamically and cannot be replaced? I ping @pietroalbini as he may know the answer or who else know that.

tesuji avatar Jan 27 '20 16:01 tesuji

Hmm, I don't really know who to ask.

pietroalbini avatar Jan 28 '20 10:01 pietroalbini

Is this intended that cargo on musl target depend on libgcc dynamically and cannot be replaced? I ping @pietroalbini as he may know the answer or who else know that.

That's a very good question. I haven't thought of that.

thedrow avatar Jan 28 '20 13:01 thedrow

Thank pietroalbini. I ping @ehuss as another change to get answer for https://github.com/rust-lang/rustup/issues/2213#issuecomment-578838898 .

tesuji avatar Jan 28 '20 14:01 tesuji

I think the short answer is yes, libgcc_s.so is needed for now. I don't know if it is possible (or desirable) to avoid.

But you're also asking the wrong person, as I know next to nothing about musl. I think @mati865 is the expert here (rust-lang/rust#59302).

ehuss avatar Jan 28 '20 15:01 ehuss

It's not specific to musl. Similar error will appear when you try to run Cargo on glibc based distro without libgcc_s.so.1 installed.

The reason you can see it here but not on Ubuntu is because Alpine containers are stripped to the bare minimum and nothing has pulled libgcc as a dependency.

Generally you need linker (GCC or Clang) to use Rust and I'd be surprised if installing one of them haven't pulled libgcc.

So the only issue here could be missing documentation (I haven't checked).

mati865 avatar Jan 28 '20 15:01 mati865

So this is another example of "where does the documentation belong?" -- for Windows we include instructions on getting the MSVC tooling installed, but we don't include instructions really for other platforms. Where do we draw the line? Should the instructions be in the code or just the README, etc. There is at least some assumption that developers installing Rust with rustup know what they're doing with respect to developing software on their host platform because otherwise they're going to encounter many other interesting problems; but perhaps we (as an organisation) need to start documenting things more thoroughly so that newcomers are less surprised with the complexities?

I'm not sure that rustup can do anything programmatically to solve this, but perhaps more README docs are plausible.

kinnison avatar Jan 28 '20 17:01 kinnison

So this is another example of "where does the documentation belong?" -- for Windows we include instructions on getting the MSVC tooling installed, but we don't include instructions really for other platforms. Where do we draw the line? Should the instructions be in the code or just the README, etc. There is at least some assumption that developers installing Rust with rustup know what they're doing with respect to developing software on their host platform because otherwise they're going to encounter many other interesting problems; but perhaps we (as an organisation) need to start documenting things more thoroughly so that newcomers are less surprised with the complexities?

I'm not sure that rustup can do anything programmatically to solve this, but perhaps more README docs are plausible.

Assuming that the user knows the platform they are using is a bad idea. What if they are a junior developer with no prior experience with Docker or with Alpine?

thedrow avatar Jan 28 '20 17:01 thedrow

I feel it's a really tough call to make @thedrow -- is it our place to know all the possible targets and the possible dependencies our users might have or not have? Or is it our place to recommend that platforms document what's needed to get Rust working? If we assume it's the responsibility of the rust-lang org in some sense, then what's the right thing to do? Something specific to Alpine? Something where we guess that if you're unable to run rustc and the host and build are musl then you can run whatever this apk is? We don't instruct Ubuntu/Debian people to apt install binutils or for Fedora people to play with yum. Where is the cutoff and where does the documentation go, and who is responsible for ensuring it's correct and kept up to date?

I really want to do the right thing here, but we need to work out what that is.

kinnison avatar Jan 28 '20 17:01 kinnison

I think we need to document about using Rustc on Alpine in Rustup's README file. The requirement is that Rustc needs gcc or clang pre-existing.

tesuji avatar Jan 30 '20 13:01 tesuji

I think we need to document about using Rustc on Alpine in Rustup's README file. The requirement is that Rustc needs gcc or clang pre-existing.

It's not only for Alpine but for every Linux. While Ubuntu has libgcc installed by default I think it does have gcc.

mati865 avatar Jan 30 '20 13:01 mati865

Yes, I agree. While people could run rustc and cargo when having libgcc, missing C compiler prevents users from compiling libc, which is a huge loss anyway.

tesuji avatar Jan 30 '20 13:01 tesuji

So somewhere in README.md we should perhaps have a small section about how you most likely need gcc or clang in order to usefully build Rust applications, and how rustc and cargo itself is linked against libgcc on Linux platforms. Then instructions for a few common Linux platforms? That'd be a PR I'd very much consider merging.

kinnison avatar Feb 01 '20 17:02 kinnison

A tree of platform specific notes / gotchas with rust? I could see that being well read.

gilescope avatar Sep 23 '20 10:09 gilescope

Yes, I agree. While people could run rustc and cargo when having libgcc, missing C compiler prevents users from compiling libc, which is a huge loss anyway.

Rustc uses GCC as the linker so users without GCC installed can only create static libs.

mati865 avatar Sep 23 '20 10:09 mati865

Rustc uses GCC as the linker so users without GCC installed can only create static libs.

@mati865 while this is true with the default config, it's possible to tell rustc to use rust-lld to link crates. In fact, this is done by default for certain targets (wasm comes to mind) and is used in a few projects to allow Rust to work standalone, without requiring additional software to be installed on the host.

My expectations for the musl toolchain binaries were for them to be entirely statically linked. After all, when you build a crate with the musl toolchain, it defaults to statically linking the libc and everything else. Is there a reason why libgcc-s cannot be statically linked?

roblabla avatar Nov 16 '20 16:11 roblabla

My expectations for the musl toolchain binaries were for them to be entirely statically linked. After all, when you build a crate with the musl toolchain, it defaults to statically linking the libc and everything else. Is there a reason why libgcc-s cannot be statically linked?

@roblabla in the past there was no way to build proc-macros (they are required by cargo and rustc) without dynamic linking. So in order to support musl as the host, the toolchain had to be linked dynamically. I don't know if this limitation still holds but the right place to ask for it would be rustc bugtracker: https://github.com/rust-lang/rustup/issues/

mati865 avatar Nov 16 '20 16:11 mati865

I am trying to create a "No GNU" Rust toolchain stack on Alpine Linux. Any chance I can use compiler-rt from the llvm project in libgcc's stead?

iranvir avatar Jan 22 '21 23:01 iranvir

I am trying to create a "No GNU" Rust toolchain stack on Alpine Linux. Any chance I can use compiler-rt from the llvm project in libgcc's stead?

This issue is about libgcc_s which provide the same functions of llvm's libunwind.

Functions of libgcc is provided by https://github.com/rust-lang/compiler-builtins/

12101111 avatar Jan 23 '21 05:01 12101111

I am trying to create a "No GNU" Rust toolchain stack on Alpine Linux. Any chance I can use compiler-rt from the llvm project in libgcc's stead?

You might have better luck trying llvm-crt-replacement.

firasuke avatar Apr 24 '21 18:04 firasuke

@rustbot label: +O-linux

workingjubilee avatar Apr 29 '21 20:04 workingjubilee

You might have better luck trying llvm-crt-replacement.

crt is a different thing, see the doc at https://github.com/rust-lang/rust/blob/master/compiler/rustc_target/src/spec/crt_objects.rs

But it's possible to bootstrap such toolchain that don't need libgcc_s.so or libunwind.so: https://github.com/rust-lang/rust/pull/85600

> ldd stage1-tools-bin/cargo
	/lib/ld-musl-x86_64.so.1 (0x7f36d5bca000)
	libc.so => /lib/ld-musl-x86_64.so.1 (0x7f36d5bca000)
> lddtree stage2/bin/rustc
rustc => stage2/bin/rustc (interpreter => /lib/ld-musl-x86_64.so.1)
    librustc_driver-834e481193e490c9.so => stage2/bin/../lib/librustc_driver-834e481193e490c9.so
    libstd-e89f79e493e23cf7.so => stage2/bin/../lib/libstd-e89f79e493e23cf7.so
    libc.so => /usr/lib/libc.so

12101111 avatar May 19 '21 07:05 12101111

@rustbot label: +O-containers

workingjubilee avatar May 21 '21 19:05 workingjubilee

What is the current recommended approach for this? Just apk add libgcc or any better toolchain?

rinarakaki avatar Aug 31 '23 19:08 rinarakaki

Couldn't this issue be solved by linking LLVM libunwind statically in the binary builds used for Rustup?

Even dynamic libunwind.so works as a drop-in replace replacing libgcc_s for me. I'm running Gentoo (with llvm+musl profile), I don't have GCC installed and all I had to do to fix the issue locally is:

ln -s /usr/lib/libunwind.so.1 /usr/lib/libgcc_s.so.1
ln -s /usr/lib/libunwind.so /usr/lib/libgcc_s.so

That's it. I'm pretty sure it would work on Alpine too. Rustup toolchains work and I didn't have to install GCC, my environment pretty much stays non-GNU. I'm using Rust daily for pretty much all of my programming work and I didn't notice any issues.

But I think that the right thing to do would be just linking libunwind statically. Any objections against that? I think that would make everyone happy:

  • People trying to use non-GNU musl-based distros/sysroots.
  • Users of GNU/glibc-based distros who are not going to notice any difference.

From what @12101111 says, it should be already possible. I can try building rustc myself and I will follow up with a config and options that need to be passed, if you are open for going with this solution.

vadorovsky avatar Dec 31 '23 16:12 vadorovsky

It is unlikely that rustup's build will be significantly special-cased compared to the default build for that platform. If the appropriate thing to change here is to change the linkage of programs, then it is a problem that should probably be addressed upstream with rustc. I recommend that this issue be closed, because it incorrectly asks for rustup to have a special behavior regarding issuing warnings instead of simply solving the damn problem.

workingjubilee avatar Jan 01 '24 20:01 workingjubilee