Compare commits

..

No commits in common. "7385b2195071116e808e97aa0e561d513da8f1d4" and "2be3111b2c0911f40b47fe0a1fb22b5f5188cf59" have entirely different histories.

13 changed files with 1548 additions and 1519 deletions

View file

@ -3,10 +3,10 @@
"lib": { "lib": {
"locked": { "locked": {
"dir": "lib", "dir": "lib",
"dirtyRev": "2be3111b2c0911f40b47fe0a1fb22b5f5188cf59-dirty", "dirtyRev": "a707b0f06be6b36bcbfe88d0a9a5b9a803983a06-dirty",
"dirtyShortRev": "2be3111-dirty", "dirtyShortRev": "a707b0f-dirty",
"lastModified": 1719251485, "lastModified": 1719079124,
"narHash": "sha256-63NvfFVeTDITfNu60rmCUlaZtAeZUnvrIaOLSk9ScC8=", "narHash": "sha256-4HwA3q5f7SUBmcXX9Vz9WsA9oHBQ/GiZTwE4iSVq9s8=",
"type": "git", "type": "git",
"url": "file:../?dir=lib" "url": "file:../?dir=lib"
}, },

View file

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

View file

@ -1048,7 +1048,7 @@ lib: {
merge = location: definitions: let merge = location: definitions: let
process = value: process = value:
if initial.check value if initial.check value
then transform value then (builtins.trace "transforming...") transform value
else value; else value;
normalize = definition: definition // {value = process definition.value;}; normalize = definition: definition // {value = process definition.value;};
normalized = builtins.map normalize definitions; normalized = builtins.map normalize definitions;
@ -1068,43 +1068,6 @@ lib: {
}; };
}; };
## Create a type that allows a value which is either the final type or is transformable
## to the final type.
##
## @type Attrs -> (Any -> Any) -> Attrs -> Attrs
coerceWithLocation = initial: transform: final: let
in
if initial.getSubModules != null
then builtins.throw "lib.types.coerceWithLocation's first argument may not have submodules, but got ${initial.description}"
else
lib.types.create {
name = "Coerce";
description = "${initial.description} that is transformed to ${final.description}";
fallback = final.fallback;
check = value: final.check value || (initial.check value && final.check (transform [] value));
merge = location: definitions: let
process = value:
if initial.check value
then transform location value
else value;
normalize = definition: definition // {value = process definition.value;};
normalized = builtins.map normalize definitions;
in
final.merge location normalized;
getSubOptions = final.getSubOptions;
getSubModules = final.getSubModules;
withSubModules = modules: lib.types.coerceWithLocation initial transform (final.withSubModules modules);
mergeType = x: y: null;
functor =
lib.types.functor "coerceWithLocation"
// {
wrapped = final;
};
children = {
inherit initial final;
};
};
dag = { dag = {
## Create a type that allows a DAG (Directed Acyclic Graph) of a given type. ## Create a type that allows a DAG (Directed Acyclic Graph) of a given type.
## ##

View file

@ -8,10 +8,10 @@
}, },
"locked": { "locked": {
"dir": "foundation", "dir": "foundation",
"dirtyRev": "2be3111b2c0911f40b47fe0a1fb22b5f5188cf59-dirty", "dirtyRev": "a707b0f06be6b36bcbfe88d0a9a5b9a803983a06-dirty",
"dirtyShortRev": "2be3111-dirty", "dirtyShortRev": "a707b0f-dirty",
"lastModified": 1719251485, "lastModified": 1719079124,
"narHash": "sha256-9G1TPBdlQNXCZf6A66bCT9m2vhodkSF+rDtqOVuFteY=", "narHash": "sha256-hz9vVcHSvlq/W01UOh/GqPFUoH9DzCFB16n23oj7fnQ=",
"type": "git", "type": "git",
"url": "file:../?dir=foundation" "url": "file:../?dir=foundation"
}, },
@ -24,10 +24,10 @@
"lib": { "lib": {
"locked": { "locked": {
"dir": "lib", "dir": "lib",
"dirtyRev": "2be3111b2c0911f40b47fe0a1fb22b5f5188cf59-dirty", "dirtyRev": "a707b0f06be6b36bcbfe88d0a9a5b9a803983a06-dirty",
"dirtyShortRev": "2be3111-dirty", "dirtyShortRev": "a707b0f-dirty",
"lastModified": 1719251485, "lastModified": 1719079124,
"narHash": "sha256-9G1TPBdlQNXCZf6A66bCT9m2vhodkSF+rDtqOVuFteY=", "narHash": "sha256-hz9vVcHSvlq/W01UOh/GqPFUoH9DzCFB16n23oj7fnQ=",
"type": "git", "type": "git",
"url": "file:../?dir=lib" "url": "file:../?dir=lib"
}, },

View file

@ -83,13 +83,7 @@ in {
} }
); );
in in
built built // {inherit (package) meta;};
// {
inherit (package) meta;
extras = {
inherit package;
};
};
}; };
}; };
} }

View file

@ -1,13 +1,16 @@
# This file handles creating all of the exports for this project and is not # This file handles creating all of the exports for this project and is not
# exported itself. # exported itself.
{config}: let {
inherit (config) lib; lib,
config,
}: let
lib' = config.lib;
in { in {
# freeform = lib.types.any; freeform = lib.types.any;
config = { config = {
exports = { exports = {
inherit lib; lib = config.lib;
modules = import ./modules.nix; modules = import ./modules.nix;
packages = { packages = {
@ -22,14 +25,13 @@ 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.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";
# }; # };
# example-x = config.packages.example.x; # example-x = config.packages.example.x;
cross-aux-a-x86_64-linux = config.packages.cross.x86_64-linux.aux.a; # cross-example-x-x86_64-linux = config.packages.cross.x86_64-linux.example.x;
cross-foundation-gcc-x86_64-linux = config.packages.cross.x86_64-linux.foundation.gcc;
}; };
}; };

View file

@ -1,9 +1,8 @@
{ {
lib, lib,
lib',
config, config,
}: let }: {
lib' = config.lib;
in {
config = { config = {
lib.packages = { lib.packages = {
dependencies = { dependencies = {
@ -21,70 +20,52 @@ in {
in in
builtins.head sorted; builtins.head sorted;
resolve = alias: resolve = package:
if alias ? versions if package ? versions
then then
alias.versions.${config.preferences.packages.version} package.versions.${config.preferences.packages.version}
or (alias.versions.${lib'.packages.getLatest alias}) or (package.versions.${lib'.packages.getLatest package})
else alias; else package;
build = alias: build: host: target: let build = package: build: host: target: let
package = lib'.packages.resolve alias; resolved = lib'.packages.resolve package;
buildDependencies = build': host': target': buildDependencies = build': host': target':
builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target'); builtins.mapAttrs (name: dep: lib'.packages.build dep build' host' target');
result = lib.modules.run { result = resolved.extend (
modules = {config}: {
package.__modules__ config = {
++ [ platform = {
lib'.types.package.children.submodule build = build;
( host = host;
{config}: { target = lib.modules.override 150 target;
config = { };
__modules__ = package.__modules__;
platform = { deps = {
build = lib.modules.overrides.force build; build = {
host = lib.modules.overrides.force host; only = buildDependencies build build build resolved.deps.build.only;
target = lib.modules.overrides.force target; build = buildDependencies build build target resolved.deps.build.build;
}; host = buildDependencies build host target resolved.deps.build.host;
}; target = buildDependencies build target target resolved.deps.build.target;
} };
) host = {
]; only = buildDependencies host host host resolved.deps.host.only;
}; host = buildDependencies host host target resolved.deps.host.host;
target = buildDependencies host target target resolved.deps.host.target;
};
target = {
only = buildDependencies target target target resolved.deps.target.only;
target = buildDependencies target target target resolved.deps.target.target;
};
};
# Not all platform information can be effectively handled via submodules. To handle package = config.builder.build config;
# the case where a user copies the resolved config over we need to ensure that
# dependencies are appropriately updated.
resolved =
result.config
// {
deps = {
build = {
only = buildDependencies build build build package.deps.build.only;
build = buildDependencies build build target package.deps.build.build;
host = buildDependencies build host target package.deps.build.host;
target = buildDependencies build target target package.deps.build.target;
};
host = {
only = buildDependencies host host host package.deps.host.only;
host = buildDependencies host host target package.deps.host.host;
target = buildDependencies host target target package.deps.host.target;
};
target = {
only = buildDependencies target target target package.deps.target.only;
target = buildDependencies target target target package.deps.target.target;
};
}; };
}; }
);
in in
resolved result;
// {
package = resolved.builder.build resolved;
};
}; };
}; };
} }

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,8 @@
{ {
lib, lib,
lib',
config, config,
}: let }: {
inherit (config) preferences builders;
lib' = config.lib;
in {
config = { config = {
lib.types = { lib.types = {
license = let license = let
@ -55,12 +52,6 @@ in {
in in
lib.types.either type (lib.types.list.of type); lib.types.either type (lib.types.list.of type);
platform =
lib.types.coerce
lib.types.string
lib'.systems.withBuildInfo
lib'.systems.types.platformWithBuildInfo;
builder = lib.types.submodule { builder = lib.types.submodule {
freeform = lib.types.any; freeform = lib.types.any;
@ -72,291 +63,385 @@ in {
}; };
}; };
packages = lib.types.attrs.of (lib.types.attrs.of lib'.types.alias); packages = lib.types.attrs.of (lib'.types.alias);
dependencies = build: host: target: let alias = lib.types.attrs.of (
initial = lib.types.attrs.any; lib.types.submodule {
transform = value: let
package = lib'.packages.resolve value;
in
(builtins.trace "building dependency ${package.name}: build=${build.triple} host=${host.triple} target=${target.triple}")
lib'.packages.build package build host target;
in
lib.types.attrs.of (lib.types.coerce initial transform lib'.types.package);
alias = lib.types.submodule {
options = {
stable = lib.options.create {
description = "The stable version of the package.";
type = lib.types.nullish lib'.types.package;
};
latest = lib.options.create {
description = "The latest version of the package.";
type = lib'.types.package;
};
versions = lib.options.create {
description = "Available versions of the package.";
type = lib.types.attrs.of lib'.types.package;
default.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;
in
builtins.concatLists
normalized;
};
transform = location: value: let
modules =
lib.lists.from.any (normalize value);
result = lib.modules.run {
prefix = location;
modules =
modules
++ [submodule {config.__modules__ = modules;}];
};
in
result.config;
final = lib.types.attrs.any;
submodule = {config}: let
build = config.platform.build;
host = config.platform.host;
target = config.platform.target;
in {
options = { options = {
__modules__ = lib.options.create { versions = lib.options.create {
description = "User specified modules for the package definition."; description = "All available package versions.";
type = lib.types.list.of (initial type = lib.types.attrs.of lib'.types.package.base;
// {
merge = lib.options.merge.one;
});
# writable = false;
internal = true;
default.value = [];
};
meta = {
description = lib.options.create {
description = "The description for the package.";
type = lib.types.nullish lib.types.string;
default.value = null;
};
homepage = lib.options.create {
description = "The homepage for the package.";
type = lib.types.nullish lib.types.string;
default.value = null;
};
license = lib.options.create {
description = "The license for the package.";
type = lib.types.nullish lib'.types.license;
default.value = null;
};
free = lib.options.create {
description = "Whether the package is free.";
type = lib.types.bool;
default.value = true;
};
insecure = lib.options.create {
description = "Whether the package is insecure.";
type = lib.types.bool;
default.value = false;
};
broken = lib.options.create {
description = "Whether the package is broken.";
type = lib.types.bool;
default.value = false;
};
main = lib.options.create {
description = "The main entry point for the package.";
type = lib.types.nullish lib.types.string;
default.value = null;
};
platforms = lib.options.create {
description = "The platforms the package supports.";
type = lib.types.list.of lib.types.string;
default.value = [];
};
};
platform = {
build = lib.options.create {
description = "The build platform for the package.";
type = lib'.types.platform;
default.value = lib'.systems.withBuildInfo "x86_64-linux";
};
host = lib.options.create {
description = "The host platform for the package.";
type = lib'.types.platform;
default.value = lib'.systems.withBuildInfo "x86_64-linux";
};
target = lib.options.create {
description = "The target platform for the package.";
type = lib'.types.platform;
default.value = lib'.systems.withBuildInfo "x86_64-linux";
};
};
name = lib.options.create {
description = "The name of the package.";
type = lib.types.string;
default = {
text = "\${config.pname}-\${config.version}";
value =
if config.pname != null && config.version != null
then "${config.pname}-${config.version}"
else "";
};
};
pname = lib.options.create {
description = "The program name for the package";
type = lib.types.nullish lib.types.string;
default.value = null;
};
version = lib.options.create {
description = "The version for the package.";
type = lib.types.nullish lib.types.version;
default.value = null;
};
builder = lib.options.create {
description = "The builder for the package.";
type = lib'.types.builder;
};
phases = lib.options.create {
description = "The phases for the package.";
type = lib.types.dag.of lib.types.string;
default.value = {};
};
env = lib.options.create {
description = "The environment for the package.";
type = lib.types.attrs.of lib.types.string;
default.value = {};
};
package = lib.options.create {
description = "The built derivation.";
type = lib.types.derivation;
default.value = config.builder.build config;
};
deps = {
build = {
only = lib.options.create {
description = "Dependencies which are only used in the build environment.";
type = lib'.types.dependencies build build build;
default.value = {};
};
build = lib.options.create {
description = "Dependencies which are created in the build environment and are executed in the build environment.";
type = lib'.types.dependencies build build target;
default.value = {};
};
host = lib.options.create {
description = "Dependencies which are created in the build environment and are executed in the host environment.";
type = lib'.types.dependencies build host target;
default.value = {};
};
target = lib.options.create {
description = "Dependencies which are created in the build environment and are executed in the target environment.";
type = lib'.types.dependencies build target target;
default.value = {};
};
};
host = {
only = lib.options.create {
description = "Dependencies which are only used in the host environment.";
type = lib'.types.dependencies host host host;
default.value = {};
};
host = lib.options.create {
description = "Dependencies which are executed in the host environment.";
type = lib'.types.dependencies host host target;
default.value = {};
};
target = lib.options.create {
description = "Dependencies which are executed in the host environment which produces code for the target environment.";
type = lib'.types.dependencies host target target;
default.value = {};
};
};
target = {
only = lib.options.create {
description = "Dependencies which are only used in the target environment.";
type = lib'.types.dependencies target target target;
default.value = {};
};
target = lib.options.create {
description = "Dependencies which are executed in the target environment.";
type = lib'.types.dependencies target target target;
default.value = {};
};
};
}; };
}; };
}; }
);
type = dependencies = lib.types.attrs.of (
(lib.types.coerceWithLocation initial transform final) lib.types.nullish (lib'.types.package.resolved)
// { );
name = "Package";
description = "a package definition"; package = {
}; resolved = let
in initial =
type lib.types.raw
// {
children =
type.children
// { // {
inherit submodule; check = value:
!(value ? __merged__)
&& lib.types.raw.check
value;
}; };
};
transform = value: let
package = lib'.packages.resolve value;
packageSubmodule = package.extend (args: {
options.__export__ = lib.options.create {
type = lib.types.raw;
default.value = {
inherit (args) options config;
};
};
config.__export__ = {
inherit (args) options config;
};
});
type = lib'.types.package.base.withSubModules (lib'.types.package.base.getSubModules
++ [
(args: {
options.__export__ = lib.options.create {
type = lib.types.raw;
default.value = {
inherit (args) options config;
};
};
config.__export__ = {
inherit (args) options config;
};
})
]);
typeSubmodule = lib.modules.run {
modules = type.getSubModules;
args = type.functor.payload.args;
};
getOptions = export: let
process = path: option:
if builtins.isAttrs option
then
if lib.types.is "option" option
then [
{
inherit path;
option = option;
}
]
else
builtins.concatLists (
lib.attrs.mapToList
(name: value: process (path ++ [name]) value)
option
)
else [];
in
process [] export.options;
packageOptions = getOptions packageSubmodule.__export__;
typeOptions = getOptions typeSubmodule.config.__export__;
customOptions =
builtins.filter
(
packageOption:
builtins.all (typeOption: packageOption.path != typeOption.path) typeOptions
)
packageOptions;
packageOptionsIds = builtins.map (option: builtins.concatStringsSep "." option.path) packageOptions;
typeOptionsIds = builtins.map (option: builtins.concatStringsSep "." option.path) typeOptions;
customOptionsIds = builtins.map (option: builtins.concatStringsSep "." option.path) customOptions;
resolvedOptions =
builtins.foldl' (
resolved: option: let
first = builtins.head option.path;
generated = lib.attrs.set option.path option.option;
in
if first == "__export__" || first == "__module__" || first == "__merged__"
then resolved
else lib.attrs.mergeRecursive resolved generated
) {}
customOptions;
in
# (builtins.trace (builtins.deepSeq packageOptionsIds packageOptionsIds))
# (builtins.trace (builtins.deepSeq typeOptionsIds typeOptionsIds))
# (builtins.trace (builtins.deepSeq customOptionsIds customOptionsIds))
# (builtins.trace packageSubmodule.__export__.config)
(args: {
__file__ = packageSubmodule.__export__.config.__file__ or "virtual:tidepool/src/lib/types.nix";
options =
resolvedOptions
// {
__merged__ = lib.options.create {
type = lib.types.bool;
default.value = true;
};
};
config =
builtins.removeAttrs package ["extend" "package" "platform"]
// {
platform = {
build = lib.modules.overrides.default package.platform.build.triple;
host = lib.modules.overrides.default package.platform.host.triple;
target = lib.modules.overrides.default package.platform.target.triple;
};
};
# // {
# builder =
# (builtins.trace "builder")
# (builtins.trace (args.config ? builder))
# lib.modules.alias
# packageSubmodule.__export__.options.builder;
# };
});
in
lib.types.coerce initial transform lib'.types.package.base;
base = lib.types.submodule (
{
config,
meta,
}: {
options = {
extend = lib.options.create {
description = "Extend the package's submodules with additional configuration.";
type = lib.types.function lib.types.raw;
default.value = value: let
result = meta.extend {
modules =
if builtins.isAttrs value
then [{config = value;}]
else lib.lists.from.any value;
};
in
result.config;
};
name = lib.options.create {
description = "The name of the package.";
type = lib.types.string;
default = {
text = "\${config.pname}-\${config.version}";
value =
if config.pname != null && config.version != null
then "${config.pname}-${config.version}"
else "";
};
};
pname = lib.options.create {
description = "The program name for the package";
type = lib.types.nullish lib.types.string;
default.value = null;
};
version = lib.options.create {
description = "The version for the package.";
type = lib.types.nullish lib.types.version;
default.value = null;
};
meta = {
description = lib.options.create {
description = "The description for the package.";
type = lib.types.nullish lib.types.string;
default.value = null;
};
homepage = lib.options.create {
description = "The homepage for the package.";
type = lib.types.nullish lib.types.string;
default.value = null;
};
license = lib.options.create {
description = "The license for the package.";
type = lib.types.nullish lib'.types.license;
default.value = null;
};
free = lib.options.create {
description = "Whether the package is free.";
type = lib.types.bool;
default.value = true;
};
insecure = lib.options.create {
description = "Whether the package is insecure.";
type = lib.types.bool;
default.value = false;
};
broken = lib.options.create {
description = "Whether the package is broken.";
type = lib.types.bool;
default.value = false;
};
main = lib.options.create {
description = "The main entry point for the package.";
type = lib.types.nullish lib.types.string;
default.value = null;
};
platforms = lib.options.create {
description = "The platforms the package supports.";
type = lib.types.list.of lib.types.string;
default.value = [];
};
};
platform = {
build = lib.options.create {
description = "The build platform for the package.";
type = lib.types.string;
default.value = "x86_64-linux";
apply = raw: let
system = lib'.systems.from.string raw;
x = lib'.systems.withBuildInfo raw;
in
x;
};
host = lib.options.create {
description = "The host platform for the package.";
type = lib.types.string;
default.value = "x86_64-linux";
# apply = raw: let
# system = lib'.systems.from.string raw;
# in {
# inherit raw system;
# double = lib'.systems.into.double system;
# triple = lib'.systems.into.triple system;
# };
apply = raw: let
system = lib'.systems.from.string raw;
x = lib'.systems.withBuildInfo raw;
in
x;
};
target = lib.options.create {
description = "The target platform for the package.";
type = lib.types.string;
default.value = "x86_64-linux";
# apply = raw: let
# system = lib'.systems.from.string raw;
# in {
# inherit raw system;
# double = lib'.systems.into.double system;
# triple = lib'.systems.into.triple system;
# };
apply = raw: let
system = lib'.systems.from.string raw;
x = lib'.systems.withBuildInfo raw;
in
x;
};
};
phases = lib.options.create {
description = "The phases for the package.";
type = lib.types.dag.of (lib.types.either lib.types.string (lib.types.function lib.types.string));
default.value = {};
};
env = lib.options.create {
description = "The environment for the package.";
type = lib.types.attrs.of lib.types.string;
default.value = {};
};
builder = lib.options.create {
description = "The builder for the package.";
type = lib'.types.builder;
};
deps = {
build = {
only = lib.options.create {
description = "Dependencies which are only used in the build environment.";
type = lib'.types.dependencies;
default.value = {};
};
build = lib.options.create {
description = "Dependencies which are created in the build environment and are executed in the build environment.";
type = lib'.types.dependencies;
default.value = {};
};
host = lib.options.create {
description = "Dependencies which are created in the build environment and are executed in the host environment.";
type = lib'.types.dependencies;
default.value = {};
};
target = lib.options.create {
description = "Dependencies which are created in the build environment and are executed in the target environment.";
type = lib'.types.dependencies;
default.value = {};
};
};
host = {
only = lib.options.create {
description = "Dependencies which are only used in the host environment.";
type = lib'.types.dependencies;
default.value = {};
};
host = lib.options.create {
description = "Dependencies which are executed in the host environment.";
type = lib'.types.dependencies;
default.value = {};
};
target = lib.options.create {
description = "Dependencies which are executed in the host environment which produces code for the target environment.";
type = lib'.types.dependencies;
default.value = {};
};
};
target = {
only = lib.options.create {
description = "Dependencies which are only used in the target environment.";
type = lib'.types.dependencies;
default.value = {};
};
target = lib.options.create {
description = "Dependencies which are executed in the target environment.";
type = lib'.types.dependencies;
default.value = {};
};
};
};
package = lib.options.create {
description = "The built derivation.";
type = lib.types.derivation;
default.value = config.builder.build config;
};
};
}
);
};
}; };
}; };
} }

View file

@ -12,8 +12,6 @@ in {
platforms = ["i686-linux"]; platforms = ["i686-linux"];
}; };
name = "${config.pname}-${config.version}";
pname = "a"; pname = "a";
version = "1.0.0"; version = "1.0.0";

View file

@ -1,12 +1,15 @@
{config}: let {
inherit (config) lib builders packages; lib',
config,
}: let
inherit (config) builders packages;
in { in {
config.packages.aux.b = { config.packages.aux.b = {
versions = { versions = {
"latest" = {config}: { "latest" = {config}: {
options = { options = {
custom = lib.options.create { custom = lib'.options.create {
type = lib.types.bool; type = lib'.types.bool;
}; };
}; };
@ -15,8 +18,6 @@ in {
platforms = ["i686-linux"]; platforms = ["i686-linux"];
}; };
name = "${config.pname}-${config.version}";
custom = true; custom = true;
pname = "b"; pname = "b";

View file

@ -1,7 +1,9 @@
{config}: let {
inherit (config) lib; lib,
lib',
doubles = lib.systems.doubles.all; config,
}: let
doubles = lib'.systems.doubles.all;
packages = builtins.removeAttrs config.packages ["cross"]; packages = builtins.removeAttrs config.packages ["cross"];
in { in {
@ -15,13 +17,13 @@ in {
packages = lib.options.create { packages = lib.options.create {
description = "The package set."; description = "The package set.";
type = lib.types.submodule { type = lib.types.submodule {
freeform = lib.types.packages; freeform = lib.types.attrs.of (lib.types.submodule {freeform = lib'.types.alias;});
options.cross = lib.attrs.generate doubles ( options.cross = lib.attrs.generate doubles (
system: system:
lib.options.create { lib.options.create {
description = "The cross-compiled package set for the ${system} target."; description = "The cross-compiled package set for the ${system} target.";
type = lib.types.packages; type = lib'.types.packages;
default = {}; default = {};
} }
); );
@ -47,48 +49,38 @@ in {
builtins.mapAttrs ( builtins.mapAttrs (
name: alias: let name: alias: let
setHost = package: setHost = package:
package // { if package != {}
__modules__ = package.__modules__ ++ [ then
{ (package.extend (
config.platform = { {config}: {
host = lib.modules.override 5 system; config = {
target = lib.modules.override 5 system; platform = {
}; host = lib.modules.overrides.force system;
} target = lib.modules.overrides.default system;
]; };
};
# if package != {}
# then
# (package.extend (
# {config}: {
# config = {
# platform = {
# host = lib.modules.overrides.force system;
# target = lib.modules.overrides.default system;
# };
# deps = { deps = {
# build = { build = {
# only = setHost package.deps.build.only; only = setHost package.deps.build.only;
# build = setHost package.deps.build.build; build = setHost package.deps.build.build;
# host = setHost package.deps.build.host; host = setHost package.deps.build.host;
# target = setHost package.deps.build.target; target = setHost package.deps.build.target;
# }; };
# host = { host = {
# only = setHost package.deps.host.only; only = setHost package.deps.host.only;
# host = setHost package.deps.host.host; host = setHost package.deps.host.host;
# target = setHost package.deps.host.target; target = setHost package.deps.host.target;
# }; };
# target = { target = {
# only = setHost package.deps.target.only; only = setHost package.deps.target.only;
# target = setHost package.deps.target.target; target = setHost package.deps.target.target;
# }; };
# }; };
# }; };
# } }
# )) ))
# .config .config
# else package; else package;
updated = updated =
alias alias

View file

@ -1,217 +1,236 @@
{ {
lib,
lib',
config, config,
options, options,
}: let }:
inherit let
(config) inherit (config)
lib
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
packages
; ;
in { in
{
config.packages.foundation.gcc = { config.packages.foundation.gcc = {
versions = { versions = {
"latest" = { "latest" =
config, { config, meta }:
meta, {
}: { options = {
options = {
src = lib.options.create {
type = lib.types.derivation;
description = "Source for the package.";
};
cc = {
src = lib.options.create { src = lib.options.create {
type = lib.types.derivation; type = lib.types.derivation;
description = "The cc source for the package."; description = "Source for the package.";
};
cc = {
src = lib.options.create {
type = lib.types.derivation;
description = "The cc source for the package.";
};
};
gmp = {
src = lib.options.create {
type = lib.types.derivation;
description = "The gmp source for the package.";
};
version = lib.options.create {
type = lib.types.string;
description = "Version of gmp.";
};
};
mpfr = {
src = lib.options.create {
type = lib.types.derivation;
description = "The mpfr source for the package.";
};
version = lib.options.create {
type = lib.types.string;
description = "Version of mpfr.";
};
};
mpc = {
src = lib.options.create {
type = lib.types.derivation;
description = "The mpc source for the package.";
};
version = lib.options.create {
type = lib.types.string;
description = "Version of mpc.";
};
};
isl = {
src = lib.options.create {
type = lib.types.derivation;
description = "The isl source for the package.";
};
version = lib.options.create {
type = lib.types.string;
description = "Version of isl.";
};
}; };
}; };
gmp = { config = {
src = lib.options.create { meta = {
type = lib.types.derivation; platforms = [ "i686-linux" ];
description = "The gmp source for the package.";
}; };
version = lib.options.create { pname = "gcc";
type = lib.types.string; version = "13.2.0";
description = "Version of gmp.";
};
};
mpfr = { builder = builders.basic;
src = lib.options.create {
type = lib.types.derivation; env = {
description = "The mpfr source for the package."; PATH =
let
gcc =
if
config.platform.build.triple == config.platform.host.triple
# If we're on the same system then we can use the existing GCC instance.
then
foundation.stage2-gcc
# Otherwise we are going to need a cross-compiler.
else
# TODO: Create a gcc-cross package.
(meta.extend (args: {
config = {
platform = {
build = config.platform.build.triple;
host = config.platform.build.triple;
target = lib.modules.override.force config.platform.host.triple;
};
};
})).config.package;
in
lib.paths.bin [
foundation.stage2-gcc
foundation.stage2-binutils
foundation.stage2-gnumake
foundation.stage2-gnused
foundation.stage2-gnugrep
foundation.stage2-gawk
foundation.stage2-diffutils
foundation.stage2-findutils
foundation.stage2-gnutar
foundation.stage2-gzip
foundation.stage2-bzip2
foundation.stage1-xz
];
}; };
version = lib.options.create { phases =
type = lib.types.string; let
description = "Version of mpfr."; host = lib'.systems.withBuildInfo config.platform.host;
};
};
mpc = { mbits = if host.system.cpu.family == "x86" then if host.is64bit then "-m64" else "-m32" else "";
src = lib.options.create { in
type = lib.types.derivation; {
description = "The mpc source for the package."; unpack = lib.dag.entry.before [ "patch" ] ''
# Unpack
tar xf ${config.src}
tar xf ${config.gmp.src}
tar xf ${config.mpfr.src}
tar xf ${config.mpc.src}
tar xf ${config.isl.src}
cd gcc-${config.version}
ln -s ../gmp-${config.gmp.version} gmp
ln -s ../mpfr-${config.mpfr.version} mpfr
ln -s ../mpc-${config.mpc.version} mpc
ln -s ../isl-${config.isl.version} isl
'';
patch = lib.dag.entry.between [ "configure" ] [ "unpack" ] ''
# Patch
# force musl even if host triple is gnu
sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host
'';
configure = lib.dag.entry.between [ "build" ] [ "patch" ] ''
# Configure
export CC="gcc -Wl,-dynamic-linker -march=${
host.gcc.arch or host.system.cpu.family
} ${mbits} -Wl,${foundation.stage1-musl}/lib/libc.so"
export CXX="g++ -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export CFLAGS_FOR_TARGET="-Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export LIBRARY_PATH="${foundation.stage1-musl}/lib"
bash ./configure \
--prefix=$out \
--build=${config.platform.build.triple} \
--host=${config.platform.host.triple} \
--target=${config.platform.target.triple} \
--with-native-system-header-dir=/include \
--with-sysroot=${foundation.stage1-musl} \
--enable-languages=c,c++ \
--disable-bootstrap \
--disable-libsanitizer \
--disable-lto \
--disable-multilib \
--disable-plugin \
CFLAGS=-static \
CXXFLAGS=-static
'';
build = lib.dag.entry.between [ "install" ] [ "configure" ] ''
# Build
make -j $NIX_BUILD_CORES
'';
install = lib.dag.entry.after [ "build" ] ''
# Install
make -j $NIX_BUILD_CORES install-strip
'';
};
src = builtins.fetchurl {
url = "${mirrors.gnu}/gcc/gcc-${config.version}/gcc-${config.version}.tar.xz";
sha256 = "4nXnZEKmBnNBon8Exca4PYYTFEAEwEE1KIY9xrXHQ9o=";
}; };
version = lib.options.create { gmp = {
type = lib.types.string; version = "6.3.0";
description = "Version of mpc."; src = builtins.fetchurl {
url = "${mirrors.gnu}/gmp/gmp-${config.gmp.version}.tar.xz";
sha256 = "o8K4AgG4nmhhb0rTC8Zq7kknw85Q4zkpyoGdXENTiJg=";
};
}; };
};
isl = { mpfr = {
src = lib.options.create { version = "4.2.1";
type = lib.types.derivation; src = builtins.fetchurl {
description = "The isl source for the package."; url = "${mirrors.gnu}/mpfr/mpfr-${config.mpfr.version}.tar.xz";
sha256 = "J3gHNTpnJpeJlpRa8T5Sgp46vXqaW3+yeTiU4Y8fy7I=";
};
}; };
version = lib.options.create {
type = lib.types.string; mpc = {
description = "Version of isl."; version = "1.3.1";
src = builtins.fetchurl {
url = "${mirrors.gnu}/mpc/mpc-${config.mpc.version}.tar.gz";
sha256 = "q2QkkvXPiCt0qgy3MM1BCoHtzb7IlRg86TDnBsHHWbg=";
};
};
isl = {
version = "0.24";
src = builtins.fetchurl {
url = "https://gcc.gnu.org/pub/gcc/infrastructure/isl-${config.isl.version}.tar.bz2";
sha256 = "/PeN2WVsEOuM+fvV9ZoLawE4YgX+GTSzsoegoYmBRcA=";
};
}; };
}; };
}; };
config = {
meta = {
platforms = ["i686-linux"];
};
pname = "gcc";
version = "13.2.0";
builder = builders.basic;
env = {
PATH = lib.paths.bin [
foundation.stage2-gcc
foundation.stage2-binutils
foundation.stage2-gnumake
foundation.stage2-gnused
foundation.stage2-gnugrep
foundation.stage2-gawk
foundation.stage2-diffutils
foundation.stage2-findutils
foundation.stage2-gnutar
foundation.stage2-gzip
foundation.stage2-bzip2
foundation.stage1-xz
];
};
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 {
unpack = lib.dag.entry.before ["patch"] ''
# Unpack
tar xf ${config.src}
tar xf ${config.gmp.src}
tar xf ${config.mpfr.src}
tar xf ${config.mpc.src}
tar xf ${config.isl.src}
cd gcc-${config.version}
ln -s ../gmp-${config.gmp.version} gmp
ln -s ../mpfr-${config.mpfr.version} mpfr
ln -s ../mpc-${config.mpc.version} mpc
ln -s ../isl-${config.isl.version} isl
'';
patch = lib.dag.entry.between ["configure"] ["unpack"] ''
# Patch
# force musl even if host triple is gnu
sed -i 's|"os/gnu-linux"|"os/generic"|' libstdc++-v3/configure.host
'';
configure = lib.dag.entry.between ["build"] ["patch"] ''
# Configure
export CC="gcc -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export CXX="g++ -Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export CFLAGS_FOR_TARGET="-Wl,-dynamic-linker -Wl,${foundation.stage1-musl}/lib/libc.so"
export LIBRARY_PATH="${foundation.stage1-musl}/lib"
bash ./configure \
--prefix=$out \
--build=${config.platform.build.triple} \
--host=${config.platform.host.triple} \
--target=${config.platform.target.triple} \
--with-native-system-header-dir=/include \
--with-sysroot=${foundation.stage1-musl} \
--enable-languages=c,c++ \
--disable-bootstrap \
--disable-libsanitizer \
--disable-lto \
--disable-multilib \
--disable-plugin \
CFLAGS=-static \
CXXFLAGS=-static
'';
build = lib.dag.entry.between ["install"] ["configure"] ''
# Build
make -j $NIX_BUILD_CORES
'';
install = lib.dag.entry.after ["build"] ''
# Install
make -j $NIX_BUILD_CORES install-strip
'';
};
src = builtins.fetchurl {
url = "${mirrors.gnu}/gcc/gcc-${config.version}/gcc-${config.version}.tar.xz";
sha256 = "4nXnZEKmBnNBon8Exca4PYYTFEAEwEE1KIY9xrXHQ9o=";
};
gmp = {
version = "6.3.0";
src = builtins.fetchurl {
url = "${mirrors.gnu}/gmp/gmp-${config.gmp.version}.tar.xz";
sha256 = "o8K4AgG4nmhhb0rTC8Zq7kknw85Q4zkpyoGdXENTiJg=";
};
};
mpfr = {
version = "4.2.1";
src = builtins.fetchurl {
url = "${mirrors.gnu}/mpfr/mpfr-${config.mpfr.version}.tar.xz";
sha256 = "J3gHNTpnJpeJlpRa8T5Sgp46vXqaW3+yeTiU4Y8fy7I=";
};
};
mpc = {
version = "1.3.1";
src = builtins.fetchurl {
url = "${mirrors.gnu}/mpc/mpc-${config.mpc.version}.tar.gz";
sha256 = "q2QkkvXPiCt0qgy3MM1BCoHtzb7IlRg86TDnBsHHWbg=";
};
};
isl = {
version = "0.24";
src = builtins.fetchurl {
url = "https://gcc.gnu.org/pub/gcc/infrastructure/isl-${config.isl.version}.tar.bz2";
sha256 = "/PeN2WVsEOuM+fvV9ZoLawE4YgX+GTSzsoegoYmBRcA=";
};
};
};
};
}; };
}; };
} }