Skip to content

Windows GNU target: rsbegin.o / rsend.o injection is unconfigurable and breaks cross-compilation #146739

@tahadostifam

Description

@tahadostifam

What Happend?

When cross-compiling for x86_64-pc-windows-gnu on NixOS (or similar Linux environments), the Rust compiler automatically injects rsbegin.o and rsend.o into the linker command. However, there is no mechanism to configure or override the path to these startup object files.

Linker cannot find the object files unless they are in the expected sysroot location, e.g.:

$HOME/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-pc-windows-gnu/lib

Attempts to pass rsbegin.o / rsend.o manually via RUSTFLAGS or -C link-args result in duplicate object name errors, because the compiler still injects its own copies automatically.

This makes cross-compiling a minimal hello-world executable for x86_64-pc-windows-gnu unreliable on NixOS or other Linux systems using non-standard sysroot paths.

Steps to reproduce:

rustup target add x86_64-pc-windows-gnu
cargo new hello
cd hello
cargo build --target x86_64-pc-windows-gnu -Zbuild-std

Relevant code:

Rust bootstrap currently injects startup objects here:

https://github.com/rust-lang/rust/blob/master/src/bootstrap/src/core/build_steps/compile.rs#L909

for file in &["rsbegin", "rsend"] {
    let src_file = &src_dir.join(file.to_string() + ".rs");
    let dst_file = &dst_dir.join(file.to_string() + ".o");
    if !up_to_date(src_file, dst_file) {
        let mut cmd = Command::new(&builder.initial_rustc);
        cmd.env("RUSTC_BOOTSTRAP", "1");
        ...
        builder.run(
            cmd.arg("--target")
                .arg(target.rustc_target_arg())
                .arg("--emit=obj")
                .arg("-o")
                .arg(dst_file)
                .arg(src_file),
        );
    }
}

Proposed improvement / feature request:

  • Allow overriding the path to rsbegin.o / rsend.o via environment variable or Cargo configuration.

  • Alternatively, provide a mechanism to disable automatic injection for advanced cross-compilation setups.

This would make cross-compilation on non-standard systems (NixOS, custom sysroots) feasible without hacks.

Environment:

Rust nightly (toolchain: nightly-x86_64-unknown-linux-gnu)
Target: x86_64-pc-windows-gnu
OS: NixOS / Linux
cargo and rustc via rustup

Metadata

Metadata

Assignees

No one assigned

    Labels

    -Zbuild-stdUnstable cargo option: -Zbuild-stdA-crossArea: Cross compilationC-bugCategory: This is a bug.O-NixOSOperating system: NixOS, https://nixos.org/O-windows-gnuToolchain: GNU, Operating system: Windows

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions