about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-04-25T15·33+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-04-25T15·33+0000
commit0ef4b6d0f8dcaec093e3db366b6dfb6ba47f73a6 (patch)
treee36801703e1203a057acfc21b3408d3ddb5c9f18
parentd6d930a975cf0bfacb8a3117752452b89921b6ee (diff)
* Cleaned up the semantics of Fix expressions.
* Conditionals and variables in Fix expressions.  This allows, e.g.,

    Descr(
    [ Bind("pkgId", "subversion-0.21.0")

    , Bind("httpsClient", Bool(True))
    , Bind("httpServer", Bool(True))

    , Bind("ssl", If(Var("httpsClient"), Fix("./openssl-0.9.7b.fix"), ""))

    , Bind("httpd", If(Var("httpServer"), Fix("./httpd-2.0.45.fix"), ""))
    ...
    ])

  which introduces domain feature variables httpsClient and httpServer
  (i.e., whether Subversion is built with https client and webdav
  server support); the values of the variables influences package
  dependencies and the build scripts.

  The next step is to allow that packages can express constraints on
  each other.  E.g., StrategoXT is dependent on an ATerm library with
  the "gcc" variant enabled.  In fact, this may cause several
  Nix instantiations to be created from a single Fix descriptor.  If
  possible, Fix should try to find the least set of instantiations
  that obeys the constraints.


-rw-r--r--src/fix.cc196
-rwxr-xr-xtest/build/httpd-build.sh12
-rwxr-xr-xtest/build/openssl-build.sh12
-rwxr-xr-xtest/build/subversion-build.sh16
-rw-r--r--test/fixdescriptors/aterm-2.0.fix10
-rw-r--r--test/fixdescriptors/atk-1.2.0.fix12
-rw-r--r--test/fixdescriptors/glib-2.2.1.fix10
-rw-r--r--test/fixdescriptors/gnet-1.1.8.fix12
-rw-r--r--test/fixdescriptors/gtk+-2.2.1.fix16
-rw-r--r--test/fixdescriptors/gtkspell-2.0.2.fix20
-rw-r--r--test/fixdescriptors/httpd-2.0.45.fix10
-rw-r--r--test/fixdescriptors/openssl-0.9.7b.fix8
-rw-r--r--test/fixdescriptors/pan-0.13.95.fix24
-rw-r--r--test/fixdescriptors/pango-1.2.1.fix12
-rw-r--r--test/fixdescriptors/pkgconfig-0.15.0.fix8
-rw-r--r--test/fixdescriptors/pspell-.12.2.fix8
-rw-r--r--test/fixdescriptors/subversion-0.21.0.fix16
-rw-r--r--test/fixdescriptors/system.fix24
18 files changed, 276 insertions, 150 deletions
diff --git a/src/fix.cc b/src/fix.cc
index 0d3ae9bff868..052c1d4c9103 100644
--- a/src/fix.cc
+++ b/src/fix.cc
@@ -16,6 +16,9 @@ static string nixDescriptorDir;
 static string nixSourcesDir;
 
 
+static bool verbose = false;
+
+
 /* Mapping of Fix file names to the hashes of the resulting Nix
    descriptors. */
 typedef map<string, string> DescriptorMap;
@@ -23,10 +26,6 @@ typedef map<string, string> DescriptorMap;
 
 /* Forward declarations. */
 
-string instantiateDescriptor(string filename,
-    DescriptorMap & done);
-
-
 void registerFile(string filename)
 {
     int res = system(("nix regfile " + filename).c_str());
@@ -74,79 +73,136 @@ string fetchURL(string url)
 }
 
 
-/* Term evaluation functions. */
-
-string evaluateStr(ATerm e)
+Error badTerm(const string & msg, ATerm e)
 {
-    char * s;
-    if (ATmatch(e, "<str>", &s))
-        return s;
-    else throw Error("invalid string expression");
+    char * s = ATwriteToString(e);
+    return Error(msg + ", in `" + s + "'");
 }
 
 
-ATerm evaluateBool(ATerm e)
+/* Term evaluation. */
+
+typedef map<string, ATerm> BindingsMap;
+
+struct EvalContext
 {
-    if (ATmatch(e, "True") || ATmatch(e, "False"))
-        return e;
-    else throw Error("invalid boolean expression");
-}
+    string dir;
+    DescriptorMap * done;
+    BindingsMap * vars;
+};
+
 
