#!/usr/bin/perl -w use strict; use File::Spec; use Getopt::Long; ############################################################################# # SETTINGS # my %config = ( thirdParty => "$ENV{WM_PROJECT_INST_DIR}/ThirdParty", project => ( $ENV{WM_PROJECT} || '' ) . "-" . ( $ENV{WM_PROJECT_VERSION} || '' ), ); my %packages = ( cmake => { -opt => 1, url => "http://www.cmake.org/files/v2.6/cmake-2.6.0.tar.gz", }, lam => { -opt => 1, url => "http://www.lam-mpi.org/download/files/lam-7.1.4.tar.bz2", }, libccmio => { -opt => 1, url => "https://wci.llnl.gov/codes/visit/3rd_party/libccmio-2.6.1.tar.gz", }, openmpi => { url => "http://www.open-mpi.org/software/ompi/v1.2/downloads/openmpi-1.2.6.tar.bz2", }, metis => { url => "http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.0pre2.tar.gz" }, mico => { -opt => 1, url => "http://www.mico.org/mico-2.3.12.tar.gz", }, mpich => { -opt => 1, url => "ftp://ftp.mcs.anl.gov/pub/mpi/old/mpich-1.2.4.tar.gz", }, ParMetis => { url => "http://glaros.dtc.umn.edu/gkhome/fetch/sw/parmetis/ParMetis-3.1.tar.gz", }, ParMGridGen => { url => "http://www-users.cs.umn.edu/~moulitsa/download/ParMGridGen-1.0.tar.gz", }, zlib => { url => "http://www.zlib.net/zlib-1.2.3.tar.gz", }, hoard => { -opt => 1, url => "http://www.cs.umass.edu/%7Eemery/hoard/hoard-3.7.1/hoard-371.tar.gz" }, ## # this really doesn't work well, but code needs minor patching anyhow: ## fbsdmalloc => { ## url => ## "http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/src/lib/libc/stdlib/malloc.c?rev=1.171", ## ## }, ); # # END OF SETTINGS ############################################################################ ( my $Script = $0 ) =~ s{^.*/}{}; # -------------------------------------------------------------------------- sub usage { my ( @req, @opt ); for ( sort keys %packages ) { if ( $packages{$_}{-opt} ) { push @opt, $_; } else { push @req, $_; } } $! = 0; # clean exit warn "@_\n" if @_; die <<"USAGE"; usage: $Script [OPTION] [package1 .. packageN] options: -help usage -status show status [default] -list list versions and resource locations -version list versions only -dir list unpack directory -reldir list unpack directory relative to cwd -get get packages as required (uses curl) -unpack unpack packages where required and possible Simple management of 3rd party software for '$config{project}' using the directory $config{thirdParty} Packages: @req Optional: @opt Return codes: -status -get -unpack number of missing packages or errors USAGE } # -------------------------------------------------------------------------- my %opt; # default action is -status @ARGV or $opt{status}++; GetOptions( \%opt, ## "help", "status", "list", "version", "dir", "reldir", "get", "unpack", ) or usage; $opt{help} and usage; -d $config{thirdParty} or usage "ERROR: no '$config{thirdParty}' dir"; # # complete the config # if ( not exists $config{sources} ) { $config{sources} = "$config{thirdParty}/sources"; -d $config{sources} or mkdir $config{sources}; } # # cleanup the packages table # for my $name ( keys %packages ) { my $href = $packages{$name}; if ( not $href->{url} ) { warn "$name without url\n"; delete $packages{$name}; next; } if ( not exists $href->{file} ) { ( $href->{file} = $href->{url} ) =~ s{^.*/|\?.*$}{}g; } if ( not exists $href->{dir} ) { ( $href->{dir} = $href->{file} ) =~ s{\.(zip|tar(\.(gz|bz2))?)$}{}; } } # # check for names in the packages # sub selectNames { my @names; my $req; while ( @_ and $_[0] =~ /^-/ ) { my $opt = shift; if ( $opt =~ /^-req/ ) { $req++; } } if (@_) { my ( %seen, @reject ); for my $name (@_) { next if $seen{$name}++; if ( exists $packages{$name} ) { push @names, $name; } else { push @reject, $name; } } usage "unknown package(s): @reject" if @reject; } else { @names = grep { not $req or not $packages{$_}{-opt} } sort keys %packages; } @names or usage "no packages"; return @names; } # # list the current status # if ( $opt{status} ) { my @names = selectNames @ARGV; my $nMissing = 0; for my $name (@names) { my $href = $packages{$name}; my ( $dir, $file, $url ) = @$href{qw( dir file url )}; my @status; if ( -e "$config{sources}/$file" ) { push @status, " packed: $config{sources}/$file"; } if ( -d "$config{thirdParty}/$dir" ) { push @status, "unpacked: $config{thirdParty}/$dir"; } unless (@status) { $nMissing++; @status = "missing"; } for (@status) { printf "%-16s %-16s %s", $name, $dir, $_; if ( $href->{-opt} ) { print " [optional]"; } print "\n"; } } exit $nMissing; } # # show an overview of the versions and the resource locations # if ( $opt{list} ) { my @names = selectNames @ARGV; for my $name (@names) { my $href = $packages{$name}; my ( $dir, $file, $url ) = @$href{qw( dir file url )}; printf "%-16s %-16s %s", $name, $dir, $url; if ( $href->{-opt} ) { print " [optional]"; } print "\n"; } exit 0; } # # show the version (directory name) only # if ( $opt{version} ) { my @names = selectNames @ARGV; for my $name (@names) { my $href = $packages{$name}; my ( $dir, $file, $url ) = @$href{qw( dir file url )}; print $dir, "\n"; } exit 0; } # # show the unpack directory name # if ( $opt{dir} or $opt{reldir} ) { my @names = selectNames @ARGV; my $base = $config{thirdParty}; if ( $opt{reldir} ) { $base = File::Spec->abs2rel($base); length $base or $base = '.'; } for my $name (@names) { my $href = $packages{$name}; my ( $dir, $file, $url ) = @$href{qw( dir file url )}; print File::Spec->catfile( $base, $dir ), "\n"; } exit 0; } # # get and/or unpack packages as required and possible # avoid getting/unpacking optional packages # if ( $opt{get} or $opt{unpack} ) { my @names = selectNames -required => @ARGV; my $nError = 0; for my $name (@names) { my $href = $packages{$name}; my ( $dir, $file, $url ) = @$href{qw( dir file url )}; my $flags = ""; if ( $href->{-opt} ) { $flags .= "[optional]"; } warn '-' x 70, "\n", "$name ($dir) $flags\n"; if ( -d "$config{thirdParty}/$dir" ) { warn "unpacked: $config{thirdParty}/$dir\n"; next; } if ( $opt{get} ) { if ( -e "$config{sources}/$file" ) { warn " packed: $config{sources}/$file\n"; } else { my $fetch = "curl -k -o $file"; # curl seems to hang on anonymous ftp? if ( $url =~ /^ftp:/ ) { $fetch = "wget -v"; } system "set -x; cd $config{sources} && $fetch $url"; if ( not -e "$config{sources}/$file" ) { $nError++; warn " download failed!?\n"; next; } } } if ( $opt{unpack} ) { if ( -e "$config{sources}/$file" ) { my $unpack; if ( $file =~ m{\.zip$} ) { $unpack = "unzip"; } elsif ( $file =~ m{\.tar$} ) { $unpack = "tar -xf"; } elsif ( $file =~ m{\.tar\.bz2$} ) { $unpack = "tar -xjf"; } elsif ( $file =~ m{\.(tgz|tar\.gz)$} ) { $unpack = "tar -xzf"; } else { $nError++; warn " no unpack defined for $file\n"; next; } system "set -x; cd $config{thirdParty} && $unpack $config{sources}/$file"; # catch isolated cases where it unpacks without a version number if ( -d "$config{thirdParty}/$name" and not -d "$config{thirdParty}/$dir" ) { rename "$config{thirdParty}/$name", "$config{thirdParty}/$dir"; } unless ( -d "$config{thirdParty}/$dir" ) { $nError++; warn "unpack failed!?\n"; next; } } } } warn '-' x 70, "\n\n"; exit $nError; } # --------------------------------------------------------------------------