diff options
author | Marc Weber <marco-oweber@gmx.de> | 2008-12-20 01:20:35 +0000 |
---|---|---|
committer | Marc Weber <marco-oweber@gmx.de> | 2008-12-20 01:20:35 +0000 |
commit | e996113be7f41f067aaefac881c540b5ceb8d2d4 (patch) | |
tree | 177f16552ca2d05020c3d45a0b45502556a09502 /pkgs/lib | |
parent | 5ab6464edb9bbc2a9aa15122ffc02b57ad236bb7 (diff) |
removed mkDerivationByConfiguration, using composableDerivation instead
qgis, vim_configurable both work now svn path=/nixpkgs/trunk/; revision=13661
Diffstat (limited to 'pkgs/lib')
-rw-r--r-- | pkgs/lib/composable-derivation.nix | 46 | ||||
-rw-r--r-- | pkgs/lib/default.nix | 246 |
2 files changed, 46 insertions, 246 deletions
diff --git a/pkgs/lib/composable-derivation.nix b/pkgs/lib/composable-derivation.nix new file mode 100644 index 0000000000000..790a0bcc9dbcb --- /dev/null +++ b/pkgs/lib/composable-derivation.nix @@ -0,0 +1,46 @@ +{lib, pkgs} : +let inherit (lib) nv nvs; in +{ + # see new python derivations for example.. + # You should be able to override anything you like easily + # grep the mailinglist by title "python proposal" (dec 08) + # -> http://mail.cs.uu.nl/pipermail/nix-dev/2008-December/001571.html + # to see why this got complicated when using all its features + composableDerivation = { + # modify args before applying stdenv.mkDerivation, this should remove at least attrs removeAttrsBy + f ? lib.prepareDerivationArgs, + stdenv ? pkgs.stdenv, + # initial set of arguments to be passed to stdenv.mkDerivation passing prepareDerivationArgs by default + initial ? {}, + # example func : (x: x // { x.buildInputs ++ ["foo"] }), but see mergeAttrByFunc which does this for you + merge ? (lib.mergeOrApply lib.mergeAttrByFunc) + }: lib.applyAndFun + (args: stdenv.mkDerivation (f args)) + merge + (merge { inherit (lib) mergeAttrBy; } initial); + + # some utility functions + # use this function to generate flag attrs for prepareDerivationArgs + # E nable D isable F eature + edf = {name, feat ? name, enable ? {}, disable ? {} , value ? ""}: + nvs name { + set = { + configureFlags = ["--enable-${feat}${if value == "" then "" else "="}${value}"]; + } // enable; + unset = { + configureFlags = ["--disable-${feat}"]; + } // disable; + }; + + # same for --with and --without- + # W ith or W ithout F eature + wwf = {name, feat ? name, enable ? {}, disable ? {}, value ? ""}: + nvs name { + set = { + configureFlags = ["--with-${feat}${if value == "" then "" else "="}${value}"]; + } // enable; + unset = { + configureFlags = ["--without-${feat}"]; + } // disable; + }; +} diff --git a/pkgs/lib/default.nix b/pkgs/lib/default.nix index 66b67baafef76..6af24f6a6b004 100644 --- a/pkgs/lib/default.nix +++ b/pkgs/lib/default.nix @@ -805,251 +805,5 @@ rec { in removeAttrs (mergeAttrsByFuncDefaults ([args] ++ opts)) ["flags" "cfg" "mergeAttrBy" "fixed" ]; # fixed may be passed as fix argument or such - # supportFlag functions for convinience - sFlagEnable = { name, buildInputs ? [], propagatedBuildInputs ? [] } : { - set = { configureFlags = "--enable-${name}"; inherit buildInputs; inherit propagatedBuildInputs; }; - unset = { configureFlags = "--disable-${name}"; }; - }; - - - -# Marc 2nd proposal: (not everything has been tested in detail yet..) -# depreceated because it's too complicated. use prepareDerivationArgs instead - - # usage / example - # flagConfig = { - # } // (enableDisableFeature "flagName" "configure_feature" extraAttrs;) - # - # is equal to - # flagConfig = { - # flagName = { cfgOption = "--enable-configure_feature"; } // extraAttrs; - # no_flagName = { cfgOption = "--disable-configure_feature"; }; - enableDisableFeature = flagName : configure_feature : extraAttrs : - listToAttrs [ ( nv flagName ({ cfgOption = "--enable-${configure_feature}"; } // extraAttrs ) ) - ( nv "no_${flagName}" ({ cfgOption = "--disable-${configure_feature}"; } ) )]; - - # calls chooseOptionsByFlags2 with some preprocessing - # chooseOptionsByFlags2 returns an attribute set meant to be used to create new derivaitons. - # see mkDerivationByConfiguration in all-packages.nix and the examples given below. - # You can just copy paste them into all-packages.nix to test them.. - - chooseOptionsByFlags = { flagConfig, args, optionals ? [], defaults ? [], - collectExtraPhaseActions ? [] } : - let passedOptionals = filter ( x : hasAttr x args ) optionals; # these are in optionals and in args - # we simply merge in <optional_name> = { buildInputs = <arg.<optional_name>; pass = <arg.optional_name>; } - flagConfigWithOptionals = flagConfig // ( listToAttrs - (map ( o : nv o ( { buildInputs = o; pass = nvs o (builtins.getAttr o args); } - // getAttr [o] {} flagConfig ) - ) - passedOptionals ) ); - - in chooseOptionsByFlags2 flagConfigWithOptionals collectExtraPhaseActions args - ( (getAttr ["flags"] defaults args) ++ passedOptionals); - - chooseOptionsByFlags2 = flagConfig : collectExtraPhaseActions : args : flags : - let - # helper function - collectFlags = # state : flags : - fold ( flag : s : ( - if (hasAttr flag s.result) then s # this state has already been visited - else if (! hasAttr flag flagConfig) then throw "unkown flag `${flag}' specified" - else let fDesc = (builtins.getAttr flag flagConfig); - implied = flatten ( getAttr ["implies"] [] fDesc ); - blocked = flatten ( getAttr ["blocks"] [] fDesc ); - # add this flag - s2 = s // { result = ( setAttr s.result flag (builtins.getAttr flag flagConfig) ); - blockedFlagsBy = s.blockedFlagsBy - // listToAttrs (map (b: nv b flag ) blocked); }; - # add implied flags - in collectFlags s2 implied - )); - - # chosen contains flagConfig but only having those attributes elected by flags - # (or by implies attributes of elected attributes) - options = let stateOpts = collectFlags { blockedFlagsBy = {}; result = {}; } - (flags ++ ( if (hasAttr "mandatory" flagConfig) then ["mandatory"] else [] )); - # these options have not been chosen (neither by flags nor by implies) - unsetOptions = filter ( x : (! hasAttr x stateOpts.result) && (hasAttr ("no_"+x) flagConfig)) - ( attrNames flagConfig ); - # no add the corresponding no_ attributes as well .. - state = collectFlags stateOpts (map ( x : "no_" + x ) unsetOptions); - in # check for blockings: - assert ( all id ( map ( b: if (hasAttr b state.result) - then throw "flag ${b} is blocked by flag ${__getAttr b state.blockedFlagsBy}" - else true ) - (attrNames state.blockedFlagsBy) ) ); - state.result; - flatOptions = flattenAttrs options; - - # helper functions : - collectAttrs = attr : catAttrs attr flatOptions; - optsConcatStrs = delimiter : attrs : concatStrings - ( intersperse delimiter (flatten ( collectAttrs attrs ) ) ); - - ifStringGetArg = x : if (__isAttrs x) then x # ( TODO implement __isString ?) - else nvs x (__getAttr x args); - - in assert ( all id ( mapRecordFlatten ( attr : r : if ( all id ( flatten (getAttr ["assertion"] [] r ) ) ) - then true else throw "assertion failed flag ${attr}" ) - options) ); - ( rec { - - #foldOptions = attr: f : start: fold f start (catAttrs attr flatOptions); - - # compared to flags flagsSet does also contain the implied flags.. This makes it easy to write assertions. ( assert args. - inherit options flatOptions collectAttrs optsConcatStrs; - buildInputs = map ( attr: if (! hasAttr attr args) then throw "argument ${attr} is missing!" else (builtins.getAttr attr args) ) - (flatten (catAttrs "buildInputs" flatOptions)); - propagatedBuildInputs = map ( attr: if (! hasAttr attr args) then throw "argument ${attr} is missing!" else (builtins.getAttr attr args) ) - (flatten (catAttrs "propagatedBuildInputs" flatOptions)); - - configureFlags = optsConcatStrs " " "cfgOption"; - - #flags = listToAttrs (map ( flag: nv flag (hasAttr flag options) ) (attrNames flagConfig) ); - flags_prefixed = listToAttrs (map ( flag: nv ("flag_set_"+flag) (hasAttr flag options) ) (attrNames flagConfig) ); - - pass = mergeAttrs ( map ifStringGetArg ( flatten (collectAttrs "pass") ) ); - } # now add additional phase actions (see examples) - // listToAttrs ( map ( x : nv x (optsConcatStrs "\n" x) ) collectExtraPhaseActions ) ); } - -/* - TODO: Perhaps it's better to move this documentation / these tests into some extra packages .. - - # ########################################################################### - # configuration tutorial .. examples and tests.. - # Copy this into all-packages.nix and try - - # The following derviations will all fail.. - # But they will print the passed options so that you can get to know - # how these configurations ought to work. - # TODO: There is no nice way to pass an otpion yet. - # I could imagine something like - # flags = [ "flagA" "flagB" { flagC = 4; } ]; - - # They are named: - # simpleYes, simpleNo, - # defaultsimpleYes, defaultsimpleNo - # optionalssimpleYes, optionalssimpleNo - # bitingsimpleYes can only be ran with -iA blockingBiteMonster - # assertionsimpleNo - # of course you can use -iA and the attribute name as well to select these examples - - # dummy build input - whoGetsTheFlagFirst = gnused; - whoGetsTheFlagLast = gnumake; - - # simple example demonstrating containing one flag. - # features: - # * configure options are passed automatically - # * buildInputs are collected (they are special, see the setup script) - # * they can be passed by additional name as well using pass = { inherit (args) python } - # ( or short (value not attrs) : pass = "python" ) - # * an attribute named the same way as the flag is added indicating - # true/ false (flag has been set/ not set) - # * extra phase dependend commands can be added - # Its easy to add your own stuff using co.collectAttrs or co.optsConcatStrs - # ( perhaps this name will change?) - simpleFlagYesNoF = namePrefix : extraFlagAttrs : mkDerivationByConfiguration ( { - flagConfig = { - flag = { name = namePrefix + "simpleYes"; - cfgOption = [ "--Yes" "--you-dont-need-a-list" ]; - buildInputs = [ "whoGetsTheFlagFirst" ]; - pass = { inherit gnumake; }; - extraConfigureCmd = "echo Hello, it worked! "; - blocks = "bitingMonster"; - }; - no_flag = { name = namePrefix + "simpleNo"; - cfgOption = "--no"; - implies = ["bitingMonster"]; - }; - bitingMonster = { - extraConfigureCmd = "echo Ill bite you"; - }; - gnutar = { cfgOption="--with-gnutar"; - # buildInputs and pass will be added automatically if gnutar is added to optionals - }; - # can be used to check configure options of dependencies - # eg testFlag = { assertion = [ arg.desktop.flag_set_wmii (! arg.desktop.flag_set_gnome) (! arg.desktops.flag_set_kde ]; } - assertionFlag = { assertion = false; }; # assert is nix language keyword - - }; - - collectExtraPhaseActions = [ "extraConfigureCmd" ]; - - extraAttrs = co : { - name = ( __head (co.collectAttrs "name") ); - - unpackPhase = " - echo my name is - echo \$name - echo - echo flag given \\(should be 1 or empty string\\) ? - echo \$flag_set_flag - echo - echo my build inputs are - echo \$buildInputs - echo - echo my configuration flags are - echo \$configureFlags - echo - echo what about gnumake? Did it pass? - echo \$gnumake - echo - echo configurePhase command is - echo $\configurePhase - echo - echo gnutar passed? \\(optional test\\) - echo \$gnutar - echo - echo dying now - echo die_Hopefully_Soon - "; - configurePhase = co.extraConfigureCmd; - }; - } // extraFlagAttrs ); - - - simpleYes = simpleFlagYesNoF "" {} { - inherit whoGetsTheFlagFirst lib stdenv; - flags = ["flag"]; - }; - # note the "I'll bite you" because of the implies attribute - simpleNo = simpleFlagYesNoF "" {} { - inherit whoGetsTheFlagFirst lib stdenv; - flags = []; - }; - - # specifying defaults by adding a default attribute - - yesAgainDefault = simpleFlagYesNoF "default" { defaults = [ "flag" ];} { - inherit whoGetsTheFlagFirst lib stdenv; - }; - noAgainOverridingDefault = simpleFlagYesNoF "default" { defaults = [ "flag" ];} { - inherit whoGetsTheFlagFirst lib stdenv; - flags = []; - }; - - # requested by Michael Raskin: activate flag automatically if dependency is passed: - withGnutarOptional = simpleFlagYesNoF "optionals" { optionals = [ "gnutar" ];} { - flags = [ "flag" ]; # I only need to pass this to trigger name optionalssimpleYes - inherit whoGetsTheFlagFirst lib stdenv; - inherit gnutar; - }; - withoutGnutarOptional = simpleFlagYesNoF "optionals" { optionals = [ "gnutar" ];} { - inherit whoGetsTheFlagFirst lib stdenv; - }; - - # blocking example, this shouldn't even start building: - blockingBiteMonster = simpleFlagYesNoF "biting" {} { - inherit whoGetsTheFlagFirst lib stdenv; - flags = [ "flag" "bitingMonster" ]; - }; - - # assertion example this shouldn't even start building: - assertion = simpleFlagYesNoF "assertion" {} { - inherit whoGetsTheFlagFirst lib stdenv; - flags = [ "assertionFlag" ]; - }; -*/ |