new patch. now specifying settings if flags are not set is also possible.
svn path=/nixpkgs/trunk/; revision=9281
This commit is contained in:
parent
bc92b20f9a
commit
4c44560d95
|
@ -187,6 +187,10 @@ rec {
|
||||||
|
|
||||||
# to be used with listToAttrs (_a_ttribute _v_alue)
|
# to be used with listToAttrs (_a_ttribute _v_alue)
|
||||||
av = attr : value : { inherit attr value; };
|
av = attr : value : { inherit attr value; };
|
||||||
|
# attribute set containing one attribute
|
||||||
|
avs = attr : value : listToAttrs [ (av attr value) ];
|
||||||
|
# adds / replaces an attribute of an attribute set
|
||||||
|
setAttr = set : attr : v : set // (avs attr v);
|
||||||
|
|
||||||
id = x : x;
|
id = x : x;
|
||||||
# true if all/ at least one element(s) satisfy f
|
# true if all/ at least one element(s) satisfy f
|
||||||
|
@ -196,43 +200,51 @@ rec {
|
||||||
# iterates over a list of attributes collecting the attribute attr if it exists
|
# iterates over a list of attributes collecting the attribute attr if it exists
|
||||||
catAttrs = attr : l : fold ( s : l : if (__hasAttr attr s) then [(__getAttr attr s)] ++ l else l) [] l;
|
catAttrs = attr : l : fold ( s : l : if (__hasAttr attr s) then [(__getAttr attr s)] ++ l else l) [] l;
|
||||||
|
|
||||||
flattenSet = set : map ( attr : __getAttr attr set) (__attrNames set);
|
mergeAttrs = fold ( x : y : x // y) {};
|
||||||
|
|
||||||
|
flattenAttrs = set : map ( attr : __getAttr attr set) (__attrNames set);
|
||||||
mapIf = cond : f : fold ( x : l : if (cond x) then [(f x)] ++ l else l) [];
|
mapIf = cond : f : fold ( x : l : if (cond x) then [(f x)] ++ l else l) [];
|
||||||
|
|
||||||
# Marc 2nd proposal: (not everything has been tested in detail yet..)
|
# Marc 2nd proposal: (not everything has been tested in detail yet..)
|
||||||
# One example showing how to use mandatory dependencies [1], default flags [2], ..
|
# One example showing how to use mandatory dependencies [1], default flags [2], settings if a flag is not set [3] ..
|
||||||
#
|
#
|
||||||
# note that you should be able to use either ["value1"] or just "value" .. (if I haven't forgotten a flatten)
|
# note that you should be able to use either ["value1"] or just "value" .. (if I haven't forgotten a flatten)
|
||||||
# linuxthreads
|
# linuxthreads
|
||||||
|
|
||||||
#args: with args.lib; with args;
|
# args: with args.lib; with args;
|
||||||
#let
|
# let
|
||||||
# flagDescr = {
|
# co = chooseOptionsByFlags {
|
||||||
# defaults = { implies = [ "addOns" "addOns2"]; }; [> [2] defaults and mandatory should be the first listed ? Would you like it different?
|
# inherit args;
|
||||||
# mandatory ={ cfgOption = [ "--with-headers=${args.kernelHeaders}/include" [> [1]
|
# flagDescr = {
|
||||||
# "--with-tls" "--without-__thread" "--disable-sanity-checks" ];
|
# defaults = { implies = [ "addOns" "addOns2"]; }; # [2] defaults and mandatory should be the first listed ? Would you like it different?
|
||||||
# assertion = [ args.glibc.nptl ];
|
# mandatory ={ cfgOption = [ "--with-headers=${args.kernelHeaders}/include" # [1]
|
||||||
# };
|
# "--with-tls" "--without-__thread" "--disable-sanity-checks" ];
|
||||||
# addOns = { cfgOption = "--enable-add-ons"; };
|
# assertion = [ args.glibc.nptl ];
|
||||||
# addOns2 = { cfgOption = "--enable-add-ons2"; implies = "addOns"; };
|
# };
|
||||||
# alternativeAddOn = { cfgOption = "--enable-add-ons-alt"; blocks = ["addOns", "addOns2"]; };
|
# defaultFeature = {};
|
||||||
# justAOption = { };
|
# no_defaultFeature = { cfgOption = "--disable-defaultFeature"; }; [3]
|
||||||
# };
|
# addOns = { cfgOption = "--enable-add-ons"; };
|
||||||
# co = chooseOptionsByFlags flagDescr ["libpng", "libjpg"] args;
|
# addOns2 = { cfgOption = "--enable-add-ons2"; implies = "addOns"; };
|
||||||
|
# alternativeAddOn = { cfgOption = "--enable-add-ons-alt"; blocks = ["addOns", "addOns2"]; };
|
||||||
#in args.stdenv.mkDerivation {
|
# justAOption = { };
|
||||||
|
# };
|
||||||
# # passing the flags in case a library using this want's to check them (*) ..
|
# optionals = ["option1" "option2"]; # are equal to a given flag description like option1 = { buildInputs = "option1"; };
|
||||||
# inherit (co) /* flags */ buildInputs configureFlags;
|
# defaultFlags = [ "demos" "doc" ]; # are used if flags is not set by args
|
||||||
# inherit (co.flags) justAOption;
|
# };
|
||||||
|
#
|
||||||
# extraSrc = (if co.flags.justAOption then null else src = .. );
|
# in args.stdenv.mkDerivation ( {
|
||||||
|
#
|
||||||
# src = fetchurl {
|
# # passing the flags in case a library using this want's to check them (*) ..
|
||||||
# url = http://ftp.gnu.org/gnu/glibc/glibc-2.5.tar.bz2;
|
# inherit (co) flags buildInputs configureFlags;
|
||||||
# md5 = "1fb29764a6a650a4d5b409dda227ac9f";
|
# inherit (co.flags) justAOption;
|
||||||
# };
|
#
|
||||||
#}
|
# extraSrc = (if co.flags.justAOption then null else src = .. );
|
||||||
|
#
|
||||||
|
# src = fetchurl {
|
||||||
|
# url = http://ftp.gnu.org/gnu/glibc/glibc-2.5.tar.bz2;
|
||||||
|
# md5 = "1fb29764a6a650a4d5b409dda227ac9f";
|
||||||
|
# };
|
||||||
|
# } // co.pass)
|
||||||
|
|
||||||
# (*) does'nt work because nix is seeing this set as derivation and complains about missing outpath.. :-(
|
# (*) does'nt work because nix is seeing this set as derivation and complains about missing outpath.. :-(
|
||||||
# using mkDerivation { ... } // oc.flags would work but would also force evaluation.. ( would be slower )
|
# using mkDerivation { ... } // oc.flags would work but would also force evaluation.. ( would be slower )
|
||||||
|
@ -241,7 +253,7 @@ rec {
|
||||||
|
|
||||||
# resolves chosen flags based on flagDescr passed dependencies in args
|
# resolves chosen flags based on flagDescr passed dependencies in args
|
||||||
# flagDescr : { name = { cfgOption = "..."; buildInputs = "..."; blocks = "..."; implies = "...";
|
# flagDescr : { name = { cfgOption = "..."; buildInputs = "..."; blocks = "..."; implies = "...";
|
||||||
# assert = "bool";
|
# assert = "bool"; pass = { inherit (args) name }
|
||||||
# any other options you need which you can get by catAttrs };
|
# any other options you need which you can get by catAttrs };
|
||||||
# ...
|
# ...
|
||||||
# args = { inherit lib stdenv;
|
# args = { inherit lib stdenv;
|
||||||
|
@ -258,61 +270,68 @@ rec {
|
||||||
|
|
||||||
# optionals is a list of dependency names. If passed as attribute in args they'll be automatically added
|
# optionals is a list of dependency names. If passed as attribute in args they'll be automatically added
|
||||||
# to flags and flagDescr ( optionalName = { buildInputs = optionalName } )
|
# to flags and flagDescr ( optionalName = { buildInputs = optionalName } )
|
||||||
chooseOptionsByFlags = flagDescr : optionals : args :
|
chooseOptionsByFlags = { flagDescr, args, optionals ? [], defaultFlags ? [],
|
||||||
|
collectExtraPhaseActions ? [] } :
|
||||||
let givenOptionals = listToAttrs
|
let givenOptionals = listToAttrs
|
||||||
(mapIf ( a : (__hasAttr a args) )
|
(mapIf ( a : (__hasAttr a args) )
|
||||||
( x: av x { buildInputs = x; } )
|
( x: av x { buildInputs = x; } )
|
||||||
optionals );
|
optionals );
|
||||||
fd = flagDescr // givenOptionals;
|
fd = flagDescr // givenOptionals;
|
||||||
in chooseOptionsByFlags2 fd args ( getAttr ["flags"] [] args ++ (__attrNames givenOptionals ) );
|
in chooseOptionsByFlags2 fd collectExtraPhaseActions args ( getAttr ["flags"] defaultFlags args ++ (__attrNames givenOptionals ) );
|
||||||
|
|
||||||
chooseOptionsByFlags2 = flagDescr : args : flags :
|
chooseOptionsByFlags2 = flagDescr : collectExtraPhaseActions : args : flags :
|
||||||
let
|
let
|
||||||
# helper function
|
# helper function
|
||||||
collectFlags = state : flags :
|
collectFlags = # state : flags :
|
||||||
fold ( flag : s :
|
fold ( flag : s : (
|
||||||
if (__hasAttr flag s.result) then s # this state has already been visited
|
if (__hasAttr flag s.result) then s # this state has already been visited
|
||||||
else if (__hasAttr flag s.blockedFlagsBy) # flag blocked by priviously visited flags?
|
else if (! __hasAttr flag flagDescr) then throw "unkown flag `${flag}' specified"
|
||||||
then throw "flag ${flag} is blocked by ${__getAttr flag s.blockedFlagsBy}"
|
else let fDesc = (__getAttr flag flagDescr);
|
||||||
else if (! __hasAttr flag flagDescr) then throw "unkown flag `${flag}' specified"
|
implied = flatten ( getAttr ["implies"] [] fDesc );
|
||||||
else let fDesc = (__getAttr flag flagDescr);
|
blocked = flatten ( getAttr ["blocks"] [] fDesc );
|
||||||
implied = flatten ( getAttr ["implies"] [] fDesc );
|
# add this flag
|
||||||
blocked = flatten ( getAttr ["blocks"] [] fDesc );
|
s2 = setAttr s "result" ( setAttr s.result flag (__getAttr flag flagDescr) ) ;
|
||||||
s2 = s //
|
# add implied flags
|
||||||
{ blockedFlagsBy =
|
in collectFlags s2 implied
|
||||||
s.blockedFlagsBy
|
));
|
||||||
// listToAttrs ( map (b: av b flag)
|
|
||||||
blocked );
|
# chosen contains flagDescr but only having those attributes elected by flags
|
||||||
result = s.result
|
# (or by implies attributes of elected attributes)
|
||||||
// (collectFlags s implied)
|
options = let stateOpts = collectFlags { blockedFlagsBy = {}; result = {}; } (flags ++ ["mandatory"]);
|
||||||
// listToAttrs [ { attr = flag; value = (__getAttr flag flagDescr); } ]; };
|
# these options have not been chosen (neither by flags nor by implies)
|
||||||
# add the whole flag to the result set
|
unsetOptions = filter ( x : __hasAttr x stateOpts ) ( __attrNames flagDescr );
|
||||||
in assert (fold ( b : t : __trace (__attrNames s.result) (
|
# no add the corresponding no_ attributes as well ..
|
||||||
if ( __hasAttr b s.result )
|
state = collectFlags stateOpts (map ( x : "no_" + x ) unsetOptions);
|
||||||
then throw "flag ${b} is blocked by ${flag}"
|
in # check for blockings:
|
||||||
else if ( b == flag) then throw "flag ${b} blocks itself"
|
assert ( mapIf ( b: __hasAttr b state.result )
|
||||||
else t)) true blocked);
|
( b: throw "flag ${b} is blocked by ${__getAttr b state.blockedFlagsBy}" )
|
||||||
s2) state flags;
|
(__attrNames state.blockedFlagsBy) == [] );
|
||||||
# chosen contains flagDescr but only having those attributes elected by flags (or by implies attributes of elected attributes)
|
state.result;
|
||||||
chosen = (collectFlags { blockedFlagsBy = {}; result = {}; } (flags ++ ["mandatory"])).result;
|
flatOptions = flattenAttrs options;
|
||||||
chosenFlat = flattenSet chosen;
|
|
||||||
|
# helper functions :
|
||||||
|
collectAttrs = attr : catAttrs attr flatOptions;
|
||||||
|
optsConcatStrs = delimiter : attrs : concatStrings
|
||||||
|
( intersperse delimiter (collectAttrs attrs) );
|
||||||
|
|
||||||
in assert ( all id ( mapRecordFlatten ( attr : r : if ( all id ( flatten (getAttr ["assertion"] [] r ) ) )
|
in assert ( all id ( mapRecordFlatten ( attr : r : if ( all id ( flatten (getAttr ["assertion"] [] r ) ) )
|
||||||
then true else throw "assertion failed flag ${attr}" )
|
then true else throw "assertion failed flag ${attr}" )
|
||||||
chosen) );
|
options) );
|
||||||
{
|
rec {
|
||||||
# compared to flags flagsSet does also contain the implied flags.. This makes it easy to write assertions. ( assert args.
|
|
||||||
inherit chosen chosenFlat;
|
|
||||||
|
|
||||||
buildInputs = map ( attr: if (! __hasAttr attr args) then throw "argument ${attr} is missing!" else (__getAttr attr args) )
|
#foldOptions = attr: f : start: fold f start (catAttrs attr flatOptions);
|
||||||
(flatten (catAttrs "buildInputs" chosenFlat));
|
|
||||||
|
|
||||||
#buildInputNames = catAttrs "name" buildInputs;
|
# compared to flags flagsSet does also contain the implied flags.. This makes it easy to write assertions. ( assert args.
|
||||||
|
inherit options flatOptions;
|
||||||
|
|
||||||
configureFlags = concatStrings (intersperse " " ( flatten ( catAttrs "cfgOption" chosenFlat) ))
|
buildInputs = map ( attr: if (! __hasAttr attr args) then throw "argument ${attr} is missing!" else (__getAttr attr args) )
|
||||||
+ (if (__hasAttr "profilingLibraries" chosen) then "" else " --disable-profiling");
|
(flatten (catAttrs "buildInputs" flatOptions));
|
||||||
|
|
||||||
flags = listToAttrs (map ( flag: av flag (__hasAttr flag chosen) ) (__attrNames flagDescr));
|
configureFlags = optsConcatStrs " " "cfgOption";
|
||||||
};
|
|
||||||
|
|
||||||
|
flags = listToAttrs (map ( flag: av flag (__hasAttr flag options) ) (__attrNames flagDescr) );
|
||||||
|
|
||||||
|
pass = mergeAttrs (flatten (collectAttrs "pass") );
|
||||||
|
} # now add additional phase actions (see examples)
|
||||||
|
// listToAttrs ( map ( x : av x (optsConcatStrs "\n" x) ) collectExtraPhaseActions );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue