Created
August 3, 2018 03:46
-
-
Save YuMingLiao/1682a571dcad9e3d50a9d6631b1e51db to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ nixpkgsFunc ? import ./nixpkgs | |
, system ? builtins.currentSystem | |
, config ? {} | |
, enableLibraryProfiling ? false | |
, enableExposeAllUnfoldings ? true | |
, enableTraceReflexEvents ? false | |
, useFastWeak ? true | |
, useReflexOptimizer ? false | |
, useTextJSString ? true | |
, iosSdkVersion ? "10.2" | |
, iosSdkLocation ? "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${iosSdkVersion}.sdk" | |
, iosSupportForce ? false | |
}: | |
let iosSupport = | |
if system != "x86_64-darwin" then false | |
else if iosSupportForce || builtins.pathExists iosSdkLocation then true | |
else builtins.trace "Warning: No iOS sdk found at ${iosSdkLocation}; iOS support disabled. To enable, either install a version of Xcode that provides that SDK or override the value of iosSdkVersion to match your installed version." false; | |
globalOverlay = self: super: { | |
all-cabal-hashes = super.all-cabal-hashes.override { | |
src-spec = { | |
owner = "commercialhaskell"; | |
repo = "all-cabal-hashes"; | |
rev = "82a8a1a49240a1b465c95de6fa6bf56323ee858f"; | |
sha256 = "1jdzl5fyp1qcsi1anjig6kglq4jjsdll53nissjcnxpy3jscmarm"; | |
}; | |
}; | |
}; | |
appleLibiconvHack = self: super: { | |
darwin = super.darwin // { | |
libiconv = | |
if self.hostPlatform == self.buildPlatform | |
then super.darwin.libiconv | |
else super.darwin.libiconv.overrideAttrs (o: { | |
postInstall = "rm $out/include/libcharset.h $out/include/localcharset.h"; | |
configureFlags = ["--disable-shared" "--enable-static"]; | |
}); | |
}; | |
}; | |
nixpkgs = nixpkgsFunc ({ | |
inherit system; | |
overlays = [globalOverlay]; | |
config = { | |
allowUnfree = true; | |
allowBroken = true; # GHCJS is marked broken in 011c149ed5e5a336c3039f0b9d4303020cff1d86 | |
permittedInsecurePackages = [ | |
"webkitgtk-2.4.11" | |
]; | |
packageOverrides = pkgs: { | |
webkitgtk = pkgs.webkitgtk216x; | |
# cabal2nix's tests crash on 32-bit linux; see https://github.com/NixOS/cabal2nix/issues/272 | |
${if system == "i686-linux" then "cabal2nix" else null} = pkgs.haskell.lib.dontCheck pkgs.cabal2nix; | |
}; | |
} // config; | |
}); | |
inherit (nixpkgs) fetchurl fetchgit fetchgitPrivate fetchFromGitHub; | |
nixpkgsCross = { | |
android = nixpkgs.lib.mapAttrs (_: args: if args == null then null else nixpkgsFunc args) rec { | |
arm64 = { | |
system = "x86_64-linux"; | |
overlays = [globalOverlay]; | |
crossSystem = { | |
config = "aarch64-unknown-linux-android"; | |
arch = "arm64"; | |
libc = "bionic"; | |
withTLS = true; | |
openssl.system = "linux-generic64"; | |
platform = nixpkgs.pkgs.platforms.aarch64-multiplatform; | |
}; | |
config.allowUnfree = true; | |
}; | |
arm64Impure = arm64 // { | |
crossSystem = arm64.crossSystem // { useAndroidPrebuilt = true; }; | |
}; | |
armv7a = { | |
system = "x86_64-linux"; | |
overlays = [globalOverlay]; | |
crossSystem = { | |
config = "arm-unknown-linux-androideabi"; | |
arch = "armv7"; | |
libc = "bionic"; | |
withTLS = true; | |
openssl.system = "linux-generic32"; | |
platform = nixpkgs.pkgs.platforms.armv7l-hf-multiplatform; | |
}; | |
config.allowUnfree = true; | |
}; | |
armv7aImpure = armv7a // { | |
crossSystem = armv7a.crossSystem // { useAndroidPrebuilt = true; }; | |
}; | |
}; | |
ios = | |
let config = { | |
allowUnfree = true; | |
packageOverrides = p: { | |
darwin = p.darwin // { | |
ios-cross = p.darwin.ios-cross.override { | |
# Depending on where ghcHEAD is in your nixpkgs checkout, you may need llvm 39 here instead | |
inherit (p.llvmPackages_39) llvm clang; | |
}; | |
}; | |
buildPackages = p.buildPackages // { | |
osx_sdk = p.buildPackages.callPackage ({ stdenv }: | |
let version = "10"; | |
in stdenv.mkDerivation rec { | |
name = "iOS.sdk"; | |
src = p.stdenv.cc.sdk; | |
unpackPhase = "true"; | |
configurePhase = "true"; | |
buildPhase = "true"; | |
target_prefix = stdenv.lib.replaceStrings ["-"] ["_"] p.targetPlatform.config; | |
setupHook = ./scripts/setup-hook-ios.sh; | |
installPhase = '' | |
mkdir -p $out/ | |
echo "Source is: $src" | |
cp -r $src/* $out/ | |
''; | |
meta = with stdenv.lib; { | |
description = "The IOS OS ${version} SDK"; | |
maintainers = with maintainers; [ copumpkin ]; | |
platforms = platforms.darwin; | |
license = licenses.unfree; | |
}; | |
}) {}; | |
}; | |
}; | |
}; | |
in nixpkgs.lib.mapAttrs (_: args: if args == null then null else nixpkgsFunc args) { | |
simulator64 = { | |
system = "x86_64-darwin"; | |
overlays = [globalOverlay appleLibiconvHack]; | |
crossSystem = { | |
useIosPrebuilt = true; | |
# You can change config/arch/isiPhoneSimulator depending on your target: | |
# aarch64-apple-darwin14 | arm64 | false | |
# arm-apple-darwin10 | armv7 | false | |
# i386-apple-darwin11 | i386 | true | |
# x86_64-apple-darwin14 | x86_64 | true | |
config = "x86_64-apple-darwin14"; | |
arch = "x86_64"; | |
isiPhoneSimulator = true; | |
sdkVer = iosSdkVersion; | |
useiOSCross = true; | |
openssl.system = "darwin64-x86_64-cc"; | |
libc = "libSystem"; | |
}; | |
inherit config; | |
}; | |
arm64 = { | |
system = "x86_64-darwin"; | |
overlays = [globalOverlay appleLibiconvHack]; | |
crossSystem = { | |
useIosPrebuilt = true; | |
# You can change config/arch/isiPhoneSimulator depending on your target: | |
# aarch64-apple-darwin14 | arm64 | false | |
# arm-apple-darwin10 | armv7 | false | |
# i386-apple-darwin11 | i386 | true | |
# x86_64-apple-darwin14 | x86_64 | true | |
config = "aarch64-apple-darwin14"; | |
arch = "arm64"; | |
isiPhoneSimulator = false; | |
sdkVer = iosSdkVersion; | |
useiOSCross = true; | |
openssl.system = "ios64-cross"; | |
libc = "libSystem"; | |
}; | |
inherit config; | |
}; | |
}; | |
}; | |
haskellLib = nixpkgs.haskell.lib; | |
filterGit = builtins.filterSource (path: type: !(builtins.any (x: x == baseNameOf path) [".git" "tags" "TAGS" "dist"])); | |
# Retrieve source that is controlled by the hack-* scripts; it may be either a stub or a checked-out git repo | |
hackGet = p: | |
if builtins.pathExists (p + "/git.json") then ( | |
let gitArgs = builtins.fromJSON (builtins.readFile (p + "/git.json")); | |
in if builtins.elem "@" (nixpkgs.lib.stringToCharacters gitArgs.url) | |
then fetchgitPrivate gitArgs | |
else fetchgit gitArgs) | |
else if builtins.pathExists (p + "/github.json") then fetchFromGitHub (builtins.fromJSON (builtins.readFile (p + "/github.json"))) | |
else { | |
name = baseNameOf p; | |
outPath = filterGit p; | |
}; | |
# All imports of sources need to go here, so that they can be explicitly cached | |
sources = { | |
ghcjs-boot = hackGet ./ghcjs-boot; | |
shims = hackGet ./shims; | |
ghcjs = hackGet ./ghcjs; | |
}; | |
inherit (nixpkgs.stdenv.lib) optional optionals optionalAttrs; | |
optionalExtension = cond: overlay: if cond then overlay else _: _: {}; | |
in with haskellLib; | |
let overrideCabal = pkg: f: if pkg == null then null else haskellLib.overrideCabal pkg f; | |
replaceSrc = pkg: src: version: overrideCabal pkg (drv: { | |
inherit src version; | |
sha256 = null; | |
revision = null; | |
editedCabalFile = null; | |
}); | |
combineOverrides = old: new: (old // new) // { | |
overrides = nixpkgs.lib.composeExtensions old.overrides new.overrides; | |
}; | |
makeRecursivelyOverridable = x: old: x.override old // { | |
override = new: makeRecursivelyOverridable x (combineOverrides old new); | |
}; | |
foreignLibSmuggleHeaders = pkg: overrideCabal pkg (drv: { | |
postInstall = '' | |
cd dist/build/${pkg.pname}/${pkg.pname}-tmp | |
for header in $(find . | grep '\.h'$); do | |
local dest_dir=$out/include/$(dirname "$header") | |
mkdir -p "$dest_dir" | |
cp "$header" "$dest_dir" | |
done | |
''; | |
}); | |
cabal2nixResult = src: builtins.trace "cabal2nixResult is deprecated; use ghc.haskellSrc2nix or ghc.callCabal2nix instead" (ghc.haskellSrc2nix { | |
name = "for-unknown-package"; | |
src = "file://${src}"; | |
sha256 = null; | |
}); | |
addReflexTraceEventsFlag = if enableTraceReflexEvents | |
then drv: appendConfigureFlag drv "-fdebug-trace-events" | |
else drv: drv; | |
addFastWeakFlag = if useFastWeak | |
then drv: enableCabalFlag drv "fast-weak" | |
else drv: drv; | |
extendHaskellPackages = haskellPackages: makeRecursivelyOverridable haskellPackages { | |
overrides = self: super: | |
let reflexDom = import (hackGet ./reflex-dom) self nixpkgs; | |
jsaddlePkgs = import (hackGet ./jsaddle) self; | |
gargoylePkgs = self.callPackage (hackGet ./gargoyle) self; | |
ghcjsDom = import (hackGet ./ghcjs-dom) self; | |
addReflexOptimizerFlag = if useReflexOptimizer && (self.ghc.cross or null) == null | |
then drv: appendConfigureFlag drv "-fuse-reflex-optimizer" | |
else drv: drv; | |
in { | |
base-compat = self.callHackage "base-compat" "0.9.2" {}; | |
constraints = self.callHackage "constraints" "0.9" {}; | |
servant-auth-server = self.callHackage "servant-auth-server" "0.3.1.0" {}; | |
vector = doJailbreak super.vector; | |
these = doJailbreak super.these; | |
aeson-compat = doJailbreak super.aeson-compat; | |
timezone-series = self.callCabal2nix "timezone-series" (fetchFromGitHub { | |
owner = "ygale"; | |
repo = "timezone-series"; | |
rev = "9f42baf542c54ad554bd53582819eaa454ed633d"; | |
sha256 = "1axrx8lziwi6pixws4lq3yz871vxi81rib6cpdl62xb5bh9y03j6"; | |
}) {}; | |
timezone-olson = self.callCabal2nix "timezone-olson" (fetchFromGitHub { | |
owner = "ygale"; | |
repo = "timezone-olson"; | |
rev = "aecec86be48580f23145ffb3bf12a4ae191d12d3"; | |
sha256 = "1xxbwb8z27qbcscbg5qdyzlc2czg5i3b0y04s9h36hfcb07hasnz"; | |
}) {}; | |
quickcheck-instances = doJailbreak super.quickcheck-instances; | |
haskell-src-meta = self.callHackage "haskell-src-meta" "0.8.0.1" {}; | |
gtk2hs-buildtools = doJailbreak super.gtk2hs-buildtools; | |
# hindent was overriden with a newer version of haskell-src-exts for some reason | |
hindent = super.hindent.override { haskell-src-exts = self.haskell-src-exts; }; | |
# Not sure why these tests fail... | |
hfmt = dontCheck super.hfmt; | |
######################################################################## | |
# Reflex packages | |
######################################################################## | |
reflex = addFastWeakFlag (addReflexTraceEventsFlag (addReflexOptimizerFlag (self.callPackage (hackGet ./reflex) {}))); | |
reflex-dom = addReflexOptimizerFlag (doJailbreak reflexDom.reflex-dom); | |
reflex-dom-core = addReflexOptimizerFlag (doJailbreak reflexDom.reflex-dom-core); | |
reflex-todomvc = self.callPackage (hackGet ./reflex-todomvc) {}; | |
reflex-aeson-orphans = self.callPackage (hackGet ./reflex-aeson-orphans) {}; | |
haven = self.callHackage "haven" "0.2.0.0" {}; | |
inherit (jsaddlePkgs) jsaddle jsaddle-clib jsaddle-wkwebview jsaddle-webkit2gtk jsaddle-webkitgtk; | |
jsaddle-warp = dontCheck jsaddlePkgs.jsaddle-warp; | |
jsaddle-dom = overrideCabal (self.callPackage (hackGet ./jsaddle-dom) {}) (drv: { | |
# On macOS, the jsaddle-dom build will run out of file handles the first time it runs | |
preBuild = ''./setup build || true''; | |
}); | |
inherit (ghcjsDom) ghcjs-dom-jsffi; | |
# TODO: Fix this in Cabal | |
# When building a package with no haskell files, cabal haddock shouldn't fail | |
ghcjs-dom-jsaddle = dontHaddock ghcjsDom.ghcjs-dom-jsaddle; | |
ghcjs-dom = dontHaddock ghcjsDom.ghcjs-dom; | |
inherit (gargoylePkgs) gargoyle gargoyle-postgresql; | |
######################################################################## | |
# Tweaks | |
######################################################################## | |
gi-glib = self.callPackage ./gi-glib.nix {}; | |
gi-gio = self.callPackage ./gi-gio.nix {}; | |
gi-gtk = self.callPackage ./gi-gtk.nix { | |
gtk3 = nixpkgs.gnome3.gtk; | |
}; | |
gi-javascriptcore = self.callPackage ./gi-javascriptcore.nix {}; | |
gi-webkit2 = self.callPackage ./gi-webkit2.nix { | |
webkitgtk = nixpkgs.webkitgtk216x; | |
}; | |
gi-gtksource = super.gi-gtksource.override { | |
inherit (nixpkgs.gnome3) gtksourceview; | |
}; | |
ghcjs-base-stub = dontHaddock super.ghcjs-base-stub; | |
haskell-gi-overloading = super.haskell-gi-overloading_0_0; | |
webkit2gtk3-javascriptcore = super.webkit2gtk3-javascriptcore.override { | |
webkitgtk = nixpkgs.webkitgtk216x; | |
}; | |
cabal-macosx = overrideCabal super.cabal-macosx (drv: { | |
src = fetchFromGitHub { | |
owner = "obsidiansystems"; | |
repo = "cabal-macosx"; | |
rev = "b1e22331ffa91d66da32763c0d581b5d9a61481b"; | |
sha256 = "1y2qk61ciflbxjm0b1ab3h9lk8cm7m6ln5ranpf1lg01z1qk28m8"; | |
}; | |
doCheck = false; | |
}); | |
######################################################################## | |
# Fixes to be upstreamed | |
######################################################################## | |
foundation = dontCheck super.foundation; | |
MonadCatchIO-transformers = doJailbreak super.MonadCatchIO-transformers; | |
blaze-builder-enumerator = doJailbreak super.blaze-builder-enumerator; | |
process-extras = dontCheck super.process-extras; | |
miso = addBuildDepend (self.callHackage "miso" "0.12.0.0" {}) self.ghcjs-base; | |
######################################################################## | |
# Packages not in hackage | |
######################################################################## | |
servant-reflex = self.callCabal2nix "servant-reflex" (fetchFromGitHub { | |
owner = "imalsogreg"; | |
repo = "servant-reflex"; | |
rev = "5cd3098880741e6ade52ef4477422d9c776e5478"; | |
sha256 = "18yjfamx3k9xd8pz251jsmvhlj4riw0brk2fyvjq00r87cx67a6f"; | |
}) {}; | |
concat = dontHaddock (dontCheck (self.callCabal2nix "concat" (fetchFromGitHub { | |
owner = "conal"; | |
repo = "concat"; | |
rev = "24a4b8ccc883605ea2b0b4295460be2f8a245154"; | |
sha256 = "0mcwqzjk3f8qymmkbpa80l6mh6aa4vcyxky3gpwbnx19g721mj35"; | |
}) {})); | |
direct-sqlite = self.callCabal2nix "direct-sqlite" (fetchFromGitHub { | |
owner = "IreneKnapp"; | |
repo = "direct-sqlite"; | |
rev = "cd1ab3c0ee7894d888be826fc653b75813fd53c9"; | |
sha256 = "13i6lz99x0jb9fgns7brlqnv5s5w4clp26l8c3kxd318r1krvr6w"; | |
}) {}; | |
superconstraints = | |
# Remove override when assertion fails | |
assert (super.superconstraints or null) == null; | |
self.callPackage (self.haskellSrc2nix { | |
name = "superconstraints"; | |
src = fetchurl { | |
url = "https://hackage.haskell.org/package/superconstraints-0.0.1/superconstraints.cabal"; | |
sha256 = "0bgc8ldml3533522gp1x2bjiazllknslpl2rvdkd1k1zfdbh3g9m"; | |
}; | |
sha256 = "1gx9p9i5jli91dnvvrc30j04h1v2m3d71i8sxli6qrhplq5y63dk"; | |
}) {}; | |
} // (if enableLibraryProfiling then { | |
mkDerivation = expr: super.mkDerivation (expr // { enableLibraryProfiling = true; }); | |
} else {}); | |
}; | |
haskellOverlays = import ./haskell-overlays { | |
inherit | |
haskellLib | |
nixpkgs jdk fetchFromGitHub | |
useReflexOptimizer stage2Script; | |
androidActivity = hackGet ./android-activity; | |
}; | |
stage2Script = nixpkgs.runCommand "stage2.nix" { | |
GEN_STAGE2 = builtins.readFile (nixpkgs.path + "/pkgs/development/compilers/ghcjs/gen-stage2.rb"); | |
buildCommand = '' | |
echo "$GEN_STAGE2" > gen-stage2.rb && chmod +x gen-stage2.rb | |
patchShebangs . | |
./gen-stage2.rb "${sources.ghcjs-boot}" >"$out" | |
''; | |
nativeBuildInputs = with nixpkgs; [ | |
ruby cabal2nix | |
]; | |
} ""; | |
ghcjsCompiler = ghc.callPackage (nixpkgs.path + "/pkgs/development/compilers/ghcjs/base.nix") { | |
bootPkgs = ghc; | |
ghcjsSrc = sources.ghcjs; | |
ghcjsBootSrc = sources.ghcjs-boot; | |
shims = sources.shims; | |
stage2 = import stage2Script; | |
}; | |
ghcjsPackages = nixpkgs.callPackage (nixpkgs.path + "/pkgs/development/haskell-modules") { | |
ghc = ghcjsCompiler; | |
compilerConfig = nixpkgs.callPackage (nixpkgs.path + "/pkgs/development/haskell-modules/configuration-ghc-7.10.x.nix") { inherit haskellLib; }; | |
packageSetConfig = nixpkgs.callPackage (nixpkgs.path + "/pkgs/development/haskell-modules/configuration-ghcjs.nix") { inherit haskellLib; }; | |
inherit haskellLib; | |
}; | |
# TODO: Figure out why this approach doesn't work; it doesn't seem to evaluate our overridden ghc at all | |
# ghcjsPackages = nixpkgs.haskell.packages.ghcjs.override { | |
# ghc = builtins.trace "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ghcjsCompiler; | |
# }; | |
ghcjs = (extendHaskellPackages ghcjsPackages).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghcjs | |
(optionalExtension useTextJSString haskellOverlays.textJSString) | |
]; | |
}; | |
ghcHEAD = (extendHaskellPackages nixpkgs.pkgs.haskell.packages.ghcHEAD).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-head | |
]; | |
}; | |
ghc8_2_1 = (extendHaskellPackages nixpkgs.pkgs.haskell.packages.ghc821).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-8_2_1 | |
]; | |
}; | |
ghc = (extendHaskellPackages nixpkgs.pkgs.haskell.packages.ghc802).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-8 | |
]; | |
}; | |
ghc7 = (extendHaskellPackages nixpkgs.pkgs.haskell.packages.ghc7103).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-7 | |
]; | |
}; | |
ghc7_8 = (extendHaskellPackages nixpkgs.pkgs.haskell.packages.ghc784).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-7_8 | |
]; | |
}; | |
ghcAndroidArm64 = (extendHaskellPackages nixpkgsCross.android.arm64Impure.pkgs.haskell.packages.ghc821).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-8_2_1 | |
haskellOverlays.disableTemplateHaskell | |
haskellOverlays.android | |
]; | |
}; | |
ghcAndroidArmv7a = (extendHaskellPackages nixpkgsCross.android.armv7aImpure.pkgs.haskell.packages.ghc821).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-8_2_1 | |
haskellOverlays.disableTemplateHaskell | |
haskellOverlays.android | |
]; | |
}; | |
ghcIosSimulator64 = (extendHaskellPackages nixpkgsCross.ios.simulator64.pkgs.haskell.packages.ghc821).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-8_2_1 | |
]; | |
}; | |
ghcIosArm64 = (extendHaskellPackages nixpkgsCross.ios.arm64.pkgs.haskell.packages.ghc821).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-8_2_1 | |
haskellOverlays.disableTemplateHaskell | |
haskellOverlays.ios | |
]; | |
}; | |
ghcIosArmv7 = (extendHaskellPackages nixpkgsCross.ios.armv7.pkgs.haskell.packages.ghc821).override { | |
overrides = nixpkgs.lib.foldr nixpkgs.lib.composeExtensions (_: _: {}) [ | |
(optionalExtension enableExposeAllUnfoldings haskellOverlays.exposeAllUnfoldings) | |
haskellOverlays.ghc-8_2_1 | |
haskellOverlays.disableTemplateHaskell | |
haskellOverlays.ios | |
]; | |
}; | |
#TODO: Separate debug and release APKs | |
#TODO: Warn the user that the android app name can't include dashes | |
android = androidWithHaskellPackages { inherit ghcAndroidArm64 ghcAndroidArmv7a; }; | |
androidWithHaskellPackages = { ghcAndroidArm64, ghcAndroidArmv7a }: import ./android { | |
nixpkgs = nixpkgsFunc { system = "x86_64-linux"; }; | |
inherit nixpkgsCross ghcAndroidArm64 ghcAndroidArmv7a overrideCabal; | |
}; | |
nix-darwin = fetchFromGitHub { | |
owner = "3noch"; # TODO: Update to LnL7 once PR is merged: https://github.com/LnL7/nix-darwin/pull/78 | |
repo = "nix-darwin"; | |
rev = "adfe63988d8e0f07739bc7dafd7249c3a78faf96"; | |
sha256 = "0rca00lajdzf8lf2hgwn6mbmii656dnw725y6nnraz4qf87907zq"; | |
}; | |
# TODO: This should probably be upstreamed to nixpkgs. | |
plistLib = import (nix-darwin + /modules/launchd/lib.nix) { lib = nixpkgs.lib; }; | |
ios = iosWithHaskellPackages ghcIosArm64; | |
iosWithHaskellPackages = ghcIosArm64: { | |
buildApp = import ./ios { | |
inherit ghcIosArm64 plistLib; | |
nixpkgs = nixpkgsFunc { system = "x86_64-darwin"; }; | |
}; | |
}; | |
in let this = rec { | |
inherit nixpkgs | |
nixpkgsCross | |
overrideCabal | |
hackGet | |
extendHaskellPackages | |
foreignLibSmuggleHeaders | |
stage2Script | |
ghc | |
ghcHEAD | |
ghc8_2_1 | |
ghc8_0_1 | |
ghc7 | |
ghc7_8 | |
ghcIosSimulator64 | |
ghcIosArm64 | |
ghcIosArmv7 | |
ghcAndroidArm64 | |
ghcAndroidArmv7a | |
ghcjs | |
android | |
androidWithHaskellPackages | |
ios | |
iosWithHaskellPackages | |
filterGit; | |
androidReflexTodomvc = android.buildApp { | |
package = p: p.reflex-todomvc; | |
executableName = "reflex-todomvc"; | |
applicationId = "org.reflexfrp.todomvc"; | |
displayName = "Reflex TodoMVC"; | |
}; | |
iosReflexTodomvc = ios.buildApp { | |
package = p: p.reflex-todomvc; | |
executableName = "reflex-todomvc"; | |
bundleIdentifier = "org.reflexfrp.todomvc"; | |
bundleName = "Reflex TodoMVC"; | |
}; | |
setGhcLibdir = ghcLibdir: inputGhcjs: | |
let libDir = "$out/lib/ghcjs-${inputGhcjs.version}"; | |
ghcLibdirLink = nixpkgs.stdenv.mkDerivation { | |
name = "ghc_libdir"; | |
inherit ghcLibdir; | |
buildCommand = '' | |
mkdir -p ${libDir} | |
echo "$ghcLibdir" > ${libDir}/ghc_libdir_override | |
''; | |
}; | |
in inputGhcjs // { | |
outPath = nixpkgs.buildEnv { | |
inherit (inputGhcjs) name; | |
paths = [ inputGhcjs ghcLibdirLink ]; | |
postBuild = '' | |
mv ${libDir}/ghc_libdir_override ${libDir}/ghc_libdir | |
''; | |
}; | |
}; | |
platforms = [ | |
"ghcjs" | |
"ghc" | |
]; | |
attrsToList = s: map (name: { inherit name; value = builtins.getAttr name s; }) (builtins.attrNames s); | |
mapSet = f: s: builtins.listToAttrs (map ({name, value}: { | |
inherit name; | |
value = f value; | |
}) (attrsToList s)); | |
mkSdist = pkg: pkg.override { | |
mkDerivation = drv: ghc.mkDerivation (drv // { | |
postConfigure = '' | |
./Setup sdist | |
mkdir "$out" | |
mv dist/*.tar.gz "$out/${drv.pname}-${drv.version}.tar.gz" | |
exit 0 | |
''; | |
doHaddock = false; | |
}); | |
}; | |
sdists = mapSet mkSdist ghc; | |
mkHackageDocs = pkg: pkg.override { | |
mkDerivation = drv: ghc.mkDerivation (drv // { | |
postConfigure = '' | |
./Setup haddock --hoogle --hyperlink-source --html --for-hackage --haddock-option=--built-in-themes | |
cd dist/doc/html | |
mkdir "$out" | |
tar cz --format=ustar -f "$out/${drv.pname}-${drv.version}-docs.tar.gz" "${drv.pname}-${drv.version}-docs" | |
exit 0 | |
''; | |
doHaddock = false; | |
}); | |
}; | |
hackageDocs = mapSet mkHackageDocs ghc; | |
mkReleaseCandidate = pkg: nixpkgs.stdenv.mkDerivation (rec { | |
name = pkg.name + "-rc"; | |
sdist = mkSdist pkg + "/${pkg.pname}-${pkg.version}.tar.gz"; | |
docs = mkHackageDocs pkg + "/${pkg.pname}-${pkg.version}-docs.tar.gz"; | |
builder = builtins.toFile "builder.sh" '' | |
source $stdenv/setup | |
mkdir "$out" | |
echo -n "${pkg.pname}-${pkg.version}" >"$out/pkgname" | |
ln -s "$sdist" "$docs" "$out" | |
''; | |
# 'checked' isn't used, but it is here so that the build will fail if tests fail | |
checked = overrideCabal pkg (drv: { | |
doCheck = true; | |
src = sdist; | |
}); | |
}); | |
releaseCandidates = mapSet mkReleaseCandidate ghc; | |
androidDevTools = [ | |
ghc.haven | |
nixpkgs.maven | |
nixpkgs.androidsdk | |
]; | |
# Tools that are useful for development under both ghc and ghcjs | |
generalDevToolsAttrs = haskellPackages: | |
let nativeHaskellPackages = ghc; | |
in { | |
inherit (nativeHaskellPackages) | |
Cabal | |
cabal-install | |
ghcid | |
hasktags | |
hlint; | |
inherit (nixpkgs) | |
cabal2nix | |
curl | |
nix-prefetch-scripts | |
nodejs | |
pkgconfig | |
closurecompiler; | |
} // (optionalAttrs (!(haskellPackages.ghc.isGhcjs or false) && builtins.compareVersions haskellPackages.ghc.version "8.2" < 0) { | |
# ghc-mod doesn't currently work on ghc 8.2.2; revisit when https://github.com/DanielG/ghc-mod/pull/911 is closed | |
# When ghc-mod is included in the environment without being wrapped in justStaticExecutables, it prevents ghc-pkg from seeing the libraries we install | |
ghc-mod = (nixpkgs.haskell.lib.justStaticExecutables nativeHaskellPackages.ghc-mod); | |
inherit (haskellPackages) hdevtools; | |
}) // (optionalAttrs (builtins.compareVersions haskellPackages.ghc.version "7.10" >= 0) { | |
inherit (nativeHaskellPackages) stylish-haskell; # Recent stylish-haskell only builds with AMP in place | |
}); | |
generalDevTools = haskellPackages: builtins.attrValues (generalDevToolsAttrs haskellPackages); | |
nativeHaskellPackages = haskellPackages: | |
if haskellPackages.isGhcjs or false | |
then haskellPackages.ghc | |
else haskellPackages; | |
workOn = haskellPackages: package: (overrideCabal package (drv: { | |
buildDepends = (drv.buildDepends or []) ++ generalDevTools (nativeHaskellPackages haskellPackages); | |
})).env; | |
workOnMulti' = { env, packageNames, tools ? _: [], shellToolOverrides ? _: _: {} }: | |
let ghcEnv = | |
let inherit (builtins) filter all concatLists; | |
dependenciesOf = x: (x.buildDepends or []) | |
++ (x.libraryHaskellDepends or []) | |
++ (x.executableHaskellDepends or []) | |
++ (x.testHaskellDepends or []); | |
elemByPname = p: all (pname: (p.pname or "") != pname) packageNames; | |
overiddenOut = pkgEnv: n: (overrideCabal pkgEnv.${n} (args: { | |
passthru = (args.passthru or {}) // { | |
out = filter elemByPname (dependenciesOf args); | |
}; | |
})).out; | |
in env.ghc.withPackages (pkgEnv: concatLists (map (overiddenOut pkgEnv) packageNames)); | |
baseTools = generalDevToolsAttrs env; | |
overriddenTools = baseTools // shellToolOverrides env baseTools; | |
in nixpkgs.runCommand "shell" (ghcEnv.ghcEnvVars // { | |
buildInputs = [ | |
ghcEnv | |
] ++ builtins.attrValues overriddenTools ++ tools env; | |
}) ""; | |
workOnMulti = env: packageNames: workOnMulti' { inherit env packageNames; }; | |
# A simple derivation that just creates a file with the names of all of its inputs. If built, it will have a runtime dependency on all of the given build inputs. | |
pinBuildInputs = drvName: buildInputs: otherDeps: nixpkgs.runCommand drvName { | |
buildCommand = '' | |
mkdir "$out" | |
echo "$propagatedBuildInputs $buildInputs $nativeBuildInputs $propagatedNativeBuildInputs $otherDeps" > "$out/deps" | |
''; | |
inherit buildInputs otherDeps; | |
} ""; | |
# The systems that we want to build for on the current system | |
cacheTargetSystems = [ | |
"x86_64-linux" | |
"i686-linux" | |
"x86_64-darwin" | |
]; | |
isSuffixOf = suffix: s: | |
let suffixLen = builtins.stringLength suffix; | |
in builtins.substring (builtins.stringLength s - suffixLen) suffixLen s == suffix; | |
reflexEnv = platform: | |
let haskellPackages = builtins.getAttr platform this; | |
ghcWithStuff = if platform == "ghc" || platform == "ghcjs" then haskellPackages.ghcWithHoogle else haskellPackages.ghcWithPackages; | |
in ghcWithStuff (p: import ./packages.nix { haskellPackages = p; inherit platform; }); | |
tryReflexPackages = generalDevTools ghc | |
++ builtins.map reflexEnv platforms; | |
cachePackages = | |
let otherPlatforms = optionals (system == "x86_64-linux") [ | |
"ghcAndroidArm64" | |
"ghcAndroidArmv7a" | |
] ++ optional iosSupport "ghcIosArm64"; | |
in tryReflexPackages | |
++ builtins.map reflexEnv otherPlatforms | |
++ optionals (system == "x86_64-linux") [ | |
androidDevTools | |
androidReflexTodomvc | |
] ++ optionals iosSupport [ | |
iosReflexTodomvc | |
]; | |
demoVM = (import "${nixpkgs.path}/nixos" { | |
configuration = { | |
imports = [ | |
"${nixpkgs.path}/nixos/modules/virtualisation/virtualbox-image.nix" | |
"${nixpkgs.path}/nixos/modules/profiles/demo.nix" | |
]; | |
environment.systemPackages = tryReflexPackages; | |
}; | |
}).config.system.build.virtualBoxOVA; | |
lib = haskellLib; | |
inherit cabal2nixResult sources system iosSupport; | |
project = args: import ./project this (args ({ pkgs = nixpkgs; } // this)); | |
tryReflexShell = pinBuildInputs ("shell-" + system) tryReflexPackages []; | |
js-framework-benchmark-src = hackGet ./js-framework-benchmark; | |
ghcjsExternsJs = ./ghcjs.externs.js; | |
}; in this |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment