Building common software packages with gfortran

This page is intended to give you a little help to get common scientific software built with gfortran. Some support gfortran out-of-the-box, for others it might need tweaking the makefile... Share the knowledge!

This page currently features:

BLAS (Basic Linear Algebra Subprograms)

The software package is available from http://www.netlib.org/blas/ (direct link: http://www.netlib.org/blas/blas.tgz). Get the archive, and untar it into an empty directory; you now have a bunch of .f files (BLAS doesn't come with a makefile). With these Fortran files, you can created either a static library or a shared library. A shared library libblas.so is built with:

gfortran -shared -O2 *.f -o libblas.so -fPIC

while a static library is built with the two following commands (the first compiles code into object files, and the second archives the object files into a static archive):

gfortran -O2 -c *.f
ar cr libblas.a *.o

After that, you can link programs with BLAS using -lblas on command-line (and optionnaly, -L/path/to/blas if the library is not in the current directory). You can also specify different optimization options when compiling BLAS, such as -mtune=pentium4 or -ffast-math

LAPACK (Linear Algebra PACKage)

LAPACK is available from http://www.netlib.org/lapack/. Download the source code, untar it, and change the file make.inc so that it contains:

####################################################################
#  LAPACK make include file.                                       #
#  LAPACK, Version 3.0                                             #
#  June 30, 1999                                                  #
####################################################################
#
SHELL = /bin/sh
#
#  The machine (platform) identifier to append to the library names
#
PLAT =
#
#  Modify the FORTRAN and OPTS definitions to refer to the
#  compiler and desired compiler options for your machine.  NOOPT
#  refers to the compiler options desired when NO OPTIMIZATION is
#  selected.  Define LOADER and LOADOPTS to refer to the loader and
#  desired load options for your machine.
#
FORTRAN  = gfortran
OPTS     = -O2 -mtune=pentium4
DRVOPTS  = $(OPTS)
NOOPT    = -O0
LOADER   = gfortran
LOADOPTS = -O2 -mtune=pentium4
#
#  The archiver and the flag(s) to use when building archive (library)
#  If you system has no ranlib, set RANLIB = echo.
#
ARCH     = ar
ARCHFLAGS= cr
RANLIB   = ranlib
#
#  The location of the libraries to which you will link.  (The
#  machine-specific, optimized BLAS library should be used whenever
#  possible.)
#
BLASLIB      = -lblas -L/path/to/blas
LAPACKLIB    = liblapack$(PLAT).a
TMGLIB       = tmglib$(PLAT).a
EIGSRCLIB    = eigsrc$(PLAT).a
LINSRCLIB    = linsrc$(PLAT).a

where /path/to/blas is the path to the BLAS library you just compiled (see above). With this modified make.inc you can now run make in this folder, which will compile the static LAPACK library liblapack.a . You can tweak the optimization options (variable OPTS , but take care not to change NOOPT

Windows Users of the "native Windows" mingw compiled gfortran : The above modifications to make.inc are appropriate, but the make process may fail due to a technical problem with make.exe on Windows. Be consoled, this page may help LAPACK on Windows .

LAPACK95 (F95 interface to Linear Algebra PACKage)

LAPACK95 is available from http://www.netlib.org/lapack95/. Download the source code, untar it, and change the file make.inc so that it contains:

#  -- LAPACK95 interface driver routine (version 2.0) --
#     UNI-C, Denmark; Univ. of Tennessee, USA; NAG Ltd., UK
#     August 5, 2000
#
FC       = gfortran -ffree-form
FC1      = gfortran -ffixed-form
# -dcfuns  Enable recognition of non-standard double
#          precision  complex intrinsic functions
# -dusty   Allows the compilation and execution of "legacy"
#          software by downgrading the category  of  common
#          errors  found  in  such software from "Error" to
# -ieee=full enables all IEEE arithmetic facilities
#          including non-stop arithmetic.

OPTS0    = -mcpu=G4 -pipe -maltivec -mabi=altivec -mpowerpc-gfxopt -ftree-vectorize
MODLIB   = -I./../lapack95_modules
OPTS1    = -c -O3 $(OPTS0)
OPTS3    = $(OPTS1) $(MODLIB)
OPTL     = -o
OPTLIB   =

LAPACK_PATH = /usr/lib/

LAPACK95 = ../lapack95.a
LAPACK77 = $(LAPACK_PATH)/liblapack.a
TMG77    = $(LAPACK_PATH)/tmglib.a
BLAS     = $(LAPACK_PATH)/libblas.a

LIBS     = $(LAPACK95) $(TMG77) $(LAPACK77) $(BLAS)
SUF      = f90

XX = 'rm' -f $@; \
        'rm' -f $@.res; \
        $(FC) $(OPTS0) -o $@ $(MODLIB) $@.$(SUF) $(OPTLIB) $(LIBS); \
        $@ < $@.dat > $@.res; \
        'rm' -f $@

YY = $(FC) $(OPTS0) -o $@ $(MODLIB) $@.$(SUF) $(OPTLIB) $(LIBS)

.SUFFIXES: .f90 .f .o

.$(SUF).o:
        $(FC) $(OPTS3) $<

.f.o:
        $(FC1) $(OPTS3) $<

where OPTS0 describes your own specific cpu/arch fflags. You must obviously check for your LAPACK_PATH too.

LAM/MPI

LAM/MPI is a free implementation of the MPI spec, widely used for parallel computing. This is mainly implemented in C, but contains a Fortran interface. Download the latest version (7.1.1 as of writing this) from the LAM/MPI website and untar it. The directory created contains a configure script, which you have to run (with correct options) to generate the makefile. The basic usage, to compile LAM/MPI and install it into /path/to/install is:

FC=gfortran ./configure --prefix=/path/to/install
make
make install

_You might need to become root (or get admin privileges) to perform the last operation make install if you chose a /path/to/install which has restricted access /usr/local for example)._

You can specify additionnal options for gfortran with the FFLAGS variable FC=gfortran FFLAGS -O2 -mtune=pentium4' ./configure=, for example). A complete list of options is available by typing ./configure --help Have fun!

F90gl

F90gl is an interface to access OpenGL http://www.opengl.org, a cool library for 3D graphics, from Fortran 90.

Prerequisites

Again, follow the installation instructions (Hint: copy mf8lum to Makefile; you will need to do small edits like changing g95 to gfortran etc.)

I tested all example programs that come with f90gl and encountered 2 problems: In glutdino, the extrusion seems to fail. In molehill, the color is white only. This might be due to MESA rather than f90gl, but requires further study. Reports from others are wellcome.

Example programs were compiled with a two-line shell script:

gfortran $1.f90 -g -L /usr/X11R6/lib/ -lX11 libf90GLU.a libf90glut.a libglsmap.a libmui.a libf90GL.a \
    libgle.a libglut.a -I ../include/GL/ -lMesaGLU -lMesaGL -lXi -lXmu -o $1

Posix calls

There is a library available at http://savannah.nongnu.org/projects/posix90/

netCDF

The Network Common Data Form is an open-standard, self-describing, machine-independent data format, and set of I/O APIs for that format, widely used for array-oriented data, especially in the earth sciences. In mid-Sep 2011 I built netCDF 4.1.3 from source on a laptop running debian testing

$ uname -rv
2.6.39-2-amd64 #1 SMP Tue Jul 5 02:51:22 UTC 2011
$ gcc --version
gcc (Debian 4.6.1-4) 4.6.1
...
$ gfortran --version
GNU Fortran (Debian 4.6.1-4) 4.6.1
...

using the following bash scriptlet (parameters of which you may want to change in accordance with local desires):

# Note need for `sudo` below, if installing canonically (e.g., to /usr/lib)
# To check your syntax before execution, comment out the 'eval` statement below.
NETCDF_VERSION="4.1.3"
URI="http://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-${NETCDF_VERSION}.tar.gz"
TARGET_FN="$(basename ${URI})"
# TARGET_DIRROOT="/tmp/netcdf-${NETCDF_VERSION}"
# will make /tmp/netcdf-${NETCDF_VERSION}
TARGET_DIRROOT="/tmp"
TARGET_DIR="${TARGET_DIRROOT}/netcdf-${NETCDF_VERSION}"
for CMD in \
  "mkdir -p ${TARGET_DIRROOT}" \
  "pushd ${TARGET_DIRROOT} > /dev/null" \
  "curl ${URI} | tar xfz -" \
  "find ${TARGET_DIR} -type f -name 'configure'" \
  "popd > /dev/null" \
  "pushd ${TARGET_DIR} > /dev/null" \
  "export FC=\"$(which gfortran)\"" \
  "./configure --disable-netcdf-4 --disable-dap --disable-hdf4 --prefix=/usr --enable-docs-install --enable-shared " \
  "make check" \
  "sudo make install" \
  "popd > /dev/null" \
; do
  echo -e "$ ${CMD}"
  eval "${CMD}"
done

Afterward I was able to check my install with

$ nc-config --all
This netCDF 4.1.3 has been built with the following features:

  --cc        -> gcc
  --cflags    ->  -I/usr/include
  --libs      -> -L/usr/lib -lnetcdf

  --cxx       -> g++
  --has-c++   -> yes

  --fc        -> /usr/bin/gfortran
  --fflags    -> -g -O2 -I/usr/include
  --flibs     -> -L/usr/lib -lnetcdff -lnetcdf
  --has-f77   -> yes
  --has-f90   -> yes

  --has-dap   -> no
  --has-nc2   -> yes
  --has-nc4   -> no
  --has-hdf5  -> no
  --has-hdf4  -> no
  --has-pnetcdf-> no
  --has-szlib ->

  --prefix    -> /usr
  --includedir-> /usr/include
  --version   -> netCDF 4.1.3

I/O API

IOAPI is an open-source API wrapping input/output to structured, scientific data sources/sinks including netCDF files, in-memory buffers, and PVM mailboxes. It is used by Earth system models including WRF and CMAQ. In late-Sep 2011 I built IOAPI-3.1-beta1 from source on a laptop running debian testing

$ uname -rv
2.6.39-2-amd64 #1 SMP Tue Jul 5 02:51:22 UTC 2011
$ gcc --version
gcc (Debian 4.6.1-4) 4.6.1
...
$ gfortran --version
GNU Fortran (Debian 4.6.1-4) 4.6.1
...

for this "single configuration": i.e., to run serially on a 64-bit linux using gcc/gfortran. (Note that the IOAPI Makefiles support simultaneous building for multiple targets.) Note that the IOAPI developers emphasize building IOAPI using the same compiler/linker flags as were used to build netCDF, if one intends to use IOAPI to wrap access to netCDF files. Toward that end, I used the following bash scriptlet (parameters of which you may want to change in accordance with local desires), after building netCDF from source:

IOAPI_VERSION="3.1-beta1"
URI="http://www.baronams.com/products/ioapi/ioapi-3.1.tar.gz"
TARGET_DIRROOT="/tmp"
TARGET_DIR="${TARGET_DIRROOT}/ioapi-${IOAPI_VERSION}"
# INSTALL_DIRROOT="/usr/local"
# `sudo make install` fails, so just do
INSTALL_DIRROOT="/tmp/install"
# then move manually
INSTALL_DIR="${INSTALL_DIRROOT}/ioapi-${IOAPI_VERSION}"
NETCDF_LIBS="/usr/lib/libnetcdf*"

export FC="$(which gfortran)"
export MFLAGS='-ffast-math'
export ARCHLIB='-lc -lgfortran'
# This token means "build for 64-bit linux using gfortran (and gcc)"
export BIN='Linux2_x86_64gfort'
export INSTALL="${INSTALL_DIR}"

# Get the source tarball.
for CMD in \
  "rm -fr ${TARGET_DIR}" \
  "rm -fr ${INSTALL_DIR}" \
  "mkdir -p ${TARGET_DIR}" \
  "mkdir -p ${INSTALL_DIR}" \
  "pushd ${TARGET_DIR} > /dev/null" \
  "curl ${URI} | tar xfz -" \
  "popd > /dev/null" \
; do
  echo -e "$ ${CMD}"
  eval "${CMD}"
done

# Build using -lnetcdff: not currently supported by IOAPI Makefiles.
pushd ${TARGET_DIR} > /dev/null
for F in $(find $(pwd) -name 'Make*' | xargs grep -le '-lioapi\s*-lnetcdf') ; do
  for CMD in \
    "cp ${F} ${F}~" \
    "chmod a-w ${F}~" \
    "sed -si 's|-lioapi\s*-lnetcdf|-lioapi -lnetcdff -lnetcdf|g' ${F}" \
  ; do
    echo -e "$ ${CMD}"
    eval "${CMD}"
  done
done

# To build serially, assign null values to OMP* configuration variables.
for F in $(find $(pwd) -name 'Make*' | xargs grep -le 'OMPFLAGS\|OMPLIBS') ; do
  for CMD in \
    "sed -si 's|^\s*OMPFLAGS\s*=.*$|OMPFLAGS=|g' ${F}" \
    "sed -si 's|^\s*OMPLIBS\s*=.*$|OMPLIBS=|g' ${F}" \
  ; do
    echo -e "$ ${CMD}"
    eval "${CMD}"
  done
done

# Do not install NOTDIR, a kludge for folks who cannot install netCDF.
for F in $(find $(pwd) -name 'Make*' | xargs fgrep -le 'NOTDIR') ; do
  echo -e "${F}"
  for CMD in \
    "sed -si '/\t(cd\s*\$(NOTDIR)\s*;\s*make\s*install)/d' ${F}" \
    "popd > /dev/null" \
  ; do
    echo -e "$ ${CMD}"
    eval "${CMD}"
  done
done

# Fix default values in Makefiles, then make configuration directories.
for CMD in \
  "pushd ${TARGET_DIR} > /dev/null" \
  "sed -si 's|BASEDIR\s*=\s*\${HOME}/web31|BASEDIR=${TARGET_DIR}|' Makefile" \
  "sed -si 's|INSTALL\s*=\s*/SOMEWHERE|INSTALL=${INSTALL}|' Makefile" \
  "popd > /dev/null" \
  "pushd ${TARGET_DIR}/ioapi > /dev/null" \
  "cp Makefile.nocpl Makefile" \
  "sed -si 's|BASEDIR = \${HOME}/apps|BASEDIR = ${TARGET_DIR}|' Makefile" \
  "sed -si 's|INSTALL\s*=\s*/SOMEWHERE|INSTALL=${INSTALL}|' Makefile" \
  "sed -si 's|-Wsurprising||g' Makeinclude.${BIN}" \
  "popd > /dev/null" \
  "pushd ${TARGET_DIR} > /dev/null" \
  "make dirs" \
  "popd > /dev/null" \
; do
  echo -e "$ ${CMD}"
  eval "${CMD}"
done

# Put netCDF archives where needed, fix more Makefiles.
for CMD in \
  "pushd ${TARGET_DIR}/${BIN} > /dev/null" \
  "cp ${NETCDF_LIBS} ./" \
  "popd > /dev/null" \
  "pushd ${TARGET_DIR} > /dev/null" \
  "sed -si 's|LIBINST\s*=\s*\$(INSTALL)/\$(BIN)|LIBINST=\$(INSTALL)/lib|' Makefile" \
  "sed -si 's|BININST\s*=\s*\$(INSTALL)/\$(BIN)|BININST=\$(INSTALL)/bin|' Makefile" \
  "sed -si 's|CPLMODE\s*=\s*cpl|CPLMODE=nocpl|' Makefile" \
  "sed -si 's|IOAPIDEFS\s*=\s*-DIOAPICPL|IOAPIDEFS=|' Makefile" \
  "sed -si 's|PVMINCL\s*=\s*\$(PVM_ROOT)/conf/\$(PVM_ARCH).def|PVMINCL=/dev/null|' Makefile" \
  "echo -e 'nocpl:  dirs fix
\t(cd \$(IODIR)   ; make -f Makefile.nocpl all)
\t(cd \$(TOOLDIR) ; make -f Makefile.nocpl all)
' >> Makefile" \
; do
  echo -e "$ ${CMD}"
  eval "${CMD}"
done

# Payload.
for CMD in \
  "make configure" \
  "make nocpl" \
  "make install" \
; do
  echo -e "$ ${CMD}"
  eval "${CMD}"
done
echo -e 'REMEMBER TO MOVE FILES FROM /tmp/install to /usr/local'

None: GfortranBuild (last edited 2011-09-25 03:25:10 by 75)