diff options
author | Marc Weber <marco-oweber@gmx.de> | 2008-01-16 03:29:56 +0000 |
---|---|---|
committer | Marc Weber <marco-oweber@gmx.de> | 2008-01-16 03:29:56 +0000 |
commit | 2cfe440b0285f4bb042a2bfd49e0a5f8a258af06 (patch) | |
tree | 54599491ca36bfb5c0b33e2020ba9fae66421f46 | |
parent | bcc577894a83565ac04f0e7244137f07cdd42b77 (diff) | |
download | nixpkgs-2cfe440b0285f4bb042a2bfd49e0a5f8a258af06.tar nixpkgs-2cfe440b0285f4bb042a2bfd49e0a5f8a258af06.tar.gz nixpkgs-2cfe440b0285f4bb042a2bfd49e0a5f8a258af06.tar.bz2 nixpkgs-2cfe440b0285f4bb042a2bfd49e0a5f8a258af06.tar.lz nixpkgs-2cfe440b0285f4bb042a2bfd49e0a5f8a258af06.tar.xz nixpkgs-2cfe440b0285f4bb042a2bfd49e0a5f8a258af06.tar.zst nixpkgs-2cfe440b0285f4bb042a2bfd49e0a5f8a258af06.zip |
Merge lib and lib_unstable. lift lib_unstabel in place in case I've broken something - can be deleted in some days
svn path=/nixpkgs/trunk/; revision=10166
-rw-r--r-- | pkgs/lib/default.nix | 286 | ||||
-rw-r--r-- | pkgs/top-level/all-packages.nix | 33 |
2 files changed, 295 insertions, 24 deletions
diff --git a/pkgs/lib/default.nix b/pkgs/lib/default.nix index 2d300891bcf..21c48e9017b 100644 --- a/pkgs/lib/default.nix +++ b/pkgs/lib/default.nix @@ -3,7 +3,8 @@ let inherit (builtins) - head tail isList stringLength substring lessThan sub; + head tail isList stringLength substring lessThan sub + listToAttrs attrNames hasAttr; in @@ -54,6 +55,7 @@ rec { else [(head list) separator] ++ (intersperse separator (tail list)); + toList = x : if (__isList x) then x else [x]; concatStringsSep = separator: list: concatStrings (intersperse separator list); @@ -71,6 +73,7 @@ rec { # Return an attribute from nested attribute sets. For instance ["x" # "y"] applied to some set e returns e.x.y, if it exists. The # default value is returned otherwise. + # comment: there is also builtins.getAttr ? (is there a better name for this function?) getAttr = attrPath: default: e: let attr = head attrPath; in @@ -115,6 +118,12 @@ rec { else if pred (head list) then all pred (tail list) else false; + # much shorter implementations using map and fold (are lazy as well) + # which ones are better? + # true if all/ at least one element(s) satisfy f + # all = f : l : fold logicalAND true (map f l); + # any = f : l : fold logicalOR false (map f l); + # Return true if each element of a list is equal, false otherwise. eqLists = xs: ys: @@ -245,8 +254,6 @@ rec { checker else condConcat name (tail (tail list)) checker; - - /* Options. */ mkOption = attrs: attrs // {_type = "option";}; @@ -304,4 +311,277 @@ rec { closePropagation = list: (uniqList {inputList = (innerClosePropagation [] list);}); + # calls a function (f attr value ) for each record item. returns a list + mapRecordFlatten = f : r : map (attr: f attr (builtins.getAttr attr r) ) (attrNames r); + + whenFlip = x : cond : if (cond) then x else ""; + + # to be used with listToAttrs (_a_ttribute _v_alue) + # TODO should be renamed to nv because niksnut has renamed the attribute attr to name + av = name : value : { inherit name value; }; + # attribute set containing one attribute + avs = name : value : listToAttrs [ (av name value) ]; + # adds / replaces an attribute of an attribute set + setAttr = set : name : v : set // (avs name v); + + # iterates over a list of attributes collecting the attribute attr if it exists + catAttrs = attr : l : fold ( s : l : if (hasAttr attr s) then [(builtins.getAttr attr s)] ++ l else l) [] l; + + mergeAttrs = fold ( x : y : x // y) {}; + + # Using f = a : b = b the result is similar to // + # merge attributes with custom function handling the case that the attribute + # exists in both sets + mergeAttrsWithFunc = f : set1 : set2 : + fold (n: set : if (__hasAttr n set) + then setAttr set n (f (__getAttr n set) (__getAttr n set2)) + else set ) + set1 (__attrNames set2); + + # merging two attribute set concatenating the values of same attribute names + # eg { a = 7; } { a = [ 2 3 ]; } becomes { a = [ 7 2 3 ]; } + mergeAttrsConcatenateValues = mergeAttrsWithFunc ( a : b : (toList a) ++ (toList b) ); + + # returns atribute values as a list + flattenAttrs = set : map ( attr : builtins.getAttr attr set) (attrNames set); + 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..) + + # 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 [ ( av flagName ({ cfgOption = "--enable-${configure_feature}"; } // extraAttrs ) ) + ( av "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 : av o ( { buildInputs = o; pass = avs 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: av 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 avs 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: av flag (hasAttr flag options) ) (attrNames flagConfig) ); + flags_prefixed = listToAttrs (map ( flag: av ("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 : av 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" ]; + }; +*/ diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 3f0ebb86d0c..f4c3d8cc7cc 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -124,7 +124,8 @@ rec { lib = library; library = import ../lib; - lib_unstable = import ../lib/default-unstable.nix; + # TODO remove + # lib_unstable = import ../lib/default-unstable.nix; # Return an attribute from the Nixpkgs configuration file, or # a default value if the attribute doesn't exist. @@ -204,7 +205,7 @@ rec { args: with args.lib; with args; if ( builtins.isAttrs extraAttrs ) then builtins.throw "the argument extraAttrs needs to be a function beeing passed co, but attribute set passed " else - let co = lib_unstable.chooseOptionsByFlags { inherit args flagConfig optionals defaults collectExtraPhaseActions; }; in + let co = lib.chooseOptionsByFlags { inherit args flagConfig optionals defaults collectExtraPhaseActions; }; in args.stdenv.mkDerivation ( { inherit (co) configureFlags buildInputs /*flags*/; @@ -1007,10 +1008,9 @@ rec { ghcsAndLibs = assert builtins ? listToAttrs; recurseIntoAttrs (import ../development/compilers/ghcs { - inherit ghcboot fetchurl recurseIntoAttrs perl gnum4 gmp readline; + inherit ghcboot fetchurl recurseIntoAttrs perl gnum4 gmp readline lib; inherit ghcPkgUtil; stdenv = stdenvUsingSetupNew2; - lib = lib_unstable; }); # creates ghc-X-wl wich adds the passed libraries to the env var GHC_PACKAGE_PATH @@ -1268,8 +1268,7 @@ rec { # compiling without xdebug is currenlty broken (should be easy to fix though php_unstable = (import ../development/interpreters/php_configurable) { - inherit mkDerivationByConfiguration autoconf automake; - lib = lib_unstable; + inherit mkDerivationByConfiguration autoconf automake lib; stdenv = stdenvUsingSetupNew2; # optional features inherit fetchurl flex bison apacheHttpd mysql; # gettext; @@ -1799,10 +1798,9 @@ rec { fltk20 = (import ../development/libraries/fltk) { - inherit mkDerivationByConfiguration x11; + inherit mkDerivationByConfiguration x11 lib; inherit fetchurl stdenv mesa mesaHeaders libpng libjpeg zlib ; flags = [ "useNixLibs" "threads" "shared" "gl" ]; - lib = lib_unstable; }; fontconfig = import ../development/libraries/fontconfig { @@ -1826,8 +1824,7 @@ rec { }; geos = import ../development/libraries/geos { - lib = lib_unstable; - inherit fetchurl fetchsvn stdenv mkDerivationByConfiguration autoconf automake libtool swig which; + inherit fetchurl fetchsvn stdenv mkDerivationByConfiguration autoconf automake libtool swig which lib; use_svn = stdenv.system == "x86_64-linux"; python = python; # optional features: @@ -2064,8 +2061,6 @@ rec { } null; libdv = import ../development/libraries/libdv { - lib = lib_unstable; - inherit fetchurl stdenv mkDerivationByConfiguration; }; libdrm = import ../development/libraries/libdrm { @@ -2970,8 +2965,7 @@ rec { }; squid = import ../servers/squid { - inherit fetchurl stdenv mkDerivationByConfiguration perl; - lib = lib_unstable; + inherit fetchurl stdenv mkDerivationByConfiguration perl lib; }; tomcat5 = import ../servers/http/tomcat { @@ -3794,10 +3788,9 @@ rec { openal = openalSoft; }; blender = import ../applications/misc/blender { - inherit cmake mesa gettext freetype SDL libtiff fetchurl glibc scons x11 + inherit cmake mesa gettext freetype SDL libtiff fetchurl glibc scons x11 lib libjpeg libpng zlib /* smpeg sdl */; inherit (xlibs) inputproto libXi; - lib = lib_unstable; python = python_alts.v_2_5; freealut = freealut_soft; openal = openalSoft; @@ -4591,11 +4584,10 @@ rec { }; vim_configurable = import ../applications/editors/vim/configurable.nix { - inherit fetchurl stdenv ncurses pkgconfig mkDerivationByConfiguration; + inherit fetchurl stdenv ncurses pkgconfig mkDerivationByConfiguration lib; inherit (xlibs) libX11 libXext libSM libXpm libXt libXaw libXau libXmu; inherit (gtkLibs) glib gtk; - lib = lib_unstable; features = "huge"; # one of tiny, small, normal, big or huge # optional features by passing # python @@ -4744,11 +4736,10 @@ rec { # doesn't compile yet - in case someone else want's to continue .. /* qgis_svn = import ../applications/misc/qgis_svn { - lib = lib_unstable; - inherit mkDerivationByConfiguration fetchsvn flex + inherit mkDerivationByConfiguration fetchsvn flex lib ncurses fetchurl perl cmake gdal geos proj x11 gsl libpng zlib - sqlite glibc fontconfig freetype; + sqlite glibc fontconfig freetype / * use libc from stdenv ? - to lazy now - Marc * /; inherit (xlibs) libSM libXcursor libXinerama libXrandr libXrender; inherit (xorg) libICE; stdenv = stdenvUsingSetupNew2; |