|
|
CMake is perfectly capable of handling Fortran code; however, examples
|
|
|
are less abundant than for C or C++. In the example below we write a
|
|
|
very small `CMakeLists.txt` to wrap a simple Fortran project.
|
|
|
|
|
|
The motivation for this was to easily compile Fortran code that came
|
|
|
with the [NORMA](http://www.igs.cnrs-mrs.fr/elnemo/NORMA/) package. The
|
|
|
distribution NORMA-1.0.tgz was downloaded and unpacked. [following
|
|
|
`CMakeLists.txt`](#Example_CMakeLists.txt "wikilink") was placed into
|
|
|
the `./software` directory where the NORMA sources are stored.
|
|
|
|
|
|
To build one would typically create a build directory at the same level
|
|
|
as `software`:
|
|
|
|
|
|
mkdir build && cd build
|
|
|
ccmake ../software
|
|
|
make
|
|
|
make install
|
|
|
|
|
|
and then configure, build and install.
|
|
|
|
|
|
The project is very simple:
|
|
|
|
|
|
- There are only a few fortran source code files in the software
|
|
|
directory.
|
|
|
- There are no library dependencies.
|
|
|
- Executables are typically installed in a bin directory in the
|
|
|
package itself (i.e. `NORMA/bin`) although the user is free to to
|
|
|
change the installation prefix.
|
|
|
- Two shell scripts are also installed alongside.
|
|
|
|
|
|
The `CMakeLists.txt` is commented and [additional
|
|
|
comments](#Comments_on_CMakeLists.txt "wikilink") can be found after it.
|
|
|
|
|
|
## Example CMakeLists.txt
|
|
|
|
|
|
# CMake project file for NORMA
|
|
|
|
|
|
cmake_minimum_required (VERSION 2.6)
|
|
|
project (NORMA)
|
|
|
enable_language (Fortran)
|
|
|
|
|
|
# make sure that the default is a RELEASE
|
|
|
if (NOT CMAKE_BUILD_TYPE)
|
|
|
set (CMAKE_BUILD_TYPE RELEASE CACHE STRING
|
|
|
"Choose the type of build, options are: None Debug Release."
|
|
|
FORCE)
|
|
|
endif (NOT CMAKE_BUILD_TYPE)
|
|
|
|
|
|
# default installation
|
|
|
get_filename_component (default_prefix ".." ABSOLUTE)
|
|
|
set (CMAKE_INSTALL_PREFIX ${default_prefix} CACHE STRING
|
|
|
"Choose the installation directory; by default it installs in the NORMA directory."
|
|
|
FORCE)
|
|
|
|
|
|
# FFLAGS depend on the compiler
|
|
|
get_filename_component (Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME)
|
|
|
|
|
|
if (Fortran_COMPILER_NAME MATCHES "gfortran.*")
|
|
|
# gfortran
|
|
|
set (CMAKE_Fortran_FLAGS_RELEASE "-funroll-all-loops -fno-f2c -O3")
|
|
|
set (CMAKE_Fortran_FLAGS_DEBUG "-fno-f2c -O0 -g")
|
|
|
elseif (Fortran_COMPILER_NAME MATCHES "ifort.*")
|
|
|
# ifort (untested)
|
|
|
set (CMAKE_Fortran_FLAGS_RELEASE "-f77rtl -O3")
|
|
|
set (CMAKE_Fortran_FLAGS_DEBUG "-f77rtl -O0 -g")
|
|
|
elseif (Fortran_COMPILER_NAME MATCHES "g77")
|
|
|
# g77
|
|
|
set (CMAKE_Fortran_FLAGS_RELEASE "-funroll-all-loops -fno-f2c -O3 -m32")
|
|
|
set (CMAKE_Fortran_FLAGS_DEBUG "-fno-f2c -O0 -g -m32")
|
|
|
else (Fortran_COMPILER_NAME MATCHES "gfortran.*")
|
|
|
message ("CMAKE_Fortran_COMPILER full path: " ${CMAKE_Fortran_COMPILER})
|
|
|
message ("Fortran compiler: " ${Fortran_COMPILER_NAME})
|
|
|
message ("No optimized Fortran compiler flags are known, we just try -O2...")
|
|
|
set (CMAKE_Fortran_FLAGS_RELEASE "-O2")
|
|
|
set (CMAKE_Fortran_FLAGS_DEBUG "-O0 -g")
|
|
|
endif (Fortran_COMPILER_NAME MATCHES "gfortran.*")
|
|
|
|
|
|
|
|
|
# build executables
|
|
|
set (NMPROGRAMS "diagstd" "diagrtb" "proj_modes_bin" "pdbmat")
|
|
|
set (EXECUTABLES "NORMA.exe" ${NMPROGRAMS})
|
|
|
set (SCRIPTS "gen_pert.sh" "pert_multi_mode.sh")
|
|
|
|
|
|
add_executable ("NORMA.exe" "NORMA.f")
|
|
|
foreach (p ${NMPROGRAMS})
|
|
|
add_executable (${p} "${p}.f")
|
|
|
endforeach (p)
|
|
|
|
|
|
# install executables and scripts
|
|
|
install (TARGETS ${EXECUTABLES}
|
|
|
RUNTIME DESTINATION "bin")
|
|
|
install (PROGRAMS ${SCRIPTS}
|
|
|
DESTINATION "bin")
|
|
|
|
|
|
## Comments on CMakeLists.txt
|
|
|
|
|
|
- Use cmake v2.6 or better for [optimum Fortran
|
|
|
support](CMake_Fortran_Issues "wikilink").
|
|
|
- Make sure that we build a RELEASE by default (and let the user know
|
|
|
in the GUI); uses example code from the docs.
|
|
|
- Set the default prefix to the non-standard installation scheme in
|
|
|
which one installs all component into the package directory. This
|
|
|
directory is assumed to be one above relative the build directory.
|
|
|
The full canonical path is obtained with the
|
|
|
[get_filename_component](http://www.cmake.org/cmake/help/cmake2.6docs.html#command:get_filename_component)
|
|
|
function.
|
|
|
- As it is typical for scientific Fortran code, the compiler
|
|
|
optimizations are fairly specific. Here we are trying to detect a
|
|
|
few common ones (gfortran, Intel ifort, g77) and set the compile
|
|
|
options accordingly. If all else fails we use -O2 and hope for the
|
|
|
best (but let the user know).
|
|
|
- The `NORMA.exe` binary is built from the source `NORMA.f` so we have
|
|
|
to say this explicitly with the
|
|
|
add_executable ("NORMA.exe" "NORMA.f")
|
|
|
line but the other binaries are simply built from corresponding .f
|
|
|
files and we write this as a simple foreach-loop.
|
|
|
- Executables are installed in the `bin` dir (which is relative to the
|
|
|
prefix).
|
|
|
- Finally, scripts are copied to the `bin` directory, too.
|
|
|
|
|
|
----
|
|
|
This page was initially populated by conversion from its [original location](https://public.kitware.com/Wiki/CMakeForFortranExample) in another wiki. |