Unverified Commit 9396352f authored by Philip Taron's avatar Philip Taron Committed by GitHub
Browse files

lib/systems: elaborate properly with non-matching system / config / parsed args (#351608)

parents 3b56519f 3c21a5c9
Loading
Loading
Loading
Loading
+17 −6
Original line number Diff line number Diff line
@@ -6,9 +6,9 @@ let
    filterAttrs
    foldl
    hasInfix
    isAttrs
    isFunction
    isList
    isString
    mapAttrs
    optional
    optionalAttrs
@@ -55,24 +55,34 @@ let
  */
  flakeExposed = import ./flake-systems.nix { };

  # Turn localSystem or crossSystem, which could be system-string or attrset, into
  # attrset.
  systemToAttrs = systemOrArgs:
    if isAttrs systemOrArgs then systemOrArgs else { system = systemOrArgs; };

  # Elaborate a `localSystem` or `crossSystem` so that it contains everything
  # necessary.
  #
  # `parsed` is inferred from args, both because there are two options with one
  # clearly preferred, and to prevent cycles. A simpler fixed point where the RHS
  # always just used `final.*` would fail on both counts.
  elaborate = args': let
    args = if isString args' then { system = args'; }
           else args';
  elaborate = systemOrArgs: let
    allArgs = systemToAttrs systemOrArgs;

    # Those two will always be derived from "config", if given, so they should NOT
    # be overridden further down with "// args".
    args = builtins.removeAttrs allArgs [ "parsed" "system" ];

    # TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL.
    rust = args.rust or args.rustc or {};

    final = {
      # Prefer to parse `config` as it is strictly more informative.
      parsed = parse.mkSystemFromString (if args ? config then args.config else args.system);
      # Either of these can be losslessly-extracted from `parsed` iff parsing succeeds.
      parsed = parse.mkSystemFromString (args.config or allArgs.system);
      # This can be losslessly-extracted from `parsed` iff parsing succeeds.
      system = parse.doubleFromSystem final.parsed;
      # TODO: This currently can't be losslessly-extracted from `parsed`, for example
      # because of -mingw32.
      config = parse.tripleFromSystem final.parsed;
      # Determine whether we can execute binaries built for the provided platform.
      canExecute = platform:
@@ -435,5 +445,6 @@ in
    inspect
    parse
    platforms
    systemToAttrs
    ;
}
+12 −0
Original line number Diff line number Diff line
@@ -78,6 +78,18 @@ lib.runTests (
    expr = toLosslessStringMaybe (lib.systems.elaborate "x86_64-linux" // { something = "extra"; });
    expected = null;
  };
  test_elaborate_config_over_system = {
    expr = (lib.systems.elaborate { config = "i686-unknown-linux-gnu"; system = "x86_64-linux"; }).system;
    expected = "i686-linux";
  };
  test_elaborate_config_over_parsed = {
    expr = (lib.systems.elaborate { config = "i686-unknown-linux-gnu"; parsed = (lib.systems.elaborate "x86_64-linux").parsed; }).parsed.cpu.arch;
    expected = "i686";
  };
  test_elaborate_system_over_parsed = {
    expr = (lib.systems.elaborate { system = "i686-linux"; parsed = (lib.systems.elaborate "x86_64-linux").parsed; }).parsed.cpu.arch;
    expected = "i686";
  };
}

# Generate test cases to assert that a change in any non-function attribute makes a platform unequal
+8 −7
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ let
      })] ++ overlays;
      ${if stdenv.hostPlatform == stdenv.buildPlatform
        then "localSystem" else "crossSystem"} = {
        parsed = makeMuslParsedPlatform stdenv.hostPlatform.parsed;
        config = lib.systems.parse.tripleFromSystem (makeMuslParsedPlatform stdenv.hostPlatform.parsed);
      };
    } else throw "Musl libc only supports 64-bit Linux systems.";

@@ -258,9 +258,9 @@ let
      })] ++ overlays;
      ${if stdenv.hostPlatform == stdenv.buildPlatform
        then "localSystem" else "crossSystem"} = {
        parsed = stdenv.hostPlatform.parsed // {
        config = lib.systems.parse.tripleFromSystem (stdenv.hostPlatform.parsed // {
          cpu = lib.systems.parse.cpuTypes.i686;
        };
        });
      };
    } else throw "i686 Linux package set can only be used with the x86 family.";

@@ -270,9 +270,9 @@ let
        pkgsx86_64Darwin = super';
      })] ++ overlays;
      localSystem = {
        parsed = stdenv.hostPlatform.parsed // {
        config = lib.systems.parse.tripleFromSystem (stdenv.hostPlatform.parsed // {
          cpu = lib.systems.parse.cpuTypes.x86_64;
        };
        });
      };
    } else throw "x86_64 Darwin package set can only be used on Darwin systems.";

@@ -311,10 +311,11 @@ let
      })] ++ overlays;
      crossSystem = {
        isStatic = true;
        parsed =
        config = lib.systems.parse.tripleFromSystem (
          if stdenv.hostPlatform.isLinux
          then makeMuslParsedPlatform stdenv.hostPlatform.parsed
          else stdenv.hostPlatform.parsed;
          else stdenv.hostPlatform.parsed
        );
        gcc = lib.optionalAttrs (stdenv.hostPlatform.system == "powerpc64-linux") { abi = "elfv2"; } //
          stdenv.hostPlatform.gcc or {};
      };