Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpath is incorrect when crate links against compiler libraries #58343

Open
RalfJung opened this issue Feb 10, 2019 · 4 comments
Open

rpath is incorrect when crate links against compiler libraries #58343

RalfJung opened this issue Feb 10, 2019 · 4 comments
Labels
A-miri Area: The miri tool C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@RalfJung
Copy link
Member

RalfJung commented Feb 10, 2019

When compiling something like Miri that links against librustc and other compiler libraries, even with rpath = true in my Cargo.toml, the resulting binary does not work without LD_LIBRARY_PATH:

$ target/release/miri
target/release/miri: error while loading shared libraries: librustc_driver-e8ad12ee87dce48b.so: cannot open shared object file: No such file or directory

Looking at the bianary, I noticed a RUNPATH and no RPATH and learned that RPATH got deprecated in favor of RUNPATH:

$ readelf -d target/release/miri | egrep 'R(UN)?PATH'
 0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN/../../../../rustc.2/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib:/home/r/src/rust/miri/lib/rustlib/x86_64-unknown-linux-gnu/lib]

However, after some research, two things strike me about this:

  • First of all, the number of "../" is wrong -- there is one too much. Starting at the directory containing the binary (~/src/rust/miri/target/release), going up 4 times leads to ~/src, while the rustc.2 directory is at ~/src/rust/rustc.2.

  • Second, according to this, the binary needs to have the ORIGIN flag set for $ORIGIN to actually work, and that flag is not set: I verified this locally and that flag does not seem to be needed.

    $ readelf -d target/release/miri | egrep -i flag
     0x000000000000001e (FLAGS)              BIND_NOW
     0x000000006ffffffb (FLAGS_1)            Flags: NOW PIE
    

I am also really surprised that it encodes the path to the sysroot as relative to the binary, but the path to other libs compiled in the same crate as absolute to the binary. Shouldn't it rather be the other way around?

@RalfJung RalfJung changed the title rpath is insufficient when crate links against compiler libraries rpath is incorrect when crate links against compiler libraries Feb 10, 2019
@RalfJung
Copy link
Member Author

The "one ../ too much" is caused by --out-dir /home/r/src/rust/miri/target/release/deps, which is passed in by cargo: Cargo builds the binary in a different directory and moves it around later, which of course is not compatible with relative RPATHS.

Cc @alexcrichton

@RalfJung
Copy link
Member Author

Notice that relative rpaths are generally unsuited for what I want to do, which is cargo install --path . and then use the binary. So I need binaries that survive being copied around.

I suppose there are also good reasons to want relative rpaths, so I think this should be a flag. I am not sure what kind of flag and what would be a good default, though.

@RalfJung
Copy link
Member Author

Turns out $ORIGIN works without -z origin being passed to the linker -- I still wonder if we should set that flag, though.

@BD103
Copy link

BD103 commented Sep 4, 2024

For those who stumble upon this issue, you can workaround this by specifying LD_LIBRARY_PATH when executing the binary.

# Fails
$ ./target/debug/binary
./target/debug/binary: error while loading shared libraries: librustc_driver-110042e1a47a5f15.so: cannot open shared object file: No such file or directory

# Add the path to the `lib` folder of your toolchain.
$ LD_LIBRARY_PATH=~/.rustup/toolchains/nightly-2024-08-21-x86_64-unknown-linux-gnu/lib ./target/debug/binary
(Runs successfully)

Interestingly enough, I don't have to specify LD_LIBRARY_PATH when using cargo run. Perhaps Cargo automatically adds the environmental variable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-miri Area: The miri tool C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants