[Nix-dev] Overriding packages (was Re: Kernel headers)

Nicolas Pierron nicolas.b.pierron at gmail.com
Thu Aug 14 18:14:13 CEST 2008


On Thu, Aug 14, 2008 at 16:48, Eelco Dolstra <e.dolstra at tudelft.nl> wrote:
> 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.

Who is Andres ?

> 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 ...
>      };
>    };
>  }

So why not making ~/.nixpkgs/config.nix a new part of
all-packages.nix, instead of creating an attribute "override" to
rewrite some parts of it ?

This sound to be a bit redundant if the user wants to set an option of
a package.  So why not writing things like:

## override
pkgs: {
  subversion = { drvFun = import .../subversion;
    stdenv = pkgs.overrideGCC pkgs.stdenv pkgs.gcc34;
    bdbSupport = true;
    httpServer = true;
    sslSupport = false;
    ... more silly options ...
  };

  # this is the same except that there is no getConfig require. (override)
  git = {
    svnSupport = true;
  };
}

Therefore with an "override" merge which take the latest definition of
the attribute you would be able to keep the last definition before
calling the derivation fun with its own arguments.  The merge could
also substitute the subversion attribute by a call to its derivation
function with its own set of arguments.

evalAttrDrvFun = name: attr: listToAttr [{
  name = name;
  value = attr.drvFun attr;
}];

Therefore any reference to subversion attribute will refer to the
derivation as it is currently.


>    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;

hum .. pkgs.lib.finalReference ?

> it would work.  But this has the downside that you have to write "pkgs" everywhere (so it would make all-packages.nix more verbose).

Yes, this kind of configuration is quite verbose if you want to refer
to the override attributes.

> 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.

What cause this problem ? Can this be solved ?

> Maybe we need some language extension to allow attributes in recs to be
> overriden properly...

I am not sure that creating directly a language extension would be a
good solution because someone will always arise with a new issue.  May
be we should concentrate our effort at findings the good solution with
the current syntax instead of searching new syntax that could help for
one specific kind of writing.  Otherwise, I can suggest something like
"%%" which will substitute the older definition by the new definition
at the opposite of "//" which will only mask the older definition with
the new one.

-- 
Nicolas Pierron
- If you are doing something twice then you should try to do it once.



More information about the nix-dev mailing list