about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/nix-build.in37
1 files changed, 37 insertions, 0 deletions
diff --git a/scripts/nix-build.in b/scripts/nix-build.in
index 3ac02ad35ea5..b7c923f88607 100755
--- a/scripts/nix-build.in
+++ b/scripts/nix-build.in
@@ -25,6 +25,8 @@ my @envExclude = ();
 
 my $myName = $runEnv ? "nix-shell" : "nix-build";
 
+my $inShebang = 0;
+my $script;
 
 my $tmpDir = mkTempDir($myName);
 
@@ -35,6 +37,29 @@ my $drvLink = "$tmpDir/derivation";
 $SIG{'INT'} = sub { exit 1 };
 
 
+# Heuristic to see if we're invoked as a shebang script, namely, if we
+# have a single argument, it's the name of an executable file, and it
+# starts with "#!".
+if ($runEnv && scalar @ARGV == 1) {
+    $script = $ARGV[0];
+    if (-f $script && -x $script) {
+        open SCRIPT, "<$script" or die "$0: cannot open ‘$script’: $!\n";
+        my $first = <SCRIPT>;
+        if ($first =~ /^\#\!/) {
+            $inShebang = 1;
+            @ARGV = ();
+            while (<SCRIPT>) {
+                chomp;
+                if (/^\#\!\s*nix-shell (.*)$/) {
+                    @ARGV = split / /, $1;
+                }
+            }
+        }
+        close SCRIPT;
+    }
+}
+
+
 for (my $n = 0; $n < scalar @ARGV; $n++) {
     my $arg = $ARGV[$n];
 
@@ -155,6 +180,18 @@ for (my $n = 0; $n < scalar @ARGV; $n++) {
         $packages = 1;
     }
 
+    elsif ($inShebang && $arg eq "-i") {
+        $n++;
+        die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV;
+        my $interpreter = $ARGV[$n];
+        # Überhack to support Perl. Perl examines the shebang and
+        # executes it unless it contains the string "perl" or "indir",
+        # or (undocumented) argv[0] does not contain "perl". Exploit
+        # the latter by doing "exec -a".
+        my $execArgs = $interpreter =~ /perl/ ? "-a PERL" : "";
+        $envCommand = "exec $execArgs $interpreter $script";
+    }
+
     elsif (substr($arg, 0, 1) eq "-") {
         push @buildArgs, $arg;
     }