diff --git a/arch/build_arch-auto.sh b/arch/build_arch-auto.sh new file mode 100755 index 0000000000000000000000000000000000000000..0ce9a56862b519e5922f1a6c06758053cc2c4264 --- /dev/null +++ b/arch/build_arch-auto.sh @@ -0,0 +1,587 @@ +#!/bin/bash +# +set -u +# +#- Choice of the options --- +# +while [ $# -gt 0 ] +do + case $( echo $1 | tr '[:upper:]' '[:lower:]' ) in + -h|--help) cat <<'EOF' + +Usage: +------ +./build_arch-auto.sh + + +build_arch-auto.sh should automatically find all necessary information by itself... +However the following environment variables or their corresponding optional arguments can be used +to force the default and automatic definition of the variables used by build_arch-auto.sh + +Environment variables that can be defined +----------------------------------------- + + NETCDF_C_prefix : prefix of the NetCDF-C library ($NCDF_F_PREFIX/lib) and include ($NCDF_C_PREFIX/include) + - set it to "no" if you don't want to use NetCDF library + - if not defined : we look for the path of the command "nc-config" + Can also be specified with the optional argument --NETCDF_C_prefix + + NETCDF_F_prefix : prefix of the NetCDF-Fortran library ($NCDF_F_PREFIX/lib) and include ($NCDF_F_PREFIX/include) + - if not defined : we use "nc-config --flibs" to find it + - not used if NETCDF_C_prefix="no" + Can also be specified with the optional argument --NETCDF_F_prefix + + HDF5_prefix : prefix of the HFD5 library ($HDF5_PREFIX/lib) + - if not defined : we use "nc-config --cflags" and "h5pcc -showconfig" to find it + - not used if NETCDF_C_prefix="no" + Can also be specified with the optional argument --HDF5_prefix + + XIOS_prefix : prefix of the XIOS library ($XIOS_PREFIX/lib) and include ($XIOS_PREFIX/inc) + Can also be specified with the optional argument --XIOS_prefix + + OASIS_prefix : prefix of the OASIS library ($OASIS_PREFIX/lib) and + include ($OASIS_PREFIX/build/lib/mct and $OASIS_PREFIX/build/lib/psmile.MPI1) + Can also be specified with the optional argument --OASIS_prefix + + LIBMpath : path of the m library (standard C library of basic mathematical functions) + Can also be specified with the optional argument --LIBMpath + + CURLpath : path of the curl library + Can also be specified with the optional argument --CURLpath + + ZLIBpath : path of the z library + Can also be specified with the optional argument --ZLIBpath + + FCnemo : fortran compiler + Can also be specified with the optional argument --FCnemo + + CCnemo : C compiler (used only for AGRIF conv) + Can also be specified with the optional argument --CCnemo + + CPPnemo : cpp compiler + Can also be specified with the optional argument --CPPnemo + + MKnemo : make + Can also be specified with the optional argument --MKnemo + + ARnemo : archiver + Can also be specified with the optional argument --ARnemo + +EOF + exit 0 ;; + + --netcdf_c_prefix) NETCDF_C_prefix=${2} ; shift ;; + --netcdf_f_prefix) NETCDF_F_prefix=${2} ; shift ;; + --hdf5_prefix) HDF5_prefix=${2} ; shift ;; + --xios_prefix) XIOS_prefix=${2} ; shift ;; + --oasis_prefix) OASIS_prefix=${2} ; shift ;; + --libmpath) LIBMpath=${2} ; shift ;; + --curlpath) CURLpath=${2} ; shift ;; + --zlibpath) ZLIBpath=${2} ; shift ;; + --fcnemo) FCnemo=${2} ; shift ;; + --ccnemo) CCnemo=${2} ; shift ;; + --cppnemo) CPPnemo=${2} ; shift ;; + --mknemo) MKnemo=${2} ; shift ;; + --arnemo) ARnemo=${2} ; shift ;; + + *) echo -e "\033[0;31m\nERROR: \"$1\" BAD OPTION\033[0m\n" + exit 2 ;; + esac + + shift +done +# +#----------------------------------------------------- +# +echo_red () { + echo + while [ $# -gt 0 ] ; do echo -e "\033[0;31m$1\033[0m" ; shift ; done +} + +echo_green () { + echo + while [ $# -gt 0 ] ; do echo -e "\033[0;32m$1\033[0m" ; shift ; done +} +# +echo_orange () { + echo + while [ $# -gt 0 ] ; do echo -e "\033[0;33m$1\033[0m" ; shift ; done +} +# +# check the exit status of which +err_which () { which ${1} > /dev/null 2>&1 ; echo $? ; } +# +# call err_which and print and error message +chk_which () { + if [ $( err_which ${!1} ) -ne 0 ] + then + echo_red "ERROR: ${2^} ${!1} not found." \ + " please define your ${2,} path with 'export $1=...'" + exit 1 + fi +} +# +# find fortran wrapper +find_fortran_wrapper () { + if [ $( err_which mpiifort ) -eq 0 ] ; then FCnemo=mpiifort + elif [ $( err_which mpif90 ) -eq 0 ] ; then FCnemo=mpif90 + elif [ $( err_which ftn ) -eq 0 ] ; then FCnemo=ftn + else + echo_red "ERROR: we found neither \"mpiifort\" nor \"mpif90\" nor \"ftn\"." \ + " please define your fortran compiler path with 'export FCnemo=...'" + exit 1 + fi +} +# find the fortran compiler associated with the fortran wrapper $FCnemo +find_fortran_compiler () { + if [ $( $FCnemo --version | head -n 1 | grep -ci gcc ) -eq 1 ] ; then ftncomp="gnu" + elif [ $( $FCnemo --version | head -n 1 | grep -ci ifort ) -eq 1 ] ; then ftncomp="intel" + elif [ $( $FCnemo --version | head -n 1 | grep -ci "Cray Fortran" ) -eq 1 ] ; then ftncomp="cray" + else + echo_red "ERROR: the fortran wrapper $FCnemo does not correspond to the gnu, the intel or the cray compiler" \ + " please use one of these compilers or add your compiler in $0" + exit 1 + fi +} +# +#----------------------------------------------------- +# NetCDF +#----------------------------------------------------- +# +NETCDF_C_prefix=${NETCDF_C_prefix:-notdef} +if [ "$NETCDF_C_prefix" == "no" ] +then + echo_orange "WARNING: You chose to compile without any NetCDF Library" \ + " 1) You must use --nonetcdf when calling makenemo" \ + " 2) You won't be able to read/write any input/output file when running nemo" \ + " -> You can run only the BENCH test" \ + " 3) You can neither use XIOS nor OASIS" \ + + NETCDF_F_prefix=no + HDF5_prefix=no + XIOS_prefix=no + OASIS_prefix=no + NCDF_INC="" + NCDF_LIB="" + XIOS_INC="" + XIOS_LIB="" + OASIS_INC="" + OASIS_LIB="" +else + if [ "$NETCDF_C_prefix" == "notdef" ] + then + if [ $( err_which nc-config ) -ne 0 ] # use nc-config to define NETCDF_C_prefix + then + echo_red "ERROR: nc-config not found." \ + " please define either your path to the NETCDF_C with 'export NETCDF_C_prefix=...'" \ + " or specify you don't want to use NetCDF with 'export NETCDF_C_prefix=no'" \ + exit 2 + fi + NC_CONFIG=nc-config + NETCDF_C_prefix=$( $NC_CONFIG --prefix ) + else + NC_CONFIG=$NETCDF_C_prefix/bin/nc-config # assume that nc-config is in $NETCDF_C_prefix/bin + nbok=$( ls $NC_CONFIG 2>/dev/null | wc -l ) # check if we have nc-config + if [ $nbok -eq 0 ] + then + echo_red "ERROR: nc-config not found in $NETCDF_C_prefix/bin" ; exit 2 + fi + fi + + # do we have the proper path to the netcdf library? + nbok=$( ls $NETCDF_C_prefix/lib/libnetcdf* 2>/dev/null | wc -l ) + if [ $nbok -eq 0 ] + then + echo_red "ERROR: netcdf library not found in $NETCDF_C_prefix/lib" ; exit 2 + else + echo_green "NETCDF_C_prefix=$NETCDF_C_prefix" + fi + + # do we have NetCDF-Fortran? + if [ "$( $NC_CONFIG --has-fortran )" != "yes" ] + then + echo_red "ERROR: no netcdf-fortran " ; exit 2 + fi + + # do we have NetCDF-F90 interface? + if [ "$( $NC_CONFIG --has-f03 )" != "yes" ] + then + if [ "$( $NC_CONFIG --has-f90 )" != "yes" ] + then + echo_red "ERROR: no netcdf-fortran F90 interface" ; exit 2 + fi + fi + + # NetCDF fortran prefix + NETCDF_F_prefix=${NETCDF_F_prefix:-notdef} + if [ "$NETCDF_F_prefix" == "notdef" ] + then + # get the path of the netcdff library + NETCDF_F_prefix=$( $NC_CONFIG --flibs | sed -e "s/.*\(-L\|-rpath,\)\([^ ]*\)\/lib *-lnetcdff.*/\2/" ) + [ -z $NETCDF_F_prefix ] && NETCDF_F_prefix=$NETCDF_C_prefix # empty -> we try NETCDF_C_prefix + fi + + # do we have the proper path to the netcdff library? + nbok=$( ls $NETCDF_F_prefix/lib/libnetcdff* 2>/dev/null | wc -l ) + if [ $nbok -eq 0 ] + then + echo_red "ERROR: netcdff library not found in $NETCDF_F_prefix/lib" ; exit 2 + else + echo_green "NETCDF_F_prefix=$NETCDF_F_prefix" + fi + + # do we have nc4? + if [ "$( $NC_CONFIG --has-nc4 )" != "yes" ] + then + echo_red "ERROR: no nc4 interface in your netcdf library" ; exit 2 + fi + + # do we have hdf5? + if [ "$( $NC_CONFIG --has-hdf5 )" != "yes" ] + then + echo_red "ERROR: no hdf5 interface in your netcdf library" ; exit 2 + fi + + HDF5_prefix=${HDF5_prefix:-notdef} + if [ "$HDF5_prefix" == "notdef" ] + then + # look for libhdf5 in the paths found in nc-config --cflags + for dd in $( $NC_CONFIG --cflags | sed -e "s/-I//g" ) + do + nbok=$( ls $dd/../lib/libhdf5* 2>/dev/null | wc -l ) + [ $nbok -gt 0 ] && HDF5_prefix=$( dirname $dd ) + done + fi + if [ "$HDF5_prefix" == "notdef" ] # not found any libhdf5 file... try "h5pcc -showconfig" + then + if [ $( err_which h5pcc ) -eq 0 ] # do we have h5pcc? + then + HDF5_prefix=$( h5pcc -showconfig | grep "Installation point" | sed -e "s/.*: //" ) + [ -z $HDF5_prefix ] && HDF5_prefix=notdef # empty -> back to "notdef" + fi + fi + if [ "$HDF5_prefix" == "notdef" ] # still not found any libhdf5 file... try $NETCDF_C_prefix + then + nbok=$( ls $NETCDF_C_prefix/lib/libhdf5* 2>/dev/null | wc -l ) + [ $nbok -gt 0 ] && HDF5_prefix=$NETCDF_C_prefix + fi + if [ "$HDF5_prefix" == "notdef" ] # still not found any libhdf5 file... + then + echo_red "ERROR: HDF5_prefix not found." \ + " please define it with 'export HDF5_prefix=...'" ; exit 2 + fi + + # do we have the proper path to the hdf5 library? + nbok=$( ls $HDF5_prefix/lib/libhdf5* 2>/dev/null | wc -l ) + if [ $nbok -eq 0 ] + then + echo_red "ERROR: hdf5 library not found in $HDF5_prefix/lib" ; exit 2 + else + echo_green "HDF5_prefix=$HDF5_prefix" + fi + + # do we have netcdf parallel? + if [ "$( $NC_CONFIG --has-parallel )" != "yes" ] + then + echo_orange "WARNING: your netcdf library cannot write in parallel" \ + " you can use only 'the one_file' mode in XOS" + fi + if [ $( err_which h5pcc ) -eq 0 ] + then + if [ $( h5pcc -showconfig | grep "Parallel HDF5" | grep -c yes ) -ne 1 ] + then + echo_orange "WARNING: your hdf5 library was configured without --enable-parallel" \ + " you cannot use only the 'one_file' mode in XOS" + fi + fi + + # curl + CURLpath=${CURLpath:-notdef} + if [ "$( $NC_CONFIG --dap )" == "yes" ] + then + if [ "$CURLpath" == "notdef" ] + then + if [ $( err_which curl ) -eq 0 ] + then + CURLpath="-L$( dirname $( ls -1 $( dirname $( dirname $( which curl ) ) )/*/libcurl* | head -n 1 ) )" + echo_green "CURLpath=$CURLpath" + else + CURLpath="" + fi + fi + CURLlib="$CURLpath -lcurl" + else + CURLlib="" + fi + + # Zlib: compression library + Zlib="${ZLIBpath:-""} -lz" + + # libM: standard C library of basic mathematical functions + libM="${LIBMpath:-""} -lm" + + # NCDF_INC and NCDF_LIB + NCDF_INC="-I%NCDF_F_PREFIX/include -I%NCDF_C_PREFIX/include" + NCDF_LIB="-L%NCDF_F_PREFIX/lib -lnetcdff -L%NCDF_C_PREFIX/lib -lnetcdf -L%HDF5_PREFIX/lib -lhdf5_hl -lhdf5 $CURLlib $Zlib $libM" + +fi +# +#----------------------------------------------------- +# fortran Compileur +#----------------------------------------------------- +# +nompi=0 # default +FCnemo=${FCnemo:-notdef} +if [ "$FCnemo" == "notdef" ] +then + if [ "$NETCDF_C_prefix" == "no" ] + then + find_fortran_wrapper + else + FCnemo=$( $NC_CONFIG --fc ) # use nc-config to find the fortran compiler + [ -z $FCnemo ] && find_fortran_wrapper # if $FCnemo is empty try to find it... + chk_which FCnemo "fortran compiler" + + # does the fortran compiler start with the 3 letters mpi or ftn + ismpi=$( basename $FCnemo | cut -c 1-3 | grep -Ec 'mpi|ftn' ) + if [ $ismpi -eq 0 ] + then + echo_orange "WARNING: the fortran compiler provided by nc-config \"$FCnemo\" is not starting with \"mpi\" or \"ftn\"." \ + " we look for mpiifort, mpif90 or ftn..." + FCnemo_org=$FCnemo + find_fortran_compiler + ftncomp_org=$ftncomp + find_fortran_wrapper + find_fortran_compiler + if [ "$ftncomp" != "$ftncomp_org" ] + then + echo_red "ERROR: \"$FCnemo\" and \"$FCnemo_org\" are refering to different compilers: \"$ftncomp\" and \"$ftncomp_org\"" \ + " please define your fortran compiler path with 'export FCnemo=...'" + exit 1 + fi + fi + fi +else + ismpi=$( basename $FCnemo | cut -c 1-3 | grep -Ec 'mpi|ftn' ) # the fortran compiler does not start with mpi or ftn... + if [ $ismpi -eq 0 ] + then + echo_orange "WARNING: the fortran compiler you provided does not start with mpi or ftn." \ + " you must compile nemo with key_mpi_off and you cannot run nemo in parallel" + nompi=1 + fi +fi +echo_green "FCnemo=$FCnemo" + +find_fortran_compiler +# +#----------------------------------------------------- +# C Compileur (not critical, needed only for the conv of AGRIF) +#----------------------------------------------------- +# +# first guess +case "$ftncomp" in + intel) guess=${CCnemo:-icc} ;; + gnu) guess=${CCnemo:-gcc} ;; + cray) guess=${CCnemo:-cc} ;; + *) guess=${CCnemo:-""} ;; +esac +listcc="$guess gcc cc icc" # try $guess and other usuals C compilers... +CCnemo="notfound" +for ii in $listcc +do + [ $( err_which $ii ) -eq 0 ] && [ "$CCnemo" == "notfound" ] && CCnemo=$ii +done +if [ "$CCnemo" == "notfound" ] +then + echo_red "ERROR: we found neither \"gcc\" nor \"icc\" nor \"cc\"." \ + " please define your C compiler with 'export CCnemo=...'" + exit 1 +fi +# +#----------------------------------------------------- +# CPP +#----------------------------------------------------- +# +CPPnemo=${CPPnemo:-cpp} +chk_which CPPnemo "pre-compiler" +echo_green "CPPnemo=$CPPnemo" + +[ "$ftncomp" == "gnu" ] || [ "$ftncomp" == "cray" ] && CPPnemo="$CPPnemo -Dkey_nosignedzero" +[ $nompi -eq 1 ] && CPPnemo="$CPPnemo -Dkey_mpi_off" +# +#----------------------------------------------------- +# FCFLAGS +#----------------------------------------------------- +# +case "$ftncomp" in + intel) + PROD_FCFLAGS="-i4 -r8 -O3 -fp-model strict -xHost -fno-alias" + DEBUG_FCFLAGS="-i4 -r8 -g -O0 -debug all -traceback -fp-model strict -ftrapuv -check all,noarg_temp_created -fpe-all0 -ftz -init=arrays,snan,huge" + echo_orange "WARNING: We assume you will execute NEMO on the same machine you compiled it. " \ + " If it is not the case, replace -xHost by the appropiate option in PROD_FCFLAGS" + ;; + gnu) + PROD_FCFLAGS="-fdefault-real-8 -O3 -march=native -funroll-all-loops -fcray-pointer -ffree-line-length-none" + DEBUG_FCFLAGS="-fdefault-real-8 -Og -g -fbacktrace -funroll-all-loops -fcray-pointer -ffree-line-length-none -fcheck=all -finit-real=nan -ffpe-trap=invalid,zero,overflow -ffpe-summary=invalid,zero,overflow" + rev=$( $FCnemo --version | head -n 1 | sed -e "s/.* \([0-9]*\).*/\1/" ) + # if gfortran version >= 10 : add -fallow-argument-mismatch + if [ $rev -ge 10 ] + then + PROD_FCFLAGS="$PROD_FCFLAGS -fallow-argument-mismatch" + DEBUG_FCFLAGS="$DEBUG_FCFLAGS -fallow-argument-mismatch" + fi + echo_orange "WARNING: We assume you will execute NEMO on the same machine you compiled it. " \ + " If it is not the case, replace -march=native by the appropiate option in PROD_FCFLAGS" + ;; + cray) + PROD_FCFLAGS="-s real64 -s integer32 -O2 -hflex_mp=intolerant" + DEBUG_FCFLAGS="-s real64 -s integer32 -Ovector0 -hfp0 -O0 -hflex_mp=intolerant -e mCI -G0 -m2 -rl -Rcdsp -N1023" + ;; + *) + echo_red "ERROR: compilation options for $ftncomp are not defined..." + exit 1 + ;; +esac +# +#----------------------------------------------------- +# XIOS and OASIS +#----------------------------------------------------- +# +if [ "$NETCDF_C_prefix" != "no" ] +then + + # XIOS + XIOS_prefix=${XIOS_prefix:-notdef} + if [ "$XIOS_prefix" == "notdef" ] + then + echo_orange "WARNING: XIOS_prefix not specified" \ + " either define it with 'export XIOS_prefix=...'" \ + " or don't use key_xios when compiling nemo (-> you will not be able to use XIOS)." + XIOS_INC="" + XIOS_LIB="" + else + XIOS_INC="-I%XIOS_PREFIX/inc" + XIOS_LIB="-L%XIOS_PREFIX/lib -lxios -lstdc++ " + fi + + # OASIS + OASIS_prefix=${OASIS_prefix:-notdef} + if [ "$OASIS_prefix" == "notdef" ] + then + echo_orange "WARNING: OASIS_prefix not specified" \ + " either define it with 'export OASIS_prefix=...'" \ + " or don't use key_oasis3 when compiling nemo (-> you will not be able to run coupled simulations)." + OASIS_INC="" + OASIS_LIB="" + else + OASIS_INC="-I%OASIS_PREFIX/build/lib/mct -I%OASIS_PREFIX/build/lib/psmile.MPI1" + OASIS_LIB="-L%OASIS_PREFIX/lib -lpsmile.MPI1 -lmct -lmpeu -lscrip" + fi +fi +# +#----------------------------------------------------- +# make +#----------------------------------------------------- +# +MKnemo=${MKnemo:-make} +mkerr=$( err_which make ) +gmkerr=$( err_which gmake ) + +if [ $( err_which $MKnemo ) -ne 0 ] # no make found +then + if [ $mkerr -eq 0 ] # make found + then + echo_orange "WARNING: $MKnemo not found, we switch to make" + MKnemo=make + else + if [ $gmkerr -ne 0 ] # gmake found + then + echo_orange "WARNING: $MKnemo not found, we switch to gmake" + MKnemo=gmake + else + echo_red "ERROR: gnu make not found, please define its path with 'export MKnemo=...'" + exit 1 + fi + fi +fi +# +isgnu=$( $MKnemo --version | head -n 1 | grep -ic gnu ) # make is gmake +if [ $isgnu -ne 1 ] +then + if [ $gmkerr -ne 0 ] # gmake found + then + echo_orange "WARNING: $MKnemo is not gnu make, we switch to gmake" + MKnemo=gmake + else + echo_red "ERROR: $MKnemo is not gnu make and gmake not found." \ + " please define gnu make path with 'export MKnemo=...'" + exit 1 + fi +fi +echo_green "MKnemo=$MKnemo" +# +#----------------------------------------------------- +# ar command +#----------------------------------------------------- +# +ARnemo=${ARnemo:-ar} +chk_which ARnemo "archiver" +echo_green "ARnemo=$ARnemo" +# +# +#----------------------------------------------------- +#----------------------------------------------------- +# write arch file +#----------------------------------------------------- +#----------------------------------------------------- +# +# +archname=arch-auto.fcm +cat > $archname << EOF +# +# This arch file was automatically created by $0 +# $( date ) +# +%NCDF_C_PREFIX $NETCDF_C_prefix +%NCDF_F_PREFIX $NETCDF_F_prefix +%HDF5_PREFIX $HDF5_prefix +%XIOS_PREFIX $XIOS_prefix +%OASIS_PREFIX $OASIS_prefix + +%NCDF_INC $NCDF_INC +%NCDF_LIB $NCDF_LIB +%XIOS_INC $XIOS_INC +%XIOS_LIB $XIOS_LIB +%OASIS_INC $OASIS_INC +%OASIS_LIB $OASIS_LIB + +%CPP $CPPnemo +%FC $FCnemo +%FCFLAGS $PROD_FCFLAGS +### comment out the following line if you want to use the debugging compilation options +#%FCFLAGS $DEBUG_FCFLAGS +%FFLAGS %FCFLAGS +%LD %FC +%LDFLAGS +%FPPFLAGS -P -traditional +%AR $ARnemo +%ARFLAGS rs +%MK $MKnemo +%USER_INC %XIOS_INC %OASIS_INC %NCDF_INC +%USER_LIB %XIOS_LIB %OASIS_LIB %NCDF_LIB + +%CC $CCnemo +%CFLAGS -O0 +EOF +# +# Additional module search command for Cray Fortran to enable successful parallel builds +if [ $ftncomp == "cray" ] ; then + echo "bld::tool::fc_modsearch -J" >> $archname +fi +# +echo +echo "Content of the created $archname:" +echo "-------------------------------------" +echo +cat $archname +echo