build Script

From WikiROMS
Jump to: navigation, search
Build Script - build_roms.csh,

As mentioned in makefile, you need to provide settings for some user-defined choices before you can compile ROMS. If you have more than one application (or more than one compiler), you may get tired of editing the makefile. One option is to have a makefile for each configuration. The recommended solution, however, is to use the ROMS build script.

Note Note: in SVN revision 1030 (April 30, 2020) the ROMS build scripts (and other shell scripts) were renamed to follow accepted naming conventions; *.sh scripts were changed to *.csh and *.bash where changed to *.sh.


There are two of these build scripts in the ROMS/Bin directory: build_roms.csh and The build scripts use environment variables to provide values for the user-defined make variables, overwriting those found in the ROMS makefile. Just as in the multiple makefile option, you will need as many copies of the build script as you have applications. However, the scope of these variables is local to the build script, allowing you to compile different applications at the same time from the same sources as long as each $(SCRATCH_DIR) is unique.


./build_roms.csh [options]


-j [N] Compile in parallel using N CPUs
omit argument for all available CPUs.

-p macro Prints any Makefile macro value. For example, -p FFLAGS

-noclean Do not clean already compiled objects.


./ -j 2

User Definable Compilation Options

ROMS has a growing list of choices the user must make about the compilation before starting the compile process. These user-defined variables can be set in the build script. Since we use gnu make, it is possible to set the value of these variables in the Unix environment, rather than inside the Makefile (see gmake). The user-definable variables understood by the ROMS makefile are:

CPP option defining a particular application (for example, UPWELLING). The makefile will include its associated header file which is located in either the ROMS/Include directory or the path specified in the MY_HEADER_DIR definition. The header file name is the lowercase value of ROMS_APPLICATION with the .h extension (for example, upwelling.h). Recall the CPP option defining an application must be unique.

This path is internal to the build script and has no equivalent in the makefile. It can be used to set the base path to your ROMS source code and/or your application input and output files. This variable is not strictly necessary but can make setting the necessary paths easier.

This path is internal to the build script and has no equivalent in the makefile. MY_PROJECT_DIR is most often used to set the paths: MY_HEADER_DIR, MY_ANALYTICAL_DIR, and BINDIR and to set the base path to SCRATCH_DIR. This can be seen near the bottom of the build script.

This path is internal to the build script and has no equivalent in the makefile. It is the location of your ROMS source code and is necessary for the build script to work properly.

Directory where make can find your system/compiler specific mk include files as described in FORT. In some situations you will need to edit the appropriate mk file in the Compilers directory (i.e. Compilers/ Rather than editing the mk files released with ROMS and possibly creating conflicts during updates, we suggest that you copy the appropriate system specific mk file and the Compilers/ to another folder and set COMPILERS to that folder.

Additional CPP options to activate. Sometimes it is desirable to activate one or more CPP options to run different variants of the same application without modifying its header file. If this is the case, specify such options here using the -D syntax. Notice that you need to use your shell's quoting syntax to enclose the definitions. For example:
can be use to write time-averaged fields and use analytical initial conditions. Notice that you can have as many definitions as you want by appending values.

WarningWarning: Be sure to leave environment variables meant to be off set to an empty string or commented out. Any string value (including off) will evaluate to TRUE in conditional if-statements.

Compile your application using MPI (distributed-memory) libraries.

If USE_MPI is activated, use this to turn on compilation via the script mpif90. This is needed in most Linux operating systems. In some systems with native MPI libraries the compilation does not require MPICH type scripts. This macro is also convenient when there are several Fortran compiliers (ifort, pgf90, pathf90) in the system that use mpif90. In this case, the user needs to select the desired compiler via the FORT variable and turn on both USE_MPI and USE_MPIF90 macros.

If USE_MPI and USE_MPIF90 are activated, this macro is used to determine which mpif90 to compile with. This macro is convenient when there are several Fortran compiliers (ifort, pgf90, etc.) in the system that use mpif90. The choice of which mpif90 to use will be determined by the combination of this macro and the FORT macro.

Compile your application using OpenMP librairies and compiler options. Note: you cannot set USE_OpenMP and USE_MPI at the same time.

The ROMS make system will include a file with all the settings that depend on the system and the compiler. The name of this file is determined from the output of the uname command and the value of FORT (i.e. Set your compiler here from the following list:
Operating System Compiler(s)

AIX: xlf
CYGWIN: df, g95, gfortran, ifort
Darwin: f90, gfortran, ifort, pgi, xlf
IRIX64: f90
Linux: ftn, g95, gfortran, ifc, ifort, necsx, path, pgi
MINGW: g95, gfortran
OSF1: f90
SunOS: f95, ftn
UNICOS-mk: f90
UNICOS-mp: ftn
UNICOS-sk: f90
Feel free to send us additional rule files to include!

Activate debugging compiler options.

If applicable, activate 64-bit compilation.

If applicable, link with NetCDF-4 library. Notice that the NetCDF-4 library needs both the HDF5 and, if you want to enable parallel I/O, MPI libraries. In order to write the output files in NetCDF-4/HDF5 format, you will need to set the HDF5 CPP Option.

Activate parallel I/O using parallel enabled NetCDF-4/HDF5 libraries. You will also need to set the HDF5 and PARALLEL_IO CPP Options to enable parallel I/O.

WRF cannot be built in a directory specified by the user; it must be built in its own root directory and cannot be moved when debugging with tools like TotalView. If you wish to couple ROMS with the Earth Systems Model (ESM) WRF, ROMS needs to know the WRF root directory.

Use custom library paths for ESMF, HDF5, NetCDF libraries, etc.

Path to your my_build_paths.csh (or .sh) file that contains custom library paths for your system.

This is the Directory where your application's header file is located. Recall that a ROMS header file contains all the CPP options defining a particular application. This is the header file that is included in cppdefs.h. Notice that if the header file is located in the ROMS/Include directory, it is possible to include the same header file name located somewhere else because the full directory path is specified here. The user may copy the distributed header file(s) into a different directory and modify it to explore different CPP options.

This is the directory containing the user's analytic files, if any. Templates of the analytic expressions are provided in the User/Functionals directory. If analytic expressions are activated, the makefile will first load the ones located in MY_ANALYTICAL_DIR and then the ones located in ROMS/Functionals. We recommended that you do not modify the analytical expressions in the ROMS/Functionals directory since these are the official versions of these files and updates will conflict with your changes. The user however can modify those in User/Functionals or some other directory and specify which directory with this variable.

Directory where your romsG, romsM, romsO, or romsS executable will be created.

Directory where your temporary objects and files will be placed during the build process.

Library and Executable Paths

NoteNote: in SVN revision 933 (January 26, 2019) the custom libraries section was removed from the ROMS build script and placed in Compilers/my_build_paths.csh and Compilers/ to both streamline the ROMS build script and make setting up new applications less tedious. More information can be found in ROMS Trac ticket #794. Prior to ROMS release 933, the paths mentioned below were included in the ROMS build script.

The path of the libraries and MPI implementations required by ROMS can be set using environment variables which take precedence over the values specified in the makefile macro definitions file (Compilers/*.mk). If so desired, uncomment the local USE_MY_LIBS definition above and properly set MY_PATHS. There is a section (the one from my_build_paths.csh is shown below) in the MY_PATHS file to make it easier to switch between different compilers and MPI implementations. This will only apply to MPI implementations that use the mpif90 wrapper script (MPICH, MPICH2, OpenMPI, etc.).

if ($?USE_MPIF90) then
switch ($FORT)

case "ifort"
if ($which_MPI == "mpich" ) then
setenv MPI_ROOT /opt/intelsoft/mpich
else if ($which_MPI == "mpich2" ) then
setenv MPI_ROOT /opt/intelsoft/mpich2
else if ($which_MPI == "openmpi" ) then
setenv MPI_ROOT /opt/intelsoft/openmpi
else if ($which_MPI == "mvapich2" ) then
setenv MPI_ROOT /opt/intelsoft/mvapich2
setenv PATH ${MPI_ROOT}/bin:$PATH
setenv MPI_INCDIR ${MPI_ROOT}/include

case "pgi"
if ($which_MPI == "mpich" ) then
setenv MPI_ROOT /opt/pgisoft/mpich
else if ($which_MPI == "mpich2" ) then
setenv MPI_ROOT /opt/pgisoft/mpich2
else if ($which_MPI == "openmpi" ) then
setenv MPI_ROOT /opt/pgisoft/openmpi
else if ($which_MPI == "mvapich2" ) then
setenv MPI_ROOT /opt/pgisoft/mvapich2
setenv PATH ${MPI_ROOT}/bin:$PATH
setenv MPI_INCDIR ${MPI_ROOT}/include

case "gfortran"
if ($which_MPI == "mpich2" ) then
setenv MPI_ROOT /opt/gfortransoft/mpich2
else if ($which_MPI == "openmpi" ) then
setenv MPI_ROOT /opt/gfortransoft/openmpi
else if ($which_MPI == "mvapich2" ) then
setenv MPI_ROOT /opt/gfortransoft/mvapich2
setenv PATH ${MPI_ROOT}/bin:$PATH
setenv MPI_INCDIR ${MPI_ROOT}/include


NoteKeep in mind that you need to adjust the paths to you MPI implementations for your particular system. You must also set USE_MPIF90 to on.

For most applications, only the location of the NetCDF library (NETCDF_LIBDIR) and include directory (NETCDF_INCDIR) are needed. Notice that when the USE_NETCDF4 macro is activated, we need the serial or parallel version of the NetCDF-4/HDF5 library. The configuration script NF_CONFIG (available since NetCDF 4.2) is used to set up all the required libraries according to the installed options (OPeNDAP, NetCDF4/HDF5 file format). The parallel library uses the MPI-I/O layer (usually available in MPICH2 and OpenMPI) requiring compiling with the selected MPI library.

In ROMS distributed-memory applications, you may use either the serial or parallel version of the NetCDF-4/HDF5 library. The parallel version is required when parallel I/O is activated (ROMS cpp option PARALLEL_IO and HDF5).

However, in serial or shared-memory ROMS applications, we need to use the serial version of the NetCDF-4/HDF5 to avoid conflicts with the compiler. We cannot activate MPI constructs in serial or shared-memory ROMS code. Hybrid parallelism is not possible.

Below is an excerpt from the custom library section.

setenv MPI_SOFT ""

switch ($FORT)

# Intel Compiler:

case "ifort"
setenv ESMF_COMPILER intelgcc
if ($?USE_DEBUG) then
setenv ESMF_BOPT g
setenv ESMF_BOPT O

setenv ESMF_ABI 64
setenv ESMF_COMM ${which_MPI}
setenv ESMF_SITE default

setenv ARPACK_LIBDIR /opt/intelsoft/serial/ARPACK

if ($?USE_MPI) then
if ($which_MPI == "mpich" ) then
setenv MPI_SOFT /opt/intelsoft/mpich
else if ($which_MPI == "mpich2" ) then
setenv MPI_SOFT /opt/intelsoft/mpich2
else if ($which_MPI == "openmpi" ) then
setenv MPI_SOFT /opt/intelsoft/openmpi
else if ($which_MPI == "mvapich2" ) then
setenv MPI_SOFT /opt/intelsoft/mvapich2

setenv MCT_INCDIR ${MPI_SOFT}/mct/include
setenv MCT_LIBDIR ${MPI_SOFT}/mct/lib

if ($?USE_NETCDF4) then
if ($?USE_PARALLEL_IO && $?USE_MPI) then
setenv ESMF_DIR ${MPI_SOFT}/esmf_nc4
setenv NETCDF ${MPI_SOFT}/netcdf4
setenv NF_CONFIG ${NETCDF}/bin/nf-config
setenv NETCDF_INCDIR ${NETCDF}/include
setenv NETCDF4 1
setenv ESMF_DIR ${MPI_SOFT}/esmf_nc4
setenv NETCDF /opt/intelsoft/serial/netcdf4
setenv NF_CONFIG ${NETCDF}/bin/nf-config
setenv NETCDF_INCDIR ${NETCDF}/include
setenv NETCDF4 1
setenv ESMF_DIR ${MPI_SOFT}/esmf_nc3
setenv NETCDF /opt/intelsoft/serial/netcdf3
setenv NETCDF_INCDIR ${NETCDF}/include

if ($?USE_HDF5) then
if ($?USE_PARALLEL_IO && $?USE_MPI) then
setenv HDF5 ${MPI_SOFT}/hdf5
setenv HDF5_LIBDIR ${HDF5}/lib
setenv HDF5_INCDIR ${HDF5}/include
setenv HDF5 /opt/intelsoft/serial/hdf5
setenv HDF5_LIBDIR ${HDF5}/lib
setenv HDF5_INCDIR ${HDF5}/include

. . .

Notes and Recommendations

The new structure of ROMS (version 3.0 or higher) allows user specific CPP definitions and analytical options to be set in a small number of separate standalone header files. Therefore, users no longer have to modify small blocks of code within huge files as was necessary in previous versions (cppdefs.h and analytical.F). This makes it easy to distribute the configuration for a specific application via a small number of source code related files plus the inputs (grid, initial conditions, and forcing NetCDF files), while allowing users of the application to keep current with central code improvements via svn. This also takes care of all licensing issues. You are free to include your own statement of your contributions in the files you distribute. The license and copyright statements by the ROMS developer group remain in the source code distributed at

We recommend that users work with a local source code that is regularly updated with the official version at the ROMS svn repository using svn update. This will allow bug fixes and new code developments to be pushed out to users and minimize the risk of a user unwittingly working with code with known flaws. The user can download any of these set-ups from the test svn repository. Note that these applications do not include the source code since the user can checkout the latest version of ROMS from the svn repository. The recommended practice is to create a Projects root directory containing all applications. For example, the WC13 root directory for the data assimilation tutorial has the following strcuture:

 /WC13                                 Main California Current System 4D-Var applications
      /ARRAY_MODES                     Stabilized representer matrix array modes and clipping
      /Data                            Input data directory
      /Functionals                     Analytical expressions header files
      /I4DVAR                          Primal form of incremental, strong constraint 4D-Var, I4D-Var
      /I4DVAR_analysis_impact          I4D-Var analysis observation impact
      /Normalization                   4D-Var error covariance normalization coefficients
      /plotting                        4D-Var plotting scripts (Matlab and ROMS plotting package)
      /RBL4DVAR                        Dual form of 4D-Var, Restricted B-preconditioned Lanczos Analysis System, RBL4D-Var
      /RBL4DVAR_analysis_impact        RBL4D-Var analysis observation impact
      /RBL4DVAR_analysis_sensitivity   RBL4D-Var analysis observation sensitivity (adjoint of RBL4D-Var)
      /RBL4DVAR_forecast_impact        RBL4D-Var forecast observation impact
      /RBL4DVAR_forecast_sensitivity   RBL4D-Var forecast observation sensitivity (adjoint of RBL4D-Var)

If you check the I4DVAR sub-directory, you will find the following files:

              /Exercise_1.pdf       Exercise 1 instructions (4D-Var Tutorial)
              /Exercise_2.pdf       Exercise 2 instructions (4D-Var Tutorial)
              /Readme               Information and instructions
              /build_roms.csh       csh Unix script to compile application
              /        bash shell script to compile application
              /        job configuration script
              /  ROMS standard input script for WC13 2 hour averages
              /   ROMS standard input script for WC13 daily averages
              /            4D-Var standard input script template
              /wc13.h               WC13 header with CPP options

Notice that there is a local copy of the header file wc13.h containing the CPP options to use in this application. We highly recommend that the user have a local copy of the header file instead of editing the distributed files in the ROMS/Include directory. During the compilation build_roms.csh will direct make to use the appropriate one.