Index: lib/Tinderbox/MakeCache.pm
==================================================================
--- lib/Tinderbox/MakeCache.pm
+++ lib/Tinderbox/MakeCache.pm
@@ -47,10 +47,11 @@
         my $name = shift;
         my $self = bless {
                 CACHE   => undef,
                 SEEN    => undef,
                 BASEDIR => shift,
+                CHROOT  => shift,
         }, $name;
 
         $self;
 }
 
@@ -65,11 +66,14 @@
 
         return if ($self->{SEEN}->{$port} eq 1);
 
         $tmp = '-V ' . join(' -V ', @makeTargets);
         my $dir = $self->{BASEDIR} . '/' . $port;
-        @ret = split("\n", `cd $dir && make $tmp`);
+        my $cmd = "cd $dir && make $tmp";
+        $cmd = "chroot $self->{CHROOT} /bin/sh -c '$cmd'";
+
+        @ret = split("\n", `$cmd`);
 
         foreach $tmp (@makeTargets) {
                 $self->{CACHE}->{$port}{$tmp} = shift @ret;
         }
         $self->{SEEN}->{$port} = 1;

Index: lib/makemake
==================================================================
--- lib/makemake
+++ lib/makemake
@@ -133,24 +133,25 @@
 #---------------------------------------------------------------------------
 
 my (
         %pkgdir,   %pkgdeps,  %pkgedeps, %pkgpdeps, %pkgfdeps,
         %pkgbdeps, %pkgrdeps, @duds,     $portbase, $makecache,
-        %pkgtdeps, %pkgpkgdeps,
+        %pkgtdeps, %pkgpkgdeps,          $chroot,
 );
 
 $portbase  = $ENV{'PORTSDIR'};
