\documentclass[a4paper,10pt,DIV9,headings=small]{scrartcl}
\usepackage{listings}
\usepackage{hyperref}
\usepackage[utf8]{inputenc}
\usepackage{xspace}

\lstset{language=c++, basicstyle=\normalfont\ttfamily\scriptsize,
  keywordstyle=\color{black}\bfseries, tabsize=4,
  stringstyle=\ttfamily, commentstyle=\it, extendedchars=true}

\newlength\tindent
\setlength{\tindent}{\parindent}
\setlength{\parindent}{0pt}
\renewcommand{\indent}{\hspace*{\tindent}}

\newcommand{\cmakelists}{\lstinline!CMakeLists.txt!\xspace}
\newcommand{\dune}{\lstinline!DUNE!\xspace}
\newcommand{\dunecommon}{\lstinline!dune-common!\xspace}
\newcommand{\duneistl}{\lstinline!dune-istl!\xspace}
\newcommand{\dunegeometry}{\lstinline!dune-geometry!\xspace}
\newcommand{\dunegrid}{\lstinline!dune-grid!\xspace}
\newcommand{\dunegridhowto}{\lstinline!dune-grid-howto!\xspace}
\newcommand{\dunecontrol}{\lstinline!dunecontrol!\xspace}
\newcommand{\duneproject}{\lstinline!duneproject!\xspace}
\newcommand{\dunemodule}{\lstinline!dune.module!\xspace}


\title{Building Dune with CMake - Frequently Asked Questions}
\author{Dominic Kempf$^\ast$ and Christoph Grüninger$^\spadesuit$}
\publishers{%
\vspace{10mm}
\normalsize{$^\ast$Interdisziplin\"ares Zentrum f\"ur Wissenschaftliches Rechnen,
Universit\"at Heidelberg,\\
Im Neuenheimer Feld 368, D-69120 Heidelberg, Germany}
\\
\normalsize{$^\spadesuit$Institut für Wasser- und Umweltsystemmodellierung,
Universität Stuttgart,\\
Pfaffenwaldring 61, D-70569 Stuttgart, Germany}
}


\begin{document}

\maketitle
\tableofcontents
\pagebreak

This document collects some frequently asked questions about building Dune with the new CMake build system. It is nowhere near complete and does not intend to be a technical documentation of the build system. Instead, it tries to sum up the essentials of the build system to users that do not (want to) care about the build system.

\section{What is CMake anyway?}
CMake...
 \begin{itemize}
  \item is an open source buildsystem tool developed at KITware.
  \item offers a one-tool-solution to all building tasks, like configuring, building, linking, testing and packaging.
  \item is a build system generator: It supports a set of backends called ``generators''
  \item is portable
  \item is controlled by ONE rather simple language
 \end{itemize}

Dune got support for CMake in version 2.3 alongside the old Autotools build system. It got the default in the
2.4 release. After that release, the Autotools build system will be removed from the master branch.

You can install cmake through your favorite package manager or downloading source code from www.cmake.org. The minimum required version to build Dune with CMake is 2.8.6.

\section{How do I use Dune with CMake?}

As with the Autotools, the build process is controlled by the script \dunecontrol, located in \lstinline!dune-common/bin!.
There is a compatibility layer that will translate all the configure flags from your opts file into the corresponding
CMake flags. While this is a great tool to determine how to do the transition, in the long run you should switch to
a CMake-only approach.

\dunecontrol will pickup the variable \lstinline!CMAKE_FLAGS! from your opts file and use it as command line options for
any call to CMake. There, you can define variables for the configure process with CMakes \lstinline!-D! option; just as
with the C pre-processor.

The most important part of the configure flags is to tell the build system where to look for external libraries. You can either use the variable \lstinline!CMAKE_PREFIX_PATH! for that or set the variable given in the documentation of the corresponding find module (see below for details).

\section{What files in a dune module belong to the CMake build system?}
\label{files}
Every directory in a project contains a file called \cmakelists, which is written in the CMake language.
You can think of these as a distributed configure script. Upon configure, the top-level \cmakelists is executed.
Whenever an \lstinline!add_subdirectory! command is encountered, the \cmakelists of that sub-directory is executed.
The top-level \cmakelists is special, because it sets up the entire Dune module correctly. You should not delete the
auto-generated parts of it.

Additionally, a Dune module can export some cmake modules. A cmake module is a file that contains one or more build system macros meant for downstream use. If a module provides modules, they can be found in the subfolder \lstinline!cmake/modules!. The module
\begin{lstlisting}
 dune-foo/cmake/modules/DuneFooMacros.cmake
\end{lstlisting}
is special: Its contents are always executed when configuring the module \lstinline!dune-foo! or any other Dune module, that
requires or suggests the module \lstinline!dune-foo!. This is the perfect place to put your checks for external packages,
see section~\ref{external} below.

