deal.II CMake documentation
Author: the deal.II authors <authors @ dealii.org>
Keywords: deal.II

# Details on the deal.II configuration and build system

The deal.II README file gives an overview over the basics of configuring and building the deal.II library. This page provides more details about using the deal.II CMake build system.

## Operating cmake

When configuring deal.II by running `cmake`, the `cmake` program creates a cache in the current (build) directory that contains the values of all (cached) variables that had previously been passed as command line arguments, been found through running tests, or had otherwise been set.

On a subsequent call to `cmake`, e.g. to change the configuration or due to a callback from the build system because some configuration file (the `CMakeLists.txt` and `cmake/<..>.cmake` files) has changed, `cmake` will only run whatever tests are necessary; values for variables that are already in the cache are not re-evaluated. This means that calling `cmake` a second time without any arguments at all in a situation like this

    mkdir build
    cd build
    cmake -DCMAKE_INSTALL_PREFIX=/path/install/dir ../deal.II
    cmake ../deal.II

has no effect: In particular, the `CMAKE_INSTALL_PREFIX` specified on the first invocation of `cmake` is cached and therefore still valid after the second invocation of `cmake` This is different from the way the `autoconf/configure` mechanism worked.

The cache has an important reason: one can modify all sort of configuration parameters and thereby interact with the configuration system in rather powerful (and, possibly, destructive) ways. For example, the following commands

    mkdir build
    cd build
    cmake  ../deal.II
    ccmake

first configure a bare-bone setup and then call the `ccmake` program -- an interactive editor for the cached variables. Similarly,

    mkdir build
    cd build
    cmake  ../deal.II
    cmake -D<OPTION>=<VALUE> [...] ../deal.II

sets a variable the second time around without destroying all the configuration that has happened the first time around. Likewise,

    mkdir build
    cd build
    cmake  ../deal.II
    cmake -DDEAL_II_WITH_METIS=OFF .
    cmake -DDEAL_II_WITH_TRILINOS=ON -DTRILINOS_DIR=/path/to/trilinos .

switches off support for the METIS library that may have been automatically detected during the first invocation of `cmake` and enables support for Trilinos by enabling `DEAL_II_WITH_TRILINOS` and setting `TRILINOS_DIR`.

### Manipulating the cache

A cached variable can be set on the command line via

    cmake -D<VARIABLE>=<VALUE> .

Cached variables can be removed from the cache via

    cmake -U<VARIABLE> .

It is possible to use `-U` together with a globbing expression. E.g. to remove the current feature configuration and rerun the autodetection one can invoke

    cmake -U"DEAL_II_WITH_*" .

### `ccmake` and special build targets

A very convenient way to alter the configuration is to use the graphical user interface `ccmake` to the variables `cmake` stores upon running. It can be invoked via

    ccmake .

or by

    make edit_cache

A reconfiguration (without editing the cache) can be run via

    make rebuild_cache

### Shortcuts

All variables starting with `WITH_` will be automatically renamed to `DEAL_II_WITH_*`. So, it suffices to specify

    cmake -DWITH_MPI=ON <...>

instead of the longer

    cmake -DDEAL_II_WITH_MPI=ON <...>

The same holds for all variables starting with `COMPONENT_` and all individual component names: `DOCUMENTATION`, and `EXAMPLES` (which will be expanded to the full `DEAL_II_COMPONENT_*` variable name).

## Configuring and Building deal.II

This section provides some further details and advanced topics with respect to configuration and building that is not covered in the README.

### Primary build targets

The current list of primary build targets can be queried via `make info`:

    ###
    #
    #  The following targets are available (invoke by $ make <target>):
    #
    #    all            - compile the library and all enabled components
    #    clean          - remove all generated files
    #    install        - install into CMAKE_INSTALL_PREFIX
    #
    #    info           - print this help message
    #    help           - print a list of valid top level targets
    #
    #    edit_cache     - run ccmake for changing (cached) configuration variables
    #                     and reruns the configure and generate phases of CMake
    #    rebuild_cache  - rerun the configure and generate phases of CMake
    #
    #    compat_files   - build and install component 'compat_files'
    #    documentation  - build and install component 'documentation'
    #    examples       - build and install component 'examples'
    #    library        - build and install component 'library'
    #    package        - build binary package
    #
    #    test           - run a minimal set of tests
    #
    #    setup_tests    - set up testsuite subprojects
    #    prune_tests    - remove all testsuite subprojects
    #
    ###

