nix-community / crate2nix

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

Build fails when using `rust-overlay` due to some dependencies being built with Nixpkgs Rust when cross-compiling #359

Open drakon64 opened 3 weeks ago

drakon64 commented 3 weeks ago

I have a simple derivation using crate2nix:

{
  pkgs,
  crate2nix,
  system,
  src,
  ...
}:
let
  rustToolchain = pkgs.rust-bin.stable."1.80.1".default;

  buildRustCrateForPkgs =
    pkgs:
    pkgs.buildRustCrate.override {
      rustc = rustToolchain;
      cargo = rustToolchain;
    };

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

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

When I try to build this, I get this error:

error[E0514]: found crate `derive_builder_macro` compiled by an incompatible version of rustc
   --> src/lib.rs:718:1
    |
718 | extern crate derive_builder_macro;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the following crate versions were found:
            crate `derive_builder_macro` compiled by rustc 1.80.1 (3f5fd8dd4 2024-08-06) (built from a source tarball): /nix/store/ay24n13hpxymp9wvrw08a0qh5fwzkhlx-rust_derive_bui>
    = help: please recompile that crate using this compiler (rustc 1.80.1 (3f5fd8dd4 2024-08-06)) (consider running `cargo clean` first)

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0514`.

If I downgrade the Rust overlay to 1.80.0, I get the same error but with 'this' compiler correctly appearing as 1.80.0.

It seems like crate2nix is still building some of the dependencies with the Nixpkgs version of Rust.

In my Flake, pkgs is defined as follows:

pkgs = import nixpkgs {
  inherit system;

  overlays = [ (import rust-overlay) ];

  crossSystem = {
    config = "x86_64-unknown-linux-musl";
  };
};
drakon64 commented 3 weeks ago

I cannot reproduce this when commenting out crossSystem.config, or changing it to x86_64-unknown-linux-gnu

drakon64 commented 3 weeks ago

I was able to reproduce this when setting crossSystem.config to aarch64-unknown-linux-gnu, so it seems that this bug only affects cross-compilation

drakon64 commented 3 weeks ago

I decided to see what would happen if I ran a build with Rust 1.80.1 and then 1.80.0. It seems that crate2nix only ever rebuilds the main crate and leaves all dependencies unchanged, so it looks like setting the overlay with buildRustCrateForPkgs doesn't work as expected anyway (unless the crates don't need a rebuild? Surely their inputs have changed which should trigger a rebuild).

Removing buildRustCrateForPkgs also allows me to cross-compile to x86_64-unknown-linux-musl without errors.

apoelstra commented 3 weeks ago

Rather than overriding

      rustc = rustToolchain;
      cargo = rustToolchain;

what if you tried just

    rust = rustToolchain;

This is what I have in my setup which seems to work. I am also using callPackage to call the generatedCargoNix, though I don't think that matters here.

drakon64 commented 3 weeks ago

Rather than overriding

      rustc = rustToolchain;
      cargo = rustToolchain;

what if you tried just

    rust = rustToolchain;

This is what I have in my setup which seems to work. I am also using callPackage to call the generatedCargoNix, though I don't think that matters here.

error:
       … while calling the 'derivationStrict' builtin

         at /builtin/derivation.nix:9:12: (source not available)

       … while evaluating derivation 'package-x86_64-unknown-linux-musl-0.2.0'
         whose name attribute is located at /nix/store/d87mpjlsl8flcgazpjnhimq21y46a3g4-source/pkgs/stdenv/generic/make-derivation.nix:336:7

       … while evaluating attribute 'installPhase' of derivation 'package-x86_64-unknown-linux-musl-0.2.0'

         at /nix/store/55b4fg2hir08g0vvamgxi8sg2jvdgq8s-source/nix/package.nix:28:3:

           27|   # Nix will build these packages if they aren't already in the store, or if their inputs have been modified
           28|   installPhase = ''
             |   ^
           29|     mkdir -p $out/frontend $out/mock

       error: function 'anonymous lambda' called with unexpected argument 'rust'

       at /nix/store/d87mpjlsl8flcgazpjnhimq21y46a3g4-source/pkgs/build-support/rust/build-rust-crate/default.nix:7:1:

            6|
            7| { lib
             | ^
            8| , stdenv
       Did you mean rustc?

Same result with import generatedCargoNix and callPackage generatedCargoNix.

apoelstra commented 3 weeks ago

What if you remove the inherit pkgs (I am just guessing things now)

drakon64 commented 3 weeks ago

What if you remove the inherit pkgs (I am just guessing things now)

error:
       … while calling the 'derivationStrict' builtin

         at /builtin/derivation.nix:9:12: (source not available)

       … while evaluating derivation 'package-x86_64-unknown-linux-musl-0.2.0'
         whose name attribute is located at /nix/store/d87mpjlsl8flcgazpjnhimq21y46a3g4-source/pkgs/stdenv/generic/make-derivation.nix:336:7

       … while evaluating attribute 'installPhase' of derivation 'package-x86_64-unknown-linux-musl-0.2.0'

         at /nix/store/kc1zr5vr1ccxdkxrg9nfwgc88rrhmman-source/nix/package.nix:28:3:

           27|   # Nix will build these packages if they aren't already in the store, or if their inputs have been modified
           28|   installPhase = ''
             |   ^
           29|     mkdir -p $out/frontend $out/mock

       error: cannot look up '<nixpkgs>' in pure evaluation mode (use '--impure' to override)

       at «none»:0: (source not available)
drakon64 commented 3 weeks ago

If I build with --impure I get a different error:

error: builder for '/nix/store/i7rrp94pmayls2mqn46ml9bz7x3k6ks7-rust_pin-project-1.1.5.drv' failed with exit code 1;
       last 10 log lines:
       >
       > error[E0463]: can't find crate for `pin_project_internal`
       >    --> src/lib.rs:197:13
       >     |
       > 197 |     pub use pin_project_internal::__PinProjectInternalDerive;
       >     |             ^^^^^^^^^^^^^^^^^^^^ can't find crate
       >
       > error: aborting due to 3 previous errors
       >
       > For more information about this error, try `rustc --explain E0463`.
       For full logs, run 'nix log /nix/store/i7rrp94pmayls2mqn46ml9bz7x3k6ks7-rust_pin-project-1.1.5.drv'.
apoelstra commented 3 weeks ago

Ah, you are using flakes. I don't know much about flakes.

But I have my nixpkgs pinned to 4f3a074422623781034daf8b1a966ee556587539 right now. Maybe you could try that one and see if it "used to work"?

drakon64 commented 3 weeks ago

Ah, you are using flakes. I don't know much about flakes.

But I have my nixpkgs pinned to 4f3a074422623781034daf8b1a966ee556587539 right now. Maybe you could try that one and see if it "used to work"?

error:
       … while calling the 'derivationStrict' builtin

         at /builtin/derivation.nix:9:12: (source not available)

       … while evaluating derivation 'package-x86_64-unknown-linux-musl-0.2.0'
         whose name attribute is located at /nix/store/jd9avbycb0k0jaz8k98lzf8dp7ssxyb1-source/pkgs/stdenv/generic/make-derivation.nix:300:7

       … while evaluating attribute 'installPhase' of derivation 'package-x86_64-unknown-linux-musl-0.2.0'

         at /nix/store/id2n4imbpbvak9vr613xzmlfagw5y102-source/nix/package.nix:28:3:

           27|   # Nix will build these packages if they aren't already in the store, or if their inputs have been modified
           28|   installPhase = ''
             |   ^
           29|     mkdir -p $out/frontend $out/mock

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: attribute 'rust' missing

       at /nix/store/q0b3r882zr7ip8241fcsgv44g8062glv-source/crate2nix/Cargo.nix:3158:14:

         3157|
         3158|     inherit (platform.rust.platform)
             |              ^
         3159|       arch
       Did you mean rustc?
drakon64 commented 3 weeks ago

Based on https://github.com/nix-community/crate2nix/issues/348#issuecomment-2090350760 the issue might be caused by crate2nix itself running with the Nixpkgs Rust version. Is there a way to tell crate2nix to use the Rust toolchain from rust-overlay?

apoelstra commented 3 weeks ago

I'm mystified. You can see my code here: https://github.com/apoelstra/local-nix-ci/blob/main/andrew-utils.nix#L520-L532

and the README on the rust-overlay repo says that you should be able to override rust (not rustc or cargo) like this.

drakon64 commented 3 weeks ago

The rust override doesn't exist in nixpkgs-unstable.

https://github.com/NixOS/nixpkgs/blob/ae815cee91b417be55d43781eb4b73ae1ecc396c/pkgs/build-support/rust/build-rust-crate/default.nix#L7-L16

drakon64 commented 3 weeks ago

I don't know why, but this worked:

rustToolchain = pkgs.rust-bin.stable."1.80.1".default;

buildRustCrateForPkgs =
  crate:
  pkgs.buildRustCrate.override {
    rustc = rustToolchain;
    cargo = rustToolchain;
  };

Worked insofar as the build now fails because the linker can't find OpenSSL. I'll have to see what I did in Crane to fix that but I fear that I'll just get hit by https://github.com/nix-community/crate2nix/pull/266.

drakon64 commented 3 weeks ago

I'm going to leave this open since I'll raise a PR to have the process for correctly applying rust-overlay documented.

Also, didn't get hit by https://github.com/nix-community/crate2nix/pull/266, telling crate2nix to use static LibreSSL seems to work fine. I'll probably PR documentation for this too.

drakon64 commented 3 weeks ago

The rust override doesn't exist in nixpkgs-unstable.

https://github.com/NixOS/nixpkgs/blob/ae815cee91b417be55d43781eb4b73ae1ecc396c/pkgs/build-support/rust/build-rust-crate/default.nix#L7-L16

Probably worth mentioning that it did previously exist per https://github.com/NixOS/nixpkgs/blob/4f3a074422623781034daf8b1a966ee556587539/pkgs/build-support/rust/build-rust-crate/default.nix#L7-L17