[Nix-dev] another style proposal

Eelco Dolstra e.dolstra at tudelft.nl
Tue Apr 6 13:18:00 CEST 2010


Hi,

Yury G. Kudryashov wrote:

> In all-packages.nix:
> 
> mypkg = makeOverridable (import ../path/to/mypkg) ( pkgs // { cg = 
> getPkgConfig "mypkg"; } );
> 
> In mypkg/default.nix:
> 
> a:
> let
>   inherit (a) stdenv fetchurl other things cg;
>   inherit (a.gtkLibs) gtk glib;

I'm really not in favour of this:

- It makes it harder (IMHO) to see what the expected arguments are.
- It's inefficient: you now pass a few *thousand* arguments to the function.
- Possibly error messages become harder to understand: if an argument is
missing, you get a (lazy) error about a missing attribute, rather than an
immediate error about a missing function argument.

BTW, if you're passing all of Nixpkgs to the package, you might as well leave
out the "inherits" and just write:

  pkgs:

  pkgs.stdenv.mkDerivation {
    name = "mypkgs-0.1";

    src = pkgs.fetchurl { ... };

    buildInputs = [ pkgs.gtkLibs.gtk pkgs.gtkLibs.glib ... ];
  }

However, I think a better solution to reducing the duplication is to keep the
formal function arguments, and call the function in all-packages.nix
automatically (that is, with all expected arguments inherited automatically from
`pkgs').  This is possible since Nix 0.14.  For an example, see
https://svn.nixos.org/repos/nix/nix/trunk/tests/lang/eval-okay-functionargs.nix.
 The idea is that in all-packages.nix we can just write:

  aterm = callPackage (import ../development/libraries/aterm) { };
  libxml2 = callPackage (import ../development/libraries/libxml2) { };

I.e. `callPackage' looks at the arguments expected by the function, and copies
any arguments that haven't been supplied explicitly from `pkgs'.  Then you only
need to pass an argument explicitly if you need to deviate from the default:

  mplayer = callPackage (import ...) {
    stdenv = overrideGCC stdenv gcc43;
  };

`callPackage' should make all-packages.nix a lot shorter.

> stdenv.mkDerivation {
>   buildInputs = if cg "gtk" false then [ gtk glib ] else [];

On a different topic, I don't really like this whole getConfig / getPkgConfig
thing to customise packages.  It's kind of redundant, since you can also just
declare the function as:

  { stdenv, fetchurl, useGTK ? false, gtk, glib }: ...

and then put this in your ~/.nixpkgs/config.nix:

  { packageOverrides.libiodbc.useGTK = true; }

This also doesn't rely on ugly lists of strings (`getConfig ["foo" "bar"] true')
but uses the facilities of the language (function argument defaults, attribute
sets, ...).

-- 
Eelco Dolstra | http://www.st.ewi.tudelft.nl/~dolstra/



More information about the nix-dev mailing list