1#! /bin/sh 2## 3## Copyright (C) by Argonne National Laboratory 4## See COPYRIGHT in top-level directory 5## 6 7# Simple script to compile and/or link MPI programs. 8# This script knows the default flags and libraries, and can handle 9# alternative C compilers and the associated flags and libraries. 10# The important terms are: 11# includedir, libdir - Directories containing an *installed* mpich 12# prefix, execprefix - Often used to define includedir and libdir 13# FC - Fortran 90 compiler 14# WRAPPER_FCFLAGS - Any special flags needed to compile 15# WRAPPER_LDFLAGS - Any special flags needed to link 16# WRAPPER_LIBS - Any special libraries needed in order to link 17# FC_OTHER_LIBS - Yet more libraries, needed just with FC 18# 19# We assume that (a) the C compiler can both compile and link programs 20# 21# Handling of command-line options: 22# This is a little tricky because some options may contain blanks. 23# 24# Special issues with shared libraries - todo 25# 26# -------------------------------------------------------------------------- 27# Set the default values of all variables. 28# 29# Directory locations: Fixed for any MPI implementation. 30# Set from the directory arguments to configure (e.g., --prefix=/usr/local) 31prefix=__PREFIX_TO_BE_FILLED_AT_INSTALL_TIME__ 32exec_prefix=__EXEC_PREFIX_TO_BE_FILLED_AT_INSTALL_TIME__ 33sysconfdir=__SYSCONFDIR_TO_BE_FILLED_AT_INSTALL_TIME__ 34includedir=__INCLUDEDIR_TO_BE_FILLED_AT_INSTALL_TIME__ 35libdir=__LIBDIR_TO_BE_FILLED_AT_INSTALL_TIME__ 36modincdir=@modincdir@ 37 38# Default settings for compiler, flags, and libraries 39# Determined by a combination of environment variables and tests within 40# configure (e.g., determining whehter -lsocket is needee) 41FC="@FC@" 42FCCPP="@FCCPP@" 43# 44# Fortran 90 Compiler characteristics 45FCINC="@FCINC@" 46# f90modinc specifies how to add a directory to the search path for modules. 47# Some compilers (Intel ifc version 5) do not support this concept, and 48# instead need 49# a specific list of files that contain module names and directories. 50# The FCMODINCSPEC is a more general approach that uses <dir> and <file> 51# for the directory and file respectively. 52FCMODINC="@FCMODINCFLAG@" 53FCMODINCSPEC="@FCMODINCSPEC@" 54FCEXT="@FCEXT@" 55# 56MPICH_VERSION="@MPICH_VERSION@" 57 58@fc_shlib_conf@ 59 60# Attempt to construct dynamic loading info, based on the user 61# preference of rpath, runpath or none and on the detected libdir 62# flags. 63with_wrapper_dl_type=@with_wrapper_dl_type@ 64if test "X${with_wrapper_dl_type}" = "Xrunpath" ; then 65 eval wrapper_dl_type_flags=\"${hardcode_libdir_flag_spec} ${enable_dtags_flag}\" 66elif test "X${with_wrapper_dl_type}" = "Xrpath" ; then 67 eval wrapper_dl_type_flags=\"${hardcode_libdir_flag_spec} ${disable_dtags_flag}\" 68else 69 wrapper_dl_type_flags="" 70fi 71 72# Internal variables 73# Show is set to echo to cause the compilation command to be echoed instead 74# of executed. 75Show=eval 76# 77# End of initialization of variables 78#--------------------------------------------------------------------- 79# Environment Variables. 80# The environment variables MPICH_FC may be used to override the 81# default choices. 82# In addition, if there is a file $sysconfdir/mpifort-$FCname.conf, 83# where FCname is the name of the compiler with all spaces replaced by hyphens 84# (e.g., "fc -64" becomes "fc--64", that file is sources, allowing other 85# changes to the compilation environment. See the variables used by the 86# script (defined above) 87# Added MPICH_FC_OLD, MPICH_FC can be used to prefix FC with external utility, 88# e.g. setenv MPICH_FC 'eval linkcache $MPICH_FC_OLD' 89if [ -n "$MPICH_FC" ] ; then 90 MPICH_FC_OLD="$FC" 91 FC="$MPICH_FC" 92 FCname=`echo $FC | sed 's/ /-/g'` 93 if [ -s $sysconfdir/mpifort-$FCname.conf ] ; then 94 . $sysconfdir/mpifort-$FCname.conf 95 fi 96fi 97# Allow a profiling option to be selected through an environment variable 98if [ -n "$MPIFORT_PROFILE" ] ; then 99 profConf=$MPIFORT_PROFILE 100fi 101# 102# ------------------------------------------------------------------------ 103# Argument processing. 104# This is somewhat awkward because of the handling of arguments within 105# the shell. We want to handle arguments that include spaces without 106# loosing the spacing (an alternative would be to use a more powerful 107# scripting language that would allow us to retain the array of values, 108# which the basic (rather than enhanced) Bourne shell does not. 109# 110# Look through the arguments for arguments that indicate compile only. 111# If these are *not* found, add the library options 112# 113linking=yes 114allargs="" 115interlib_deps=yes 116static_mpi=no 117for arg in "$@" ; do 118 # Set addarg to no if this arg should be ignored by the C compiler 119 addarg=yes 120 qarg=$arg 121 case $arg in 122 # ---------------------------------------------------------------- 123 # Compiler options that affect whether we are linking or no 124 -c|-S|-E|-M|-MM) 125 # The compiler links by default 126 linking=no 127 ;; 128 # ---------------------------------------------------------------- 129 # Options that control how we use mpifort (e.g., -show, 130 # -fc=* -config=* 131 -static) 132 interlib_deps=no 133 ;; 134 -static-mpi) 135 interlib_deps=no 136 static_mpi=yes 137 addarg=no 138 ;; 139 -echo) 140 addarg=no 141 set -x 142 ;; 143 -fc=*) 144 FC=`echo A$arg | sed -e 's/A-fc=//g'` 145 addarg=no 146 ;; 147 -fc=*) 148 FC=`echo A$arg | sed -e 's/A-fc=//g'` 149 addarg=no 150 ;; 151 -show) 152 addarg=no 153 Show=echo 154 ;; 155 -config=*) 156 addarg=no 157 FCname=`echo A$arg | sed -e 's/A-config=//g'` 158 if [ -s "$sysconfdir/mpifort-$FCname.conf" ] ; then 159 . "$sysconfdir/mpifort-$FCname.conf" 160 else 161 echo "Configuration file mpifort-$FCname.conf not found" 162 fi 163 ;; 164 -compile-info|-compile_info) 165 # -compile_info included for backward compatibility 166 Show=echo 167 addarg=no 168 ;; 169 -link-info|-link_info) 170 # -link_info included for backward compatibility 171 Show=echo 172 addarg=no 173 ;; 174 -v) 175 # Pass this argument to the compiler as well. 176 echo "mpifort for MPICH version $MPICH_VERSION" 177 # if there is only 1 argument, it must be -v. 178 if [ "$#" -eq "1" ] ; then 179 linking=no 180 fi 181 ;; 182 -profile=*) 183 # Pass the name of a profiling configuration. As 184 # a special case, lib<name>.so or lib<name>.la may be used 185 # if the library is in $libdir 186 profConf=`echo A$arg | sed -e 's/A-profile=//g'` 187 addarg=no 188 # Loading the profConf file is handled below 189 ;; 190 -nativelinking) 191 # Internal option to use native compiler for linking without MPI libraries 192 nativelinking=yes 193 addarg=no 194 ;; 195 -help) 196 NC=`echo "$FC" | sed 's%\/% %g' | awk '{print $NF}' -` 197 if [ -f "$sysconfdir/mpixxx_opts.conf" ] ; then 198 . $sysconfdir/mpixxx_opts.conf 199 echo " -fc=xxx - Reset the native compiler to xxx." 200 else 201 if [ -f "./mpixxx_opts.conf" ] ; then 202 . ./mpixxx_opts.conf 203 echo " -fc=xxx - Reset the native compiler to xxx." 204 fi 205 fi 206 exit 0 207 ;; 208 # ----------------------------------------------------------------- 209 # Other arguments. We are careful to handle arguments with 210 # quotes (we try to quote all arguments in case they include 211 # any spaces) 212 *\"*) 213 qarg="'"$arg"'" 214 case $arg in 215 -D*) 216 cppflags="$cppflags $qarg" 217 ;; 218 esac 219 ;; 220 *\'*) 221 qarg='\"'"$arg"'\"' 222 case $arg in 223 -D*) 224 cppflags="$cppflags $qarg" 225 ;; 226 esac 227 ;; 228 # The following are special args used to handle .F files when the 229 # Fortran compiler itself does not handle these options 230 -I*) 231 cppflags="$cppflags $arg" 232 ;; 233 -D*) 234 cppflags="$cppflags $arg" 235 ;; 236 *.F|*.F90|.fpp|.FPP) 237# If FCCPP is not empty, then we need to do the following: 238# If any input files have the .F or .F90 extension, then 239# If FCCPP = false, then 240# generate an error message and exit 241# Use FCCPP to convert the file from .F to .f, using 242# $TMPDIR/f$$-$count.f as the output file name 243# Replace the input file with this name in the args 244# This is needed only for very broken systems 245# 246 if [ -n "$FCCPP" ] ; then 247 if [ "$FCCPP" = "false" ] ; then 248 echo "This Fortran compiler does not accept .F or .F90 files" 249 exit 1 250 fi 251 addarg=no 252 # Remove and directory names and extension 253 $ext=`expr "$arg" : '.*\(\..*\)'` 254 bfile=`basename $arg $ext` 255 # 256 TMPDIR=${TMPDIR:-/tmp} 257 # Make sure that we use a valid extension for the temp file. 258 tmpfile=$TMPDIR/f$$-$bfile.$FCEXT 259 if $FCCPP $cppflags $arg > $tmpfile ; then 260 # Add this file to the commandline list 261 count=`expr $count + 1` 262 allargs="$allargs $tmpfile" 263 rmfiles="$rmfiles $tmpfile" 264 else 265 echo "Aborting compilation because of failure in preprocessing step" 266 echo "for file $arg ." 267 exit 1 268 fi 269 fi 270 # Otherwise, just accept the argument 271 ;; 272 # - end of special handling for .F files 273 274 *) 275 qarg="'$arg'" 276 ;; 277 278 esac 279 if [ $addarg = yes ] ; then 280 allargs="$allargs $qarg" 281 fi 282done 283 284if [ $# -eq 0 ] ; then 285 echo "Error: Command line argument is needed!" 286 "$0" -help 287 exit 1 288fi 289 290 291# ----------------------------------------------------------------------- 292# Derived variables. These are assembled from variables set from the 293# default, environment, configuration file (if any) and command-line 294# options (if any) 295 296PROFILE_FOO= 297# Handle the case of a profile switch 298if [ -n "$profConf" ] ; then 299 profConffile= 300 if [ -s "$libdir/lib$profConf.a" -o -s "$libdir/lib$profConf.so" ] ; then 301 PROFILE_FOO="-l$profConf" 302 elif [ -s "$sysconfdir/$profConf.conf" ] ; then 303 profConffile="$sysconfdir/$profConf.conf" 304 elif [ -s "$profConf.conf" ] ; then 305 profConffile="$profConf.conf" 306 else 307 echo "Profiling configuration file $profConf.conf not found in $sysconfdir" 308 fi 309 if [ -n "$profConffile" -a -s "$profConffile" ] ; then 310 . $profConffile 311 fi 312fi 313 314# Construct the line to add the include directory (not all compilers 315# use -I, unfortunately) 316if [ -z "${FCINC}" ] ; then 317 # If there is no path, add a link to the mpif.h file. 318 # There *must* be a way to provide the path the any modules (there 319 # may be too many to link) 320 if [ ! -r mpif.h ] ; then 321 #echo "Adding a symbolic link for mpif.h" 322 trap "$Show rm -f mpif.h" 0 323 # This should really be the (related) f77includedir. 324 $Show ln -s ${includedir}/mpif.h mpif.h 325 # Remember to remove this file 326 rmfiles="$rmfiles mpif.h" 327 fi 328 FCINCDIRS= 329else 330 # Normally, FCINC is just -I, but some compilers have used different 331 # command line arguments 332 FCINCDIRS=${FCINC}${includedir} 333fi 334 335# Handle the specification of the directory containing the modules 336if [ -n "$FCMODINCSPEC" ] ; then 337 newarg=`echo A"$FCMODINCSPEC" | \ 338 sed -e 's/^A//' -e 's%<dir>%'"$includedir%g" -e 's/<file>/mpi/g'` 339 FCMODDIRS="$newarg" 340elif [ -n "$FCMODINC" ] ; then 341 FCMODDIRS="${FCMODINC}$modincdir" 342fi 343 344final_fcflags="@MPICH_MPIFORT_FCFLAGS@ @WRAPPER_FCFLAGS@" 345final_ldflags="@MPICH_MPIFORT_LDFLAGS@ @WRAPPER_LDFLAGS@" 346final_libs="@MPICH_MPIFORT_LIBS@" 347if test "@INTERLIB_DEPS@" = "no" -o "${interlib_deps}" = "no" ; then 348 final_ldflags="${final_ldflags} @LDFLAGS@" 349 final_libs="${final_libs} @LIBS@ @WRAPPER_LIBS@" 350fi 351 352# A temporary statement to invoke the compiler 353# Place the -L before any args incase there are any mpi libraries in there. 354# Eventually, we'll want to move this after any non-MPI implementation 355# libraries 356if [ "$linking" = yes ] ; then 357 if [ "$nativelinking" = yes ] ; then 358 $Show $FC $PROFILE_INCPATHS ${final_fcflags} ${final_ldflags} $allargs 359 rc=$? 360 else 361 if [ "$static_mpi" = no ] ; then 362 $Show $FC $PROFILE_INCPATHS ${final_fcflags} ${final_ldflags} "${allargs[@]}" $FCINCDIRS $FCMODDIRS -L$libdir -l@MPIFCLIBNAME@ $PROFILE_PRELIB $PROFILE_FOO ${wrapper_dl_type_flags} -l@MPILIBNAME@ @LPMPILIBNAME@ $PROFILE_POSTLIB ${final_libs} @FC_OTHER_LIBS@ 363 else 364 $Show $FC $PROFILE_INCPATHS ${final_fcflags} ${final_ldflags} "${allargs[@]}" $FCINCDIRS $FCMODDIRS -L$libdir -l@MPIFCLIBNAME@ $PROFILE_PRELIB $PROFILE_FOO ${wrapper_dl_type_flags} $libdir/lib@MPILIBNAME@.a @LPMPILIBNAME@ $PROFILE_POSTLIB ${final_libs} @FC_OTHER_LIBS@ 365 fi 366 rc=$? 367 fi 368else 369 $Show $FC $PROFILE_INCPATHS ${final_fcflags} $allargs $FCINCDIRS $FCMODDIRS 370 rc=$? 371fi 372if [ -n "$rmfiles" ] ; then 373 for file in $rmfiles ; do 374 objfile=`basename $file .f` 375 if [ -s "${objfile}.o" ] ; then 376 # Rename 377 destfile=`echo $objfile | sed -e "s/.*$$-//"` 378 mv -f ${objfile}.o ${destfile}.o 379 fi 380 rm -f $file 381 done 382 rm -f $rmfiles 383fi 384exit $rc 385