summary refs log tree commit diff
path: root/corepkgs/buildenv/builder.pl.in
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-04-06 11:42:28 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-04-06 11:42:28 +0000
commit2be8ac48bb4349bdd61e993ccf325a7b9e167627 (patch)
treef9bf870def580f36c90333ae53e232d5950dbf91 /corepkgs/buildenv/builder.pl.in
parentbf3863b546dcb9bd62e86c0f17d8b12b2d08b874 (diff)
downloadguix-2be8ac48bb4349bdd61e993ccf325a7b9e167627.tar.gz
* Make the creation of user environments much faster and more storage
  efficient by creating only a single symlink to entire directory
  trees unless a collission occurs.

Diffstat (limited to 'corepkgs/buildenv/builder.pl.in')
-rwxr-xr-xcorepkgs/buildenv/builder.pl.in111
1 files changed, 66 insertions, 45 deletions
diff --git a/corepkgs/buildenv/builder.pl.in b/corepkgs/buildenv/builder.pl.in
index d9ff73e17d..9a5fad9125 100755
--- a/corepkgs/buildenv/builder.pl.in
+++ b/corepkgs/buildenv/builder.pl.in
@@ -2,71 +2,92 @@
 
 use strict;
 use Cwd;
+use IO::Handle;
+
+STDOUT->autoflush(1);
+
+my $out = $ENV{"out"};
+mkdir "$out", 0755 || die "error creating $out";
 
-my $selfdir = $ENV{"out"};
-mkdir "$selfdir", 0755 || die "error creating $selfdir";
 
 # For each activated package, create symlinks.
 
 sub createLinks {
-    my $srcdir = shift;
-    my $dstdir = shift;
-
-    my @srcfiles = glob("$srcdir/*");
-
-    foreach my $srcfile (@srcfiles) {
-        my $basename = $srcfile;
-        $basename =~ s/^.*\///g; # strip directory
-        my $dstfile = "$dstdir/$basename";
-	if ($srcfile =~ /\/propagated-build-inputs$/) {
-	} elsif (-d $srcfile) {
-            # !!! hack for resolving name clashes
-            if (!-e $dstfile) {
-                mkdir $dstfile, 0755 || 
-                    die "error creating directory $dstfile";
+    my $srcDir = shift;
+    my $dstDir = shift;
+
+    my @srcFiles = glob("$srcDir/*");
+
+    foreach my $srcFile (@srcFiles) {
+        my $baseName = $srcFile;
+        $baseName =~ s/^.*\///g; # strip directory
+        my $dstFile = "$dstDir/$baseName";
+        
+	if ($srcFile =~ /\/propagated-build-inputs$/ ||
+            $srcFile =~ /\/nix-support$/)
+        {
+            # Do noting.
+	}
+
+        elsif (-d $srcFile) {
+
+            lstat $dstFile;
+            
+            if (-d _) {
+                createLinks($srcFile, $dstFile);
+            }
+
+            elsif (-l _) {
+                my $target = readlink $dstFile or die;
+                if (!-d $target) {
+                    die "collission between directory `$srcFile' and non-directory `$target'";
+                }
+                unlink $dstFile or die "error unlinking `$dstFile': $!";
+                mkdir $dstFile, 0755 || 
+                    die "error creating directory `$dstFile': $!";
+                createLinks($target, $dstFile);
+                createLinks($srcFile, $dstFile);
             }
-            -d $dstfile or die "$dstfile is not a directory";
-            createLinks($srcfile, $dstfile);
-        } elsif (-l $dstfile) {
-            my $target = readlink($dstfile);
-            die "collission between $srcfile and $target";
-        } else {
-#            print "linking $dstfile to $srcfile\n";
-            symlink($srcfile, $dstfile) ||
-                die "error creating link $dstfile";
+
+            else {
+                symlink($srcFile, $dstFile) ||
+                    die "error creating link `$dstFile': $!";
+            }
+        }
+
+        elsif (-l $dstFile) {
+            my $target = readlink $dstFile;
+            die "collission between `$srcFile' and `$target'";
+        }
+
+        else {
+#            print "linking $dstFile to $srcFile\n";
+            symlink($srcFile, $dstFile) ||
+                die "error creating link `$dstFile': $!";
         }
     }
 }
 
+
 my %done;
 
 sub addPkg {
-    my $pkgdir = shift;
+    my $pkgDir = shift;
 
-    return if (defined $done{$pkgdir});
-    $done{$pkgdir} = 1;
+    return if (defined $done{$pkgDir});
+    $done{$pkgDir} = 1;
 
-#    print "merging $pkgdir\n";
-
-    createLinks("$pkgdir", "$selfdir");
-
-#    if (-f "$pkgdir/envpkgs") {
-#	my $envpkgs = `cat $pkgdir/envpkgs`;
-#	chomp $envpkgs;
-#	my @envpkgs = split / +/, $envpkgs;
-#	foreach my $envpkg (@envpkgs) {
-#	    addPkg($envpkg);
-#	}
-#    }
+    createLinks("$pkgDir", "$out");
 }
 
+
 my @args = split ' ', $ENV{"derivations"};
 
 while (scalar @args > 0) {
-    my $drvpath = shift @args;
-    print "adding $drvpath\n";
-    addPkg($drvpath);
+    my $drvPath = shift @args;
+    print "adding $drvPath\n";
+    addPkg($drvPath);
 }
 
-symlink($ENV{"manifest"}, "$selfdir/manifest") or die "cannot create manifest";
 
+symlink($ENV{"manifest"}, "$out/manifest") or die "cannot create manifest";