The file \lstinline!config.h.cmake! defines a template for the section of \lstinline!config.h!, that is generated by the module.

The file \lstinline!stamp-regenerate-config-h! also belongs to the CMake build system. You can trigger regeneration of \lstinline!config.h! by touching it.

\section{How do I port an existing module?}
\label{porting}
There is multiple approaches to this:
\begin{itemize}
 \item First, check section~\ref{simplified} and decide whether such simple approach is sufficient for your project.
 \item There is the python script \lstinline!dune-common/bin/am2cmake.py!, which automatically generates \lstinline!CMakeLists.txt!'s from its \lstinline!Makefile.am! counterparts. While this works fine, for many modules the resulting files look very autotoolish and are often too complicated.
 \item Copy the top-level \lstinline!CMakeLists.txt! file from a freshly generated Dune module (you still need to adjust the project name to have it match the module name) and write all other \lstinline!CMakeLists.txt! by hand. This sounds cumbersome, but its actually not very much work if you read below advices.
\end{itemize}

In order to write your own \lstinline!CMakeLists.txt! files you should be aware of the following basic commands of the CMake language.

\begin{itemize}
 \item \lstinline!add_subdirectory(dir)! immediately executes the \lstinline!CMakeLists.txt! in the \lstinline!dir! subfolder.
 \item \lstinline!add_executable(target src1 [, src2 ..])! adds an executable named \lstinline!target!. Note that, unlike in autotools, target names have to be unique throughout the entire project. The given sources are the \lstinline!*.cc! files that are used to determine the dependencies of the target. Configuring the targets with the correct flags and linked libraries is described in section~\ref{target}.
 \item \lstinline!add_test(testname execname [args..])! registers a test. If \lstinline!execname! matches a target name within the project, it is automatically replaced with the corresponding executable, but any executable may be given.
 \item \lstinline!install(FILES files DESTINATION dest)! \footnote{Note that CMake uses positional arguments for some commands and named arguments for more complicated ones. If you ever happen to write your own macro, try going for named arguments using the module \lstinline!CMakeParseArguments!} Use to define the install location of a list of headers.
\end{itemize}

For a detailed reference, use:
\begin{lstlisting}
 cmake --help-command <command>
\end{lstlisting}

If your module requires any other packages than the dune modules listed in your \lstinline!dune.module! file, you should also use the command \lstinline!find_package! in the module \lstinline!dune-foo/cmake/modules/DuneFooMacros.cmake! (as mentioned in section~\ref{files}). How to do this with external packages not yet supported by Dune is covered in section~\ref{external}.

\section{How do I modify the flags and linked libraries of a given target?}
\label{target}
Again, there are multiple ways to do this. The Dune build system offers macros to make this task as easy as possible. For each external module, there is a macro \lstinline!add_dune_*_flags(targets)!. Those macros should cover most flags. Example usage:
\begin{lstlisting}
add_executable(foo foo.cc)
add_dune_umfpack_flags(foo)
add_dune_mpi_flags(foo)
\end{lstlisting}
There is also the macro \lstinline!add_dune_all_flags(targets)!, which uses the same flag registry mechansim then the simplfied build system in section~\ref{simplified}.

If you want to fully control the configuration of the targets, you can do so. Build system entities such as targets, directories and tests do have so called properties in CMake. You can access and modify those properties via the commands \lstinline!get_property! and \lstinline!set_property!. You can for example use those to modify a targets \lstinline!COMPILE_DEFINITIONS! or \lstinline!INCLUDE_DIRECTORIES! property:
\begin{lstlisting}
add_executable(foo foo.cc)
set_property(TARGET foo APPEND PROPERTY COMPILE_DEFINITIONS <somedefinition>)
set_property(TARGET foo APPEND PROPERTY INCLUDE_DIRECTORIES <somepath>)
\end{lstlisting}
For a full list of properties, check the manual:
\begin{lstlisting}
 cmake --help-property-list
\end{lstlisting}
Manually linking libraries can be done through the \lstinline!target_link_libraries! command instead of manually tweaking properties.

\section{How do I link against external libraries, that are not checked for by Dune?}
\label{external}

While there might be many solutions that make your application work, there is only one clean solution to this: You have
to provide a find module for the package. A find module is a CMake module that follows a specific naming scheme: For
an external package called \lstinline!SomePackage! it is called \lstinline!FindSomePackage.cmake!. Note that CMake
treats package names case sensitive. If CMake encounters a \lstinline!find_package(SomePackage)! line, it searches
its module include paths for this find module. A good read to get started writing a find module is
\href{http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries}{\emph{How to find Libraries}} in the CMake wiki.