-$makecache = new Tinderbox::MakeCache($portbase, $ENV{'PKGSUFFIX'});
+$chroot    = $ENV{'CHROOT'};
+$makecache = new Tinderbox::MakeCache($portbase, $chroot, $ENV{'PKGSUFFIX'});
 
 while (scalar(@PORTS)) {
         my $port    = shift @PORTS;
         my $portdir = $port->getDirectory();
         my ($pkgname, $deplist, $tportdir);
 
         next if (defined($pkgdir{$portdir}));
 
-        $tportdir = "$portbase/$portdir";
+        $tportdir = "$chroot$portbase/$portdir";
         if (!-d $tportdir) {
                 print STDERR "ERROR: Directory $tportdir does not exist.\n";
                 if (defined($pkgdeps{$portdir})
                         && scalar(@{$pkgdeps{$portdir}}))
                 {

Index: lib/tc_command.pl
==================================================================
--- lib/tc_command.pl
+++ lib/tc_command.pl
@@ -1534,11 +1534,12 @@
 # Internal function: do NOT call directly, but only from addPort
 # This code assumes its mount points and environment have been set up
 sub addPortToOneBuild {
         my $build = $ds->getBuildByName($opts->{'b'});
         my $makecache =
-            new Tinderbox::MakeCache($ENV{'PORTSDIR'}, $ENV{'PKGSUFFIX'});
+            new Tinderbox::MakeCache($ENV{'PORTSDIR'}, $ENV{'CHROOT'},
+                                     $ENV{'PKGSUFFIX'});
         my @bports = ();
 
         if (!$opts->{'d'}) {
                 foreach my $port ($ds->getPortsForBuild($build)) {
                         push @bports, $port->getDirectory();
@@ -3412,16 +3413,18 @@
         my $port  = shift;
         my $build = shift;
         my $cache = shift;
         my $deps  = shift;
 
-        my $portdir = $ENV{'PORTSDIR'} . "/" . $port;
+        my $portsdir = $ENV{'CHROOT'} . $ENV{'PORTSDIR'};
+
+        my $portdir = $portsdir . "/" . $port;
         return undef if (!-d $portdir);
 
         # Canonicalize the port directory.
         $port = abs_path($portdir);
-        $port =~ s|$ENV{'PORTSDIR'}/||;
+        $port =~ s|$portsdir/||;
 
         if (defined($deps)) {
                 my @list;
                 push @list, $cache->PkgDependsList($port);
                 push @list, $cache->BuildDependsList($port);

Index: lib/tc_command.sh
==================================================================
--- lib/tc_command.sh
+++ lib/tc_command.sh
@@ -1396,11 +1396,11 @@
     # Clean up any previous build tree
     tinderbuild_reset ${buildName}
     cleanDirs ${buildName} ${BUILD_DIR}
 
     if [ "${MD_FSTYPE}" = "ufs" -o "${MD_FSTYPE}" = "zfs" ]; then
-	if [ -n "${MD_SIZE}" -a ${MD_SIZE%[a-zA-Z]} -gt 0 ]; then
+	if [ -n "${MD_SIZE}" ] && [ ${MD_SIZE%[a-zA-Z]} -gt 0 ]; then
 	    # setup md (ramdisk) backing for the build
 	    mdconfig -a -t swap -s ${MD_SIZE} > /tmp/tinderbuild_md.${build}
 	    read MD_UNIT </tmp/tinderbuild_md.${build}
 
 	    if [ "${MD_FSTYPE}" = "ufs" ]; then
@@ -1411,11 +1411,11 @@
 		zfs set compression=on ${MD_UNIT}
 		zfs set mountpoint=${BUILD_DIR} ${MD_UNIT}
 	    fi
 	fi
     elif [ "${MD_FSTYPE}" = "tmpfs" ]; then
-	if [ -n "${MD_SIZE}" -a ${MD_SIZE%[a-zA-Z]} -gt 0 ]; then
+	if [ -n "${MD_SIZE}" ] && [ ${MD_SIZE%[a-zA-Z]} -gt 0 ]; then
 	    mount -t tmpfs -o size=${MD_SIZE} tmpfs ${BUILD_DIR}
 	else
 	    mount -t tmpfs tmpfs ${BUILD_DIR}
 	fi
     elif [ -n "${MD_FSTYPE}" ]; then
@@ -1427,11 +1427,11 @@
     tar -C ${BUILD_DIR} -xpf ${JAIL_TARBALL}
 
     execute_hook "postBuildExtract" "BUILD=${buildName} DESTDIR=${BUILD_DIR} JAIL=${jailName} PB=${pb} RC=0"
 
     # Finalize environment
-    cp -f /etc/resolv.conf ${BUILD_DIR}/etc
+    cp /etc/resolv.conf ${BUILD_DIR}/etc || touch ${BUILD_DIR}/etc/resolv.conf
 
     return 0
 }
 
 resetBuild () {
@@ -1975,49 +1975,46 @@
     if [ ${updateports} -eq 1 ]; then
 	echo "tinderbuild: Updating ${portstree} portstree for ${build}"
 	${tc} updatePortsTree -p ${portstree}
     fi
 
-    # Create makefile if required
+    # Set up the chrooted environment
+    osmajor=$(echo ${jail} | sed -E -e 's|(^[[:digit:]]+).*$|\1|')
+    if [ ${osmajor} -lt 6 ]; then
+	echo "tinderbuild: unhandled OS version: ${osmajor}"
+	tinderbuild_cleanup 1
+    fi
+
+    tinderbuild_setup
+
+    # Create Makefile if required
     if [ ${skipmake} -eq 0 ]; then
 	echo "tinderbuild: creating makefile..."
 
 	# Need to do this in a subshell so as to only hide the host
 	# environment during makefile creation
 	(
 	    export PORTBUILD_ARGS="$(echo ${pbargs})"
 	    buildenvNoHost ${build}
-	    if ! requestMount -t portstree -p ${portstree}; then
-		echo "tinderbuild: cannot mount portstree: ${portstree}"
-		exit 1
-	    fi
-	    env PORTSDIR=$(tinderLoc portstree ${portstree})/ports \
+	    buildenv ${jail} ${portstree} ${build}
+	    HOST_WORKDIR=$(${tc} configGet | \
+		awk -F= '/^HOST_WORKDIR/ {print $2}')
+	    env PORTSDIR=/a/ports \
+		CHROOT=$(tinderLoc buildroot ${build}) \
 		$(tinderLoc scripts lib/makemake) ${noduds} ${build} ${ports}
 	)
 	if [ $? -ne 0 ]; then
 	    echo "tinderbuild: failed to generate Makefile for ${build}"
-	    cleanupMounts -t portstree -p ${portstree}
 	    tinderbuild_cleanup 1
-	else
-	    cleanupMounts -t portstree -p ${portstree}
 	fi
     fi
 
     if [ ${onlymake} -eq 1 ]; then
 	echo "onlymake specified: not running tinderbuild"
 	tinderbuild_cleanup 0
     fi
 
-    # Set up the chrooted environment
-    osmajor=$(echo ${jail} | sed -E -e 's|(^[[:digit:]]+).*$|\1|')
-    if [ ${osmajor} -lt 6 ]; then
-	echo "tinderbuild: unhandled OS version: ${osmajor}"
-	tinderbuild_cleanup 1
-    fi
-
-    tinderbuild_setup
-
     # Seatbelts off.  Away we go.
     ${tc} updateBuildStatus -b ${build} -s PORTBUILD
     tinderbuild_phase 0 ${jobs} ${pkgDir}
     error=$?
     if [ ${onceonly} -ne 1 ]; then
@@ -2063,11 +2060,15 @@
 #---------------------------------------------------------------------------
 
 addPortToBuild_cleanup () {
     jail=$1
     portsTree=$2
+    build=$3
 
+    cleanupMounts -t buildports -b ${build}
+    cleanupMounts -t buildsrc -b ${build}
+    cleanupMounts -t buildoptions -b ${build}
     cleanupMounts -t jail -j ${jail}
     cleanupMounts -t portstree -p ${portsTree}
 }
 
 addPortToBuild () {
@@ -2088,11 +2089,33 @@
     if ! requestMount -t portstree -p ${portsTree} -r; then
 	echo "addPortToBuild: cannot mount portstree source"
 	exit 1
     fi
 
-    trap "addPortToBuild_cleanup ${jail} ${portsTree}" 1 2 3 9 10 11 15
+    # Extracting the Jail tarball takes ages on some systems, so we can
+    # pretty safely (for these purposes) reuse the extraction as long as
+    # resolv.conf is newer than the tarball (resolv.conf is created
+    # by makeBuild)
+    HOST_WORKDIR=$(${tc} configGet | awk -F= '/^HOST_WORKDIR/ {print $2}')
+    if [ $(tinderLoc jailtarball ${jail}) -ot \
+	 $(tinderLoc buildroot ${build})/etc/resolv.conf ]; then
+	echo "addPortToBuild: recent jail tarball exists; no need to reextract"
+    else
+	echo "addPortToBuild: extracting jail tarball to calculate dependencies inside"
+	makeBuild -b ${build}
+    fi
+
+    if ! requestMount -t buildports -b ${build} -r -n; then
+	echo "addPortToBuild: cannot mount ports source inside ${build}"
+	exit 1
+    fi
+    if ! requestMount -t buildsrc -b ${build} -r -n; then
+	echo "addPortToBuild: cannot mount base source inside ${build}"
+	exit 1
+    fi
+
+    trap "addPortToBuild_cleanup ${jail} ${portsTree} ${build}" 1 2 3 9 10 11 15
 
     # Save TERM since we need that for OPTIONS
     save_TERM=${TERM}
     save_SRCBASE=
     if [ -n "${SRCBASE}" ]; then
@@ -2100,26 +2123,34 @@
     fi
 
     buildenv ${jail} ${portsTree} ${build}
     buildenvNoHost ${build}
 
-    export PORTSDIR=$(tinderLoc portstree ${portsTree})/ports
-    if [ -z "${portDir}" ]; then
-	${tc} addPortToOneBuild -b ${build} ${norecurse}
-    else
-        if [ ! -d ${PORTSDIR}/${portDir} ]; then
-            echo "addPort: Unknown port ${portDir}"
-            exit 1
-        fi
-        ${tc} addPortToOneBuild -b ${build} -d ${portDir} ${norecurse}
+    if [ ${options} -eq 1 -a ${OPTIONS_ENABLED} -eq 1 ]; then
+	mkdir -p $(tinderLoc options ${build}) \
+		 $(tinderLoc buildoptions ${build})
+	if ! requestMount -t buildoptions -b ${build} \
+		-s $(tinderLoc options ${build}) -n; then
+	    echo "addPortToBuild: cannot mount options inside ${build}"
+	    exit 1
+	fi
     fi
+
+    export PORTSDIR=/a/ports
+    export CHROOT=$(tinderLoc buildroot ${build})
+
+    if [ -n "${portDir}" ] && [ ! -d ${CHROOT}/${PORTSDIR}/${portDir} ]; then
+        echo "addPort: Unknown port ${portDir}"
+        exit 1
+    fi
+
     if [ ${options} -eq 1 -a ${OPTIONS_ENABLED} -eq 1 ]; then
 	pdirs=""
 	if [ -z "${portDir}" ]; then
 	    pdirs=$(${tc} getPortsForBuild -b ${build} 2>/dev/null)
 	else
-	    pdirs="${PORTSDIR}/${portDir}"
+	    pdirs="${portDir}"
 	fi
 	rmconfig=true
 	if [ ${cleanOptions} -eq 1 ]; then
 	    if [ -z "${norecurse}" ]; then
 		rmconfig="make rmconfig-recursive"
@@ -2126,32 +2157,42 @@
 	    else
 		rmconfig="make rmconfig"
 	    fi
 	fi
 	for pdir in ${pdirs}; do
-	    if [ -d ${pdir} ]; then
+	    if [ -d ${CHROOT}${PORTSDIR}/${pdir} ]; then
 	        export TERM=${save_TERM}
+		if ! cp /usr/local/bin/dialog4ports-static ${CHROOT}/; then
+		    echo "In order to customise OPTIONS, you must install"
+		    echo "ports-mgmt/dialog4ports-static."
+		    break
+		fi
 	        read -p "Generating options for ${build}; hit Enter to continue..." key
 	        echo ""
 	        if [ -z "${norecurse}" ]; then
-		    ( cd ${pdir} && ${rmconfig} \
-			&& DIALOG4PORTS=/usr/local/bin/dialog4ports make -k config-recursive )
+		    chroot ${CHROOT} /bin/sh -c \
+			"cd ${PORTSDIR}/${pdir} && ${rmconfig} && \
+			make -k DIALOG4PORTS=/dialog4ports-static \
+			    config-recursive"
 	        else
-		    ( cd ${pdir} && ${rmconfig} \
-			&& DIALOG4PORTS=/usr/local/bin/dialog4ports make config )
+		    chroot ${CHROOT} /bin/sh -c \
+			"cd ${PORTSDIR}/${pdir} && ${rmconfig} && \
+			make DIALOG4PORTS=/dialog4ports-static config"
 	        fi
 	    fi
 	done
     fi
+
+    ${tc} addPortToOneBuild -b ${build} ${portDir:+-d} ${portDir} ${norecurse}
 
     if [ -n "${save_SRCBASE}" ]; then
 	export SRCBASE=${save_SRCBASE}
     else
 	unset SRCBASE
     fi
 
-    addPortToBuild_cleanup ${jail} ${portsTree}
+    addPortToBuild_cleanup ${jail} ${portsTree} ${build}
 }
 
 addPort () {
     # set up defaults
     build=""

Index: lib/tinderlib.sh
==================================================================
--- lib/tinderlib.sh
+++ lib/tinderlib.sh
@@ -537,17 +537,10 @@
     jail=$(${tc} getJailForBuild -b ${build})
     jailBase=$(tinderLoc jail ${jail})
     eval "export __MAKE_CONF=${jailBase}/make.conf" >/dev/null 2>&1
     eval "export LOCALBASE=/nonexistentlocal" >/dev/null 2>&1
     eval "export PKG_DBDIR=/nonexistentdb" >/dev/null 2>&1
-    if [ x"${OPTIONS_ENABLED}" != x"1" ]; then
-        eval "export PORT_DBDIR=/nonexistentportdb" >/dev/null 2>&1
-    else
-	optionsDir=$(tinderLoc options ${build})
-
-	eval "export PORT_DBDIR=${optionsDir}" >/dev/null 2>&1
-    fi
     eval "export LINUXBASE=/nonexistentlinux" >/dev/null 2>&1
     eval "unset DISPLAY" >/dev/null 2>&1
 }
 
 getDbDriver () {

