Cargo: wrong libc linked during build

Created on 22 Jan 2019  ·  5Comments  ·  Source: rust-lang/cargo

Problem


It's been just two months I have not touched Rust but today after upgrading to the most recent version I was no longer able to use cargo install.

Steps

  1. update to rust 1.32: rustup update + rustup default stable
  2. cargo install ripgrep

at the end of compilation the error message shows up:

  ...
  Compiling globset v0.4.2
  Compiling grep-regex v0.1.1
  Compiling grep-cli v0.1.1
  Compiling ignore v0.4.6
  Compiling grep-printer v0.1.1
error: /usr/lib64/libc.so.6: version `GLIBC_2.18' not found (required by /tmp/cargo-installkV0c2k/release/deps/libserde_derive-615594b83ebc865a.so)
  --> ~/.cargo/registry/src/github.com-1ecc6299db9ec823/grep-printer-0.1.1/src/lib.rs:81:1
   |
81 | extern crate serde_derive;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: failed to compile `ripgrep v0.10.0`, intermediate artifacts can be found at `/tmp/cargo-installkV0c2k`

I think the problem happens at linking time so I don't know if the additional error message at the end was really helpful.

This should not happen because rustc is not supposed to link against /usr/lib64/libc.so.6:

➜  ~ ldd /tmp/cargo-installkV0c2k/release/deps/libserde_derive-615594b83ebc865a.so
linux-vdso.so.1 (0x00007fffe41ba000)
libdl.so.2 => /home/linuxbrew/.linuxbrew/lib/libdl.so.2 (0x00007ff1ce55a000)
librt.so.1 => /home/linuxbrew/.linuxbrew/lib/librt.so.1 (0x00007ff1ce352000)
libpthread.so.0 => /home/linuxbrew/.linuxbrew/lib/libpthread.so.0 (0x00007ff1ce135000)
libgcc_s.so.1 => /home/linuxbrew/.linuxbrew/lib/libgcc_s.so.1 (0x00007ff1cdf1e000)
libc.so.6 => /home/linuxbrew/.linuxbrew/lib/libc.so.6 (0x00007ff1cdb7f000)
/home/linuxbrew/.linuxbrew/Cellar/glibc/2.23/lib64/ld-linux-x86-64.so.2 (0x00007ff1cea71000)

and /home/linuxbrew/.linuxbrew/lib/libc.so.6 is an updated version of glibc:

➜  ~ strings /home/linuxbrew/.linuxbrew/lib/libc.so.6 | grep ^GLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
GLIBC_2.18
GLIBC_2.22
GLIBC_2.23
GLIBC_PRIVATE
GLIBC_2.23
GLIBC_2.8
GLIBC_2.5
GLIBC_2.9
GLIBC_2.7
GLIBC_2.6
GLIBC_2.18
GLIBC_2.11
GLIBC_2.16
GLIBC_2.10
GLIBC_2.17
GLIBC_2.13
GLIBC_2.2.6

Notes

Output of cargo version:

➜  ~ cargo version
cargo 1.32.0 (8610973aa 2019-01-02)
➜  ~ rustc --version 
rustc 1.32.0 (9fda7c223 2019-01-16)

The platform I have is CentOS 7. And if I downgrade rust to 1.31.0, it works without any problem. So this should be related to the version update.


A-linkage C-bug

Most helpful comment

This will lead to another problem when i tried to compile rust-zmq

error: linking with `/usr/bin/cc` failed: exit code: 1
  |
  = note: "/usr/bin/cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" ...
  = note: /home/linuxbrew/.linuxbrew/bin/ld: //home/linuxbrew/.linuxbrew/lib/libstdc++.so.6: undefined reference to `__cxa_thread_atexit_impl@GLIBC_2.18'
             collect2: error: ld returned 1 exit status

So i was wondering how to compile rust with linuxbrew glibc?

All 5 comments

I have the same problem.
But it seems to be rust issue because cargo 1.31.1 with rustc 1.32.0 can't fix it.
I created a new issue:
https://github.com/rust-lang/rust/issues/58394

The cause of this issue seems to be below:

  • libserde_derive-615594b83ebc865a.so is linked by cc. In linuxbrew environment, cc becomes ~/.linuxbrew/bin/cc by PATH environment variable. Therefore libserde_derive-615594b83ebc865a.so is linked to ~/.linuxbrew/lib/libc.so.6.
  • rustc loads libserde_derive-615594b83ebc865a.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.

There is a workaround that change cc to /usr/bin/cc.
If ~/.cargo/config is below, default linker becomes /usr/bin/cc, so this issue can be resolved.

[target.x86_64-unknown-linux-gnu]
linker = "/usr/bin/cc"

This will lead to another problem when i tried to compile rust-zmq

error: linking with `/usr/bin/cc` failed: exit code: 1
  |
  = note: "/usr/bin/cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" ...
  = note: /home/linuxbrew/.linuxbrew/bin/ld: //home/linuxbrew/.linuxbrew/lib/libstdc++.so.6: undefined reference to `__cxa_thread_atexit_impl@GLIBC_2.18'
             collect2: error: ld returned 1 exit status

So i was wondering how to compile rust with linuxbrew glibc?

Now I have another workaround.
If cargo command is defined like below, all linkers and compilers called by cargo become /usr/bin/cc.
This example is zsh function. If you use another shell, some modification may be required.

function cargo() {
      PATH=~/.cargo/bin:/usr/bin:/bin command cargo $@
}

I have a similar problem:

/app # rustup default
1.45.2-x86_64-unknown-linux-musl (default)
/app # cargo run --release --target x86_64-unknown-linux-musl --bin server
    Finished release [optimized] target(s) in 0.92s
     Running `target/x86_64-unknown-linux-musl/release/server`
error: could not execute process `target/x86_64-unknown-linux-musl/release/server` (never executed)
/app # ldd target/x86_64-unknown-linux-musl/release/server
    /lib/ld64.so.1 (0x7f6ee00f0000)
    libssl.so.1.1 => /lib/libssl.so.1.1 (0x7f6ee006f000)
    libcrypto.so.1.1 => /lib/libcrypto.so.1.1 (0x7f6edfdf0000)
    libc.musl-x86_64.so.1 => /lib/ld64.so.1 (0x7f6ee00f0000)
/app # cargo --version
cargo 1.45.1 (f242df6ed 2020-07-22)
/app # rustc -V
rustc 1.45.2 (d3fb005a3 2020-07-31)

The problem is that /lib/ld64.so.1 doesn't exist in the system (alpine 3.12) and despite i specified a musl target it still linked with /lib/ld64.so.1. Workaround which worked for me is to copy libc.musl-x86_64.so.1 to /lib/ld64.so.1 .

Was this page helpful?
0 / 5 - 0 ratings