Depending on how common your external package is, you may not even need to write the find module on your own.
You can have a look at the list of find modules shipped by CMake \footnote{Linux distributions may put them at
\lstinline!/usr/share/cmake-<version>/modules! or \lstinline!/usr/share/cmake/modules!} or simply search the
internet for the module name and profit from other open-source project's work.

It is considered good style to also provide a macro \lstinline!add_dune_somepackage_flags(targets)!.

\section{What is an out-of-source build?}
\label{outofsource}

An out-of-source build does leave the version-controlled source tree untouched and puts all files that are
generated by the build process into a different directory -- the build directory. The build directory does mirror
your source tree's structure as seen in the following figure:
\begin{center}
\begin{tabular}{lcr}
\begin{minipage}{.4\textwidth}
\begin{verbatim}
dune-foo/
  CMakeLists.txt
  dune/
    foo/
      CmakeLists.txt
  src/
    CMakeLists.txt
\end{verbatim}
\end{minipage} &
$\Rightarrow$ &
\begin{minipage}{.4\textwidth}
\begin{verbatim}
build-dune-foo/
  Makefile
  dune/
    foo/
      Makefile
  src/
    Makefile
\end{verbatim}
\end{minipage}
\end{tabular}
\end{center}
Using the \lstinline!Unix Makefiles! generator, your Makefiles are generated in the build tree, so that is where you
have to call \lstinline!make!. There are multiple advantages with this approach, such as a clear separation between
version controlled and generated files and you can have multiple out-of-source builds with different configurations
at the same time.

Out-of-source builds are the default with CMake. In-source builds are strongly discouraged.

By default, a subfolder \verb!build-cmake! is generated within each dune module and is used as a build directory. You can customize this folder through the \verb!--builddir! option of \verb!dunecontrol!. Give an absolute path to the \verb!--builddir! option, you will get something like this:

\begin{center}
 \begin{verbatim}
build/
  dune-common/
    Makefile
  dune-foo/
    Makefile
\end{verbatim}
\end{center}


\section{What is the new simplified build system and how do I use it?}
\label{simplified}
Dune offers a simplified build system, where all flags are added to all targets and all libraries are linked to all targets. You can enable the feature with:
\begin{lstlisting}
 dune_enable_all_packages(INCLUDE_DIRS [include_dirs]
                          COMPILE_DEFINITIONS [compile_definitions]
                          MODULE_LIBRARIES [libraries]
                          [VERBOSE] [APPEND]
                         )
\end{lstlisting}
This will modify all targets in the directory of the \cmakelists, where you put this, and also in all
sub-directories. The compile flags for all found external packages are added to those targets and the target is
linked against all found external libraries. The \lstinline!VERBOSE! option will prompt those flags upon
configure. This is especially useful for application modules.

To use this while using custom external packages, you have to register your flags. Check the module
\begin{lstlisting}
 dune-common/cmake/modules/DuneEnableAllPackages.cmake
\end{lstlisting}

Some special care has to be given, if your module does build one or more library which targets within the module do link against. Carefully read the in-module documentation of above module in that case.

\section{How do I change my compiler and compiler flags?}
\label{compiler}
In general, there are multiple ways to do this:
\begin{itemize}
 \item Setting the CMake variables \verb!CMAKE_{C,CXX}_COMPILER! from the opts file
 \item Setting those variables within the project with the \verb!set! command
 \item Setting the environment variables \verb!CC!, \verb!CXX! etc.
\end{itemize}

The first option is the recommended way. Whenever you change your compiler, you should delete all build
directories. For some CMake versions, there is a known CMake bug, that requires you to give an absolute path
to your compiler, but Dune will issue a warning, if you violate that.

You can modify your default compiler flags by setting the variables
\lstinline!CMAKE_{C,CXX}_FLAGS! in your opts file. Note, you can define build-type specific
flags with \lstinline!CMAKE_{C,CXX}_FLAGS_{DEBUG,RELEASE}!. You can switch the build type
with \lstinline!CMAKE_BUILD_TYPE={Release,Debug}!.

\section{How should I handle ini and grid files in an out-of-source-build setup?}
\label{inifiles}
Such files are under version control, but they are needed in the build directory. The module
\begin{lstlisting}
 dune-common/cmake/modules/DuneSymlinkOrCopy.cmake
\end{lstlisting}
delivers macros for that purpose.

The simplest way to solve the problem is to add  \verb!-DDUNE_SYMLINK_TO_SOURCE_TREE=1! to your opts file. This will execute \lstinline!dune_symlink_to_source_tree()! to your top-level \lstinline!CMakeLists.txt!. This will add a symlink \lstinline!src_dir! to all subdirectories of the build directory, which points to the corresponding directory of the source tree. This will only work on platforms that support symlinking. For other (more portable) solutions, check the documentation of above module.

