[Nix-dev] Yet another configure proposal (final ?)

Marc Weber marco-oweber at gmx.de
Thu Aug 16 06:45:19 CEST 2007


  note how useNixLibs implies jpeg, png and zlib and how
  mandatory ensures that the not tested flags cygwin and quartz cannot
  be used..

  Drawback: I've used
   __getAttr __hasAttr listToSet which are not yet stable or in svn
   (which could be changed, niksnut ??)

   I think its really easy and you have a chonge to see what is
   happening without knowing details..

  Speed won't be a big issue because lazy evaluation (thus the flags and
  buildInputs are only evaluated if the derivation itself is
  instantiated except when adding flags to the meta info as below ..)

Marc

============= all-packages.nix =======================================
  fltk20 = (import ../development/libraries/fltk) {
    inherit fetchurl stdenv lib mesa mesaHeaders libpng libjpeg zlib;
    flags = [ "useNixLibs" "threads" "shared" ];
  };

============= fltk/default.nix =======================================
args:
with args;
with args.lib; 
let 
  flagDescr = 
    { mandatory = { cfgOption = " --prefix=\$out"; blocks = ["cygwin" "quartz" ]; }
    ; cygwin = { cfgOption = "--enable-cygwin"; } #         use the CygWin libraries default=no
    ; debug = { cfgOption = "--enable-debug"; } #          turn on debugging default=no
    ; gl = { cfgOption = "--enable-gl"; buildInputs = [ "mesa" "mesa-heaaders"]; } #             turn on OpenGL support default=yes
    ; shared = { cfgOption = "--enable-shared"; } #         turn on shared libraries default=no
    ; threads = { cfgOption = "--enable-threads"; } #        enable multi-threading support
    ; quartz = { cfgOption = "--enable-quartz"; buildInputs = "quartz"; } # don't konw yet what quartz is #         use Quartz instead of Quickdraw (default=no)
    ; largefile = { cfgOption = "--disable-largefile"; } #     omit support for large files
    ; useNixLibs = { implies = [ "nixjpeg" "nixpng" "nixzlib" ]; } # use nix libraries only
    ; nixjpeg = { cfgOption = "--disable-localjpeg"; buildInputs = "libjpeg"; } #      use local JPEG library, default=auto
    ; nixzlib = { cfgOption = "--disable-localzlib"; buildInputs = "zlib"; } #      use local ZLIB library, default=auto
    ; nixpng = { cfgOption = "--disable-localpng"; buildInputs = "libpng"; } #       use local PNG library, default=auto
    ; xinerama = { cfgOption = "--enable-xinerama"; buildInputs = "xinerama"; } #       turn on Xinerama support default=no
    ; xft = { cfgOption = "--enable-xft"; buildInputs="xft"; } #            turn on Xft support default=no
    ; xdbe = { cfgOption = "--enable-xdbe"; } #           turn on Xdbe support default=no
    ;};
  res = getFlagAttrs flagDescr args ( ["mandatory"] ++ args.flags );
  flattend = flattenSet res;
  buildInputs = map ( attr: if (! __hasAttr attr args) then throw "argument ${attr} is missing!" else (__getAttr attr args) )
                (uniqList { inputList = catAttrs "buildInputs" flattend; });
  buildInputNames = catAttrs "name" buildInputs;
  configureFlags = uniqList { inputList = intersperse " " ( catAttrs "cfgOption" flattend); };
in
args.stdenv.mkDerivation {
  name = "fltk-2.0.x-r5940";

  inherit buildInputs configureFlags buildInputNames;

  unpackPhase = "unset unpackPhase; echo build inputs are: \$buildInputNames; unpackPhase;";
 
  src = fetchurl {
    url = http://mirror.switch.ch/mirror/gentoo/distfiles/fltk-1.1.7-source.tar.bz2;
    sha256 = "899bbefa0fab3e25cb04697f3113763a68e16263fe934e8cab4454111e84fd5f";
  };

  meta = { 
      description = "a C++ cross platform lightweight gui library binding";
      homepage = http://www.fltk.org;
      flags = ( __attrNames res );
    };
}

============= the not very well tested implementation ================

  # l : list of attribute sets
  # returns a list of attributes. Sets not having the attribute are ignored
  catAttrs = attr : l : fold ( s : l : if (__hasAttr attr s) then [(__getAttr attr s)] ++ l else l) [] l;

  # {a="a"; b="b" c = {};} =>  [ "a" "b" {} ]
  flattenSet = set : map ( attr : __getAttr attr set) (__attrNames set);

# Marc 2nd proposal:
#          flags = 
#            { mandatory = { configure = .. ; derivations = ..;};
#              opengl  = { configure = "--with-opengl"; derivations = ["mesa"]; blocks = ["directX"]; implies = ["gui"]; };
#              directX = { configure = "--with-directX"; derivations = ["windirectXBindings"]; blocks = ["opengl"]; implies = ["gui"]; };
#              gui = { derivation ..
#            }; # you got it, didn't you?

  getFlagAttrs = flagDescr: args: flags: 
    let collectFlags = state : flags :
            fold ( flag : s : 
                   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?
                        then throw "flag ${flag} is blocked by ${__getAttr flag s.blockedFlagsBy}"
                        else if (! __hasAttr flag flagDescr) then throw "unkown flag `${flag}' specified"
                             else let fDesc = (__getAttr flag flagDescr);
                                      implied = flatten ( getAttr ["implies"] [] fDesc );
                                      blocked = flatten ( getAttr ["blocks"] [] fDesc ); 
                                      s2 = assert (fold ( b : t : 
                                               if ( __hasAttr b s.result ) 
                                                 then  throw "flag ${b} is blocked by ${flag}"
                                                 else t) true (flatten blocked));
                                           (collectFlags s implied);
                                      # add the whole flag to the result set
                                      in s2 // { result = s2.result //
                                                    listToSet [ { attr = flag; value = (__getAttr flag flagDescr); } ]; }
            ) state flags;
      s = collectFlags { blockedFlagsBy = {}; result = {}; } flags;
    in s.result;



More information about the nix-dev mailing list