CMakeForFortranExample: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
No edit summary
(Replace content with link to new CMake community wiki)
 
Line 1: Line 1:
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 <code>CMakeLists.txt</code> to wrap a simple Fortran project.
{{CMake/Template/Moved}}


The motivation for this was to easily compile Fortran code that came with the [http://www.igs.cnrs-mrs.fr/elnemo/NORMA/ NORMA] package. The distribution NORMA-1.0.tgz was downloaded and unpacked. [[#Example CMakeLists.txt|following <tt>CMakeLists.txt</tt>]] was placed into the <tt>./software</tt> directory where the NORMA sources are stored.
This page has moved [https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/languages/fortran/ForFortranExample here].
 
To build one would typically create a build directory at the same level as <tt>software</tt>:
<pre>
mkdir build && cd build
ccmake ../software
make
make install
</pre>
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. <tt>NORMA/bin</tt>) although the user is free to to change the installation prefix.
* Two shell scripts are also installed alongside.
 
The <tt>CMakeLists.txt</tt> is commented and [[#Comments on CMakeLists.txt|additional comments]] can be found after it.
 
== Example CMakeLists.txt ==
<pre># 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")
</pre>
 
== Comments on CMakeLists.txt ==
* Use cmake v2.6 or better for [[CMake Fortran Issues|optimum Fortran support]].
* 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 [http://www.cmake.org/cmake/help/cmake2.6docs.html#command:get_filename_component 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 <tt>NORMA.exe</tt> binary is built from the source <tt>NORMA.f</tt> so we have to say this explicitly with the <pre>add_executable ("NORMA.exe" "NORMA.f")</pre>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 <tt>bin</tt> dir (which is relative to the prefix).
* Finally, scripts are copied to the <tt>bin</tt> directory, too.
 
{{CMake/Template/Footer}}

Latest revision as of 15:41, 30 April 2018


The CMake community Wiki has moved to the Kitware GitLab Instance.

This page has moved here.