I’ve been playing around with cross compiling rust from my m1 mac to an x86_64-linux machine running Arch. I got things working ( ) but then refactored the logic a bit and am now getting
error: value is a function while a Boolean was expected
for unclear reasons; if I don’t explicitly pass a value, the makeStatic
boolean that I’m passing in is a lambda
whenever I builtins.trace
it.
# flake.nix
{
description = "Example of cross-compiling Rust on aarch64-darwin for x86_64-linux";
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
};
outputs = {
self,
nixpkgs,
rust-overlay,
}: let
system = "aarch64-darwin";
overlays = [(import rust-overlay)];
pkgs = import nixpkgs {
inherit overlays system;
crossSystem = {
config = "x86_64-unknown-linux-gnu";
rustc.config = "x86_64-unknown-linux-gnu";
};
};
in {
packages.${system} = {
default = self.outputs.packages.${system}.x86_64-linux;
x86_64-linux = pkgs.callPackage ./. {};
x86_64-linux-static = pkgs.callPackage ./. {makeStatic = true;};
};
};
}
# default.nix
{
rustPlatform,
glibc,
makeStatic ? false,
}:
rustPlatform.buildRustPackage ({
name = "rust-cross-test";
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
CARGO_BUILD_TARGET = "x86_64-unknown-linux-gnu";
}
// (
if makeStatic
then {
buildInputs = [glibc.static];
RUSTFLAGS = ["-C" "target-feature=+crt-static"];
}
else {
postBuild = ''
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 target/x86_64-unknown-linux-gnu/release/linux-cross-example
'';
}
))
$ nix build --show-trace
error:
… while evaluating the attribute 'outputs.packages.aarch64-darwin.x86_64-linux'
at /nix/store/vf03xql3nkz3am5f6rpdi0j3w7i8x3fi-source/flake.nix:27:7:
26| # x86_64-linux = pkgs.callPackage ./. {makeStatic = false;};
27| x86_64-linux = pkgs.callPackage ./. {};
| ^
28| x86_64-linux-static = pkgs.callPackage ./. {makeStatic = true;};
… while evaluating call site
at /nix/store/vf03xql3nkz3am5f6rpdi0j3w7i8x3fi-source/flake.nix:27:22:
26| # x86_64-linux = pkgs.callPackage ./. {makeStatic = false;};
27| x86_64-linux = pkgs.callPackage ./. {};
| ^
28| x86_64-linux-static = pkgs.callPackage ./. {makeStatic = true;};
… while calling 'callPackageWith'
at /nix/store/jfji1id0l3xxy8mgph757dwyngsjaamr-source/lib/customisation.nix:122:35:
121| */
122| callPackageWith = autoArgs: fn: args:
| ^
123| let
… while evaluating call site
at /nix/store/jfji1id0l3xxy8mgph757dwyngsjaamr-source/lib/customisation.nix:173:34:
172|
173| in if missingArgs == [] then makeOverridable f allArgs else abort error;
| ^
174|
… while calling 'makeOverridable'
at /nix/store/jfji1id0l3xxy8mgph757dwyngsjaamr-source/lib/customisation.nix:72:24:
71| */
72| makeOverridable = f: origArgs:
| ^
73| let
… while evaluating call site
at /nix/store/jfji1id0l3xxy8mgph757dwyngsjaamr-source/lib/customisation.nix:74:16:
73| let
74| result = f origArgs;
| ^
75|
… while calling anonymous lambda
at /nix/store/vf03xql3nkz3am5f6rpdi0j3w7i8x3fi-source/default.nix:1:1:
1| {
| ^
2| rustPlatform,
error: value is a function while a Boolean was expected
at /nix/store/vf03xql3nkz3am5f6rpdi0j3w7i8x3fi-source/default.nix:13:5:
12| // (
13| if makeStatic
| ^
14| then {
However, this works fine, but seems essentially identical:
# flake.nix
{
outputs = {
self,
nixpkgs,
}: let
system = "aarch64-darwin";
pkgs = import nixpkgs {inherit system;};
in {
packages.${system} = {
default = self.outputs.packages.${system}.first;
first = pkgs.callPackage ./. {foo = true;};
second = pkgs.callPackage ./. {};
};
};
}
# default.nix
{
pkgs,
foo ? false,
}:
pkgs.stdenv.mkDerivation ({
name = "test";
dontUnpack = true;
patchPhase = ''
echo yup >> $out
'';
}
// (
if foo
then {
installPhase = ''echo "foo was true!" >> $out'';
}
else {
installPhase = ''echo "foo was false!" >> $out'';
}
))
$ nix build .#first && cat result
yup
foo was true!
$ nix build .#second && cat result
yup
foo was false!
What gives? What makes the second build fine but the first fail?