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.
##
## @type Location -> List Definition -> Any
default =
location: definitions:
let
default = location: definitions: let
values = lib.options.getDefinitionValues definitions;
first = builtins.elemAt values 0;
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;
mergedStrings = lib.strings.concat values;
in
if builtins.length values == 1 then
builtins.elemAt values 0
else if builtins.all builtins.isFunction values then
mergedFunctions
else if builtins.all builtins.isList values then
mergedLists
else if builtins.all builtins.isAttrs values then
mergedAttrs
else if builtins.all builtins.isBool values then
mergedBools
else if builtins.all lib.strings.isString values then
mergedStrings
else if builtins.all builtins.isInt values && builtins.all (x: x == first) values then
first
if builtins.length values == 1
then builtins.elemAt values 0
else if builtins.all builtins.isFunction values
then mergedFunctions
else if builtins.all builtins.isList values
then mergedLists
else if builtins.all builtins.isAttrs values
then mergedAttrs
else if builtins.all builtins.isBool values
then mergedBools
else if builtins.all lib.strings.isString values
then mergedStrings
else if builtins.all builtins.isInt values && builtins.all (x: x == first) values
then first
# 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.
##
## @type Location -> Type -> List Definition
definitions =
location: type: definitions:
let
definitions = location: type: definitions: let
identifier = lib.options.getIdentifier location;
resolve =
definition:
let
resolve = definition: let
properties = builtins.addErrorContext "while evaluating definitions from `${definition.__file__ or "<unknown>"}`:" (
lib.modules.apply.properties definition.value
);
@ -57,27 +50,27 @@ lib: {
overridden = lib.modules.apply.overrides resolved;
values =
if builtins.any (definition: lib.types.is "order" definition.value) overridden.values then
lib.modules.apply.order overridden.values
else
overridden.values;
if builtins.any (definition: lib.types.is "order" definition.value) overridden.values
then lib.modules.apply.order overridden.values
else overridden.values;
isDefined = values != [];
invalid = builtins.filter (definition: !(type.check definition.value)) values;
merged =
if isDefined then
if builtins.all (definition: type.check definition.value) values then
type.merge location values
else
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.";
if isDefined
then
if builtins.all (definition: type.check definition.value) values
then type.merge location values
else 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.";
optional = if isDefined then { value = merged; } else { };
in
{
optional =
if isDefined
then {value = merged;}
else {};
in {
inherit
isDefined
values
@ -94,12 +87,8 @@ lib: {
## Merge multiple option declarations together.
##
## @type Location -> List Option
declarations =
location: options:
let
merge =
result: option:
let
declarations = location: options: let
merge = result: option: let
mergedType = result.type.mergeType option.options.type.functor;
isTypeMergeable = mergedType != null;
shared = name: option.options ? ${name} && result ? ${name};
@ -108,14 +97,15 @@ lib: {
serializedFiles = builtins.concatStringsSep " and " files;
getSubModules = option.options.type.getSubModules or null;
submodules =
if getSubModules != null then
if getSubModules != null
then
builtins.map (module: {
__file__ = option.__file__;
includes = [module];
}) getSubModules
})
getSubModules
++ result.options
else
result.options;
else result.options;
in
if
shared "default"
@ -123,8 +113,7 @@ lib: {
|| shared "description"
|| shared "apply"
|| (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
option.options
// result
@ -138,50 +127,43 @@ lib: {
inherit location;
declarations = [];
options = [];
} options;
}
options;
## Merge an option, only supporting a single unique definition.
##
## @type String -> Location -> List Definition -> Any
unique =
message: location: definitions:
let
unique = message: location: definitions: let
identifier = lib.options.getIdentifier location;
total = builtins.length definitions;
first = builtins.elemAt definitions 0;
in
if total == 1 then
first.value
else if total == 0 then
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}";
if total == 1
then first.value
else if total == 0
then 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}";
## Merge a single instance of an option.
##
## @type Location -> List Definition -> Any
one = lib.options.merge.unique "";
equal =
location: definitions:
let
equal = location: definitions: let
identifier = lib.options.getIdentifier location;
first = builtins.elemAt definitions 0;
rest = builtins.tail definitions;
merge =
x: y:
if x != y then
builtins.throw "The option `${identifier}` has conflicting definitions:${lib.options.getDefinitions definitions}"
else
x;
merge = x: y:
if x != y
then builtins.throw "The option `${identifier}` has conflicting definitions:${lib.options.getDefinitions definitions}"
else x;
merged = builtins.foldl' merge first rest;
in
if builtins.length definitions == 0 then
builtins.throw "Cannot merge unused option `${identifier}`."
else if builtins.length definitions == 1 then
first.value
else
merged.value;
if builtins.length definitions == 0
then builtins.throw "Cannot merge unused option `${identifier}`."
else if builtins.length definitions == 1
then first.value
else merged.value;
};
## Check whether a value is an option.
@ -192,8 +174,7 @@ lib: {
## 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
create =
settings@{
create = settings @ {
type ? lib.types.unspecified,
apply ? null,
default ? {},
@ -202,8 +183,7 @@ lib: {
internal ? null,
writable ? null,
description ? null,
}:
{
}: {
__type__ = "option";
inherit
type
@ -220,9 +200,7 @@ lib: {
## Create a sink option.
##
## @type @alias lib.options.create
sink =
settings:
let
sink = settings: let
defaults = {
internal = true;
visible = false;
@ -246,9 +224,7 @@ lib: {
## Convert a list of option identifiers into a single identifier.
##
## @type List String -> String
getIdentifier =
location:
let
getIdentifier = location: let
special = [
# lib.types.attrs.of (lib.types.submodule {})
"<name>"
@ -257,23 +233,24 @@ lib: {
# lib.types.function
"<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
lib.strings.concatMapSep "." escape location;
## Get a string message of the definitions for an option.
##
## @type List Definition -> String
getDefinitions =
definitions:
let
serialize =
definition:
let
valueWithRecursionLimit = lib.generators.withRecursion {
getDefinitions = definitions: let
serialize = definition: let
valueWithRecursionLimit =
lib.generators.withRecursion {
limit = 10;
throw = false;
} definition.value;
}
definition.value;
eval = builtins.tryEval (lib.generators.pretty {} valueWithRecursionLimit);
@ -286,27 +263,24 @@ lib: {
value = builtins.concatStringsSep "\n " (firstFiveLines ++ ellipsis);
result =
if !eval.success then
""
else if linesLength > 1 then
":\n " + value
else
": " + value;
in
"\n- In `${definition.__file__}`${result}";
if !eval.success
then ""
else if linesLength > 1
then ":\n " + value
else ": " + value;
in "\n- In `${definition.__file__}`${result}";
in
lib.strings.concatMap serialize definitions;
## 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 }
run =
location: option: definitions:
let
run = location: option: definitions: let
identifier = lib.options.getIdentifier location;
definitionsWithDefault =
if option ? default && option.default ? value then
if option ? default && option.default ? value
then
[
{
__file__ = builtins.head option.declarations;
@ -314,25 +288,28 @@ lib: {
}
]
++ definitions
else
definitions;
else definitions;
merged =
if option.writable or null == false && builtins.length definitionsWithDefault > 1 then
let
separatedDefinitions = builtins.map (
if option.writable or null == false && builtins.length definitionsWithDefault > 1
then let
separatedDefinitions =
builtins.map (
definition:
definition
// {
value = (lib.options.merge.definitions location option.type [definition]).merged;
}
) definitionsWithDefault;
)
definitionsWithDefault;
in
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 = 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
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;
lib' = config.lib;
inherit (config) foundation;
in
{
in {
config.builders = {
basic = {
executable = "${foundation.stage2-bash}/bin/bash";
build =
package:
let
build = package: let
phases = lib.dag.apply.defaults package.phases {
unpack = lib.dag.entry.before ["patch"] "";
@ -27,9 +26,14 @@ in
};
sorted = lib.dag.sort.topographic phases;
script = lib.strings.concatMapSep "\n" (
entry: if builtins.isFunction entry.value then entry.value package else entry.value
) sorted.result;
script =
lib.strings.concatMapSep "\n" (
entry:
if builtins.isFunction entry.value
then entry.value package
else entry.value
)
sorted.result;
system = package.platform.build.double;
@ -43,8 +47,7 @@ in
SHELL = cfg.executable;
PATH =
let
PATH = let
bins = lib.paths.bin (
(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
# exported itself.
{ config }:
let
{config}: let
inherit (config) lib;
in
{
in {
# freeform = lib.types.any;
config = {
@ -26,7 +24,6 @@ in
# .config;
foundation-gcc = config.packages.foundation.gcc;
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 {
# platform.host = lib.modules.overrides.force "x86_64-linux";
# };

View file

@ -1,7 +1,8 @@
{ lib, config }:
let
in
{
lib,
config,
}: let
in {
config = {
lib.options = {
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 = {
lib.packages = {
dependencies = {
getPackages =
dependencies:
let
getPackages = dependencies: let
available = builtins.filter (dependency: !(builtins.isNull dependency)) (
builtins.attrValues dependencies
);
in
builtins.map (dependency: dependency.package) available;
build =
build': host': target':
builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target');
build = 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;
sorted = builtins.sort (lib.versions.gte) versions;
in
builtins.head sorted;
resolve =
alias:
if alias ? versions then
resolve = alias:
if alias ? versions
then
alias.versions.${config.preferences.packages.version}
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;
buildDependencies =
build': host': target':
buildDependencies = build': host': target':
builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target');
platform = {
@ -52,11 +45,12 @@ in
};
withPlatform = lib.modules.run {
modules = package.__modules__ ++ [
modules =
package.__modules__
++ [
lib'.types.package.children.submodule
(
{ config }:
{
{config}: {
config = {
__modules__ = package.__modules__;
@ -70,7 +64,9 @@ in
# 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
# dependencies are appropriately updated.
withDeps = withPlatform.config // {
withDeps =
withPlatform.config
// {
deps = {
build = {
only = buildDependencies build build build withPlatform.config.deps.build.only;
@ -91,11 +87,12 @@ in
};
withPackage = lib.modules.run {
modules = package.__modules__ ++ [
modules =
package.__modules__
++ [
lib'.types.package.children.submodule
(
{ config }:
{
{config}: {
config = {
__modules__ = package.__modules__;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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