### Information about current configuration

A configuration run of `cmake` (or `ccmake`) writes a short summary of the current configuration into `CMAKE_BUILD_DIR/summary.log`:

    ###
    #
    #  deal.II configuration:
    #        CMAKE_BUILD_TYPE:       DebugRelease
    #        BUILD_SHARED_LIBS:      ON
    #        CMAKE_INSTALL_PREFIX:   /tmp/deal.II/install
    #        CMAKE_SOURCE_DIR:       /tmp/deal.II/deal.II (Version 8.1.pre)
    #        CMAKE_BINARY_DIR:       /tmp/deal.II/build
    #        CMAKE_CXX_COMPILER:     GNU 4.7.3 on platform Linux x86_64
    #                                /usr/bin/c++
    #
    #  Configured Features (DEAL_II_ALLOW_BUNDLED = ON, DEAL_II_ALLOW_AUTODETECTION = ON):
    #      ( DEAL_II_WITH_64BIT_INDICES = OFF )
    #        DEAL_II_WITH_ARPACK set up with external dependencies
    #        DEAL_II_WITH_BOOST set up with external dependencies
    #        [...]
    #
    #  Component configuration:
    #      ( DEAL_II_COMPONENT_DOCUMENTATION = OFF )
    #        DEAL_II_COMPONENT_EXAMPLES
    #
    #  Detailed information (compiler flags, feature configuration) can be found in detailed.log
    #
    #  Run  $ make info  to print a help message with a list of top level targets
    #
    ###

This summary is also printed at the end of the configuration phase. It tells you about build and install directory locations, feature configuration (whether a feature is enabled with external/internal dependencies, disabled or forced) and component configuration. A more detailed version can be found in `CMAKE_BUILD_DIR/detailed.log` that also includes detailed information about feature configuration, e.g.

    #        DEAL_II_WITH_BOOST set up with external dependencies
    #            BOOST_VERSION = 1.61.0
    #            BOOST_DIR =
    #            Boost_INCLUDE_DIRS = /usr/include
    #            Boost_LIBRARIES = /usr/lib64/libboost_serialization-mt.so;/usr/lib64/libboost_system-mt.so;
    # [...]

If this information is not sufficient, you might want to have a look at the following files in `CMAKE_BUILD_DIR`

- `CMakeCache.txt`: The file CMake stores its cached variables in. Do not change directly.
- `include/deal.II/base/config.h`: The generated config.h file
- `lib/cmake/deal.II/deal.IIConfig.cmake`: The project configuration file for external projects.

### Out-of-source versus in-source builds

A so called out-of-source build is a setup where the build directory (the directory containing intermediate and generated files) is different from the source directory (the directory containing the source code). With CMake an out-of-source build is set up by invoking `cmake` (or `ccmake`) from the designated build directory, so for example (a build directory under the source directory):

    $ mkdir build
    $ cd build
    $ cmake ..

The big advantage is that source files and intermediate files are strictly separated (highly desired for version control) and that you can have multiple build directories (with different configuration) at the same time.

Note: However, under rare occasions an in-source build might be useful or needed, so it is supported

    $ cmake .

But we highly discourage it!

### CMake Generators

Cmake is a Makefile Generator. This allows to switch the generator that is used to something different. If you for example want to automatically generate an Eclipse project of deal.II, you can run

    $ cmake -G"Eclipse CDT4 - Unix Makefiles" [...]

and load up the build directory as a project directly into Eclipse. Have a look at the Wiki's Eclipse page for more information.

An interesting alternative to (GNU) Make might also be Ninja. Configure via

    $ cmake -GNinja [...]

and run `ninja` instead of `make`.

### Installation

It is not necessary to install the library in order to use deal.II. Invoking the `all` or `library` target will compile the library and set up all necessary configuration in the build directory so that external projects can directly use it. However, we strongly recommend to proceed in the way explained in the README and install the library to a designated install directory (different from source and build directory).

