Forked from
Core Modules / dune-common
4759 commits behind the upstream repository.
-
Christoph Grüninger authored
There is no obvious reason to quote one variable and not the other. If more CMP0019 warnings are found, they have to be fixed in the same way. This was only an issue with CMake 2.8.11 or newer.
Christoph Grüninger authoredThere is no obvious reason to quote one variable and not the other. If more CMP0019 warnings are found, they have to be fixed in the same way. This was only an issue with CMake 2.8.11 or newer.
DuneMacros.cmake 36.11 KiB
# Core DUNE module for CMake.
#
# Provides the following macros:
#
# dune_module_to_uppercase(upper_name module_name)
#
# Converts a module name given by module_name into an uppercase string
# upper_name where all dashes (-) are replaced by underscores (_)
# Example: dune-common -> DUNE_COMMON
#
# dune_module_information(MODULE_DIR [QUIET])
#
# Parse ${MODULE_DIR}/dune.module and provide that information.
# If the second argument is QUIET no status message is printed.
#
#
# dune_project()
#
# macro that should be called near the begin of the top level CMakeLists.txt.
# Namely it sets up the module, defines basic variables and manages
# depedencies.
# Don't forget to call finalize_dune_project afterwards.
#
#
# dune_create_dependency_tree()
#
# Creates the dependency tree of the module.
#
# dune_module_to_macro(_macro_name, _dune_module)
#
# Converts a module name given by _dune_module into a string _macro_name
# where all dashes (-) are removed and letters after a dash are capitalized
# Example: dune-grid-howto -> DuneGridHowto
#
# _macro_name: variable where the name will be stored.
# _dune_module: the name of the dune module.
#
#
# dune_regenerate_config_cmake()
#
# Creates a new config.h.cmake file in ${CMAKE_CURRENT_BINARY_DIR) that
# consists of entries from ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
# and includes non-private entries from the files config.h.cmake files
# of all dependent modules.
# Finally config.h is created from config.h.cmake.
#
#
# dune_add_library(<basename> [NO_EXPORT] [ADD_LIBS <lib1> [<lib2> ...]]
# [OBJECT] SOURCES <source1> [<source2> ...] [COMPILE_FLAGS <flags>])
#
# Creates shared and static libraries with the same basename.
# <basename> is the basename of the library.
# On Unix this creates lib<basename>.so and lib<BASENAME>.a.
# Libraries that should be incorporate into this libary can
# be specified with the ADD_LIBS option.
# The libraries will be built in ${PROJECT_BINARY_DIR}/lib.
# If the option NO_EXPORT is omitted the library is exported
# for usage in other modules.
#
# Object libraries can now be created with dune_add_library(<target>
# OBJECT <sources>). It will create a GLOBAL property
# _DUNE_TARGET_OBJECTS:<target>_ that records the full path to the
# source files. Theses can later be referenced by providing
# _DUNE_TARGET_OBJECTS:<target>_ as one of the sources to dune_add_library
#
# finalize_dune_project()
#
# macro that should be called at the end of the top level CMakeLists.txt.
# Namely it creates config.h and the cmake-config files,
# some install directives and exports the module.
#
#
# dune_target_link_libraries(BASENAME, LIBRARIES)
#
# Link libraries to the static and shared version of
# library BASENAME
#
enable_language(C) # Enable C to skip CXX bindings for some tests.
# Converts a module name given by _module into an uppercase string
# _upper where all dashes (-) are replaced by underscores (_)
# Example: dune-common -> DUNE_COMMON
macro(dune_module_to_uppercase _upper _module)
string(TOUPPER "${_module}" ${_upper})
string(REPLACE "-" "_" ${_upper} "${${_upper}}")
endmacro(dune_module_to_uppercase _upper _module)
macro(find_dune_package module)
if(NOT (${module}_DIR OR ${module}_ROOT OR
"${CMAKE_PREFIX_PATH}" MATCHES ".*${module}.*"))
string(REPLACE ${ProjectName} ${module} ${module}_DIR
${PROJECT_BINARY_DIR})
endif()
find_package(${ARGV} NO_CMAKE_PACKAGE_REGISTRY)
endmacro(find_dune_package module)
macro(extract_line HEADER OUTPUT FILE_CONTENT)
set(REGEX "${HEADER}[ ]*[^\n]+")
string(REGEX MATCH ${REGEX} OUTPUT1 "${FILE_CONTENT}")
if(OUTPUT1)
set(REGEX "^[ ]*${HEADER}[ ]*(.+)[ ]*$")
string(REGEX REPLACE ${REGEX} "\\1" ${OUTPUT} "${OUTPUT1}")
else(OUTPUT1)
set(OUTPUT OUTPUT-NOTFOUND)
endif(OUTPUT1)
endmacro(extract_line)
macro(split_module_version STRING MODULES VERSIONS)
set(REGEX "[a-zA-Z-]+[ ]*(\\([ ]*([^ ]+)?[ ]*[^ ]+[ ]*\\))?")
#set(REGEX "dune")
string(REGEX MATCHALL "${REGEX}" matches "${STRING}")
set(${MODULES} "")
set(${VERSIONS} "")
foreach(i ${matches})
string(REGEX REPLACE "^([a-zA-Z-]+).*$" "\\1" mod ${i})
string(REGEX MATCH "\\([ ]*(([^ ]+)?[ ]*[^ ]+)[ ]*\\)" have_version
${i})
if(have_version)
string(REGEX REPLACE "^\\([ ]*([^ ]*[ ]*[^ ]+)[ ]*\\)$" "\\1"
version ${have_version})
else(have_version)
set(version >=0.0)
endif(have_version)
list(APPEND ${MODULES} ${mod})
list(APPEND ${VERSIONS} ${version})
endforeach(i "${matches}")
endmacro(split_module_version)
function(convert_deps_to_list var)
string(REGEX REPLACE "([a-zA-Z\\)]) ([a-zA-Z])" "\\1;\\2" ${var} ${${var}})
set(${var} ${${var}} PARENT_SCOPE)
endfunction(convert_deps_to_list var)
# add dune-common version from dune.module to config.h
# optional second argument is verbosity
macro(dune_module_information MODULE_DIR)
file(READ "${MODULE_DIR}/dune.module" DUNE_MODULE)
# find version string
extract_line("Version:" MODULE_LINE "${DUNE_MODULE}")
if(NOT MODULE_LINE)
message(FATAL_ERROR "${MODULE_DIR}/dune.module is missing a version.")
endif(NOT MODULE_LINE)
string(REGEX REPLACE ".*Version:[ ]*([^ \n]+).*" "\\1" DUNE_MOD_VERSION "${MODULE_LINE}")
string(REGEX REPLACE "([0-9]).*" "\\1" DUNE_VERSION_MAJOR "${DUNE_MOD_VERSION}")
string(REGEX REPLACE "[0-9]*\\.([0-9]).*" "\\1" DUNE_VERSION_MINOR "${DUNE_MOD_VERSION}")
string(REGEX REPLACE "[0-9]*\\.[0-9]*\\.([0-9]).*" "\\1" DUNE_VERSION_REVISION "${DUNE_MOD_VERSION}")
# remove false matches in version string
string(REGEX MATCH "[^0-9]" NON_NUMBER_CHARACTER "${DUNE_VERSION_MINOR}")
if(NON_NUMBER_CHARACTER)
set(DUNE_VERSION_MINOR "0")
endif(NON_NUMBER_CHARACTER)
string(REGEX MATCH "[^0-9]" NON_NUMBER_CHARACTER "${DUNE_VERSION_REVISION}")
if(NON_NUMBER_CHARACTER)
set(DUNE_VERSION_REVISION "0")
endif(NON_NUMBER_CHARACTER)
# find strings for module name, maintainer
# 1. Check for line starting with Module
extract_line("Module:" DUNE_MOD_NAME "${DUNE_MODULE}")
if(NOT DUNE_MOD_NAME)
message(FATAL_ERROR "${MODULE_DIR}/dune.module is missing a module name.")
endif(NOT DUNE_MOD_NAME)
# 2. Check for line starting with Maintainer
extract_line("Maintainer:" DUNE_MAINTAINER "${DUNE_MODULE}")
if(NOT DUNE_MAINTAINER)
message(FATAL_ERROR "${MODULE_DIR}/dune.module is missing a maintainer.")
endif(NOT DUNE_MAINTAINER)
# 3. Check for line starting with Depends
extract_line("Depends:" DUNE_DEPENDS "${DUNE_MODULE}")
if(DUNE_DEPENDS)
split_module_version(${DUNE_DEPENDS} DEPENDS_MODULE DEPENDS_VERSIONS)
foreach(_mod ${DUNE_DEPENDS})
set(${_mod}_REQUIRED REQUIRED)
endforeach(_mod ${DUNE_DEPENDS})
convert_deps_to_list(DUNE_DEPENDS)
if(NOT ("${ARGV1}" STREQUAL QUIET))
message(STATUS "Dependencies: ${DEPENDS_MODULE} (versions: ${DEPENDS_VERSIONS}) DUNE_DEPENDS=${DUNE_DEPENDS}")
endif(NOT ("${ARGV1}" STREQUAL QUIET))
endif(DUNE_DEPENDS)
# 4. Check for line starting with Suggests
extract_line("Suggests:" DUNE_SUGGESTS "${DUNE_MODULE}")
if(DUNE_SUGGESTS)
split_module_version(${DUNE_SUGGESTS} SUGGESTS_MODULE SUGGESTS_VERSION)
convert_deps_to_list(DUNE_SUGGESTS)
if(NOT ("${ARGV1}" STREQUAL QUIET))
message(STATUS "Suggestions: ${SUGGESTS_MODULE} (versions: ${SUGGESTS_VERSIONS}) DUNE_SUGGESTS=${DUNE_SUGGESTS}")
endif(NOT ("${ARGV1}" STREQUAL QUIET))
endif(DUNE_SUGGESTS)
dune_module_to_uppercase(DUNE_MOD_NAME_UPPERCASE ${DUNE_MOD_NAME})
# set module version
set(${DUNE_MOD_NAME_UPPERCASE}_VERSION "${DUNE_MOD_VERSION}")
set(${DUNE_MOD_NAME_UPPERCASE}_VERSION_MAJOR "${DUNE_VERSION_MAJOR}")
set(${DUNE_MOD_NAME_UPPERCASE}_VERSION_MINOR "${DUNE_VERSION_MINOR}")
set(${DUNE_MOD_NAME_UPPERCASE}_VERSION_REVISION "${DUNE_VERSION_REVISION}")
endmacro(dune_module_information)
macro(dune_process_dependency_leafs modules versions is_required next_level_deps
next_level_sugs)
# modules is not a real variable, make it one
set(mmodules ${modules})
list(LENGTH mmodules mlength)
if(mlength GREATER 0)
math(EXPR length "${mlength}-1")
foreach(i RANGE 0 ${length})
list(GET mmodules ${i} _mod)
find_dune_package(${_mod} ${REQUIRED})
if(${_mod}_MODULE_PATH)
list(APPEND CMAKE_MODULE_PATH ${${_mod}_MODULE_PATH})
endif(${_mod}_MODULE_PATH)
set(${_mod}_SEARCHED ON)
if(NOT "${is_required}" STREQUAL "")
set(${_mod}_REQUIRED ON)
set(${next_level_deps} ${${_mod}_DEPENDS} ${${next_level_deps}})
else(NOT "${is_required}" STREQUAL "")
set(${next_level_sugs} ${${_mod}_DEPENDS} ${${next_level_sugs}})
endif(NOT "${is_required}" STREQUAL "")
set(${next_level_sugs} ${${_mod}_SUGGESTS} ${${next_level_sugs}})
endforeach(i RANGE 0 ${length})
endif(mlength GREATER 0)
endmacro(dune_process_dependency_leafs)
function(remove_processed_modules modules versions is_required)
list(LENGTH ${modules} mlength)
if(mlength GREATER 0)
math(EXPR length "${mlength}-1")
foreach(i RANGE ${length} 0 -1)
list(GET ${modules} ${i} _mod)
if(${_mod}_SEARCHED)
list(REMOVE_AT ${modules} ${i})
list(REMOVE_AT ${versions} ${i})
if(is_required AND NOT ${_mod}_REQUIRED AND NOT ${_mod}_FOUND)
message(FATAL_ERROR "Required module ${_mod} not found!")
endif(is_required AND NOT ${_mod}_REQUIRED AND NOT ${_mod}_FOUND)
endif(${_mod}_SEARCHED)
endforeach(i RANGE 0 ${length})
endif(mlength GREATER 0)
set(${modules} ${${modules}} PARENT_SCOPE)
set(${versions} ${${versions}} PARENT_SCOPE)
endfunction(remove_processed_modules modules versions is_required)
macro(dune_create_dependency_leafs depends depends_versions suggests suggests_versions
global_depends global_suggests)
set(deps "")
set(sugs "")
#Process dependencies
if(NOT "${depends}" STREQUAL "")
dune_process_dependency_leafs("${depends}" "${depends_versions}" REQUIRED deps sugs)
endif(NOT "${depends}" STREQUAL "")
# Process suggestions
if(NOT "${suggests}" STREQUAL "")
dune_process_dependency_leafs("${suggests}" "${suggests_versions}" "" deps sugs)
endif(NOT "${suggests}" STREQUAL "")
split_module_version("${deps}" next_mod_depends next_depends_versions)
#remove_processed_modules(next_mod_depends next_depends_versions REQUIRED)
set(${global_depends} "${${global_depends}}" ${next_mod_depends})
split_module_version("${sugs}" next_mod_suggests next_suggests_versions)
#remove_processed_modules(next_mod_suggests next_suggests_versions "")
set(${global_suggests} "${${global_suggests}}" ${next_mod_suggests})
# Move to next level
if(next_mod_suggests OR next_mod_depends)
dune_create_dependency_leafs("${next_mod_depends}" "${next_depends_versions}"
"${next_mod_suggests}" "${next_suggests_versions}" global_depends global_suggests)
endif(next_mod_suggests OR next_mod_depends)
endmacro(dune_create_dependency_leafs)
macro(dune_create_dependency_tree)
set(ALL_DEPENDENCIES "")
if(DEPENDS_MODULE OR SUGGESTS_MODULE)
set(global_depends ${DEPENDS_MODULE})
set(global_suggests ${SUGGESTS_MODULE})
foreach(_mod ${DEPENDS_MODULE})
find_dune_package(${_mod} REQUIRED)
if(${_mod}_MODULE_PATH)
list(APPEND CMAKE_MODULE_PATH ${${_mod}_MODULE_PATH})
endif(${_mod}_MODULE_PATH)
set(${_mod}_REQUIRED ON)
endforeach(_mod ${DEPENDS_MODULE})
foreach(_mod ${SUGGESTS_MODULE})
find_dune_package(${_mod})
if(${_mod}_MODULE_PATH)
list(APPEND CMAKE_MODULE_PATH ${${_mod}_MODULE_PATH})
endif(${_mod}_MODULE_PATH)
set(${_mod}_REQUIRED ON)
endforeach(_mod ${SUGGESTS_MODULE})
dune_create_dependency_leafs("${DEPENDS_MODULE}" "${DEPENDS_VERSIONS}"
"${SUGGESTS_MODULE}" "${SUGGESTS_VERSIONS}" global_depends
global_suggests)
set(ALL_DEPENDENCIES "${global_depends}" "${global_suggests}")
endif(DEPENDS_MODULE OR SUGGESTS_MODULE)
# reverse ALL_DEPENDENCIES
list(REVERSE ALL_DEPENDENCIES)
list(REMOVE_DUPLICATES ALL_DEPENDENCIES)
list(REMOVE_DUPLICATES CMAKE_MODULE_PATH)
endmacro(dune_create_dependency_tree _immediates)
# Converts a module name given by _dune_module into a string _macro_name
# where all dashes (-) are removed and letters after a dash are capitalized
# Example: dune-grid-howto -> DuneGridHowto
macro(dune_module_to_macro _macro_name _dune_module)
set(${_macro_name} "")
set(_rest "${_dune_module}")
string(FIND "${_rest}" "-" _found)
while(_found GREATER -1)
string(REGEX REPLACE "([^-]*)-.*" "\\1" _first_part
"${_rest}")
string(REGEX REPLACE "[^-]*-(.*)" "\\1" _rest
"${_rest}")
string(SUBSTRING "${_first_part}" 0 1 _first_letter)
string(SUBSTRING "${_first_part}" 1 -1 _rest_first_part)
string(TOUPPER "${_first_letter}" _first_letter)
set(${_macro_name} "${${_macro_name}}${_first_letter}${_rest_first_part}")
string(FIND "${_rest}" "-" _found)
endwhile(_found GREATER -1)
string(LENGTH "${_rest}" _length)
string(SUBSTRING "${_rest}" 0 1 _first_letter)
string(SUBSTRING "${_rest}" 1 -1 _rest)
string(TOUPPER "${_first_letter}" _first_letter)
set(${_macro_name} "${${_macro_name}}${_first_letter}${_rest}")
endmacro(dune_module_to_macro _macro_name _dune_module)
macro(dune_process_dependency_tree DEPENDS DVERSIONS SUGGESTS SVERSIONS)
foreach(_mod ${ALL_DEPENDENCIES})
if(NOT ${_mod}_PROCESSED)
# module not processed yet
set(${_mod}_PROCESSED ${_mod})
# Search for a cmake files containing tests and directives
# specific to this module
dune_module_to_macro(_cmake_mod_name "${_mod}")
set(_macro "${_cmake_mod_name}Macros")
set(_mod_cmake _mod_cmake-NOTFOUND) # Prevent false positives due to caching
find_file(_mod_cmake
${_macro}.cmake
${CMAKE_MODULE_PATH}
NO_DEFAULT_PATH)
if(_mod_cmake)
message(STATUS "Performing tests specific to ${_mod} from file ${_mod_cmake}.")
include(${_mod_cmake})
endif(_mod_cmake)
# Find the module
#find_package(${_mod})
# set includes
dune_module_to_uppercase(_upper_case "${_mod}")
if(${_mod}_INCLUDE_DIRS)
message(STATUS "Setting ${_mod}_INCLUDE_DIRS=${${_mod}_INCLUDE_DIRS}")
include_directories("${${_mod}_INCLUDE_DIRS}")
endif(${_mod}_INCLUDE_DIRS)
if(${_mod}_LIBRARIES)
message(STATUS "Setting ${_mod}_LIBRARIES=${${_mod}_LIBRARIES}")
foreach(_lib ${${_mod}_LIBRARIES})
list(INSERT DUNE_DEFAULT_LIBS 0 "${_lib}")
list(INSERT DUNE_LIBS 0 "${_lib}")
endforeach(_lib ${${_mod}_LIBRARIES})
endif(${_mod}_LIBRARIES)
message(STATUS "Dependencies for ${_mod}: ${${_mod}_DEPENDENCIES}")
endif(NOT ${_mod}_PROCESSED)
endforeach(_mod DEPENDENCIES)
endmacro(dune_process_dependency_tree)
# macro that should be called near the begin of the top level CMakeLists.txt.
# Namely it sets up the module, defines basic variables and manages
# depedencies.
# Don't forget to call finalize_dune_project afterwards.
macro(dune_project)
# extract information from dune.module
dune_module_information(${CMAKE_SOURCE_DIR})
set(ProjectName "${DUNE_MOD_NAME}")
set(ProjectVersion "${DUNE_MOD_VERSION}")
set(ProjectMaintainerEmail "${DUNE_MAINTAINER}")
dune_create_dependency_tree()
# assert the project names matches
if(NOT (ProjectName STREQUAL CMAKE_PROJECT_NAME))
message(FATAL_ERROR "Module name from dune.module does not match the name given in CMakeLists.txt.")
endif(NOT (ProjectName STREQUAL CMAKE_PROJECT_NAME))
# optional Fortran support
include(LanguageSupport)
workaround_9220(Fortran Fortran_Works)
if(Fortran_Works)
enable_language(Fortran OPTIONAL)
endif(Fortran_Works)
option(DUNE_USE_ONLY_STATIC_LIBS "If set to ON, we will force static linkage everywhere" OFF)
if(DUNE_USE_ONLY_STATIC_LIBS)
set(_default_enable_shared OFF)
set(_default_enable_static ON)
else(DUNE_USE_ONLY_STATIC_LIBS)
set(_default_enable_shared ON)
set(_default_enable_static OFF)
endif(DUNE_USE_ONLY_STATIC_LIBS)
option(BUILD_SHARED_LIBS "If set to ON, shared libs will be built" ${_default_enable_shared})
option(DUNE_BUILD_BOTH_LIBS "If set to ON, shared and static libs will be built"
${_default_enable_static})
if(DUNE_USE_ONLY_STATIC_LIBS)
# Use only static libraries.
# We do this by overriding the library suffixes.
set( BLA_STATIC 1)
set( _dune_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif (WIN32)
if (APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
else (APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
endif (APPLE)
endif(DUNE_USE_ONLY_STATIC_LIBS)
# set required compiler flags for C++11 (former C++0x)
find_package(CXX11Features)
find_package(CXX11Conditional)
include(DuneCxaDemangle)
# search for headers
include(CheckIncludeFile)
include(CheckIncludeFileCXX)
check_include_file("malloc.h" HAVE_MALLOC_H)
check_include_file("stdint.h" HAVE_STDINT_H)
check_include_file_cxx("memory" HAVE_MEMORY)
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -DHAVE_MEMORY=${HAVE_MEMORY}")
# set include path and link path for the current project.
include_directories("${CMAKE_BINARY_DIR}")
include_directories("${CMAKE_SOURCE_DIR}")
link_directories("${CMAKE_SOURCE_DIR}/lib")
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
add_definitions(-DHAVE_CONFIG_H)
# Search for MPI and set the relevant variables.
include(DuneMPI)
# Make calling fortran routines from C/C++ possible
if(Fortran_Works)
include(FortranCInterface)
FortranCInterface_VERIFY(CXX)
# Write FC.h header containing information about
# how to call fortran routined.
# It will be included in config.h
FortranCInterface_HEADER(FC.h MACRO_NAMESPACE "FC_")
else(Fortran_Works)
# Write empty FC.h header
file(WRITE ${CMAKE_BINARY_DIR}/FC.h "")
endif(Fortran_Works)
# Create custom target for building the documentation
# and provide macros for installing the docs and force
# building them before.
include(DuneDoc)
# activate testing the DUNE way
include(DuneTests)
# activate pkg-config
include(DunePkgConfig)
dune_process_dependency_tree("${DEPENDS_MODULE}" "${DEPENDS_VERSION}"
"${SUGGESTS_MODULE}" "${SUGGESTS_VERSION}")
# Search for cmake files containing tests and directives
# specific to this module
dune_module_to_macro(_macro ${DUNE_MOD_NAME})
set(DUNE_MOD_NAME_CMAKE "${_macro}")
set(_macro "${_macro}Macros")
set(_mod_cmake _mod_cmake-NOTFOUND) # Prevent false positives due to caching
find_file(_mod_cmake
${_macro}.cmake
${CMAKE_MODULE_PATH}
${CMAKE_SOURCE_DIR}/cmake/modules
NO_DEFAULT_PATH)
if(_mod_cmake)
set(${DUNE_MOD_NAME_CMAKE}_FOUND FOUND)
message(STATUS " Performing tests specific to ${DUNE_MOD_NAME} from file ${_mod_cmake}.")
include(${_mod_cmake})
else(_mod_cmake)
message(STATUS "There are no tests for module ${DUNE_MOD_NAME}.")
endif(_mod_cmake)
include(GNUInstallDirs)
# Set variable where the cmake modules will be installed.
# Thus the user can override it and for example install
# directly into the CMake installation. We use a cache variable
# that is overridden by a local variable of the same name if
# the user does not explicitely set a value for it. Thus the value
# will automatically change if the user changes CMAKE_INSTALL_DATAROOTDIR
# or CMAKE_INSTALL_PREFIX
if(NOT DUNE_INSTALL_MODULEDIR)
set(DUNE_INSTALL_MODULEDIR ""
CACHE PATH
"Installation directory for CMake modules. Default is \${CMAKE_INSTALL_DATAROOTDIR}/cmake/modules when not set explicitely")
set(DUNE_INSTALL_MODULEDIR ${CMAKE_INSTALL_DATAROOTDIR}/cmake/modules)
endif(NOT DUNE_INSTALL_MODULEDIR)
endmacro(dune_project)
# create a new config.h file and overwrite the existing one
macro(dune_regenerate_config_cmake)
set(CONFIG_H_CMAKE_FILE "${CMAKE_BINARY_DIR}/config.h.cmake")
if(EXISTS ${CMAKE_SOURCE_DIR}/config.h.cmake)
file(READ ${CMAKE_SOURCE_DIR}/config.h.cmake _file)
string(REGEX MATCH
"/[\\*/][ ]*begin[ ]+${DUNE_MOD_NAME}.*\\/[/\\*][ ]*end[ ]*${DUNE_MOD_NAME}[^\\*]*\\*/"
_myfile "${_file}")
endif(EXISTS ${CMAKE_SOURCE_DIR}/config.h.cmake)
# overwrite file with new content
file(WRITE ${CONFIG_H_CMAKE_FILE} "/* config.h. Generated from config.h.cmake by CMake.
It was generated from config.h.cmake which in turn is generated automatically
from the config.h.cmake files of modules this module depends on. */"
)
# define that we found this module
set(${DUNE_MOD_NAME}_FOUND 1)
foreach(_dep ${DUNE_MOD_NAME} ${ALL_DEPENDENCIES})
dune_module_to_uppercase(upper ${_dep})
set(HAVE_${upper} ${${_dep}_FOUND})
file(APPEND ${CONFIG_H_CMAKE_FILE}
"\n\n/* Define to 1 if you have module ${_dep} available */
#cmakedefine01 HAVE_${upper}\n")
endforeach(_dep ${DUNE_MOD_NAME} ${ALL_DEPENDENCIES})
# add previous module specific section
foreach(_dep ${ALL_DEPENDENCIES})
foreach(_mod_conf_file ${${_dep}_PREFIX}/config.h.cmake
${${_dep}_PREFIX}/share/${_dep}/config.h.cmake)
if(EXISTS ${_mod_conf_file})
file(READ "${_mod_conf_file}" _file)
string(REGEX REPLACE
".*/\\*[ ]*begin[ ]+${_dep}[^\\*]*\\*/(.*)/[/\\*][ ]*end[ ]*${_dep}[^\\*]*\\*/" "\\1"
_tfile "${_file}")
# strip the private section
string(REGEX REPLACE "(.*)/[\\*][ ]*begin private.*/[\\*][ ]*end[ ]*private[^\\*]\\*/(.*)" "\\1\\2" _file "${_tfile}")
file(APPEND ${CONFIG_H_CMAKE_FILE} "${_file}")
endif(EXISTS ${_mod_conf_file})
endforeach()
# parse other modules dune.module file to generate variables for config.h
foreach(_dune_module_file ${${_dep}_PREFIX}/dune.module
${${_dep}_PREFIX}/share/${_dep}/dune.module)
if(EXISTS ${_dune_module_file})
get_filename_component(_dune_module_file_path ${_dune_module_file} PATH)
dune_module_information(${_dune_module_file_path} QUIET)
endif(EXISTS ${_dune_module_file})
endforeach()
endforeach(_dep ${ALL_DEPENDENCIES})
# parse again dune.module file of current module to set PACKAGE_* variables
dune_module_information(${CMAKE_SOURCE_DIR} QUIET)
file(APPEND ${CONFIG_H_CMAKE_FILE} "\n${_myfile}")
endmacro(dune_regenerate_config_cmake)
# macro that should be called at the end of the top level CMakeLists.txt.
# Namely it creates config.h and the cmake-config files,
# some install directives and exports the module.
macro(finalize_dune_project)
#create cmake-config files for build tree
configure_file(
${PROJECT_SOURCE_DIR}/${DUNE_MOD_NAME}-config.cmake.in
${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-config.cmake @ONLY)
#create cmake-config files for installation tree
configure_file(
${PROJECT_SOURCE_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake.in
${PROJECT_BINARY_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake @ONLY)
list(LENGTH DEPENDS_MODULE mlength)
math(EXPR len2 "${mlength}-1")
if(mlength GREATER 0)
foreach(i RANGE 0 ${len2})
list(GET DEPENDS_MODULE ${i} _mod)
dune_module_to_macro(_macro ${_mod})
list(GET DEPENDS_VERSION ${i} _ver)
#file(APPEND ${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-config.cmake
#"find_package(${_mod})\n")#include(${_macro}Macros)\n")
#file(APPEND ${PROJECT_BINARY_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake
#"find_package(${_mod})\n")#include(${_macro}Macros)\n")
endforeach(i RANGE 0 ${mlength})
endif(mlength GREATER 0)
if(${DUNE_MOD_NAME_CMAKE}_FOUND)
# This module hast its own tests.
# Execute them during find_package
#file(APPEND ${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-config.cmake
# "include(${DUNE_MOD_NAME_CMAKE}Macros)\n")
#file(APPEND ${PROJECT_BINARY_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake
# "\ninclude(${DUNE_MOD_NAME_CMAKE}Macros)\n")
endif(${DUNE_MOD_NAME_CMAKE}_FOUND)
configure_file(
${PROJECT_SOURCE_DIR}/${DUNE_MOD_NAME}-version.cmake.in
${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-version.cmake @ONLY)
#install dune.module file
install(FILES dune.module DESTINATION lib/dunecontrol/${DUNE_MOD_NAME})
#install cmake-config files
install(FILES ${PROJECT_BINARY_DIR}/cmake/pkg/${DUNE_MOD_NAME}-config.cmake
${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-version.cmake
DESTINATION lib/cmake/${DUNE_MOD_NAME})
#install config.h
if(EXISTS ${CMAKE_SOURCE_DIR}/config.h.cmake)
install(FILES config.h.cmake DESTINATION share/${DUNE_MOD_NAME})
endif(EXISTS ${CMAKE_SOURCE_DIR}/config.h.cmake)
if("${ARGC}" EQUAL "1")
message(STATUS "Adding custom target for config.h generation")
dune_regenerate_config_cmake()
# add a target to generate config.h.cmake
add_custom_target(OUTPUT config.h.cmake
COMMAND dune_regenerate_config_cmake()
DEPENDS stamp-regenerate-config-h)
# actually write the config.h file to disk
# using generated file
configure_file(${CMAKE_CURRENT_BINARY_DIR}/config.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/config.h)
else("${ARGC}" EQUAL "1")
message(STATUS "Not adding custom target for config.h generation")
# actually write the config.h file to disk
configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
endif("${ARGC}" EQUAL "1")
test_dep()
endmacro(finalize_dune_project)
macro(target_link_dune_default_libraries _target)
foreach(_lib ${DUNE_DEFAULT_LIBS})
target_link_libraries(${_target} ${_lib})
endforeach(_lib ${DUNE_DEFAULT_LIBS})
endmacro(target_link_dune_default_libraries)
# Gets path to the common Dune CMake scripts
macro(dune_common_script_dir _script_dir)
if("${CMAKE_PROJECT_NAME}" STREQUAL "dune-common")
set(${_script_dir} ${CMAKE_SOURCE_DIR}/cmake/scripts)
else("${CMAKE_PROJECT_NAME}" STREQUAL "dune-common")
set(${_script_dir} ${dune-common_SCRIPT_DIR})
endif("${CMAKE_PROJECT_NAME}" STREQUAL "dune-common")
endmacro(dune_common_script_dir)
# Gets path to the common Dune CMake scripts source
macro(dune_common_script_source_dir _script_dir)
if("${CMAKE_PROJECT_NAME}" STREQUAL "dune-common")
set(${_script_dir} ${CMAKE_SOURCE_DIR}/cmake/scripts)
else("${CMAKE_PROJECT_NAME}" STREQUAL "dune-common")
set(${_script_dir} ${dune-ommon_SCRIPT_SOURCE_DIR})
endif("${CMAKE_PROJECT_NAME}" STREQUAL "dune-common")
endmacro(dune_common_script_source_dir)
function(dune_expand_object_libraries _SOURCES_var _ADD_LIBS_var _COMPILE_FLAGS_var)
set(_new_SOURCES "")
set(_new_ADD_LIBS "${${_ADD_LIBS_var}}")
set(_new_COMPILE_FLAGS "${${_COMPILE_FLAGS_var}}")
set(_regex "_DUNE_TARGET_OBJECTS:([a-zA-Z0-9_-]+)_")
foreach(_source ${${_SOURCES_var}})
string(REGEX MATCH ${_regex} _matched "${_source}")
if(_matched)
string(REGEX REPLACE "${_regex}" "\\1" _basename "${_source}")
foreach(var _SOURCES _ADD_LIBS _COMPILE_FLAGS)
get_property(_prop GLOBAL PROPERTY DUNE_LIB_${_basename}${var})
list(APPEND _new${var} "${_prop}")
endforeach(var _SOURCES _ADD_LIBS _COMPILE_FLAGS)
else(_matched)
list(APPEND _new_SOURCES "${_source}")
endif(_matched)
endforeach(_source ${${_SOURCES_var}})
foreach(var _SOURCES _ADD_LIBS _COMPILE_FLAGS)
set(${${var}_var} "${_new${var}}" PARENT_SCOPE)
endforeach(var _SOURCES _ADD_LIBS _COMPILE_FLAGS)
endfunction(dune_expand_object_libraries)
# Creates shared and static libraries with the same basename.
# More docu can be found at the top of this file.
macro(dune_add_library basename)
include(CMakeParseArguments)
cmake_parse_arguments(DUNE_LIB "NO_EXPORT;OBJECT" "COMPILE_FLAGS"
"ADD_LIBS;SOURCES" ${ARGN})
if(DUNE_LIB_OBJECT)
if(DUNE_LIB_${basename}_SOURCES)
message(FATAL_ERROR "There is already a library with the name ${basename}, "
"but only one is allowed!")
else(DUNE_LIB_${basename}_SOURCES)
foreach(source ${DUNE_LIB_UNPARSED_ARGUMENTS})
list(APPEND full_path_sources ${CMAKE_CURRENT_SOURCE_DIR}/${source})
endforeach(source ${DUNE_LIB_UNPARSED_ARGUMENTS})
# register sources, libs and flags for building the library later
define_property(GLOBAL PROPERTY DUNE_LIB_${basename}_SOURCES
BRIEF_DOCS "Convenience property with sources for library ${basename}. DO NOT EDIT!"
FULL_DOCS "Convenience property with sources for library ${basename}. DO NOT EDIT!")
set_property(GLOBAL PROPERTY DUNE_LIB_${basename}_SOURCES
"${full_path_sources}")
define_property(GLOBAL PROPERTY DUNE_LIB_${basename}_ADD_LIBS
BRIEF_DOCS "Convenience property with libraries for library ${basename}. DO NOT EDIT!"
FULL_DOCS "Convenience property with libraries for library ${basename}. DO NOT EDIT!")
set_property(GLOBAL PROPERTY DUNE_LIB_${basename}_ADD_LIBS
"${DUNE_LIB_ADD_LIBS}")
define_property(GLOBAL PROPERTY DUNE_LIB_${basename}_COMPILE_FLAGS
BRIEF_DOCS "Convenience property with compile flags for library ${basename}. DO NOT EDIT!"
FULL_DOCS "Convenience property with compile flags for library ${basename}. DO NOT EDIT!")
set_property(GLOBAL PROPERTY DUNE_LIB_${basename}_COMPILE_FLAGS
"${DUNE_LIB_COMPILE_FLAGS}")
endif(DUNE_LIB_${basename}_SOURCES)
else(DUNE_LIB_OBJECT)
list(APPEND DUNE_LIB_SOURCES ${DUNE_LIB_UNPARSED_ARGUMENTS})
dune_expand_object_libraries(DUNE_LIB_SOURCES DUNE_LIB_ADD_LIBS DUNE_LIB_COMPILE_FLAGS)
#create lib
add_library(${basename} ${DUNE_LIB_SOURCES})
# link with specified libraries.
if(DUNE_LIB_ADD_LIBS)
dune_target_link_libraries(${basename} ${DUNE_LIB_ADD_LIBS})
endif(DUNE_LIB_ADD_LIBS)
if(DUNE_LIB_COMPILE_FLAGS)
setproperty(${basename} APPEND_STRING COMPILE_FLAGS
"${DUNE_LIB_COMPILE_FLAGS}")
endif(DUNE_LIB_COMPILE_FLAGS)
# Build library in ${PROJECT_BINARY_DIR}/lib
set_target_properties(${basename} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib"
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set(_created_libs ${basename})
if(DUNE_BUILD_BOTH_LIBS)
if(BUILD_SHARED_LIBS)
#create static lib
add_library(${basename}-static STATIC ${DUNE_LIB_SOURCES})
# make sure both libs have the same name.
set_target_properties(${basename}-static PROPERTIES
OUTPUT_NAME ${basename}
ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
list(APPEND _created_libs ${basename}-static)
# link with specified libraries.
if(DUNE_LIB_ADD_LIBS)
dune_target_link_libraries(${basename}-static ${DUNE_LIB_ADD_LIBS})
endif(DUNE_LIB_ADD_LIBS)
if(DUNE_LIB_COMPILE_FLAGS)
setproperty(${basename}-static APPEND_STRING COMPILE_FLAGS
"${DUNE_LIB_COMPILE_FLAGS}")
endif(DUNE_LIB_COMPILE_FLAGS)
else(BUILD_SHARED_LIBS)
#create shared libs
add_library(${basename}-shared SHARED ${DUNE_LIB_SOURCES})
set_target_properties(${basename}-shared PROPERTIES
OUTPUT_NAME ${basename}
LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
# link with specified libraries.
if(DUNE_LIB_ADD_LIBS)
dune_target_link_libraries(${basename}-shared ${DUNE_LIB_ADD_LIBS})
endif(DUNE_LIB_ADD_LIBS)
if(DUNE_LIB_COMPILE_FLAGS)
setproperty(${basename}-shared APPEND_STRING COMPILE_FLAGS
"${DUNE_LIB_COMPILE_FLAGS}")
endif(DUNE_LIB_COMPILE_FLAGS)
list(APPEND _created_libs ${basename}-shared)
endif(BUILD_SHARED_LIBS)
endif(DUNE_BUILD_BOTH_LIBS)
if(NOT DUNE_LIB_NO_EXPORT)
if(NOT _MODULE_EXPORT_USED)
set(_MODULE_EXPORT_USED ON)
set(_append "")
else(NOT _MODULE_EXPORT_USED)
set(_append APPEND)
endif(NOT _MODULE_EXPORT_USED)
# install targets to use the libraries in other modules.
install(TARGETS ${_created_libs}
EXPORT ${DUNE_MOD_NAME}-targets DESTINATION lib)
install(EXPORT ${DUNE_MOD_NAME}-targets
DESTINATION lib/cmake)
# export libraries for use in build tree
export(TARGETS ${_created_libs} ${_append}
FILE ${PROJECT_BINARY_DIR}/${DUNE_MOD_NAME}-targets.cmake)
endif(NOT DUNE_LIB_NO_EXPORT)
endif(DUNE_LIB_OBJECT)
endmacro(dune_add_library basename sources)
macro(replace_properties_for_one)
get_property(properties ${option_command} ${_target}
PROPERTY ${REPLACE_PROPERTY})
if(NOT properties)
# property not set. set it directly
foreach(i RANGE 0 ${hlength})
math(EXPR idx "(2 * ${i}) + 1")
list(GET REPLACE_UNPARSED_ARGUMENTS ${idx} repl)
list(APPEND replacement ${repl})
endforeach(i RANGE 0 ${hlength})
list(REMOVE_DUPLICATES replacement)
set_property(${option_command} ${_target} ${REPLACE_APPEND}
${REPLACE_APPEND_STRING} PROPERTY ${REPLACE_PROPERTY} ${replacement})
else(NOT properties)
foreach(prop ${properties})
set(matched FALSE)
foreach(i RANGE 0 ${hlength})
math(EXPR regexi "2 * ${i}")
math(EXPR repli "${regexi} +1")
list(GET REPLACE_UNPARSED_ARGUMENTS ${regexi} regex)
list(GET REPLACE_UNPARSED_ARGUMENTS ${repli} replacement)
string(REGEX MATCH ${regex} match ${prop})
if(match)
list(APPEND new_props ${replacement})
set(matched TRUE)
endif(match)
endforeach(i RANGE 0 ${hlength})
if(NOT matched)
list(APPEND new_props ${prop})
endif(NOT matched)
endforeach(prop ${properties})
list(REMOVE_DUPLICATES new_props)
set_property(${option_command} ${_target}
PROPERTY ${REPLACE_PROPERTY} ${new_props})
endif(NOT properties)
get_property(properties ${option_command} ${_target} PROPERTY ${REPLACE_PROPERTY})
endmacro(replace_properties_for_one)
function(dune_target_link_libraries basename libraries)
target_link_libraries(${basename} ${libraries})
if(DUNE_BUILD_BOTH_LIBS)
if(BUILD_SHARED_LIBS)
target_link_libraries(${basename}-static ${libraries})
else(BUILD_SHARED_LIBS)
target_link_libraries(${basename}-shared ${libraries})
endif(BUILD_SHARED_LIBS)
endif(DUNE_BUILD_BOTH_LIBS)
endfunction(dune_target_link_libraries basename libraries)
function(replace_properties)
include(CMakeParseArguments)
set(_first_opts "GLOBAL;DIRECTORY;TARGET;SOURCE;CACHE")
cmake_parse_arguments(REPLACE "GLOBAL"
"DIRECTORY;PROPERTY" "TARGET;SOURCE;TEST;CACHE" ${ARGN})
set(MY_DIRECTORY TRUE)
foreach(i ${_first_opts})
if(REPLACE_${i})
set(MY_DIRECTORY FALSE)
endif(REPLACE_${i})
endforeach(i ${_first_opts})
if(NOT MY_DIRECTORY)
list(FIND REPLACE_UNPARSED_ARGUMENTS DIRECTORY _found)
if(_found GREATER -1)
list(REMOVE_AT REPLACE_UNPARSED_ARGUMENTS ${_found})
set(MY_DIRECTORY TRUE)
set(REPLACE_DIRECTORY "")
endif(_found GREATER -1)
else(NOT MY_DIRECTORY)
#set(REPLACE_PROPERTY
endif(NOT MY_DIRECTORY)
#setup options
if(REPLACE_GLOBAL)
set(option_command GLOBAL)
elseif(MY_DIRECTORY)
set(option_command DIRECTORY)
elseif(REPLACE_DIRECTORY)
set(option_command DIRECTORY)
set(option_arg ${REPLACE_DIRECTORY})
elseif(REPLACE_TARGET)
set(option_command TARGET)
set(option_arg ${REPLACE_TARGET})
elseif(REPLACE_SOURCE)
set(option_command SOURCE)
set(option_arg ${REPLACE_SOURCE})
elseif(REPLACE_TEST)
set(option_command TEST)
set(option_arg${REPLACE_TEST})
elseif(REPLACE_CACHE)
set(option_command CACHE)
set(option_arg ${REPLACE_CACHE})
endif()
if(NOT (REPLACE_CACHE OR REPLACE_TEST OR REPLACE_SOURCE
OR REPLACE_TARGET OR REPLACE_DIRECTORY OR REPLACE_GLOBAL
OR MY_DIRECTORY))
message(ERROR "One of GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, or CACHE"
" has to be present")
endif()
list(LENGTH REPLACE_UNPARSED_ARGUMENTS length)
# if(NOT (REPLACE_GLOBAL AND REPLACE_TARGET AND
# REPLACE_SOURCE AND REPLACE
math(EXPR mlength "${length} % 2 ")
math(EXPR hlength "${length} / 2 - 1")
if(NOT ${mlength} EQUAL 0)
message(ERROR "You need to specify pairs consisting of a regular expression and a replacement string.")
endif(NOT ${mlength} EQUAL 0)
if(NOT length GREATER 0)
message(ERROR "You need to specify at least on pair consisting of a regular expression
and a replacement string. ${REPLACE_UNPARSED_ARGUMENTS}")
endif(NOT length GREATER 0)
foreach(_target ${option_arg})
replace_properties_for_one()
endforeach(_target ${option_arg})
list(LENGTH option_arg _length)
if(_length EQUAL 0)
replace_properties_for_one()
endif(_length EQUAL 0)
endfunction(replace_properties)