Last active
February 7, 2023 03:52
-
-
Save cdepillabout/a1b7226063f7aa57878059f9a3c638b4 to your computer and use it in GitHub Desktop.
Example of overriding a GHC core Haskell package with Nix
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
# This file is an example of overriding a GHC core Haskell library (like | |
# bytestring, containers, text, unix, etc) when building a Haskell package. | |
let default-nixpkgs = | |
builtins.fetchTarball { | |
# nixpkgs haskell-updates branch as of 2019/09/15. | |
url = "https://github.com/NixOS/nixpkgs/archive/a51b3367ab6acc72630da0bad50ce14fa86996d0.tar.gz"; | |
sha256 = "05d3jxxk5dxzs9b3nan16lhkrjnzf0bjd4xy66az86fsafnrr9rd"; | |
}; | |
in | |
{ nixpkgs ? default-nixpkgs }: | |
with (import nixpkgs {}); | |
let | |
my-haskell-packages = haskell.packages.ghc865.extend (hself: hsuper: rec { | |
# The bytestring version provided by GHC is 0.10.8.2. This overrides it to use | |
# bytestring-0.10.8.1. | |
# | |
# Tests are disabled because they cause circular dependencies. | |
bytestring = haskell.lib.dontCheck (hself.callHackage "bytestring" "0.10.8.1" {}); | |
# We have to make sure that our overriden 0.10.8.1 version of bytestring is used | |
# instead of the version 0.10.8.2 provided by GHC. | |
# | |
# This is needed because when Nix compiles Haskell packages, it actually passes two | |
# different GHC package databases to Cabal. The first package database contains | |
# all the Haskell packages that are distributed with GHC, like bytestring, binary, | |
# text, etc. The second package database actually contains the Nix-built Haskell | |
# dependencies, like conduit, lens, etc. | |
# | |
# By default, GHC (Cabal?) picks the highest version of a library it has. So, for instance, | |
# if we try to pass the bytestring-0.10.8.1 library in the second package database, | |
# but bytestring-0.10.8.2 is already in the first package database, GHC will always | |
# pick bytestring-0.10.8.2, even though we have explicitly overridden the bytestring | |
# package with 0.10.8.1 in Nix. | |
# | |
# To work around this, we pass a constraint to Cabal that tells it to force | |
# bytestring-0.10.8.1 even though there is a later version of bytestring | |
# available. | |
# | |
# I don't think this would be required if you wanted to go the other way (e.g. use | |
# bytestring-0.10.8.3 instead of bytestring-0.10.8.2). | |
mkDerivation = drv: (hsuper.mkDerivation drv).override { | |
configureFlags = [ "--constraint=bytestring==0.10.8.1" ]; | |
}; | |
# The following are all GHC core libraries. We need to build them from | |
# Hackage so that they have a dependency on our bytestring-0.10.8.1. | |
binary = haskell.lib.dontCheck (hself.callHackage "binary" "0.8.6.0" {}); | |
directory = hself.callHackage "directory" "1.3.3.0" {}; | |
ghc-boot = hself.callHackage "ghc-boot" "8.6.5" {}; | |
ghci = hself.callHackage "ghci" "8.6.5" {}; | |
hpc = hself.callHackage "hpc" "0.6.0.3" {}; | |
parsec = hself.callHackage "parsec" "3.1.13.0" {}; | |
process = hself.callHackage "process" "1.6.5.0" {}; | |
text = hself.callHackage "text" "1.2.3.1" {}; | |
unix = hself.callHackage "unix" "2.7.2.2" {}; | |
# The Cabal library is a GHC core library, but it is somewhat special because | |
# it needs to be forced to link to the correct version of bytestring when | |
# linking the Setup.hs file. | |
Cabal = haskell.lib.overrideCabal (hself.callHackage "Cabal" "2.4.0.1" {}) (oldAttrs: { | |
preCompileBuildDriver = '' | |
setupCompileFlags="$setupCompileFlags -package bytestring-0.10.8.1" | |
''; | |
}); | |
# doctest needs to be linked to the ghc Haskell package. We are not able | |
# to override the ghc package with a call to `callHackage` like we do above | |
# because the `ghc` attribute actually becomes the compiler. | |
# | |
# That is to say, `haskell.packages.ghc865.ghc` is a derivation for the GHC | |
# compiler, not the ghc Haskell package. | |
doctest = hsuper.doctest.override { | |
ghc = hself.ghc_8_6_5; | |
}; | |
ghc_8_6_5 = haskell.lib.enableCabalFlag hsuper.ghc_8_6_5 "buildable"; | |
}); | |
in | |
my-haskell-packages.conduit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment