on iko/ghcjs-patch-master help sign in
Add cross compilation and devShell to project.flake (#1141)
c3841b4Hamish Mackenzie
@@ -4,9 +4,8 @@
4 inputs = {
4 inputs = {
5 # Note: keep this in sync with sources.json!
5 # Note: keep this in sync with sources.json!
6 nixpkgs.url = github:NixOS/nixpkgs/f02bf8ffb9a5ec5e8f6f66f1e5544fd2aa1a0693;
6 nixpkgs.url = github:NixOS/nixpkgs/f02bf8ffb9a5ec5e8f6f66f1e5544fd2aa1a0693;
7− nixpkgs-2003.url = github:NixOS/nixpkgs/7f73e46625f508a793700f5110b86f1a53341d6e;
8 nixpkgs-2009.url = github:NixOS/nixpkgs/f02bf8ffb9a5ec5e8f6f66f1e5544fd2aa1a0693;
7 nixpkgs-2009.url = github:NixOS/nixpkgs/f02bf8ffb9a5ec5e8f6f66f1e5544fd2aa1a0693;
9− nixpkgs-unstable.url = github:NixOS/nixpkgs/410bbd828cdc6156aecd5bc91772ad3a6b1099c7;
8+ nixpkgs-unstable.url = github:NixOS/nixpkgs/d8eb97e3801bde96491535f40483d550b57605b9;
10 };
9 };
11
10
12 outputs = { self, nixpkgs, ... }:
11 outputs = { self, nixpkgs, ... }:
@@ -14,14 +13,10 @@
14
13
15 internal = rec {
14 internal = rec {
16 config = import ./config.nix;
15 config = import ./config.nix;
17− # We can't import ./nix/sources.nix directly, because that uses nixpkgs to fetch by default,
16+ # Use a shim for pkgs that does not depend on `builtins.currentSystem`.
18− # and importing nixpkgs without specifying localSystem doesn't work on flakes.
17+ sources = import ./nix/sources.nix {
19− sources = let
20− sourcesInfo =
21− builtins.fromJSON (builtins.readFile ./nix/sources.json);
22− fetch = sourceInfo:
23− builtins.fetchTarball { inherit (sourceInfo) url sha256; };
18+ pkgs = { fetchzip = builtins.fetchTarball; };
24− in builtins.mapAttrs (_: fetch) sourcesInfo;
19+ };
25
20
26 nixpkgsArgs = {
21 nixpkgsArgs = {
27 inherit config;
22 inherit config;
modules/cabal-project.nix+13
@@ -8,6 +8,7 @@ let readIfExists = src: fileName:
8 then __readFile (origSrcDir + "/${fileName}")
8 then __readFile (origSrcDir + "/${fileName}")
9 else null;
9 else null;
10in {
10in {
11+ _file = "haskell.nix/modules/cabal-project.nix";
11 options = {
12 options = {
12 # Used by callCabalProjectToNix
13 # Used by callCabalProjectToNix
13 name = mkOption {
14 name = mkOption {
@@ -136,5 +137,17 @@ in {
136 type = nullOr (listOf unspecified);
137 type = nullOr (listOf unspecified);
137 default = [];
138 default = [];
138 };
139 };
140+
141+ # Default shell arguments
142+ shell = mkOption {
143+ # TODO make this a submodule
144+ type = unspecified;
145+ default = {};
146+ description = ''
147+ Arguments to use for the default shell `p.shell` (these are passed to p.shellFor).
148+ For instance to include `cabal` and `ghcjs` support use
149+ shell = { tools.cabal = {}; crossPlatforms = p: [ p.ghcjs ]; }
150+ '';
151+ };
139 };
152 };
140}
153}
modules/stack-project.nix+13
@@ -2,6 +2,7 @@
2with lib;
2with lib;
3with types;
3with types;
4{
4{
5+ _file = "haskell.nix/modules/stack-project.nix";
5 options = {
6 options = {
6 # Used by callStackToNix
7 # Used by callStackToNix
7 name = mkOption {
8 name = mkOption {
@@ -108,5 +109,17 @@ with types;
108 default = null;
109 default = null;
109 description = "Deprecated in favour of `compiler-nix-name`";
110 description = "Deprecated in favour of `compiler-nix-name`";
110 };
111 };
112+
113+ # Default shell arguments
114+ shell = mkOption {
115+ # TODO make this a submodule
116+ type = unspecified;
117+ default = {};
118+ description = ''
119+ Arguments to use for the default shell `p.shell` (these are passed to p.shellFor).
120+ For instance to include `cabal` and `ghcjs` support use
121+ shell = { tools.cabal = {}; crossPlatforms = p: [ p.ghcjs ]; }
122+ '';
123+ };
111 };
124 };
112}
125}
overlays/haskell.nix+52−33
@@ -543,6 +543,9 @@ final: prev: {
543 final.lib.fix (project':
543 final.lib.fix (project':
544 let project = project' // { recurseForDerivations = false; };
544 let project = project' // { recurseForDerivations = false; };
545 in rawProject // rec {
545 in rawProject // rec {
546+ # It is often handy to be able to get nix pkgs from the project.
547+ pkgs = final;
548+ # Haskell packages
546 hsPkgs = final.lib.mapAttrs (packageName: package':
549 hsPkgs = final.lib.mapAttrs (packageName: package':
547 if package' == null
550 if package' == null
548 then null
551 then null
@@ -648,6 +651,9 @@ final: prev: {
648 inputsFrom = args'.inputsFrom or [] ++ crossShells;
651 inputsFrom = args'.inputsFrom or [] ++ crossShells;
649 });
652 });
650
653
654+ # Default shell
655+ shell = shellFor rawProject.args.shell;
656+
651 # Like `.hsPkgs.${packageName}` but when compined with `getComponent` any
657 # Like `.hsPkgs.${packageName}` but when compined with `getComponent` any
652 # cabal configure errors are defered until the components derivation builds.
658 # cabal configure errors are defered until the components derivation builds.
653 getPackage = packageName:
659 getPackage = packageName:
@@ -697,51 +703,64 @@ final: prev: {
697 # `checks` and `apps` output attributes.
703 # `checks` and `apps` output attributes.
698 flake = {
704 flake = {
699 packages ? haskellLib.selectProjectPackages
705 packages ? haskellLib.selectProjectPackages
706+ , crossPlatforms ? p: []
700 }:
707 }:
701− let packageNames = builtins.attrNames (packages project.hsPkgs);
708+ let packageNames = project: builtins.attrNames (packages project.hsPkgs);
709+ packagesForProject = prefix: project:
710+ final.lib.concatMap (packageName:
711+ let package = project.hsPkgs.${packageName};
712+ in final.lib.optional (package.components ? library)
713+ { name = "${prefix}${packageName}:lib:${packageName}"; value = package.components.library; }
714+ ++ final.lib.mapAttrsToList (n: v:
715+ { name = "${prefix}${packageName}:lib:${n}"; value = v; })
716+ (package.components.sublibs)
717+ ++ final.lib.mapAttrsToList (n: v:
718+ { name = "${prefix}${packageName}:exe:${n}"; value = v; })
719+ (package.components.exes)
720+ ++ final.lib.mapAttrsToList (n: v:
721+ { name = "${prefix}${packageName}:test:${n}"; value = v; })
722+ (package.components.tests)
723+ ) (packageNames project);
724+ checksForProject = prefix: project:
725+ final.lib.concatMap (packageName:
726+ let package = project.hsPkgs.${packageName};
727+ in final.lib.mapAttrsToList (n: v:
728+ { name = "${packageName}:test:${n}"; value = v; })
729+ (final.lib.filterAttrs (_: v: final.lib.isDerivation v) (package.checks))
730+ ) (packageNames project);
731+ appsForProject = prefix: project:
732+ final.lib.concatMap (packageName:
733+ let package = project.hsPkgs.${packageName};
734+ in final.lib.mapAttrsToList (n: v:
735+ { name = "${packageName}:exe:${n}"; value = { type = "app"; program = v.exePath; }; })
736+ (package.components.exes)
737+ ++ final.lib.mapAttrsToList (n: v:
738+ { name = "${packageName}:test:${n}"; value = { type = "app"; program = v.exePath; }; })
739+ (package.components.tests)
740+ ) (packageNames project);
741+ attrsForAllProjects = f: builtins.listToAttrs (
742+ f "" project
743+ ++ final.lib.concatMap (project:
744+ f (project.pkgs.stdenv.hostPlatform.config + ":") project)
745+ (crossPlatforms project.projectCross)
746+ );
702 in {
747 in {
703 # Used by:
748 # Used by:
704 # `nix build .#pkg-name:lib:pkg-name`
749 # `nix build .#pkg-name:lib:pkg-name`
705 # `nix build .#pkg-name:lib:sublib-name`
750 # `nix build .#pkg-name:lib:sublib-name`
706 # `nix build .#pkg-name:exe:exe-name`
751 # `nix build .#pkg-name:exe:exe-name`
707 # `nix build .#pkg-name:test:test-name`
752 # `nix build .#pkg-name:test:test-name`
708− packages = builtins.listToAttrs (
753+ packages = attrsForAllProjects packagesForProject;
709− final.lib.concatMap (packageName:
710− let package = project.hsPkgs.${packageName};
711− in final.lib.optional (package.components ? library)
712− { name = "${packageName}:lib:${packageName}"; value = package.components.library; }
713− ++ final.lib.mapAttrsToList (n: v:
714− { name = "${packageName}:lib:${n}"; value = v; })
715− (package.components.sublibs)
716− ++ final.lib.mapAttrsToList (n: v:
717− { name = "${packageName}:exe:${n}"; value = v; })
718− (package.components.exes)
719− ++ final.lib.mapAttrsToList (n: v:
720− { name = "${packageName}:test:${n}"; value = v; })
721− (package.components.tests)
722− ) packageNames);
723 # Used by:
754 # Used by:
724 # `nix check .#pkg-name:test:test-name`
755 # `nix check .#pkg-name:test:test-name`
725− checks = builtins.listToAttrs (
756+ checks = attrsForAllProjects checksForProject;
726− final.lib.concatMap (packageName:
727− let package = project.hsPkgs.${packageName};
728− in final.lib.mapAttrsToList (n: v:
729− { name = "${packageName}:test:${n}"; value = v; })
730− (final.lib.filterAttrs (_: v: final.lib.isDerivation v) (package.checks))
731− ) packageNames);
732 # Used by:
757 # Used by:
733 # `nix run .#pkg-name:exe:exe-name`
758 # `nix run .#pkg-name:exe:exe-name`
734 # `nix run .#pkg-name:test:test-name`
759 # `nix run .#pkg-name:test:test-name`
735− apps = builtins.listToAttrs (
760+ apps = attrsForAllProjects appsForProject;
736− final.lib.concatMap (packageName:
761+ # Used by:
737− let package = project.hsPkgs.${packageName};
762+ # `nix develop`
738− in final.lib.mapAttrsToList (n: v:
763+ devShell = project.shell;
739− { name = "${packageName}:exe:${n}"; value = { type = "app"; program = v.exePath; }; })
740− (package.components.exes)
741− ++ final.lib.mapAttrsToList (n: v:
742− { name = "${packageName}:test:${n}"; value = { type = "app"; program = v.exePath; }; })
743− (package.components.tests)
744− ) packageNames);
745 };
764 };
746 inherit (rawProject.hsPkgs) makeConfigFiles ghcWithHoogle ghcWithPackages;
765 inherit (rawProject.hsPkgs) makeConfigFiles ghcWithHoogle ghcWithPackages;
747 });
766 });