[Nix-dev] Overriding packages (was Re: Kernel headers)
Eelco Dolstra
e.dolstra at tudelft.nl
Thu Aug 14 16:48:15 CEST 2008
Hi,
Michael Raskin wrote:
> Pjotr Prins wrote:
> | I have a basic question. I have created a Kernel_headers expression for
> | 2.6.18. How do I override the NIX build without changing:
> |
> | kernelHeaders = kernelHeaders_2_6_23;
> |
> | to:
> |
> | kernelHeaders = kernelHeaders_2_6_18;
> |
> | In other words, what switch to I pass nix-build/nix-env -i to
> | ascertain headers 2.6.18 without changing the default line in
> | all-packages.nix? I would like to keep the SVN tree generic.
>
> Write something like
>
> kernelHeaders =
> ~ let kernelHeadersVersion = getConfig
> ~ ["kernelHeaders" "version"]
> ~ "2.6.23";
> ~ in
> ~ if kernelHeadersVersion == "2.6.23" then
> ~ kernelHeaders_2_6_23 else
> ~ if kernelHeadersVersion == "2.6.22" then
> ~ kernelHeaders_2_6_22 else
> ~ if kernelHeadersVersion == "2.6.18" then
> ~ kernelHeaders_2_6_18 else
> ~ abort "Unknown kernelHeaders version.";
I brainstormed with Andres a while ago about how to make Nixpkgs more
configurable without polluting it with zillions of options, which is related to
this.
Rather than having messy options like this (which would have to grow to include
each version), it would be much cleaner if you could override packages globally
in ~/.nixpkgs/config.nix, e.g. something like
{
overrides = pkgs: {
kernelHeaders = pkgs.kernelHeaders_2_6_18;
}
}
where "pkgs" is the original set of packages. (As an added benefit, we wouldn't
have to have config options for every obscure feature, since you could always
define your own override, like
{
overrides = pkgs: {
subversion = import .../subversion {
stdenv = pkgs.overrideGCC pkgs.stdenv pkgs.gcc34;
bdbSupport = true;
httpServer = true;
sslSupport = false;
... more silly options ...
};
};
}
if for some strange reason you want Subversion compiled with a non-standard GCC
and non-standard options).
The problem is that this isn't currently possible, since all the references to
"kernelHeaders" in all-packages.nix would continue to reference the original
value. That is, even if all-packages.nix looked like this:
let
pkgs =
rec {
kernelHeaders = kernelHeaders_2_6_23;
kernelHeaders_2_6_18 = ...;
kernelHeaders_2_6_23 = ...;
somePackage = ... {
inherit kernelHeaders;
};
} // (getConfig "overrides" {}) pkgs;
in pkgs
it wouldn't work because the "rec" causes the value of kernelHeaders_2_6_23 to
be substituted in somePackage, even though the "//" then replaces the
kernelHeaders attribute by kernelHeaders_2_6_18. OTOH, if we didn't use a rec
but wrote all-packages.nix like this:
let
pkgsFun = pkgs:
{ # <-- no rec
kernelHeaders = pkgs.kernelHeaders_2_6_23;
kernelHeaders_2_6_18 = ...;
kernelHeaders_2_6_23 = ...;
somePackage = ... {
inherit (pkgs) kernelHeaders;
};
} // (getConfig "overrides" {}) pkgs;
# Tie the knot. This works thanks to laziness.
pkgs = pkgsFun pkgs;
in pkgs
it would work. But this has the downside that you have to write "pkgs"
everywhere (so it would make all-packages.nix more verbose). It might seem that
writing pkgsFun as "pkgsFun = pkgs: with pkgs; {...}" would solve this, but then
you get an infinite recursion as "with" isn't lazy enough.
Maybe we need some language extension to allow attributes in recs to be
overriden properly...
--
Eelco Dolstra | http://www.st.ewi.tudelft.nl/~dolstra/
More information about the nix-dev
mailing list