For installing the library it is necessary to set the CMake variable `CMAKE_INSTALL_PREFIX` to the designated install directory. You can do this by invoking `cmake` together with `-DCMAKE_INSTALL_PREFIX=<...>` or by invoking `ccmake`.

Note: When you don't install deal.II to an install directory and use it directly from a build directory, both, the build and source directories have to be kept.

Note: It is not necessary for the source, build and or install directory to be different. All combinations are supported.

#### Install a single component

If you want to only generate, compile and install a specific component (most notably the documentation) you can use one of the following top level targets:

    documentation  - builds and installs the 'documentation' component
    examples       - builds and installs the 'examples' component
    library        - builds and installs the 'library' component

## Configuration options

The various configuration options of the deal.II library are organized in three categories: feature, component, and build/install configuration.

The library will be compiled with the default C++ standard enabled by the compiler. This is (as of May 2020) C++14 for all compilers. If you want to override this behavior, please set the C++ standard directly for example by configuring with `-DDEAL_II_CXX_FLAGS="-std=c++17"`, or by setting the environement variable `CXXFLAGS="-std=c++17"`. Similarly, for enabling SIMD vectorization support, you have to set an appropriate target architecture via `-march=...`, for example `-DDEAL_II_CXX_FLAGS="-march=native"`.

### Feature configuration

deal.II provides (optional) interfaces to quite a number of external libraries as well as multiple versions of `C++`. All of these options are represented by `cmake` variables that may be set to either `ON` or `OFF`. The remaining flags are set to `ON` if an external package is found or to `OFF` otherwise. By explicitly setting it to off either on the command line or using `ccmake`, you can prevent deal.II from using an external package, even if it is found.

Specifically, the following variables exist (the list may grow over time, but names are standardized):

    DEAL_II_WITH_64BIT_INDICES
    DEAL_II_WITH_ADOLC
    DEAL_II_WITH_ARPACK
    DEAL_II_WITH_ASSIMP
    DEAL_II_WITH_BOOST
    DEAL_II_WITH_CGAL
    DEAL_II_WITH_COMPLEX_VALUES
    DEAL_II_WITH_CUDA
    DEAL_II_WITH_GINKGO
    DEAL_II_WITH_GMSH
    DEAL_II_WITH_GSL
    DEAL_II_WITH_HDF5
    DEAL_II_WITH_LAPACK
    DEAL_II_WITH_METIS
    DEAL_II_WITH_MPI
    DEAL_II_WITH_MUPARSER
    DEAL_II_WITH_OPENCASCADE
    DEAL_II_WITH_P4EST
    DEAL_II_WITH_PETSC
    DEAL_II_WITH_SCALAPACK
    DEAL_II_WITH_SLEPC
    DEAL_II_WITH_SUNDIALS
    DEAL_II_WITH_SYMENGINE
    DEAL_II_WITH_TBB
    DEAL_II_WITH_TRILINOS
    DEAL_II_WITH_UMFPACK
    DEAL_II_WITH_ZLIB

They all have standard meanings with the exception of one:

- `DEAL_II_WITH_BOOST` is always `ON` since BOOST is a mandatory build time dependency.

If enabled, each of the features above will usually add one or more dependencies to external or 'bundled' (i.e. bundled with deal.II and residing under `bundled/`) libraries.

There are some options to determine the behavior of the dependency resolution.

- `DEAL_II_ALLOW_BUNDLED`:

  If set to `ON` external libraries still have precedence. But if there is no external library the bundled library will be used. If set to `OFF` bundled libraries will not be used and the dependency resolution will fail if there is no external library.

- `DEAL_II_FORCE_BUNDLED_(BOOST|MUPARSER|THREADS|UMFPACK)`:

  Forces the use of the bundled library regardless whether `DEAL_II_ALLOW_BUNDLED` is set to `OFF` or an external library is found.

- Thus, to ensure that no bundled library is used at all `DEAL_II_ALLOW_BUNDLED`, as well as every `DEAL_II_FORCE_BUNDLED_<library>` have to be set to `OFF`. Conversely, `DEAL_II_FORCE_BUNDLED_<library>=ON` will not automatically enable the corresponding `DEAL_II_WITH_<feature>` toggle. This has to be set separately.

### Autoconfiguration

