Build system internals

This page provides details about the CMake build system. Files processed by the top level CMakeLists.txt script are listed in the TOC in chronological order.

  1. Coding convention
  2. Configuration
    1. ./CMakeLists.txt and ./cmake/setup_*.cmake
    2. ./cmake/checks/check_*.cmake
    3. ./cmake/modules/Find*.cmake
    4. ./cmake/configure/configure_*.cmake
    5. Global variables controlling the build process
  3. Target definition and installation
    1. ./include/deal.II/base/config.h.in
    2. ./source/CMakeLists.txt
    3. ./cmake/config/CMakeLists.txt

Coding convention

Coding conventions are always a matter of choice. Nevertheless, the following rules should be considered:

An example:
FOREACH(_build ${DEAL_II_BUILD_TYPES})
  #
  # Set an appropriate keyword depending on target and build type:
  #
  IF(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "DebugRelease")
    SET(_keyword "general")
  ELSE()
    IF(_build MATCHES DEBUG)
      SET(_keyword "debug")
    ELSE()
      SET(_keyword "optimized")
    ENDIF()
  ENDIF()
ENDFOREACH()
LIST(APPEND CONFIG_LIBRARIES
  ${_keyword}
  ${CONFIG_LIBRARIES_${_build}}
  )

SET_TARGET_PROPERTIES(${DEAL_II_BASE_NAME}${DEAL_II_${build}_SUFFIX}
  PROPERTIES
  VERSION ${VERSION}
  SOVERSION ${VERSION}
  LINK_FLAGS "${DEAL_II_LINKER_FLAGS_${build}}"
  COMPILE_DEFINITIONS "${DEAL_II_DEFINITIONS};${DEAL_II_DEFINITIONS_${build}}"
  COMPILE_FLAGS "${DEAL_II_CXX_FLAGS_${build}}"
  )

CMake operates almost always with variables in global state. To guard against accidental overwrite of variables the following naming conventions must be followed at all times:

Configuration

./CMakeLists.txt and ./cmake/setup_*.cmake

The very first configuration steps after some initial setup in ./CMakeLists.txt takes place in some ./cmake/setup_*.cmake files:

./cmake/checks/check_*.cmake

The next step in the configuration process is to include all checks residing under ./cmake/checks. Currently there are:

./cmake/checks/check_01_compiler_features.cmake
  - Search for support for compiler dependent features such as stack
    trace support, demangler support, etc.

./cmake/checks/check_01_cpu_features.cmake
  - Platform introspection for CPU features goes here and must be
    guarded with DEAL_II_ALLOW_PLATFORM_INTROSPECTION

./cmake/checks/check_01_cxx_features.cmake
  - Check for supported C++ language features such as sufficient C++11
    support

./cmake/checks/check_01_system_features.cmake
  - Checks for specific platform (Linux/Darwin/CYGWIN/Windows..)
    features and support

./cmake/checks/check_02_compiler_bugs.cmake
  - Check for compiler bugs

./cmake/modules/Find*.cmake

These are find modules for the configure_*.cmake files and the CONFIGURE_FEATURE macro as will explained later. It is crucial that a find module behaves correctly. Therefore, the following rules are mandatory:

./cmake/configure/configure_*.cmake

The final step in the configuration phase is the setup of features (which refer to external or bundled libraries deal.II can optionally interface with.)

At bare minimum configure_<feature>.cmake file for a feature just consists of a call to the CONFIGURE_FEATURE(<FEATURE>) macro which is implemented in ./cmake/macros/macro_configure_feature.cmake. In this case the corresponding Find<FEATURE>.cmake module is used to determine whether an external dependency can be resolved or not. Depending on the current state of DEAL_II_WITH_<FEATURE> (see here) the configuration variables

FEATURE_LIBRARIES
FEATURE_LIBRARIES(|_DEBUG|_RELEASE)
FEATURE_(|USER_|BUNDLED_)INCLUDE_DIRS
FEATURE_LINKER_FLAGS(|_DEBUG|_RELEASE)
FEATURE_CXX_FLAGS(|_DEBUG|_RELEASE)
FEATURE_DEFINITIONS(|_DEBUG|_RELEASE)
are appended to the set of global variables and DEAL_II_WITH_<FEATURE> is set to TRUE.

It is possible to override this default behaviour with the following variables and macros (all of them are optional and will be replaced by an appropriate default action if unset):

Global variables controlling the build process

The following list describes all global variables controlling the build process and the visibility associated with it (internal use for compiling deal.Ii, externally used variables will get exported in deal.IIConfig.cmake). Lists should be manipulated with LIST(APPEND ...), flags with ADD_FLAGS(...) (or if it is necessary to guard them with ENABLE_IF_SUPPORTED(...).)

Feature configuration must not be added directly to this variables but to corresponding <FEATURE>_* variables, instead. Feature configuration variables get appended to the below list of global configuration variables automatically.

Target definition and installation

./include/deal.II/base/config.h.in

In contrast to autoconf there is no intermediate step any more that automatically generates config.h.in. The setup in this file has to be done by hand. Please note:

./source/CMakeLists.txt

All parts of the library are organized into logical object libraries with their respective sources lying under ./source/<foo>, or ./bundled/<foo>/<...>. The actual setup of an object library happens within that subdirectories with the help of two macros:

#
# Glob for all header files associated with the object target:
# As this list is only for cosmetic reasons, so that associated header
# files show up in IDEs, we don't manage an explicit list (with the
# trade-off to have to run "make rebuild_cache" when a new header file
# emerges...)
#
FILE(GLOB _header
  ${CMAKE_SOURCE_DIR}/include/deal.II/dofs/*.h
  )

#
# A list of source files forming the object target:
#
SET(_src
  ...
  dof_tools.cc
  )

#
# A list of instantiations that must be expanded:
#
SET(_inst
  ...
  dof_tools.inst.in
  )

#
# The following macro will set up an obj_dofs.debug and
# obj_dofs.release target  with appropriate compile flags and
# definitions for a simultaneous build of debug and release library.
# Furthermore, the object name will be stored in
#   ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/deal_ii_objects_(debug/release)
# so that it is available in global scope.
#
# Header files and instantiation files (${_header}, ${_inst}) are added
# for cosmetic reasons, so that they show up in IDEs.
#
DEAL_II_ADD_LIBRARY(obj_dofs OBJECT ${_src} ${_header} ${_inst})

#
# This macro will set up an obj_dofs.inst target for expanding all
# files listed in ${inst_in_files}. Appropriate target dependencies
# will be added to obj_dofs.debug and obj_dofs.release.
#
EXPAND_INSTANTIATIONS(obj_dofs "${inst_in_files}")

Later, all object targets are collected in ./source/CMakeLists.txt to define the actual debug and releases libraries. For further details, see ./source/CMakelists.txt and ./cmake/macros/macro_deal_ii_add_library.cmake.

./cmake/config/CMakeLists.txt

The final bits of configuration happens in ./cmake/config/CMakeLists.txt where the templates for the project configuration deal.IIConfig.cmake and the compatibility file Make.global_options get expanded. Furthermore, the configuration for the template expansion mechanism resides under ./cmake/config/template_arguments.in.


Valid HTML 4.01! Valid CSS!