feat: add support for platform specs

This commit is contained in:
Jake Hamilton 2025-09-02 04:55:18 -07:00
parent 2c19b9ff12
commit 85e84618d6
Signed by: jakehamilton
GPG key ID: 9762169A1B35EA68
6 changed files with 176 additions and 78 deletions

View file

@ -20,9 +20,9 @@
},
"branch": "main",
"submodules": false,
"revision": "c55943c5e8197cbc2d0e506693fd5e7e3ea0a0c3",
"revision": "2af4e9f1d5dfe835c0eba15be1035bfa4065aca7",
"url": null,
"hash": "sha256-XBhIQ0XR1QabTgyo2c5wMk6xk/Bd3bCUlnTzRPcVfcw="
"hash": "sha256-fwycuhXJGDHniLlxA8Xx4IELUObrP0EW3EnsDwNdyoQ="
}
},
"version": 6

View file

@ -2,8 +2,8 @@
includes = [
./options.nix
./packages.nix
./platforms.nix
./systems.nix
./types.nix
./fp.nix
];
}

View file

@ -1,14 +0,0 @@
{ lib, config }:
{
config = {
lib.fp = {
foldl =
f: default: items:
let
process =
index: if index < 0 then default else f (process (index - 1)) (builtins.elemAt items index);
in
process (builtins.length items - 1);
};
};
}

View file

@ -0,0 +1,98 @@
{ config }:
let
inherit (config) lib;
in
{
config.lib.platforms = {
from = {
# Converts a platform spec into a list of platforms.
#
# Example specs:
#
# {
# build = "x86_64-linux";
# host = "x86_64-linux";
# target = "x86_64-linux";
# }
#
# {
# build = "*";
# host = "*";
# target = "@host";
# }
#
# {
# build = "*";
# host = ["x86_64-linux", "aarch64-linux"];
# target = "@host";
# }
#
# [
# {
# build = "*";
# host = ["x86_64-linux", "aarch64-linux"];
# target = "@host";
# }
# {
# build = "i686-linux";
# host = "@build";
# target = "@host";
# }
# ]
#
spec = input:
let
specs = lib.lists.from.any input;
platforms = lib.lists.flatten (
builtins.map
(spec:
let
build = lib.platforms.expand spec spec.build;
host = lib.platforms.expand spec spec.host;
target = lib.platforms.expand spec spec.target;
in
builtins.concatMap
(build:
builtins.concatMap
(host:
builtins.map
(target: {
build = build;
host =
if host == "@build" then
build
else host;
target =
if target == "@host" then
host
else if target == "@build" then
build
else
target;
})
target
)
host
)
build
)
specs
);
in
platforms;
};
expand = spec: value:
if builtins.isList value then
builtins.concatMap (system: lib.platforms.expand spec system) value
else if value == "@build" then
lib.platforms.expand spec spec.build
else if value == "@build" || value == "@host" then
[ value ]
else if lib.strings.hasPrefix "@" value then
lib.systems.doubles.${lib.strings.removePrefix "@" value}
else
[ value ];
};
}

View file

@ -25,7 +25,10 @@ let
lib.attrs.match patterns;
getDoubles =
predicate: builtins.map lib.systems.into.double (builtins.filter predicate lib.systems.doubles.all);
predicate:
builtins.map
lib.systems.into.double
(builtins.filter predicate lib.systems.doubles.resolved);
in
{
config = {

View file

@ -152,9 +152,11 @@ in
merge =
location: definitions:
let
modules = builtins.concatMap (
definition: lib.lists.from.any (normalize definition.value)
) definitions;
modules = builtins.concatMap
(
definition: lib.lists.from.any (normalize definition.value)
)
definitions;
result = lib.modules.run {
prefix = location;
@ -234,7 +236,7 @@ in
settings = lib.options.create {
description = "The settings for the builder.";
type = lib.types.submodule ({ config }: {});
type = lib.types.submodule ({ config }: { });
default.value = { };
};
};
@ -245,11 +247,11 @@ in
description = "a builder";
};
in
type // {
children = type.children // {
inherit submodule;
};
type // {
children = type.children // {
inherit submodule;
};
};
aliases =
let
@ -281,26 +283,32 @@ in
transform =
value:
let
result = builtins.mapAttrs (
namespace: aliases:
builtins.mapAttrs (
id: alias:
alias
// {
versions = builtins.mapAttrs (version: package: {
__modules__ = (lib.lists.from.any (normalize package)) ++ [
{
config = {
id = lib.modules.overrides.default id;
version = lib.modules.overrides.default version;
namespace = lib.modules.overrides.default namespace;
};
}
];
}) alias.versions;
}
) aliases
) value;
result = builtins.mapAttrs
(
namespace: aliases:
builtins.mapAttrs
(
id: alias:
alias
// {
versions = builtins.mapAttrs
(version: package: {
__modules__ = (lib.lists.from.any (normalize package)) ++ [
{
config = {
id = lib.modules.overrides.default id;
version = lib.modules.overrides.default version;
namespace = lib.modules.overrides.default namespace;
};
}
];
})
alias.versions;
}
)
aliases
)
value;
in
result;
@ -331,6 +339,28 @@ in
};
};
};
spec = lib.types.submodule (
{ config }:
{
options = {
build = lib.options.create {
description = "The build platform for the package.";
type = lib.types.string;
};
host = lib.options.create {
description = "The host platform for the package.";
type = lib.types.string;
};
target = lib.options.create {
description = "The target platform for the package.";
type = lib.types.string;
};
};
}
);
};
artifact =
@ -376,8 +406,8 @@ in
let
default = config.${global.config.preferences.packages.version};
in
default.extend
or (builtins.throw "Package \"${name}\" does not have a ${global.config.preferences.packages.version} release.");
default.extend
or (builtins.throw "Package \"${name}\" does not have a ${global.config.preferences.packages.version} release.");
};
stable = lib.options.create {
@ -459,9 +489,11 @@ in
merge =
location: definitions:
let
modules = builtins.concatMap (
definition: lib.lists.from.any (normalize definition.value)
) definitions;
modules = builtins.concatMap
(
definition: lib.lists.from.any (normalize definition.value)
)
definitions;
result = lib.modules.run {
prefix = location;
@ -528,9 +560,9 @@ in
};
submodule =
{
config,
meta,
{ config
, meta
,
}:
let
build = config.platform.build;
@ -696,30 +728,9 @@ in
platforms = lib.options.create {
description = "The platforms that the package supports.";
type = lib.types.list.of (
lib.types.submodule (
{ config }:
{
options = {
build = lib.options.create {
description = "The build platform for the package.";
type = lib.types.string;
};
host = lib.options.create {
description = "The host platform for the package.";
type = lib.types.string;
};
target = lib.options.create {
description = "The target platform for the package.";
type = lib.types.string;
};
};
}
)
);
type = lib.types.either lib.types.platforms.spec (lib.types.list.of lib.types.platforms.spec);
default.value = [ ];
apply = spec: lib.platforms.from.spec spec;
};
platform =
@ -859,7 +870,7 @@ in
]
);
in
lib.types.either type (lib.types.attrs.of type);
lib.types.either type (lib.types.attrs.of type);
default.value = null;
};