\section{How do I use CMake with IDEs?}
\label{ides}
As already said, CMake is merely a build system generator with multiple backends (called a generator). Using IDEs requires a different generator. Check \lstinline!cmake --help! for a list of generators. You can then add the \lstinline!-G! to the \verb!CMAKE_FLAGS! in your opts file, like:
\begin{lstlisting}
 -G'Eclipse CDT4 - Unix Makefiles'
\end{lstlisting}
Note that the generator name has to match character by character, including case and spaces.

\section{I usually modify my CXXFLAGS upon calling make. How can I do this in CMake?}
\label{cxxflags}
This violates the CMake philosophy and there is no clean solution to achieve it. The CMake-ish solution would be
to have for each configuration one out-of-source build. We have nevertheless implemented a workaround. It can be enable
by setting \lstinline!ALLOW_CXXFLAGS_OVERWRITE=ON! in your opts file. You can then type:
\begin{lstlisting}
 make CXXFLAGS="<your flags>" <target>
\end{lstlisting}
Furthermore any C pre-processor variable of the form \lstinline!-DVAR=<value>! can be overloaded on the command line
and the grid type can be set via \lstinline!GRIDTYPE="<grid type>"!.

Note this only works with generators that are based on Makefiles and several Unix tools like bash must be
available.

\section{How do I run the test suite from CMake?}
\label{tests}
The built-in target to run the tests is called \lstinline!test! instead of Autotools' \lstinline!check!.
It is a mere wrapper around CMake's own testing tool CTest. You can check \lstinline!ctest --help!
for a lot of useful options, such as choosing the set of tests to be run by matching regular expressions or
showing the output of failed tests.

Although this is not the CMake-ish way, \lstinline!make test! also builds the tests before executing them.
This behavior will change in the near future.

\section{Where can I get a list of all configuration options?}
\label{listconfigurations}
There are two ways. Either use \lstinline!ccmake! which is a graphical user interface and shows
you all variables and their values after a configure run. You can edit these values, too. Or
add \lstinline!-LH! to the CMake call, then CMake will print all variables and their values
after configuration.

There is nothing comparable to Autotools' \lstinline!configure --help!.

\section{Can I disable an external dependency?}
\label{disabledependency}
To disable an external dependency \lstinline!Foo!, add
\begin{lstlisting}
 -DCMAKE_DISABLE_FIND_PACKAGE_Foo=TRUE
\end{lstlisting}
to your opts file. The name of the dependency is case sensitive but there is no canonical naming
scheme; it can be \lstinline!FOO!, \lstinline!Foo!, or even something else. See the output of configure
to get the right name.

Make sure to not use cached configure results by deleting the cache file or the build directory, cf.
\ref{troubleshoot}.

\section{How do I switch between parallel and sequential builds?}
\label{parallel}
Dune builds with CMake are parallel if and only if MPI is found. To have a sequential build despite an installed MPI library, you have to explicitly disable the corresponding find module by setting
\begin{lstlisting}
 -DCMAKE_DISABLE_FIND_PACKAGE_MPI=TRUE
\end{lstlisting}
in the \lstinline!CMAKE_FLAGS! of your opts file.

\section{Why is it not possible anymore to do make headercheck?}
\label{headercheck}
The headercheck feature has been disabled by default. You can enable it by setting the CMake variable \lstinline!ENABLE_HEADERCHECK=1! through your opts file. This step has been necessary, because of the large amount of additional file the headercheck adds to the build directory. A better implementation has not been found yet, because it simply does not fit the CMake philosophy.

\section{How do I troubleshoot?}
\label{troubleshoot}
CMake caches aggressively which makes it bad at recognizing changed configurations.

To trigger a fresh run of configure, you can delete the \lstinline!CMakeCache.txt! file from
the build directory and maybe save some compilation time afterward.

Whenever
you experience any problems, your first step should be to delete all build directories. Nice trick:
\begin{lstlisting}
 dunecontrol exec rm -rf build-cmake
\end{lstlisting}
This will remove all build directories from all DUNE modules.

Later on you can get an error log from the file \lstinline!CMakeError.log! in the \lstinline!CMakeFiles!
sub-directory of your build directory. This is what you should send to the mailing list alongside the
description of your setup and efforts to help us help you.

\section{Where can I get help?}
\label{help}

The CMake manual is available on the command line:
 \begin{itemize}
  \item \verb!cmake --help-command-list!
  \item \verb!cmake --help-command <command>!
  \item \verb!cmake --help-property-list!
  \item \verb!cmake --help-property <property>!
  \item \verb!cmake --help-module-list!
  \item \verb!cmake --help-module <module>!
 \end{itemize}

To get help on which variables are picked up by CMake, there is a CMake wiki page collecting them.
Of course, there is also Google, StackOverflow and the CMake Mailing list (archive).
For problems specific to DUNE's build system, ask on our mailing lists.
\end{document}