As long as `DEAL_II_WITH_<FEATURE>` is not explicitly set to `ON` or `OFF` in the cache it will be automatically configured. If a toggle `DEAL_II_WITH_<FEATURE>` is defined it won't be altered. This means that the very first configuration run will set all available features to `ON` and the rest to `OFF`. In all subsequent configuration steps `DEAL_II_WITH_<FEATURE>` has to be changed by hand, see the previous section.

This behavior can be controlled via several variables:

- `DEAL_II_ALLOW_AUTODETECTION=OFF`: This will disable any autoconfiguration by setting undefined `DEAL_II_WITH_<FEATURE>` toggles to `OFF`.
- `DEAL_II_FORCE_AUTODETECTION=ON`: This will force the reconfiguration of every feature by undefining `DEAL_II_WITH_<FEATURE>` prior to configuration, effectively overwriting any supplied or cached value.

### External library locations

External libraries will be searched depending on hints in the following order:

1. Paths specified via `CMAKE_PREFIX_PATH` take precedence, e.g. with

       make -DCMAKE_PREFIX_PATH=~/workspace/local ../deal.II

   libraries from `~/workspace/local` will be preferred for dependency resolution.

2. Hints given by `<library>_DIR` via command line or environment for some libraries:

       make -DP4EST_DIR=~/workspace/p4est-install/ ../deal.II

   or

       export P4EST_DIR=~/workspace/p4est-install/
       cmake ../deal.II

   where `-D<library>_DIR` takes precedence over environment.

   Currently, the following variables will be considered:

       ARPACK_DIR,
       BOOST_DIR,
       HDF5_DIR,
       LAPACK_DIR (and BLAS_DIR),
       METIS_DIR,
       MUPARSER_DIR,
       P4EST_DIR (and SC_DIR),
       PETSC_DIR and PETSC_ARCH (forming ${PETSC_DIR}/${PETSC_ARCH}),
       SCALAPACK_DIR (and optionally BLACS_DIR)
       SLEPC_DIR (forming ${SLEPC_DIR}/${PETSC_ARCH}),
       TBB_DIR,
       TRILINOS_DIR,
       UMFPACK_DIR and SUITESPARSE_DIR (AMD_DIR, CHOLMOD_DIR, COLAMD_DIR, SUITESPARSECONFIG_DIR)

3. The default system locations for libraries and includes.

Alternatively, cached variables set by the `Find<Module>` mechanism may be set, hinted or overwritten directly (variable names are highly dependent on the actual library). You can get a list via

    make edit_cache

and entering advanced configuration mode by pressing [t]. Variables that could not be determined are suffixed with `-NOTFOUND` and may be set by hand.

#### Library conflicts

Caveat: if you have a set of standard libraries in the default location, say `/usr/lib` and a set of private versions of the same libraries, for instance because you need different revisions sometimes, in your own library directory, you may receive an error message of the form:

    CMake Warning at source/CMakeLists.txt:65 (ADD_LIBRARY):
      Cannot generate a safe runtime search path for target deal_II.g because
      files in some directories may conflict with libraries in implicit
      directories:

        runtime library [libtbb.so.2] in /usr/lib may be hidden by files in:
          /my/private/lib

      Some of these libraries may not be found correctly.

This is not a problem of CMake or deal.II, but rather a general Linux problem. In order to fix this, you have two options:

1. Choose all libraries either from your private directory or from the standard one.
2. Install all your private library versions in different directories.

### Manual override

Warning: Do not do this unless absolutely necessary!

It is possible to override the CMake find mechanism for external libraries manually. This is useful if a non standard library (e.g. BLAS or LAPACK) should be used but cannot be found by the `FIND_PACKAGE(...)` mechanism. In this case you can set by hand:

    cmake -D<feature>_FOUND=true \
          -D<feature>_LIBRARIES="library;and;complete;link;interface" \
        ( -D<feature>_INCLUDE_DIRS="semicolon;separated;list;of;include;dirs" \
          -D<feature>_LINKER_FLAGS="..." \
          -D<feature>_<...depending on library...> )

The first define ensures that `cmake` does not call the corresponding `Find<lib>.cmake` module. Therefore, all information that would be otherwise exported by the module must be specified by hand. (See the config.sample file for a detailed list of valid variables per feature.)

