nix-community / crate2nix

rebuild only changed crates in CI with crate2nix and nix
https://nix-community.github.io/crate2nix/
Apache License 2.0
385 stars 89 forks source link

`--target` and `-C linker` aren't passed to some crates when cross-compiling #362

Open drakon64 opened 2 months ago

drakon64 commented 2 months ago

I am trying to compile a Rust project to x86_64-unknown-linux-musl from a x86_64-unknown-linux-gnu host (NixOS 24.05).

pkgs is defined as follows:

pkgs = nixpkgs.legacyPackages.x86_64-linux;

I call the Rust derivation:

crossSystem = "musl64";
pkgsCross = pkgs.pkgsCross.${crossSystem};

cratePackage = pkgsCross.callPackage ./nix/rust.nix {
  inherit crate2nix rust-overlay;
  rustupToolchainFile = ./rust-toolchain.toml;
  src = ./.;
};

Where ./nix/rust.nix is:

{
  lib,
  system,
  rust-overlay,
  buildPackages,
  buildRustCrate,
  callPackage,
  crate2nix,
  rustupToolchainFile,
  src,
  ...
}:

let
  buildRustCrateForPkgs =
    let
      rustToolchain =
        (rust-overlay.lib.mkRustBin { } buildPackages).fromRustupToolchainFile
          rustupToolchainFile;
    in
    crate:
    buildRustCrate.override {
      rustc = rustToolchain;
      cargo = rustToolchain;
    };

  generatedCargoNix = crate2nix.tools.${system}.generatedCargoNix {
    inherit src;

    name = "package";
  };

  cargoNix = callPackage generatedCargoNix {
    inherit buildRustCrateForPkgs;
  };
in
cargoNix.rootCrate.build

and ./rust-toolchain.toml is:

[toolchain]
channel = "1.81.0"
profile = "minimal"

While some crates build fine, eventually the build will fail because an x86_64-unknown-linux-gnu autocfg cannot be found despite the build targeting x86_64-unknown-linux-musl. The Rust compiler even acknowledges that a x86_64-unknown-linux-musl build exists. I can also replicate this issue when targeting aarch64-unknown-linux-musl and aarch64-unknown-linux-gnu.

drakon64 commented 1 month ago

It looks like the --target x86_64-unknown-linux-musl flag isn't being passed to rustc

drakon64 commented 1 month ago

autocfg is being built with --target x86_64-unknown-linux-musl and -C linker correctly set:

rustc --crate-name autocfg src/lib.rs --out-dir target/lib -L dependency=target/deps --cap-lints allow -C opt-level=3 -C codegen-units=1 --remap-path-prefix=/build=/ --cfg feature="default" --target x86_64-unknown-linux-musl --edition 2015 -C linker=/nix/store/32p3r91f5xnd87zwz8ifyn0jp3a3vl5h-x86_64-unknown-linux-musl-gcc-wrapper-13.3.0/bin/x86_64-unknown-linux-musl-cc -C metadata=1ecf74a98c -C extra-filename=-1ecf74a98c --crate-type lib --color always

num-traits, which depends on autocfg, is not:

rustc --crate-name build_script_build build.rs --crate-type bin -C opt-level=3 -C codegen-units=1 --edition 2021 --cfg feature="i128" --cfg feature="std" --out-dir target/build/num-traits --emit=dep-info,link -L dependency=target/buildDeps --extern autocfg=/nix/store/4x0mlmcwg8140lf748vm9p90rfwlw7ss-rust_autocfg-1.3.0-x86_64-unknown-linux-musl-lib/lib/libautocfg-1ecf74a98c.rlib --cap-lints allow --color always
drakon64 commented 1 month ago

Almost exactly the same error as https://github.com/nix-community/crate2nix/issues/132#issuecomment-699683437