Commit ca87fea2 authored by Simon Praetorius's avatar Simon Praetorius

initial commit of new cmake build system

parent cc5ed571
Pipeline #27075 failed with stage
in 2 minutes and 42 seconds
# set up project
project("dune-common" C CXX)
cmake_minimum_required(VERSION 3.13)
  • Great changes. A lot of information that belong into the top-level CMakeLists.txt are now provided: dune module version, required C++ standard, third-party dependencies. And the overall file is not too long (this would be longer for dune-grid, but should be still ok).

Please register or sign in to reply
project(dune-common VERSION 2.8.0 LANGUAGES C CXX)
# general stuff
cmake_minimum_required(VERSION 3.1)
# make sure our own modules are found
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/modules")
# set the script dir for the macros.
set(DUNE_COMMON_SCRIPT_DIR "${PROJECT_SOURCE_DIR}/cmake/scripts")
#include the dune macros
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules)
include(DuneMacros)
# start a dune project with information from dune.module
dune_project()
# add subdirectories to execute CMakeLists.txt there
add_subdirectory("lib")
add_subdirectory("share")
add_subdirectory("dune")
add_subdirectory("bin")
add_subdirectory("doc")
add_subdirectory("cmake/modules")
add_subdirectory("cmake/scripts")
# if Python bindings are enabled, include necessary sub directories.
if( DUNE_ENABLE_PYTHONBINDINGS )
add_subdirectory("python")
dune_python_install_package(PATH "python")
endif()
# finalize the dune project, e.g. generating config.h etc.
finalize_dune_project()
include(DuneCommonMacros)
# create the dune-common library
dune_add_library(dune-common)
# set minimal required c++ standard version
target_compile_features(dune-common PUBLIC cxx_std_17)
# check for optional compile rfeatures and set cpp flags
dune_target_optional_compile_features(dune-common PUBLIC
cxx_identity
cxx_experimental_is_detected
cxx_experimental_make_array)
if (LAPACK_FOUND AND BLAS_FOUND)
target_link_libraries(dune-common PUBLIC BLAS::BLAS LAPACK::LAPACK)
target_compile_definitions(dune-common PUBLIC HAVE_BLAS HAVE_LAPACK
$<$<BOOL:${LAPACK_NEEDS_UNDERLINE}>:LAPACK_NEEDS_UNDERLINE>)
endif ()
if (MPI_FOUND)
target_link_libraries(dune-common PUBLIC MPI::MPI_CXX)
target_compile_definitions(dune-common PUBLIC HAVE_MPI)
endif ()
if (MProtect_FOUND)
target_link_libraries(dune-common PUBLIC MProtect::MProtect)
target_compile_definitions(dune-common PUBLIC HAVE_MPROTECT HAVE_SYS_MMAN_H) # NOTE: the latter should be removed
endif ()
# traverse all directories
add_subdirectory(cmake/modules)
add_subdirectory(dune)
# specify installation of targets, create exports and config files
dune_install_library(dune-common)
dune_feature_summary(WHAT ALL)
This diff is collapsed.
include_guard(GLOBAL)
function (add_feature TARGET SCOPE)
include(CheckCXXSymbolExists)
include(CMakePushCheckState)
message(STATUS "Looking for optional compiler feature std::experimental::detected_t")
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET TRUE)
check_cxx_symbol_exists(
"std::move<std::experimental::detected_t<std::decay_t,int>>"
"utility;experimental/type_traits"
DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED)
cmake_pop_check_state()
if (DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED)
target_compile_definitions(${TARGET} ${SCOPE} DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED)
message(STATUS "Looking for optional compiler feature std::experimental::detected_t - found")
else ()
message(STATUS "Looking for optional compiler feature std::experimental::detected_t - not found")
endif ()
endfunction (add_feature)
include_guard(GLOBAL)
function (add_feature TARGET SCOPE)
include(CheckCXXSymbolExists)
include(CMakePushCheckState)
message(STATUS "Looking for optional compiler feature std::experimental::make_array")
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET TRUE)
check_cxx_symbol_exists(
"std::experimental::make_array<int,int>"
"experimental/array"
DUNE_HAVE_CXX_EXPERIMENTAL_MAKE_ARRAY)
cmake_pop_check_state()
if (DUNE_HAVE_CXX_EXPERIMENTAL_MAKE_ARRAY)
target_compile_definitions(${TARGET} ${SCOPE} DUNE_HAVE_CXX_EXPERIMENTAL_MAKE_ARRAY)
message(STATUS "Looking for optional compiler feature std::experimental::make_array - found")
else ()
message(STATUS "Looking for optional compiler feature std::experimental::make_array - not found")
endif ()
endfunction (add_feature)
include_guard(GLOBAL)
function (add_feature TARGET SCOPE)
include(CheckCXXSymbolExists)
include(CMakePushCheckState)
message(STATUS "Looking for optional compiler feature std::identity")
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET TRUE)
set(CMAKE_REQUIRED_FLAGS "-std=c++20")
check_cxx_symbol_exists(
"std::move<std::identity>"
"utility;functional"
DUNE_HAVE_CXX_IDENTITY)
cmake_pop_check_state()
if (DUNE_HAVE_CXX_IDENTITY)
target_compile_definitions(${TARGET} ${SCOPE} DUNE_HAVE_CXX_IDENTITY)
target_compile_features(${TARGET} ${SCOPE} cxx_std_20)
message(STATUS "Looking for optional compiler feature std::identity - found")
else ()
message(STATUS "Looking for optional compiler feature std::identity - not found")
endif ()
endfunction (add_feature)
# Defines the functions to use GMP
#
# .. cmake_function:: add_dune_gmp_flags
#
# .. cmake_param:: targets
# :positional:
# :single:
# :required:
#
# A list of targets to use GMP with.
#
function(add_dune_gmp_flags _targets)
if(GMP_FOUND)
foreach(_target ${_targets})
target_link_libraries(${_target} ${GMP_LIBRARIES})
set_property(TARGET ${_target}
APPEND_STRING
PROPERTY COMPILE_FLAGS "-DENABLE_GMP=1 ")
foreach(_path ${GMP_INCLUDE_DIRS})
set_property(TARGET ${_target}
APPEND_STRING
PROPERTY COMPILE_FLAGS "-I${_path}")
endforeach(_path ${GMP_INCLUDE_DIRS})
endforeach(_target ${_targets})
endif(GMP_FOUND)
endfunction(add_dune_gmp_flags)
# Defines the functions to use QuadMath
#
# .. cmake_function:: add_dune_quadmath_flags
#
# .. cmake_param:: targets
# :positional:
# :single:
# :required:
#
# A list of targets to use QuadMath with.
#
function(add_dune_quadmath_flags _targets)
if(QUADMATH_FOUND)
foreach(_target ${_targets})
target_link_libraries(${_target} "quadmath")
set_property(TARGET ${_target}
APPEND_STRING
PROPERTY COMPILE_FLAGS "-DENABLE_QUADMATH=1 -D_GLIBCXX_USE_FLOAT128=1 ")
if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)
set_property(TARGET ${_target}
APPEND_STRING
PROPERTY COMPILE_FLAGS "-fext-numeric-literals ")
endif()
endforeach(_target ${_targets})
endif(QUADMATH_FOUND)
endfunction(add_dune_quadmath_flags)
# This modules contains only documentation for CMake builtins.
# This is necessary to have an complete API documentation.
#
# .. cmake_function:: add_subdirectory
#
# .. cmake_param:: dir
# :single:
# :positional:
# :required:
#
# The :code:`CMakeLists.txt` file from this subdirectory
# will be executed next.
#
# .. cmake_param:: EXCLUDE_FROM_ALL
# :option:
#
# Whether targets added in this subdirectory should be built
# during :code:`make all`.
#
# This is a cmake builtin command.
# For detailed information, check the cmake documentation:
#
# ::
#
# cmake --help-command add_subdirectory
#
# .. cmake_function:: install
#
# Define installation rules to customize the behaviour of :code:`make install`.
#
# This is a cmake builtin command.
# For detailed information, check the cmake documentation:
#
# ::
#
# cmake --help-command install
#
# .. cmake_function:: add_executable
#
# Adds an executable to the project.
#
# This is a cmake builtin command.
# For detailed information, check the cmake documentation:
#
# ::
#
# cmake --help-command add_executable
#
# .. cmake_variable:: CMAKE_<LANG>_COMPILER
#
# Set the compiler for the language LANG.
# LANG is in our case out of C, CXX.
#
# This is a cmake builtin variable.
# For detailed information, check the cmake documentation:
#
# ::
#
# cmake --help-variable CMAKE_\<LANG\>_COMPILER
#
# .. cmake_variable:: CMAKE_<LANG>_FLAGS
#
# Set the compile flags for the language LANG.
# LANG is in our case out of C, CXX.
#
# This is a cmake builtin variable.
# For detailed information, check the cmake documentation:
#
# ::
#
# cmake --help-variable CMAKE_\<LANG\>_FLAGS
#
# .. cmake_function:: find_package
#
# Look for an external package.
#
# This is a cmake builtin command.
# For detailed information, check the cmake documentation:
#
# ::
#
# cmake --help-command find_package
#
install(FILES
AddGMPFlags.cmake
AddMETISFlags.cmake
AddParMETISFlags.cmake
AddPTScotchFlags.cmake
AddQuadMathFlags.cmake
AddSuiteSparseFlags.cmake
AddUMFPackFlags.cmake
AddVcFlags.cmake
CheckCXXFeatures.cmake
CMakeBuiltinFunctionsDocumentation.cmake
DuneAddPybind11Module.cmake
DuneCMakeCompat.cmake
DuneCommonMacros.cmake
DuneCxaDemangle.cmake
DuneDoc.cmake
DuneDoxygen.cmake
DuneEnableAllPackages.cmake
DuneExecuteProcess.cmake
DuneInstance.cmake
set(INSTALL_FILES
DuneAddLibrary.cmake
DuneAddTest.cmake
DuneCheckCXXSourceCompiles.cmake
DuneDeclareTestLabel.cmake
DuneFeatureSummary.cmake
DuneInstallLibrary.cmake
DuneMacros.cmake
DuneMPI.cmake
DunePathHelper.cmake
DunePkgConfig.cmake
DunePythonCommonMacros.cmake
DunePythonFindPackage.cmake
DunePythonInstallPackage.cmake
DunePythonMacros.cmake
DunePythonRequireVersion.cmake
DunePythonTestCommand.cmake
DunePythonVirtualenv.cmake
DuneSphinxDoc.cmake
DuneSphinxCMakeDoc.cmake
DuneStreams.cmake
DuneSymlinkOrCopy.cmake
DuneTestMacros.cmake
FindGMP.cmake
FindInkscape.cmake
FindLatexMk.cmake
FindMETIS.cmake
DuneModuleName.cmake
DuneTesting.cmake
DuneTargetOptionalCompileFeatures.cmake
FindBLAS.cmake
FindHYPRE.cmake
FindLAPACK.cmake
FindMProtect.cmake
FindParMETIS.cmake
FindPTScotch.cmake
FindQuadMath.cmake
FindSphinx.cmake
FindSuiteSparse.cmake
FindTBB.cmake
FindUMFPack.cmake
Headercheck.cmake
latexmkrc.cmake
OverloadCompilerFlags.cmake
UseInkscape.cmake
UseLatexMk.cmake
DESTINATION ${DUNE_INSTALL_MODULEDIR})
TargetSourcesLocal.cmake
)
install(
FILES ${INSTALL_FILES}
DESTINATION
${CMAKE_INSTALL_DATADIR}/cmake
)
foreach (file ${INSTALL_FILES})
configure_file(${file} ${PROJECT_BINARY_DIR}/${file} COPYONLY)
endforeach (file)
add_subdirectory(legacy)
\ No newline at end of file
function (dune_add_library NAME)
include(DuneModuleName)
dune_module_name(${NAME} MODULE_NAME)
add_library(${NAME})
add_library(Dune::${NAME} ALIAS ${NAME})
# set properties of target ${NAME}
set_target_properties(${NAME} PROPERTIES
EXPORT_NAME ${NAME}
VERSION ${${NAME}_VERSION}
SOVERSION ${${NAME}_VERSION_MAJOR} )
# set include directories for target
target_include_directories(${NAME} PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> )
# set <PackageName>_FOUND as if find_package was called for this library
set(${NAME}_FOUND ON PARENT_SCOPE)
endfunction(dune_add_library)
# This cmake module provides infrastructure for building modules using Pybind11
#
# .. cmake_function:: dune_add_pybind11_module
#
# .. cmake_param:: NAME
# :required:
# :single:
#
# name of the Python module
#
# .. cmake_param:: SOURCES
# :multi:
#
# source files to build shared library
#
# If this parameter is omitted, <name>.cc will be used if it exists.
#
# .. cmake_param:: EXCLUDE_FROM_ALL
# :option:
#
# exclude this module from the all target
#
# .. cmake_param:: COMPILE_DEFINITIONS
# :multi:
# :argname: def
#
# A set of compile definitions to add to the target.
# Only definitions beyond the application of :ref:`add_dune_all_flags`
# have to be stated.
#
# .. cmake_param:: CMAKE_GUARD
# :multi:
# :argname: condition
#
# A number of conditions that CMake should evaluate before adding this
# module. Use this feature instead of guarding the call to
# :code:`dune_add_pybind11_module` with an :code:`if` clause.
#
# The passed condition can be a complex expression like
# `( A OR B ) AND ( C OR D )`. Mind the spaces around the parentheses.
#
# Example: Write CMAKE_GUARD dune-foo_FOUND if you want your module to only
# build when the dune-foo module is present.
#
function(dune_add_pybind11_module)
include(CMakeParseArguments)
cmake_parse_arguments(PYBIND11_MODULE "EXCLUDE_FROM_ALL" "NAME" "SOURCES;COMPILE_DEFINITIONS;CMAKE_GUARD" ${ARGN})
if(PYBIND11_MODULE_UNPARSED_ARGUMENTS)
message(WARNING "dune_add_pybind11_module: extra arguments provided (typos in named arguments?)")
endif()
if(NOT PYBIND11_MODULE_NAME)
message(FATAL_ERROR "dune_add_pybind11_module: module name not specified")
endif()
if(NOT PYBIND11_MODULE_SOURCES)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${PYBIND11_MODULE_NAME}.cc)
set(PYBIND11_MODULE_SOURCES ${PYBIND11_MODULE_NAME}.cc)
else()
message(FATAL_ERROR "dune_add_pybind11_module: no source files specified")
endif()
endif()
foreach(condition ${PYBIND11_MODULE_CMAKE_GUARD})
separate_arguments(condition)
if(NOT (${condition}))
message(STATUS "not building ${PYBIND11_MODULE_NAME}, because condition ${condition} failed.")
return()
endif()
endforeach()
add_library(${PYBIND11_MODULE_NAME} SHARED ${PYBIND11_MODULE_SOURCES})
set_target_properties(${PYBIND11_MODULE_NAME} PROPERTIES PREFIX "")
target_compile_definitions(${PYBIND11_MODULE_NAME} PRIVATE ${PYBIND11_MODULE_COMPILE_DEFINITIONS})
dune_target_enable_all_packages(${PYBIND11_MODULE_NAME})
if(PYBIND11_MODULE_EXCLUDE_FROM_ALL)
set_property(TARGET ${PYBIND11_MODULE_NAME} PROPERTY EXCLUDE_FROM_ALL 1)
endif()
endfunction()
This diff is collapsed.
# Module with backward compatibility implementation of newer cmake functionality
#
# .. cmake_module::
#
# This module contains backward compatibility implementations of cmake
# functionality that is not available in all cmake versions we support.
#
# * :ref:`dune_list_filter(...) <dune_list_filter>` for ``list(FILTER
# ...)`` from cmake 3.7
#
#
# .. cmake_function:: dune_list_filter
#
# .. cmake_brief::
#
# Compatibility implementation of ``list(FILTER)``
#
# .. cmake_param:: list
# :positional:
# :single:
# :required:
#
# Name of list variable used as both input and output.
#
# .. cmake_param:: <INCLUDE|EXCLUDE>
# :positional:
# :option:
# :required:
#
# Whether to include or to exclude the items matching the regular
# expression.
#
# .. cmake_param:: REGEX
# :single:
# :required:
# :argname: regular_expression
#
# The regular expression to match the items against.
#
# Match each item in the list against the regular expression. In
# ``INCLUDE`` mode the result contains all items that matched, in
# ``EXCLUDE`` mode it contains all items that did not match. Store the
# result back in the variable ``list`` in the scope of the caller.
#
# This is exactly the same as the ``list(FILTER ...)`` command available in
# cmake 3.7 and onward.
# list(FILTER...) was introduced in cmake 3.6, this is a compatibility
# implementation for earlier cmakes
function(dune_list_filter list mode REGEX regular_expression)
# validate arguments
if(NOT (("${mode}" STREQUAL "INCLUDE") OR ("${mode}" STREQUAL "EXCLUDE")))
message(FATAL_ERROR "unsupported mode '${mode}', must be either INCLUDE or EXCLUDE")
endif()
if(NOT ("${REGEX}" STREQUAL "REGEX"))
message(FATAL_ERROR "dune_list_filter can only filter by regular expression")
endif()
if("${ARGC}" GREATER 4)
message(FATAL_ERROR "extra arguments given: <${ARGN}>")
endif()
# cmake can't destinguish between empty lists and lists with one empty
# element. This is a problem when consecutively appending elements to a
# list: if the first elements we append are empty, we loose them. The
# "non-empty" token makes sure we start with a non-empty list and avoid this
# problem.
set(matched "non-empty")
set(unmatched "non-empty")
foreach(item IN LISTS "${list}")
# list(APPEND) does not quote the appended item (as of cmake 3.7.2), so do
# it manually
string(REPLACE [[;]] [[\;]] quoted_item "${item}")
if("${item}" MATCHES "${regular_expression}")
list(APPEND matched "${quoted_item}")
else()
list(APPEND unmatched "${quoted_item}")
endif()
endforeach(item)
if("${mode}" STREQUAL "INCLUDE")
set(result "${matched}")
else()
set(result "${unmatched}")
endif()
# remove the non-empty token from above. If the proper result would be a
# list of one empty element, we have no way of preserving that, it will turn
# into an empty list.
string(REGEX REPLACE "^non-empty;?" "" result "${result}")
# export
set("${list}" "${result}" PARENT_SCOPE)
endfunction(dune_list_filter)
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
DuneCheckCXXSourceCompiles
----------------------
Check if given C++ source compiles and links into an executable with the compiel and
link properties derived from a given target.
.. command:: dune_check_cxx_source_compiles
.. code-block:: cmake
dune_check_cxx_source_compiles(<target> <code> <resultVar>)
Check that the source supplied in ``<code>`` can be compiled as a C++ source
file and linked as an executable (so it must contain at least a ``main()``
function). The result will be stored in the internal cache variable specified
by ``<resultVar>``, with a boolean true value for success and boolean false
for failure.
The underlying check is performed by the :command:`try_compile` command. The
compile and link commands are incluences by the target properties of ``<target>``.
The check is only performed once, with the result cached in the variable
named by ``<resultVar>``. Every subsequent CMake run will re-use this cached
value rather than performing the check again, even if the ``<code>`` changes.
In order to force the check to be re-evaluated, the variable named by
``<resultVar>`` must be manually removed from the cache.
#]=======================================================================]
include_guard(GLOBAL)
# Get the property of the TARGET or return the DEFAULT value
macro(get_target_property_opt OUT_VAR TARGET PROPERTY DEFAULT)
get_target_property(${OUT_VAR}_tmp ${TARGET} ${PROPERTY})
set(${OUT_VAR} ${DEFAULT})
if (${OUT_VAR}_tmp)
set(${OUT_VAR} ${${OUT_VAR}_tmp})
endif ()
endmacro(get_target_property_opt)
# Get the properties of the TARGET and combine the resulting lists or return an empty list
# All requested properties are listed after the TARGET argument
macro(get_target_properties_opt OUT_VAR TARGET)
set(${OUT_VAR} "")
foreach (PROP ${ARGN})
get_target_property(${OUT_VAR}_${PROP} ${TARGET} ${PROP})
if (${OUT_VAR}_${PROP})
list(APPEND ${OUT_VAR} ${${OUT_VAR}_${PROP}})
endif ()
endforeach ()
endmacro(get_target_properties_opt)
# Check whether SOURCE compiles when compiled and linked with the corresponding properties of given TARGET
macro(dune_check_cxx_source_compiles TARGET SOURCE VAR)
if(NOT DEFINED "${VAR}")
# write source to file
file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.cxx"
"${SOURCE}\n")
# get compile and link properties from target
get_target_properties_opt(ARG_INCLUDE_DIRECTORIES ${TARGET} INCLUDE_DIRECTORIES INTERFACE_INCLUDE_DIRECTORIES)
get_target_properties_opt(ARG_COMPILE_OPTIONS ${TARGET} COMPILE_OPTIONS INTERFACE_COMPILE_OPTIONS)
get_target_properties_opt(ARG_COMPILE_DEFINITIONS ${TARGET} COMPILE_DEFINITIONS INTERFACE_COMPILE_DEFINITIONS)
get_target_properties_opt(ARG_LINK_LIBRARIES ${TARGET} LINK_LIBRARIES INTERFACE_LINK_LIBRARIES)
get_target_properties_opt(ARG_LINK_OPTIONS ${TARGET} LINK_OPTIONS INTERFACE_LINK_OPTIONS)
list(TRANSFORM ARG_COMPILE_DEFINITIONS PREPEND "-D")
if (${ARG_COMPILE_OPTIONS})
set(ARG_COMPILE_DEFINITIONS "${ARG_COMPILE_DEFINITIONS};${ARG_COMPILE_OPTIONS}")