+#!/usr/bin/perl
+# -*- cperl -*-
+use strict;
+use warnings;
+use File::Spec;
+
+if (!@ARGV) {
+ print "This is stowinstall,\n";
+ print " does `make install DESTDIR=...' for the GNU stow.\n";
+ print "\n";
+ print " Usage: stowinstall [-f] [stow-dir]\n";
+ print " (e.g. stowinstall /usr/local/stow/emacs)\n";
+ print "\n";
+ print " Options:\n";
+ print " -f --force force install even if the Makefile\n";
+ print " doesn't have any \$(DESTDIR)\n";
+ print " --file=<file> specify the name of Makefile explicitly\n";
+ print " --prefix=<dir> specify the prefix instead of scanning Makefile\n";
+ print " --target=<targ> specify the target instead of `install'\n";
+ print "\n";
+ print "stowinstall can only install packages whose Makefile corresponds:\n";
+ print " * file name is exactly `Makefile'\n";
+ print " * the Makefile has target `install'\n";
+ print " * the Makefile has `prefix = ...' form\n";
+ print " * the Makefile has at least one `\$(DESTDIR)' form\n";
+ print "autotools is our friend; it generates such Makefile:s.\n";
+}
+
+my $stowdir;
+my $opt_force;
+my $opt_prefix;
+my $opt_file = 'Makefile';
+my $opt_target = 'install';
+foreach (@ARGV) {
+ if (/^-f$/ or /^--force$/) {
+ $opt_force = 1;
+ }
+ elsif (/^--prefix=(.+)$/) {
+ $opt_prefix = $1;
+ }
+ elsif (/^--file=(.+)$/) {
+ $opt_file = $1;
+ }
+ elsif (/^--target=(.+)$/) {
+ $opt_target = $1;
+ }
+ else {
+ $stowdir = $_;
+ }
+}
+
+if (-r $opt_file) {
+ print "stowinstall: $opt_file exists.\n";
+}
+else {
+ die "stowinstall: $opt_file doesn't exist.\n";
+}
+
+my $makefile = do {
+ local $/ = undef;
+ open my $fh, '<', $opt_file;
+ <$fh>;
+};
+
+my ($prefix, $destdir, $target_install);
+$prefix = $opt_prefix;
+do {
+ foreach my $line (split /\r?\n/, $makefile) {
+ if (!$prefix and
+ $line =~ /^prefix\s*=\s*(.+?)\s*$/) {
+ $prefix = $1;
+ if ($prefix =~ /^(["'])(.+?)\1$/) {
+ $prefix = $2;
+ }
+ }
+ elsif ($line =~ /\$\(DESTDIR\)/) {
+ $destdir = 1;
+ }
+ elsif ($line =~ /^\Q$opt_target\E\s*:/) {
+ $target_install = 1;
+ }
+ }
+};
+
+if ($prefix) {
+ print "stowinstall: found prefix $prefix\n";
+}
+else {
+ die "stowinstall: prefix not found...\n";
+}
+
+if ($destdir) {
+ print "stowinstall: found \$(DESTDIR).\n";
+}
+else {
+ if ($opt_force) {
+ print "stowinstall: \$(DESTDIR) not found; doing force install. THIS IS DANGEROUS.\n";
+ }
+ else {
+ die "stowinstall: \$(DESTDIR) not found; this $opt_file seems not to support DESTDIR.\n";
+ }
+}
+
+if ($target_install) {
+ print "stowinstall: found target $opt_target.\n";
+}
+else {
+ die "stowinstall: $opt_target target not found; this $opt_file seems not to support $opt_target!\n";
+}
+
+if (!-d $stowdir) {
+ mkdir $stowdir or
+ die "stowinstall: failed to mkdir $stowdir\n";
+}
+
+my @destdir = File::Spec->splitdir(
+ File::Spec->canonpath("/tmp/stowinstall-$$/".$prefix));
+my $linkname = pop @destdir;
+
+my $path = '';
+foreach (@destdir) {
+ $path .= '/'.$_;
+ if (!-d $path) {
+ mkdir $path or
+ die "stowinstall: failed to mkdir $path\n";
+ }
+}
+
+my $linktarget = File::Spec->catdir(@destdir, $linkname);
+symlink $stowdir => $linktarget or
+ die "stowinstall: failed to symlink $stowdir => $linktarget\n";
+
+system("make $opt_target DESTDIR=/tmp/stowinstall-$$");
+system("rm -rf /tmp/stowinstall-$$");