nix-community / crate2nix

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

Cross-compiling requires `NIXPKGS_ALLOW_BROKEN=1` to be set #358

Closed drakon64 closed 3 months ago

drakon64 commented 3 months ago

I'm trying to cross-compile a crate to x86_64-unknown-linux-musl. My package is defined as follows:

{
  pkgs,
  crate2nix,
  src,
  dev ? false,
  ...
}:
let
  crateTools = pkgs.callPackage "${crate2nix}/tools.nix" { };

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

  buildRustCrate = pkgs.buildRustCrate.override {
    rust = rustToolchain;
    cargo = rustToolchain;

    release = if dev then false else true;
  };

  cargoNix = pkgs.callPackage (crateTools.generatedCargoNix {
    name = "package";
    inherit src;
  }) { inherit buildRustCrate; };
in
cargoNix.rootCrate.build

This won't work because the cargo package is broken. If I run export NIXPKGS_ALLOW_BROKEN=1 and rerun nix build with --impure Cargo will eventually fail to build because the readelf command cannot be found.

pkgs is simply defined in a Flake as:

import nixpkgs {
  inherit system;

  overlays = [ (import rust-overlay) ];

  crossSystem = {
    config = "x86_64-unknown-linux-musl";
  };
};

When using a similar setup with Crane, Nix would seemingly not attempt to compile cargo from source and use the native Rust compiler with the cross-target enabled.

This is with crate2nix 0.14.1 and master.

drakon64 commented 3 months ago

Using a derivation similar to the one described in the documentation:

{
  pkgs,
  crate2nix,
  system,
  src,
  ...
}:
let
  cargoNix = crate2nix.tools.${system}.appliedCargoNix {
    name = "package";
    inherit src;
  };
in
cargoNix.rootCrate.build

causes crate2nix to disregard the value of pkgs.crossSystem. I've also been unable to work out how to pass buildRustCrate to the build this way.

drakon64 commented 3 months ago
{
  pkgs,
  crate2nix,
  system,
  src,
  ...
}:
let
  generatedCargoNix = crate2nix.tools.${system}.generatedCargoNix {
    name = "package";
    inherit src;
  };

  cargoNix = pkgs.callPackage generatedCargoNix { };
in
cargoNix.rootCrate.build

seemingly works. I still need to work out how to use rust-overlay instead of Rust from Nixpkgs (the examples at https://github.com/NixOS/nixpkgs/blob/fb3d86ee0d57c8cdfc363e2108c37af3887f01b4/doc/languages-frameworks/rust.section.md#options-and-phases-configuration-options-and-phases-configuration don't make sense to me) and how to get crate2nix to use static LibreSSL instead of dynamic OpenSSL, but for now this is good enough.