refactor(format): apply formatting

This commit is contained in:
Jake Hamilton 2024-07-04 18:01:33 -07:00
parent d2b053d63a
commit 0a63667459
Signed by untrusted user: jakehamilton
GPG key ID: 9762169A1B35EA68
15 changed files with 2355 additions and 2309 deletions

View file

@ -4,7 +4,9 @@ lib: {
## Merge a list of option definitions into a single value. ## Merge a list of option definitions into a single value.
## ##
## @type Location -> List Definition -> Any ## @type Location -> List Definition -> Any
default = location: definitions: let default =
location: definitions:
let
values = lib.options.getDefinitionValues definitions; values = lib.options.getDefinitionValues definitions;
first = builtins.elemAt values 0; first = builtins.elemAt values 0;
mergedFunctions = x: lib.options.mergeDefault location (builtins.map (f: f x) values); mergedFunctions = x: lib.options.mergeDefault location (builtins.map (f: f x) values);
@ -13,29 +15,34 @@ lib: {
mergedBools = builtins.any lib.bools.or false values; mergedBools = builtins.any lib.bools.or false values;
mergedStrings = lib.strings.concat values; mergedStrings = lib.strings.concat values;
in in
if builtins.length values == 1 if builtins.length values == 1 then
then builtins.elemAt values 0 builtins.elemAt values 0
else if builtins.all builtins.isFunction values else if builtins.all builtins.isFunction values then
then mergedFunctions mergedFunctions
else if builtins.all builtins.isList values else if builtins.all builtins.isList values then
then mergedLists mergedLists
else if builtins.all builtins.isAttrs values else if builtins.all builtins.isAttrs values then
then mergedAttrs mergedAttrs
else if builtins.all builtins.isBool values else if builtins.all builtins.isBool values then
then mergedBools mergedBools
else if builtins.all lib.strings.isString values else if builtins.all lib.strings.isString values then
then mergedStrings mergedStrings
else if builtins.all builtins.isInt values && builtins.all (x: x == first) values else if builtins.all builtins.isInt values && builtins.all (x: x == first) values then
then first first
# TODO: Improve this error message to show the location and definitions for the option. # TODO: Improve this error message to show the location and definitions for the option.
else builtins.throw "Cannot merge definitions."; else
builtins.throw "Cannot merge definitions.";
## Merge multiple option definitions together. ## Merge multiple option definitions together.
## ##
## @type Location -> Type -> List Definition ## @type Location -> Type -> List Definition
definitions = location: type: definitions: let definitions =
location: type: definitions:
let
identifier = lib.options.getIdentifier location; identifier = lib.options.getIdentifier location;
resolve = definition: let resolve =
definition:
let
properties = builtins.addErrorContext "while evaluating definitions from `${definition.__file__ or "<unknown>"}`:" ( properties = builtins.addErrorContext "while evaluating definitions from `${definition.__file__ or "<unknown>"}`:" (
lib.modules.apply.properties definition.value lib.modules.apply.properties definition.value
); );
@ -50,27 +57,27 @@ lib: {
overridden = lib.modules.apply.overrides resolved; overridden = lib.modules.apply.overrides resolved;
values = values =
if builtins.any (definition: lib.types.is "order" definition.value) overridden.values if builtins.any (definition: lib.types.is "order" definition.value) overridden.values then
then lib.modules.apply.order overridden.values lib.modules.apply.order overridden.values
else overridden.values; else
overridden.values;
isDefined = values != [ ]; isDefined = values != [ ];
invalid = builtins.filter (definition: !(type.check definition.value)) values; invalid = builtins.filter (definition: !(type.check definition.value)) values;
merged = merged =
if isDefined if isDefined then
then if builtins.all (definition: type.check definition.value) values then
if builtins.all (definition: type.check definition.value) values type.merge location values
then type.merge location values else
else builtins.throw "A definition for `${identifier}` is not of type `${type.description}`. Definition values:${lib.options.getDefinitions invalid}" builtins.throw "A definition for `${identifier}` is not of type `${type.description}`. Definition values:${lib.options.getDefinitions invalid}"
else builtins.throw "The option `${identifier}` is used but not defined."; else
builtins.throw "The option `${identifier}` is used but not defined.";
optional = optional = if isDefined then { value = merged; } else { };
if isDefined in
then {value = merged;} {
else {};
in {
inherit inherit
isDefined isDefined
values values
@ -87,8 +94,12 @@ lib: {
## Merge multiple option declarations together. ## Merge multiple option declarations together.
## ##
## @type Location -> List Option ## @type Location -> List Option
declarations = location: options: let declarations =
merge = result: option: let location: options:
let
merge =
result: option:
let
mergedType = result.type.mergeType option.options.type.functor; mergedType = result.type.mergeType option.options.type.functor;
isTypeMergeable = mergedType != null; isTypeMergeable = mergedType != null;
shared = name: option.options ? ${name} && result ? ${name}; shared = name: option.options ? ${name} && result ? ${name};
@ -97,15 +108,14 @@ lib: {
serializedFiles = builtins.concatStringsSep " and " files; serializedFiles = builtins.concatStringsSep " and " files;
getSubModules = option.options.type.getSubModules or null; getSubModules = option.options.type.getSubModules or null;
submodules = submodules =
if getSubModules != null if getSubModules != null then
then
builtins.map (module: { builtins.map (module: {
__file__ = option.__file__; __file__ = option.__file__;
includes = [ module ]; includes = [ module ];
}) }) getSubModules
getSubModules
++ result.options ++ result.options
else result.options; else
result.options;
in in
if if
shared "default" shared "default"
@ -113,7 +123,8 @@ lib: {
|| shared "description" || shared "description"
|| shared "apply" || shared "apply"
|| (shared "type" && !isTypeMergeable) || (shared "type" && !isTypeMergeable)
then builtins.throw "The option `${lib.options.getIdentifier location}` in `${option.__file__}` is already declared in ${serializedFiles}" then
builtins.throw "The option `${lib.options.getIdentifier location}` in `${option.__file__}` is already declared in ${serializedFiles}"
else else
option.options option.options
// result // result
@ -127,43 +138,50 @@ lib: {
inherit location; inherit location;
declarations = [ ]; declarations = [ ];
options = [ ]; options = [ ];
} } options;
options;
## Merge an option, only supporting a single unique definition. ## Merge an option, only supporting a single unique definition.
## ##
## @type String -> Location -> List Definition -> Any ## @type String -> Location -> List Definition -> Any
unique = message: location: definitions: let unique =
message: location: definitions:
let
identifier = lib.options.getIdentifier location; identifier = lib.options.getIdentifier location;
total = builtins.length definitions; total = builtins.length definitions;
first = builtins.elemAt definitions 0; first = builtins.elemAt definitions 0;
in in
if total == 1 if total == 1 then
then first.value first.value
else if total == 0 else if total == 0 then
then builtins.throw "Cannot merge unused option `${identifier}`.\n${message}" builtins.throw "Cannot merge unused option `${identifier}`.\n${message}"
else builtins.throw "The option `${identifier}` is defined multiple times, but must be unique.\n${message}\nDefinitions:${lib.options.getDefinitions definitions}"; else
builtins.throw "The option `${identifier}` is defined multiple times, but must be unique.\n${message}\nDefinitions:${lib.options.getDefinitions definitions}";
## Merge a single instance of an option. ## Merge a single instance of an option.
## ##
## @type Location -> List Definition -> Any ## @type Location -> List Definition -> Any
one = lib.options.merge.unique ""; one = lib.options.merge.unique "";
equal = location: definitions: let equal =
location: definitions:
let
identifier = lib.options.getIdentifier location; identifier = lib.options.getIdentifier location;
first = builtins.elemAt definitions 0; first = builtins.elemAt definitions 0;
rest = builtins.tail definitions; rest = builtins.tail definitions;
merge = x: y: merge =
if x != y x: y:
then builtins.throw "The option `${identifier}` has conflicting definitions:${lib.options.getDefinitions definitions}" if x != y then
else x; builtins.throw "The option `${identifier}` has conflicting definitions:${lib.options.getDefinitions definitions}"
else
x;
merged = builtins.foldl' merge first rest; merged = builtins.foldl' merge first rest;
in in
if builtins.length definitions == 0 if builtins.length definitions == 0 then
then builtins.throw "Cannot merge unused option `${identifier}`." builtins.throw "Cannot merge unused option `${identifier}`."
else if builtins.length definitions == 1 else if builtins.length definitions == 1 then
then first.value first.value
else merged.value; else
merged.value;
}; };
## Check whether a value is an option. ## Check whether a value is an option.
@ -174,7 +192,8 @@ lib: {
## Create an option. ## Create an option.
## ##
## @type { type? :: String | Null, apply? :: (a -> b) | Null, default? :: { value :: a, text :: String }, example? :: String | Null, visible? :: Bool | Null, internal? :: Bool | Null, writable? :: Bool | Null, description? :: String | Null } -> Option a ## @type { type? :: String | Null, apply? :: (a -> b) | Null, default? :: { value :: a, text :: String }, example? :: String | Null, visible? :: Bool | Null, internal? :: Bool | Null, writable? :: Bool | Null, description? :: String | Null } -> Option a
create = settings @ { create =
settings@{
type ? lib.types.unspecified, type ? lib.types.unspecified,
apply ? null, apply ? null,
default ? { }, default ? { },
@ -183,7 +202,8 @@ lib: {
internal ? null, internal ? null,
writable ? null, writable ? null,
description ? null, description ? null,
}: { }:
{
__type__ = "option"; __type__ = "option";
inherit inherit
type type
@ -200,7 +220,9 @@ lib: {
## Create a sink option. ## Create a sink option.
## ##
## @type @alias lib.options.create ## @type @alias lib.options.create
sink = settings: let sink =
settings:
let
defaults = { defaults = {
internal = true; internal = true;
visible = false; visible = false;
@ -224,7 +246,9 @@ lib: {
## Convert a list of option identifiers into a single identifier. ## Convert a list of option identifiers into a single identifier.
## ##
## @type List String -> String ## @type List String -> String
getIdentifier = location: let getIdentifier =
location:
let
special = [ special = [
# lib.types.attrs.of (lib.types.submodule {}) # lib.types.attrs.of (lib.types.submodule {})
"<name>" "<name>"
@ -233,24 +257,23 @@ lib: {
# lib.types.function # lib.types.function
"<function body>" "<function body>"
]; ];
escape = part: escape = part: if builtins.elem part special then part else lib.strings.escape.nix.identifier part;
if builtins.elem part special
then part
else lib.strings.escape.nix.identifier part;
in in
lib.strings.concatMapSep "." escape location; lib.strings.concatMapSep "." escape location;
## Get a string message of the definitions for an option. ## Get a string message of the definitions for an option.
## ##
## @type List Definition -> String ## @type List Definition -> String
getDefinitions = definitions: let getDefinitions =
serialize = definition: let definitions:
valueWithRecursionLimit = let
lib.generators.withRecursion { serialize =
definition:
let
valueWithRecursionLimit = lib.generators.withRecursion {
limit = 10; limit = 10;
throw = false; throw = false;
} } definition.value;
definition.value;
eval = builtins.tryEval (lib.generators.pretty { } valueWithRecursionLimit); eval = builtins.tryEval (lib.generators.pretty { } valueWithRecursionLimit);
@ -263,24 +286,27 @@ lib: {
value = builtins.concatStringsSep "\n " (firstFiveLines ++ ellipsis); value = builtins.concatStringsSep "\n " (firstFiveLines ++ ellipsis);
result = result =
if !eval.success if !eval.success then
then "" ""
else if linesLength > 1 else if linesLength > 1 then
then ":\n " + value ":\n " + value
else ": " + value; else
in "\n- In `${definition.__file__}`${result}"; ": " + value;
in
"\n- In `${definition.__file__}`${result}";
in in
lib.strings.concatMap serialize definitions; lib.strings.concatMap serialize definitions;
## Run a set of definitions, calculating the resolved value and associated information. ## Run a set of definitions, calculating the resolved value and associated information.
## ##
## @type Location -> Option -> List Definition -> String & { value :: Any, highestPriority :: Int, isDefined :: Bool, files :: List String, definitions :: List Any, definitionsWithLocations :: List Definition } ## @type Location -> Option -> List Definition -> String & { value :: Any, highestPriority :: Int, isDefined :: Bool, files :: List String, definitions :: List Any, definitionsWithLocations :: List Definition }
run = location: option: definitions: let run =
location: option: definitions:
let
identifier = lib.options.getIdentifier location; identifier = lib.options.getIdentifier location;
definitionsWithDefault = definitionsWithDefault =
if option ? default && option.default ? value if option ? default && option.default ? value then
then
[ [
{ {
__file__ = builtins.head option.declarations; __file__ = builtins.head option.declarations;
@ -288,28 +314,25 @@ lib: {
} }
] ]
++ definitions ++ definitions
else definitions; else
definitions;
merged = merged =
if option.writable or null == false && builtins.length definitionsWithDefault > 1 if option.writable or null == false && builtins.length definitionsWithDefault > 1 then
then let let
separatedDefinitions = separatedDefinitions = builtins.map (
builtins.map (
definition: definition:
definition definition
// { // {
value = (lib.options.merge.definitions location option.type [ definition ]).merged; value = (lib.options.merge.definitions location option.type [ definition ]).merged;
} }
) ) definitionsWithDefault;
definitionsWithDefault;
in in
builtins.throw "The option `${identifier}` is not writable, but is set more than once:${lib.options.getDefinitions separatedDefinitions}" builtins.throw "The option `${identifier}` is not writable, but is set more than once:${lib.options.getDefinitions separatedDefinitions}"
else lib.options.merge.definitions location option.type definitionsWithDefault; else
lib.options.merge.definitions location option.type definitionsWithDefault;
value = value = if option.apply or null != null then option.apply merged.merged else merged.merged;
if option.apply or null != null
then option.apply merged.merged
else merged.merged;
in in
option option
// { // {

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,19 @@
{ { lib, config }:
lib, let
config,
}: let
cfg = config.builders.basic; cfg = config.builders.basic;
lib' = config.lib; lib' = config.lib;
inherit (config) foundation; inherit (config) foundation;
in { in
{
config.builders = { config.builders = {
basic = { basic = {
executable = "${foundation.stage2-bash}/bin/bash"; executable = "${foundation.stage2-bash}/bin/bash";
build = package: let build =
package:
let
phases = lib.dag.apply.defaults package.phases { phases = lib.dag.apply.defaults package.phases {
unpack = lib.dag.entry.before [ "patch" ] ""; unpack = lib.dag.entry.before [ "patch" ] "";
@ -26,14 +27,9 @@ in {
}; };
sorted = lib.dag.sort.topographic phases; sorted = lib.dag.sort.topographic phases;
script = script = lib.strings.concatMapSep "\n" (
lib.strings.concatMapSep "\n" ( entry: if builtins.isFunction entry.value then entry.value package else entry.value
entry: ) sorted.result;
if builtins.isFunction entry.value
then entry.value package
else entry.value
)
sorted.result;
system = package.platform.build.double; system = package.platform.build.double;
@ -47,7 +43,8 @@ in {
SHELL = cfg.executable; SHELL = cfg.executable;
PATH = let PATH =
let
bins = lib.paths.bin ( bins = lib.paths.bin (
(lib'.packages.dependencies.getPackages package.deps.build.host) (lib'.packages.dependencies.getPackages package.deps.build.host)
++ [ ++ [

View file

@ -1,8 +1,10 @@
# This file handles creating all of the exports for this project and is not # This file handles creating all of the exports for this project and is not
# exported itself. # exported itself.
{config}: let { config }:
let
inherit (config) lib; inherit (config) lib;
in { in
{
# freeform = lib.types.any; # freeform = lib.types.any;
config = { config = {

View file

@ -1,8 +1,7 @@
{ lib, config }:
let
in
{ {
lib,
config,
}: let
in {
config = { config = {
lib.options = { lib.options = {
package = lib.options.create { package = lib.options.create {

View file

@ -1,41 +1,48 @@
{ { lib, config }:
lib, let
config,
}: let
lib' = config.lib; lib' = config.lib;
in { in
{
config = { config = {
lib.packages = { lib.packages = {
dependencies = { dependencies = {
getPackages = dependencies: let getPackages =
dependencies:
let
available = builtins.filter (dependency: !(builtins.isNull dependency)) ( available = builtins.filter (dependency: !(builtins.isNull dependency)) (
builtins.attrValues dependencies builtins.attrValues dependencies
); );
in in
builtins.map (dependency: dependency.package) available; builtins.map (dependency: dependency.package) available;
build = build': host': target': build =
builtins.mapAttrs build': host': target':
(name: dep: lib'.packages.build dep build' host' target'); builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target');
}; };
getLatest = alias: let getLatest =
alias:
let
versions = builtins.attrNames alias.versions; versions = builtins.attrNames alias.versions;
sorted = builtins.sort (lib.versions.gte) versions; sorted = builtins.sort (lib.versions.gte) versions;
in in
builtins.head sorted; builtins.head sorted;
resolve = alias: resolve =
if alias ? versions alias:
then if alias ? versions then
alias.versions.${config.preferences.packages.version} alias.versions.${config.preferences.packages.version}
or (alias.versions.${lib'.packages.getLatest alias}) or (alias.versions.${lib'.packages.getLatest alias})
else alias; else
alias;
build = alias: build: host: target: let build =
alias: build: host: target:
let
package = lib'.packages.resolve alias; package = lib'.packages.resolve alias;
buildDependencies = build': host': target': buildDependencies =
build': host': target':
builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target'); builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target');
platform = { platform = {
@ -45,12 +52,11 @@ in {
}; };
withPlatform = lib.modules.run { withPlatform = lib.modules.run {
modules = modules = package.__modules__ ++ [
package.__modules__
++ [
lib'.types.package.children.submodule lib'.types.package.children.submodule
( (
{config}: { { config }:
{
config = { config = {
__modules__ = package.__modules__; __modules__ = package.__modules__;
@ -64,9 +70,7 @@ in {
# Not all platform information can be effectively handled via submodules. To handle # Not all platform information can be effectively handled via submodules. To handle
# the case where a user copies the resolved config over we need to ensure that # the case where a user copies the resolved config over we need to ensure that
# dependencies are appropriately updated. # dependencies are appropriately updated.
withDeps = withDeps = withPlatform.config // {
withPlatform.config
// {
deps = { deps = {
build = { build = {
only = buildDependencies build build build withPlatform.config.deps.build.only; only = buildDependencies build build build withPlatform.config.deps.build.only;
@ -87,12 +91,11 @@ in {
}; };
withPackage = lib.modules.run { withPackage = lib.modules.run {
modules = modules = package.__modules__ ++ [
package.__modules__
++ [
lib'.types.package.children.submodule lib'.types.package.children.submodule
( (
{config}: { { config }:
{
config = { config = {
__modules__ = package.__modules__; __modules__ = package.__modules__;

View file

@ -1,34 +1,34 @@
{ { lib, config }:
lib, let
config,
}: let
lib' = config.lib; lib' = config.lib;
types = config.lib.systems.types; types = config.lib.systems.types;
setTypes = type: let setTypes =
assign = name: value: type:
let
assign =
name: value:
assert lib.errors.trace (type.check value) assert lib.errors.trace (type.check value)
"${name} is not of type ${type.name}: ${lib.generators.pretty { } value}"; "${name} is not of type ${type.name}: ${lib.generators.pretty { } value}";
lib.types.set type.name ({ inherit name; } // value); lib.types.set type.name ({ inherit name; } // value);
in in
builtins.mapAttrs assign; builtins.mapAttrs assign;
matchAnyAttrs = patterns: matchAnyAttrs =
if builtins.isList patterns patterns:
then if builtins.isList patterns then
value: value:
builtins.any ( builtins.any (
pattern: pattern: if builtins.isFunction pattern then pattern value else matchAnyAttrs pattern value
if builtins.isFunction pattern ) patterns
then pattern value else
else matchAnyAttrs pattern value lib.attrs.match patterns;
)
patterns
else lib.attrs.match patterns;
getDoubles = predicate: getDoubles =
predicate:
builtins.map lib'.systems.into.double (builtins.filter predicate lib'.systems.doubles.all); builtins.map lib'.systems.into.double (builtins.filter predicate lib'.systems.doubles.all);
in { in
{
config = { config = {
lib.systems = { lib.systems = {
match = builtins.mapAttrs (lib.fp.const matchAnyAttrs) lib'.systems.patterns; match = builtins.mapAttrs (lib.fp.const matchAnyAttrs) lib'.systems.patterns;
@ -600,43 +600,44 @@ in {
}; };
}; };
mipsel-linux-gnu = mipsel-linux-gnu = {
{
triple = "mipsel-unknown-linux-gnu"; triple = "mipsel-unknown-linux-gnu";
} } // lib'.systems.platforms.gcc_mips32r2_o32;
// lib'.systems.platforms.gcc_mips32r2_o32;
# This function takes a minimally-valid "platform" and returns an # This function takes a minimally-valid "platform" and returns an
# attrset containing zero or more additional attrs which should be # attrset containing zero or more additional attrs which should be
# included in the platform in order to further elaborate it. # included in the platform in order to further elaborate it.
select = platform: select =
platform:
# x86 # x86
if platform.isx86 if platform.isx86 then
then lib'.systems.platforms.pc lib'.systems.platforms.pc
# ARM # ARM
else if platform.isAarch32 else if platform.isAarch32 then
then let let
version = platform.system.cpu.version or null; version = platform.system.cpu.version or null;
in in
if version == null if version == null then
then lib'.systems.platforms.pc lib'.systems.platforms.pc
else if lib.versions.gte "6" version else if lib.versions.gte "6" version then
then lib'.systems.platforms.sheevaplug lib'.systems.platforms.sheevaplug
else if lib.versions.gte "7" version else if lib.versions.gte "7" version then
then lib'.systems.platforms.raspberrypi lib'.systems.platforms.raspberrypi
else lib'.systems.platforms.armv7l-hf-multiplatform else
else if platform.isAarch64 lib'.systems.platforms.armv7l-hf-multiplatform
then else if platform.isAarch64 then
if platform.isDarwin if platform.isDarwin then
then lib'.systems.platforms.apple-m1 lib'.systems.platforms.apple-m1
else lib'.systems.platforms.aarch64-multiplatform else
else if platform.isRiscV lib'.systems.platforms.aarch64-multiplatform
then lib'.systems.platforms.riscv-multiplatform else if platform.isRiscV then
else if platform.system.cpu == types.cpus.mipsel lib'.systems.platforms.riscv-multiplatform
then lib'.systems.platforms.mipsel-linux-gnu else if platform.system.cpu == types.cpus.mipsel then
else if platform.system.cpu == types.cpus.powerpc64le lib'.systems.platforms.mipsel-linux-gnu
then lib'.systems.platforms.powernv else if platform.system.cpu == types.cpus.powerpc64le then
else {}; lib'.systems.platforms.powernv
else
{ };
}; };
architectures = { architectures = {
@ -1027,9 +1028,11 @@ in {
}; };
validate = { validate = {
architecture = let architecture =
let
isSupported = feature: x: builtins.elem feature (lib'.systems.architectures.features.${x} or [ ]); isSupported = feature: x: builtins.elem feature (lib'.systems.architectures.features.${x} or [ ]);
in { in
{
sse3Support = isSupported "sse3"; sse3Support = isSupported "sse3";
ssse3Support = isSupported "ssse3"; ssse3Support = isSupported "ssse3";
sse4_1Support = isSupported "sse4_1"; sse4_1Support = isSupported "sse4_1";
@ -1043,7 +1046,8 @@ in {
fma4Support = isSupported "fma4"; fma4Support = isSupported "fma4";
}; };
compatible = a: b: compatible =
a: b:
lib.any lib.id [ lib.any lib.id [
# x86 # x86
( (
@ -1058,114 +1062,96 @@ in {
# XXX: Not true in some cases. Like in WSL mode. # XXX: Not true in some cases. Like in WSL mode.
( (
b b == lib'.systems.types.cpus.i686
== lib'.systems.types.cpus.i686
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.x86_64 && lib'.systems.validate.compatible a lib'.systems.types.cpus.x86_64
) )
# ARMv4 # ARMv4
( (
b b == lib'.systems.types.cpus.arm
== lib'.systems.types.cpus.arm
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv5tel && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv5tel
) )
# ARMv5 # ARMv5
( (
b b == lib'.systems.types.cpus.armv5tel
== lib'.systems.types.cpus.armv5tel
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv6l && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv6l
) )
# ARMv6 # ARMv6
( (
b b == lib'.systems.types.cpus.armv6l
== lib'.systems.types.cpus.armv6l
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv6m && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv6m
) )
( (
b b == lib'.systems.types.cpus.armv6m
== lib'.systems.types.cpus.armv6m
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7l && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7l
) )
# ARMv7 # ARMv7
( (
b b == lib'.systems.types.cpus.armv7l
== lib'.systems.types.cpus.armv7l
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7a && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7a
) )
( (
b b == lib'.systems.types.cpus.armv7l
== lib'.systems.types.cpus.armv7l
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7r && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7r
) )
( (
b b == lib'.systems.types.cpus.armv7l
== lib'.systems.types.cpus.armv7l
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7m && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv7m
) )
# ARMv8 # ARMv8
(b == lib'.systems.types.cpus.aarch64 && a == lib'.systems.types.cpus.armv8a) (b == lib'.systems.types.cpus.aarch64 && a == lib'.systems.types.cpus.armv8a)
( (
b b == lib'.systems.types.cpus.armv8a
== lib'.systems.types.cpus.armv8a
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.aarch64 && lib'.systems.validate.compatible a lib'.systems.types.cpus.aarch64
) )
( (
b b == lib'.systems.types.cpus.armv8r
== lib'.systems.types.cpus.armv8r
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv8a && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv8a
) )
( (
b b == lib'.systems.types.cpus.armv8m
== lib'.systems.types.cpus.armv8m
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.armv8a && lib'.systems.validate.compatible a lib'.systems.types.cpus.armv8a
) )
# PowerPC # PowerPC
( (
b b == lib'.systems.types.cpus.powerpc
== lib'.systems.types.cpus.powerpc
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.powerpc64 && lib'.systems.validate.compatible a lib'.systems.types.cpus.powerpc64
) )
( (
b b == lib'.systems.types.cpus.powerpcle
== lib'.systems.types.cpus.powerpcle
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.powerpc64le && lib'.systems.validate.compatible a lib'.systems.types.cpus.powerpc64le
) )
# MIPS # MIPS
( (
b b == lib'.systems.types.cpus.mips
== lib'.systems.types.cpus.mips
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.mips64 && lib'.systems.validate.compatible a lib'.systems.types.cpus.mips64
) )
( (
b b == lib'.systems.types.cpus.mipsel
== lib'.systems.types.cpus.mipsel
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.mips64el && lib'.systems.validate.compatible a lib'.systems.types.cpus.mips64el
) )
# RISCV # RISCV
( (
b b == lib'.systems.types.cpus.riscv32
== lib'.systems.types.cpus.riscv32
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.riscv64 && lib'.systems.validate.compatible a lib'.systems.types.cpus.riscv64
) )
# SPARC # SPARC
( (
b b == lib'.systems.types.cpus.sparc
== lib'.systems.types.cpus.sparc
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.sparc64 && lib'.systems.validate.compatible a lib'.systems.types.cpus.sparc64
) )
# WASM # WASM
( (
b b == lib'.systems.types.cpus.wasm32
== lib'.systems.types.cpus.wasm32
&& lib'.systems.validate.compatible a lib'.systems.types.cpus.wasm64 && lib'.systems.validate.compatible a lib'.systems.types.cpus.wasm64
) )
@ -1186,13 +1172,8 @@ in {
name = "Cpu"; name = "Cpu";
description = "Instruction set architecture name and information"; description = "Instruction set architecture name and information";
merge = lib.options.merge.one; merge = lib.options.merge.one;
check = x: check =
types.bits.check x.bits x: types.bits.check x.bits && (if 8 < x.bits then types.endian.check x.endian else !(x ? endian));
&& (
if 8 < x.bits
then types.endian.check x.endian
else !(x ? endian)
);
}; };
family = lib.types.create { family = lib.types.create {
@ -1211,7 +1192,8 @@ in {
name = "Kernel"; name = "Kernel";
description = "Kernel name and information"; description = "Kernel name and information";
merge = lib.options.merge.one; merge = lib.options.merge.one;
check = value: check =
value:
types.exec.check value.exec && builtins.all types.family.check (builtins.attrValues value.families); types.exec.check value.exec && builtins.all types.family.check (builtins.attrValues value.families);
}; };
@ -1232,7 +1214,8 @@ in {
name = "system"; name = "system";
description = "fully parsed representation of llvm- or nix-style platform tuple"; description = "fully parsed representation of llvm- or nix-style platform tuple";
merge = lib.options.merge.one; merge = lib.options.merge.one;
check = { check =
{
cpu, cpu,
vendor, vendor,
kernel, kernel,
@ -1249,7 +1232,8 @@ in {
name = "systemWithBuildInfo"; name = "systemWithBuildInfo";
description = "fully parsed representation of llvm- or nix-style platform tuple with build information"; description = "fully parsed representation of llvm- or nix-style platform tuple with build information";
merge = lib.options.merge.one; merge = lib.options.merge.one;
check = value: check =
value:
lib.types.is "systemWithBuildInfo" value lib.types.is "systemWithBuildInfo" value
&& value ? system && value ? system
&& lib'.systems.types.platform.check value.system; && lib'.systems.types.platform.check value.system;
@ -1774,19 +1758,27 @@ in {
}; };
from = { from = {
string = value: let string =
value:
let
parts = lib.strings.split "-" value; parts = lib.strings.split "-" value;
skeleton = lib'.systems.skeleton parts; skeleton = lib'.systems.skeleton parts;
system = lib'.systems.create (lib'.systems.from.skeleton skeleton); system = lib'.systems.create (lib'.systems.from.skeleton skeleton);
in in
system; system;
skeleton = spec @ { skeleton =
spec@{
cpu, cpu,
vendor ? assert false; null, vendor ?
assert false;
null,
kernel, kernel,
abi ? assert false; null, abi ?
}: let assert false;
null,
}:
let
getCpu = name: types.cpus.${name} or (throw "Unknown CPU type: ${name}"); getCpu = name: types.cpus.${name} or (throw "Unknown CPU type: ${name}");
getVendor = name: types.vendors.${name} or (throw "Unknown vendor: ${name}"); getVendor = name: types.vendors.${name} or (throw "Unknown vendor: ${name}");
getKernel = name: types.kernels.${name} or (throw "Unknown kernel: ${name}"); getKernel = name: types.kernels.${name} or (throw "Unknown kernel: ${name}");
@ -1796,62 +1788,67 @@ in {
cpu = getCpu spec.cpu; cpu = getCpu spec.cpu;
vendor = vendor =
if spec ? vendor if spec ? vendor then
then getVendor spec.vendor getVendor spec.vendor
else if lib'.systems.match.isDarwin resolved else if lib'.systems.match.isDarwin resolved then
then types.vendors.apple types.vendors.apple
else if lib'.systems.match.isWindows resolved else if lib'.systems.match.isWindows resolved then
then types.vendors.pc types.vendors.pc
else types.vendors.unknown; else
types.vendors.unknown;
kernel = kernel =
if lib.strings.hasPrefix "darwin" spec.kernel if lib.strings.hasPrefix "darwin" spec.kernel then
then getKernel "darwin" getKernel "darwin"
else if lib.strings.hasPrefix "netbsd" spec.kernel else if lib.strings.hasPrefix "netbsd" spec.kernel then
then getKernel "netbsd" getKernel "netbsd"
else getKernel spec.kernel; else
getKernel spec.kernel;
abi = abi =
if spec ? abi if spec ? abi then
then getAbi spec.abi getAbi spec.abi
else if lib'.systems.match.isLinux resolved || lib'.systems.match.isWindows resolved else if lib'.systems.match.isLinux resolved || lib'.systems.match.isWindows resolved then
then if lib'.systems.match.isAarch32 resolved then
if lib'.systems.match.isAarch32 resolved if lib.versions.gte "6" (resolved.cpu.version) then types.abis.gnueabihf else types.abis.gnueabi
then else if lib'.systems.match.isPower64 resolved && lib'.systems.match.isBigEndian resolved then
if lib.versions.gte "6" (resolved.cpu.version) types.abis.gnuabielfv2
then types.abis.gnueabihf else
else types.abis.gnueabi types.abis.gnu
else if lib'.systems.match.isPower64 resolved && lib'.systems.match.isBigEndian resolved else
then types.abis.gnuabielfv2 types.abis.unknown;
else types.abis.gnu
else types.abis.unknown;
}; };
in in
resolved; resolved;
}; };
into = { into = {
double = { double =
{
cpu, cpu,
kernel, kernel,
abi, abi,
... ...
}: let }:
let
kernelName = kernel.name + builtins.toString (kernel.version or ""); kernelName = kernel.name + builtins.toString (kernel.version or "");
in in
if abi == types.abis.cygnus if abi == types.abis.cygnus then
then "${cpu.name}-cygwin" "${cpu.name}-cygwin"
else if kernel.families ? darwin else if kernel.families ? darwin then
then "${cpu.name}-darwin" "${cpu.name}-darwin"
else "${cpu.name}-${kernelName}"; else
"${cpu.name}-${kernelName}";
triple = { triple =
{
cpu, cpu,
vendor, vendor,
kernel, kernel,
abi, abi,
... ...
}: let }:
let
kernelName = kernel.name + builtins.toString (kernel.version or ""); kernelName = kernel.name + builtins.toString (kernel.version or "");
netbsdExec = netbsdExec =
if if
@ -1859,19 +1856,25 @@ in {
|| (cpu.family == "sparc" && cpu.bits == 32) || (cpu.family == "sparc" && cpu.bits == 32)
|| (cpu.family == "m68k" && cpu.bits == 32) || (cpu.family == "m68k" && cpu.bits == 32)
|| (cpu.family == "x86" && cpu.bits == 32) || (cpu.family == "x86" && cpu.bits == 32)
then types.execs.aout then
else types.execs.elf; types.execs.aout
else
types.execs.elf;
exec = lib.strings.when (kernel.name == "netbsd" && netbsdExec != kernel.exec) kernel.exec.name; exec = lib.strings.when (kernel.name == "netbsd" && netbsdExec != kernel.exec) kernel.exec.name;
abi' = lib.strings.when (abi != types.abis.unknown) "-${abi.name}"; abi' = lib.strings.when (abi != types.abis.unknown) "-${abi.name}";
in "${cpu.name}-${vendor.name}-${kernelName}${exec}${abi'}"; in
"${cpu.name}-${vendor.name}-${kernelName}${exec}${abi'}";
}; };
create = components: create =
components:
assert types.platform.check components; assert types.platform.check components;
lib.types.set "system" components; lib.types.set "system" components;
skeleton = parts: let skeleton =
parts:
let
length = builtins.length parts; length = builtins.length parts;
first = builtins.elemAt parts 0; first = builtins.elemAt parts 0;
@ -1879,52 +1882,51 @@ in {
third = builtins.elemAt parts 2; third = builtins.elemAt parts 2;
fourth = builtins.elemAt parts 3; fourth = builtins.elemAt parts 3;
in in
if length == 1 if length == 1 then
then if first == "avr" then
if first == "avr" {
then {
cpu = first; cpu = first;
kernel = "none"; kernel = "none";
abi = "unknown"; abi = "unknown";
} }
else builtins.throw "Target specification with 1 component is ambiguous." else
else if length == 2 builtins.throw "Target specification with 1 component is ambiguous."
then else if length == 2 then
if second == "cygwin" if second == "cygwin" then
then { {
cpu = first; cpu = first;
kernel = "windows"; kernel = "windows";
abi = "cygnus"; abi = "cygnus";
} }
else if second == "windows" else if second == "windows" then
then { {
cpu = first; cpu = first;
kernel = "windows"; kernel = "windows";
abi = "msvc"; abi = "msvc";
} }
else if second == "elf" else if second == "elf" then
then { {
cpu = first; cpu = first;
vendor = "unkonwn"; vendor = "unkonwn";
kernel = "none"; kernel = "none";
abi = second; abi = second;
} }
else { else
{
cpu = first; cpu = first;
kernel = second; kernel = second;
} }
else if length == 3 else if length == 3 then
then
if if
second second == "linux"
== "linux"
|| (builtins.elem third [ || (builtins.elem third [
"eabi" "eabi"
"eabihf" "eabihf"
"elf" "elf"
"gnu" "gnu"
]) ])
then { then
{
cpu = first; cpu = first;
vendor = "unknown"; vendor = "unknown";
kernel = second; kernel = second;
@ -1942,23 +1944,23 @@ in {
"ghcjs" "ghcjs"
"mingw32" "mingw32"
]) ])
then { then
{
cpu = first; cpu = first;
vendor = second; vendor = second;
kernel = kernel = if third == "mingw32" then "windows" else third;
if third == "mingw32"
then "windows"
else third;
} }
else builtins.throw "Target specification with 3 components is ambiguous." else
else if length == 4 builtins.throw "Target specification with 3 components is ambiguous."
then { else if length == 4 then
{
cpu = first; cpu = first;
vendor = second; vendor = second;
kernel = third; kernel = third;
abi = fourth; abi = fourth;
} }
else builtins.throw "Invalid component count for creating system skeleton. Expected 1-4, but got ${builtins.toString length}."; else
builtins.throw "Invalid component count for creating system skeleton. Expected 1-4, but got ${builtins.toString length}.";
patterns = { patterns = {
isi686 = { isi686 = {
@ -2020,7 +2022,8 @@ in {
isArmv7 = isArmv7 =
map map
( (
{arch, ...}: { { arch, ... }:
{
cpu = { cpu = {
inherit arch; inherit arch;
}; };
@ -2540,19 +2543,14 @@ in {
]; ];
}; };
withBuildInfo = args: let withBuildInfo =
settings = args:
if builtins.isString args let
then {system = args;} settings = if builtins.isString args then { system = args; } else args;
else args;
resolved = resolved =
{ {
system = lib'.systems.from.string ( system = lib'.systems.from.string (if settings ? triple then settings.triple else settings.system);
if settings ? triple
then settings.triple
else settings.system
);
inherit inherit
( (
@ -2571,7 +2569,8 @@ in {
double = lib'.systems.into.double resolved.system; double = lib'.systems.into.double resolved.system;
triple = lib'.systems.into.triple resolved.system; triple = lib'.systems.into.triple resolved.system;
isExecutable = platform: isExecutable =
platform:
(resolved.isAndroid == platform.isAndroid) (resolved.isAndroid == platform.isAndroid)
&& resolved.system.kernel == platform.system.kernel && resolved.system.kernel == platform.system.kernel
&& lib'.systems.validate.compatible resolved.system.cpu platform.system.cpu; && lib'.systems.validate.compatible resolved.system.cpu platform.system.cpu;
@ -2609,95 +2608,87 @@ in {
); );
libc = libc =
if resolved.isDarwin if resolved.isDarwin then
then "libSystem" "libSystem"
else if resolved.isMinGW else if resolved.isMinGW then
then "msvcrt" "msvcrt"
else if resolved.isWasi else if resolved.isWasi then
then "wasilibc" "wasilibc"
else if resolved.isRedox else if resolved.isRedox then
then "relibc" "relibc"
else if resolved.isMusl else if resolved.isMusl then
then "musl" "musl"
else if resolved.isUClibc else if resolved.isUClibc then
then "uclibc" "uclibc"
else if resolved.isAndroid else if resolved.isAndroid then
then "bionic" "bionic"
else if resolved.isLinux else if resolved.isLinux then
then "glibc" "glibc"
else if resolved.isFreeBSD else if resolved.isFreeBSD then
then "fblibc" "fblibc"
else if resolved.isNetBSD else if resolved.isNetBSD then
then "nblibc" "nblibc"
else if resolved.isAvr else if resolved.isAvr then
then "avrlibc" "avrlibc"
else if resolved.isGhcjs else if resolved.isGhcjs then
then null null
else if resolved.isNone else if resolved.isNone then
then "newlib" "newlib"
else "native/impure"; else
"native/impure";
linker = linker = if resolved.isDarwin then "cctools" else "bfd";
if resolved.isDarwin
then "cctools"
else "bfd";
extensions = extensions =
(lib.attrs.when resolved.hasSharedLibraries { (lib.attrs.when resolved.hasSharedLibraries {
shared = shared =
if resolved.isDarwin if resolved.isDarwin then
then ".dylib" ".dylib"
else if resolved.isWindows else if resolved.isWindows then
then ".dll" ".dll"
else ".so"; else
".so";
}) })
// { // {
static = static = if resolved.isWindows then ".lib" else ".a";
if resolved.isWindows
then ".lib"
else ".a";
library = library = if resolved.isStatic then resolved.extensions.static else resolved.extensions.shared;
if resolved.isStatic
then resolved.extensions.static
else resolved.extensions.shared;
executable = executable = if resolved.isWindows then ".exe" else "";
if resolved.isWindows
then ".exe"
else "";
}; };
uname = { uname = {
system = system =
if resolved.system.kernel.name == "linux" if resolved.system.kernel.name == "linux" then
then "Linux" "Linux"
else if resolved.system.kernel.name == "windows" else if resolved.system.kernel.name == "windows" then
then "Windows" "Windows"
else if resolved.system.kernel.name == "darwin" else if resolved.system.kernel.name == "darwin" then
then "Darwin" "Darwin"
else if resolved.system.kernel.name == "netbsd" else if resolved.system.kernel.name == "netbsd" then
then "NetBSD" "NetBSD"
else if resolved.system.kernel.name == "freebsd" else if resolved.system.kernel.name == "freebsd" then
then "FreeBSD" "FreeBSD"
else if resolved.system.kernel.name == "openbsd" else if resolved.system.kernel.name == "openbsd" then
then "OpenBSD" "OpenBSD"
else if resolved.system.kernel.name == "wasi" else if resolved.system.kernel.name == "wasi" then
then "Wasi" "Wasi"
else if resolved.system.kernel.name == "redox" else if resolved.system.kernel.name == "redox" then
then "Redox" "Redox"
else if resolved.system.kernel.name == "redox" else if resolved.system.kernel.name == "redox" then
then "Genode" "Genode"
else null; else
null;
processor = processor =
if resolved.isPower64 if resolved.isPower64 then
then "ppc64${lib.strings.when resolved.isLittleEndian "le"}" "ppc64${lib.strings.when resolved.isLittleEndian "le"}"
else if resolved.isPower else if resolved.isPower then
then "ppc${lib.strings.when resolved.isLittleEndian "le"}" "ppc${lib.strings.when resolved.isLittleEndian "le"}"
else if resolved.isMips64 else if resolved.isMips64 then
then "mips64" "mips64"
else resolved.system.cpu.name; else
resolved.system.cpu.name;
release = null; release = null;
}; };
@ -2706,117 +2697,109 @@ in {
useiOSPrebuilt = false; useiOSPrebuilt = false;
linux.arch = linux.arch =
if resolved.isAarch32 if resolved.isAarch32 then
then "arm" "arm"
else if resolved.isAarch64 else if resolved.isAarch64 then
then "arm64" "arm64"
else if resolved.isx86_32 else if resolved.isx86_32 then
then "i386" "i386"
else if resolved.isx86_64 else if resolved.isx86_64 then
then "x86_64" "x86_64"
# linux kernel does not distinguish microblaze/microblazeel # linux kernel does not distinguish microblaze/microblazeel
else if resolved.isMicroBlaze else if resolved.isMicroBlaze then
then "microblaze" "microblaze"
else if resolved.isMips32 else if resolved.isMips32 then
then "mips" "mips"
else if resolved.isMips64 else if resolved.isMips64 then
then "mips" # linux kernel does not distinguish mips32/mips64 "mips" # linux kernel does not distinguish mips32/mips64
else if resolved.isPower else if resolved.isPower then
then "powerpc" "powerpc"
else if resolved.isRiscV else if resolved.isRiscV then
then "riscv" "riscv"
else if resolved.isS390 else if resolved.isS390 then
then "s390" "s390"
else if resolved.isLoongArch64 else if resolved.isLoongArch64 then
then "loongarch" "loongarch"
else resolved.system.cpu.name; else
resolved.system.cpu.name;
uboot.arch = uboot.arch =
if resolved.isx86_32 if resolved.isx86_32 then
then "x86" # not i386 "x86" # not i386
else if resolved.isMips64 else if resolved.isMips64 then
then "mips64" # uboot *does* distinguish between mips32/mips64 "mips64" # uboot *does* distinguish between mips32/mips64
else resolved.linux.arch; # other cases appear to agree with linuxArch else
resolved.linux.arch; # other cases appear to agree with linuxArch
qemu.arch = qemu.arch =
if resolved.isAarch32 if resolved.isAarch32 then
then "arm" "arm"
else if resolved.isS390 && !resolved.isS390x else if resolved.isS390 && !resolved.isS390x then
then null null
else if resolved.isx86_64 else if resolved.isx86_64 then
then "x86_64" "x86_64"
else if resolved.isx86 else if resolved.isx86 then
then "i386" "i386"
else if resolved.isMips64n32 else if resolved.isMips64n32 then
then "mipsn32${lib.strings.when resolved.isLittleEndian "el"}" "mipsn32${lib.strings.when resolved.isLittleEndian "el"}"
else if resolved.isMips64 else if resolved.isMips64 then
then "mips64${lib.strings.when resolved.isLittleEndian "el"}" "mips64${lib.strings.when resolved.isLittleEndian "el"}"
else resolved.uname.processor; else
resolved.uname.processor;
efi.arch = efi.arch =
if resolved.isx86_32 if resolved.isx86_32 then
then "ia32" "ia32"
else if resolved.isx86_64 else if resolved.isx86_64 then
then "x64" "x64"
else if resolved.isAarch32 else if resolved.isAarch32 then
then "arm" "arm"
else if resolved.isAarch64 else if resolved.isAarch64 then
then "aa64" "aa64"
else resolved.system.cpu.name; else
resolved.system.cpu.name;
darwin = { darwin = {
arch = arch =
if resolved.system.cpu.name == "armv7a" if resolved.system.cpu.name == "armv7a" then
then "armv7" "armv7"
else if resolved.system.cpu.name == "aarch64" else if resolved.system.cpu.name == "aarch64" then
then "arm64" "arm64"
else resolved.system.cpu.name; else
resolved.system.cpu.name;
platform = platform =
if resolved.isMacOS if resolved.isMacOS then
then "macos" "macos"
else if resolved.isiOS else if resolved.isiOS then
then "ios" "ios"
else null; else
null;
sdk = { sdk = {
version = version = resolved.darwinSdkVersion or (if resolved.isAarch64 then "11.0" else "10.12");
resolved.darwinSdkVersion
or (
if resolved.isAarch64
then "11.0"
else "10.12"
);
min = resolved.darwin.sdk.version; min = resolved.darwin.sdk.version;
variable = variable =
if resolved.isMacOS if resolved.isMacOS then
then "MACOSX_DEPLOYMENT_TARGET" "MACOSX_DEPLOYMENT_TARGET"
else if resolved.isiOS else if resolved.isiOS then
then "IPHONEOS_DEPLOYMENT_TARGET" "IPHONEOS_DEPLOYMENT_TARGET"
else null; else
null;
}; };
}; };
} }
// builtins.mapAttrs (name: match: match resolved.system) lib'.systems.match // builtins.mapAttrs (name: match: match resolved.system) lib'.systems.match
// builtins.mapAttrs ( // builtins.mapAttrs (
name: validate: validate (resolved.gcc.arch or "default") name: validate: validate (resolved.gcc.arch or "default")
) ) lib'.systems.validate.architecture
lib'.systems.validate.architecture
// (builtins.removeAttrs settings [ "system" ]); // (builtins.removeAttrs settings [ "system" ]);
assertions = assertions = builtins.foldl' (
builtins.foldl' ( result: { assertion, message }: if assertion resolved then result else builtins.throw message
result: { ) true (resolved.system.abi.assertions or [ ]);
assertion,
message,
}:
if assertion resolved
then result
else builtins.throw message
)
true (resolved.system.abi.assertions or []);
in in
assert resolved.useAndroidPrebuilt -> resolved.isAndroid; assert resolved.useAndroidPrebuilt -> resolved.isAndroid;
assert assertions; assert assertions;

View file

@ -1,16 +1,17 @@
{ { lib, config }:
lib, let
config,
}: let
inherit (config) preferences builders; inherit (config) preferences builders;
lib' = config.lib; lib' = config.lib;
in { in
{
config = { config = {
lib.types = { lib.types = {
license = let license =
let
type = lib.types.submodule ( type = lib.types.submodule (
{config}: { { config }:
{
options = { options = {
name = { name = {
full = lib.options.create { full = lib.options.create {
@ -56,9 +57,7 @@ in {
lib.types.either type (lib.types.list.of type); lib.types.either type (lib.types.list.of type);
platform = platform =
lib.types.coerce lib.types.coerce lib.types.string lib'.systems.withBuildInfo
lib.types.string
lib'.systems.withBuildInfo
lib'.systems.types.platformWithBuildInfo; lib'.systems.types.platformWithBuildInfo;
builder = lib.types.submodule { builder = lib.types.submodule {
@ -74,10 +73,14 @@ in {
packages = lib.types.attrs.of (lib.types.attrs.of lib'.types.alias); packages = lib.types.attrs.of (lib.types.attrs.of lib'.types.alias);
dependencies = build: host: target: let dependencies =
build: host: target:
let
initial = lib.types.raw; initial = lib.types.raw;
transform = value: let transform =
value:
let
package = lib'.packages.resolve value; package = lib'.packages.resolve value;
in in
lib'.packages.build package build host target; lib'.packages.build package build host target;
@ -104,46 +107,48 @@ in {
}; };
}; };
package = let package =
normalize = value: let
if builtins.isFunction value || builtins.isList value normalize =
then value value:
else if value ? __modules__ if builtins.isFunction value || builtins.isList value then
then value.__modules__ value
else { else if value ? __modules__ then
config = value; value.__modules__
}; else
{ config = value; };
initial = lib.types.create { initial = lib.types.create {
name = "PackageConfig"; name = "PackageConfig";
description = "configuration for a package"; description = "configuration for a package";
check = value: builtins.isFunction value || builtins.isAttrs value || builtins.isList value; check = value: builtins.isFunction value || builtins.isAttrs value || builtins.isList value;
merge = location: definitions: let merge =
normalized = location: definitions:
builtins.map let
(definition: lib.lists.from.any (normalize definition.value)) normalized = builtins.map (definition: lib.lists.from.any (normalize definition.value)) definitions;
definitions;
in in
builtins.concatLists builtins.concatLists normalized;
normalized;
}; };
transform = location: value: let transform =
modules = location: value:
lib.lists.from.any (normalize value); let
modules = lib.lists.from.any (normalize value);
result = lib.modules.run { result = lib.modules.run {
prefix = location; prefix = location;
modules = modules = modules ++ [
modules submodule
++ [submodule {config.__modules__ = modules;}]; { config.__modules__ = modules; }
];
}; };
in in
result.config; result.config;
final = lib.types.raw; final = lib.types.raw;
deps = build: host: target: deps =
build: host: target:
lib.types.submodule { lib.types.submodule {
options = { options = {
build = { build = {
@ -208,18 +213,18 @@ in {
}; };
}; };
submodule = {config}: let submodule =
{ config }:
let
build = config.platform.build; build = config.platform.build;
host = config.platform.host; host = config.platform.host;
target = config.platform.target; target = config.platform.target;
in { in
{
options = { options = {
__modules__ = lib.options.create { __modules__ = lib.options.create {
description = "User specified modules for the package definition."; description = "User specified modules for the package definition.";
type = lib.types.list.of (initial type = lib.types.list.of (initial // { merge = lib.options.merge.one; });
// {
merge = lib.options.merge.one;
});
# writable = false; # writable = false;
internal = true; internal = true;
default.value = [ ]; default.value = [ ];
@ -301,9 +306,7 @@ in {
default = { default = {
text = "\${config.pname}-\${config.version}"; text = "\${config.pname}-\${config.version}";
value = value =
if config.pname != null && config.version != null if config.pname != null && config.version != null then "${config.pname}-${config.version}" else "";
then "${config.pname}-${config.version}"
else "";
}; };
}; };
@ -367,18 +370,14 @@ in {
}; };
}; };
type = type = (lib.types.coerceWithLocation initial transform final) // {
(lib.types.coerceWithLocation initial transform final)
// {
name = "Package"; name = "Package";
description = "a package definition"; description = "a package definition";
}; };
in in
type type
// { // {
children = children = type.children // {
type.children
// {
inherit submodule; inherit submodule;
}; };
}; };

View file

@ -1,12 +1,13 @@
{ { lib', config }:
lib', let
config,
}: let
inherit (config) builders packages; inherit (config) builders packages;
in { in
{
config.packages.aux.a = { config.packages.aux.a = {
versions = { versions = {
"latest" = {config}: { "latest" =
{ config }:
{
config = { config = {
meta = { meta = {
platforms = [ "i686-linux" ]; platforms = [ "i686-linux" ];

View file

@ -1,13 +1,15 @@
{config}: let { config }:
let
inherit (config) lib builders packages; inherit (config) lib builders packages;
in { in
{
config.packages.aux.b = { config.packages.aux.b = {
versions = { versions = {
"latest" = {config}: { "latest" =
{ config }:
{
options = { options = {
custom = lib.options.create { custom = lib.options.create { type = lib.types.bool; };
type = lib.types.bool;
};
}; };
config = { config = {

View file

@ -1,10 +1,12 @@
{config}: let { config }:
let
inherit (config) lib; inherit (config) lib;
doubles = lib.systems.doubles.all; doubles = lib.systems.doubles.all;
packages = builtins.removeAttrs config.packages [ "cross" ]; packages = builtins.removeAttrs config.packages [ "cross" ];
in { in
{
includes = [ includes = [
./foundation ./foundation
./aux/a.nix ./aux/a.nix
@ -45,9 +47,12 @@ in {
builtins.mapAttrs ( builtins.mapAttrs (
namespace: namespace:
builtins.mapAttrs ( builtins.mapAttrs (
name: alias: let name: alias:
setHost = package: let
package // { setHost =
package:
package
// {
__modules__ = package.__modules__ ++ [ __modules__ = package.__modules__ ++ [
{ {
config.platform = { config.platform = {
@ -90,15 +95,12 @@ in {
# .config # .config
# else package; # else package;
updated = updated = alias // {
alias
// {
versions = builtins.mapAttrs (version: package: setHost package) alias.versions; versions = builtins.mapAttrs (version: package: setHost package) alias.versions;
}; };
in in
updated updated
) )
) ) packages
packages
); );
} }

View file

@ -3,9 +3,9 @@
lib', lib',
config, config,
options, options,
}: let }:
inherit let
(config) inherit (config)
mirrors mirrors
builders builders
# These are the upstream foundational packages exported from the Aux Foundation project. # These are the upstream foundational packages exported from the Aux Foundation project.
@ -13,10 +13,13 @@
foundation foundation
packages packages
; ;
in { in
{
config.packages.foundation.binutils = { config.packages.foundation.binutils = {
versions = { versions = {
"latest" = {config}: { "latest" =
{ config }:
{
options = { options = {
src = lib.options.create { src = lib.options.create {
type = lib.types.derivation; type = lib.types.derivation;
@ -58,7 +61,8 @@ in {
]; ];
}; };
phases = let phases =
let
patches = [ patches = [
# Make binutils output deterministic by default. # Make binutils output deterministic by default.
./patches/deterministic.patch ./patches/deterministic.patch
@ -89,7 +93,8 @@ in {
"--disable-multilib" "--disable-multilib"
]; ];
in { in
{
unpack = '' unpack = ''
tar xf ${config.src} tar xf ${config.src}
cd binutils-${config.version} cd binutils-${config.version}

View file

@ -3,7 +3,8 @@
lib', lib',
config, config,
options, options,
}: { }:
{
includes = [ includes = [
./gcc ./gcc
./binutils ./binutils

View file

@ -1,9 +1,6 @@
{ { config, options }:
config, let
options, inherit (config)
}: let
inherit
(config)
lib lib
mirrors mirrors
builders builders
@ -12,13 +9,13 @@
foundation foundation
packages packages
; ;
in { in
{
config.packages.foundation.gcc = { config.packages.foundation.gcc = {
versions = { versions = {
"latest" = { "latest" =
config, { config, meta }:
meta, {
}: {
options = { options = {
src = lib.options.create { src = lib.options.create {
type = lib.types.derivation; type = lib.types.derivation;
@ -107,17 +104,13 @@ in {
]; ];
}; };
phases = let phases =
let
host = lib.systems.withBuildInfo config.platform.host; host = lib.systems.withBuildInfo config.platform.host;
mbits = mbits = if host.system.cpu.family == "x86" then if host.is64bit then "-m64" else "-m32" else "";
if host.system.cpu.family == "x86" in
then {
if host.is64bit
then "-m64"
else "-m32"
else "";
in {
unpack = '' unpack = ''
# Unpack # Unpack
tar xf ${config.src} tar xf ${config.src}

View file

@ -3,22 +3,22 @@
lib', lib',
config, config,
options, options,
}: let }:
inherit let
(config) inherit (config)
mirrors mirrors
builders builders
# These are the upstream foundational packages exported from the Aux Foundation project. # These are the upstream foundational packages exported from the Aux Foundation project.
foundation foundation
; ;
in { in
{
config.packages.foundation.linux-headers = { config.packages.foundation.linux-headers = {
versions = { versions = {
"latest" = { "latest" =
config, { config, meta }:
meta, {
}: {
options = { options = {
src = lib.options.create { src = lib.options.create {
type = lib.types.derivation; type = lib.types.derivation;