feat: add support for platform specs (#15)
This PR adds a new way of declaring supported platforms for packages. Previously individual build, host, and target values needed to be set for a given platform combination. Now, a platform spec can be written to generate many platform combinations. This allows for easy mapping of all possible systems with `@all`, linux systems with `@linux` or any other available alias of `lib.systems.doubles.<alias>` by using `@<alias>`. In addition, you can use `@build` and `@host` to lock either the host or target respectively to match the prior platform. Reviewed-on: #15
This commit is contained in:
parent
4e4b9366a4
commit
2f31813c88
10 changed files with 236 additions and 148 deletions
|
|
@ -28,7 +28,8 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
new = module:
|
||||
new =
|
||||
module:
|
||||
let
|
||||
set = lib.modules.run {
|
||||
modules = [
|
||||
|
|
@ -37,14 +38,16 @@ let
|
|||
./src/mirrors
|
||||
|
||||
recursiveLibModule
|
||||
] ++ lib.lists.from.any module;
|
||||
]
|
||||
++ lib.lists.from.any module;
|
||||
};
|
||||
in
|
||||
set.config // {
|
||||
inherit new;
|
||||
inherit (set) extend;
|
||||
};
|
||||
set.config
|
||||
// {
|
||||
inherit new;
|
||||
inherit (set) extend;
|
||||
};
|
||||
in
|
||||
new [
|
||||
./src/packages
|
||||
]
|
||||
new [
|
||||
./src/packages
|
||||
]
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@
|
|||
},
|
||||
"branch": "main",
|
||||
"submodules": false,
|
||||
"revision": "c55943c5e8197cbc2d0e506693fd5e7e3ea0a0c3",
|
||||
"revision": "2af4e9f1d5dfe835c0eba15be1035bfa4065aca7",
|
||||
"url": null,
|
||||
"hash": "sha256-XBhIQ0XR1QabTgyo2c5wMk6xk/Bd3bCUlnTzRPcVfcw="
|
||||
"hash": "sha256-fwycuhXJGDHniLlxA8Xx4IELUObrP0EW3EnsDwNdyoQ="
|
||||
}
|
||||
},
|
||||
"version": 6
|
||||
|
|
|
|||
|
|
@ -33,9 +33,10 @@ in
|
|||
hooks.target.target
|
||||
];
|
||||
in
|
||||
builtins.foldl' (
|
||||
final: defaults: lib.dag.apply.defaults final (resolvePhases defaults)
|
||||
) (resolvePhases package.phases) all;
|
||||
builtins.foldl'
|
||||
(final: defaults: lib.dag.apply.defaults final (resolvePhases defaults))
|
||||
(resolvePhases package.phases)
|
||||
all;
|
||||
|
||||
phases = lib.dag.apply.defaults phasesWithHooks {
|
||||
unpack = lib.dag.entry.before [ "patch" ] "";
|
||||
|
|
@ -91,14 +92,11 @@ in
|
|||
foundation.stage2-coreutils
|
||||
]
|
||||
++ lib.lists.when (system == "x86_64-linux") [
|
||||
(lib.packages.build packages.foundation.bash.versions."5.2.15-stage1" "i686-linux" system system)
|
||||
.package
|
||||
(lib.packages.build packages.foundation.coreutils.versions."9.4-stage1" "i686-linux" system system)
|
||||
.package
|
||||
(lib.packages.build packages.foundation.bash.versions."5.2.15-stage1" "i686-linux" system system).package
|
||||
(lib.packages.build packages.foundation.coreutils.versions."9.4-stage1" "i686-linux" system system).package
|
||||
]
|
||||
++ lib.lists.when (system != "i686-linux" && system != "x86_64-linux") [
|
||||
(lib.packages.build packages.foundation.bash.versions."5.2.15-stage1" "x86_64-linux" system system)
|
||||
.package
|
||||
(lib.packages.build packages.foundation.bash.versions."5.2.15-stage1" "x86_64-linux" system system).package
|
||||
(lib.packages.build packages.foundation.coreutils.versions."9.4-stage1" "x86_64-linux" system
|
||||
system
|
||||
).package
|
||||
|
|
|
|||
|
|
@ -6,22 +6,24 @@ let
|
|||
inherit (config.internal.packages) foundation;
|
||||
in
|
||||
{
|
||||
config.builders.passthrough = { config }: {
|
||||
options = {
|
||||
settings.derivation = lib.options.create {
|
||||
description = "The derivation to use for the package.";
|
||||
type = lib.types.derivation;
|
||||
config.builders.passthrough =
|
||||
{ config }:
|
||||
{
|
||||
options = {
|
||||
settings.derivation = lib.options.create {
|
||||
description = "The derivation to use for the package.";
|
||||
type = lib.types.derivation;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
build =
|
||||
package:
|
||||
package.builder.settings.derivation
|
||||
// {
|
||||
inherit package;
|
||||
inherit (package) meta extend extras;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
build =
|
||||
package:
|
||||
package.builder.settings.derivation
|
||||
// {
|
||||
inherit package;
|
||||
inherit (package) meta extend extras;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
includes = [
|
||||
./options.nix
|
||||
./packages.nix
|
||||
./platforms.nix
|
||||
./systems.nix
|
||||
./types.nix
|
||||
./fp.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -92,7 +92,9 @@ in
|
|||
global = global.config;
|
||||
};
|
||||
|
||||
prefix = package.__module__.args.dynamic.meta.prefix ++ [ "<context ${builtins.concatStringsSep path}>" ];
|
||||
prefix = package.__module__.args.dynamic.meta.prefix ++ [
|
||||
"<context ${builtins.concatStringsSep path}>"
|
||||
];
|
||||
modules = (builtins.map (context: { config = context; }) contexts) ++ [
|
||||
{
|
||||
freeform = lib.types.any;
|
||||
|
|
|
|||
92
tidepool/src/lib/platforms.nix
Normal file
92
tidepool/src/lib/platforms.nix
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
{ 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 ];
|
||||
};
|
||||
}
|
||||
|
|
@ -25,7 +25,8 @@ 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 = {
|
||||
|
|
@ -2788,11 +2789,7 @@ in
|
|||
// (builtins.removeAttrs settings [ "system" ]);
|
||||
|
||||
assertions = builtins.foldl' (
|
||||
result:
|
||||
{ assertion, message }:
|
||||
if assertion resolved then
|
||||
result
|
||||
else builtins.throw message
|
||||
result: { assertion, message }: if assertion resolved then result else builtins.throw message
|
||||
) true (resolved.system.abi.assertions or [ ]);
|
||||
in
|
||||
assert resolved.useAndroidPrebuilt -> resolved.isAndroid;
|
||||
|
|
|
|||
|
|
@ -172,84 +172,91 @@ in
|
|||
result.config;
|
||||
};
|
||||
|
||||
submodule = { config, meta, name ? "builder" }: {
|
||||
options = {
|
||||
__modules__ = lib.options.create {
|
||||
description = "User specified modules for the builder definition.";
|
||||
type = lib.types.list.of (initial // { merge = lib.options.merge.one; });
|
||||
internal = true;
|
||||
default.value = [ ];
|
||||
};
|
||||
|
||||
extend = lib.options.create {
|
||||
description = "Extend the package definition.";
|
||||
type = lib.types.function lib.types.raw;
|
||||
default.value =
|
||||
module:
|
||||
let
|
||||
normalized =
|
||||
if builtins.isList module then
|
||||
module
|
||||
else if builtins.isFunction module || module ? config then
|
||||
[ module ]
|
||||
else
|
||||
[
|
||||
{
|
||||
config = module;
|
||||
}
|
||||
];
|
||||
|
||||
modules = config.__modules__ ++ normalized;
|
||||
|
||||
result = lib.modules.run {
|
||||
prefix = meta.prefix;
|
||||
|
||||
args = {
|
||||
global = global.config;
|
||||
};
|
||||
|
||||
modules = [
|
||||
submodule
|
||||
{ config.__modules__ = modules; }
|
||||
]
|
||||
++ modules;
|
||||
};
|
||||
in
|
||||
result.config;
|
||||
};
|
||||
|
||||
name = lib.options.create {
|
||||
description = "The name of the builder.";
|
||||
type = lib.types.string;
|
||||
default = lib.attrs.when (name != "builder") {
|
||||
value = name;
|
||||
submodule =
|
||||
{
|
||||
config,
|
||||
meta,
|
||||
name ? "builder",
|
||||
}:
|
||||
{
|
||||
options = {
|
||||
__modules__ = lib.options.create {
|
||||
description = "User specified modules for the builder definition.";
|
||||
type = lib.types.list.of (initial // { merge = lib.options.merge.one; });
|
||||
internal = true;
|
||||
default.value = [ ];
|
||||
};
|
||||
writable = false;
|
||||
};
|
||||
|
||||
build = lib.options.create {
|
||||
description = "The build function which takes a package definition and creates a derivation.";
|
||||
type = lib.types.function lib.types.artifact;
|
||||
};
|
||||
extend = lib.options.create {
|
||||
description = "Extend the package definition.";
|
||||
type = lib.types.function lib.types.raw;
|
||||
default.value =
|
||||
module:
|
||||
let
|
||||
normalized =
|
||||
if builtins.isList module then
|
||||
module
|
||||
else if builtins.isFunction module || module ? config then
|
||||
[ module ]
|
||||
else
|
||||
[
|
||||
{
|
||||
config = module;
|
||||
}
|
||||
];
|
||||
|
||||
settings = lib.options.create {
|
||||
description = "The settings for the builder.";
|
||||
type = lib.types.submodule ({ config }: {});
|
||||
default.value = { };
|
||||
modules = config.__modules__ ++ normalized;
|
||||
|
||||
result = lib.modules.run {
|
||||
prefix = meta.prefix;
|
||||
|
||||
args = {
|
||||
global = global.config;
|
||||
};
|
||||
|
||||
modules = [
|
||||
submodule
|
||||
{ config.__modules__ = modules; }
|
||||
]
|
||||
++ modules;
|
||||
};
|
||||
in
|
||||
result.config;
|
||||
};
|
||||
|
||||
name = lib.options.create {
|
||||
description = "The name of the builder.";
|
||||
type = lib.types.string;
|
||||
default = lib.attrs.when (name != "builder") {
|
||||
value = name;
|
||||
};
|
||||
writable = false;
|
||||
};
|
||||
|
||||
build = lib.options.create {
|
||||
description = "The build function which takes a package definition and creates a derivation.";
|
||||
type = lib.types.function lib.types.artifact;
|
||||
};
|
||||
|
||||
settings = lib.options.create {
|
||||
description = "The settings for the builder.";
|
||||
type = lib.types.submodule ({ config }: { });
|
||||
default.value = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type = (lib.types.coerceWithLocation initial transform final) // {
|
||||
name = "Builder";
|
||||
description = "a builder";
|
||||
};
|
||||
in
|
||||
type // {
|
||||
children = type.children // {
|
||||
inherit submodule;
|
||||
};
|
||||
type
|
||||
// {
|
||||
children = type.children // {
|
||||
inherit submodule;
|
||||
};
|
||||
};
|
||||
|
||||
aliases =
|
||||
let
|
||||
|
|
@ -331,6 +338,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 =
|
||||
|
|
@ -696,30 +725,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 +867,7 @@ in
|
|||
]
|
||||
);
|
||||
in
|
||||
lib.types.either type (lib.types.attrs.of type);
|
||||
lib.types.either type (lib.types.attrs.of type);
|
||||
default.value = null;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue