Skip to content

reinstallable lib:ghc #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ let
# up much later on hackage; but are not installable
# anyway. Therefore we just strip them out of the
# pkg-def's packages.
boot-pkgs = [ "rts" "ghc" "ghci" "ghc-boot" "ghc-boot-th"
#
# Note: these will need to be provided by alternative
# means outside of hackage.
boot-pkgs = [ "rts" "ghc" "ghc-boot-th" "ghc-boot" "ghci"
"ghc-heap" # since ghc 8.6.
];
strip-pkg-def = pkgs: pkg-def: hackage: with pkgs.lib;
Expand Down
22 changes: 20 additions & 2 deletions modules/component-driver.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,27 @@ in
type = lib.types.listOf lib.types.str;
};

# Dependencies
#
# .--------. .------------------.
# | pretty | < ------- | template-haskell |
# '--------' '------------------'
# v |
# .---------. .-------. |
# | deepseq | - > | array | |
# '---------' '-------' v
# v v .-------------.
# .----------. .----------. .------. .- | ghc-boot-th |
# | ghc-heap | | ghc-prim | | base |< -' '-------------'
# '----------' '----------' '------' .----------------.
# | v | | | integer-simple |
# | .-----. | '-- > |-------or-------|
# '---- > | rts | < -----' | integer-gmp |
# '-----' '----------------'

config.nonReinstallablePkgs =
[ "rts" "ghc" "ghc-prim" "integer-gmp" "integer-simple" "base"
"array" "deepseq" "pretty" "ghc-boot-th" "template-haskell" "ghc-heap" ];
[ "rts" "ghc-heap" "ghc-prim" "integer-gmp" "integer-simple" "base"
"deepseq" "array" "ghc-boot-th" "pretty" "template-haskell" ];

options.hsPkgs = lib.mkOption {
type = lib.types.unspecified;
Expand Down
155 changes: 6 additions & 149 deletions modules/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,22 @@
# tests = { "..." = { depends = ... }; ... };
# };

{ parentConfig, mod_args, listOfFilteringNulls, componentOptions, packageOptions }:
{ lib, config, pkgs, haskellLib, ... }:

with lib;
with types;

let
# This is just like listOf, except that it filters out all null elements.
listOfFilteringNulls = elemType: listOf elemType // {
# Mostly copied from nixpkgs/lib/types.nix
merge = loc: defs:
map (x: x.value) (filter (x: x ? value && x.value != null) (concatLists (imap1 (n: def:
if isList def.value then
imap1 (m: def':
(mergeDefinitions
(loc ++ ["[definition ${toString n}-entry ${toString m}]"])
elemType
[{ inherit (def) file; value = def'; }]
).optionalValue
) def.value
else
throw "The option value `${showOption loc}` in `${def.file}` is not a list.") defs)));
};
in {
{
# This is how the Nix expressions generated by *-to-nix receive
# their flags argument.
config._module.args.flags = config.flags;
config._module.args = mod_args // { flags = config.flags; };

options = {
options = (packageOptions parentConfig) // {
# TODO: Add descriptions to everything.
flags = mkOption {
type = attrsOf bool;
};

package = {
specVersion = mkOption {
type = str;
Expand Down Expand Up @@ -98,7 +81,8 @@ in {

components = let
componentType = submodule {
options = {
# add the shared componentOptions
options = (componentOptions config) // {
depends = mkOption {
type = listOfFilteringNulls unspecified;
default = [];
Expand All @@ -119,43 +103,6 @@ in {
type = listOfFilteringNulls unspecified;
default = [];
};
configureFlags = mkOption {
type = listOfFilteringNulls str;
default = config.configureFlags;
};
setupBuildFlags = mkOption {
type = listOfFilteringNulls str;
default = config.setupBuildFlags;
};
setupTestFlags = mkOption {
type = listOfFilteringNulls str;
default = config.setupTestFlags;
};
setupInstallFlags = mkOption {
type = listOfFilteringNulls str;
default = config.setupInstallFlags;
};
setupHaddockFlags = mkOption {
type = listOfFilteringNulls str;
default = config.setupHaddockFlags;
};
doExactConfig = mkOption {
type = bool;
default = config.doExactConfig;
};
doCheck = mkOption {
type = bool;
default = config.doCheck;
};
doCrossCheck = mkOption {
type = bool;
default = config.doCrossCheck;
};
doHaddock = mkOption {
description = "Enable building of the Haddock documentation from the annotated Haskell source code.";
type = bool;
default = config.doHaddock;
};
};
};
in {
Expand Down Expand Up @@ -224,96 +171,6 @@ in {
type = listOf (either unspecified path);
default = [];
};
configureFlags = mkOption {
type = listOfFilteringNulls str;
default = [];
};
setupBuildFlags = mkOption {
type = listOfFilteringNulls str;
default = [];
};
setupTestFlags = mkOption {
type = listOfFilteringNulls str;
default = [];
};
setupInstallFlags = mkOption {
type = listOfFilteringNulls str;
default = [];
};
setupHaddockFlags = mkOption {
type = listOfFilteringNulls str;
default = [];
};
preUnpack = mkOption {
type = nullOr lines;
default = null;
};
postUnpack = mkOption {
type = nullOr string;
default = null;
};
preConfigure = mkOption {
type = nullOr string;
default = null;
};
postConfigure = mkOption {
type = nullOr string;
default = null;
};
preBuild = mkOption {
type = nullOr string;
default = null;
};
postBuild = mkOption {
type = nullOr string;
default = null;
};
preCheck = mkOption {
type = nullOr string;
default = null;
};
postCheck = mkOption {
type = nullOr string;
default = null;
};
preInstall = mkOption {
type = nullOr string;
default = null;
};
postInstall = mkOption {
type = nullOr string;
default = null;
};
preHaddock = mkOption {
type = nullOr string;
default = null;
};
postHaddock = mkOption {
type = nullOr string;
default = null;
};
shellHook = mkOption {
type = nullOr string;
default = null;
};
doExactConfig = mkOption {
type = bool;
default = false;
};
doCheck = mkOption {
type = bool;
default = false;
};
doCrossCheck = mkOption {
description = "Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.";
type = bool;
default = false;
};
doHaddock = mkOption {
description = "Enable building of the Haddock documentation from the annotated Haskell source code.";
type = bool;
default = true;
};
};

# This has one quirk. Manually setting options on the all component
Expand Down
136 changes: 129 additions & 7 deletions modules/plan.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,139 @@
with lib;
with types;

{
options = {

let
# This is just like listOf, except that it filters out all null elements.
listOfFilteringNulls = elemType: listOf elemType // {
# Mostly copied from nixpkgs/lib/types.nix
merge = loc: defs:
map (x: x.value) (filter (x: x ? value && x.value != null) (concatLists (imap1 (n: def:
if isList def.value then
imap1 (m: def':
(mergeDefinitions
(loc ++ ["[definition ${toString n}-entry ${toString m}]"])
elemType
[{ inherit (def) file; value = def'; }]
).optionalValue
) def.value
else
throw "The option value `${showOption loc}` in `${def.file}` is not a list.") defs)));
};

componentOptions = def: {
configureFlags = mkOption {
type = listOfFilteringNulls str;
default = (def.configureFlags or []);
};
setupBuildFlags = mkOption {
type = listOfFilteringNulls str;
default = (def.setupBuildFlags or []);
};
setupTestFlags = mkOption {
type = listOfFilteringNulls str;
default = (def.setupTestFlags or []);
};
setupInstallFlags = mkOption {
type = listOfFilteringNulls str;
default = (def.setupInstallFlags or []);
};
setupHaddockFlags = mkOption {
type = listOfFilteringNulls str;
default = (def.setupHaddockFlags or []);
};
doExactConfig = mkOption {
type = bool;
default = (def.doExactConfig or false);
};
doCheck = mkOption {
type = bool;
default = (def.doCheck or false);
};
doCrossCheck = mkOption {
description = "Run doCheck also in cross compilation settings. This can be tricky as the test logic must know how to run the tests on the target.";
type = bool;
default = (def.doCrossCheck or false);
};
doHaddock = mkOption {
description = "Enable building of the Haddock documentation from the annotated Haskell source code.";
type = bool;
default = (def.doHaddock or true);
};
};
packageOptions = def: componentOptions def // {
preUnpack = mkOption {
type = nullOr lines;
default = (def.preUnpack or null);
};
postUnpack = mkOption {
type = nullOr string;
default = (def.postUnpack or null);
};
preConfigure = mkOption {
type = nullOr string;
default = (def.preConfigure or null);
};
postConfigure = mkOption {
type = nullOr string;
default = (def.postConfigure or null);
};
preBuild = mkOption {
type = nullOr string;
default = (def.preBuild or null);
};
postBuild = mkOption {
type = nullOr string;
default = (def.postBuild or null);
};
preCheck = mkOption {
type = nullOr string;
default = (def.preCheck or null);
};
postCheck = mkOption {
type = nullOr string;
default = (def.postCheck or null);
};
preInstall = mkOption {
type = nullOr string;
default = (def.preInstall or null);
};
postInstall = mkOption {
type = nullOr string;
default = (def.postInstall or null);
};
preHaddock = mkOption {
type = nullOr string;
default = (def.preHaddock or null);
};
postHaddock = mkOption {
type = nullOr string;
default = (def.postHaddock or null);
};
shellHook = mkOption {
type = nullOr string;
default = (def.shellHook or null);
};
};


in {
# Global options. These are passed down to the package level, and from there to the
# component level, unless specifically overridden. Depending on the flag flags are
# combined or replaced. We seed the package Options with an empty set forcing the
# default values.
options = (packageOptions {}) // {
packages = mkOption {
type = attrsOf (submodule {
imports = [./package.nix];
_module.args = {
type =
let mod_args = {
inherit pkgs pkgconfPkgs haskellLib;
inherit (config) hsPkgs;
inherit (config.cabal) system compiler;
};
});
}; in
attrsOf (submodule (import ./package.nix {
inherit mod_args listOfFilteringNulls;
inherit componentOptions packageOptions;
parentConfig = config;
}));
};

compiler = {
Expand Down