1#! /bin/bash 2########################################################################## 3# Author : Yvon.Lafranche@univ-rennes1.fr 4# 5# Installation script of XLiFE++ libraries. 6# 7# XLiFE++ may use other libraries (Umfpack, ARPACK, Lapack, Blas) or 8# third party softwares (Gmsh, Paraview), depending on their presence on 9# the computer. This script performs the installation in an automatic way, 10# without any user action. This means that these libraries or softwares 11# are really used only if they are detected. 12# 13# The installation requires a C++ compiler. The C++ compiler to use can 14# be imposed by the mean of the environment variable CPPCMP before calling 15# this script. 16# The Fortran library is needed if ARPACK is used. Thus, the name of the 17# Fortran compiler, from which is deduced the name of the Fortran library, 18# can also be imposed by the mean of the environment variable FCMP. 19# 20# The installation process conforms to the following rules: 21# 1. if they are not found in the file system, Lapack and Blas are not 22# installed, neither any third party software, 23# 2. the Umfpack and ARPACK libraries present on the system are used first 24# and foremost, 25# 3. if ARPACK has not been found in the system and if a Fortran compiler 26# is available, the ARPACK library is built locally, 27# 4. if Umfpack has not been found in the system, the SuiteSparse libraries 28# are built locally. 29# 30# Some options may be used to alter the default configuration: 31# -noAmo prevents XLiFE++ to use the Amos library, 32# -noArp prevents XLiFE++ to use the ARPACK library, 33# -noOmp prevents XLiFE++ to use OpenMP capabilities, 34# -noUmf prevents XLiFE++ to use the Umfpack (SuiteSparse) libraries. 35# 36# Indeed, in case of trouble, this script can be relaunched with one or 37# more of these options. 38# 39# Calling sequence : bash installLibs [-noAmo] [-noArp] [-noOmp] [-noUmf] 40########################################################################## 41# Check options 42noAmo=0 43noArp=0 44noOmp=0 45noUmf=0 46while [ $# -gt 0 ]; do 47 case $1 in 48 -noAmo) noAmo=1; shift;; 49 -noArp) noArp=1; shift;; 50 -noOmp) noOmp=1; shift;; 51 -noUmf) noUmf=1; shift;; 52 *) echo "*** Warning. Option $1 is unrecognised and ignored." 53 shift;; 54 esac 55done 56# Absolute location of this script 57dirdist=`dirname $0` 58##if [ ${dirdist:0:1} != "/" ]; then ## Inexistant syntax in dash under Ubuntu 59if [ ${dirdist#/} = $dirdist ]; then 60 dirdist=$PWD/$dirdist 61fi 62dirdist=`echo $dirdist |sed -e "s,/\.,,g"` 63# Current installation directory 64dirinst=`dirname $dirdist` 65# Temporary files 66warnMes=/tmp/warnMes$$ 67testerrf=/tmp/temperr$$ 68# Names of expected compilers. The default values can be overidden by the 69# environment variables FCMP or CPPCMP. 70FCMPLR=${FCMP:-gfortran} 71CPPCMPLR=${CPPCMP:-g++} 72#------------------------------------------------------------------------- 73# Functions (in alphabetical order) 74 75# ======== 76checkLd_options () { 77# Calling sequence : checkLd_options 78# Check linkage with LAPACK and BLAS libraries with initial content of ld_options. 79# Try to find the libraries in case of failure, and reset ld_options to a correct 80# value if the libraries are finally found. 81# Moreover, the variable failLink (to be tested after this function returns) 82# is set to 0 in case of success, to 1 if a failure has occured. 83failLink=0 84if [ `testCrExec $ld_options` -eq 0 ]; then 85# Initial ld_options are not correct. Trying to locate BLAS and LAPACK libraries. 86 pathToLapa=`findPathToLib lapack` 87 if [ `testCrExec $pathToLapa -llapack` -eq 0 ]; then failLink=1; printWarnLib LAPACK; fi 88# Depending on the distribution, BLAS library may have different names 89 pathToBlas=`findPathToLib blas` 90 pathTofBla=`findPathToLib f77blas` 91 if [ `testCrExec $pathToBlas -lblas` -eq 0 -a `testCrExec $pathTofBla -lblas` -eq 0 ]; then 92 failLink=1; printWarnLib BLAS 93 fi 94 if [ $failLink -eq 0 ]; then 95 ld_options="$pathToLapa -llapack $pathToBlas $pathTofBla -lblas" 96 else 97 ld_options="" 98 fi 99fi 100} 101 102# ======== 103checkLink () { 104# Calling sequence : checkLink Options 105# Check linkage with given Options 106# Moreover, the variable failLink (to be tested after this function returns) 107# is set to 0 in case of success, to 1 if a failure has occured. 108failLink=0 109if [ `testCrExec $1` -eq 0 ]; then 110 failLink=1 111 printf "%s\n" "** WARNING : linkage with $1 failed." \ 112 " Error message:" \ 113 "= = = = = =" | tee -a $warnMes $logfile 114 cat $testerrf | tee -a $warnMes $logfile 115 printf "%s\n" "= = = = = =" | tee -a $warnMes $logfile 116fi 117} 118 119# ======== 120checkScript () { 121# Calling sequence : checkScript 122# Preliminary test to make sure this script is consistent with the template file. 123# The following variable names should be those used in the template file since 124# they are used in some fonctions defined in this file. 125# Any change in the template file should be propagated in this script. 126# Returned value: sets the variable scriptOK to 0 if a problem is detected, to 1 otherwise. 127scriptOK=1 128varnamelist=(OS_TYPE PREC_TYPE BITS_TYPE STRING_TYPE ARPACK UMFPACK OMP GMSH XLIFEPP_GMSH_EXECUTABLE PARAVIEW XLIFEPP_PARAVIEW_EXECUTABLE EIGEN AMOS) 129nbvar=`grep '${' $dirinst/etc/templates/setup.cmake.hpp | wc -l` 130let nbvar-- 131if [ $nbvar -eq ${#varnamelist[*]} ]; then 132 for var in ${varnamelist[*]} ; do 133 nbvar=`grep {$var} $dirinst/etc/templates/setup.cmake.hpp | wc -l` 134 if [ $nbvar -ne 1 ]; then 135 printWarn "Variable $var not found in template file as expected." 136 scriptOK=0 137 fi 138 done 139# Particular case of INSTALL_PATH whose value depend on a non reliable variable name. 140# Get the name this variable. 141 sourcedir=`grep INSTALL_PATH $dirinst/etc/templates/setup.cmake.hpp | sed -e 's/^.*{//' -e 's/}.*$//'` 142 if [ ${#sourcedir} -eq 0 ]; then 143 printWarn "Variable INSTALL_PATH not found in template file as expected." 144 scriptOK=0 145 fi 146else 147 printWarn "Incorrect number of variables." 148 scriptOK=0 149fi 150} 151printWarn () { 152# Calling sequence : printWarn Mes 153# Print the warning message Mes 154printf "%s\n" "*** $1" \ 155 " This shell-script $0 should be updated. Please inform the author." \ 156 " (template file is: $dirinst/etc/templates/setup.cmake.hpp)" \ 157 "*** Abort." \ 158 | tee -a $warnMes $logfile 159} 160 161# ======== 162checkUmfLink () { 163# Calling sequence : checkUmfLink 164# Check linkage against SuiteSparse libraries if they exist. 165# In this case, initialize the variable umflibs (needs previous intialization of umfdylnk) 166# and update the variable failInq with the value of failLink, which is also relevant. 167if [ $failInq -eq 0 ]; then 168# Umfpack libraries exist: check linkage 169 OK="`$comldd $umflibdir/libumfpack.* | grep metis`" 170 OK="`$comldd $umflibdir/libcholmod.* | grep metis`$OK" 171 if [ ${#OK} -eq 0 ]; then lmetis=""; else lmetis="-lmetis"; fi 172 umflibs="-lumfpack -lcholmod -lamd -lcamd -lcolamd -lccolamd $lmetis -lsuitesparseconfig $umfdylnk" 173 checkLink "-L$umflibdir $umflibs" 174 failInq=$failLink 175 if [ $failLink -eq 1 ]; then 176 printf "\n%s\n" "** Linkage error with SuiteSparse libraries." >> $logfile 177 fi 178fi 179} 180 181# ======== 182configParams () { 183# Calling sequence : configParams INSTALL_DIR 184# Gather the parameters necessary to the configuration file INSTALL_DIR/etc/include/setup.hpp 185# created later by the function crsetup. 186OS_TYPE=OS_IS_UNIX 187INSTALL_PATH=$1 188PREC_TYPE=LONG_TYPES 189BITS_TYPE=64 190STRING_TYPE=STD_STRING 191# 192withORwithout ARPACK $ArpackOk NOASK 193ARPACK=$REPwOw 194# 195withORwithout UMFPACK $UmfpackOk NOASK 196UMFPACK=$REPwOw 197# 198ompOK=0 199if [ $noOmp -eq 0 ]; then 200# Test if the compiler supports OpenMP directives 201testsrcfomp=infileomp$$.c++ 202cat > $testsrcfomp << EOD 203#include <omp.h> 204EOD 205cat $testsrcf >> $testsrcfomp 206ompflag=-fopenmp 207$CPPCMPLR -c $ompflag $testsrcfomp -o /dev/null >/dev/null 2>/dev/null && ompOK=1 208\rm $testsrcfomp 209fi 210if [ $ompOK -eq 0 ]; then ompflag=""; fi 211withORwithout OMP $ompOK NOASK 212OMP=$REPwOw 213# 214dirsToScan="/usr/local/bin \ 215 `ls -d /usr/local/* 2>/dev/null | grep -i gmsh` \ 216 `ls -d /Applications/* 2>/dev/null | grep -i gmsh`" 217locateExtSoft gmsh GMSH "$dirsToScan" "geometry/ioMesh/loadGmsh.cpp term/ioTerm/ioTermVector.cpp" 218GMSH=$REPwOw 219XLIFEPP_GMSH_EXECUTABLE=$softExe 220# 221dirsToScan="/usr/local/bin \ 222 `ls -d /usr/local/* 2>/dev/null | grep -i paraview` \ 223 `ls -d /Applications/* 2>/dev/null | grep -i paraview`" 224locateExtSoft paraview PARAVIEW "$dirsToScan" "term/ioTerm/ioTermVector.cpp" 225PARAVIEW=$REPwOw 226XLIFEPP_PARAVIEW_EXECUTABLE=$softExe 227# 228withORwithout EIGEN 0 NOASK 229EIGEN=$REPwOw 230# 231withORwithout AMOS $AmosOk NOASK 232AMOS=$REPwOw 233} 234 235# ======== 236crLib () { 237# Calling sequence : crLib 238# Compile the source files and create the library. The library is static. 239# Initialization of xlilibs 240dirsrc=${dirinst}/src 241printf "\n%s\n" ">>> Installation of the library..." >> $logfile 242# 243for reper in `ls $dirsrc`; do 244 cd $dirsrc/$reper 245 printf "\n%s\n" "--> Compilation in $dirsrc/$reper" | tee -a $logfile 246 for fic in `find . -name "*.cpp"`; do 247 dirloc=`dirname $fic` 248 fname=`basename $fic` 249 echo "$CPPCMPLR $CPPflags -o $dirlib/${fname%.*}.o $fic" | tee -a $logfile 250 ($CPPCMPLR $CPPflags -o $dirlib/${fname%.*}.o $fic) 2>&1 | tee -a $logfile 251 done 252 if [ `ls $dirlib/*.o 2>/dev/null | wc -c` -eq 0 ]; then 253 echo " Nothing to compile, nothing to add to library." | tee -a $logfile 254 else 255 (ar r $dirlib/libxlifepp.a $dirlib/*.o 256 rm -f $dirlib/*.o 257 ) 2>&1 | tee -a $logfile 258 echo " Files in $dirsrc/$reper compiled." | tee -a $logfile 259 fi 260done 261ranlib $dirlib/libxlifepp.a 262xlilibs="-lxlifepp" 263printf " done." >> $logfile 264} 265 266# ======== 267crsetup () { 268# Calling sequence : crsetup 269# Create the configuration file INSTALL_PATH/etc/include/setup.hpp 270# using the parameters initialized by the function configParams. 271printf "\n%s\n" "Create setup file." | tee -a $logfile 272crsetupsh=/tmp/crsetup$$ 273cp /dev/null $crsetupsh 274for var in ${varnamelist[*]} ; do 275 echo "$var=${!var}" >> $crsetupsh 276done 277echo "$sourcedir=${INSTALL_PATH}" >> $crsetupsh 278echo "mkdir -p ${INSTALL_PATH}/etc/include" >> $crsetupsh 279echo "cat > ${INSTALL_PATH}/etc/include/setup.hpp << EOD" >> $crsetupsh 280cat ${INSTALL_PATH}/etc/templates/setup.cmake.hpp >> $crsetupsh 281echo "EOD" >> $crsetupsh 282sh $crsetupsh 283\rm $crsetupsh 284} 285 286# ======== 287crXLiMk () { 288# Calling sequence : crXLiMk 289# Create a Bourne shell script that can be used to create an executable file using XLiFE++. 290shscr=$dirinst/etc/xlmake 291printf "\n%s\n" "Create shell-script to use XLiFE++ $shscr" | tee -a $logfile 292cat > $shscr << EOD 293#! /bin/sh 294# 295# Script that creates an executable file using XLiFE++. 296# Usage: 297# Change to the directory containing the source files and enter the command: 298# sh $shscr 299# 300# Alternatively, you can make a link in this directory: 301# ln -s $shscr . 302# and then enter the command: 303# `basename $shscr` 304 305XLI_INST_DIR=$dirinst 306if [ ! -d \$XLI_INST_DIR ]; then 307 echo "*** XLiFE++ installation directory not found. Abort." 308 echo " Check XLI_INST_DIR variable in \$0." 309 exit 310fi 311 312ARP_INC_OPS="$arpincops" 313UMF_INC_OPS="$umfincops" 314XLI_INC_OPS="$xliincops" 315LD_OPTIONS="$ld_options" 316AMO_LIB_DIR="$amolibdir" 317ARP_LIB_DIR="$arplibdir" 318UMF_LIB_DIR="$umflibdir" 319XLI_LIB_DIR="$dirlib" 320FTN_LIB_DIR="$ftnlibdir" 321AMO_LIBS="$amolibs" 322ARP_LIBS="$arplibs" 323UMF_LIBS="$umflibs" 324XLI_LIBS="$xlilibs" 325XLI_FLAGS="$xliflags" 326 327XFILE=xlifeppexec 328CPPCMP=$CPPCMPLR 329EOD 330# For the end of the script, it is easier to deactivate metacharacter interpretation. 331cat >> $shscr << \EOD 332CPPflags="$XLI_FLAGS $XLI_INC_OPS $UMF_INC_OPS $ARP_INC_OPS" 333 334srcfiles=`ls *.c++ *.cpp *.cc *.C *.cxx 2>/dev/null` 335if [ -f $XFILE ]; then \rm $XFILE; fi 336$CPPCMP $CPPflags $srcfiles -o $XFILE -L$XLI_LIB_DIR $XLI_LIBS -L$UMF_LIB_DIR $UMF_LIBS -L$ARP_LIB_DIR -L$FTN_LIB_DIR $ARP_LIBS -L$AMO_LIB_DIR $AMO_LIBS $LD_OPTIONS 337if [ -x $XFILE ]; then 338 echo " XLiFE++ executable file created: $XFILE" 339fi 340EOD 341chmod a+rx $shscr 342} 343 344# ======== 345crXLiUp () { 346# Calling sequence : crXLiUp 347# Create a Bourne shell script that can be used to update the library of XLiFE++. 348shscr=$dirinst/etc/updateLib 349cat > $shscr << EOD 350#! /bin/sh 351# 352# Script allowing to update the library of XLiFE++. 353# The arguments should be a list of files, separated by a space, each of them given by 354# their pathname relative to the directory $dirinst/src, e.g. term/ioTerm/ioTermVector.cpp. 355# Usage: 356# sh $shscr Files 357# 358 359XLI_INST_DIR=$dirinst 360if [ ! -d \$XLI_INST_DIR ]; then 361 echo "*** XLiFE++ installation directory not found. Abort." 362 echo " Check XLI_INST_DIR variable in \$0." 363 exit 364fi 365 366ARP_INC_OPS="$arpincops" 367UMF_INC_OPS="$umfincops" 368XLI_INC_OPS="$xliincops" 369XLI_LIB_DIR="$dirlib" 370XLI_FLAGS="$xliflags" 371CPPCMP=$CPPCMPLR 372EOD 373# For the end of the script, it is easier to deactivate metacharacter interpretation. 374cat >> $shscr << \EOD 375CPPflags="-c $XLI_FLAGS $XLI_INC_OPS $UMF_INC_OPS $ARP_INC_OPS" 376 377libTOupdate=$XLI_LIB_DIR/libxlifepp.a 378for fic in $*; do 379 reper=`echo $fic | cut -d/ -f1` 380 if [ -d $XLI_INST_DIR/src/$reper ]; then 381 fname=`basename $fic` 382 srcfile=$XLI_INST_DIR/src/$fic 383 if [ -f $srcfile ]; then 384 $CPPCMP $CPPflags $srcfile -o $XLI_LIB_DIR/${fname%.*}.o 385 ar r $libTOupdate $XLI_LIB_DIR/*.o 386 rm -f $XLI_LIB_DIR/*.o 387 echo "Library $libTOupdate updated." 388 else 389 echo "** File $srcfile does not exist. Argument ignored." 390 fi 391 else 392 echo "** Directory $XLI_INST_DIR/src/$reper does not exist. Argument ignored." 393 fi 394done 395ranlib $libTOupdate 396EOD 397chmod a+rx $shscr 398} 399 400# ======== 401findPathToInc () { 402# Calling sequence : findPathToInc Name 403# Return the absolute pathname of the file Name if found, nothing otherwise. 404# Several commands are tried successively ; the result obtained by the first 405# successful search is returned. 406# - - - - - 407# 1. Try with find, if available 408 OK=0 409 which find >/dev/null 2>/dev/null && OK=1 410 if [ $OK -eq 1 ]; then 411 pathsToSearch=(/usr/include /usr/local) # /opt ? 412 for reper in ${pathsToSearch[*]}; do 413 path=`searchInPath $reper $1` 414 if [ "X$path" != "X" ]; then break; fi 415 done 416 path=`getDirName "$path"` 417 fi 418# - - - - - 419if [ "X$path" = "X" ]; then 420# 2. Try with locate, if available 421 OK=0 422 locate -S >/dev/null 2>/dev/null && OK=1 423# The database exists, but not necessarily up to date. 424 if [ $OK -eq 1 ]; then 425 path=`locate $1` 426 path=`getDirName "$path"` 427 fi 428fi 429printf "$path" 430} 431 432# ======== 433findPathToLib () { 434# Calling sequence : findPathToLib Name 435# Return the absolute pathname of the library libName.* if found, nothing otherwise. 436# The library found may either be a static or a dynamic library. Several commands 437# are tried successively (ldconfig, locate, find) ; the result obtained by the first 438# successful search is returned. 439# - - - - - 440# 1. Try with ldconfig, if available (search for a dynamic library under Unix) 441OK=0 442which /sbin/ldconfig >/dev/null 2>/dev/null && OK=1 443if [ $OK -eq 1 ]; then 444# To be used on Linux-like system only. 445# We should get .../lib$1.so if it exists, .../lib$1.so.n otherwise 446 path=`/sbin/ldconfig -p | grep lib$1 | cut -d\> -f2 | sort | head -1` 447fi 448# - - - - - 449if [ "X$path" = "X" ]; then 450# 2. Try with locate, if available 451 OK=0 452 locate -S >/dev/null 2>/dev/null && OK=1 453# The database exists, but not necessarily up to date. 454 if [ $OK -eq 1 ]; then 455 path=`locate lib$1.` 456 path=`getDirName "$path"` 457 fi 458else 459# Get dirname from ldconfig result 460 path=`dirname $path` 461fi 462# - - - - - 463if [ "X$path" = "X" ]; then 464# 3. Try with find, if available 465 OK=0 466 which find >/dev/null 2>/dev/null && OK=1 467 if [ $OK -eq 1 ]; then 468 pathsToSearch=(/lib64 /usr/lib64 /lib /usr/lib /usr/local/lib /usr/local) # /opt ? 469 for reper in ${pathsToSearch[*]}; do 470 path=`searchInPath $reper "lib$1.*"` 471 if [ "X$path" != "X" ]; then break; fi 472 done 473 path=`getDirName "$path"` 474 fi 475fi 476printf "$path" 477} 478 479# ======== 480getDirName () { 481# Calling sequence : getDirName listOfPaths 482# Select a directory name among the given listOfPaths. 483# The directory part of the path (dirname) is selected in such a way that it is 484# at the highest level in the file hierarchy, among the possibilities derived 485# from the given listOfPaths, leading presumably to the least specific choice, which 486# is the most convenient one, owing to the context in which this function is called 487# (namely locating a file in a part of the file system). 488# If there are several such candidates, the first in the list is arbitrarily 489# selected, given that they are alphabetically sorted. 490 (for fic in $1; do 491 reper=`dirname $fic` 492 reperws=`echo $reper | sed -e "s,/,,g"` 493 let n="${#reper} - ${#reperws}" 494 printf "%s:%s\n" "$n" "$reper" 495 done) | sort -n | head -1 | cut -d : -f2 496} 497 498# ======== 499initExtLibPaths () { 500# Calling sequence : initExtLibPaths 501# Sets various variables related to external libraries 502 503# Look for Fortran library and compiler (needed for Arpack and Amos) 504inquireFortran 505# 506inquireAmos 507if [ $failInq -eq 1 ]; then AmosOk=0; else AmosOk=1; fi 508inquireArpack 509if [ $failInq -eq 1 ]; then ArpackOk=0; else ArpackOk=1; fi 510inquireUmfpack 511if [ $failInq -eq 1 ]; then UmfpackOk=0; else UmfpackOk=1; fi 512# 513if [[ $ArpackOk -eq 1 || $UmfpackOk -eq 1 ]]; then 514# Linker options to be used related to BLAS and LAPACK 515 case $theOS in 516 # MacOS X 517 Darwin) 518 ld_options="-framework Accelerate" ;; 519 # Other systems (Linux,...) 520 *) 521 ld_options="-llapack -lblas" ;; 522 esac 523 checkLd_options 524 if [ $failLink -eq 1 ]; then 525 # None of the packages can be used: disable them 526 ArpackOk=0 527 UmfpackOk=0 528 fi 529else 530 ld_options="" 531fi 532} 533 534# ======== 535inquireAmos () { 536# Calling sequence : inquireAmos 537# Initialization of: 538# - the directory containing the Amos library (amolibdir), 539# - the list of libraries needed (amolibs). 540# These variables are set to a neutral value in case of failure. 541# Moreover, the variable failInq (to be tested after this function returns) 542# is set to 0 in case of success, to 1 if a failure has occured. 543failInq=0 544if [ $noAmo -eq 1 ]; then 545 echo "-> Amos not used." >> $logfile 546 amolibdir="." 547 amolibs="" 548 failInq=1 549 return 550fi 551if [ "$ftnlibdir" = "." ]; then 552 failInq=1 553else 554 if [ $FCMPLRok -eq 1 ]; then 555 installAmos 556 # Fortran and Amos libraries exist: check linkage 557 amolibs="-lamos -l$FCMPLR" 558 checkLink "-L$amolibdir -L$ftnlibdir $amolibs" 559 failInq=$failLink 560 if [ $failLink -eq 1 ]; then 561 printf "\n%s\n" "** Linkage error with Amos library." >> $logfile 562 fi 563 else 564 failInq=1 565 fi 566fi 567if [ $failInq -eq 1 ]; then 568 printf "%s\n" " Package Amos will not be used." >> $logfile 569 # Reset to neutral value in case of failure: 570 amolibdir="." 571 amolibs="" 572fi 573} 574 575# ======== 576inquireArpack () { 577# Calling sequence : inquireArpack 578# Initialization of: 579# - the compiler option for Arpack++ (arpincops) 580# - the directory containing the ARPACK library (arplibdir), 581# - the list of libraries needed (arplibs). 582# These variables are set to a neutral value in case of failure. 583# Moreover, the variable failInq (to be tested after this function returns) 584# is set to 0 in case of success, to 1 if a failure has occured. 585failInq=0 586if [ $noArp -eq 1 ]; then 587 echo "-> ARPACK not used." >> $logfile 588 arpincops="" 589 arplibdir="." 590 arplibs="" 591 failInq=1 592 return 593fi 594if [ "$ftnlibdir" = "." ]; then 595 failInq=1 596else 597 # Fortran library found: look for ARPACK library 598 arplibdir=`findPathToLib arpack` 599 if [ "X$arplibdir" = "X" ]; then 600 # No ARPACK library found: install one if the Fortran compiler is available 601 printf "\n%s\n" "** No ARPACK library found." >> $logfile 602 if [ $FCMPLRok -eq 1 ]; then 603 installArpack 604 failInq=$failIns 605 else 606 failInq=1 607 fi 608 else 609 echo "-> ARPACK library found in $arplibdir." | tee -a $logfile 610 fi 611 if [ $failInq -eq 0 ]; then 612 # Include files for Arpack++ 613 arpincops="-I$dirinst/ext/ARPACK++/include" 614 # Fortran and ARPACK libraries exist: check linkage 615 arplibs="-larpack -l$FCMPLR" 616 checkLink "-L$arplibdir -L$ftnlibdir $arplibs" 617 failInq=$failLink 618 if [ $failLink -eq 1 ]; then 619 printf "\n%s\n" "** Linkage error with ARPACK library." >> $logfile 620 fi 621 fi 622fi 623if [ $failInq -eq 1 ]; then 624 printf "%s\n" " Package ARPACK will not be used." >> $logfile 625 # Reset to neutral value in case of failure: 626 arpincops="" 627 arplibdir="." 628 arplibs="" 629fi 630} 631 632# ======== 633inquireFortran () { 634# Calling sequence : inquireFortran 635# Initialization of the directory ftnlibdir containing the Fortran library. 636# If the directory is not found, ftnlibdir is set to ".". 637# The variable FCMPLRok is also set to 1 if the Fortran compiler is available, 0 otherwise. 638# Take note that the library may exist though there is no compiler. 639 640FCMPLRok=0 641ftnlibdir="." 642if [[ $noAmo -eq 1 && $noArp -eq 1 ]]; then return; fi 643# 644# Check if the Fortran compiler is available 645$FCMPLR -v >/dev/null 2>/dev/null && FCMPLRok=1 646if [ $FCMPLRok -eq 0 ]; then 647 printf "\n%s\n" "** No $FCMPLR compiler available." >> $logfile 648else 649 # Flag to insure compatibility with BLAS and LAPACK system libraries 650 # under MacOS X which use g77 calling conventions 651 if [ $theOS = "Darwin" ]; then compatflag="-ff2c"; else compatflag=""; fi 652fi 653# Locate Fortran library 654ftnlibdir=`findPathToLib $FCMPLR` 655if [ "X$ftnlibdir" = "X" ]; then 656 ftnlibdir="." 657# Fortran library not found: try from compiler information if available 658 if [ $FCMPLRok -eq 1 ]; then 659# Look for a directory containing either a static or a dynamic fortran library 660 listext=(a so dylib) 661 for ext in ${listext}; do 662 ftnlibdir=`$FCMPLR -print-file-name=lib${FCMPLR}.$ext` 663 ftnlibdir=`dirname $ftnlibdir` 664 if [ "$ftnlibdir" != "." ]; then break; fi 665 done 666 fi 667fi 668if [ "$ftnlibdir" = "." ]; then 669 printf "\n%s\n" "** No Fortran library found." >> $logfile 670else 671 echo "-> Fortran library found in $ftnlibdir." >> $logfile 672fi 673} 674 675# ======== 676inquireUmfpack () { 677# Calling sequence : inquireUmfpack 678# Initialization of: 679# - the directory containing SuiteSparse include files (umfincops), 680# - the directory containing SuiteSparse libraries (umflibdir), 681# - the list of libraries needed (umflibs). 682# These variables are set to a neutral value in case of failure. 683# Moreover, the variable failInq (to be tested after this function returns) 684# is set to 0 in case of success, to 1 if a failure has occured. 685failInq=0 686if [ $noUmf -eq 1 ]; then 687 echo "-> Umfpack (SuiteSparse) not used." >> $logfile 688 umflibdir="." 689 umfincops="" 690 umflibs="" 691 failInq=1 692 return 693fi 694# Look for include file 695umfincops=`findPathToInc umfpack.h` 696if [ "X$umfincops" = "X" ]; then 697 # Include file not found 698 printf "\n%s\n" "** Umfpack include file not found." >> $logfile 699 failInq=1 700else 701 # Include file found 702 umfincops="-I$umfincops" 703 # Look for Umfpack libraries 704 umflibdir=`findPathToLib umfpack` 705 if [ "X$umflibdir" = "X" ]; then 706 printf "\n%s\n" "** No Umfpack library found." >> $logfile 707 failInq=1 708 else 709 echo "-> Umfpack library found in $umflibdir." | tee -a $logfile 710 fi 711fi 712# 713if [ $theOS = "Darwin" ]; then comldd="otool -L"; else comldd="ldd"; fi 714umfdylnk="" 715checkUmfLink 716# 717if [ $failInq -eq 1 ]; then 718 printf "\n%s\n" "** No Umfpack library found, or found but not functional." >> $logfile 719 installUmfpack 720 failInq=$failIns 721 checkUmfLink 722fi 723# 724if [ $failInq -eq 1 ]; then 725 printf "%s\n" " Package SuiteSparse will not be used." >> $logfile 726 # Reset to neutral value in case of failure: 727 umflibdir="." 728 umfincops="" 729 umflibs="" 730fi 731} 732 733# ======== 734installAmos () { 735# Calling sequence : installAmos 736# Creation of the Amos Fortran library from the source files contained in the 737# distribution archive of XLiFE++. 738# This function also sets the variable amolibdir. 739# If the library is not installed, amolibdir is set to ".", which will cause 740# an error caught later. 741amolibdir=`find $dirinst/ext -name cairy.f` 742amolibdir=`dirname $amolibdir 2>/dev/null` 743if [[ ! -d $amolibdir ]]; then 744 printf "%s\n" "*** Directory \"$amolibdir\" unexpectedly not found." \ 745 " Please inform the authors." \ 746 | tee -a $warnMes $logfile 747 amolibdir="." 748 return 749fi 750# Create Amos library 751printf "%s\n" "Building local Amos library" | tee -a $logfile 752(cd $amolibdir 753 $FCMPLR -c $compatflag *.f 754 libName=amos 755 ar r lib$libName.a *.o 756 \rm *.o 757 ranlib lib$libName.a 758 chmod a+r lib$libName.a 759) 2>&1 | tee -a $logfile 760printf "%s\n" "End of building local Amos library" | tee -a $logfile 761} 762 763# ======== 764installArpack () { 765# Calling sequence : installArpack 766# Creation of the ARPACK Fortran library from the source files contained in the 767# distribution archive of XLiFE++. 768# The variable failIns (to be tested after this function returns) is set to 0 if the 769# library is installed, in which case this function also sets the variable arplibdir. 770# The variable failIns is set to 1 if the library is not installed. 771failIns=0 772dirutil=`find $dirinst/ext -name second.f` 773dirutil=`dirname $dirutil 2>/dev/null` 774dirsrc=`find $dirinst/ext -name dneupd.f` 775dirsrc=`dirname $dirsrc 2>/dev/null` 776if [[ ! ( -d $dirutil && -d $dirsrc ) ]]; then 777 printf "%s\n" "*** Directory \"$dirutil\" or \"$dirsrc\" unexpectedly not found." \ 778 " Please inform the authors." \ 779 | tee -a $warnMes $logfile 780 failIns=1 781 return 782fi 783# 784printf "%s\n" "Building local ARPACK library." | tee -a $logfile 785arplibdir=`dirname $dirsrc`/lib 786mkdir -p $arplibdir 787chmod a+rx $arplibdir 788(cd $arplibdir 789if [ $FCMPLR != gfortran ]; then 790 cp $dirutil/second.f $arplibdir 791 printf "%s\n" \ 792 "** WARNING: $FCMPLR compiler used. Check whether ETIME is INTRINSIC" \ 793 " or EXTERNAL and update $dirutil/second.f accordingly." \ 794 " We assume ETIME is EXTERNAL and continue." \ 795 | tee -a $warnMes 796else 797 (sed -e '/EXTERNAL/{s/EXTERNAL// 798 a\ 799\ INTRINSIC ETIME 800 }' $dirutil/second.f > $arplibdir/second.f 801 ) 2>&1 | tee -a $warnMes 802fi 803$FCMPLR -c $compatflag second.f 804$FCMPLR -c $compatflag `ls $dirutil/*.f | grep -v second` 805$FCMPLR -c $compatflag `ls $dirsrc/*.f | grep -v naupe` 806libName=arpack 807ar r lib$libName.a *.o 808\rm second.f *.o 809ranlib lib$libName.a 810chmod a+r lib$libName.a 811) 2>&1 | tee -a $logfile 812printf "%s\n" "End of building local ARPACK library." | tee -a $logfile 813} 814 815# ======== 816installUmfpack () { 817# Calling sequence : installUmfpack 818# Creation of the Umfpack libraries (SuiteSparse) from the source files contained 819# in the distribution archive of XLiFE++. 820# The variable failIns (to be tested after this function returns) is set to 0 if 821# the libraries are installed, in which case this function also sets the variables 822# umfincops, umflibdir and umfdylnk. 823# The variable failIns is set to 1 if the libraries are not installed. 824failIns=0 825SuiteSppkg=`ls $dirinst/ext/SuiteSparse*tar* 2>/dev/null` 826if [ ${#SuiteSppkg} -eq 0 ]; then 827 printf "%s\n" "*** SuiteSparse archive unexpectedly not found." \ 828 " Please inform the authors." \ 829 | tee -a $warnMes $logfile 830 failIns=1 831 return 832fi 833printf "%s\n" "Building local Umfpack libraries (SuiteSparse)." | tee -a $logfile 834tar xf $SuiteSppkg -C $dirinst/ext 835SuiteSpDir=`find $dirinst/ext -name UMFPACK` 836SuiteSpDir=`dirname $SuiteSpDir` 837umflibdir=$SuiteSpDir/lib 838umfincops="-I$SuiteSpDir/include" 839(cd $SuiteSpDir 840 make library 841 chmod a+rx $umflibdir $SuiteSpDir/include 842 chmod a+r $umflibdir/* $SuiteSpDir/include/* 843) 2>&1 | tee -a $logfile 844umfdylnk="" 845if [ $theOS = "Linux" ]; then 846# SuiteSparse libraries are dynamic: insure they are found at run time (unuseful for MacOS X). 847 umfdylnk="$umfdylnk -Wl,-rpath,$umflibdir" 848fi 849printf "%s\n" "End of building local Umfpack libraries (SuiteSparse)." | tee -a $logfile 850} 851 852# ======== 853locateExtSoft () { 854# Calling sequence : locateExtSoft Software IDENT Dirs XLFiles 855# Try to find Software firstly in user's path, secondly in Dirs. 856# IDENT is the macro name in the setup file. 857# XLFiles are the source files in XLiFE++ that depend on the configuration of this Software. 858# Returns absolute pathname found in softExe (may be empty) and initialize IDENT accordingly. 859 860# 1. Try with which in user's path 861softExe=`which $1 2>/dev/null` 862softFound=1 863if [ "X$softExe" = "X" ]; then 864# 2. Not found: try with find in Dirs 865 for reper in $3; do 866 softExe=`searchInPath $reper $1` 867 if [ "X$softExe" != "X" ]; then 868 echo "-> $1 found ($softExe)" | tee -a $logfile 869 break 870 fi 871 done 872 if [ "X$softExe" = "X" ]; then 873 printf "%s\n" "** WARNING: $1 not found, thus XLiFE++ will not use it." \ 874 " This may not be a problem, since XLiFE++ can however be used without $1." \ 875 " This can be manually changed by setting the macros containing $2 in the file:" \ 876 " ${INSTALL_PATH}/etc/include/setup.hpp" \ 877 " This will then need to update the XLiFE++ library by typing in a terminal:" \ 878 " $dirinst/etc/updateLib $4" | tee -a $warnMes 879 softFound=0 880 fi 881else 882 echo "-> $1 found ($softExe)" | tee -a $logfile 883fi 884withORwithout $2 $softFound NOASK 885} 886 887# ======== 888printWarnLib () { 889# Calling sequence : printWarnLib Lib 890printf "%s\n" "** WARNING : $1 library not found." \ 891 " Shell $dirinst/etc/xlmake will be incorrect (check LD_OPTIONS or xxx_LIB_DIR)." \ 892 " Continue installation however." | tee -a $warnMes 893} 894 895# ======== 896searchInPath () { 897# Calling sequence : searchInPath Path Name 898# Search for Name in Path using find. 899# The search is restricted to find a regular file or a symbolic link. 900if [ -d $1 ]; then 901 find $1 \( -type f -or -type l \) -name "$2" -print 2>/dev/null 902fi 903} 904 905# ======== 906testCrExec () { 907# Calling sequence : testCrExec LibArgs 908# Returns 1 if LibArgs are successfully used, 0 otherwise 909 testoutf=/tmp/tempout$$ 910 $CPPCMPLR $testsrcf $* -o $testoutf > $testerrf 2>&1 911# If a library in $* is not found or $* is empty, the executable file is not created. 912 if [ -e $testoutf ]; then 913 \rm $testoutf 914 printf "1" 915 else 916 printf "0" 917 fi 918} 919 920# ======== 921withORwithout () { 922# Calling sequence : withORwithout NAME DEFAULT ASK 923# If the third parameter is ASK, this function asks for a choice about NAME 924# else the question is not asked and the DEFAULT choice is made. 925# Returns the corresponding parameter value in REPwOw 926if [ "$3" = "ASK" ]; then 927 read -p "With (1) or without (0) $1 [default=0] : " rep 928else 929 rep=$2 930fi 931case $rep in 932 1) REPwOw=XLIFEPP_WITH_$1 ;; 933 *) REPwOw=XLIFEPP_WITHOUT_$1 ;; 934esac 935} 936 937#------------------------------------------------------------------------- 938# Preliminary tests and settings 939for compil in $CPPCMPLR; do 940 OK=0 941 $compil -v >/dev/null 2>/dev/null && OK=1 942 if [ $OK -eq 0 ]; then 943 echo "*** $compil compiler not found (required for the installation)." 944 echo "*** Abort." 945 exit 946 fi 947done 948# 949echo "Installation directory : $dirinst" 950# 951# Directory containing the library. This directory may already exist. 952# We need write access on $dirinst and $dirlib. 953dirlib=$dirinst/lib 954OK=0 955mkdir -p $dirlib && OK=1 956if [ $OK -eq 0 -o ! -w $dirlib ]; then 957 echo "*** Insufficient access rigths on $dirinst or $dirlib." 958 echo "*** Abort." 959 exit 960fi 961chmod a+rx $dirlib 962#------------------------------------------------------------------------- 963# Installation steps 964# 965# Log file of the installation process 966logfile=$dirinst/`basename $0`.log 967echo "--- `date`" > $logfile 968echo `uname -a` >> $logfile 969 970checkScript 971if [ $scriptOK -eq 1 ]; then 972 printf "\nLooking for libraries and softwares...\n" | tee -a $logfile 973# Create test source file 974 testsrcf=infile$$.c++ 975 cat > $testsrcf << EOD 976 int main(){} 977EOD 978# Initilization of pathnames to external libraries if they are found 979 theOS=`uname` 980 initExtLibPaths 981# Initilization of configuration parameters of XLiFE++ 982 configParams $dirinst 983 \rm -f $testsrcf 984 printf " done.\n" | tee -a $logfile 985# Create configuration file 986 crsetup 987 988 printf "\n%s\n" " C++ compiler version:" >> $logfile 989 $CPPCMPLR -v >> $logfile 2>&1 990 xliincops="-I$dirinst/etc/include -I$dirinst/include -I$dirinst/src" 991 xliflags="$ompflag -O3 -std=c++11" 992 CPPflags="-c $xliflags $xliincops $umfincops $arpincops" 993 printf "\n%s\n" " C++ compiler options used: $CPPflags" >> $logfile 994 995# Create the library 996 crLib 997 998# Create shell-script to make executables from XLiFE++. 999 crXLiMk 1000# Create shell-script to update library of XLiFE++. 1001 crXLiUp 1002fi 1003# 1004# End 1005# --- 1006echo "Terminated." | tee -a $logfile 1007if [ -s $warnMes ]; then 1008 echo "" | tee -a $logfile 1009 printf "%s\n" "-> Some problems have been encountered ; depending on their nature," \ 1010 " they are best to be fixed before trying to use the library." \ 1011 " Recall of warning messages previously printed:" \ 1012 "----------" | tee -a $logfile 1013 cat $warnMes | tee -a $logfile 1014 echo "----------" | tee -a $logfile 1015fi 1016rm -f $warnMes $testerrf 1017echo "--- `date`" >> $logfile 1018echo "End of log file." >> $logfile 1019printf "\n%s\n" "Please check installation log file $logfile." 1020# End of file 1021