An example of use is to select BLAS and LAPACK manually from a PETSc configuration: (Here, these libraries have been compiled with the gfortran compiler and need its support library):

    cmake -DLAPACK_FOUND=true \
          -DLAPACK_LIBRARIES="/tmp/petsc-3.3-p6/arch-linux2-c-debug/lib/libflapack.a;/tmp/petsc-3.3-p6/arch-linux2-c-debug/lib/libfblas.a" \
          -DLAPACK_LINKER_FLAGS="-lgfortran -lm"

You can set these values on the command line, with `ccmake` or by providing an initial cache file, see advanced setup section. Possible manual overrides are explained in detail in the in the config.sample file.

### Component selection

The following options control which components of deal.II will be configured, built and installed:

- `DEAL_II_COMPONENT_DOCUMENTATION` (default `OFF`):

  Enable configuration, build and installation of the documentation including all of the tutorial programs and the doxygen-generated manual. This adds a component `documentation` to the build system.

- `DEAL_II_COMPONENT_EXAMPLES` (default `ON`):

  Enable configuration and installation of the example steps (but not generate the documentation for the tutorial steps). This adds a component `examples` to the build system.

### Build configuration

The `cmake` variable `CMAKE_BUILD_TYPE` controls the type of build. We support `Debug`, `Release` and `DebugRelease` mode. Default is `DebugRelease`.

- Passing `cmake` the flag `-DCMAKE_BUILD_TYPE=Debug` will produce makefiles that compile and install only the debug library `libdeal_II.g.so`.
- Passing `cmake` the flag `-DCMAKE_BUILD_TYPE=Release` result in only compiling and installing the optimized library `libdeal_II.so`.
- Passing `cmake` the flag `-DCMAKE_BUILD_TYPE=DebugRelease` will build and install both libraries.

For more information, see the general discussion here.

The build can be further controlled by the following variables:

- `DEAL_II_ALLOW_PLATFORM_INTROSPECTION`: If set (default), deal.II will perform platform introspection for the given CPU.
- `BUILD_SHARED_LIBS`: If set (default), deal.II will be linked as a shared library
- `DEAL_II_PREFER_STATIC_LIBS` (defaults to off): If set to true, static archives will be preferred over dynamic libraries when searching for features and corresponding link interface.
- `DEAL_II_STATIC_EXECUTABLE` (defaults to off): If set to true, deal.II will be configured in a way to provide a link interface that is suitable for static linkage of executables. Enabling this option forces `BUILD_SHARED_LIBS=OFF` and `DEAL_II_PREFER_STATIC_LIBS=ON`.
- `CMAKE_INSTALL_RPATH_USE_LINK_PATH`: If set (default), the deal.II library will be installed with rpaths set for all libraries outside of the system search paths

### Selecting a compiler

Compilers can be switched either by command line or by setting `CMAKE_(C|CXX|Fortran)_COMPILER`:

    CC=my_c_compiler CXX=my_cxx_compiler FC=my_fortran_compiler cmake <...>

    cmake -DCMAKE_C_COMPILER=my_c_compiler -DCMAKE_CXX_COMPILER=my_cxx_compiler -DCMAKE_Fortran_COMPILER=my_fortran_compiler <...>

Please note that

- The compiler must be specified at the very first invocation of `cmake`.
- A working CXX compiler is needed. It is optional to provide a C or Fortran compiler.

deal.II will configure sensible default `CXXFLAGS` and `LDFLAGS` depending on platform, compiler and build target. There are two options to override this behaviour:

1. Override the default configuration by setting the following cached variables:

       DEAL_II_CXX_FLAGS         - used during all builds
       DEAL_II_CXX_FLAGS_DEBUG   - additional flags for the debug library
       DEAL_II_CXX_FLAGS_RELEASE - additional flags for the release library

       DEAL_II_LINKER_FLAGS         - used during all builds
       DEAL_II_LINKER_FLAGS_DEBUG   - additional flags for the debug library
       DEAL_II_LINKER_FLAGS_RELEASE - additional flags for the release library

   The content of the cached variables will be preserved and added to the end of the default compiler flags, hence providing the possibility for overriding a flag. E.g.: `-Wsign-compare`, set by the build system, can be overwritten by specifying:

       cmake -DDEAL_II_CXX_FLAGS="-Wno-sign-compare" <...>

