[Nix-dev] Another way to configure packages using flags ..
Michael Raskin
7c6f434c at mail.ru
Wed Aug 15 13:27:20 CEST 2007
Marc Weber wrote:
> Thanks Michael Raskins for your inspiring work..
>
> However some things seemed to be complicated to me..
>
> So I've worked out another design similar to yours:
>
> The key function is
> getArgs which simply is some kind of map replacing all occurences of
> attribute names with the attribute values.
> Thus [ "dep1" "dep2" ] becomes [ <derivation dep1> <derivation dep2> ]
> If a dependency (requirement) hasn't been supplied an exception is
> thrown. Thus you no longer need an extra call checkArgs ..
And what about flags depending on flags? It may be wort its price sometimes.
> The second advantage is that you can no only pass a set of args but also
> a set of configure args (see confArgsReqs).. Then you won't get a set of
> derivations taken from args but a set of configure argument strings..
> flatten the set and you are done..
Yes, it is a nice feature, it can be merged into any design though.
> # much shorter but perhaps slower?
> #uniqList = xs :
> #if xs == [] then []
> #else let
> #h = __head xs;
> #t = __tail xs;
> #in [h] ++ uniqList ( filter ( x : x != h ) t );
Slower in case of frequent repetitions; also I'd like to have isInList
anyway.
> # returns true if all list elements are true
> all = fold (x: y : x && y) true;
Isn't having just one declaration of logicalAND theoretically cleaner as
we'll have a guarantee that Nix doesn't create repeating functions?
> # replaces the names of args by the arguments
> # throws exception if arguments are missing.
> getArgs = flags: # the flags to be used ["opengl" "de" "us" ]
> reqs: # an attribute set like the one given in the example below
> args: # the dependencies passed as recordset as sugessted by Michael Raskin
> let attrsFromArgs = msg : attrs :
> map ( attr : if (__hasAttr attr args)
> then (__getAttr attr args)
> else throw (msg attr)
> ) attrs;
> in { mandatory = attrsFromArgs
> ( attr: "mandatory argument ${attr} not in argument list!" )
> ( getAttr ["mandatory"] [] reqs);
> # only added if flag is set
> conditional = map
> ( flag: if (__hasAttr flag reqs.flags)
> then attrsFromArgs
> ( attr: "argument ${attr} needed by flag ${flag} missing!" )
> (__getAttr flag reqs.flags)
> else throw "unkown given flag ${flag}!"
> ) (uniqList flags);
> };
Also it looks that you cannot make a dependency "optional, but also
required by this flag".
> # # alternative proposal (Marc Weber), example:
> # # advantages: attribute sets are used,
> # # list iterations to check flags are avoided (might be faster ?)
> # $ should be self-explanatory
> # # its easy to get configure flags depending on the given flags as well
> #
> # # default.nix:
> # args: let
> # reqsDeps =
> # { # have to be passed if the flag exists
> # flags : { opengl = [ "opengl" "otherlib" ];
> # directx = [ "directx" "winlib" ];
> # de = [ "spellde" ];
> # us = [ "spellus" ];
> # };
> # # these deps have to be passed in any case
> # mandatory : [ "gnused" ];
> # # these deps will be recognized by the builder automatically when passed
> # };
> # confArgsReqs =
> # { flags : { opengl = [ "--with-opengl" ]
> # directx = [ "--with-directx"];
> # de = []; us = [];
> # } };
> # in args.stdenv.mkDerivation {
> # [...]
> # buildInputs = flattenListAndSet ( getArgs args.flags reqsDeps args );
> # configureFlags = intersperse " " ( flattenListAndSet args.flags confArgsReqs args );
> # [...]
> # }
> #
> # # all-packages.nix:
> # foo = (import [..]) {
> # inherit opengl otherlib directx winlib spellde spellus gnused;
> # flags = ["opengl" "spellde"];
> # }
>
> # you can realize optional dependencies ( you don't want to create/ add a flag for each) by
> # adding them to the mandatory list only if they are passed
> # mandatory : [ "gnused" ] ++ filter ( flag: __hasAttr flag args ) [ "optional1" "optional2" ];
Well, adding purely optional arguments to mandatory list is a bit
counter-intuitive. And also it blocks going from calculations to
declarations where we can do it. Maybe it is better to have a list
'optional' and remove non-supplied arguments from it.
More information about the nix-dev
mailing list