require 5.005; # to compile BibTeX.xs (I think)
use strict;
use ExtUtils::MakeMaker;
use File::Basename;
# $Id: Makefile.PL,v 1.17 2000/12/23 03:55:10 greg Exp $
# NB. btparse 0.33 hasn't actually been released as I write this
# (ie. as Text::BibTeX 0.33 is going out the door), but I anticipate
# that it will be -- so this list is ready for it!
my @btparse_versions = qw(0.30 0.31 0.32 0.33);
# Searches the specified @$search_dirs for either release directories or
# archive files of any of the btparse versions listed in @$versions;
# returns the name of whatever it finds (a single string, might be either a
# directory or file name).
sub find_btparse
{
my ($versions, $search_dirs) = @_;
# We'll look for things in reverse order by version, so be sure
# we have a version list sorted that way.
my @versions = sort { $b <=> $a } @$versions;
sub latest_file
{
my @files = @_;
my %mtime = map (($_ => (stat $_)[9]), @files);
return (sort { $mtime{$a} <=> $mtime{$b} } @files)[-1];
}
my ($dir, @archive_files, @release_dirs);
local *DIR;
DIR:
for my $dir (@$search_dirs)
{
opendir (DIR, $dir) || die "Couldn't open $dir: $!\n";
my @all_files = map ("$dir/$_", readdir (DIR));
closedir (DIR);
VERSION:
for my $version (@versions)
{
my $release = "btparse-$version";
@release_dirs = grep (-d && m+/$release$+, @all_files);
@archive_files = grep (-f && m+/$release\.(tar(\.(g?z|Z))|tgz|zip)$+,
@all_files);
last DIR if @release_dirs || @archive_files;
}
}
my $extra_versions = join (", ", @versions[1..$#versions]);
my $wanted_dirs = "btparse-$versions[0]";
$wanted_dirs .= " or $extra_versions" if $extra_versions;
$search_dirs = join (" ", @$search_dirs);
# If no release directories were found, try looking for archive files.
if (@release_dirs == 0)
{
# If no archive files were found, we failed -- crash
if (@archive_files == 0) # found nothing applicable
{
warn <<MSG;
I couldn't find an acceptable version of btparse nearby, either
as a release directory ($wanted_dirs)
or archive file. I'll try to download it from CPAN now.
MSG
return download_btparse (\@versions);
}
# Multiple archive files found -- warn and pick the latest one
# (according to file mtime)
elsif (@archive_files > 1)
{
my $file = latest_file (@archive_files);
warn <<WARN;
Found multiple archive files in @$search_dirs
-- using $file because it\'s the latest
WARN
return $file;
}
# Good, exactly one archive file found -- return it
else
{
return $archive_files[0];
}
}
# Multiple directories found -- warn and pick the latest one
elsif (@release_dirs > 1)
{
my $dir = latest_file (@release_dirs);
warn <<WARN;
Found multiple release directories
-- using $dir because it\'s the latest
WARN
return $dir;
}
# Exactly one directory found -- return it
else
{
return $release_dirs[0];
}
} # find_btparse()
sub download_http
{
my ($trials) = @_;
eval { require LWP::Simple; require HTTP::Status; };
if ($@)
{
die <<MSG . " " . join (" \n", map ($_->[1], @$trials)) . "\n";
I couldn't load the LWP::Simple and HTTP::Status modules, so I can't
download btparse. I would have tried to download it from:
MSG
}
my ($trial, $last_error, @urls_tried);
foreach $trial (@$trials)
{
my ($filename, $url, $save_to) = @$trial;
print "Trying to download btparse from $url...\n";
my $response = LWP::Simple::getstore ($url, $save_to);
if (LWP::Simple::is_success ($response))
{
return $save_to;
}
else
{
$last_error = sprintf ("%d: %s",
$response,
HTTP::Status::status_message ($response));
print "warning: download failed ($last_error), trying another one\n";
push (@urls_tried, $url);
}
}
# only get here if all failed
my $msg = "I tried to download btparse from the following URLs:\n ";
$msg .= join (" \n", @urls_tried);
$msg .= <<MSG;
but they all failed. The last HTTP response was:
$last_error
MSG
die $msg;
}
sub download_ftp
{
my ($trials) = @_;
my ($trial, $last_error, @urls_tried);
foreach $trial (@$trials)
{
my ($filename, $url, $save_to) = @$trial;
my ($host, $dir, $check_filename) =
($url =~ m|^ftp://([^/]+)(/.*)/([^/]+)|);
die "this should not happen: '$filename' ne '$check_filename'\n"
if $filename ne $check_filename;
eval { require Net::FTP; };
if ($@)
{
die <<MSG . " " . join (" \n", map ($_->[1], @$trials)) . "\n";
I couldn't load the Net::FTP module, so I can't download
btparse. I would have tried to download it from:
MSG
}
eval
{
print "Connecting to $host...\n";
my $ftp = Net::FTP->new ($host) or die "$@\n";
$ftp->login or die "login failed\n";
$ftp->binary or die "couldn't set binary mode\n";
$ftp->cwd ($dir) or die "couldn't chdir to $dir\n";
#$ftp->cwd ($cpan_dir) or die "couldn't chdir to $cpan_dir\n";
print "Downloading $dir/$filename...\n";
$ftp->get ($filename, $save_to)
or die "download failed (file not there?)\n";
};
if ($@) # oh dear, we blew up
{
$last_error = $@;
chop $last_error;
print "warning: download failed ($last_error), trying another one\n";
push (@urls_tried, $url);
}
else # success!
{
return $save_to;
}
}
# if we get here, all attempts failed
my $msg = "I tried to download btparse from the following URLs:\n ";
$msg .= join (" \n", @urls_tried);
$msg .= <<MSG;
but they all failed. The last error message was:
$last_error
MSG
die $msg;
} # download_ftp ()
sub download_btparse
{
my ($versions) = @_;
# Try to find a preferred CPAN mirror from the CPAN.pm config.
my $cpan_url;
eval { require CPAN::Config; $cpan_url = $CPAN::Config->{'urllist'}[0]; };
if ($@ || !$cpan_url)
{
$cpan_url = 'http://www.cpan.org/';
print "CPAN module not fully configured -- " .
"using default CPAN site at $cpan_url\n";
}
else
{
$cpan_url .= '/' unless substr($cpan_url,-1,1) eq '/';
print "Using your preferred CPAN mirror at $cpan_url\n";
}
# build list of [base-filename, whole-url, where-to-save-it] lists
my $cpan_dir = 'modules/by-authors/id/GWARD/';
my @download_trials = ();
my ($ver, $archive_file);
foreach $ver (@$versions)
{
$archive_file = "btparse-${ver}.tar.gz";
push (@download_trials, [$archive_file,
$cpan_url . $cpan_dir . $archive_file,
"../$archive_file"]);
}
my $saved_archive;
eval
{
if ($cpan_url =~ /^http:/)
{
$saved_archive = download_http (\@download_trials);
}
elsif ($cpan_url =~ m|^ftp://|)
{
$saved_archive = download_ftp (\@download_trials);
}
else
{
die <<MSG;
I can't download btparse, because I don't know how to deal with the URL
$cpan_url
MSG
}
};
if ($@)
{
die $@ . <<MSG if $@;
You\'ll have to download it yourself and put it in the current
directory or its parent.
MSG
}
if ($saved_archive)
{
print "Successfully downloaded btparse to $saved_archive\n";
return $saved_archive;
}
die "this should not happen: can't get here!\n";
} # download_btparse()
# Takes the directory or filename returned by 'find_btparse()' and
# ensures that it is unpacked and ready to build.
sub unpack_btparse
{
my ($versions, $search_dirs) = @_;
if (-d "btparse")
{
print "btparse already unpacked to 'btparse' -- " .
"no further detective work needed\n";
return;
}
my $btparse_release = find_btparse ($versions, $search_dirs);
print "Found btparse release in $btparse_release\n";
if (-f $btparse_release)
{
$| = 1;
my $cmd;
if ($btparse_release =~ /\.tar\.(g?z|Z)$/)
{ $cmd = "gzip -dc $btparse_release | tar xf -"; }
elsif ($btparse_release =~ /\.tar$/)
{ $cmd = "tar xf $btparse_release"; }
elsif ($btparse_release =~ /\.zip$/)
{ $cmd = "unzip -d $btparse_release"; }
print "Unpacking $btparse_release: $cmd\n";
system $cmd;
die "unpacking failed\n" if $?;
# strip off directory and extension(s) -- this should just give
# us the name of the directory we just unpacked to
$btparse_release = fileparse ($btparse_release, '\.tar.*', '\.zip');
if (! -d $btparse_release)
{
die <<ERR
Directory "$btparse_release" doesn't exist, but it should have
been created when we unpacked the archive file.
ERR
}
}
print "Creating symlink: btparse -> $btparse_release\n";
symlink ($btparse_release, "btparse")
|| die "symlink failed: $!\n";
} # unpack_btparse ()
sub configure_btparse
{
my ($dir) = @_;
chdir $dir or die "couldn't chdir to $dir: $!\n";
unless (-f "config.status" && -f "config.cache" &&
-M "config.status" < -M "configure" &&
-M "config.cache" < -M "configure")
{
print "btparse distribution in '$dir' is not configured; doing so now:\n";
my @cmd = ('sh', './configure');
print "@cmd\n";
system @cmd;
die "configure failed\n" unless $? == 0;
}
chdir ".." or die "couldn't chdir to ..: $!\n";
print "btparse distribution in '$dir' is configured and ready to build\n";
}
# -- BEGIN main --------------------------------------------------------
# This stuff is arranged so that I do not need to keep a complete copy of
# the btparse distribution around for the development copy of Text::BibTeX,
# but can still have Makefile.PL take care of unpacking btparse for
# building anywhere else.
unpack_btparse (\@btparse_versions, ['.', '..']);
my @support_files = ('btxs_support$(OBJ_EXT)');
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile (
'NAME' => 'Text::BibTeX',
'VERSION' => '0.34',
'XSPROTOARG' => '-prototypes',
'LIBS' => [''], # e.g., '-lm'
'DEFINE' => '', # e.g., '-DHAVE_SOMETHING'
'INC' => '-Ibtparse/src',
'MYEXTLIB' => 'btparse/libbtparse$(LIB_EXT)',
'OBJECT' => 'BibTeX$(OBJ_EXT) ' . join (' ', @support_files),
'dynamic_lib' => { INST_DYNAMIC_DEP => join (' ', @support_files) },
'dist' => { COMPRESS => "gzip", SUFFIX => "gz" }
);
configure_btparse ('btparse');
# -- END main ----------------------------------------------------------
# -- Overrides ---------------------------------------------------------
package MY;
sub dist
{
local $_ = shift->SUPER::dist;
s/CI \s* = \s* .*/CI = true/mx;
s/-Nv/-sRel -N\$(NAME_SYM)_v/m;
return $_;
}
sub postamble
{
'
$(MYEXTLIB):
cd btparse && $(MAKE)
';
}
sub manifypods
{
local $_ = shift->SUPER::manifypods (@_);
s/Text::btool_faq/btool_faq/;
return $_;
}