Skip to content

Conversation

@oxalica
Copy link
Owner

@oxalica oxalica commented May 29, 2024

Upstream-shipped rust-ld is now used as default linker for some targets on nightly. It needs ld-wrapper for interopation with libraries from Nix. Currently wrapBintools interface is uneasy for hook use inside a derivation also containing non-bintools stuff. We hereby copy part of the implementation and wrap rust-ld in-place.

See: rust-lang/rust#71515 (comment)
Fixes #168

External library linking is now working correct. Previously it compiles but the binary fails to run.

$ echo '#[link(name = "crypt")] extern "C" { fn crypt(); } fn main() { dbg!(crypt as unsafe extern "C" fn()); }' >test.rs
$ nix build -f ./repl.nix rust-bin.nightly.2024-05-27.minimal
$ nix-shell -p libxcrypt --run './result/bin/rustc test.rs'
$ ./test
[test.rs:3:13] crypt as unsafe extern "C" fn() = 0x00007f1b90941a40 # address is not deterministic tho

Upstream-shipped `rust-ld` is now used as default linker for some
targets on nightly. It needs ld-wrapper for interopation with libraries
from Nix. Currently `wrapBintools` interface is uneasy for hook use
inside a derivation also containing non-bintools stuff. We hereby copy
part of the implementation and wrap `rust-ld` in-place.

See: rust-lang/rust#71515 (comment)
We use `env` attrset in `mkDerivation`.
@Nemo157
Copy link

Nemo157 commented May 29, 2024

I can confirm this works in my test project too. Building with RUSTC_LOG=rustc_codegen_ssa::back::link=info cargo rustc -- -Clink-arg=-Wl,-v I can see in the logs it's using /nix/store/ij8y2zxhbq4ys6d7zrj0iqq0hrm14xdh-rust-minimal-1.80.0-nightly-2024-05-29/lib/rustlib/x86_64-unknown-linux-gnu/bin/gcc-ld/ld.lld as the linker, and the associated rust-lld from there is the wrapped script, and the resulting binary successfully finds its native dependencies.

@oxalica oxalica merged commit 0bf05d8 into master May 29, 2024
@oxalica oxalica deleted the feat/rust-ld-wrapper branch May 29, 2024 23:39
@dianqk
Copy link

dianqk commented May 29, 2024

Will you port to the upstream rustup? I've submitted a PR (NixOS/nixpkgs#314268), but it only ensures that rust-lld can run. :)

@oxalica
Copy link
Owner Author

oxalica commented May 30, 2024

Will you port to the upstream rustup? I've submitted a PR (NixOS/nixpkgs#314268), but it only ensures that rust-lld can run. :)

Sorry but I think it may be too complicated to handle ld wrapping as a rustup patch, especially with the current wrapBintoolsWith interface. It may also be fragile because of adding more store path dependencies on the wrapped ELF/script, as they cannot be tracked by nix's GC. You can try it if you want to, though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Change to use self-contained lld by default in rustup nightly artifacts breaks native linking

4 participants