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

x86_64-unknown-linux-musl target and main-returning-Result produces a dynamically-linked executable instead of a statically linked one. #54243

Closed
luqmana opened this issue Sep 15, 2018 · 5 comments
Labels
O-musl Target: The musl libc

Comments

@luqmana
Copy link
Member

luqmana commented Sep 15, 2018

I've run into this weird interaction between the musl target, diesel, returning Result from main and debug vs release mode.

The setup:

Cargo.toml:

[package]
name = "main-musl-bug"
version = "0.1.0"

[dependencies]
diesel = { version = "1.3", features = ["sqlite"] }

main.rs:

extern crate diesel;

fn main() -> Result<(), std::io::Error> {
    println!("Hello, world!");
    Ok(())
}

Now if we take this simple innocuous looking program and try to run it:

➜  cargo run --target x86_64-unknown-linux-musl 
   Compiling main-musl-bug v0.1.0 (/home/luqman/Develop/tmp/main-musl-bug)                                                 
    Finished dev [unoptimized + debuginfo] target(s) in 0.37s                                                              
     Running `target/x86_64-unknown-linux-musl/debug/main-musl-bug`
error: could not execute process `target/x86_64-unknown-linux-musl/debug/main-musl-bug` (never executed)

Caused by:
  No such file or directory (os error 2)

Well, the file is definitely there but running file gives this:

➜  file ./target/x86_64-unknown-linux-musl/debug/main-musl-bug
./target/x86_64-unknown-linux-musl/debug/main-musl-bug: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld64.so.1, BuildID[sha1]=c43d7e9e32151f6240e2e93e744c3bda8e2e179f, with debug_info, not stripped

That's odd, I would've expected a statically linked binary but file disagrees here. The no such file or directory error I'm guessing results from the bogus program interpreter in the elf header:

➜  readelf -a ./target/x86_64-unknown-linux-musl/debug/main-musl-bug
[...]
      [Requesting program interpreter: /lib/ld64.so.1]
[...]

That path doesn't exist on my machine.

Now, the weird thing is a couple different things workaround the issue:

  1. build/run with --release OR
  2. use a plain old fn main() { ... } function.

rustc/cargo version:

➜  ~ rustc -V
rustc 1.29.0 (aa3ca1994 2018-09-11)
➜  ~ cargo -V
cargo 1.29.0 (524a578d7 2018-08-05)

EDIT: Repros on stable.

@luqmana luqmana added the O-musl Target: The musl libc label Sep 15, 2018
@bossmc
Copy link
Contributor

bossmc commented Sep 19, 2018

Is this repros on nightly you can add rustflags = ["-Z", "print-link-args"] to the [build] section of your .cargo/config file (see https://doc.rust-lang.org/cargo/reference/config.html) to see the actual link command used which should help analyse this issue.

@bossmc
Copy link
Contributor

bossmc commented Sep 21, 2018

I think there's various things going on here:

  1. I guess you're linking with gcc and are thus linking to the system-wide libsqlite3.so (dynamically) - this leads to your issue, but it's never going to work anyway
    • The reason --release made this appear to work is that the dynamic link was optimized out (as it's not used anywhere)
    • I'm guessing something similar occurs with non-Result main the linker can more easily see that the dynamic library is unneeded
  2. Changing the linker to musl-gcc leads to -lsqlite3: Not found errors (as expected - musl-gcc sets library lookup paths to a special place to prevent cross-contamination)
  3. Adding libsqlite3-sys = { version = "0.9.3", features = ["bundled"] } as a dependency causes a local (static/musl) version to be compiled and linked in and the world to work once more. Probably diesel should add that feature when compiling for x86_64-unknown-linux-musl....?

@luqmana
Copy link
Member Author

luqmana commented Sep 22, 2018

@bossmc Hmm, I'm pretty sure it's already using musl-gcc (since I forgot to install it earlier and it complained).

And yea, just working around it now by using the bundled version for now.

@bossmc
Copy link
Contributor

bossmc commented Sep 22, 2018

Can you run the print-link-args test and paste the output?

@luqmana
Copy link
Member Author

luqmana commented Sep 22, 2018

Ah ok, you were right, it was indeed just invoking cc. I only got the error when I was trying the bundled sqlite feature.

A bit unfortunate but the bundled feature does actually map to more what I want.

Thanks @bossmc

@luqmana luqmana closed this as completed Sep 24, 2018
smaeul added a commit to smaeul/rust that referenced this issue Nov 10, 2018
gcc/ld will create a dynamically-linked executable without warning, even
when passed `-static`, when asked to link to a `.so`. Avoid this
confusing and unintended behavior by always using the static version of
libraries when trying to link static executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue Dec 29, 2018
gcc/ld will create a dynamically-linked executable without warning, even
when passed `-static`, when asked to link to a `.so`. Avoid this
confusing and unintended behavior by always using the static version of
libraries when trying to link static executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue Dec 29, 2018
gcc/ld will create a dynamically-linked executable without warning, even
when passed `-static`, when asked to link to a `.so`. Avoid this
confusing and unintended behavior by always using the static version of
libraries when trying to link static executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue Mar 18, 2019
gcc/ld will create a dynamically-linked executable without warning, even
when passed `-static`, when asked to link to a `.so`. Avoid this
confusing and unintended behavior by always using the static version of
libraries when trying to link static executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue Apr 2, 2019
On ELF targets like Linux, gcc/ld will create a dynamically-linked
executable without warning, even when passed `-static`, when asked to
link to a `.so`. Avoid this confusing and unintended behavior by always
using the static version of libraries when trying to link static
executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue May 21, 2019
On ELF targets like Linux, gcc/ld will create a dynamically-linked
executable without warning, even when passed `-static`, when asked to
link to a `.so`. Avoid this confusing and unintended behavior by always
using the static version of libraries when trying to link static
executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue May 27, 2019
On ELF targets like Linux, gcc/ld will create a dynamically-linked
executable without warning, even when passed `-static`, when asked to
link to a `.so`. Avoid this confusing and unintended behavior by always
using the static version of libraries when trying to link static
executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue Sep 3, 2019
On ELF targets like Linux, gcc/ld will create a dynamically-linked
executable without warning, even when passed `-static`, when asked to
link to a `.so`. Avoid this confusing and unintended behavior by always
using the static version of libraries when trying to link static
executables.

Fixes rust-lang#54243
smaeul added a commit to smaeul/rust that referenced this issue Nov 5, 2019
On ELF targets like Linux, gcc/ld will create a dynamically-linked
executable without warning, even when passed `-static`, when asked to
link to a `.so`. Avoid this confusing and unintended behavior by always
using the static version of libraries when trying to link static
executables.

Fixes rust-lang#54243
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-musl Target: The musl libc
Projects
None yet
Development

No branches or pull requests

2 participants