2. Set the corresponding environment variables: `CFLAGS`, `CXXFLAGS`, or `LDFLAGS` environment. These variables will also be appended after the default compiler flags (but before the corresponding cached variables).
3. Disable the configuration completely by adding the flag `-D DEAL_II_SETUP_DEFAULT_COMPILER_FLAGS=OFF`. Beware of the fact that certain features may still pull in necessary compiler flags.
4. You can setup additional debug compiler flags to provide test coverage information by adding the flag `-D DEAL_II_SETUP_COVERAGE=ON`.

### Compiling using Ccache

Ccache is a compiler caching tool. It accelerates recompilation by caching previously executed compilations and subsequently detecting when the same compilation is being performed again.

It is possible for the library to be built using the Ccache tool. This may be useful for those who frequently rebuild the library, as it caches the output of the compilation (the C++ components, at least). The next time that the library is built, if the compilation objects remain the same then rebuilding them can be avoided as the results will be taken from directly the cache. Anecdotally, Ccache is not well suited to everybody's workflow, so it may take some experimentation to determine if it's effective and helpful, or offers no particular gain to you.

Building with Ccache can be enabled directly via the command line. When using a version of CMake that is greater or equal to 3.4, then using Ccache is easy. Passing the configure-time argument

      -DCXX_COMPILER_LAUNCHER="ccache"

to Cmake ensures that Ccache is invoked whenever C++ code is compiled.

For older versions of CMake, Ccache may be invoked by prefixing the compiler commands passed to CMake by environment or configure-time variables. For example, if building using GCC then

      -DCMAKE_C_COMPILER="ccache gcc" -DCMAKE_CXX_COMPILER="ccache g++"

would indicate that ccache should invoke the GCC compilers to build deal.II. Ccache itself is invoked when calling `make` or `ninja`.

### Installation

the location, where the deal.II library will be installed when invoking `make install` to is set with the help of

    CMAKE_INSTALL_PREFIX

The default directory structure is:

    ${CMAKE_INSTALL_PREFIX}/
        bin
        include
        lib${LIB_SUFFIX}
        lib${LIB_SUFFIX}/cmake/deal.II
        share/deal.II/
        ./
        doc
        examples

The default directory structure can be changed by setting the following variables:

    DEAL_II_EXECUTABLE_RELDIR       default: bin
    DEAL_II_INCLUDE_RELDIR          default: include
    DEAL_II_LIBRARY_RELDIR          default: lib${LIB_SUFFIX}
    DEAL_II_PROJECT_CONFIG_RELDIR   default: lib${LIB_SUFFIX}/cmake/deal.II
    DEAL_II_SHARE_RELDIR            default: share/deal.II/
    DEAL_II_DOCREADME_RELDIR        default: ./
    DEAL_II_DOCHTML_RELDIR          default: doc
    DEAL_II_EXAMPLES_RELDIR         default: examples

## Initial cache file and advanced options

A sample configuration file for preloading the CMake cache with

    $ cmake -C config.sample <...>

can be found here. This sample configuration covers all options mentioned in this documentation as well as some advanced aspects in feature configuration.

## Compiling only certain parts

While developing the library itself, it is often desirable to only compile certain parts. The build system generated by `cmake` allows to build specific, selected targets. A common scenario is that you only want to build debug or optimized libraries. This can be achieved using the following commands in the build directory:

    make  deal_II.g        # only debug library
    make  deal_II          # only release (optimized) library
    make  all              # both

    make  obj_grid_release # all objects in ./source/grid in release configuration

For a complete list of possible targets that allow even finer-grained control, do

    make  help

It is frequently useful to be able to see what a particular command does. In that case, use the following:

    make  deal_II.g VERBOSE=ON

This will show, for every command executed, the exact command line with which it was invoked, including compiler arguments, etc. Every command `cmake` executes starts with a `cd` command to change the current directory appropriately so that the command line can be copied and executed from anywhere within the build directory.

Note: Just because you can call `make deal_II.g` to only compile the debug version does not mean that a subsequent `make install` will only install the debug library. Rather, `make install` will still want to have both libraries up to date and will therefore invoke `make all` automatically. To restrict builds in such a way that only one library will be installed, see configuration and installation sections.