Compare commits

..

No commits in common. "93157512205af050b96e9f84ce7d90f425906c51" and "af571a03a4c37f98e44aa4ab37d499a7ffc0c77c" have entirely different histories.

15 changed files with 2325 additions and 2372 deletions

View file

@ -4,9 +4,7 @@ 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 = default = location: definitions: let
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);
@ -15,34 +13,29 @@ 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 then if builtins.length values == 1
builtins.elemAt values 0 then builtins.elemAt values 0
else if builtins.all builtins.isFunction values then else if builtins.all builtins.isFunction values
mergedFunctions then mergedFunctions
else if builtins.all builtins.isList values then else if builtins.all builtins.isList values
mergedLists then mergedLists
else if builtins.all builtins.isAttrs values then else if builtins.all builtins.isAttrs values
mergedAttrs then mergedAttrs
else if builtins.all builtins.isBool values then else if builtins.all builtins.isBool values
mergedBools then mergedBools
else if builtins.all lib.strings.isString values then else if builtins.all lib.strings.isString values
mergedStrings then mergedStrings
else if builtins.all builtins.isInt values && builtins.all (x: x == first) values then else if builtins.all builtins.isInt values && builtins.all (x: x == first) values
first then 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 else builtins.throw "Cannot merge definitions.";
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 = definitions = location: type: definitions: let
location: type: definitions:
let
identifier = lib.options.getIdentifier location; identifier = lib.options.getIdentifier location;
resolve = resolve = definition: let
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
); );
@ -57,27 +50,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 then if builtins.any (definition: lib.types.is "order" definition.value) overridden.values
lib.modules.apply.order overridden.values then lib.modules.apply.order overridden.values
else else overridden.values;
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 then if isDefined
if builtins.all (definition: type.check definition.value) values then then
type.merge location values if builtins.all (definition: type.check definition.value) values
else then type.merge location values
builtins.throw "A definition for `${identifier}` is not of type `${type.description}`. Definition values:${lib.options.getDefinitions invalid}" else builtins.throw "A definition for `${identifier}` is not of type `${type.description}`. Definition values:${lib.options.getDefinitions invalid}"
else else builtins.throw "The option `${identifier}` is used but not defined.";
builtins.throw "The option `${identifier}` is used but not defined.";
optional = if isDefined then { value = merged; } else { }; optional =
in if isDefined
{ then {value = merged;}
else {};
in {
inherit inherit
isDefined isDefined
values values
@ -94,12 +87,8 @@ lib: {
## Merge multiple option declarations together. ## Merge multiple option declarations together.
## ##
## @type Location -> List Option ## @type Location -> List Option
declarations = declarations = location: options: let
location: options: merge = result: option: let
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};
@ -108,14 +97,15 @@ 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 then if getSubModules != null
then
builtins.map (module: { builtins.map (module: {
__file__ = option.__file__; __file__ = option.__file__;
includes = [module]; includes = [module];
}) getSubModules })
getSubModules
++ result.options ++ result.options
else else result.options;
result.options;
in in
if if
shared "default" shared "default"
@ -123,8 +113,7 @@ lib: {
|| shared "description" || shared "description"
|| shared "apply" || shared "apply"
|| (shared "type" && !isTypeMergeable) || (shared "type" && !isTypeMergeable)
then then builtins.throw "The option `${lib.options.getIdentifier location}` in `${option.__file__}` is already declared in ${serializedFiles}"
builtins.throw "The option `${lib.options.getIdentifier location}` in `${option.__file__}` is already declared in ${serializedFiles}"
else else
option.options option.options
// result // result
@ -138,50 +127,43 @@ 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 = unique = message: location: definitions: let
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 then if total == 1
first.value then first.value
else if total == 0 then else if total == 0
builtins.throw "Cannot merge unused option `${identifier}`.\n${message}" then builtins.throw "Cannot merge unused option `${identifier}`.\n${message}"
else else builtins.throw "The option `${identifier}` is defined multiple times, but must be unique.\n${message}\nDefinitions:${lib.options.getDefinitions definitions}";
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 = equal = location: definitions: let
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 = merge = x: y:
x: y: if x != y
if x != y then then builtins.throw "The option `${identifier}` has conflicting definitions:${lib.options.getDefinitions definitions}"
builtins.throw "The option `${identifier}` has conflicting definitions:${lib.options.getDefinitions definitions}" else x;
else
x;
merged = builtins.foldl' merge first rest; merged = builtins.foldl' merge first rest;
in in
if builtins.length definitions == 0 then if builtins.length definitions == 0
builtins.throw "Cannot merge unused option `${identifier}`." then builtins.throw "Cannot merge unused option `${identifier}`."
else if builtins.length definitions == 1 then else if builtins.length definitions == 1
first.value then first.value
else else merged.value;
merged.value;
}; };
## Check whether a value is an option. ## Check whether a value is an option.
@ -192,8 +174,7 @@ 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 = create = settings @ {
settings@{
type ? lib.types.unspecified, type ? lib.types.unspecified,
apply ? null, apply ? null,
default ? {}, default ? {},
@ -202,8 +183,7 @@ lib: {
internal ? null, internal ? null,
writable ? null, writable ? null,
description ? null, description ? null,
}: }: {
{
__type__ = "option"; __type__ = "option";
inherit inherit
type type
@ -220,9 +200,7 @@ lib: {
## Create a sink option. ## Create a sink option.
## ##
## @type @alias lib.options.create ## @type @alias lib.options.create
sink = sink = settings: let
settings:
let
defaults = { defaults = {
internal = true; internal = true;
visible = false; visible = false;
@ -246,9 +224,7 @@ 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 = getIdentifier = location: let
location:
let
special = [ special = [
# lib.types.attrs.of (lib.types.submodule {}) # lib.types.attrs.of (lib.types.submodule {})
"<name>" "<name>"
@ -257,23 +233,24 @@ lib: {
# lib.types.function # lib.types.function
"<function body>" "<function body>"
]; ];
escape = part: if builtins.elem part special then part else lib.strings.escape.nix.identifier part; escape = 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 = getDefinitions = definitions: let
definitions: serialize = definition: let
let valueWithRecursionLimit =
serialize = lib.generators.withRecursion {
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);
@ -286,27 +263,24 @@ lib: {
value = builtins.concatStringsSep "\n " (firstFiveLines ++ ellipsis); value = builtins.concatStringsSep "\n " (firstFiveLines ++ ellipsis);
result = result =
if !eval.success then if !eval.success
"" then ""
else if linesLength > 1 then else if linesLength > 1
":\n " + value then ":\n " + value
else else ": " + value;
": " + value; in "\n- In `${definition.__file__}`${result}";
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 = run = location: option: definitions: let
location: option: definitions:
let
identifier = lib.options.getIdentifier location; identifier = lib.options.getIdentifier location;
definitionsWithDefault = definitionsWithDefault =
if option ? default && option.default ? value then if option ? default && option.default ? value
then
[ [
{ {
__file__ = builtins.head option.declarations; __file__ = builtins.head option.declarations;
@ -314,25 +288,28 @@ lib: {
} }
] ]
++ definitions ++ definitions
else else definitions;
definitions;
merged = merged =
if option.writable or null == false && builtins.length definitionsWithDefault > 1 then if option.writable or null == false && builtins.length definitionsWithDefault > 1
let then let
separatedDefinitions = builtins.map ( separatedDefinitions =
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 else lib.options.merge.definitions location option.type definitionsWithDefault;
lib.options.merge.definitions location option.type definitionsWithDefault;
value = if option.apply or null != null then option.apply merged.merged else merged.merged; value =
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,19 +1,18 @@
{ lib, config }: {
let lib,
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 = build = package: let
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"] "";
@ -27,9 +26,14 @@ in
}; };
sorted = lib.dag.sort.topographic phases; sorted = lib.dag.sort.topographic phases;
script = lib.strings.concatMapSep "\n" ( script =
entry: if builtins.isFunction entry.value then entry.value package else entry.value lib.strings.concatMapSep "\n" (
) sorted.result; entry:
if builtins.isFunction entry.value
then entry.value package
else entry.value
)
sorted.result;
system = package.platform.build.double; system = package.platform.build.double;
@ -43,8 +47,7 @@ in
SHELL = cfg.executable; SHELL = cfg.executable;
PATH = PATH = let
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,10 +1,8 @@
# 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 }: {config}: let
let
inherit (config) lib; inherit (config) lib;
in in {
{
# freeform = lib.types.any; # freeform = lib.types.any;
config = { config = {
@ -26,7 +24,6 @@ in
# .config; # .config;
foundation-gcc = config.packages.foundation.gcc; foundation-gcc = config.packages.foundation.gcc;
foundation-binutils = config.packages.foundation.binutils; foundation-binutils = config.packages.foundation.binutils;
foundation-linux-headers = config.packages.foundation.linux-headers;
# foundation-linux-headers = config.packages.foundation.linux-headers.versions.latest.extend { # foundation-linux-headers = config.packages.foundation.linux-headers.versions.latest.extend {
# platform.host = lib.modules.overrides.force "x86_64-linux"; # platform.host = lib.modules.overrides.force "x86_64-linux";
# }; # };

View file

@ -1,7 +1,8 @@
{ 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,48 +1,41 @@
{ lib, config }:
let
lib' = config.lib;
in
{ {
lib,
config,
}: let
lib' = config.lib;
in {
config = { config = {
lib.packages = { lib.packages = {
dependencies = { dependencies = {
getPackages = getPackages = dependencies: let
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 = build': host': target':
build': host': target': builtins.mapAttrs
builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target'); (name: dep: lib'.packages.build dep build' host' target');
}; };
getLatest = getLatest = alias: let
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 = resolve = alias:
alias: if alias ? versions
if alias ? versions then 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 else alias;
alias;
build = build = alias: build: host: target: let
alias: build: host: target:
let
package = lib'.packages.resolve alias; package = lib'.packages.resolve alias;
buildDependencies = buildDependencies = build': host': target':
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 = {
@ -52,11 +45,12 @@ in
}; };
withPlatform = lib.modules.run { withPlatform = lib.modules.run {
modules = package.__modules__ ++ [ modules =
package.__modules__
++ [
lib'.types.package.children.submodule lib'.types.package.children.submodule
( (
{ config }: {config}: {
{
config = { config = {
__modules__ = package.__modules__; __modules__ = package.__modules__;
@ -70,7 +64,9 @@ 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 = withPlatform.config // { withDeps =
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;
@ -91,11 +87,12 @@ in
}; };
withPackage = lib.modules.run { withPackage = lib.modules.run {
modules = package.__modules__ ++ [ 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 }: {
let lib,
config,
}: let
lib' = config.lib; lib' = config.lib;
types = config.lib.systems.types; types = config.lib.systems.types;
setTypes = setTypes = type: let
type: assign = name: value:
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 = matchAnyAttrs = patterns:
patterns: if builtins.isList patterns
if builtins.isList patterns then then
value: value:
builtins.any ( builtins.any (
pattern: if builtins.isFunction pattern then pattern value else matchAnyAttrs pattern value pattern:
) patterns if builtins.isFunction pattern
else then pattern value
lib.attrs.match patterns; else matchAnyAttrs pattern value
)
patterns
else lib.attrs.match patterns;
getDoubles = getDoubles = predicate:
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,44 +600,43 @@ 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 = select = platform:
platform:
# x86 # x86
if platform.isx86 then if platform.isx86
lib'.systems.platforms.pc then lib'.systems.platforms.pc
# ARM # ARM
else if platform.isAarch32 then else if platform.isAarch32
let then let
version = platform.system.cpu.version or null; version = platform.system.cpu.version or null;
in in
if version == null then if version == null
lib'.systems.platforms.pc then lib'.systems.platforms.pc
else if lib.versions.gte "6" version then else if lib.versions.gte "6" version
lib'.systems.platforms.sheevaplug then lib'.systems.platforms.sheevaplug
else if lib.versions.gte "7" version then else if lib.versions.gte "7" version
lib'.systems.platforms.raspberrypi then lib'.systems.platforms.raspberrypi
else else lib'.systems.platforms.armv7l-hf-multiplatform
lib'.systems.platforms.armv7l-hf-multiplatform else if platform.isAarch64
else if platform.isAarch64 then then
if platform.isDarwin then if platform.isDarwin
lib'.systems.platforms.apple-m1 then lib'.systems.platforms.apple-m1
else else lib'.systems.platforms.aarch64-multiplatform
lib'.systems.platforms.aarch64-multiplatform else if platform.isRiscV
else if platform.isRiscV then then lib'.systems.platforms.riscv-multiplatform
lib'.systems.platforms.riscv-multiplatform else if platform.system.cpu == types.cpus.mipsel
else if platform.system.cpu == types.cpus.mipsel then then lib'.systems.platforms.mipsel-linux-gnu
lib'.systems.platforms.mipsel-linux-gnu else if platform.system.cpu == types.cpus.powerpc64le
else if platform.system.cpu == types.cpus.powerpc64le then then lib'.systems.platforms.powernv
lib'.systems.platforms.powernv else {};
else
{ };
}; };
architectures = { architectures = {
@ -1028,11 +1027,9 @@ in
}; };
validate = { validate = {
architecture = architecture = let
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";
@ -1046,8 +1043,7 @@ in
fma4Support = isSupported "fma4"; fma4Support = isSupported "fma4";
}; };
compatible = compatible = a: b:
a: b:
lib.any lib.id [ lib.any lib.id [
# x86 # x86
( (
@ -1062,96 +1058,114 @@ in
# XXX: Not true in some cases. Like in WSL mode. # XXX: Not true in some cases. Like in WSL mode.
( (
b == lib'.systems.types.cpus.i686 b
== 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 == lib'.systems.types.cpus.arm b
== 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 == lib'.systems.types.cpus.armv5tel b
== 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 == lib'.systems.types.cpus.armv6l b
== 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 == lib'.systems.types.cpus.armv6m b
== 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 == lib'.systems.types.cpus.armv7l b
== 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 == lib'.systems.types.cpus.armv7l b
== 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 == lib'.systems.types.cpus.armv7l b
== 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 == lib'.systems.types.cpus.armv8a b
== 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 == lib'.systems.types.cpus.armv8r b
== 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 == lib'.systems.types.cpus.armv8m b
== 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 == lib'.systems.types.cpus.powerpc b
== 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 == lib'.systems.types.cpus.powerpcle b
== 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 == lib'.systems.types.cpus.mips b
== 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 == lib'.systems.types.cpus.mipsel b
== 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 == lib'.systems.types.cpus.riscv32 b
== 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 == lib'.systems.types.cpus.sparc b
== 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 == lib'.systems.types.cpus.wasm32 b
== 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
) )
@ -1172,8 +1186,13 @@ 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 = check = x:
x: types.bits.check x.bits && (if 8 < x.bits then types.endian.check x.endian else !(x ? endian)); types.bits.check x.bits
&& (
if 8 < x.bits
then types.endian.check x.endian
else !(x ? endian)
);
}; };
family = lib.types.create { family = lib.types.create {
@ -1192,8 +1211,7 @@ 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 = check = value:
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);
}; };
@ -1214,8 +1232,7 @@ 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,
@ -1232,8 +1249,7 @@ 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 = check = value:
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;
@ -1758,27 +1774,19 @@ in
}; };
from = { from = {
string = string = value: let
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 = skeleton = spec @ {
spec@{
cpu, cpu,
vendor ? vendor ? assert false; null,
assert false;
null,
kernel, kernel,
abi ? abi ? assert false; null,
assert false; }: let
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}");
@ -1788,67 +1796,62 @@ in
cpu = getCpu spec.cpu; cpu = getCpu spec.cpu;
vendor = vendor =
if spec ? vendor then if spec ? vendor
getVendor spec.vendor then getVendor spec.vendor
else if lib'.systems.match.isDarwin resolved then else if lib'.systems.match.isDarwin resolved
types.vendors.apple then types.vendors.apple
else if lib'.systems.match.isWindows resolved then else if lib'.systems.match.isWindows resolved
types.vendors.pc then types.vendors.pc
else else types.vendors.unknown;
types.vendors.unknown;
kernel = kernel =
if lib.strings.hasPrefix "darwin" spec.kernel then if lib.strings.hasPrefix "darwin" spec.kernel
getKernel "darwin" then getKernel "darwin"
else if lib.strings.hasPrefix "netbsd" spec.kernel then else if lib.strings.hasPrefix "netbsd" spec.kernel
getKernel "netbsd" then getKernel "netbsd"
else else getKernel spec.kernel;
getKernel spec.kernel;
abi = abi =
if spec ? abi then if spec ? abi
getAbi spec.abi then getAbi spec.abi
else if lib'.systems.match.isLinux resolved || lib'.systems.match.isWindows resolved then else if lib'.systems.match.isLinux resolved || lib'.systems.match.isWindows resolved
if lib'.systems.match.isAarch32 resolved then then
if lib.versions.gte "6" (resolved.cpu.version) then types.abis.gnueabihf else types.abis.gnueabi if lib'.systems.match.isAarch32 resolved
else if lib'.systems.match.isPower64 resolved && lib'.systems.match.isBigEndian resolved then then
types.abis.gnuabielfv2 if lib.versions.gte "6" (resolved.cpu.version)
else then types.abis.gnueabihf
types.abis.gnu else types.abis.gnueabi
else else if lib'.systems.match.isPower64 resolved && lib'.systems.match.isBigEndian resolved
types.abis.unknown; then types.abis.gnuabielfv2
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 then if abi == types.abis.cygnus
"${cpu.name}-cygwin" then "${cpu.name}-cygwin"
else if kernel.families ? darwin then else if kernel.families ? darwin
"${cpu.name}-darwin" then "${cpu.name}-darwin"
else else "${cpu.name}-${kernelName}";
"${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
@ -1856,25 +1859,19 @@ 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 then types.execs.aout
types.execs.aout else types.execs.elf;
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 in "${cpu.name}-${vendor.name}-${kernelName}${exec}${abi'}";
"${cpu.name}-${vendor.name}-${kernelName}${exec}${abi'}";
}; };
create = create = components:
components:
assert types.platform.check components; assert types.platform.check components;
lib.types.set "system" components; lib.types.set "system" components;
skeleton = skeleton = parts: let
parts:
let
length = builtins.length parts; length = builtins.length parts;
first = builtins.elemAt parts 0; first = builtins.elemAt parts 0;
@ -1882,51 +1879,52 @@ 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 then if length == 1
if first == "avr" then then
{ if first == "avr"
then {
cpu = first; cpu = first;
kernel = "none"; kernel = "none";
abi = "unknown"; abi = "unknown";
} }
else else builtins.throw "Target specification with 1 component is ambiguous."
builtins.throw "Target specification with 1 component is ambiguous." else if length == 2
else if length == 2 then then
if second == "cygwin" then if second == "cygwin"
{ then {
cpu = first; cpu = first;
kernel = "windows"; kernel = "windows";
abi = "cygnus"; abi = "cygnus";
} }
else if second == "windows" then else if second == "windows"
{ then {
cpu = first; cpu = first;
kernel = "windows"; kernel = "windows";
abi = "msvc"; abi = "msvc";
} }
else if second == "elf" then else if second == "elf"
{ 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 then else if length == 3
then
if if
second == "linux" second
== "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;
@ -1944,23 +1942,23 @@ in
"ghcjs" "ghcjs"
"mingw32" "mingw32"
]) ])
then then {
{
cpu = first; cpu = first;
vendor = second; vendor = second;
kernel = if third == "mingw32" then "windows" else third; kernel =
if third == "mingw32"
then "windows"
else third;
} }
else else builtins.throw "Target specification with 3 components is ambiguous."
builtins.throw "Target specification with 3 components is ambiguous." else if length == 4
else if length == 4 then then {
{
cpu = first; cpu = first;
vendor = second; vendor = second;
kernel = third; kernel = third;
abi = fourth; abi = fourth;
} }
else else builtins.throw "Invalid component count for creating system skeleton. Expected 1-4, but got ${builtins.toString length}.";
builtins.throw "Invalid component count for creating system skeleton. Expected 1-4, but got ${builtins.toString length}.";
patterns = { patterns = {
isi686 = { isi686 = {
@ -2022,8 +2020,7 @@ in
isArmv7 = isArmv7 =
map map
( (
{ arch, ... }: {arch, ...}: {
{
cpu = { cpu = {
inherit arch; inherit arch;
}; };
@ -2543,14 +2540,19 @@ in
]; ];
}; };
withBuildInfo = withBuildInfo = args: let
args: settings =
let if builtins.isString args
settings = if builtins.isString args then { system = args; } else args; then {system = args;}
else args;
resolved = resolved =
{ {
system = lib'.systems.from.string (if settings ? triple then settings.triple else settings.system); system = lib'.systems.from.string (
if settings ? triple
then settings.triple
else settings.system
);
inherit inherit
( (
@ -2569,8 +2571,7 @@ 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 = isExecutable = platform:
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;
@ -2608,87 +2609,95 @@ in
); );
libc = libc =
if resolved.isDarwin then if resolved.isDarwin
"libSystem" then "libSystem"
else if resolved.isMinGW then else if resolved.isMinGW
"msvcrt" then "msvcrt"
else if resolved.isWasi then else if resolved.isWasi
"wasilibc" then "wasilibc"
else if resolved.isRedox then else if resolved.isRedox
"relibc" then "relibc"
else if resolved.isMusl then else if resolved.isMusl
"musl" then "musl"
else if resolved.isUClibc then else if resolved.isUClibc
"uclibc" then "uclibc"
else if resolved.isAndroid then else if resolved.isAndroid
"bionic" then "bionic"
else if resolved.isLinux then else if resolved.isLinux
"glibc" then "glibc"
else if resolved.isFreeBSD then else if resolved.isFreeBSD
"fblibc" then "fblibc"
else if resolved.isNetBSD then else if resolved.isNetBSD
"nblibc" then "nblibc"
else if resolved.isAvr then else if resolved.isAvr
"avrlibc" then "avrlibc"
else if resolved.isGhcjs then else if resolved.isGhcjs
null then null
else if resolved.isNone then else if resolved.isNone
"newlib" then "newlib"
else else "native/impure";
"native/impure";
linker = if resolved.isDarwin then "cctools" else "bfd"; linker =
if resolved.isDarwin
then "cctools"
else "bfd";
extensions = extensions =
(lib.attrs.when resolved.hasSharedLibraries { (lib.attrs.when resolved.hasSharedLibraries {
shared = shared =
if resolved.isDarwin then if resolved.isDarwin
".dylib" then ".dylib"
else if resolved.isWindows then else if resolved.isWindows
".dll" then ".dll"
else else ".so";
".so";
}) })
// { // {
static = if resolved.isWindows then ".lib" else ".a"; static =
if resolved.isWindows
then ".lib"
else ".a";
library = if resolved.isStatic then resolved.extensions.static else resolved.extensions.shared; library =
if resolved.isStatic
then resolved.extensions.static
else resolved.extensions.shared;
executable = if resolved.isWindows then ".exe" else ""; executable =
if resolved.isWindows
then ".exe"
else "";
}; };
uname = { uname = {
system = system =
if resolved.system.kernel.name == "linux" then if resolved.system.kernel.name == "linux"
"Linux" then "Linux"
else if resolved.system.kernel.name == "windows" then else if resolved.system.kernel.name == "windows"
"Windows" then "Windows"
else if resolved.system.kernel.name == "darwin" then else if resolved.system.kernel.name == "darwin"
"Darwin" then "Darwin"
else if resolved.system.kernel.name == "netbsd" then else if resolved.system.kernel.name == "netbsd"
"NetBSD" then "NetBSD"
else if resolved.system.kernel.name == "freebsd" then else if resolved.system.kernel.name == "freebsd"
"FreeBSD" then "FreeBSD"
else if resolved.system.kernel.name == "openbsd" then else if resolved.system.kernel.name == "openbsd"
"OpenBSD" then "OpenBSD"
else if resolved.system.kernel.name == "wasi" then else if resolved.system.kernel.name == "wasi"
"Wasi" then "Wasi"
else if resolved.system.kernel.name == "redox" then else if resolved.system.kernel.name == "redox"
"Redox" then "Redox"
else if resolved.system.kernel.name == "redox" then else if resolved.system.kernel.name == "redox"
"Genode" then "Genode"
else else null;
null;
processor = processor =
if resolved.isPower64 then if resolved.isPower64
"ppc64${lib.strings.when resolved.isLittleEndian "le"}" then "ppc64${lib.strings.when resolved.isLittleEndian "le"}"
else if resolved.isPower then else if resolved.isPower
"ppc${lib.strings.when resolved.isLittleEndian "le"}" then "ppc${lib.strings.when resolved.isLittleEndian "le"}"
else if resolved.isMips64 then else if resolved.isMips64
"mips64" then "mips64"
else else resolved.system.cpu.name;
resolved.system.cpu.name;
release = null; release = null;
}; };
@ -2697,109 +2706,117 @@ in
useiOSPrebuilt = false; useiOSPrebuilt = false;
linux.arch = linux.arch =
if resolved.isAarch32 then if resolved.isAarch32
"arm" then "arm"
else if resolved.isAarch64 then else if resolved.isAarch64
"arm64" then "arm64"
else if resolved.isx86_32 then else if resolved.isx86_32
"i386" then "i386"
else if resolved.isx86_64 then else if resolved.isx86_64
"x86_64" then "x86_64"
# linux kernel does not distinguish microblaze/microblazeel # linux kernel does not distinguish microblaze/microblazeel
else if resolved.isMicroBlaze then else if resolved.isMicroBlaze
"microblaze" then "microblaze"
else if resolved.isMips32 then else if resolved.isMips32
"mips" then "mips"
else if resolved.isMips64 then else if resolved.isMips64
"mips" # linux kernel does not distinguish mips32/mips64 then "mips" # linux kernel does not distinguish mips32/mips64
else if resolved.isPower then else if resolved.isPower
"powerpc" then "powerpc"
else if resolved.isRiscV then else if resolved.isRiscV
"riscv" then "riscv"
else if resolved.isS390 then else if resolved.isS390
"s390" then "s390"
else if resolved.isLoongArch64 then else if resolved.isLoongArch64
"loongarch" then "loongarch"
else else resolved.system.cpu.name;
resolved.system.cpu.name;
uboot.arch = uboot.arch =
if resolved.isx86_32 then if resolved.isx86_32
"x86" # not i386 then "x86" # not i386
else if resolved.isMips64 then else if resolved.isMips64
"mips64" # uboot *does* distinguish between mips32/mips64 then "mips64" # uboot *does* distinguish between mips32/mips64
else else resolved.linux.arch; # other cases appear to agree with linuxArch
resolved.linux.arch; # other cases appear to agree with linuxArch
qemu.arch = qemu.arch =
if resolved.isAarch32 then if resolved.isAarch32
"arm" then "arm"
else if resolved.isS390 && !resolved.isS390x then else if resolved.isS390 && !resolved.isS390x
null then null
else if resolved.isx86_64 then else if resolved.isx86_64
"x86_64" then "x86_64"
else if resolved.isx86 then else if resolved.isx86
"i386" then "i386"
else if resolved.isMips64n32 then else if resolved.isMips64n32
"mipsn32${lib.strings.when resolved.isLittleEndian "el"}" then "mipsn32${lib.strings.when resolved.isLittleEndian "el"}"
else if resolved.isMips64 then else if resolved.isMips64
"mips64${lib.strings.when resolved.isLittleEndian "el"}" then "mips64${lib.strings.when resolved.isLittleEndian "el"}"
else else resolved.uname.processor;
resolved.uname.processor;
efi.arch = efi.arch =
if resolved.isx86_32 then if resolved.isx86_32
"ia32" then "ia32"
else if resolved.isx86_64 then else if resolved.isx86_64
"x64" then "x64"
else if resolved.isAarch32 then else if resolved.isAarch32
"arm" then "arm"
else if resolved.isAarch64 then else if resolved.isAarch64
"aa64" then "aa64"
else else resolved.system.cpu.name;
resolved.system.cpu.name;
darwin = { darwin = {
arch = arch =
if resolved.system.cpu.name == "armv7a" then if resolved.system.cpu.name == "armv7a"
"armv7" then "armv7"
else if resolved.system.cpu.name == "aarch64" then else if resolved.system.cpu.name == "aarch64"
"arm64" then "arm64"
else else resolved.system.cpu.name;
resolved.system.cpu.name;
platform = platform =
if resolved.isMacOS then if resolved.isMacOS
"macos" then "macos"
else if resolved.isiOS then else if resolved.isiOS
"ios" then "ios"
else else null;
null;
sdk = { sdk = {
version = resolved.darwinSdkVersion or (if resolved.isAarch64 then "11.0" else "10.12"); version =
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 then if resolved.isMacOS
"MACOSX_DEPLOYMENT_TARGET" then "MACOSX_DEPLOYMENT_TARGET"
else if resolved.isiOS then else if resolved.isiOS
"IPHONEOS_DEPLOYMENT_TARGET" then "IPHONEOS_DEPLOYMENT_TARGET"
else else null;
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 = builtins.foldl' ( assertions =
result: { assertion, message }: if assertion resolved then result else builtins.throw message builtins.foldl' (
) true (resolved.system.abi.assertions or [ ]); result: {
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,17 +1,16 @@
{ lib, config }: {
let lib,
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 = license = let
let
type = lib.types.submodule ( type = lib.types.submodule (
{ config }: {config}: {
{
options = { options = {
name = { name = {
full = lib.options.create { full = lib.options.create {
@ -57,7 +56,9 @@ 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.string lib'.systems.withBuildInfo lib.types.coerce
lib.types.string
lib'.systems.withBuildInfo
lib'.systems.types.platformWithBuildInfo; lib'.systems.types.platformWithBuildInfo;
builder = lib.types.submodule { builder = lib.types.submodule {
@ -73,14 +74,10 @@ 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 = dependencies = build: host: target: let
build: host: target:
let
initial = lib.types.raw; initial = lib.types.raw;
transform = transform = value: let
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;
@ -107,48 +104,46 @@ in
}; };
}; };
package = package = let
let normalize = value:
normalize = if builtins.isFunction value || builtins.isList value
value: then value
if builtins.isFunction value || builtins.isList value then else if value ? __modules__
value then value.__modules__
else if value ? __modules__ then else {
value.__modules__ config = value;
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 = merge = location: definitions: let
location: definitions: normalized =
let builtins.map
normalized = builtins.map (definition: lib.lists.from.any (normalize definition.value)) definitions; (definition: lib.lists.from.any (normalize definition.value))
definitions;
in in
builtins.concatLists normalized; builtins.concatLists
normalized;
}; };
transform = transform = location: value: let
location: value: modules =
let lib.lists.from.any (normalize value);
modules = lib.lists.from.any (normalize value);
result = lib.modules.run { result = lib.modules.run {
prefix = location; prefix = location;
modules = modules ++ [ modules =
submodule modules
{ config.__modules__ = modules; } ++ [submodule {config.__modules__ = modules;}];
];
}; };
in in
result.config; result.config;
final = lib.types.raw; final = lib.types.raw;
deps = deps = build: host: target:
build: host: target:
lib.types.submodule { lib.types.submodule {
options = { options = {
build = { build = {
@ -213,18 +208,18 @@ in
}; };
}; };
submodule = submodule = {config}: let
{ 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 // { merge = lib.options.merge.one; }); type = lib.types.list.of (initial
// {
merge = lib.options.merge.one;
});
# writable = false; # writable = false;
internal = true; internal = true;
default.value = []; default.value = [];
@ -306,7 +301,9 @@ in
default = { default = {
text = "\${config.pname}-\${config.version}"; text = "\${config.pname}-\${config.version}";
value = value =
if config.pname != null && config.version != null then "${config.pname}-${config.version}" else ""; if config.pname != null && config.version != null
then "${config.pname}-${config.version}"
else "";
}; };
}; };
@ -370,14 +367,18 @@ in
}; };
}; };
type = (lib.types.coerceWithLocation initial transform final) // { type =
(lib.types.coerceWithLocation initial transform final)
// {
name = "Package"; name = "Package";
description = "a package definition"; description = "a package definition";
}; };
in in
type type
// { // {
children = type.children // { children =
type.children
// {
inherit submodule; inherit submodule;
}; };
}; };

View file

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

View file

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

View file

@ -1,12 +1,10 @@
{ config }: {config}: let
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
@ -47,12 +45,9 @@ in
builtins.mapAttrs ( builtins.mapAttrs (
namespace: namespace:
builtins.mapAttrs ( builtins.mapAttrs (
name: alias: name: alias: let
let setHost = package:
setHost = package // {
package:
package
// {
__modules__ = package.__modules__ ++ [ __modules__ = package.__modules__ ++ [
{ {
config.platform = { config.platform = {
@ -95,12 +90,15 @@ in
# .config # .config
# else package; # else package;
updated = alias // { updated =
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
let inherit
inherit (config) (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,13 +13,10 @@ let
foundation foundation
packages packages
; ;
in in {
{
config.packages.foundation.binutils = { config.packages.foundation.binutils = {
versions = { versions = {
"latest" = "latest" = {config}: {
{ config }:
{
options = { options = {
src = lib.options.create { src = lib.options.create {
type = lib.types.derivation; type = lib.types.derivation;
@ -61,8 +58,7 @@ in
]; ];
}; };
phases = phases = let
let
patches = [ patches = [
# Make binutils output deterministic by default. # Make binutils output deterministic by default.
./patches/deterministic.patch ./patches/deterministic.patch
@ -93,8 +89,7 @@ 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,8 +3,7 @@
lib', lib',
config, config,
options, options,
}: }: {
{
includes = [ includes = [
./gcc ./gcc
./binutils ./binutils

View file

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