1
1
openmpi/autogen.pl

1129 строки
35 KiB
Prolog
Исполняемый файл

#!/usr/bin/env perl
#
# Copyright (c) 2009-2010 Cisco Systems, Inc. All rights reserved.
#
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
use strict;
use Cwd;
use File::Basename;
use File::Find;
use Data::Dumper;
use Getopt::Long;
#
# Global variables
#
# The m4 file we'll write at the end
my $m4_output_file = "config/autogen_found_items.m4";
my $m4;
# Sanity check file
my $topdir_file = "opal/include/opal_config_bottom.h";
my $dnl_line = "dnl ---------------------------------------------------------------------------";
# Data structures to fill up with all the stuff we find
my $mca_found;
my $mpiext_found;
my $mpicontrib_found;
my @subdirs;
# Command line parameters
my $no_ompi_arg = 0;
my $no_orte_arg = 0;
my $quiet_arg = 0;
my $debug_arg = 0;
my $help_arg = 0;
my $platform_arg = 0;
my $include_arg = 0;
my $exclude_arg = 0;
# Include/exclude lists
my $include_list;
my $exclude_list;
# Minimum versions
my $ompi_automake_version = "1.11.1";
my $ompi_autoconf_version = "2.65";
my $ompi_libtool_version = "2.2.6b";
# Search paths
my $ompi_autoconf_search = "autoconf";
my $ompi_automake_search = "automake";
my $ompi_libtoolize_search = "libtoolize;glibtoolize";
# One-time setup
my $username;
my $hostname;
my $full_hostname;
$username = getpwuid($>);
$full_hostname = `hostname`;
chomp($full_hostname);
$hostname = $full_hostname;
$hostname =~ s/^([\w\-]+)\..+/\1/;
##############################################################################
sub verbose {
print @_
if (!$quiet_arg);
}
sub debug {
print @_
if ($debug_arg);
}
sub debug_dump {
my $d = new Data::Dumper([@_]);
$d->Purity(1)->Indent(1);
debug $d->Dump;
}
##############################################################################
sub read_config_params {
my ($filename, $dir_prefix) = @_;
my $dir = dirname($filename);
open(FILE, $filename) ||
die "Can't open $filename";
my $file;
$file .= $_
while(<FILE>);
close(FILE);
# Save all lines of the form "foo = bar" in a hash
my $ret;
while ($file =~ s/^\s*(\w+)\s*=\s*(.+)\s*$//m) {
my $key = $1;
my $val = $2;
# Strip off any leading and trailing "'s
$val = $1
if ($val =~ m/^\"(.+)\"$/);
$ret->{$key} = $val;
}
# Split PARAM_CONFIG_FILES into an array
if (exists($ret->{PARAM_CONFIG_FILES})) {
my @out;
foreach my $f (split(/\s+/, $ret->{PARAM_CONFIG_FILES})) {
push(@out, "$dir_prefix/$f");
}
$ret->{PARAM_CONFIG_FILES} = \@out;
}
debug_dump($ret);
return $ret;
}
##############################################################################
# Process a "subdir", meaning that the directory isn't a component or
# an extension; it probably just needs an autoreconf, autogen, etc.
sub process_subdir {
my ($dir) = @_;
# Chdir to the subdir
print "\n=== Processing subdir: $dir\n";
my $start = cwd();
chdir($dir);
# Run an action depending on what we find in that subdir
if (-x "autogen.pl") {
print "--- Found autogen.pl; running...\n";
safe_system("./autogen.pl");
} elsif (-x "autogen.sh") {
print "--- Found autogen.sh; running...\n";
safe_system("./autogen.sh");
} elsif (-f "configure.in" || -f "configure.ac") {
print "--- Found configure.in|ac; running autoreconf...\n";
safe_system("autoreconf -ivf");
} else {
die "Found subdir, but no autogen.sh or configure.in|ac to do anything";
}
# Ensure that we got a good configure executable.
die "Did not generate a \"configure\" executable in $dir.\n"
if (! -x "configure");
# Chdir back to where we came from
chdir($start);
}
##############################################################################
sub process_autogen_subdirs {
my ($dir) = @_;
my $file = "$dir/autogen.subdirs";
if (-f $file) {
open(FILE, $file) || die "Can't open $file";
while (<FILE>) {
chomp;
$_ =~ s/#.*$//;
$_ =~ s/^\s*//;
$_ =~ s/\s*$//;
if ($_ ne "") {
print " Found subdir: $_ (will process later)\n";
# Note: there's no real technical reason to defer
# processing the subdirs. It's more of an aesthetic
# reason -- don't interrupt the current flow of
# finding mca / ext / contribs (which is a nice, fast
# process). Then process the subdirs (which is a slow
# process) all at once.
push(@subdirs, "$dir/$_");
}
}
close(FILE);
}
}
##############################################################################
sub mca_process_component {
my ($topdir, $project, $framework, $component) = @_;
my $pname = $project->{name};
my $pdir = $project->{dir};
my $cdir = "$topdir/$pdir/mca/$framework/$component";
return
if (! -d $cdir);
# Process this directory (pretty much the same treatment as for
# mpiext, so it's in a sub).
my $found_component;
# Does this directory have a configure.m4 file?
if (-f "$cdir/configure.m4") {
$found_component->{"configure.m4"} = 1;
verbose " Found configure.m4 file\n";
}
$found_component->{"name"} = $component;
# Push the results onto the $mca_found hash array
push(@{$mca_found->{$pname}->{$framework}->{"components"}},
$found_component);
# Is there an autogen.subdirs in here?
process_autogen_subdirs($cdir);
}
##############################################################################
sub ignored {
my ($dir) = @_;
# If this directory does not have .ompi_ignore, or if it has a
# .ompi_unignore that has my username in it, then add it to the
# list of components.
my $ignored = 0;
if (-f "$dir/.ompi_ignore") {
$ignored = 1;
}
if (-f "$dir/.ompi_unignore") {
open(UNIGNORE, "$dir/.ompi_unignore") ||
die "Can't open $dir/.ompi_unignore file";
my $unignore;
$unignore .= $_
while (<UNIGNORE>);
close(UNIGNORE);
$ignored = 0
if ($unignore =~ /^$username$/ ||
$unignore =~ /^$username\@$hostname$/ ||
$unignore =~ /^$username\@$full_hostname$/);
}
return $ignored;
}
##############################################################################
sub mca_process_framework {
my ($topdir, $project, $framework) = @_;
my $pname = $project->{name};
my $pdir = $project->{dir};
# Does this framework have a configure.m4 file?
my $dir = "$topdir/$pdir/mca/$framework";
if (-f "$dir/configure.m4") {
$mca_found->{$pname}->{$framework}->{"configure.m4"} = 1;
verbose " Found framework configure.m4 file\n";
}
# Did we exclude all components for this framework?
if (exists($exclude_list->{$framework}) &&
$exclude_list->{$framework}[0] eq "AGEN_EXCLUDE_ALL") {
verbose " => Excluded\n";
} else {
# Look for component directories in this framework
if (-d $dir) {
$mca_found->{$pname}->{$framework}->{found} = 1;
opendir(DIR, $dir) ||
die "Can't open $dir directory";
foreach my $d (readdir(DIR)) {
# Skip any non-directory, "base", or any dir that
# begins with "."
next
if (! -d "$dir/$d" || $d eq "base" ||
substr($d, 0, 1) eq ".");
# Skip any component that doesn't have a configure.m4
# or Makefile.am as we couldn't build it anyway
if (! -f "$dir/$d/configure.m4" &&
! -f "$dir/$d/Makefile.am" &&
! -f "$dir/$d/configure.ac" &&
! -f "$dir/$d/configure.in") {
verbose " => No sentinel file found in $dir/$d -> Excluded\n";
next;
}
verbose "--- Found $pname / $framework / $d component\n";
# Skip if specifically excluded
if (exists($exclude_list->{$framework}) &&
$exclude_list->{$framework}[0] eq $d) {
verbose " => Excluded\n";
next;
}
# Skip if the framework is on the include list, but
# doesn't contain this component
if (exists($include_list->{$framework})) {
my $tst = 0;
foreach my $ck (@{$include_list->{$framework}}) {
if ($ck ne $d) {
verbose " => Not included\n";
$tst = 1;
last;
}
}
if ($tst) {
next;
}
}
# Check ignore status
if (ignored("$dir/$d")) {
verbose " => Ignored (found .ompi_ignore file)\n";
} else {
mca_process_component($topdir, $project, $framework, $d);
}
}
}
closedir(DIR);
}
}
##############################################################################
sub mca_process_project {
my ($topdir, $project) = @_;
my $pname = $project->{name};
my $pdir = $project->{dir};
# Does this project have a configure.m4 file?
if (-f "$topdir/$pdir/configure.m4") {
$mca_found->{$pname}->{"configure.m4"} = 1;
verbose " Found $topdir/$pdir/configure.m4 file\n";
}
# Look for framework directories in this project
my $dir = "$topdir/$pdir/mca";
if (-d $dir) {
opendir(DIR, $dir) ||
die "Can't open $dir directory";
my @my_dirs = readdir(DIR);
@my_dirs = sort(@my_dirs);
foreach my $d (@my_dirs) {
# Skip any non-directory, "base", or any dir that begins with "."
next
if (! -d "$dir/$d" || $d eq "base" || substr($d, 0, 1) eq ".");
# If this directory has a $dir.h file and a base/
# subdirectory, or its name is "common", then it's a
# framework.
if ("common" eq $d || !$project->{need_base} ||
(-f "$dir/$d/$d.h" && -d "$dir/$d/base")) {
verbose "\n=== Found $pname / $d framework\n";
mca_process_framework($topdir, $project, $d);
}
}
closedir(DIR);
}
}
##############################################################################
sub mca_run_global {
my ($projects) = @_;
# For each project, go find a list of frameworks, and for each of
# those, go find a list of components.
my $topdir = Cwd::cwd();
foreach my $p (@$projects) {
if (-d "$topdir/$p->{dir}") {
verbose "\n*** Found $p->{name} project\n";
mca_process_project($topdir, $p);
}
}
# Debugging output
debug_dump($mca_found);
#-----------------------------------------------------------------------
$m4 .= "\n$dnl_line
$dnl_line
$dnl_line
dnl MCA information\n";
# Array for all the m4_includes that we'll need to pick up the
# configure.m4's.
my @includes;
# Next, for each project, write the list of frameworks
foreach my $p (@$projects) {
my $pname = $p->{name};
my $pdir = $p->{dir};
if (exists($mca_found->{$pname})) {
my $frameworks_comma;
# Does this project have a configure.m4 file?
push(@includes, "$pdir/configure.m4")
if (exists($mca_found->{$p}->{"configure.m4"}));
# Print out project-level info
my @mykeys = keys(%{$mca_found->{$pname}});
@mykeys = sort(@mykeys);
foreach my $f (@mykeys) {
$frameworks_comma .= ", $f";
# Does this framework have a configure.m4 file?
push(@includes, "$pdir/mca/$f/configure.m4")
if (exists($mca_found->{$pname}->{$f}->{"configure.m4"}));
# This framework does have a Makefile.am (or at least,
# it should!)
die "Missing $pdir/mca/$f/Makefile.am"
if (! -f "$pdir/mca/$f/Makefile.am");
}
$frameworks_comma =~ s/^, //;
$m4 .= "$dnl_line
dnl Frameworks in the $pname project and their corresponding directories
m4_define([mca_${pname}_framework_list], [$frameworks_comma])
";
# Print out framework-level info
foreach my $f (@mykeys) {
my $components;
my $m4_config_component_list;
my $no_config_component_list;
# Troll through each of the found components
foreach my $comp (@{$mca_found->{$pname}->{$f}->{components}}) {
my $c = $comp->{name};
$components .= "$c ";
# Does this component have a configure.m4 file?
if (exists($comp->{"configure.m4"})) {
push(@includes, "$pdir/mca/$f/$c/configure.m4");
$m4_config_component_list .= ", $c";
} else {
$no_config_component_list .= ", $c";
}
}
$m4_config_component_list =~ s/^, //;
$no_config_component_list =~ s/^, //;
$m4 .= "dnl Components in the $pname / $f framework
m4_define([mca_${pname}_${f}_m4_config_component_list], [$m4_config_component_list])
m4_define([mca_${pname}_${f}_no_config_component_list], [$no_config_component_list])
";
}
}
}
# List out all the m4_include
$m4 .= "$dnl_line
dnl List of configure.m4 files to include\n";
foreach my $i (@includes) {
$m4 .= "m4_include([$i])\n";
}
}
##############################################################################
sub mpiext_process_extension {
my ($topdir, $ext_prefix, $extdir) = @_;
my $edir = "$topdir/$ext_prefix/$extdir";
return
if (! -d $edir);
# Process this directory (pretty much the same treatment as for
# MCA components, so it's in a sub).
my $found_ext;
$found_ext->{"name"} = $extdir;
# Push the results onto the hash array
push(@{$mpiext_found}, $found_ext);
# Is there an autogen.subdirs in here?
process_autogen_subdirs($edir);
}
##############################################################################
sub mpiext_run_global {
my ($ext_prefix) = @_;
my $topdir = Cwd::cwd();
my $dir = "$topdir/$ext_prefix";
opendir(DIR, $dir) ||
die "Can't open $dir directory";
foreach my $d (readdir(DIR)) {
# Skip any non-directory, "base", or any dir that begins with "."
next
if (! -d "$dir/$d" || $d eq "base" || substr($d, 0, 1) eq ".");
# If this directory has a configure.m4, then it's an
# extension.
if (-f "$dir/$d/configure.m4") {
verbose "=== Found $d MPI extension";
# Check ignore status
if (ignored("$dir/$d")) {
verbose " (ignored)\n";
} else {
verbose "\n";
mpiext_process_extension($topdir, $ext_prefix, $d);
}
}
}
closedir(DIR);
debug_dump($mpiext_found);
#-----------------------------------------------------------------------
$m4 .= "\n$dnl_line
$dnl_line
$dnl_line
dnl Open MPI extensions information
$dnl_line\n\n";
# Array for all the m4_includes that we'll need to pick up the
# configure.m4's.
my @includes;
my $m4_config_ext_list;
# Troll through each of the found exts
foreach my $ext (@{$mpiext_found}) {
my $e = $ext->{name};
push(@includes, "$ext_prefix/$e/configure.m4");
$m4_config_ext_list .= ", $e";
}
$m4_config_ext_list =~ s/^, //;
# List the M4 and no configure exts
$m4 .= "dnl List of all MPI extensions
m4_define([ompi_mpiext_list], [$m4_config_ext_list])\n";
# List out all the m4_include
$m4 .= "\ndnl List of configure.m4 files to include\n";
foreach my $i (@includes) {
$m4 .= "m4_include([$i])\n";
}
}
##############################################################################
sub mpicontrib_process {
my ($topdir, $contrib_prefix, $contribdir) = @_;
my $cdir = "$topdir/$contrib_prefix/$contribdir";
return
if (! -d $cdir);
# Process this directory (pretty much the same treatment as for
# MCA components, so it's in a sub).
my $found_contrib;
$found_contrib->{"name"} = $contribdir;
# Push the results onto the hash array
push(@{$mpicontrib_found}, $found_contrib);
# Is there an autogen.subdirs in here?
process_autogen_subdirs($cdir);
}
##############################################################################
sub mpicontrib_run_global {
my ($contrib_prefix) = @_;
my $topdir = Cwd::cwd();
my $dir = "$topdir/$contrib_prefix";
opendir(DIR, $dir) ||
die "Can't open $dir directory";
foreach my $d (readdir(DIR)) {
# Skip any non-directory, "base", or any dir that begins with "."
next
if (! -d "$dir/$d" || $d eq "base" || substr($d, 0, 1) eq ".");
# If this directory has a configure.m4, then it's an
# extension.
if (-f "$dir/$d/configure.m4") {
verbose "=== Found $d MPI contrib";
# Check ignore status
if (ignored("$dir/$d")) {
verbose " (ignored)\n";
} else {
verbose "\n";
mpicontrib_process($topdir, $contrib_prefix, $d);
}
}
}
closedir(DIR);
debug_dump($mpiext_found);
#-----------------------------------------------------------------------
$m4 .= "\n$dnl_line
$dnl_line
$dnl_line
dnl Open MPI contrib information
$dnl_line\n\n";
# Array for all the m4_includes that we'll need to pick up the
# configure.m4's.
my @includes;
my $m4_config_contrib_list;
# Troll through each of the found contribs
foreach my $contrib (@{$mpicontrib_found}) {
my $c = $contrib->{name};
push(@includes, "$contrib_prefix/$c/configure.m4");
$m4_config_contrib_list .= ", $c";
}
$m4_config_contrib_list =~ s/^, //;
# List the M4 and no configure exts
$m4 .= "dnl List of all MPI contribs
m4_define([ompi_mpicontrib_list], [$m4_config_contrib_list])\n";
# List out all the m4_include
$m4 .= "\ndnl List of configure.m4 files to include\n";
foreach my $i (@includes) {
$m4 .= "m4_include([$i])\n";
}
}
##############################################################################
# Find and remove stale files
sub find_and_delete {
foreach my $file (@_) {
my $removed = 0;
if (-f $file) {
unlink($file);
$removed = 1;
}
if (-f "config/$file") {
unlink("config/$file");
$removed = 1;
}
debug " Removed stale copy of $file\n"
if ($removed);
}
}
##############################################################################
# Find a specific executable and ensure that it is a recent enough
# version.
sub find_and_check {
my ($app, $app_name, $req_version) = @_;
my @search_path = split(/;/, $app_name);
my @min_version = split(/\./, $req_version);
my @versions_found = ();
foreach (@search_path) {
verbose " Searching for $_\n";
my $version = `$_ --version`;
if (!defined($version)) {
verbose " $_ not found\n";
next;
}
$version =~ m/\s([\d\w\.]+)$/m;
$version = $1;
verbose " Found $_ version $version; checking version...\n";
push(@versions_found, $version);
my @parts = split(/\./, $version);
my $i = 0;
# Check every component of the version number
while ($i <= $#min_version) {
verbose " Found version component $parts[$i] -- need $min_version[$i]\n";
# Check to see if there are any characters (!) in the
# version number (e.g., Libtool's "2.2.6b" -- #%@#$%!!!).
# Do separate comparisons between the number and any
# trailing digits. You can't just "lt" compare the whole
# string because "10 lt 2b" will return true. #@$@#$#@$
# Libtool!!
$parts[$i] =~ m/(\d+)([a-z]*)/i;
my $pn = $1;
my $pa = $2;
$min_version[$i] =~ m/(\d+)([a-z]*)/i;
my $mn = $1;
my $ma = $2;
# If the version is higher, we're done.
if ($pn > $mn) {
verbose " ==> ACCEPTED\n";
return;
}
# If the version is lower, we're done.
elsif ($pn < $mn ||
($pn == $mn && $pa lt $ma)) {
verbose " ==> Too low! Skipping this version\n";
last;
}
# If the version was equal, keep checking.
++$i;
}
# If we found a good version, return.
if ($i > $#min_version) {
verbose " ==> ACCEPTED\n";
return;
}
}
# if no acceptable version found, reject it
print "
=================================================================
I could not find a recent enough copy of $app.
I need at least $req_version, but only found the following versions:\n\n";
my $i = 0;
foreach (@search_path) {
print " $_: $versions_found[$i]\n";
$i++;
}
print "\nI am gonna abort. :-(
Please make sure you are using at least the following versions of the
GNU tools:
GNU Autoconf: $ompi_autoconf_version
GNU Automake: $ompi_automake_version
GNU Libtool: $ompi_libtool_version
=================================================================\n";
exit(1);
}
##############################################################################
sub safe_system {
my $ret = system(@_);
$ret >>= 8;
if (0 != $ret) {
print "Command failed: @_\n";
exit($ret);
}
$ret;
}
##############################################################################
##############################################################################
## main - do the real work...
##############################################################################
##############################################################################
# Command line parameters
my $ok = Getopt::Long::GetOptions("no-ompi" => \$no_ompi_arg,
"no-orte" => \$no_orte_arg,
"quiet|q" => \$quiet_arg,
"debug|d" => \$debug_arg,
"help|h" => \$help_arg,
"platform=s" => \$platform_arg,
"include=s" => \$include_arg,
"exclude=s" => \$exclude_arg,
);
if (!$ok || $help_arg) {
print "Invalid command line argument.\n\n"
if (!$ok);
print "Options:
--no-ompi | -no-ompi Do not build the Open MPI layer
--no-orte | -no-orte Do not build the ORTE layer
--quiet | -q Do not display normal verbose output
--debug | -d Output lots of debug information
--help | -h This help list
--platform | -p Specify a platform file to be parsed for no_build
and only_build directives
--include | -i Comma-separated list of framework-component pairs
to be exclusively built - i.e., all other components
will be ignored and only those specified will be marked
to build
--exclude | -e Comma-separated list of framework or framework-component
to be excluded from the build\n";
exit($ok ? 0 : 1);
}
#---------------------------------------------------------------------------
# Check for project existence
my $project_name_long = "Open MPI";
my $project_name_short = "openmpi";
if (! -e "ompi") {
$no_ompi_arg=1;
$project_name_long = "Open MPI Run Time Environment";
$project_name_short = "open-rte";
debug "No ompi subdirectory found - will not build MPI layer\n";
}
if (! -e "orte") {
$project_name_long = "Open Portability Access Layer";
$project_name_short = "open-pal";
$no_orte_arg=1;
debug "No orte subdirectory found - will not build ORTE\n";
}
#---------------------------------------------------------------------------
$full_hostname = `hostname`;
chomp($full_hostname);
$m4 = "dnl
dnl \$HEADER\$
dnl
$dnl_line
dnl This file is automatically created by autogen.pl; it should not
dnl be edited by hand!!
dnl
dnl Generated by $username at " . localtime(time) . "
dnl on $full_hostname.
$dnl_line\n\n";
#---------------------------------------------------------------------------
my $step = 1;
verbose "Open MPI autogen (buckle up!)
$step. Checking tool versions\n\n";
# Check the autotools revision levels
&find_and_check("autoconf", $ompi_autoconf_search, $ompi_autoconf_version);
&find_and_check("libtool", $ompi_libtoolize_search, $ompi_libtool_version);
&find_and_check("automake", $ompi_automake_search, $ompi_automake_version);
#---------------------------------------------------------------------------
# Save the platform file in the m4
$m4 .= "dnl Platform file\n";
# Process platform arg, if provided
if ($platform_arg) {
$m4 .= "m4_define([autogen_platform_file], [$platform_arg])\n\n";
open(IN, $platform_arg) || die "Can't open $platform_arg";
# Read all lines from the file
while (<IN>) {
my $line = $_;
my @fields = split(/=/,$line);
if ($fields[0] eq "enable_mca_no_build") {
if ($exclude_arg) {
print "The specified platform file includes an
enable_mca_no_build line. However, your command line
also contains an exclude specification. Only one of
these directives can be given.\n";
exit(1);
}
$exclude_arg = $fields[1];
} elsif ($fields[0] eq "enable_mca_only_build") {
if ($include_arg) {
print "The specified platform file includes an
enable_mca_only_build line. However, your command line
also contains an include specification. Only one of
these directives can be given.\n";
exit(1);
}
$include_arg = $fields[1];
}
}
close(IN);
} else {
# No platform file -- write an empty list
$m4 .= "m4_define([autogen_platform_file], [])\n\n";
}
if ($exclude_arg) {
debug "Using exclude list: $exclude_arg";
my @list = split(/,/, $exclude_arg);
foreach (@list) {
my @pairs = split(/-/, $_);
if (exists($pairs[1])) {
# Remove any trailing newlines
chomp($pairs[1]);
debug " Adding ".$pairs[0]."->".$pairs[1]." to exclude list\n";
push(@{$exclude_list->{$pairs[0]}}, $pairs[1]);
} else {
debug " Adding $pairs[0] to exclude list\n";
push(@{$exclude_list->{$pairs[0]}}, "AGEN_EXCLUDE_ALL");
}
}
}
if ($include_arg) {
debug "Using include list: $include_arg";
my @list = split(/,/, $include_arg);
foreach (@list) {
my @pairs = split(/-/, $_);
if (exists($pairs[1])) {
# Remove any trailing newlines
chomp($pairs[1]);
debug " Adding ".$pairs[0]."->".$pairs[1]." to include list\n";
push(@{$include_list->{$pairs[0]}}, $pairs[1]);
}
# NOTE: it makes no sense to include all as that is the default
# so ignore that scenario here, if given
}
}
#---------------------------------------------------------------------------
##########################################################################
# Temporary: while we're transitioning from autogen.sh, remove some of
# the old generated .m4 files, just so that we don't automatically
# pick them up (because they'll cause problems / conflicts with
# the autogen.pl-generated .m4 file).
##########################################################################
++$step;
verbose "\n$step. Remove autogen.sh-generated files (this is a temporary step!)\n\n";
unlink("config/mca_m4_config_include.m4");
unlink("config/mca_no_configure_components.m4");
unlink("config/ext_no_configure_components.m4");
unlink("config/ext_m4_config_include.m4");
unlink("config/project_list.m4");
##########################################################################
#---------------------------------------------------------------------------
# Find projects, frameworks, components
++$step;
verbose "\n$step. Searching for projects, MCA frameworks, and MCA components\n";
my $ret;
# Figure out if we're at the top level of the OMPI tree or not.
if (! (-f "VERSION" && -f "configure.ac" && -f $topdir_file)) {
print("\n\nYou must run this script from the top-level directory of the Open MPI tree.\n\n");
exit(1);
}
# Top-level projects to examine
my $projects;
push(@{$projects}, { name => "opal", dir => "opal", need_base => 1 });
push(@{$projects}, { name => "orte", dir => "orte", need_base => 1 })
if (!$no_ompi_arg || !$no_orte_arg);
push(@{$projects}, { name => "ompi", dir => "ompi", need_base => 1 })
if (!$no_ompi_arg);
# Save the list of projects in the m4 file
my $str;
foreach my $p (@$projects) {
$str .= "$p->{name}, ";
}
$str =~ s/, $//;
$m4 .= "dnl List of projects found by autogen.pl
m4_define([mca_project_list], [$str])
dnl Separate m4 define for each project\n";
foreach my $p (@$projects) {
$m4 .= "m4_define([project_$p->{name}], [1])\n";
}
$m4 .= "\ndnl Project names
m4_define([project_name_long], [$project_name_long])
m4_define([project_name_short], [$project_name_short])\n";
# Setup MCA
mca_run_global($projects);
#---------------------------------------------------------------------------
# Find MPI extensions and contribs
if (!$no_ompi_arg) {
++$step;
verbose "\n$step. Searching for Open MPI extensions\n\n";
mpiext_run_global("ompi/mpiext");
++$step;
verbose "\n$step. Searching for Open MPI contribs\n\n";
mpicontrib_run_global("ompi/contrib");
}
#---------------------------------------------------------------------------
# Process all subdirs that we found in previous steps
++$step;
verbose "\n$step. Processing autogen.subdirs directories\n";
if ($#subdirs >= 0) {
foreach my $d (@subdirs) {
process_subdir($d);
}
} else {
print "<none found>\n";
}
#---------------------------------------------------------------------------
# If we got here, all was good. Run the auto tools.
++$step;
verbose "\n$step. Running autotools on top-level tree\n\n";
# Remove old versions of the files (this is probably overkill, but...)
verbose "==> Remove stale files\n";
find_and_delete(qw/config.guess config.sub depcomp compile install-sh ltconfig
ltmain.sh missing mkinstalldirs libtool/);
system("rm -rf opal/libltdl");
# Remove the old m4 file and write the new one
verbose "==> Writing m4 file with autogen.pl results\n";
unlink($m4_output_file);
open(M4, ">$m4_output_file") ||
die "Can't open $m4_output_file";
print M4 $m4;
close(M4);
# Generate the version checking script with autom4te
verbose "==> Generating opal_get_version.sh\n";
chdir("config");
safe_system("autom4te --language=m4sh opal_get_version.m4sh -o opal_get_version.sh");
# Run autoreconf
verbose "==> Running autoreconf\n";
chdir("..");
my $cmd = "autoreconf -ivf --warnings=all,no-obsolete,no-override -I config";
foreach my $project (@{$projects}) {
$cmd .= " -I $project->{dir}/config";
}
safe_system($cmd);
#---------------------------------------------------------------------------
# For FreeBSD (carried over from autogen.sh); apparently some versions
# of automake don't so this (prior to 1.9.7...?).
system("chmod u+w opal/libltdl/configure");
#---------------------------------------------------------------------------
++$step;
verbose "\n$step. Patching autotools output :-(\n\n";
# Patch preopen error in libltdl
if (-f "opal/libltdl/loaders/preopen.c") {
verbose "=== Patching preopen error masking in libltdl\n";
safe_system("patch -N -p0 < config/libltdl-preopen-error.diff");
unlink("opal/libltdl/loaders/preopen.c.rej");
}
# Patch ltmain.sh error for PGI version numbers. Redirect stderr to
# /dev/null because this patch is only necessary for some versions of
# Libtool (e.g., 2.2.6b); it'll [rightfully] fail if you have a new
# enough Libtool that dosn't need this patch. But don't alarm the
# user and make them think that autogen failed if this patch fails --
# make the errors be silent.
verbose "=== Patching PGI compiler version numbers in ltmain.sh\n";
# Solaris patch is not compatible with Linux patch
if ("$^O" eq "SunOS") {
verbose "--- Using SunOS gpatch\n";
system("gpatch -N -p0 < config/ltmain_pgi_tp.diff >/dev/null 2>&1");
} else {
verbose "--- Using $^O patch\n";
system("patch -N -p0 < config/ltmain_pgi_tp.diff >/dev/null 2>&1");
}
unlink("config/ltmain.sh.rej");
# Total ugh. We have to patch the configure script itself. See below
# for explainations why.
open(IN, "configure") || die "Can't open configure";
my $c;
$c .= $_
while(<IN>);
close(IN);
# LT <=2.2.6b need to be patched for the PGI 10.0 fortran compiler
# name (pgfortran). The following comes from the upstream LT patches:
# http://lists.gnu.org/archive/html/libtool-patches/2009-11/msg00012.html
# http://lists.gnu.org/archive/html/bug-libtool/2009-11/msg00045.html
# Note that that patch is part of Libtool (which is not in this OMPI
# source tree); we can't fix it. So all we can do is patch the
# resulting configure script. :-(
print("=== Patching configure for Libtool PGI 10 fortran compiler name\n");
$c =~ s/gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn/gfortran g95 xlf95 f95 fort ifort ifc efc pgfortran pgf95 lf95 ftn/g;
$c =~ s/pgcc\* \| pgf77\* \| pgf90\* \| pgf95\*\)/pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)/g;
$c =~ s/pgf77\* \| pgf90\* \| pgf95\*\)/pgf77* | pgf90* | pgf95* | pgfortran*)/g;
# Similar issue as above -- the PGI 10 version number broke <=LT
# 2.2.6b's version number checking regexps. Again, we can't fix the
# Libtool install; all we can do is patch the resulting configure
# script. :-( The following comes from the upstream patch:
# http://lists.gnu.org/archive/html/libtool-patches/2009-11/msg00016.html
print("=== Patching configure for Libtool PGI version number regexps\n");
$c =~ s/\*pgCC\\ \[1-5\]\* \| \*pgcpp\\ \[1-5\]\*/*pgCC\\ [1-5]\.* | *pgcpp\\ [1-5]\.*/g;
open(OUT, ">configure.patched") || die "Can't open configure.patched";
print OUT $c;
close(OUT);
# Use cp so that we preserve permissions on configure
safe_system("cp configure.patched configure");
unlink("configure.patched");
#---------------------------------------------------------------------------
verbose "
================================================
Open MPI autogen: completed successfully. w00t!
================================================\n\n";
# Done!
exit($ret);