+ATerm evaluate(ATerm e, EvalContext ctx);
+string instantiateDescriptor(string filename, EvalContext ctx);
 
-string evaluateFile(ATerm e, string dir)
+
+string evaluateStr(ATerm e, EvalContext ctx)
 {
+    e = evaluate(e, ctx);
     char * s;
-    ATerm t;
-    if (ATmatch(e, "<str>", &s)) {
-        checkHash(s);
+    if (ATmatch(e, "Str(<str>)", &s))
         return s;
-    } else if (ATmatch(e, "Url(<term>)", &t)) {
-        string url = evaluateStr(t);
-        string filename = fetchURL(url);
-        registerFile(filename);
-        return hashFile(filename);
-    } else if (ATmatch(e, "Local(<term>)", &t)) {
-        string filename = absPath(evaluateStr(t), dir); /* !!! */
-        string cmd = "cp -p " + filename + " " + nixSourcesDir;
-        int res = system(cmd.c_str());
-        if (WEXITSTATUS(res) != 0)
-            throw Error("cannot copy " + filename);
-        registerFile(nixSourcesDir + "/" + baseNameOf(filename));
-        return hashFile(filename);
-    } else throw Error("invalid file expression");
+    else throw badTerm("string value expected", e);
 }
 
 
-string evaluatePkg(ATerm e, string dir, DescriptorMap & done)
+bool evaluateBool(ATerm e, EvalContext ctx)
 {
-    char * s;
-    ATerm t;
-    if (ATmatch(e, "<str>", &s)) {
-        checkHash(s);
-        return s;
-    } else if (ATmatch(e, "Fix(<term>)", &t)) {
-        string filename = absPath(evaluateStr(t), dir); /* !!! */
-        return instantiateDescriptor(filename, done);
-    } else throw Error("invalid pkg expression");
+    e = evaluate(e, ctx);
+    if (ATmatch(e, "Bool(True)"))
+        return true;
+    else if (ATmatch(e, "Bool(False)"))
+        return false;
+    else throw badTerm("boolean value expected", e);
 }
 
 
-ATerm evaluate(ATerm e, string dir, DescriptorMap & done)
+ATerm evaluate(ATerm e, EvalContext ctx)
 {
-    ATerm t;
-    if (ATmatch(e, "Str(<term>)", &t))
-        return ATmake("Str(<str>)", evaluateStr(t).c_str());
-    else if (ATmatch(e, "Bool(<term>)", &t))
-        return ATmake("Bool(<term>)", evaluateBool(t));
-    else if (ATmatch(e, "File(<term>)", &t))
-        return ATmake("File(<str>)", evaluateFile(t, dir).c_str());
-    else if (ATmatch(e, "Pkg(<term>)", &t))
-        return ATmake("Pkg(<str>)", evaluatePkg(t, dir, done).c_str());
-    else throw Error("invalid expression type");
-}
+    char * s;
+    ATerm e2;
+    ATerm eCond, eTrue, eFalse;
 
+    /* Check for normal forms first. */
 
