use ExtUtils::MakeMaker; use strict; use File::Copy; use File::Find; my ($perlmacs_ver, $emacs_ver, $emacs_src, $emacs_tar_gz, @configure_opts); my $aborted = "\n### $0 aborted\n"; my $gzip_size_at_least = 14_000_000; my ($pure_emacs_src); # unpatched tree for making diffs $| = 1; # for when we ask questions check_perl_ver (5.005); find_perlmacs_ver (); # finds perlmacs and emacs version #s in version.el for my $i (0 .. $#ARGV) { if ($ARGV[$i] =~ /^-*h/) { die "\nUsage: perl Makefile.PL [EMACS_SRC=dir/emacs-$emacs_ver\[.tar.gz]] [MakeMaker-opts] [-- configure-opts]\n"; } if ($ARGV[$i] =~ /^EMACS_SRC=(.+)/) { ($1 =~ /\.tar\.gz$/ ? $emacs_tar_gz : $emacs_src) = $1; splice @ARGV, $i, 1; } if ($ARGV[$i] =~ /^PURE_EMACS_SRC=(.+)/) { $pure_emacs_src = $1; splice @ARGV, $i, 1; } next unless $ARGV[$i] eq '--'; @configure_opts = splice @ARGV, $i; shift @configure_opts; for (@configure_opts) { s|\$|\$\$|g; if (s|'|'\\''|g) { $_ = "'$_'" } } last; } grep { /^--p/ } @configure_opts or push @configure_opts, '--prefix=$(PREFIX)'; find_emacs_src () unless defined $emacs_src; unpack_emacs_src () if defined $emacs_tar_gz; prep_emacs_src (); WriteMakefile ( VERSION => $perlmacs_ver, NAME => 'Emacs::PerlmacsPatch', dist => { DIST_DEFAULT => 'emacs-perlmacs.diff tardist' }, ); # Makefile must depend on version.el, but MakeMaker makes no provision # for this, as far as I can tell. # So bludgeon it into shape. rename ("Makefile", "Makefile.tmp") or exit; open MFT, "Makefile.tmp" or die $!; open MF, ">Makefile" or die $!; while () { s|^CONFIGDEP =|CONFIGDEP = perlmacs/lisp/version.el|; print MF or die $!; } unlink "Makefile.tmp"; exit; sub MY::post_initialize { return "PURE_EMACS_SRC = " .($pure_emacs_src || "/src/emacs-$emacs_ver")."\n"; } sub MY::top_targets { return < \$\@.tmp || test \$\$? = 1 mv -f \$\@.tmp \$\@ clean :: -cd $emacs_src/build && \$(MAKE) clean \$(RM_F) perlmacs-* emacs-perlmacs.diff.tmp distclean :: \$(RM_RF) $emacs_src/build END } sub check_perl_ver { my ($wanted) = @_; return if $] >= $wanted; die <; return ($p, $e); } sub find_perlmacs_ver { my $verfile = "perlmacs/lisp/version.el"; print "Finding Perlmacs version..."; ($perlmacs_ver, $emacs_ver) = analyze_version_file ($verfile); defined ($perlmacs_ver) or die "\nCan't deduce Perlmacs version from contents of $verfile.\n$aborted"; defined ($emacs_ver) or die "\nCan't deduce required Emacs version from contents of $verfile.\n$aborted"; print "$perlmacs_ver\n"; } sub find_emacs_src { my $gzipname = "emacs-$emacs_ver.tar.gz"; my $dirname = "emacs-$emacs_ver"; my $maybe_dir = ""; my $def_url = "ftp://metalab.unc.edu/pub/gnu/emacs/$gzipname"; my ($ans, $ua, $url, $request, $response); if (-f "perlmacs/ChangeLog") { $emacs_src = "perlmacs"; return; } $emacs_src = $dirname; return if defined $emacs_tar_gz || -e $emacs_src; # prefer gzipped since it avoids asking the user whether to patch # the found tree. foreach (qw(. .. ../.. ../../..)) { next unless -f "$_/$gzipname" && -s "$_/$gzipname" >= $gzip_size_at_least; ($emacs_tar_gz = "$_/$gzipname") =~ s:^\./::; return; } foreach (qw(.. ../.. ../../..)) { next unless -d "$_/$dirname"; $maybe_dir = "$_/$dirname"; last; } print "\nWhere should I find the Emacs $emacs_ver source tree to patch?\n"; print "Specify a tar.gz file, a directory, `net' to download now,\n"; print "or `q' to give up.\n\n"; while (1) { print "Emacs source location? [$maybe_dir] "; $ans = ; chomp $ans; if ($ans eq '') { next if $maybe_dir eq ''; $emacs_src = $maybe_dir; return; } die $aborted if ("quit" =~ /^$ans/); if ($ans =~ /\.gz$/) { if (-f $ans) { $emacs_tar_gz = $ans; return; } print "That is not a file. Did you mistype the name?\n"; next; } last if $ans eq 'net'; if (-d $ans) { $emacs_src = $ans; return; } print "\nPlease enter a filename ending in .gz or a directory name.\n"; } # here they have asked for a download. print "\nNOTE: $gzipname is over " .int($gzip_size_at_least/1_000_000)." megabytes.\n"; print "Do you really want me to try to download it? [y] "; die $aborted unless =~ /^($|[yY])/; require LWP::UserAgent; require URI; require URI::Heuristic; $ua = new LWP::UserAgent; $request = HTTP::Request->new ('GET'); while (1) { print "Download $gzipname from where? [$def_url] "; $ans = ; chomp $ans; $ans = $def_url if $ans eq ''; die $aborted if ("quit" =~ /^$ans/); if (! $ans =~ /$gzipname$/) { $ans =~ s:/$::; $ans .= "/$gzipname"; } # snarfed from lwp-request if ($ans =~ /^\w+:/) { # is there any scheme specification $url = URI->new($ans); } else { $url = URI::Heuristic::uf_uri($ans); } $request->url($url); print "Attempting to fetch $ans\n(this will take a while)..."; $response = $ua->request($request, $gzipname); if ($response->is_success && -s $gzipname >= $gzip_size_at_least) { print "success!!\n"; $emacs_tar_gz = $gzipname; return; } $def_url = 'q' if $ans eq $def_url; print "failed.\nType `q' if you want to give up.\n"; } } sub unpack_emacs_src { print "Unpacking $emacs_tar_gz..."; system ("gzip -dc $emacs_tar_gz |tar xf -") and die $aborted; print "done\n"; } sub prep_emacs_src { -d $emacs_src or die "\n$emacs_src is not a directory.\n$aborted"; print "Using source in $emacs_src.\n"; my $verfile = "$emacs_src/lisp/version.el"; my ($p, $e) = analyze_version_file ($verfile); defined ($e) or die "\nCan't find Emacs version number in $verfile.\n$aborted"; $e eq $emacs_ver or die <