about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2023-11-17 20:16:22 +0100
committergithub-actions[bot] <github-actions[bot]@users.noreply.github.com>2023-11-24 11:22:00 +0000
commit50152ef89e875886c19ec3f0a22920aa292ec6ae (patch)
tree3cdab579ff93a30ab9efe6770bf3f4168051bf2f /lib
parentffcadd021d929dd87dcc3a3fc39098e13cbc8f60 (diff)
lib.systems.elaborate: fix passing `rust`
Usually, attributes passed explicitly to elaborate take precedence
over the elaborated ones, but since we also elaborate the nested
"rust" attrset, we need to push that one level down, so the rest of
"rust" is still filled in if you just pass
{ rust = { config = ... } }.

I've had to drop the assertion that checked that at most one of "rust"
and "rustc" was part of the un-elaborated system, because doing this
broke passing an elaborated system in, which should be idempotent.

For the same reason, I've also had to make it possible for
rust.rustcTargetSpec to be passed in.  Otherwise, on the second call,
since platform was filled in by the first, the custom target file
would be constructed.  The only other way to avoid this would be to
compare the platform attrs to all built in Rust targets to check it
wasn't one of those, and that isn't feasible.

Fixes: e3e57b8f1885 ("lib.systems: elaborate Rust metadata")
(cherry picked from commit 886c89287f6a35adb6eb9230a3a0cccf682d0f88)
Diffstat (limited to 'lib')
-rw-r--r--lib/systems/default.nix184
1 files changed, 92 insertions, 92 deletions
diff --git a/lib/systems/default.nix b/lib/systems/default.nix
index ada8c66e3618b..0d21175914a3d 100644
--- a/lib/systems/default.nix
+++ b/lib/systems/default.nix
@@ -45,7 +45,7 @@ rec {
            else args';
 
     # TODO: deprecate args.rustc in favour of args.rust after 23.05 is EOL.
-    rust = assert !(args ? rust && args ? rustc); args.rust or args.rustc or {};
+    rust = args.rust or args.rustc or {};
 
     final = {
       # Prefer to parse `config` as it is strictly more informative.
@@ -169,96 +169,6 @@ rec {
       # TODO: remove after 23.05 is EOL, with an error pointing to the rust.* attrs.
       rustc = args.rustc or {};
 
-      rust = rust // {
-        # Once args.rustc.platform.target-family is deprecated and
-        # removed, there will no longer be any need to modify any
-        # values from args.rust.platform, so we can drop all the
-        # "args ? rust" etc. checks, and merge args.rust.platform in
-        # /after/.
-        platform = rust.platform or {} // {
-          # https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch
-          arch =
-            /**/ if rust ? platform then rust.platform.arch
-            else if final.isAarch32 then "arm"
-            else if final.isMips64  then "mips64"     # never add "el" suffix
-            else if final.isPower64 then "powerpc64"  # never add "le" suffix
-            else final.parsed.cpu.name;
-
-          # https://doc.rust-lang.org/reference/conditional-compilation.html#target_os
-          os =
-            /**/ if rust ? platform then rust.platform.os or "none"
-            else if final.isDarwin then "macos"
-            else final.parsed.kernel.name;
-
-          # https://doc.rust-lang.org/reference/conditional-compilation.html#target_family
-          target-family =
-            /**/ if args ? rust.platform.target-family then args.rust.platform.target-family
-            else if args ? rustc.platform.target-family
-            then
-              (
-                # Since https://github.com/rust-lang/rust/pull/84072
-                # `target-family` is a list instead of single value.
-                let
-                  f = args.rustc.platform.target-family;
-                in
-                  if builtins.isList f then f else [ f ]
-              )
-            else lib.optional final.isUnix "unix"
-                 ++ lib.optional final.isWindows "windows";
-
-          # https://doc.rust-lang.org/reference/conditional-compilation.html#target_vendor
-          vendor = let
-            inherit (final.parsed) vendor;
-          in rust.platform.vendor or {
-            "w64" = "pc";
-          }.${vendor.name} or vendor.name;
-        };
-
-        # The name of the rust target, even if it is custom. Adjustments are
-        # because rust has slightly different naming conventions than we do.
-        rustcTarget = let
-          inherit (final.parsed) cpu kernel abi;
-          cpu_ = rust.platform.arch or {
-            "armv7a" = "armv7";
-            "armv7l" = "armv7";
-            "armv6l" = "arm";
-            "armv5tel" = "armv5te";
-            "riscv64" = "riscv64gc";
-          }.${cpu.name} or cpu.name;
-          vendor_ = final.rust.platform.vendor;
-        in rust.config
-          or "${cpu_}-${vendor_}-${kernel.name}${lib.optionalString (abi.name != "unknown") "-${abi.name}"}";
-
-        # The name of the rust target if it is standard, or the json file
-        # containing the custom target spec.
-        rustcTargetSpec =
-          /**/ if rust ? platform
-          then builtins.toFile (final.rust.rustcTarget + ".json") (builtins.toJSON rust.platform)
-          else final.rust.rustcTarget;
-
-        # The name of the rust target if it is standard, or the
-        # basename of the file containing the custom target spec,
-        # without the .json extension.
-        #
-        # This is the name used by Cargo for target subdirectories.
-        cargoShortTarget =
-          lib.removeSuffix ".json" (baseNameOf "${final.rust.rustcTargetSpec}");
-
-        # When used as part of an environment variable name, triples are
-        # uppercased and have all hyphens replaced by underscores:
-        #
-        # https://github.com/rust-lang/cargo/pull/9169
-        # https://github.com/rust-lang/cargo/issues/8285#issuecomment-634202431
-        cargoEnvVarTarget =
-          lib.strings.replaceStrings ["-"] ["_"]
-            (lib.strings.toUpper final.rust.cargoShortTarget);
-
-        # True if the target is no_std
-        # https://github.com/rust-lang/rust/blob/2e44c17c12cec45b6a682b1e53a04ac5b5fcc9d2/src/bootstrap/config.rs#L415-L421
-        isNoStdTarget =
-          builtins.any (t: lib.hasInfix t final.rust.rustcTarget) ["-none" "nvptx" "switch" "-uefi"];
-      };
-
       linuxArch =
         if final.isAarch32 then "arm"
         else if final.isAarch64 then "arm64"
@@ -356,7 +266,97 @@ rec {
 
     }) // mapAttrs (n: v: v final.parsed) inspect.predicates
       // mapAttrs (n: v: v final.gcc.arch or "default") architectures.predicates
