#!/usr/bin/env 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= specify the name of Makefile explicitly\n"; print " --prefix= specify the prefix instead of scanning Makefile\n"; print " --target= 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 { if ($opt_force) { print "stowinstall: $opt_target target not found, but proceeding anyway...\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-$$");