-typedef map<string, ATerm> BindingsMap;
+    if (ATmatch(e, "Str(<str>)", &s) ||
+        ATmatch(e, "Bool(True)") || ATmatch(e, "Bool(False)"))
+        return e;
+    
+    else if (
+        ATmatch(e, "Pkg(<str>)", &s) || 
+        ATmatch(e, "File(<str>)", &s))
+    {
+        checkHash(s);
+        return e;
+    }
+
+    /* Short-hands. */
+
+    else if (ATmatch(e, "<str>", &s))
+        return ATmake("Str(<str>)", s);
+
+    else if (ATmatch(e, "True", &s))
+        return ATmake("Bool(True)", s);
+
+    else if (ATmatch(e, "False", &s))
+        return ATmake("Bool(False)", s);
+
+    /* Functions. */
+
+    /* `Var' looks up a variable. */
+    else if (ATmatch(e, "Var(<str>)", &s)) {
+        string name(s);
+        ATerm e2 = (*ctx.vars)[name];
+        if (!e2) throw Error("undefined variable " + name);
+        return evaluate(e2, ctx); /* !!! update binding */
+    }
+
+    /* `Fix' recursively instantiates a Fix descriptor, returning the
+       hash of the generated Nix descriptor. */
+    else if (ATmatch(e, "Fix(<term>)", &e2)) {
+        string filename = absPath(evaluateStr(e2, ctx), ctx.dir); /* !!! */
+        return ATmake("Pkg(<str>)",
+            instantiateDescriptor(filename, ctx).c_str());
+    }
+
+    /* `Source' copies the specified file to nixSourcesDir, registers
+       it with Nix, and returns the hash of the file. */
+    else if (ATmatch(e, "Source(<term>)", &e2)) {
+        string source = absPath(evaluateStr(e2, ctx), ctx.dir); /* !!! */
+        string target = nixSourcesDir + "/" + baseNameOf(source);
+
+        // Don't copy if filename is already in nixSourcesDir.
+        if (source != target) {
+            if (verbose)
+                cerr << "copying source " << source << endl;
+            string cmd = "cp -p " + source + " " + target;
+            int res = system(cmd.c_str());
+            if (WEXITSTATUS(res) != 0)
+                throw Error("cannot copy " + source + " to " + target);
+        }
+        
+        registerFile(target);
+        return ATmake("File(<str>)", hashFile(target).c_str());
+    }
+
+    /* `Url' fetches a file from the network, caching it in
+       nixSourcesDir and returning the file name. */
+    else if (ATmatch(e, "Url(<term>)", &e2)) {
+        string url = evaluateStr(e2, ctx);
+        if (verbose)
+            cerr << "fetching " << url << endl;
+        string filename = fetchURL(url);
+        return ATmake("Str(<str>)", filename.c_str());
+    }
+
+    /* `If' provides conditional evaluation. */
+    else if (ATmatch(e, "If(<term>, <term>, <term>)", 
+                 &eCond, &eTrue, &eFalse)) 
+        return evaluate(evaluateBool(eCond, ctx) ? eTrue : eFalse, ctx);
+
+    else throw badTerm("invalid expression", e);
+}
 
 
 string getStringFromMap(BindingsMap & bindingsMap,
@@ -164,15 +220,14 @@ string getStringFromMap(BindingsMap & bindingsMap,
 
 /* Instantiate a Fix descriptors into a Nix descriptor, recursively
    instantiating referenced descriptors as well. */
-string instantiateDescriptor(string filename,
-    DescriptorMap & done)
+string instantiateDescriptor(string filename, EvalContext ctx)
 {
     /* Already done? */
-    DescriptorMap::iterator isInMap = done.find(filename);
-    if (isInMap != done.end()) return isInMap->second;
+    DescriptorMap::iterator isInMap = ctx.done->find(filename);
+    if (isInMap != ctx.done->end()) return isInMap->second;
 
     /* No. */
-    string dir = dirOf(filename);
+    ctx.dir = dirOf(filename);
 
     /* Read the Fix descriptor as an ATerm. */
     ATerm inTerm = ATreadFromNamedFile(filename.c_str());
@@ -184,6 +239,7 @@ string instantiateDescriptor(string filename,
     
     /* Iterate over the bindings and evaluate them to normal form. */
     BindingsMap bindingsMap; /* the normal forms */
+    ctx.vars = &bindingsMap;
 
     char * cname;
     ATerm value;
@@ -191,7 +247,7 @@ string instantiateDescriptor(string filename,
                &cname, &value, &bindings)) 
     {
         string name(cname);
-        ATerm e = evaluate(value, dir, done);
+        ATerm e = evaluate(value, ctx);
         bindingsMap[name] = e;
     }
 
@@ -229,7 +285,10 @@ string instantiateDescriptor(string filename,
     /* Register it with Nix. */
     registerFile(outFilename);
 
-    done[filename] = outHash;
+    if (verbose)
+        cerr << "instantiated " << outHash << " from " << filename << endl;
+
+    (*ctx.done)[filename] = outHash;
     return outHash;
 }
 
@@ -239,11 +298,14 @@ void instantiateDescriptors(Strings filenames)
 {
     DescriptorMap done;
 
+    EvalContext ctx;
+    ctx.done = &done;
+
     for (Strings::iterator it = filenames.begin();
          it != filenames.end(); it++)
     {
         string filename = absPath(*it);
-        cout << instantiateDescriptor(filename, done) << endl;
+        cout << instantiateDescriptor(filename, ctx) << endl;
     }
 }
 
@@ -274,7 +336,9 @@ void run(Strings::iterator argCur, Strings::iterator argEnd)
         if (arg == "-h" || arg == "--help") {
             printUsage();
             return;
-        } if (arg == "--instantiate" || arg == "-i") {
+        } else if (arg == "-v" || arg == "--verbose") {
+            verbose = true;
+        } else if (arg == "--instantiate" || arg == "-i") {
             command = cmdInstantiate;
         } else if (arg[0] == '-')
             throw UsageError("invalid option `" + arg + "'");
diff --git a/test/build/httpd-build.sh b/test/build/httpd-build.sh
new file mode 100755
index 000000000000..a5b43d744329
--- /dev/null
+++ b/test/build/httpd-build.sh
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+export PATH=/bin:/usr/bin
+
+top=`pwd`
+tar xvfz $src || exit 1
+cd httpd-* || exit 1
+./configure --prefix=$top --enable-ssl --with-ssl=$ssl --enable-mods-shared=all || exit 1
+make || exit 1
+make install || exit 1
+cd $top || exit 1
+rm -rf httpd-* || exit 1
diff --git a/test/build/openssl-build.sh b/test/build/openssl-build.sh
new file mode 100755
index 000000000000..23437a37b336
--- /dev/null
+++ b/test/build/openssl-build.sh
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+export PATH=/bin:/usr/bin
+
+top=`pwd`
+tar xvfz $src || exit 1
+cd openssl-* || exit 1
+./config --prefix=$top || exit 1
+make || exit 1
+make install || exit 1
+cd $top || exit 1
+rm -rf openssl-* || exit 1
diff --git a/test/build/subversion-build.sh b/test/build/subversion-build.sh
index cc1eba214e4f..3d1922c98ad5 100755
--- a/test/build/subversion-build.sh
+++ b/test/build/subversion-build.sh
@@ -5,10 +5,22 @@ export PATH=/bin:/usr/bin
 export LDFLAGS=-s
 
 top=`pwd`
+
+if test $httpsClient; then
+    extraflags="--with-ssl --with-libs=$ssl $extraflags"
+fi
+
+if test $httpServer; then
+    extraflags="--with-apxs=$httpd/bin/apxs --with-apr=$httpd --with-apr-util=$httpd $extraflags"
+    extrainst="APACHE_LIBEXECDIR=$top/modules $extrainst"
+fi
+
+echo "extra flags: $extraflags"
+
 tar xvfz $src || exit 1
 cd subversion-* || exit 1
-./configure --prefix=$top --with-ssl || exit 1
+./configure --prefix=$top $extraflags || exit 1
 make || exit 1
-make install || exit 1
+make install $extrainst || exit 1
 cd $top || exit 1
 rm -rf subversion-* || exit 1
diff --git a/test/fixdescriptors/aterm-2.0.fix b/test/fixdescriptors/aterm-2.0.fix
index 17e90ca8baec..8b1ba8560583 100644
--- a/test/fixdescriptors/aterm-2.0.fix
+++ b/test/fixdescriptors/aterm-2.0.fix
@@ -1,10 +1,10 @@
 Descr(
-  [ Bind("pkgId", Str("aterm-2.0"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "aterm-2.0")
+  , Bind("releaseId", "1")
 
-  , Bind("createGCC", Bool(True))
+  , Bind("createGCC", True)
 
-  , Bind("src", File(Url("http://www.cwi.nl/projects/MetaEnv/aterm/aterm-2.0.tar.gz")))
-  , Bind("build", File(Local("../build/aterm-build.sh")))
+  , Bind("src", Source(Url("http://www.cwi.nl/projects/MetaEnv/aterm/aterm-2.0.tar.gz")))
+  , Bind("build", Source("../build/aterm-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/atk-1.2.0.fix b/test/fixdescriptors/atk-1.2.0.fix
index 74e560327ca3..ab302a5ed7f4 100644
--- a/test/fixdescriptors/atk-1.2.0.fix
+++ b/test/fixdescriptors/atk-1.2.0.fix
@@ -1,11 +1,11 @@
 Descr(
-  [ Bind("pkgId", Str("atk-1.2.0"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "atk-1.2.0")
+  , Bind("releaseId", "1")
 
-  , Bind("pkgconfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
-  , Bind("glib", Pkg(Fix("./glib-2.2.1.fix")))
+  , Bind("pkgconfig", Fix("./pkgconfig-0.15.0.fix"))
+  , Bind("glib", Fix("./glib-2.2.1.fix"))
 
-  , Bind("src", File(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/atk-1.2.0.tar.bz2")))
-  , Bind("build", File(Local("../build/atk-build.sh")))
+  , Bind("src", Source(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/atk-1.2.0.tar.bz2")))
+  , Bind("build", Source("../build/atk-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/glib-2.2.1.fix b/test/fixdescriptors/glib-2.2.1.fix
index 2585c7ffb5b5..86a266707a3f 100644
--- a/test/fixdescriptors/glib-2.2.1.fix
+++ b/test/fixdescriptors/glib-2.2.1.fix
@@ -1,10 +1,10 @@
 Descr(
-  [ Bind("pkgId", Str("glib-2.2.1"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "glib-2.2.1")
+  , Bind("releaseId", "1")
 
-  , Bind("pkgconfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
+  , Bind("pkgconfig", Fix("./pkgconfig-0.15.0.fix"))
 
-  , Bind("src", File(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/glib-2.2.1.tar.bz2")))
-  , Bind("build", File(Local("../build/glib-build.sh")))
+  , Bind("src", Source(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/glib-2.2.1.tar.bz2")))
+  , Bind("build", Source("../build/glib-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/gnet-1.1.8.fix b/test/fixdescriptors/gnet-1.1.8.fix
index 34d9d10cd19f..526c2e865300 100644
--- a/test/fixdescriptors/gnet-1.1.8.fix
+++ b/test/fixdescriptors/gnet-1.1.8.fix
@@ -1,11 +1,11 @@
 Descr(
-  [ Bind("pkgId", Str("gnet-1.1.8"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "gnet-1.1.8")
+  , Bind("releaseId", "1")
 
-  , Bind("pkgconfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
-  , Bind("glib", Pkg(Fix("./glib-2.2.1.fix")))
+  , Bind("pkgconfig", Fix("./pkgconfig-0.15.0.fix"))
+  , Bind("glib", Fix("./glib-2.2.1.fix"))
 
-  , Bind("src", File(Url("http://www.gnetlibrary.org/src/gnet-1.1.8.tar.gz")))
-  , Bind("build", File(Local("../build/gnet-build.sh")))
+  , Bind("src", Source(Url("http://www.gnetlibrary.org/src/gnet-1.1.8.tar.gz")))
+  , Bind("build", Source("../build/gnet-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/gtk+-2.2.1.fix b/test/fixdescriptors/gtk+-2.2.1.fix
index 6793cac451be..7fc3da2d78d9 100644
--- a/test/fixdescriptors/gtk+-2.2.1.fix
+++ b/test/fixdescriptors/gtk+-2.2.1.fix
@@ -1,13 +1,13 @@
 Descr(
-  [ Bind("pkgId", Str("gtk+-2.2.1"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "gtk+-2.2.1")
+  , Bind("releaseId", "1")
 
-  , Bind("pkgconfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
-  , Bind("glib", Pkg(Fix("./glib-2.2.1.fix")))
-  , Bind("atk", Pkg(Fix("./atk-1.2.0.fix")))
-  , Bind("pango", Pkg(Fix("./pango-1.2.1.fix")))
+  , Bind("pkgconfig", Fix("./pkgconfig-0.15.0.fix"))
+  , Bind("glib", Fix("./glib-2.2.1.fix"))
+  , Bind("atk", Fix("./atk-1.2.0.fix"))
+  , Bind("pango", Fix("./pango-1.2.1.fix"))
 
-  , Bind("src", File(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/gtk+-2.2.1.tar.bz2")))
-  , Bind("build", File(Local("../build/gtk+-build.sh")))
+  , Bind("src", Source(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/gtk+-2.2.1.tar.bz2")))
+  , Bind("build", Source("../build/gtk+-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/gtkspell-2.0.2.fix b/test/fixdescriptors/gtkspell-2.0.2.fix
index e6d614f64a5d..3cb0b0bf12a7 100644
--- a/test/fixdescriptors/gtkspell-2.0.2.fix
+++ b/test/fixdescriptors/gtkspell-2.0.2.fix
@@ -1,15 +1,15 @@
 Descr(
-  [ Bind("pkgId", Str("gtkspell-2.0.2"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "gtkspell-2.0.2")
+  , Bind("releaseId", "1")
 
-  , Bind("pkgconfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
-  , Bind("glib", Pkg(Fix("./glib-2.2.1.fix")))
-  , Bind("atk", Pkg(Fix("./atk-1.2.0.fix")))
-  , Bind("pango", Pkg(Fix("./pango-1.2.1.fix")))
-  , Bind("gtk", Pkg(Fix("./gtk+-2.2.1.fix")))
-  , Bind("pspell", Pkg(Fix("./pspell-.12.2.fix")))
+  , Bind("pkgconfig", Fix("./pkgconfig-0.15.0.fix"))
+  , Bind("glib", Fix("./glib-2.2.1.fix"))
+  , Bind("atk", Fix("./atk-1.2.0.fix"))
+  , Bind("pango", Fix("./pango-1.2.1.fix"))
+  , Bind("gtk", Fix("./gtk+-2.2.1.fix"))
+  , Bind("pspell", Fix("./pspell-.12.2.fix"))
 
-  , Bind("src", File(Url("http://pan.rebelbase.com/download/extras/gtkspell/SOURCES/gtkspell-2.0.2.tar.gz")))
-  , Bind("build", File(Local("../build/gtkspell-build.sh")))
+  , Bind("src", Source(Url("http://pan.rebelbase.com/download/extras/gtkspell/SOURCES/gtkspell-2.0.2.tar.gz")))
+  , Bind("build", Source("../build/gtkspell-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/httpd-2.0.45.fix b/test/fixdescriptors/httpd-2.0.45.fix
new file mode 100644
index 000000000000..bb8365b450b1
--- /dev/null
+++ b/test/fixdescriptors/httpd-2.0.45.fix
@@ -0,0 +1,10 @@
+Descr(
+  [ Bind("pkgId", "httpd-2.0.45")
+  , Bind("releaseId", "1")
+
+  , Bind("ssl", Fix("./openssl-0.9.7b.fix"))
+
+  , Bind("src", Source(Url("http://apache.cs.uu.nl/dist/httpd/httpd-2.0.45.tar.gz")))
+  , Bind("build", Source("../build/httpd-build.sh"))
+  ]
+)
diff --git a/test/fixdescriptors/openssl-0.9.7b.fix b/test/fixdescriptors/openssl-0.9.7b.fix
new file mode 100644
index 000000000000..a0df665e5db4
--- /dev/null
+++ b/test/fixdescriptors/openssl-0.9.7b.fix
@@ -0,0 +1,8 @@
+Descr(
+  [ Bind("pkgId", "openssl-0.9.7b")
+  , Bind("releaseId", "1")
+
+  , Bind("src", Source(Url("http://www.openssl.org/source/openssl-0.9.7b.tar.gz")))
+  , Bind("build", Source("../build/openssl-build.sh"))
+  ]
+)
diff --git a/test/fixdescriptors/pan-0.13.95.fix b/test/fixdescriptors/pan-0.13.95.fix
index 3a32756b66c5..c9e5b9ab6d30 100644
--- a/test/fixdescriptors/pan-0.13.95.fix
+++ b/test/fixdescriptors/pan-0.13.95.fix
@@ -1,17 +1,17 @@
 Descr(
-  [ Bind("pkgId", Str("pan-0.13.95"))
-  , Bind("releaseId", Str("2"))
+  [ Bind("pkgId", "pan-0.13.95")
+  , Bind("releaseId", "2")
 
-  , Bind("pkgconfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
-  , Bind("glib", Pkg(Fix("./glib-2.2.1.fix")))
-  , Bind("atk", Pkg(Fix("./atk-1.2.0.fix")))
-  , Bind("pango", Pkg(Fix("./pango-1.2.1.fix")))
-  , Bind("gtk", Pkg(Fix("./gtk+-2.2.1.fix")))
-  , Bind("gnet", Pkg(Fix("./gnet-1.1.8.fix")))
-  , Bind("pspell", Pkg(Fix("./pspell-.12.2.fix")))
-  , Bind("gtkspell", Pkg(Fix("./gtkspell-2.0.2.fix")))
+  , Bind("pkgconfig", Fix("./pkgconfig-0.15.0.fix"))
+  , Bind("glib", Fix("./glib-2.2.1.fix"))
+  , Bind("atk", Fix("./atk-1.2.0.fix"))
+  , Bind("pango", Fix("./pango-1.2.1.fix"))
+  , Bind("gtk", Fix("./gtk+-2.2.1.fix"))
+  , Bind("gnet", Fix("./gnet-1.1.8.fix"))
+  , Bind("pspell", Fix("./pspell-.12.2.fix"))
+  , Bind("gtkspell", Fix("./gtkspell-2.0.2.fix"))
 
-  , Bind("src", File(Url("http://pan.rebelbase.com/download/releases/0.13.95/SOURCE/pan-0.13.95.tar.bz2")))
-  , Bind("build", File(Local("../build/pan-build-2.sh")))
+  , Bind("src", Source(Url("http://pan.rebelbase.com/download/releases/0.13.95/SOURCE/pan-0.13.95.tar.bz2")))
+  , Bind("build", Source("../build/pan-build-2.sh"))
   ]
 )
diff --git a/test/fixdescriptors/pango-1.2.1.fix b/test/fixdescriptors/pango-1.2.1.fix
index 7ee2486a6dce..419c4f6906c7 100644
--- a/test/fixdescriptors/pango-1.2.1.fix
+++ b/test/fixdescriptors/pango-1.2.1.fix
@@ -1,11 +1,11 @@
 Descr(
-  [ Bind("pkgId", Str("pango-1.2.1"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "pango-1.2.1")
+  , Bind("releaseId", "1")
 
-  , Bind("pkgconfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
-  , Bind("glib", Pkg(Fix("./glib-2.2.1.fix")))
+  , Bind("pkgconfig", Fix("./pkgconfig-0.15.0.fix"))
+  , Bind("glib", Fix("./glib-2.2.1.fix"))
 
-  , Bind("src", File(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/pango-1.2.1.tar.bz2")))
-  , Bind("build", File(Local("../build/pango-build.sh")))
+  , Bind("src", Source(Url("ftp://ftp.gtk.org/pub/gtk/v2.2/pango-1.2.1.tar.bz2")))
+  , Bind("build", Source("../build/pango-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/pkgconfig-0.15.0.fix b/test/fixdescriptors/pkgconfig-0.15.0.fix
index 27f32aba6419..28fe34a4b633 100644
--- a/test/fixdescriptors/pkgconfig-0.15.0.fix
+++ b/test/fixdescriptors/pkgconfig-0.15.0.fix
@@ -1,8 +1,8 @@
 Descr(
-  [ Bind("pkgId", Str("pkgconfig-0.15.0"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "pkgconfig-0.15.0")
+  , Bind("releaseId", "1")
 
-  , Bind("src", File(Url("http://www.freedesktop.org/software/pkgconfig/releases/pkgconfig-0.15.0.tar.gz")))
-  , Bind("build", File(Local("../build/pkgconfig-build.sh")))
+  , Bind("src", Source(Url("http://www.freedesktop.org/software/pkgconfig/releases/pkgconfig-0.15.0.tar.gz")))
+  , Bind("build", Source("../build/pkgconfig-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/pspell-.12.2.fix b/test/fixdescriptors/pspell-.12.2.fix
index f19600c25935..61741407982c 100644
--- a/test/fixdescriptors/pspell-.12.2.fix
+++ b/test/fixdescriptors/pspell-.12.2.fix
@@ -1,8 +1,8 @@
 Descr(
-  [ Bind("pkgId", Str("pspell-.12.2"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "pspell-.12.2")
+  , Bind("releaseId", "1")
 
-  , Bind("src", File(Url("http://unc.dl.sourceforge.net/sourceforge/pspell/pspell-.12.2.tar.gz")))
-  , Bind("build", File(Local("../build/pspell-build.sh")))
+  , Bind("src", Source(Url("http://unc.dl.sourceforge.net/sourceforge/pspell/pspell-.12.2.tar.gz")))
+  , Bind("build", Source("../build/pspell-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/subversion-0.21.0.fix b/test/fixdescriptors/subversion-0.21.0.fix
index 90d9d8d42b0d..dfe1f2482a7c 100644
--- a/test/fixdescriptors/subversion-0.21.0.fix
+++ b/test/fixdescriptors/subversion-0.21.0.fix
@@ -1,8 +1,16 @@
 Descr(
-  [ Bind("pkgId", Str("subversion-0.21.0"))
-  , Bind("releaseId", Str("1"))
+  [ Bind("pkgId", "subversion-0.21.0")
+  , Bind("releaseId", "1")
 
-  , Bind("src", File(Url("http://subversion.tigris.org/files/documents/15/3712/subversion-0.21.0.tar.gz")))
-  , Bind("build", File(Local("../build/subversion-build.sh")))
+  , Bind("httpsClient", Bool(True))
+  , Bind("httpServer", Bool(True))
+  , Bind("httpsServer", Bool(True))
+
+  , Bind("ssl", If(Var("httpsClient"), Fix("./openssl-0.9.7b.fix"), ""))
+
+  , Bind("httpd", If(Var("httpServer"), Fix("./httpd-2.0.45.fix"), ""))
+
+  , Bind("src", Source(Url("http://subversion.tigris.org/files/documents/15/3712/subversion-0.21.0.tar.gz")))
+  , Bind("build", Source("../build/subversion-build.sh"))
   ]
 )
diff --git a/test/fixdescriptors/system.fix b/test/fixdescriptors/system.fix
index 62d4eae406a7..5e9f497d1491 100644
--- a/test/fixdescriptors/system.fix
+++ b/test/fixdescriptors/system.fix
@@ -2,18 +2,18 @@ Descr(
   [ Bind("pkgId", Str("system"))
   , Bind("releaseId", Str("2"))
 
-  , Bind("actATerm", Pkg(Fix("./aterm-2.0.fix")))
-  , Bind("actPkgConfig", Pkg(Fix("./pkgconfig-0.15.0.fix")))
-  , Bind("actGlib", Pkg(Fix("./glib-2.2.1.fix")))
-  , Bind("actAtk", Pkg(Fix("./atk-1.2.0.fix")))
-  , Bind("actPango", Pkg(Fix("./pango-1.2.1.fix")))
-  , Bind("actGtk", Pkg(Fix("./gtk+-2.2.1.fix")))
-  , Bind("actGnet", Pkg(Fix("./gnet-1.1.8.fix")))
-  , Bind("actPspell", Pkg(Fix("./pspell-.12.2.fix")))
-  , Bind("actGtkspell", Pkg(Fix("./gtkspell-2.0.2.fix")))
-  , Bind("actPan", Pkg(Fix("./pan-0.13.95.fix")))
-  , Bind("actSubversion", Pkg(Fix("./subversion-0.21.0.fix")))
+  , Bind("actATerm", Fix("./aterm-2.0.fix"))
+  , Bind("actPkgConfig", Fix("./pkgconfig-0.15.0.fix"))
+  , Bind("actGlib", Fix("./glib-2.2.1.fix"))
+  , Bind("actAtk", Fix("./atk-1.2.0.fix"))
+  , Bind("actPango", Fix("./pango-1.2.1.fix"))
+  , Bind("actGtk", Fix("./gtk+-2.2.1.fix"))
+  , Bind("actGnet", Fix("./gnet-1.1.8.fix"))
+  , Bind("actPspell", Fix("./pspell-.12.2.fix"))
+  , Bind("actGtkspell", Fix("./gtkspell-2.0.2.fix"))
+  , Bind("actPan", Fix("./pan-0.13.95.fix"))
+  , Bind("actSubversion", Fix("./subversion-0.21.0.fix"))
 
-  , Bind("build", File(Local("../../scripts/nix-populate")))
+  , Bind("build", Source("../../scripts/nix-populate"))
   ]
 )