[Nix-dev] A Journey into the Haskell NG infrastructure: Part I
Peter Simons
simons at cryp.to
Fri Jan 9 16:46:17 CET 2015
Dear Haskellers `intersect` Nixers,
this is the first installment of a series of postings to describe technical
aspects of the re-factored Haskell infrastructure. When this is all done, I
intend to use these articles to create some kind of *gasp* user documentation
for the Nixpkgs manual. So I encourage everyone to point out of omissions and
technical errors, or to ask for clarification if something is vague or
misleading. I've chosen an FAQ-style approach because I felt that this is
easiest for me to write. Hopefully this translates into the document being easy
to read, too! Here we go ...
Why should I care about this "new infrastructure"?
--------------------------------------------------
The new code will break evaluation of any Haskell-related configuration you
may have in ~/.nixpkgs/config.nix or /etc/nixos/configuration.nix.
Privately generated cabal2nix expressions will cease to compile.
Installations that rely on ghc-wrapper finding GHC libraries automatically in
your ~/.nix-profile are obsolete. If you use this approach, you won't be able
to update your profile anymore.
Duh, I don't want that!
-----------------------
You can stick to the established 'haskellPackages' set, if you prefer. The
new code exists separately in 'haskellngPackages', and it's invisible to
"nix-env -i <package-name>" and "nix-env -u". If you don't make a conscious
effort to switch, you won't see any of it.
So I'll never have to update if I don't want to?
------------------------------------------------
My guess is that 'haskellPackages' and 'haskellngPackages' will co-exist for
a while. Personally, I switched to Haskell NG, though, and I won't maintain
any packages in the old hierarchy anymore. I suppose other contributors will
do the same thing. Once you've converted your setup to 'haskellngPackages',
there's no reason to look back, really.
In other words, you don't have to convert your setup *right now*, but at some
point in the future you will probably have to.
Is it difficult to migrate to Haskell NG?
-----------------------------------------
Users of 'ghcWithPackages' can easily switch back and forth between both
package sets. Your ~/.nixpkgs/config.nix file probably defines an attribute
like this one:
| {
| packageOverrides = super: let self = super.pkgs; in
| {
| haskellEnv = self.haskellPackages.ghcWithPackages (p: with p; [
| async attoparsec caseInsensitive fgl GLUT GLURaw haskellSrc
| ]);
| };
| }
Change this definition as follows to switch to Haskell NG:
| {
| provideOldHaskellAttributeNames = true;
|
| packageOverrides = super: let self = super.pkgs; in
| {
| haskellEnv = self.haskellngPackages.ghcWithPackages (p: with p; [
| async attoparsec caseInsensitive fgl GLUT GLURaw haskellSrc
| ]);
| };
| }
There are only two differences: the "ng" bit in the name of the package set,
and the new 'provideOldHaskellAttributeNames' config attribute. (Note that
this lives at the top level of ~/.nixpkgs/config.nix -- not inside of
'packageOverrides'.)
Users of the ghc-wrapper have to make a greater effort, I'm afraid, because
ghc-wrapper no longer exists in the NG code. You'll have to switch to
'ghcWithPackages' first. You may find this article helpful for the process:
<http://permalink.gmane.org/gmane.linux.distributions.nixos/15161>.
What does 'provideOldHaskellAttributeNames' do?
-----------------------------------------------
The package 'cabal-install' has the attribute 'cabalInstall' in the old
package set. In the new one, however, the attribute is now called
'cabal-install' -- just like the package. provideOldHaskellAttributeNames
enables a compatibility layer that defins the old camel-case style names on
top of the new ones. This allows you to use the same configuration for both
the new and old package sets.
Once you feel ready to migrate permanently to NG code, you can switch the
compatibility layer off, to ensure that all your definition use the new names
consistently.
Why is the ghc-wrapper gone?
----------------------------
ghc-wrapper's underlying promise is that you can install a random Haskell
package into your Nix profile, and GHC will pick it up from there
automatically. Now, this worked reasonably well for many packages, but for
may other packages it didn't work, and those cases caused us a lot trouble,
bug reports, and heated discussions in the past, and we ended up adding more
and more layers of plumbing around xmonad, ghc-mod, and whatnot in an attempt
to rescue the idea that GHC would somehow find packages automatically without
being told about them.
In the NG infrastructure, this whole notion has been abandoned. The proper
way to install ghc is trough the 'ghcWithPackages' function. It knows about
exactly those packages that you tell it to. It's slightly more effort to
define your Haskell environment this way, but what you get in return for this
extra effort is a totally deterministic compiler that doesn't depend on any
wrapper scripts, it produces predictable results independent of what else you
may or may not have installed, and it interacts just fine with cabal-install
-- something the ghc-wrapper never managed to get right.
When will the new code be available?
------------------------------------
It already is. 'haskellngPackages' was introduced to 'master' by commit
54baa53d on 2015-01-07, and it has now been picked up by the "unstable"
channel.
Why would I want to migrate? What are the advantages?
-----------------------------------------------------
The NG package set contains the latest version of every package available
from Hackage, plus some older versions that we need to make legacy stuff
compile. In total, we deliver in excess of 7,500 packages. Just look at
https://raw.githubusercontent.com/NixOS/nixpkgs/master/pkgs/development/haskell-modules/hackage-packages.nix
if you don't believe it. The 'hackage-packages.nix' file is generated
automatically by the hackage2nix utility -- which I'll describe in detail in
a later installment --, and it allows us to easily track Hackage on a daily
basis if we want to.
Haskell NG supports GHC 7.10.x.
Haskell NG allows you to configure the hell out of your installation. You can
add new packages easily, you can build your own customized package sets, you
can change Cabal flags, compiler arguments, or any other aspect of how a
package is built by means of the 'overrideCabal' function without editing the
source of Nixpgs. The file
https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/configuration-common.nix
illustrates this point nicely.
It's possible to specify deep overrides with 'overrideScope', which I'll
describe in detail in a later installment. To get a first impression, check
out
https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/configuration-ghc-7.8.x.nix#L61
for a concrete example of a deep override that replaces the version of mtl
2.1.x with 2.2.x in the context of the 'amazonka' package family.
Is there a binary cache available for the NG packages?
------------------------------------------------------
Haskelll NG is built by http://hydra.nixos.org/jobset/nixpkgs/haskell-updates
and http://hydra.cryp.to/jobset/nixpkgs/haskell-ng. You can get binaries from
these servers by adding the command line flags
--option extra-binary-caches http://hydra.nixos.org
--option extra-binary-caches http://hydra.cryp.to
to your invocations of nix-build, nix-env, etc.
The normal binary cache that backs the "unstable" channel does not yet have
binaries for NG.
Does Haskell NG support compilers other than GHC 7.8.4?
-------------------------------------------------------
Yes, there is a family of package sets 'haskell-ng.packages.ghcXYZ' that
define package sets for GHC versions 6.10.4, 6.12.3, 7.0.4, 7.2.2, 7.4.2,
7.6.3, 7.8.4, and HEAD a.k.a. 7.10.1-rc1. For example, to install a version
of GHC 7.6.3, define
ghc763Env = self.haskell-ng.packages.ghc763.ghcWithPackages (p: with p; [
mtl network parallel parsec QuickCheck random regex-base regex-compat
regex-posix stm syb text zlib alex cabal-install cpphs happy ghc-paths
monad-par
]);
in ~/.nixpkgs/config.nix. Note that the compiler-specific package sets do
*not* have the compatibility layer. Inside of 'haskell-ng.packages.ghcXYZ',
only the new attribute names exist!
Furthermore, the package sets for GHC 7.6.3, 7.8.4, and 7.10.1-r1 are the
only ones that can be expected to work. I have never tested any pre-7.6.3
compiler. Getting those package sets to work well is almost certainly going
to be a bit of an effort.
What can I do to help develop Haskell NG?
-----------------------------------------
Use it!
Switch your configuration to the 'haskellngPackages' package set and try
whether you can update your profile to the new version. If you cannot, then
please report the issue in this e-mail thread so that we can try to figure
out what's going wrong.
As of today, we can compile approximately 50% of Hackage successfully. See
http://hydra.nixos.org/jobset/nixpkgs/haskell-updates for the current state
of affairs. Obviously, we would like to get that percentage way up! Patches,
bug reports, and feature requests will help us accomplish that.
Have fun,
Peter
More information about the nix-dev
mailing list