-      // args;
+      // args // {
+        rust = rust // {
+          # Once args.rustc.platform.target-family is deprecated and
+          # removed, there will no longer be any need to modify any
+          # values from args.rust.platform, so we can drop all the
+          # "args ? rust" etc. checks, and merge args.rust.platform in
+          # /after/.
+          platform = rust.platform or {} // {
+            # https://doc.rust-lang.org/reference/conditional-compilation.html#target_arch
+            arch =
+              /**/ if rust ? platform then rust.platform.arch
+              else if final.isAarch32 then "arm"
+              else if final.isMips64  then "mips64"     # never add "el" suffix
+              else if final.isPower64 then "powerpc64"  # never add "le" suffix
+              else final.parsed.cpu.name;
+
+            # https://doc.rust-lang.org/reference/conditional-compilation.html#target_os
+            os =
+              /**/ if rust ? platform then rust.platform.os or "none"
+              else if final.isDarwin then "macos"
+              else final.parsed.kernel.name;
+
+            # https://doc.rust-lang.org/reference/conditional-compilation.html#target_family
+            target-family =
+              /**/ if args ? rust.platform.target-family then args.rust.platform.target-family
+              else if args ? rustc.platform.target-family
+              then
+                (
+                  # Since https://github.com/rust-lang/rust/pull/84072
+                  # `target-family` is a list instead of single value.
+                  let
+                    f = args.rustc.platform.target-family;
+                  in
+                    if builtins.isList f then f else [ f ]
+                )
+              else lib.optional final.isUnix "unix"
+                   ++ lib.optional final.isWindows "windows";
+
+            # https://doc.rust-lang.org/reference/conditional-compilation.html#target_vendor
+            vendor = let
+              inherit (final.parsed) vendor;
+            in rust.platform.vendor or {
+              "w64" = "pc";
+            }.${vendor.name} or vendor.name;
+          };
+
+          # The name of the rust target, even if it is custom. Adjustments are
+          # because rust has slightly different naming conventions than we do.
+          rustcTarget = let
+            inherit (final.parsed) cpu kernel abi;
+            cpu_ = rust.platform.arch or {
+              "armv7a" = "armv7";
+              "armv7l" = "armv7";
+              "armv6l" = "arm";
+              "armv5tel" = "armv5te";
+              "riscv64" = "riscv64gc";
+            }.${cpu.name} or cpu.name;
+            vendor_ = final.rust.platform.vendor;
+          in rust.config
+            or "${cpu_}-${vendor_}-${kernel.name}${lib.optionalString (abi.name != "unknown") "-${abi.name}"}";
+
+          # The name of the rust target if it is standard, or the json file
+          # containing the custom target spec.
+          rustcTargetSpec = rust.rustcTargetSpec or (
+            /**/ if rust ? platform
+            then builtins.toFile (final.rust.rustcTarget + ".json") (builtins.toJSON rust.platform)
+            else final.rust.rustcTarget);
+
+          # The name of the rust target if it is standard, or the
+          # basename of the file containing the custom target spec,
+          # without the .json extension.
+          #
+          # This is the name used by Cargo for target subdirectories.
+          cargoShortTarget =
+            lib.removeSuffix ".json" (baseNameOf "${final.rust.rustcTargetSpec}");
+
+          # When used as part of an environment variable name, triples are
+          # uppercased and have all hyphens replaced by underscores:
+          #
+          # https://github.com/rust-lang/cargo/pull/9169
+          # https://github.com/rust-lang/cargo/issues/8285#issuecomment-634202431
+          cargoEnvVarTarget =
+            lib.strings.replaceStrings ["-"] ["_"]
+              (lib.strings.toUpper final.rust.cargoShortTarget);
+
+          # True if the target is no_std
+          # https://github.com/rust-lang/rust/blob/2e44c17c12cec45b6a682b1e53a04ac5b5fcc9d2/src/bootstrap/config.rs#L415-L421
+          isNoStdTarget =
+            builtins.any (t: lib.hasInfix t final.rust.rustcTarget) ["-none" "nvptx" "switch" "-uefi"];
+        };
+      };
   in assert final.useAndroidPrebuilt -> final.isAndroid;
      assert lib.foldl
        (pass: { assertion, message }: