on master help sign in
Merge pull request #253 from obsidiansystems/config-default-compilers

Use Haskell overlays, temporarily expose __useLegacyCompilers

commitfa3e8bb0e5ef1a1ad85d3d9ee43d171f5aca9d92 authorLuigy Leon <luichi.19@gmail.com> dateThu 18 Oct 2018, 21:05 (8 years ago) parentb6fcaa2e0e2ca3
2 files changed+111−99
default.nix+109−97 dep/reflex-platform/github.json+2−2
default.nix+109−97
@@ -1,20 +1,13 @@
11{ system ? builtins.currentSystem
22, profiling ? false
33, iosSdkVersion ? "10.2"
4+, __useLegacyCompilers ? false
45}:
56let
6− getReflexPlatform = sys: import ./dep/reflex-platform { inherit iosSdkVersion; system = sys; enableLibraryProfiling = profiling; };
7− reflex-platform = getReflexPlatform system;
8− inherit (reflex-platform) hackGet nixpkgs;
9− pkgs = nixpkgs;
10−in with pkgs.haskell.lib; with pkgs.lib;
11−let
12− # TODO: Remove this after updating nixpkgs: https://github.com/NixOS/nixpkgs/issues/37750
13− justStaticExecutables' = drv: let
14− drv' = justStaticExecutables drv;
15− in if pkgs.stdenv.isDarwin
16− then removeConfigureFlag drv' "--ghc-option=-optl=-dead_strip"
17− else drv';
7+ cleanSource = builtins.filterSource (name: _: let baseName = builtins.baseNameOf name; in !(
8+ builtins.match "^\\.ghc\\.environment.*" baseName != null ||
9+ baseName == "cabal.project.local"
10+ ));
1811
1912 commandRuntimeDeps = pkgs: with pkgs; [
2013 coreutils
@@ -24,85 +17,108 @@ let
2417 openssh
2518 ];
2619
27− #TODO: Upstream
28− # Modify a Haskell package to add completion scripts for the given
29− # executable produced by it. These completion scripts will be picked up
30− # automatically if the resulting derivation is installed, e.g. by
31− # `nix-env -i`.
32− addOptparseApplicativeCompletionScripts = exeName: pkg: overrideCabal pkg (drv: {
33− postInstall = (drv.postInstall or "") + ''
34− BASH_COMP_DIR="$out/share/bash-completion/completions"
35− mkdir -p "$BASH_COMP_DIR"
36− "$out/bin/${exeName}" --bash-completion-script "$out/bin/${exeName}" >"$BASH_COMP_DIR/ob"
20+ getReflexPlatform = getReflexPlatform' __useLegacyCompilers;
21+ getReflexPlatform' = __useLegacyCompilers: sys: import ./dep/reflex-platform {
22+ inherit iosSdkVersion __useLegacyCompilers;
23+ system = sys;
24+ enableLibraryProfiling = profiling;
3725
38− ZSH_COMP_DIR="$out/share/zsh/vendor-completions"
39− mkdir -p "$ZSH_COMP_DIR"
40− "$out/bin/${exeName}" --zsh-completion-script "$out/bin/${exeName}" >"$ZSH_COMP_DIR/_ob"
26+ nixpkgsOverlays = [
27+ (self: super: {
28+ obeliskExecutableConfig = import ./lib/executable-config { nixpkgs = pkgs; filterGitSource = cleanSource; };
29+ })
30+ ];
4131
42− FISH_COMP_DIR="$out/share/fish/vendor_completions.d"
43− mkdir -p "$FISH_COMP_DIR"
44− "$out/bin/${exeName}" --fish-completion-script "$out/bin/${exeName}" >"$FISH_COMP_DIR/ob.fish"
45− '';
46− });
32+ haskellOverlays = [
4733
48− # The haskell environment used to build Obelisk itself, e.g. the 'ob' command
49− ghcObelisk = reflex-platform.ghc.override {
50− overrides = composeExtensions defaultHaskellOverrides (self: super: {
51− # Dynamic linking with split objects dramatically increases startup time (about 0.5 seconds on a decent machine with SSD)
52− obelisk-command = addOptparseApplicativeCompletionScripts "ob" (justStaticExecutables' super.obelisk-command);
53− });
54− };
34+ # Fix misc upstream packages
35+ (self: super: let
36+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
37+ in {
38+ # Need deriveSomeUniverse
39+ # PR: https://github.com/dmwit/universe/pull/32
40+ universe-template = self.callCabal2nix "universe-template" (pkgs.fetchFromGitHub {
41+ owner = "obsidiansystems";
42+ repo = "universe";
43+ rev = "5a2fc823caa4163411d7e41aa80e67cefb15944a";
44+ sha256 = "0ll2z0fh18z6x8jl8kbp7ldagwccz3wjmvrw1gw752z058n82yfa";
45+ } + /template) {};
46+ })
5547
56− fixUpstreamPkgs = self: super: {
57− # Need deriveSomeUniverse
58− # PR: https://github.com/dmwit/universe/pull/32
59− universe-template = self.callCabal2nix "universe-template" (pkgs.fetchFromGitHub {
60− owner = "obsidiansystems";
61− repo = "universe";
62− rev = "5a2fc823caa4163411d7e41aa80e67cefb15944a";
63− sha256 = "0ll2z0fh18z6x8jl8kbp7ldagwccz3wjmvrw1gw752z058n82yfa";
64− } + /template) {};
65− };
48+ # Add obelisk packages
49+ (self: super: let
50+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
51+ in {
52+ obelisk-asset-manifest = self.callCabal2nix "obelisk-asset-manifest" (hackGet ./lib/asset + "/manifest") {};
53+ obelisk-asset-serve-snap = self.callCabal2nix "obelisk-asset-serve-snap" (hackGet ./lib/asset + "/serve-snap") {};
54+ obelisk-backend = self.callCabal2nix "obelisk-backend" (cleanSource ./lib/backend) {};
55+ obelisk-cliapp = self.callCabal2nix "obelisk-cliapp" (cleanSource ./lib/cliapp) {};
56+ obelisk-command = (self.callCabal2nix "obelisk-command" (cleanSource ./lib/command) {}).overrideAttrs
57+ (drv: {
58+ buildInputs = drv.buildInputs ++ [ pkgs.makeWrapper ];
59+ postFixup = ''
60+ ${drv.postFixup or ""}
61+ # Make `ob` reference its runtime dependencies.
62+ wrapProgram "$out"/bin/ob --prefix PATH : ${pkgs.lib.makeBinPath (commandRuntimeDeps pkgs)}
63+ '';
64+ });
65+ obelisk-executable-config = pkgs.obeliskExecutableConfig.haskellPackage self;
66+ obelisk-executable-config-inject = pkgs.obeliskExecutableConfig.platforms.web.inject self;
67+ obelisk-frontend = self.callCabal2nix "obelisk-frontend" (cleanSource ./lib/frontend) {};
68+ obelisk-run = self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {};
69+ obelisk-route = self.callCabal2nix "obelisk-route" (cleanSource ./lib/route) {};
70+ obelisk-selftest = self.callCabal2nix "obelisk-selftest" (cleanSource ./lib/selftest) {};
71+ obelisk-snap = self.callCabal2nix "obelisk-snap" (cleanSource ./lib/snap) {};
72+ obelisk-snap-extras = self.callCabal2nix "obelisk-snap-extras" (cleanSource ./lib/snap-extras) {};
73+ })
6674
67− cleanSource = builtins.filterSource (name: _: let baseName = builtins.baseNameOf name; in !(
68− builtins.match "^\\.ghc\\.environment.*" baseName != null ||
69− baseName == "cabal.project.local"
70− ));
75+ # Dynamic linking with split objects dramatically increases startup time (about 0.5 seconds on a decent machine with SSD)
76+ (self: super: let
77+ pkgs = self.callPackage ({ pkgs }: pkgs) {};
78+ haskellLib = pkgs.haskell.lib;
79+ #TODO: Upstream
80+ # Modify a Haskell package to add completion scripts for the given
81+ # executable produced by it. These completion scripts will be picked up
82+ # automatically if the resulting derivation is installed, e.g. by
83+ # `nix-env -i`.
84+ addOptparseApplicativeCompletionScripts = exeName: pkg: haskellLib.overrideCabal pkg (drv: {
85+ postInstall = (drv.postInstall or "") + ''
86+ BASH_COMP_DIR="$out/share/bash-completion/completions"
87+ mkdir -p "$BASH_COMP_DIR"
88+ "$out/bin/${exeName}" --bash-completion-script "$out/bin/${exeName}" >"$BASH_COMP_DIR/ob"
7189
72− executableConfig = import ./lib/executable-config { nixpkgs = pkgs; filterGitSource = cleanSource; };
90+ ZSH_COMP_DIR="$out/share/zsh/vendor-completions"
91+ mkdir -p "$ZSH_COMP_DIR"
92+ "$out/bin/${exeName}" --zsh-completion-script "$out/bin/${exeName}" >"$ZSH_COMP_DIR/_ob"
7393
74− addLibs = self: super: {
75− obelisk-asset-manifest = self.callCabal2nix "obelisk-asset-manifest" (hackGet ./lib/asset + "/manifest") {};
76− obelisk-asset-serve-snap = self.callCabal2nix "obelisk-asset-serve-snap" (hackGet ./lib/asset + "/serve-snap") {};
77− obelisk-backend = self.callCabal2nix "obelisk-backend" (cleanSource ./lib/backend) {};
78− obelisk-cliapp = self.callCabal2nix "obelisk-cliapp" (cleanSource ./lib/cliapp) {};
79− obelisk-command = (self.callCabal2nix "obelisk-command" (cleanSource ./lib/command) {}).overrideAttrs
80− (drv: {
81− buildInputs = drv.buildInputs ++ [ pkgs.makeWrapper ];
82− postFixup = ''
83− ${drv.postFixup or ""}
84− # Make `ob` reference its runtime dependencies.
85− wrapProgram "$out"/bin/ob --prefix PATH : ${pkgs.lib.makeBinPath (commandRuntimeDeps pkgs)}
86− '';
87− });
88− obelisk-executable-config = executableConfig.haskellPackage self;
89− obelisk-executable-config-inject = executableConfig.platforms.web.inject self;
90− obelisk-frontend = self.callCabal2nix "obelisk-frontend" (cleanSource ./lib/frontend) {};
91− obelisk-run = self.callCabal2nix "obelisk-run" (cleanSource ./lib/run) {};
92− obelisk-route = self.callCabal2nix "obelisk-route" (cleanSource ./lib/route) {};
93− obelisk-selftest = self.callCabal2nix "obelisk-selftest" (cleanSource ./lib/selftest) {};
94− obelisk-snap = self.callCabal2nix "obelisk-snap" (cleanSource ./lib/snap) {};
95− obelisk-snap-extras = self.callCabal2nix "obelisk-snap-extras" (cleanSource ./lib/snap-extras) {};
94+ FISH_COMP_DIR="$out/share/fish/vendor_completions.d"
95+ mkdir -p "$FISH_COMP_DIR"
96+ "$out/bin/${exeName}" --fish-completion-script "$out/bin/${exeName}" >"$FISH_COMP_DIR/ob.fish"
97+ '';
98+ });
99+ in {
100+ obelisk-command = addOptparseApplicativeCompletionScripts "ob" (haskellLib.justStaticExecutables super.obelisk-command);
101+ obelisk-selftest = haskellLib.justStaticExecutables super.obelisk-selftest;
102+ })
103+
104+ ];
96105 };
97106
107+ reflex-platform = getReflexPlatform' false system;
108+ inherit (reflex-platform) hackGet nixpkgs;
109+ pkgs = nixpkgs;
110+
111+ # The haskell environment used to build Obelisk itself, e.g. the 'ob' command
112+ ghcObelisk = reflex-platform.ghc;
113+
98114 inherit (import ./lib/asset/assets.nix { inherit nixpkgs; }) mkAssets;
99115
100− defaultHaskellOverrides = composeExtensions fixUpstreamPkgs addLibs;
101−in
102−with pkgs.lib;
103−rec {
116+ haskellLib = pkgs.haskell.lib;
117+
118+in rec {
104119 inherit reflex-platform;
105120 inherit (reflex-platform) nixpkgs pinBuildInputs;
121+ inherit (nixpkgs) lib;
106122 pathGit = ./.; # Used in CI by the migration graph hash algorithm to correctly ignore files.
107123 path = reflex-platform.filterGit ./.;
108124 obelisk = ghcObelisk;
@@ -115,7 +131,7 @@ rec {
115131
116132 PATH="${command}/bin:$PATH"
117133 export OBELISK_IMPL="${hackGet ./.}"
118− "${justStaticExecutables' ghcObelisk.obelisk-selftest}/bin/obelisk-selftest" "$@"
134+ "${ghcObelisk.obelisk-selftest}/bin/obelisk-selftest" "$@"
119135 '';
120136 #TODO: Why can't I build ./skeleton directly as a derivation? `nix-build -E ./.` doesn't work
121137 skeleton = pkgs.runCommand "skeleton" {
@@ -123,8 +139,7 @@ rec {
123139 } ''
124140 ln -s "$dir" "$out"
125141 '';
126− nullIfAbsent = p: if pathExists p then p else null;
127− haskellOverrides = addLibs;
142+ nullIfAbsent = p: if lib.pathExists p then p else null;
128143 #TODO: Avoid copying files within the nix store. Right now, obelisk-asset-manifest-generate copies files into a big blob so that the android/ios static assets can be imported from there; instead, we should get everything lined up right before turning it into an APK, so that copies, if necessary, only exist temporarily.
129144 processAssets = { src, packageName ? "obelisk-generated-static", moduleName ? "Obelisk.Generated.Static" }: pkgs.runCommand "asset-manifest" {
130145 inherit src;
@@ -141,7 +156,7 @@ rec {
141156 compressedJs = frontend: pkgs.runCommand "compressedJs" { buildInputs = [ pkgs.closurecompiler ]; } ''
142157 mkdir $out
143158 cd $out
144− ln -s "${justStaticExecutables frontend}/bin/frontend.jsexe/all.js" all.unminified.js
159+ ln -s "${haskellLib.justStaticExecutables frontend}/bin/frontend.jsexe/all.js" all.unminified.js
145160 closure-compiler --externs "${reflex-platform.ghcjsExternsJs}" -O ADVANCED --jscomp_warning=checkVars --create_source_map="all.js.map" --source_map_format=V3 --js_output_file="all.js" all.unminified.js
146161 echo "//# sourceMappingURL=all.js.map" >> all.js
147162 '';
@@ -217,7 +232,7 @@ rec {
217232 pkgs.runCommand "serverExe" {} ''
218233 mkdir $out
219234 set -eux
220− ln -s "${justStaticExecutables backend}"/bin/* $out/
235+ ln -s "${haskellLib.justStaticExecutables backend}"/bin/* $out/
221236 ln -s "${mkAssets assets}" $out/static.assets
222237 cp -r ${config} $out/config
223238 ln -s ${mkAssets (compressedJs frontend)} $out/frontend.jsexe.assets
@@ -257,18 +272,17 @@ rec {
257272 staticName = "obelisk-generated-static";
258273 staticPath = base + "/static";
259274 # The packages whose names and roles are defined by this package
260− predefinedPackages = filterAttrs (_: x: x != null) {
275+ predefinedPackages = lib.filterAttrs (_: x: x != null) {
261276 ${frontendName} = nullIfAbsent (base + "/frontend");
262277 ${commonName} = nullIfAbsent (base + "/common");
263278 ${backendName} = nullIfAbsent (base + "/backend");
264279 };
265280 combinedPackages = predefinedPackages // packages;
266281 projectOverrides = self: super: {
267− ${staticName} = dontHaddock (self.callCabal2nix "static" processedStatic.haskellManifest {});
268− ${backendName} = addBuildDepend super.${backendName} self.obelisk-run;
282+ ${staticName} = haskellLib.dontHaddock (self.callCabal2nix "static" processedStatic.haskellManifest {});
283+ ${backendName} = haskellLib.addBuildDepend super.${backendName} self.obelisk-run;
269284 };
270− totalOverrides = composeExtensions (composeExtensions defaultHaskellOverrides projectOverrides) overrides;
271− inherit (nixpkgs) lib;
285+ totalOverrides = lib.composeExtensions projectOverrides overrides;
272286 inherit (lib.strings) hasPrefix;
273287 privateConfigDirs = ["config/backend"];
274288 injectableConfig = builtins.filterSource (path: _:
@@ -279,16 +293,16 @@ rec {
279293 overrides = totalOverrides;
280294 packages = combinedPackages;
281295 shells = {
282− ghcSavedSplices = (filter (x: hasAttr x combinedPackages) [
296+ ghcSavedSplices = (lib.filter (x: lib.hasAttr x combinedPackages) [
283297 commonName
284298 frontendName
285299 ]);
286− ghc = (filter (x: hasAttr x combinedPackages) [
300+ ghc = (lib.filter (x: lib.hasAttr x combinedPackages) [
287301 backendName
288302 commonName
289303 frontendName
290304 ]);
291− ghcjs = filter (x: hasAttr x combinedPackages) [
305+ ghcjs = lib.filter (x: lib.hasAttr x combinedPackages) [
292306 frontendName
293307 commonName
294308 ];
@@ -297,14 +311,14 @@ rec {
297311 ${if android == null then null else frontendName} = {
298312 executableName = "frontend";
299313 ${if builtins.pathExists staticPath then "assets" else null} =
300− executableConfig.platforms.android.inject injectableConfig processedStatic.symlinked;
314+ nixpkgs.obeliskExecutableConfig.platforms.android.inject injectableConfig processedStatic.symlinked;
301315 } // android;
302316 };
303317 ios = {
304318 ${if ios == null then null else frontendName} = {
305319 executableName = "frontend";
306320 ${if builtins.pathExists staticPath then "staticSrc" else null} =
307− executableConfig.platforms.ios.inject injectableConfig processedStatic.symlinked;
321+ nixpkgs.obeliskExecutableConfig.platforms.ios.inject injectableConfig processedStatic.symlinked;
308322 } // ios;
309323 };
310324 };
@@ -316,13 +330,11 @@ rec {
316330 linuxExe = linuxExe (base + "/config");
317331 exe = serverOn system (base + "/config") ;
318332 server = args@{ hostName, adminEmail, routeHost, enableHttps, config }: let
319− injectableConfig = builtins.filterSource (path: _: !(hasPrefix (toString config + "/backend") (toString path))) config;
333+ injectableConfig = builtins.filterSource (path: _: !(lib.hasPrefix (toString config + "/backend") (toString path))) config;
320334 in server (args // { exe = linuxExe injectableConfig; });
321335 obelisk = import (base + "/.obelisk/impl") {};
322336 };
323337 haskellPackageSets = {
324− ghc = reflex-platform.ghc.override {
325− overrides = defaultHaskellOverrides;
326− };
338+ inherit (reflex-platform) ghc;
327339 };
328340}
dep/reflex-platform/github.json+2−2
@@ -2,6 +2,6 @@
22 "owner": "reflex-frp",
33 "repo": "reflex-platform",
44 "branch": "develop",
5− "rev": "2f09cea8aea453969172fe1f499905af5afb4719",
6− "sha256": "1v7v2fwahq4mcywjvg1i44jyqimpxd4kgn4x4a24lcdgw9yll9wg"
5+ "rev": "0c022883469da05987810557b61d37b7ae3e922e",
6+ "sha256": "0aissxk9fpzymvr4qqnwkfvr5jya2h7qrxbx5byg0dv627six8yw"
77}