nixpkgs/pkgs/stdenv/cross/default.nix
Artturin b9e5637ade config.replaceCrossStdenv: add
Example with `clangUseLLVM` which is the default when using `useLLVM`

```nix
config.replaceCrossStdenv = { buildPackages, baseStdenv }:
  if baseStdenv.targetPlatform.useLLVM or false
  then (buildPackages.stdenvAdapters.overrideCC baseStdenv buildPackages.llvmPackages_16.clangUseLLVM)
  else baseStdenv;
```

The conditional necessary, otherwise the other sets(such as `pkgsCross.aarch64-multiplatform.llvmPackages`)
without `useLLVM` will use the stdenv without the necessary conditions to avoid infinite
recursion because of [targetLlvmLibraries](644b234e1c/pkgs/development/compilers/llvm/16/default.nix (L208))
usage.

[`replaceStdenv` is not used when cross-compiling](d77bda728d/pkgs/stdenv/cross/default.nix (L12-L13))

`replaceStdenv` uses an additional stage to replace the stdenv to avoid
infinite recursion and other issues but that should not be necessary for cross.
2024-01-27 19:54:11 +02:00

93 lines
3.4 KiB
Nix

{ lib
, localSystem, crossSystem, config, overlays, crossOverlays ? []
}:
let
bootStages = import ../. {
inherit lib localSystem overlays;
crossSystem = localSystem;
crossOverlays = [];
# Ignore custom stdenvs when cross compiling for compatibility
# Use replaceCrossStdenv instead.
config = builtins.removeAttrs config [ "replaceStdenv" ];
};
in lib.init bootStages ++ [
# Regular native packages
(somePrevStage: lib.last bootStages somePrevStage // {
# It's OK to change the built-time dependencies
allowCustomOverrides = true;
})
# Build tool Packages
(vanillaPackages: {
inherit config overlays;
selfBuild = false;
stdenv =
assert vanillaPackages.stdenv.buildPlatform == localSystem;
assert vanillaPackages.stdenv.hostPlatform == localSystem;
assert vanillaPackages.stdenv.targetPlatform == localSystem;
vanillaPackages.stdenv.override { targetPlatform = crossSystem; };
# It's OK to change the built-time dependencies
allowCustomOverrides = true;
})
# Run Packages
(buildPackages: let
adaptStdenv =
if crossSystem.isStatic
then buildPackages.stdenvAdapters.makeStatic
else lib.id;
in {
inherit config;
overlays = overlays ++ crossOverlays;
selfBuild = false;
stdenv = let
baseStdenv = adaptStdenv (buildPackages.stdenv.override (old: rec {
buildPlatform = localSystem;
hostPlatform = crossSystem;
targetPlatform = crossSystem;
# Prior overrides are surely not valid as packages built with this run on
# a different platform, and so are disabled.
overrides = _: _: {};
extraBuildInputs = [ ] # Old ones run on wrong platform
++ lib.optionals hostPlatform.isDarwin [ buildPackages.targetPackages.darwin.apple_sdk.frameworks.CoreFoundation ]
;
allowedRequisites = null;
hasCC = !targetPlatform.isGhcjs;
cc = if crossSystem.useiOSPrebuilt or false
then buildPackages.darwin.iosSdkPkgs.clang
else if crossSystem.useAndroidPrebuilt or false
then buildPackages."androidndkPkgs_${crossSystem.ndkVer}".clang
else if targetPlatform.isGhcjs
# Need to use `throw` so tryEval for splicing works, ugh. Using
# `null` or skipping the attribute would cause an eval failure
# `tryEval` wouldn't catch, wrecking accessing previous stages
# when there is a C compiler and everything should be fine.
then throw "no C compiler provided for this platform"
else if crossSystem.isDarwin
then buildPackages.llvmPackages.libcxxClang
else if crossSystem.useLLVM or false
then buildPackages.llvmPackages.clang
else buildPackages.gcc;
extraNativeBuildInputs = old.extraNativeBuildInputs
++ lib.optionals
(hostPlatform.isLinux && !buildPlatform.isLinux)
[ buildPackages.patchelf ]
++ lib.optional
(let f = p: !p.isx86 || builtins.elem p.libc [ "musl" "wasilibc" "relibc" ] || p.isiOS || p.isGenode;
in f hostPlatform && !(f buildPlatform) )
buildPackages.updateAutotoolsGnuConfigScriptsHook
;
}));
in if config ? replaceCrossStdenv then config.replaceCrossStdenv { inherit buildPackages baseStdenv; } else baseStdenv;
})
]