Why would rust ran in linuxbrew try to link to system libc?

I am trying to install Rust in a shared machine where the philosophy is to avoid bugging the sysadmin with install requests and install what we need ourselves via linuxbrew.
As a result, I would like to install rust without any link to the system libs

I have tried to install via curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh which works fine but fails later when I try to install anything that depends on proc_macro, it fails on

Compiling proc-macro-error-attr v0.4.5
error: /lib64/libc.so.6: version `GLIBC_2.18' not found

I get bitten by the same error if I try to install rust via brew install rust (but earlier: when the bootstrap tries to install serde_deriv

Compiling serde_derive v1.0.81
error: /lib64/libc.so.6: version `GLIBC_2.18' not found

From what I gather, since cc, ld and pkg-config are those I installed via linuxbrew and those correctly return the path of the linuxbrew versions of the dependencies, so why is it looking at system's libc?

I am willing to investigate more, but I am quite new to this kind of setup and I have already spent around 10h on this so it'd be great if someone could provide some guidance :slight_smile:

I tried to reproduce your problem in a Docker container.
Can you provide more details about the setup?
What linux distro are you using, what packages are installed globally?

Hi, thanks for answering!

This is a CentOS 7.6, I am not sure which packages are relevant for this situation but the system packages for what I guess is useful are

  • glibc 1.7
  • gcc 4.8.5
  • pkgconfig 0.27.1

What might be relevant: since the idea is that every user has their own linuxbrew install, it is installed in ~/.linuxbrew and not in /home/linuxbrew/.linuxbrew. According to linuxbrew doc, it can be the cause of issues, but I suppose that mean linuxbrew-internal issues?

Can you write a script like this to reproduce it?

sudo docker run -it --rm centos bash

useradd -m foo
install -y glibc  gcc pkgconfig 
su foo -s /bin/bash

sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
brew install gcc
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.profile
git clone https://github.com/dtolnay/proc-macro-workshop.git ~/proc-macro-workshop
cd ~/proc-macro-workshop/builder/

cargo test

I can reproduce with

sudo docker run -it --rm centos:7 bash

useradd -m foo
yum install -y glibc gcc pkgconfig git curl make which exec
su foo -s /bin/bash     
                                                                         
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
echo 'eval $(/home/foo/.linuxbrew/bin/brew shellenv)' >>~/.bash_profile  
eval $(/home/foo/.linuxbrew/bin/brew shellenv)
brew install gcc
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.bash_profile
git clone https://github.com/dtolnay/proc-macro-workshop.git ~/proc-macro-workshop
cd ~/proc-macro-workshop/builder/
        
cargo test

Which fails when trying to build serde

error: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /home/foo/proc-macro-workshop/target/debug/deps/libserde_derive-1fde13ccc2fe8eee.so)
   --> /home/foo/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.104/src/lib.rs:269:1
    |
269 | extern crate serde_derive;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

error: could not compile `serde`.

Caused by:
  process didn't exit successfully: `rustc --crate-name serde /home/foo/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.104/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="derive"' --cfg 'feature="serde_derive"' --cfg 'feature="std"' -C metadata=bf88f8d06a013c99 -C extra-filename=-bf88f8d06a013c99 --out-dir /home/foo/proc-macro-workshop/target/debug/deps -L dependency=/home/foo/proc-macro-workshop/target/debug/deps --extern serde_derive=/home/foo/proc-macro-workshop/target/debug/deps/libserde_derive-1fde13ccc2fe8eee.so --cap-lints allow --cfg ops_bound --cfg core_reverse --cfg de_boxed_c_str --cfg de_boxed_path --cfg de_rc_dst --cfg core_duration --cfg integer128 --cfg range_inclusive --cfg num_nonzero --cfg core_try_from --cfg num_nonzero_signed --cfg std_atomic64 --cfg std_atomic` (exit code: 1)

Oh, also sorry, I forgot to mention this issue: Wrong glibc linked in building crates using proc_macro with linuxbrew · Issue #58394 · rust-lang/rust · GitHub with this finding

rustc loads libstructopt_derive-cdf0ae629ff7e333.so by libc::dlopen . The official rustc from rustup is linked to /lib64/libc.so.6 , so libc::dlopen use /etc/ld.so.(config|cache) as library search path. Therefore libc::dlopen is failed because ~/.linuxbrew/lib/libc.so.6 can't be found.

But I don't understand why rustup would link to /lib64's libc or how to change it

Ah, also (sorry for bumping) even easier to see the issue directly by trying to build serde


sudo docker run -it --rm centos:7 bash

useradd -m foo
yum install -y glibc gcc pkgconfig git curl make which exec
su foo -s /bin/bash     
                                                                         
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
echo 'eval $(/home/foo/.linuxbrew/bin/brew shellenv)' >>~/.bash_profile  
eval $(/home/foo/.linuxbrew/bin/brew shellenv)
brew install gcc
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source ~/.bash_profile
git clone https://github.com/serde-rs/serde.git ~/serde
cd ~/serde
        
cargo build

Another update: I tried to play with RUSTFLAGS and setting

export RUSTFLAGS="-L/usr/lib64"

does make serde build work, confirming that the issue is that by default something in the build chain is trying to use both system's and linuxbrew's libc since forcing it to use system's for everything works but I still want the opposite: run everything in linuxbrew.

I have tried reinstalling rustup with

export RUSTFLAGS="-L/home/foo/.linuxbrew/lib"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

but it didn't help: building serde still fails.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.