#!/bin/bash -e # --------------------------------------------------------------------------- # # w3_make : Compile and link WAVEWATCH III programs using standard make and # # makefile methods. # # # # use : w3_make [program [...]] # # program: program name of WAVEWATCH III (sub)program. # # # # error codes : Program ends if error occurs in make_makefile.sh. # # # # programs used : # # make_makefile.sh : Makes the makefile. # # # # programs called from the makefile : # # ad3 : script to execute preprocessor and to compile. # # link : linker script. # # # # Hendrik L. Tolman # # May 2009 # # March 2014 # # # # Copyright 2009-2013 National Weather Service (NWS), # # National Oceanic and Atmospheric Administration. All rights # # reserved. WAVEWATCH III is a trademark of the NWS. # # No unauthorized use without permission. # # # # --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- # # 1. Preparations # # --------------------------------------------------------------------------- # # 1.a ID header - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - echo ' ' echo ' *****************************' echo ' *** WAVEWATCH III make ***' echo ' *****************************' echo ' ' # 1.b Input arguments - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if [ $# -eq 0 ] then default_mode=1 all_programs="" else default_mode=0 all_programs="$*" fi # 1.c Get data from setup file - - - - - - - - - - - - - - - - - - - - - - - - source $(dirname $0)/w3_setenv main_dir=$WWATCH3_DIR temp_dir=$WWATCH3_TMP source=$WWATCH3_SOURCE list=$WWATCH3_LIST echo "Main directory : $main_dir" echo "Scratch directory : $temp_dir" echo "Save source codes : $source" echo "Save listings : $list" # 1.d Check / make directories - - - - - - - - - - - - - - - - - - - - - - - # bin dir if [ ! -d $main_dir/bin ] then echo ' ' echo "[ERROR] Directory $main_dir/bin not found" echo ' Please check the content of your directory model' exit 1 fi # exe dir if [ ! -d $main_dir/exe ] then mkdir -p $main_dir/exe fi # switch file if [ -z "$(env | grep switch_file)" ] then switch_file=$main_dir/bin/switch fi if [ ! -e $switch_file ] || [ ! -r $switch_file ] then echo ' ' echo "[ERROR] switch file $switch_file not found" echo " Please run $main_dir/bin/w3_setup -c -s " exit 1 fi cp $switch_file $main_dir/exe/ # comp file comp_file=$main_dir/bin/comp if [ ! -e $comp_file ] || [ ! -r $comp_file ] then echo ' ' echo "[ERROR] comp file $comp_file not found" echo " Please run $main_dir/bin/w3_setup -c -s " exit 1 fi # link file link_file=$main_dir/bin/link if [ ! -e $link_file ] || [ ! -r $link_file ] then echo ' ' echo "[ERROR] link file $comp_file not found" echo " Please run $main_dir/bin/w3_setup -c -s " exit 1 fi # src dir makefile=$main_dir/src/makefile if [ ! -d $main_dir/src ] then echo ' ' echo "[ERROR] Directory $main_dir/src not found" echo ' Please check the content of your directory model' exit 1 fi rm -f $makefile # 1.e Set regular and netCDF progs - - - - - - - - - - - - - - - - - - - - - - # reg_programs = non-NetCDF programs # cdf_programs = NetCDF programs #STRT BOUND OUTF OUTP TRCK GRIB GINT GX* UPRSTR reg_programs="ww3_strt" reg_programs="$reg_programs ww3_bound" reg_programs="$reg_programs ww3_outf" reg_programs="$reg_programs ww3_outp" reg_programs="$reg_programs ww3_trck" reg_programs="$reg_programs ww3_grib" reg_programs="$reg_programs ww3_gint" reg_programs="$reg_programs gx_outf" reg_programs="$reg_programs gx_outp" reg_programs="$reg_programs ww3_uprstr" # PRNC OUNF OUNP BOUNC TRNC cdf_programs="ww3_prnc" cdf_programs="$cdf_programs ww3_ounf" cdf_programs="$cdf_programs ww3_ounp" cdf_programs="$cdf_programs ww3_bounc" cdf_programs="$cdf_programs ww3_trnc" # PRTIDE if [ -n "`grep TIDE $switch_file`" ] then cdf_programs="$cdf_programs ww3_prtide" fi # MULTI MULTI_ESMF SBS1 LIBWW3 if [ -n "`grep SCRIPNC $switch_file`" ] || [ -n "`grep OASIS $switch_file`" ] || [ -n "`grep PDLIB $switch_file`" ] then cdf_programs="$cdf_programs ww3_grid" cdf_programs="$cdf_programs ww3_multi" cdf_programs="$cdf_programs ww3_sbs1" cdf_programs="$cdf_programs libww3" if [ $ESMFMKFILE ] then cdf_programs="$cdf_programs ww3_multi_esmf" fi else reg_programs="$reg_programs ww3_grid" reg_programs="$reg_programs ww3_multi" reg_programs="$reg_programs ww3_sbs1" reg_programs="$reg_programs libww3" if [ $ESMFMKFILE ] then reg_programs="$reg_programs ww3_multi_esmf" fi fi # SYSTRK if [ -n "`grep TRKNC $switch_file`" ] then cdf_programs="$cdf_programs ww3_systrk" else reg_programs="$reg_programs ww3_systrk" fi # PREP GSPL if [ -n "`grep OASIS $switch_file`" ] || [ -n "`grep PDLIB $switch_file`" ] then cdf_programs="$cdf_programs ww3_gspl" cdf_programs="$cdf_programs ww3_prep" else reg_programs="$reg_programs ww3_gspl" reg_programs="$reg_programs ww3_prep" fi #SHEL if [ -n "`grep OASIS $switch_file`" ] || [ -n "`grep PDLIB $switch_file`" ] then cdf_programs="$cdf_programs ww3_shel" if [ $ESMFMKFILE ] then cdf_programs="$cdf_programs ww3_shel_esmf" fi else reg_programs="$reg_programs ww3_shel" if [ $ESMFMKFILE ] then reg_programs="$reg_programs ww3_shel_esmf" fi fi #Shared Object if [ -n "`grep -nri fPIC $comp_file`" ] then reg_programs="$reg_programs libww3.so" else echo 'Shared Object : No' fi # 1.f Set sequential or parallel folders - - - - - - - - - - - - - - - - - - - flag_SHRD=`grep SHRD $switch_file | wc -l | awk '{ print $1}'` flag_OMPH=`grep OMPH $switch_file | wc -l | awk '{ print $1}'` switch_file_old=$main_dir/bin/switch.old exec_type_file=$main_dir/exe/exec_type here=`pwd` if [ "$flag_SHRD" -gt '0' ] then pres_type='SEQ' flag_OMP=`grep OMP $switch_file | wc -l | awk '{ print $1}'` if [ "$flag_OMP" -gt '0' ] then pres_type='OMP' fi else if [ "$flag_OMPH" -gt '0' ] then pres_type='HYB' else pres_type='MPI' fi fi rm -rf $main_dir/obj rm -rf $main_dir/mod if [ -f ${switch_file_old}_$pres_type ] ; then cp ${switch_file_old}_$pres_type $switch_file_old fi if [ -f ${makefile}_$pres_type ] ; then cp ${makefile}_$pres_type $makefile fi cd $main_dir mkdir -p obj_$pres_type mod_$pres_type ln -sf obj_$pres_type obj ln -sf mod_$pres_type mod cd $here # 1.g Setup for NetCDF compile - - - - - - - - - - - - - - - - - - - - - - - - # 1.g.1 NetCDF compile message function netcdf_compile_message () { cat 2>&1 << 'EOF' *********************************************************************** *** WAVEWATCH III NetCDF Compile Instructions *** *********************************************************************** For compiling with NetCDF, the following environment variable is required: NETCDF_CONFIG = The nc-config utility (part of the NetCDF-4 install) is used to determine the appropriate compile and link flags. For NetCDF routines to compile, WAVEWATCH III requires NetCDF version 4.1.1 or higher. Use "nc-config --version" to check the version of the installed NetCDF. It is also required for NetCDF to be compiled with the NetCDF-4 API enabled. Use "nc-config --has-nc4" to check if the installed NetCDF has the NetCDF-4 API enabled. *********************************************************************** EOF } # 1.g.2 NetCDF check compile environment function netcdf_check_compile () { mode=$1 #must be ERROR or WARNING if [ -z "$NETCDF_CONFIG" ] then netcdf_compile_message echo "$mode: NETCDF_CONFIG not defined"; echo ' ' return 1 fi if [ ! -x "$NETCDF_CONFIG" ] then netcdf_compile_message echo "$mode: $NETCDF_CONFIG does not exist or is not executable"; echo ' ' return 1 fi netcdf_version=`$NETCDF_CONFIG --version | awk '{print $2}'` if [ -z "`echo $netcdf_version | cut -d. -f3`" ] then netcdf_version="$netcdf_version.0" fi if [ `echo $netcdf_version | tr -d . | tr -d - | tr -d 'A-Z a-z'` -lt 411 ] then netcdf_compile_message echo "$mode: NetCDF version $netcdf_version < 4.1.1"; echo ' ' return 1 fi return 0 } # 1.g.3 Check for NetCDF compile if [ $default_mode -eq 1 ] then if ! netcdf_check_compile WARNING then echo "NetCDF enabled programs ($cdf_programs)" echo "will not be compiled unless NetCDF compile environment is properly set."; echo ' ' echo "Continuing with compile of non-NetCDF programs ..."; echo ' ' all_programs="$reg_programs" else all_programs="$reg_programs $cdf_programs" fi else nc_compile=0 for prog in $cdf_programs do if [ -n "`echo $progs | grep $prog`" ] then nc_compile=1 fi done if [ $nc_compile -eq 1 ] then if ! netcdf_check_compile ERROR then echo "NetCDF enabled programs ($cdf_programs)" echo "will not be compiled unless NetCDF compile environment is properly set."; echo ' ' echo "Now exiting ..."; echo ' ' exit 1 fi fi fi echo ' ' echo "[INFO] list of the programs selected : $all_programs" # 1.h set progs list - - - - - - - - - - - - - - - - - - - - - - - - - - - - # no filtering is done to distinguish sequential to parallel programs progs=$all_programs # 1.i Prepare scratch directory - - - - - - - - - - - - - - - - - - - - - - - if test ! -d $temp_dir then if ! `mkdir -p $temp_dir` then echo ' ' ; echo " *** Cannot create $temp_dir ***" ; echo ' ' exit 1 fi fi cd $temp_dir if [ "$source" != 'yes' ] then rm -f *.f *.F *.f90 *.F90 fi if [ "$list" != 'yes' ] then rm -f *.l fi cd $main_dir/src # 1.j Prepare makefile - - - - - - - - - - - - - - - - - - - - - - - - - - - - make_make='y' if test -f $switch_file_old then if test -f $main_dir/src/makefile && \ test -z "`diff $switch_file $switch_file_old`" then make_make='n' fi fi if test "$make_make" = 'y' then echo 'Making makefile ...' if $main_dir/bin/make_makefile.sh then if [ "$flag_SHRD" -gt '0' ] then if [ "$flag_OMP" -gt '0' ] then cp $switch_file ${switch_file_old}_OMP cp $makefile ${makefile}_OMP else cp $switch_file ${switch_file_old}_SEQ cp $makefile ${makefile}_SEQ fi else if [ "$flag_OMPH" -gt '0' ] then cp $switch_file ${switch_file_old}_HYB cp $makefile ${makefile}_HYB else cp $switch_file ${switch_file_old}_MPI cp $makefile ${makefile}_MPI fi fi else exit 1 fi fi echo ' ' # 1.k Export paths - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - aPb="$main_dir/bin" # path containing shell scripts aPo="$main_dir/obj" # path containing .o files aPm="$main_dir/mod" # path containing .mod files aPe="$main_dir/exe" # path containing executables export aPb aPo aPm aPe # --------------------------------------------------------------------------- # # 2. Run make for all requests # # --------------------------------------------------------------------------- # # 2.a Loop over all requests for prog in $progs do echo "Processing $prog" echo "---------------------" # 2.b Check input - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OK='n' for check in $all_programs do if test "$prog" = "$check" then OK='y' fi done if test "$OK" = 'n' then echo " *** Program name not recognized ***" echo ' ' exit 1 # 2.c Run make - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - else netcdf_compile=no if [ -n "`echo $cdf_programs | grep $prog`" ] then netcdf_compile=yes fi export netcdf_compile mpi_mod=no if [ -n "`grep MPI $switch_file`" ] then mpi_mod=yes fi export mpi_mod omp_mod=no if [ -n "`grep OMP $switch_file`" ] then omp_mod=yes fi export omp_mod oasis_mod=no if [ -n "`grep OASIS $switch_file`" ] then export oasis_mod='yes' fi export oasis_mod pdlib_mod=no metis_mod=no scotch_mod=no esmfpdlib='' if [ -n "`grep PDLIB $switch_file`" ] then export pdlib_mod='yes' if [ -n "`grep METIS $switch_file`" ] then export metis_mod='yes' esmfpdlib="$METIS_PATH/lib/libparmetis.a $METIS_PATH/lib/libmetis.a" fi if [ -n "`grep SCOTCH $switch_file`" ] then export scotch_mod='yes' esmfpdlib="$SCOTCH_PATH/lib/libptscotchparmetisv3.a $SCOTCH_PATH/lib/libptscotch.a \ $SCOTCH_PATH/lib/libptscotcherr.a $SCOTCH_PATH/lib/libscotch.a" fi fi export pdlib_mod export metis_mod export scotch_mod # NCEP GRIB export ncep_grib_compile="no" #check for switch file: if [ -n "`grep NCEP $switch_file`" ] then #only set to yes if compiling ww3_grib: if [ -n "`echo $prog | grep ww3_grib`" ] then export ncep_grib_compile="yes" fi fi # if esmf is included in program name, then the compile # requires DIST switch and the ESMFMKFILE is # processed to get required ESMF compile options if [ -n "`echo $prog | grep esmf 2>/dev/null`" ] then if [ -z "`grep DIST $switch_file`" ] then echo ' ' echo "*** DIST switch must be set when compiling with ESMF ***" echo ' ' exit 1 fi ESMF_F90COMPILEPATHS= if [ $ESMFMKFILE ] then if [ ! -r $ESMFMKFILE ] then echo ' ' echo "*** ESMFMKFILE does not exist or is not readable: $ESMFMKFILE ***" echo ' ' exit 1 fi ESMF_F90COMPILEPATHS=`cat $ESMFMKFILE | grep '^ *ESMF_F90COMPILEPATHS' | sed 's/^ *ESMF_F90COMPILEPATHS *=//g'` else echo ' ' echo "*** ESMFMKFILE must be defined when compiling with ESMF ***" echo ' ' exit 1 fi fi export ESMF_F90COMPILEPATHS # if esmf is included in program name, then # the target is compile and create archive if [ -n "`echo $prog | grep esmf 2>/dev/null`" ] then target="$prog" # if program name is libww3, then # the target is compile and create archive elif [ "$prog" = "libww3" ] then target="$prog" elif [ "$prog" = "libww3.so" ] then target="$prog" else target="$aPe/$prog" fi if [ ! -f $exec_type_file ] ; then touch $exec_type_file ; fi if [ `grep $prog $exec_type_file | wc -l | awk '{ print $1}'` != '0' ] then exec_type=`grep $prog $exec_type_file | tail -1 | awk '{ print $2}'` fi if [ "$exec_type" != "$pres_type" ] ; then rm -f $main_dir/exe/$prog ; fi cp $exec_type_file tempfile sed -n "/$prog/!p" tempfile > $exec_type_file rm -f tempfile path_m=$main_dir/mod export path_m # WW3_PARCOMPN is an environment variable to set the parallel make tasks # it defaults to 4 if make -j ${WW3_PARCOMPN:-4} -f makefile $target then echo ' ' else exit 1 fi echo "$prog $pres_type" >> $exec_type_file # if esmf is included in program name, then create $main_dir/nuopc.mk if [ -n "`echo $prog | grep esmf 2>/dev/null`" ] then mkfile=$main_dir/nuopc.mk if [ -n "`grep OMP $switch_file`" ] then mod_dir=$main_dir/mod_HYB obj_dir=$main_dir/obj_HYB else mod_dir=$main_dir/mod_MPI obj_dir=$main_dir/obj_MPI fi rm -f $mkfile touch $mkfile echo "#-----------------------------------------------" >> $mkfile echo "# NUOPC/ESMF self-describing build dependency" >> $mkfile echo "# makefile fragment for Wavewatch III" >> $mkfile echo "#-----------------------------------------------" >> $mkfile echo "# component module name" >> $mkfile echo "ESMF_DEP_FRONT := WMESMFMD" >> $mkfile echo "# component module path" >> $mkfile echo "ESMF_DEP_INCPATH := $mod_dir" >> $mkfile echo "# component module objects" >> $mkfile echo "ESMF_DEP_CMPL_OBJS := $obj_dir/lib$prog.a(wmesmfmd.o)" >> $mkfile echo "# component object/archive list" >> $mkfile echo "ESMF_DEP_LINK_OBJS := $obj_dir/lib$prog.a $esmfpdlib" >> $mkfile fi fi done # 2.d copy comp and link cp $main_dir/bin/comp $main_dir/exe/ cp $main_dir/bin/link $main_dir/exe/ # --------------------------------------------------------------------------- # # 3. End of program ID. # # --------------------------------------------------------------------------- # echo ' ' echo ' **********************' echo ' *** end of compilation ***' echo ' **********************' echo ' ' # End of w3_make ------------------------------------------------------------ #