diff --git a/crane.nix b/crane.nix index b20f9c6..cc6c625 100644 --- a/crane.nix +++ b/crane.nix @@ -52,7 +52,10 @@ let }; }; }; - systems = lib.filter (s: s == system || lib.hasInfix "linux" s) supportedSystems; + systems = lib.filter (s: s == system || lib.hasInfix "linux" s) supportedSystems + # Cross from aarch64-darwin -> x86_64-darwin doesn't work yet + # Hopefully the situation will improve with the SDK bumps + ++ lib.optional (system == "x86_64-darwin") "aarch64-darwin"; in builtins.listToAttrs (map makeCrossPlatform systems); cargoTargets = lib.mapAttrsToList (_: p: p.rustTargetSpec) crossPlatforms; diff --git a/flake.nix b/flake.nix index acd68ed..c6261c8 100644 --- a/flake.nix +++ b/flake.nix @@ -57,6 +57,82 @@ age ]; + + # We _can_ cross-compile to multiple systems with one shell :) + # + # Currently stdenv isn't set up to do that, but we can invoke + # the setup mechinary in a sub-shell then compose the results. + shellHook = let + crossSystems = lib.filter (s: s != pkgs.system) (builtins.attrNames cranePkgs.crossPlatforms); + in '' + # Returns compiler environment variables for a platform + # + # getTargetFlags "suffixSalt" "nativeBuildInputs" "buildInputs" + getTargetFlags() { + # Here we only call the setup-hooks of nativeBuildInputs. + # + # What's off-limits for us: + # + # - findInputs + # - activatePackage + # - Other functions in stdenv setup that depend on the private accumulator variables + ( + suffixSalt="$1" + nativeBuildInputs="$2" + buildInputs="$3" + + # Offsets for the nativeBuildInput (e.g., gcc) + hostOffset=-1 + targetOffset=0 + + # In stdenv, the hooks are first accumulated before being called. + # Here we call them immediately + addEnvHooks() { + local depHostOffset="$1" + # For simplicity, we only call the hook on buildInputs + for pkg in $buildInputs; do + depTargetOffset=1 + $2 $pkg + done + } + + unset _PATH + unset NIX_CFLAGS_COMPILE + unset NIX_LDFLAGS + + # For simplicity, we only call the setup-hooks of nativeBuildInputs + for nbi in $nativeBuildInputs; do + addToSearchPath _PATH "$nbi/bin" + + if [ -e "$nbi/nix-support/setup-hook" ]; then + source "$nbi/nix-support/setup-hook" + fi + done + + echo "export NIX_CFLAGS_COMPILE_''${suffixSalt}='$NIX_CFLAGS_COMPILE'" + echo "export NIX_LDFLAGS_''${suffixSalt}='$NIX_LDFLAGS'" + echo "export PATH=$PATH''${_PATH+:$_PATH}" + ) + } + + target_flags=$(mktemp) + ${lib.concatMapStrings (system: let + crossPlatform = cranePkgs.crossPlatforms.${system}; + in '' + getTargetFlags \ + "${crossPlatform.cc.suffixSalt}" \ + "${crossPlatform.cc} ${crossPlatform.cc.bintools}" \ + "${builtins.concatStringsSep " " (crossPlatform.buildInputs ++ crossPlatform.pkgs.stdenv.defaultBuildInputs)}" >$target_flags + . $target_flags + '') crossSystems} + rm $target_flags + + # Suffix flags for current system as well + export NIX_CFLAGS_COMPILE_${pkgs.stdenv.cc.suffixSalt}="$NIX_CFLAGS_COMPILE" + export NIX_LDFLAGS_${pkgs.stdenv.cc.suffixSalt}="$NIX_LDFLAGS" + unset NIX_CFLAGS_COMPILE + unset NIX_LDFLAGS + ''; } // cranePkgs.cargoCrossEnvs); keygen = pkgs.mkShellNoCC { packages = with pkgs; [