From 403bf3bb57019f12a819536a8835577dd7e5778f Mon Sep 17 00:00:00 2001 From: Tristan Ross Date: Thu, 23 Jan 2025 11:00:24 -0800 Subject: [PATCH] lib.systems: replace gcc attributes with cpu options --- lib/systems/default.nix | 28 +++++++++++- lib/systems/examples.nix | 4 +- lib/systems/parse.nix | 48 ++++++++++++++++++++ lib/systems/platforms.nix | 93 +++++++++++++++------------------------ 4 files changed, 112 insertions(+), 61 deletions(-) diff --git a/lib/systems/default.nix b/lib/systems/default.nix index ec0106a13dacf..0a960a5e6d9cb 100644 --- a/lib/systems/default.nix +++ b/lib/systems/default.nix @@ -66,7 +66,9 @@ let # `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 = systemOrArgs: let + elaborate = systemOrArgs: + assert lib.assertMsg (!(lib.oldestSupportedReleaseIsAtLeast 2511 && systemOrArgs ? gcc)) "The gcc attribute has been deprecated in favor of the cpu attributes."; + let allArgs = systemToAttrs systemOrArgs; # Those two will always be derived from "config", if given, so they should NOT @@ -319,6 +321,30 @@ let }) // mapAttrs (n: v: v final.parsed) inspect.predicates // mapAttrs (n: v: v final.gcc.arch or "default") architectures.predicates // args // { + cpu = parse.mkCpu final.parsed + (if args ? gcc then + let + # For gcc attribute compatibility until 25.11 is released + cpuModels = parse.cpuModels final.parsed; + gccModels = lib.listToAttrs (lib.attrValues (lib.mapAttrs (name: value: lib.nameValuePair value.gnu name) cpuModels)); + + gccModel = args.gcc.model or args.gcc.arch or "generic"; + in { + model = gccModels.${gccModel} + or (throw "${gccModel} is not supported in ${final.parsed.cpu.name} with gcc.model compatibility"); + } + else (args.cpu or {})); + + gcc = lib.warnIf + (lib.oldestSupportedReleaseIsAtLeast 2511) + "The gcc attribute in platform was deprecated in 25.11" + (lib.optionalAttrs (final.cpu.model.gnu != "generic") { + cpu = final.cpu.model.gnu; + } // lib.optionalAttrs (final.isAarch64 && final.cpu.model.gnu == "generic") { + # TODO: find when to use this. + arch = "armv8-a"; + }); + rust = rust // { # Once args.rustc.platform.target-family is deprecated and # removed, there will no longer be any need to modify any diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix index 223de50f67dd6..7c13f61f6c789 100644 --- a/lib/systems/examples.nix +++ b/lib/systems/examples.nix @@ -26,7 +26,7 @@ rec { }; ppc64-musl = { config = "powerpc64-unknown-linux-musl"; - gcc = { abi = "elfv2"; }; + abi = "elfv2"; }; sheevaplug = { @@ -198,7 +198,7 @@ rec { libc = "newlib"; # GCC8+ does not build without this # (https://www.mail-archive.com/gcc-bugs@gcc.gnu.org/msg552339.html): - gcc = { + cpu = { arch = "armv5t"; fpu = "vfp"; }; diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index e3e6ef16c6b07..968a12fd88425 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -424,6 +424,54 @@ rec { ################################################################################ + types.openCpuModel = mkOptionType { + name = "cpu-model"; + description = "cpu model"; + merge = mergeOneOption; + }; + + types.cpuModel = platform: enum (attrValues (cpuModels platform)); + + cpuModels = platform: + let + mkCpuModel = { zig ? "baseline", gnu ? "generic", llvm ? "generic", inferiors ? [], features ? [] }@args: + { zig = "baseline"; gnu = "generic"; llvm = "generic"; inferiors = []; features = []; } // args; + + generic = mkCpuModel {}; + + sets = {}; + in setTypes types.openCpuModel ((sets.${platform.cpu.name} or {}) // { inherit generic; }); + + ################################################################################ + + types.cpu = mkOptionType { + name = "cpu"; + description = "cpu options to pass to various compilers"; + merge = mergeOneOption; + check = { platform, model }: + types.parsedPlatform.check platform + && types.cpuModel.check model; + }; + + isCpu = isType "cpu"; + + mkCpu = platform: + { + model ? "generic", + float ? null, + float-abi ? null, + fpu ? null, + }: + let + cpuModels' = cpuModels platform; + in + setType "cpu" { + inherit platform; + model = cpuModels'."${model}" or (throw "Unknown CPU model ${model} for CPU architecture ${platform.cpu.name}"); + }; + + ################################################################################ + types.parsedPlatform = mkOptionType { name = "system"; description = "fully parsed representation of llvm- or nix-style platform tuple"; diff --git a/lib/systems/platforms.nix b/lib/systems/platforms.nix index 2df6f5d731cf1..dd7082407890e 100644 --- a/lib/systems/platforms.nix +++ b/lib/systems/platforms.nix @@ -67,9 +67,7 @@ rec { # TODO reenable once manual-config's config actually builds a .dtb and this is checked to be working #DTB = true; }; - gcc = { - arch = "armv5te"; - }; + cpu.model = "armv5te"; }; sheevaplug = { @@ -180,9 +178,7 @@ rec { target = "uImage"; DTB = true; # Beyond 3.10 }; - gcc = { - arch = "armv5te"; - }; + cpu.model = "armv5te"; }; raspberrypi = { @@ -200,9 +196,9 @@ rec { ''; target = "zImage"; }; - gcc = { + cpu = { # https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications - arch = "armv6kz"; + model = "armv6kz"; fpu = "vfpv2"; }; }; @@ -212,9 +208,7 @@ rec { # Nvidia Bluefield 2 (w. crypto support) bluefield2 = { - gcc = { - arch = "armv8-a+fp+simd+crc+crypto"; - }; + cpu.model = "armv8-a+fp+simd+crc+crypto"; }; zero-gravitas = { @@ -227,9 +221,9 @@ rec { autoModules = false; DTB = true; }; - gcc = { + cpu = { + model = "cortex-a9"; fpu = "neon"; - cpu = "cortex-a9"; }; }; @@ -243,8 +237,8 @@ rec { preferBuiltin = true; target = "zImage"; }; - gcc = { - cpu = "cortex-a7"; + cpu = { + model = "cortex-a7"; fpu = "neon-vfpv4"; float-abi = "hard"; }; @@ -269,8 +263,8 @@ rec { target = "uImage"; DTB = true; }; - gcc = { - cpu = "cortex-a9"; + cpu = { + model = "cortex-a9"; fpu = "neon"; }; }; @@ -296,8 +290,8 @@ rec { # https://developer.android.com/ndk/guides/abis#v7a armv7a-android = { linux-kernel.name = "armeabi-v7a"; - gcc = { - arch = "armv7-a"; + cpu = { + model = "armv7-a"; float-abi = "softfp"; fpu = "vfpv3-d16"; }; @@ -333,7 +327,7 @@ rec { KS8851_MLL y ''; }; - gcc = { + cpu = { # Some table about fpu flags: # http://community.arm.com/servlet/JiveServlet/showImage/38-1981-3827/blogentry-103749-004812900+1365712953_thumb.png # Cortex-A5: -mfpu=neon-fp16 @@ -347,11 +341,11 @@ rec { # vfpv3-d16 is what Debian uses and seems to be the best compromise: NEON is not supported in e.g. Scaleway or Tegra 2, # and the above page suggests NEON is only an improvement with hand-written assembly. - arch = "armv7-a"; + model = "armv7-a"; fpu = "vfpv3-d16"; # For Raspberry Pi the 2 the best would be: - # cpu = "cortex-a7"; + # model = "cortex-a7"; # fpu = "neon-vfpv4"; }; }; @@ -386,16 +380,11 @@ rec { ''; target = "Image"; }; - gcc = { - arch = "armv8-a"; - }; + cpu.model = "armv8-a"; }; apple-m1 = { - gcc = { - arch = "armv8.3-a+crypto+sha2+aes+crc+fp16+lse+simd+ras+rdm+rcpc"; - cpu = "apple-a13"; - }; + cpu.model = "apple-m1"; }; ## @@ -406,8 +395,8 @@ rec { linux-kernel = { name = "ben_nanonote"; }; - gcc = { - arch = "mips32"; + cpu = { + model = "mips32"; float = "soft"; }; }; @@ -483,49 +472,37 @@ rec { ''; target = "vmlinux"; }; - gcc = { - arch = "loongson2f"; + cpu = { + model = "loongson2f"; float = "hard"; - abi = "n32"; }; + abi = "n32"; }; # can execute on 32bit chip gcc_mips32r2_o32 = { - gcc = { - arch = "mips32r2"; - abi = "32"; - }; + cpu.model = "mips32r2"; + abi = "32"; }; gcc_mips32r6_o32 = { - gcc = { - arch = "mips32r6"; - abi = "32"; - }; + cpu.model = "mips32r6"; + abi = "32"; }; gcc_mips64r2_n32 = { - gcc = { - arch = "mips64r2"; - abi = "n32"; - }; + cpu.model = "mips64r2"; + abi = "n32"; }; gcc_mips64r6_n32 = { - gcc = { - arch = "mips64r6"; - abi = "n32"; - }; + cpu.model = "mips64r6"; + abi = "n32"; }; gcc_mips64r2_64 = { - gcc = { - arch = "mips64r2"; - abi = "64"; - }; + cpu.model = "mips64r2"; + abi = "64"; }; gcc_mips64r6_64 = { - gcc = { - arch = "mips64r6"; - abi = "64"; - }; + cpu.model = "mips64r6"; + abi = "64"; }; # based on: