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:
Contents
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
GLUT: get it here http://www.opengl.org/resources/libraries/glut.html; current (as of this writing) is version 3.7.6 There is another implementation called freeglut. It might work, too. Or might not, if you know edit this page. Both packages come with good installation instructions which will not be reproduced here.
get f90gl http://math.nist.gov/f90gl; current (as of this writing) is 1.2.10, even if the homepage says it it 1.2.9
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'