From 1733ae55513e79d1e96a233bf6eeb799aabf8e4b Mon Sep 17 00:00:00 2001 From: eschnett Date: Wed, 3 Dec 2014 22:15:29 +0000 Subject: Build MPI at build time git-svn-id: http://svn.cactuscode.org/projects/ExternalLibraries/MPI/trunk@58 043a8217-7a68-40fe-abfd-36aa7d4fa6a8 --- configuration.ccl | 5 +- configure.pl | 420 ----------------------------------------------------- src/build.pl | 82 +++++++++++ src/detect.pl | 303 ++++++++++++++++++++++++++++++++++++++ src/make.code.deps | 7 + 5 files changed, 396 insertions(+), 421 deletions(-) delete mode 100644 configure.pl create mode 100644 src/build.pl create mode 100644 src/detect.pl create mode 100644 src/make.code.deps diff --git a/configuration.ccl b/configuration.ccl index e65a2fd..d094783 100644 --- a/configuration.ccl +++ b/configuration.ccl @@ -2,7 +2,10 @@ PROVIDES MPI { - SCRIPT configure.pl + SCRIPT src/detect.pl LANG perl OPTIONS MPI MPI_DIR MPI_INC_DIRS MPI_LIB_DIRS MPI_LIBS MPI_INSTALL_DIR } + +# Pass configuration options to build script +REQUIRES MPI diff --git a/configure.pl b/configure.pl deleted file mode 100644 index a17921e..0000000 --- a/configure.pl +++ /dev/null @@ -1,420 +0,0 @@ -#!/usr/bin/perl -use Carp; -use strict; -use FileHandle; -use Cwd; -$/ = undef; - -# Used by pushd/popd -my @push_dirs = (); - -# Used by begin/end message -my @messages = (); - -# Used by sys() -my $aborted = 0; - -################################################################################ -# Prepare -################################################################################ - -# Set up shell -my $verbose = 0; -$verbose = 1 if($ENV{VERBOSE} =~ /^yes$/i); - -################################################################################ -# Check for old mechanism -################################################################################ - -if(defined($ENV{MPI})) { - error("Setting the option \"MPI\" is incompatible with the MPI thorn. Please remove the option MPI=$ENV{MPI}.",2); -} - -################################################################################ -# Determine whether to build and/or search -################################################################################ - -my $info = undef; -my $mpi_info_set = 0; -my $mpi_dir = undef; -my $mpi_cmd = undef; -my $mpi_search = 1; -my $mpi_build = 0; -my $mpi_manual = 0; - -my @mpicxx_names = ("mpic++","mpiCC","mpicxx","mpicxx-openmpi-mp","mpicc"); - -if(!is_set("MPI_DIR")) { - message("MPI selected, but MPI_DIR is not set. Computing settings..."); - $mpi_build = 1; - $mpi_search = 1; -} elsif($ENV{MPI_DIR} eq "NO_BUILD") { - $mpi_dir = $ENV{MPI_DIR}; - $mpi_build = 0; - $mpi_search = 1; -} elsif($ENV{MPI_DIR} eq "BUILD") { - $mpi_build = 1; - $mpi_search = 0; -} elsif($ENV{MPI_DIR} eq "NONE") { - $mpi_build = 0; - $mpi_search = 0; - $mpi_info_set = 1; - $mpi_dir = ''; - $info = ''; -} else { - if(!-d $ENV{MPI_DIR}) { - message("MPI_DIR is set to a directory that does not exist (MPI_DIR=$ENV{MPI_DIR}); continuing anyway"); - } - $mpi_dir = $ENV{MPI_DIR}; - $mpi_build = 0; - $mpi_search = 0; - if(is_set("MPI_INC_DIRS") or is_set("MPI_LIB_DIRS") or is_set("MPI_LIBS")) { - # If some of the MPI variables are set, this is a completely - # manual configuration. - $mpi_manual = 1; - } else { - # If none of the MPI variables are set, check for the compiler - # wrapper under MPI_DIR - $mpi_manual = 0; - for my $name (@mpicxx_names) { - my $full_name = "$ENV{MPI_DIR}/bin/$name"; - if(-x $full_name) { - $mpi_cmd = $full_name; - last; - } - } - if(defined($mpi_cmd)) { - message("Found mpi compiler wrapper at $mpi_cmd!"); - mpi_get_info(); - } else { - message("No mpi compiler wrapper found beneath MPI_DIR (MPI_DIR=$ENV{MPI_DIR})"); - } - } -} - -################################################################################ -# Search -################################################################################ -if($mpi_search and !defined($mpi_cmd)) { - for my $name (@mpicxx_names) { - last if(defined($mpi_cmd)); - $mpi_cmd = which($name); - } - if(defined($mpi_cmd)) { - $mpi_dir = $mpi_cmd; - $mpi_dir =~ s{/mpi(c\+\+|CC|cc|cxx)[^/]*$}{}; - $mpi_dir =~ s{/bin$}{}; - message("Found mpi compiler wrapper at $mpi_cmd!"); - mpi_get_info(); - } -} - -################################################################################ -# Build -################################################################################ - -if($mpi_build and !$mpi_info_set) { - # check for required tools. Do this here so that we don't require - # them when using the system library - unless(defined($ENV{TAR}) and $ENV{TAR} =~ /\S/ and -x which($ENV{TAR})) { - error( - "ENV{TAR}=$ENV{TAR}\n" . - "Could not find tar command. Please make sure that (gnu) tar is present\n" . - "and that the TAR variable is set to its location.\n",3); - } - unless(defined($ENV{PATCH}) and $ENV{PATCH} =~ /\S/ and -x which($ENV{PATCH})) { - error( - "Could not find patch command. Please make sure that (gnu) patch is present\n" . - "and that the PATCH variable is set to its location.\n",4); - } - - # Set locations - my $THORN="MPI"; - my $NAME="openmpi-1.6.5"; - #my $NAME=openmpi-1.7.1 - my $INSTALL_DIR = undef; - my $BUILD_DIR = undef; - my $SRCDIR = $0; - $SRCDIR =~ s{(.*)/.*}{$1}; - ${BUILD_DIR}="$ENV{SCRATCH_BUILD}/build/${THORN}"; - if(defined($ENV{MPI_INSTALL_DIR}) and $ENV{MPI_INSTALL_DIR} =~ /\S/) { - $INSTALL_DIR = "$ENV{MPI_INSTALL_DIR}/${THORN}"; - } else { - $INSTALL_DIR = "$ENV{SCRATCH_BUILD}/external/${THORN}"; - } - message("Installing MPI into ${INSTALL_DIR}"); - my $DONE_FILE="$ENV{SCRATCH_BUILD}/done/${THORN}"; - $mpi_dir=${INSTALL_DIR}; - - # Setting $mpi_cmd enables the generic - # search method below to configure the - # various MPI variables. - $mpi_cmd="$mpi_dir/bin/mpicc"; - - if(-r ${DONE_FILE}) { - message("MPI has already been built; doing nothing"); - } else { - message("Building MPI"); - message("Using bundled MPI..."); - - chdir($ENV{SCRATCH_BUILD}); - -# Set up environment -# Disable ccache: remove "ccache" and all options that follow -# Note: we can use only basic sed regexps here -#export CC=$(echo '' ${CC} '' | -# sed -e 's/ ccache *\(-[^ ]* *\)*/ /g;s/^ //;s/ $//') -#export CXX=$(echo '' ${CXX} '' | -# sed -e 's/ ccache *\(-[^ ]* *\)*/ /g;s/^ //;s/ $//') - $ENV{CC} =~ s/ ccache .*//; - $ENV{CXX} =~ s/ ccache .*//; - if($ENV{F90} =~ /none/) { - message("No Fortran 90 compiler available. Building MPI library without Fortran support."); - $ENV{FC}=undef; - $ENV{FCFLAGS}=undef; - } else { - $ENV{FC} = $ENV{F90}; - $ENV{FCFLAGS} = $ENV{F90FLAGS}; - } - $ENV{LIBS}=undef; - $ENV{RPATH}=undef; - if($ENV{ARFLAGS} =~ /64/) { - $ENV{OBJECT_MODE}="64"; - } - - message("MPI: Preparing directory structure..."); - mkdir("external"); - mkdir("done"); - sys("rm -rf ${BUILD_DIR} ${INSTALL_DIR}"); - mkdir(${BUILD_DIR}); - mkdir(${INSTALL_DIR}); - error("${INSTALL_DIR} does not exist.",6) unless(-e ${INSTALL_DIR}); - error("${INSTALL_DIR} is not a directory.",6) unless(-d ${INSTALL_DIR}); - error("${INSTALL_DIR} is not readabile.",7) unless(-r ${INSTALL_DIR}); - error("${INSTALL_DIR} is not writeable.",8) unless(-w ${INSTALL_DIR}); - error("${INSTALL_DIR} is not executable.",8) unless(-x ${INSTALL_DIR}); - $mpi_dir = $ENV{MPI_DIR} = ${INSTALL_DIR}; - - message("MPI: Unpacking archive..."); - pushd(${BUILD_DIR}); - sys("$ENV{TAR} xzf ${SRCDIR}/dist/${NAME}.tar.gz"); - sys("$ENV{PATCH} -p0 < ${SRCDIR}/dist/default_outfile-1.6.5.patch"); - chdir(${NAME}); - sys("$ENV{PATCH} -p0 < ${SRCDIR}/dist/cuda_build_fix__svn29754"); - - message("MPI: Configuring..."); -# Cannot have a memory manager with a static library on some -# systems (e.g. Linux); see -# - sys("./configure --prefix=$mpi_dir --without-memory-manager --without-libnuma --enable-shared=no --enable-static=yes"); - - message("MPI: Building..."); - sys("$ENV{MAKE}"); - - message("MPI: Installing..."); - sys("$ENV{MAKE} install"); - popd(); - - message("MPI: Cleaning up..."); - sys("rm -rf ${BUILD_DIR}"); - - sys("date > ${DONE_FILE}"); - message("MPI: Done."); - } - mpi_get_info(); -} - -################################################################################ -# Configure MPI options -################################################################################ - -if($mpi_info_set) { - my @incdirs = (); - my @libdirs = (); - my @libs = (); - while($info =~ /\s-I\s*(\S+)/g) { - push @incdirs, $1; - } - while($info =~ /\s-L\s*(\S+)/g) { - push @libdirs, $1; - } - while($info =~ /\s-l(\S+)/g) { - push @libs, $1; - } - - $ENV{MPI_DIR}=$mpi_dir; - $ENV{MPI_INC_DIRS}=join(" ",@incdirs); - $ENV{MPI_LIB_DIRS}=join(" ",@libdirs); - $ENV{MPI_LIBS}=join(" ",@libs); - - message("Successfully configured MPI."); -} elsif($mpi_manual) { - my @incdirs = (); - my @libdirs = (); - my @libs = (); - if (is_set("MPI_INC_DIRS")) { - push @incdirs, $ENV{MPI_INC_DIRS}; - } else { - push @incdirs, $ENV{MPI_DIR} . "/include"; - } - if (is_set("MPI_LIB_DIRS")) { - push @libdirs, $ENV{MPI_LIB_DIRS}; - } else { - push @libdirs, $ENV{MPI_DIR} . "/lib64"; - push @libdirs, $ENV{MPI_DIR} . "/lib"; - } - if (is_set("MPI_LIBS")) { - push @libs, $ENV{MPI_LIBS}; - } else { - # do nothing - } - - $ENV{MPI_INC_DIRS}=join(" ",@incdirs); - $ENV{MPI_LIB_DIRS}=join(" ",@libdirs); - $ENV{MPI_LIBS}=join(" ",@libs); - - message("MPI was manually configured."); -} else { - error("MPI could not be configured: neither automatic nor manual configuration succeeded",5); -} - -################################################################################ -# Configure Cactus -################################################################################ - -# Strip standard paths -$ENV{MPI_INC_DIRS} = strip_inc_dirs($ENV{MPI_INC_DIRS}); -$ENV{MPI_LIB_DIRS} = strip_lib_dirs($ENV{MPI_LIB_DIRS}); - -# Pass options to Cactus - -begin_message("DEFINE"); -print "CCTK_MPI 1\n"; -# print "HAVE_MPI 1\n"; -end_message(); - -begin_message("MAKE_DEFINITION"); -print "CCTK_MPI = 1\n"; -# print "HAVE_MPI = 1\n"; -print "MPI_DIR = $ENV{MPI_DIR}\n"; -print "MPI_INC_DIRS = $ENV{MPI_INC_DIRS}\n"; -print "MPI_LIB_DIRS = $ENV{MPI_LIB_DIRS}\n"; -print "MPI_LIBS = $ENV{MPI_LIBS}\n"; -end_message(); - -print "INCLUDE_DIRECTORY \$(MPI_INC_DIRS)\n"; -print "LIBRARY_DIRECTORY \$(MPI_LIB_DIRS)\n"; -print "LIBRARY \$(MPI_LIBS)\n"; - -################################################################################ -# Functions -################################################################################ - -sub pushd { - push @push_dirs, Cwd::getcwd(); - chdir(shift); -} -sub popd { - chdir(shift @push_dirs); -} -sub which { - my $cmd = shift; - for my $path (split(/:/,$ENV{PATH})) { - my $full_cmd = "$path/$cmd"; - if(-x $full_cmd) { - return $full_cmd; - } - } - return undef; -} - -sub sys { - my $cmd = shift; - return unless($aborted == 0); - $aborted = system("$cmd 1>&2"); -} - -sub mpi_get_info { - my $fd = new FileHandle; - open($fd,"$mpi_cmd -compile_info 2>/dev/null|"); - $info = <$fd>; - close($fd); - if($info eq "") { - open($fd,"$mpi_cmd --showme 2>/dev/null|"); - $info = <$fd>; - close($fd); - } - if($info eq "") { - # The command, mpicc, is quite often a shell script. - # Run it with -x to trace, and find the compile command. - open($fd,"sh -x $mpi_cmd /dev/null 2>/dev/null|"); - my $contents = <$fd>; - if($contents =~ /\w+cc.*-I\/.*-lmpi.*/) { - $info = $&; - } - } - if($info =~ /^\s*$/) { - $mpi_info_set = 0; - } else { - $mpi_info_set = 1; - } -} - -sub error { - my ($msg,$errno) = @_; - $msg =~ s/\n$//; - begin_message("ERROR"); - print $msg,"\n"; - end_message("ERROR"); - exit $errno; -} -sub message { - my $msg = shift; - $msg =~ s/\n$//; - begin_message(); - print $msg,"\n"; - end_message(); -} -sub begin_message { - my $msg = shift; - my $oldmsg = ""; - $msg = "MESSAGE" unless(defined($msg)); - $oldmsg = $messages[$#messages] if($#messages >= 0); - push @messages, $msg; - Carp::carp() unless(defined($msg)); - Carp::carp() unless(length($msg)>3); - unless($oldmsg eq $msg) { - print "END $oldmsg\n" unless($oldmsg eq ""); - print "BEGIN $msg\n"; - } -} -sub end_message { - my $msg = pop @messages; - my $oldmsg = ""; - $oldmsg = $messages[$#messages] if($#messages >= 0); - Carp::carp() unless(defined($msg)); - Carp::carp() unless(length($msg)>3); - unless($oldmsg eq $msg) { - print "END $msg\n"; - print "BEGIN $oldmsg\n" unless($oldmsg eq ""); - } -} -sub is_set { - my $var = shift; - return (defined($ENV{$var}) and !($ENV{$var} =~ /^\s*$/)); -} - -sub strip_inc_dirs { - my $dirlist = shift; - my @dirs = split / /, $dirlist; - map { s{//}{/}g } @dirs; - @dirs = grep { !m{^/(usr/(local/)?)?include/?$} } @dirs; - return join ' ', @dirs; -} -sub strip_lib_dirs { - my $dirlist = shift; - my @dirs = split / /, $dirlist; - map { s{//}{/}g } @dirs; - @dirs = grep { !m{^/(usr/(local/)?)?lib(64?)/?$} } @dirs; - return join ' ', @dirs; -} diff --git a/src/build.pl b/src/build.pl new file mode 100644 index 0000000..58ab021 --- /dev/null +++ b/src/build.pl @@ -0,0 +1,82 @@ +#!/usr/bin/perl +use Carp; +use strict; +use FileHandle; +use Cwd; +$/ = undef; + +# Set locations +my $THORN = "MPI"; +my $NAME = "openmpi-1.6.5"; +my $INSTALL_DIR = undef; +my $BUILD_DIR = undef; +my $SRCDIR = $0; +$SRCDIR =~ s{(.*)/.*}{$1}; +${BUILD_DIR} = "$ENV{SCRATCH_BUILD}/build/${THORN}"; +if (defined($ENV{MPI_INSTALL_DIR}) and $ENV{MPI_INSTALL_DIR} =~ /\S/) { + $INSTALL_DIR = "$ENV{MPI_INSTALL_DIR}/${THORN}"; +} else { + $INSTALL_DIR = "$ENV{SCRATCH_BUILD}/external/${THORN}"; +} +print "Installing MPI into ${INSTALL_DIR}\n"; +my $DONE_FILE = "$ENV{SCRATCH_BUILD}/done/${THORN}"; +my $mpi_dir = ${INSTALL_DIR}; + +chdir($ENV{SCRATCH_BUILD}); + +# Set up environment +# Disable ccache: remove "ccache" and all options that follow +$ENV{CC} =~ s/^\s*ccache\s+(-\S*\s+)*//; +$ENV{CXX} =~ s/^\s*ccache\s+(-\S*\s+)*//; +if ($ENV{F90} eq 'none') { + print "No Fortran 90 compiler available. Building MPI library without Fortran support.\n"; + $ENV{FC} = undef; + $ENV{FCFLAGS} = undef; +} else { + $ENV{FC} = $ENV{F90}; + $ENV{FCFLAGS} = $ENV{F90FLAGS}; +} +$ENV{LIBS} = undef; +$ENV{RPATH} = undef; +if ($ENV{ARFLAGS} =~ /64/) { + $ENV{OBJECT_MODE} = "64"; +} + +print "MPI: Preparing directory structure...\n"; +mkdir("build"); +mkdir("external"); +mkdir("done"); +system("rm -rf ${BUILD_DIR} ${INSTALL_DIR}") == 0 or die; +mkdir(${BUILD_DIR}); +mkdir(${INSTALL_DIR}); +error("${INSTALL_DIR} does not exist.",6) unless(-e ${INSTALL_DIR}); +error("${INSTALL_DIR} is not a directory.",6) unless(-d ${INSTALL_DIR}); +error("${INSTALL_DIR} is not readable.",7) unless(-r ${INSTALL_DIR}); +error("${INSTALL_DIR} is not writeable.",8) unless(-w ${INSTALL_DIR}); +error("${INSTALL_DIR} is not executable.",8) unless(-x ${INSTALL_DIR}); + +print "MPI: Unpacking archive...\n"; +chdir(${BUILD_DIR}); +system("$ENV{TAR} xzf ${SRCDIR}/../dist/${NAME}.tar.gz") == 0 or die; +system("$ENV{PATCH} -p0 < ${SRCDIR}/../dist/default_outfile-1.6.5.patch") == 0 or die; +chdir(${NAME}); +system("$ENV{PATCH} -p0 < ${SRCDIR}/../dist/cuda_build_fix__svn29754") == 0 or die; + +print "MPI: Configuring...\n"; +# Cannot have a memory manager with a static library on some systems +# (e.g. Linux); see +# +system("./configure --prefix=$mpi_dir --without-memory-manager --without-libnuma --enable-shared=no --enable-static=yes") == 0 or die; + +print "MPI: Building...\n"; +system("$ENV{MAKE}") == 0 or die; + +print "MPI: Installing...\n"; +system("$ENV{MAKE} install") == 0 or die; +chdir($ENV{SCRATCH_BUILD}); + +print "MPI: Cleaning up...\n"; +system("rm -rf ${BUILD_DIR}") == 0 or die; + +system("date > ${DONE_FILE}") == 0 or die; +print "MPI: Done.\n"; diff --git a/src/detect.pl b/src/detect.pl new file mode 100644 index 0000000..e598f7b --- /dev/null +++ b/src/detect.pl @@ -0,0 +1,303 @@ +#!/usr/bin/perl +use Carp; +use strict; +use FileHandle; +use Cwd; +$/ = undef; + +################################################################################ +# Prepare +################################################################################ + +# Set up shell +my $verbose = 0; +$verbose = 1 if $ENV{VERBOSE} =~ /^yes$/i; + +################################################################################ +# Check for old mechanism +################################################################################ + +if (defined($ENV{MPI})) { + error("Setting the option \"MPI\" is incompatible with the MPI thorn. Please remove the option MPI = $ENV{MPI}.", 2); +} + +################################################################################ +# Determine whether to build and/or search +################################################################################ + +my $info = undef; +my $mpi_info_set = 0; +my $mpi_dir = undef; +my $mpi_cmd = undef; +my $mpi_search = 1; +my $mpi_build = 0; +my $mpi_manual = 0; + +my @mpicxx_names = ("mpic++", "mpiCC", "mpicxx", "mpicxx-openmpi-mp", "mpicc"); + +if (!is_set("MPI_DIR")) { + message("MPI selected, but MPI_DIR is not set. Computing settings..."); + $mpi_build = 1; + $mpi_search = 1; +} elsif ($ENV{MPI_DIR} eq "NO_BUILD") { + $mpi_dir = $ENV{MPI_DIR}; + $mpi_build = 0; + $mpi_search = 1; +} elsif ($ENV{MPI_DIR} eq "BUILD") { + $mpi_build = 1; + $mpi_search = 0; +} elsif ($ENV{MPI_DIR} eq "NONE") { + $mpi_build = 0; + $mpi_search = 0; + $mpi_info_set = 1; + $mpi_dir = ''; + $info = ''; +} else { + if (!-d $ENV{MPI_DIR}) { + message("MPI_DIR is set to a directory that does not exist (MPI_DIR = $ENV{MPI_DIR}); continuing anyway"); + } + $mpi_dir = $ENV{MPI_DIR}; + $mpi_build = 0; + $mpi_search = 0; + if (is_set("MPI_INC_DIRS") or is_set("MPI_LIB_DIRS") or is_set("MPI_LIBS")) + { + # If some of the MPI variables are set, this is a completely + # manual configuration. + $mpi_manual = 1; + } else { + # If none of the MPI variables are set, check for the compiler + # wrapper under MPI_DIR + $mpi_manual = 0; + for my $name (@mpicxx_names) { + my $full_name = "$ENV{MPI_DIR}/bin/$name"; + if (-x $full_name) { + $mpi_cmd = $full_name; + last; + } + } + if (defined($mpi_cmd)) { + message("Found MPI compiler wrapper at $mpi_cmd!"); + mpi_get_info(); + } else { + message("No MPI compiler wrapper found beneath MPI_DIR (MPI_DIR = $ENV{MPI_DIR})"); + } + } +} + +################################################################################ +# Search +################################################################################ +if ($mpi_search and !defined($mpi_cmd)) { + for my $name (@mpicxx_names) { + last if defined($mpi_cmd); + $mpi_cmd = which($name); + } + if (defined($mpi_cmd)) { + $mpi_dir = $mpi_cmd; + $mpi_dir =~ s{/mpi(c\+\+|CC|cc|cxx)[^/]*$}{}; + $mpi_dir =~ s{/bin$}{}; + message("Found MPI compiler wrapper at $mpi_cmd!"); + mpi_get_info(); + } +} + +################################################################################ +# Build +################################################################################ + +if ($mpi_build and !$mpi_info_set) { + # Check for required tools. Do this here so that we don't require + # them when using the system library. + unless(defined($ENV{TAR}) and $ENV{TAR} =~ /\S/ and -x which($ENV{TAR})) { + error( + "ENV{TAR} = $ENV{TAR}\n" . + "Could not find tar command. Please make sure that (GNU) tar is present,\n" . + "and that the TAR variable is set to its location.\n", 3); + } + unless(defined($ENV{PATCH}) and $ENV{PATCH} =~ /\S/ and + -x which($ENV{PATCH})) + { + error( + "Could not find patch command. Please make sure that (GNU) patch is present,\n" . + "and that the PATCH variable is set to its location.\n", 4); + } + + # Set locations + my $THORN = "MPI"; + my $NAME = "openmpi-1.6.5"; + my $INSTALL_DIR = undef; + my $BUILD_DIR = undef; + my $SRCDIR = $0; + $SRCDIR =~ s{(.*)/.*}{$1}; + ${BUILD_DIR} = "$ENV{SCRATCH_BUILD}/build/${THORN}"; + if (defined($ENV{MPI_INSTALL_DIR}) and $ENV{MPI_INSTALL_DIR} =~ /\S/) { + $INSTALL_DIR = "$ENV{MPI_INSTALL_DIR}/${THORN}"; + } else { + $INSTALL_DIR = "$ENV{SCRATCH_BUILD}/external/${THORN}"; + } + message("Installing MPI into ${INSTALL_DIR}"); + $mpi_dir = ${INSTALL_DIR}; + + $mpi_manual = 1; + $ENV{MPI_DIR} = $mpi_dir; + $ENV{MPI_INC_DIRS} = "$mpi_dir/include"; + $ENV{MPI_LIB_DIRS} = "$mpi_dir/lib"; + $ENV{MPI_LIBS} = "mpi"; +} + +################################################################################ +# Configure MPI options +################################################################################ + +if ($mpi_info_set) { + my @incdirs = (); + my @libdirs = (); + my @libs = (); + while($info =~ /\s-I\s*(\S+)/g) { + push @incdirs, $1; + } + while($info =~ /\s-L\s*(\S+)/g) { + push @libdirs, $1; + } + while($info =~ /\s-l(\S+)/g) { + push @libs, $1; + } + + $ENV{MPI_DIR} = $mpi_dir; + $ENV{MPI_INC_DIRS} = join(" ",@incdirs); + $ENV{MPI_LIB_DIRS} = join(" ",@libdirs); + $ENV{MPI_LIBS} = join(" ",@libs); + + message("Successfully configured MPI."); +} elsif ($mpi_manual) { + my @incdirs = (); + my @libdirs = (); + my @libs = (); + if (is_set("MPI_INC_DIRS")) { + push @incdirs, $ENV{MPI_INC_DIRS}; + } else { + push @incdirs, "$ENV{MPI_DIR}/include"; + } + if (is_set("MPI_LIB_DIRS")) { + push @libdirs, $ENV{MPI_LIB_DIRS}; + } else { + push @libdirs, "$ENV{MPI_DIR}/lib64"; + push @libdirs, "$ENV{MPI_DIR}/lib"; + } + if (is_set("MPI_LIBS")) { + push @libs, $ENV{MPI_LIBS}; + } else { + # do nothing + } + + $ENV{MPI_INC_DIRS} = join(" ",@incdirs); + $ENV{MPI_LIB_DIRS} = join(" ",@libdirs); + $ENV{MPI_LIBS} = join(" ",@libs); + + message("MPI was manually configured."); +} else { + error("MPI could not be configured: neither automatic nor manual configuration succeeded",5); +} + +################################################################################ +# Configure Cactus +################################################################################ + +# Strip standard paths +$ENV{MPI_INC_DIRS} = strip_inc_dirs($ENV{MPI_INC_DIRS}); +$ENV{MPI_LIB_DIRS} = strip_lib_dirs($ENV{MPI_LIB_DIRS}); + +# Pass options to Cactus + +print "BEGIN DEFINE\n"; +print "CCTK_MPI 1\n"; +print "END DEFINE\n"; + +print "BEGIN MAKE_DEFINITION\n"; +print "CCTK_MPI = 1\n"; +print "MPI_DIR = $ENV{MPI_DIR}\n"; +print "MPI_INC_DIRS = $ENV{MPI_INC_DIRS}\n"; +print "MPI_LIB_DIRS = $ENV{MPI_LIB_DIRS}\n"; +print "MPI_LIBS = $ENV{MPI_LIBS}\n"; +print "END MAKE_DEFINITION\n"; + +print "INCLUDE_DIRECTORY \$(MPI_INC_DIRS)\n"; +print "LIBRARY_DIRECTORY \$(MPI_LIB_DIRS)\n"; +print "LIBRARY \$(MPI_LIBS)\n"; + +################################################################################ +# Functions +################################################################################ + +sub which { + my $cmd = shift; + for my $path (split(/:/,$ENV{PATH})) { + my $full_cmd = "$path/$cmd"; + if (-x $full_cmd) { + return $full_cmd; + } + } + return undef; +} + +sub mpi_get_info { + my $fd = new FileHandle; + open($fd,"$mpi_cmd -compile_info 2>/dev/null|"); + $info = <$fd>; + close($fd); + if ($info eq "") { + open($fd,"$mpi_cmd --showme 2>/dev/null|"); + $info = <$fd>; + close($fd); + } + if ($info eq "") { + # The command, mpicc, is quite often a shell script. + # Run it with -x to trace, and find the compile command. + open($fd,"sh -x $mpi_cmd /dev/null 2>/dev/null|"); + my $contents = <$fd>; + if ($contents =~ /\w+cc.*-I\/.*-lmpi.*/) { + $info = $&; + } + } + if ($info =~ /^\s*$/) { + $mpi_info_set = 0; + } else { + $mpi_info_set = 1; + } +} + +sub message { + my $msg = shift; + $msg =~ s/\n$//; + print "BEGIN MESSAGE\n"; + print "$msg\n"; + print "END MESSAGE\n"; +} +sub error { + my ($msg,$errno) = @_; + $msg =~ s/\n$//; + print "BEGIN ERROR\n"; + print "$msg\n"; + print "END ERROR\n"; + exit $errno; +} + +sub is_set { + my $var = shift; + return (defined($ENV{$var}) and !($ENV{$var} =~ /^\s*$/)); +} + +sub strip_inc_dirs { + my $dirlist = shift; + my @dirs = split / /, $dirlist; + map { s{//}{/}g } @dirs; + @dirs = grep { !m{^/(usr/(local/)?)?include/?$} } @dirs; + return join ' ', @dirs; +} +sub strip_lib_dirs { + my $dirlist = shift; + my @dirs = split / /, $dirlist; + map { s{//}{/}g } @dirs; + @dirs = grep { !m{^/(usr/(local/)?)?lib(64?)/?$} } @dirs; + return join ' ', @dirs; +} diff --git a/src/make.code.deps b/src/make.code.deps new file mode 100644 index 0000000..65c2302 --- /dev/null +++ b/src/make.code.deps @@ -0,0 +1,7 @@ +# Main make.code.deps file for thorn MPI + +export MPI_INSTALL_DIR + +$(CCTK_TARGET) $(OBJS) $(SRCS:%=%.d): $(SCRATCH_BUILD)/done/$(THORN) +$(SCRATCH_BUILD)/done/$(THORN): $(SRCDIR)/build.pl + $(PERL) $(SRCDIR)/build.pl -- cgit v1.2.3