Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • jakub.both/dune-common
  • samuel.burbulla/dune-common
  • patrick.jaap/dune-common
  • tobias.leibner/dune-common
  • alexander.mueller/dune-common
  • pipping/dune-common
  • Xinyun.Li/dune-common
  • felix.schindler/dune-common
  • simon.praetorius/dune-common
  • ani.anciaux-sedrakian/dune-common
  • henrik.stolzmann/dune-common
  • matthew.t.collins/dune-common
  • liam.keegan/dune-common
  • felix.mueller/dune-common
  • ansgar/dune-common
  • dominic/dune-common
  • lars.lubkoll/dune-common
  • exadune/dune-common
  • felix.gruber/dune-common
  • govind.sahai/dune-common
  • michael.sghaier/dune-common
  • core/dune-common
  • kilian.weishaupt/dune-common
  • markus.blatt/dune-common
  • joscha.podlesny/dune-common
  • andreas.thune/dune-common
  • lars.bilke/dune-common
  • daniel.kienle/dune-common
  • lukas.renelt/dune-common
  • smuething/dune-common
  • stephan.hilb/dune-common
  • tkoch/dune-common
  • nils.dreier/dune-common
  • rene.milk/dune-common
  • lasse.hinrichsen/dune-common
  • yunus.sevinchan/dune-common
  • lisa_julia.nebel/dune-common
  • claus-justus.heine/dune-common
  • lorenzo.cerrone/dune-common
  • eduardo.bueno/dune-common
40 results
Show changes
Commits on Source (63)
Showing
with 851 additions and 134 deletions
......@@ -181,10 +181,15 @@ PROJECT="$1"
DEPENDENCIES="$2"
VERSION="$3"
MAINTAINER="$4"
ENABLE_ALL="$5"
################## READ OPTIONS ##################
while [ "$DATACORRECT" != "y" -a "$DATACORRECT" != "Y" ]; do
# Track minimum CMake version
CMAKE_MINIMUM_REQUIRED=2.8.6
while [ -z $PROJECT ]; do
read -p "1) Name of your new Project? (e.g.: dune-grid): " PROJECT
if echo "$MODULES" | grep -q ^$PROJECT$; then
......@@ -225,14 +230,30 @@ while [ "$DATACORRECT" != "y" -a "$DATACORRECT" != "Y" ]; do
while [ -z "$MAINTAINER" ]; do
read -p "4) Maintainer's email address? " MAINTAINER
done
while [ "$ENABLE_ALL" != "y" -a "$ENABLE_ALL" != "Y" ]; do
read -p "5) Enable all found packages? (WE strongly recommend yes, unless you know exactly what you are doing) [y/N]" ENABLE_ALL
while [ "$ENABLE_ALL" != "y" -a "$ENABLE_ALL" != "Y" -a "$ENABLE_ALL" != "n" -a "$ENABLE_ALL" != "N" ]; do
echo "5) Enable all available packages? (Choose 'y' if you don't understand the question, but see warning below.)"
read -p " WARNING: If you enable this option, your module will require at least CMake 2.8.12 to build. You can check your version with 'cmake --version' [y/N]" ENABLE_ALL
done
# canonicalize contents of ENABLE_ALL
ENABLE_ALL=$(tr '[:upper:]' '[:lower:]' <<< "$ENABLE_ALL")
# set newer CMake minimum version if ENABLE_ALL is true
if [ 'y' == "$ENABLE_ALL" ] ; then
CMAKE_MINIMUM_REQUIRED=2.8.12
fi
echo
echo "creating Project \"$PROJECT\", version $VERSION "
echo "which depends on \"$DEPENDENCIES\""
echo "with maintainer \"$MAINTAINER\""
if [ "y" == "$ENABLE_ALL" ] ; then
echo "and new, automatic external package handling based on dune_enable_all_packages()."
else
echo "and old external package handling (you need to manually add external dependencies to each target in CMakeLists.txt)."
fi
echo "Minimum required CMake version for building this project: ${CMAKE_MINIMUM_REQUIRED}"
echo
read -p "Are these informations correct? [y/N] " DATACORRECT
# reset data if necessary
......@@ -243,7 +264,14 @@ while [ "$DATACORRECT" != "y" -a "$DATACORRECT" != "Y" ]; do
MAINTAINER=""
ENABLE_ALL=""
fi
done
done
# canonicalize contents of ENABLE_ALL
ENABLE_ALL=$(tr '[:upper:]' '[:lower:]' <<< "$ENABLE_ALL")
echo
echo "A sample code $MODULE.cc is generated in the \"$PROJECT\" directory."
......@@ -373,7 +401,7 @@ Preparing the Sources
Additional to the software mentioned in README you'll need the
following programs installed on your system:
cmake >= 2.8.6
cmake >= ${CMAKE_MINIMUM_REQUIRED}
or if you use the old autoconf build system:
......@@ -486,7 +514,7 @@ M_DELIM
################## CMakeLists.txt ##################
echo "- $PROJECT/CMakeLists.txt"
cat> "$PROJECT/CMakeLists.txt" << M_DELIM
cmake_minimum_required(VERSION 2.8.6)
cmake_minimum_required(VERSION ${CMAKE_MINIMUM_REQUIRED})
project($PROJECT CXX)
if(NOT (dune-common_DIR OR dune-common_ROOT OR
......@@ -506,7 +534,7 @@ include(DuneMacros)
# start a dune project with information from dune.module
dune_project()
M_DELIM
if test ! -z "$ENABLE_ALL"; then
if [ 'y' == "$ENABLE_ALL" ] ; then
cat>> "$PROJECT/CMakeLists.txt" << M_DELIM
dune_enable_all_packages()
M_DELIM
......
......@@ -30,6 +30,7 @@ set(modules
FindUMFPack.cmake
Headercheck.cmake
LanguageSupport.cmake
OverloadCompilerFlags.cmake
UseInkscape.cmake
UseLATEX.cmake)
set(test_programs CheckForPthreads.c)
......
......@@ -60,7 +60,33 @@ check_cxx_source_compiles("
return 0;
}
" HAVE_NULLPTR
)
)
if(HAVE_NULLPTR)
check_cxx_source_compiles("
#include <cstddef>
int main(void)
{
std::nullptr_t npt = nullptr;
return 0;
}
" HAVE_NULLPTR_T
)
if (NOT HAVE_NULLPTR_T)
if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Intel")
message(FATAL_ERROR "Your compiler supports the 'nullptr' keyword, but not the type std::nullptr_t.
You are using an Intel compiler, where this error is typically caused by an outdated underlying system GCC.
Check if 'gcc --version' gives you at least GCC 4.6, otherwise please install a newer GCC and point your Intel compiler at it using the '-gcc-name' or '-gxx-name' options (see 'man icc' for further details)."
)
else()
message(FATAL_ERROR "Your compiler supports the 'nullptr' keyword, but not the type std::nullptr_t.
THIS SHOULD NOT HAPPEN FOR YOUR COMPILER!
Please submit a bug at https://dune-project.org/flyspray/"
)
endif()
endif()
endif()
# __attribute__((unused))
check_cxx_source_compiles("
......@@ -278,8 +304,16 @@ if(${CMAKE_VERSION} VERSION_LESS "3.1")
else()
find_package(Threads)
endif()
set(STDTHREAD_LINK_FLAGS "${CMAKE_THREAD_LIBS_INIT}"
CACHE STRING "Linker flags needed to get working C++11 threads support")
# see whether threading needs -no-as-needed
if(EXISTS /etc/dpkg/origins/ubuntu)
set(NO_AS_NEEDED "-Wl,-no-as-needed ")
else(EXISTS /etc/dpkg/origins/ubuntu)
set(NO_AS_NEEDED "")
endif(EXISTS /etc/dpkg/origins/ubuntu)
set(STDTHREAD_LINK_FLAGS "${NO_AS_NEEDED}${CMAKE_THREAD_LIBS_INIT}"
CACHE STRING "Linker flags needed to get working C++11 threads support. On Ubuntu it may be necessary to include -Wl,-no-as-needed (see FS#1650).")
# set linker flags
#
......
......@@ -8,7 +8,8 @@
# perform tests
include(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("#include <cxxabi.h>
CHECK_CXX_SOURCE_COMPILES("#include <typeinfo>
#include <cxxabi.h>
int main(void){
int foobar = 0;
const char *foo = typeid(foobar).name();
......
# This module provides the macros necessary for a simplified CMake build system
# This module provides the functions necessary for a simplified CMake build system
#
# The dune build system relies on the user to choose and add the compile and link flags
# The DUNE build system relies on the user to choose and add the compile and link flags
# necessary to build an executable. While this offers full control to the user, it
# is an error-prone procedure.
#
# Alternatively, users may use this modules macros to simply add the compile flags for all
# found external modules to all executables in a module. Likewise, all found libraries are
# Alternatively, users may use the functions in this module to simply add the compile flags for all
# found external modules to all executables in a DUNE module. Likewise, all found libraries are
# linked to all targets.
#
# This module provides the following macros:
# This module provides the following functions:
#
# dune_enable_all_packages(INCLUDE_DIRS [include_dirs]
# COMPILE_DEFINITIONS [compile_definitions]
# COMPILE_OPTIONS [compile_options]
# MODULE_LIBRARIES [libraries]
# [VERBOSE] [APPEND]
# )
#
# Adds all flags and all libraries to all executables that are subsequently added in the directory
# from where this macro is called and from all its subdirectories (recursively).
# If used, this macro MUST be called in the top level CMakeLists.txt BEFORE adding any subdirectories!
# from where this function is called and from all its subdirectories (recursively).
# If used, this function MUST be called in the top level CMakeLists.txt BEFORE adding any subdirectories!
# You can optionally add additional include dirs and compile definitions that will also be applied to
# all targets in the module.
# Finally, if your module contains libraries as well as programs and if the programs should automatically
......@@ -29,40 +30,61 @@
# versions handle linking (in particular CMP022 and CMP038). You can later add source files to the library
# anywhere in the source tree by calling dune_library_add_sources().
#
# Warning: dune_enable_all_packages() requires CMake 2.8.12+. If you call this function with an older version
# of CMake, the build will fail with a fatal error. DO NOT enable this feature if your module needs
# to compile on machines with an older version of CMake.
# Warning: The library feature requires CMake 3.1+. If you use the feature with older versions, CMake
# will emit a fatal error. Moreover, it will issue a warning if the cmake_minimum_required()
# version is older than 3.1.
# Note: If you want to use dune_enable_all_packages() with an older version of CMake and your DUNE mdule
# creates its own library, you have to manually create the library in the top-level CMakeLists.txt
# file using dune_add_library() (with all sources listed within that call), use
# dune_target_enable_all_packages() to add all packages to the library and finally list that library
# under LIBRARIES in the call to dune_register_package_flags(). See dune-pdelab for an example of
# how to do this correctly.
#
# For a description of the APPEND option, see the documentation of dune_register_package_flags().
# With the VERBOSE option being set, the list of flags is printed during configure.
#
# dune_register_package_flags(COMPILE_DEFINITIONS flags
# INCLUDE_DIRS includes
# LIBRARIES libs
# [APPEND]
# )
#
# To implement above feature, the compile flags, include paths and link flags of all
# found packages must be registered with this macro. This macro is only necessary for people
# that do link against additional libraries which are not supported by the dune core modules.
# Call this at the end of every find module. If you are using an external find module which
# you cannot alter, call it after the call find_package().
# The APPEND parameter appends the given flags to the global list instead of prepending.
# Only use it, if you know what you are doing.
# With the VERBOSE option set, the list of flags is printed during configure.
#
#
# dune_target_enable_all_packages(TARGETS [target] ...)
#
# Adds all currently registered package flags (see dune_register_package_flags()) to the given targets.
# This function is mainly intended to help write DUNE modules that want to use dune_enable_all_packages() and
# define their own libraries, but need to be compatible with CMake < 3.1.
#
# Note: Just like dune_enable_all_packages(), this function requires CMake 2.8.12+.
#
#
# dune_register_package_flags(COMPILE_DEFINITIONS [flags]
# COMPILE_OPTIONS [options]
# INCLUDE_DIRS {includes]
# LIBRARIES [libs]
# [APPEND]
# )
#
# To correctly implement the automatic handling of external libraries, the compile flags, include paths and link
# flags of all found packages must be registered with this function. This function is only necessary for people that
# want to write their own FindFooBar CMake modules to link against additional libraries which are not supported by
# the DUNE core modules. Call this function at the end of every find module. If you are using an external FindFoo
# module which you cannot alter, call it after the call to find_package(foo).
# The APPEND parameter appends the given flags to the global list instead of prepending. Only use it, if you know
# what you are doing.
#
#
# dune_library_add_sources(module_library
# SOURCES [sources]
# )
#
# Adds the source files listed in [sources] to the module library module_library created by an earlier
# call to dune_enable_all_packages.
# Adds the source files listed in [sources] to the DUNE module library module_library created by an earlier
# call to dune_enable_all_packages() in the current DUNE module.
#
function(dune_register_package_flags)
include(CMakeParseArguments)
set(OPTIONS APPEND)
set(SINGLEARGS)
set(MULTIARGS COMPILE_DEFINITIONS INCLUDE_DIRS LIBRARIES)
set(MULTIARGS COMPILE_DEFINITIONS COMPILE_OPTIONS INCLUDE_DIRS LIBRARIES)
cmake_parse_arguments(REGISTRY "${OPTIONS}" "${SINGLEARGS}" "${MULTIARGS}" ${ARGN})
if(REGISTRY_UNPARSED_ARGUMENTS)
......@@ -73,18 +95,31 @@ function(dune_register_package_flags)
set_property(GLOBAL APPEND PROPERTY ALL_PKG_INCS "${REGISTRY_INCLUDE_DIRS}")
set_property(GLOBAL APPEND PROPERTY ALL_PKG_LIBS "${REGISTRY_LIBRARIES}")
set_property(GLOBAL APPEND PROPERTY ALL_PKG_DEFS "${REGISTRY_COMPILE_DEFINITIONS}")
set_property(GLOBAL APPEND PROPERTY ALL_PKG_OPTS "${REGISTRY_COMPILE_OPTIONS}")
else(REGISTRY_APPEND)
get_property(all_incs GLOBAL PROPERTY ALL_PKG_INCS)
get_property(all_libs GLOBAL PROPERTY ALL_PKG_LIBS)
get_property(all_defs GLOBAL PROPERTY ALL_PKG_DEFS)
get_property(all_opts GLOBAL PROPERTY ALL_PKG_OPTS)
set_property(GLOBAL PROPERTY ALL_PKG_INCS "${REGISTRY_INCLUDE_DIRS}" "${all_incs}")
set_property(GLOBAL PROPERTY ALL_PKG_LIBS "${REGISTRY_LIBRARIES}" "${all_libs}")
set_property(GLOBAL PROPERTY ALL_PKG_DEFS "${REGISTRY_COMPILE_DEFINITIONS}" "${all_defs}")
set_property(GLOBAL PROPERTY ALL_PKG_OPTS "${REGISTRY_COMPILE_OPTIONS}" "${all_opts}")
endif(REGISTRY_APPEND)
endfunction(dune_register_package_flags)
macro(dune_enable_all_packages)
function(dune_enable_all_packages)
if (CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "dune_enable_all_packages() needs CMake 2.8.12+")
elseif(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(WARNING
"You are using dune_enable_all_packages().
This requires at least CMake 2.8.12, but your Dune module only requires ${CMAKE_MINIMUM_REQUIRED_VERSION}.
Update the cmake_minimum_required() call in your main CMakeLists.txt file to get rid of this warning.")
endif()
include(CMakeParseArguments)
set(OPTIONS APPEND VERBOSE)
set(SINGLEARGS)
......@@ -115,7 +150,7 @@ macro(dune_enable_all_packages)
# handle additional compile definitions specified in dune_enable_all_packages
if(DUNE_ENABLE_ALL_PACKAGES_COMPILE_DEFINITIONS)
if(DUNE_ENABLE_ALL_PACKAGES_COMPILE_DEFINITIONS)
if(DUNE_ENABLE_ALL_PACKAGES_APPEND)
set_property(GLOBAL APPEND PROPERTY ALL_PKG_DEFS "${DUNE_ENABLE_ALL_PACKAGES_COMPILE_DEFINITIONS}")
else(DUNE_ENABLE_ALL_PACKAGES_APPEND)
get_property(all_defs GLOBAL PROPERTY ALL_PKG_DEFS)
......@@ -125,14 +160,37 @@ macro(dune_enable_all_packages)
# add compile definitions to all targets in module
get_property(all_defs GLOBAL PROPERTY ALL_PKG_DEFS)
foreach(def ${all_defs})
add_definitions("-D${def}")
endforeach(def in ${all_defs})
# We have to do this in a loop because add_definitions() is kind of broken: even though it is supposed
# to be *the* function for adding compile definitions, it does not prepend "-D" (as opposed to
# target_compile_definitions(), which does). Well, whatever...
foreach(_definition ${all_defs})
if(_definition)
add_definitions("-D${_definition}")
endif()
endforeach()
# verbose output of compile definitions
if(DUNE_ENABLE_ALL_PACKAGES_VERBOSE)
message("Compile definitions for this project: ${all_defs}")
endif(DUNE_ENABLE_ALL_PACKAGES_VERBOSE)
# handle additional compile options specified in dune_enable_all_packages
if(DUNE_ENABLE_ALL_PACKAGES_COMPILE_OPTIONS)
if(DUNE_ENABLE_ALL_PACKAGES_APPEND)
set_property(GLOBAL APPEND PROPERTY ALL_PKG_OPTS "${DUNE_ENABLE_ALL_PACKAGES_COMPILE_OPTIONS}")
else(DUNE_ENABLE_ALL_PACKAGES_APPEND)
get_property(all_opts GLOBAL PROPERTY ALL_PKG_OPTS)
set_property(GLOBAL PROPERTY ALL_PKG_OPTS "${DUNE_ENABLE_ALL_PACKAGES_COMPILE_OPTIONS}" "${all_opts}")
endif(DUNE_ENABLE_ALL_PACKAGES_APPEND)
endif(DUNE_ENABLE_ALL_PACKAGES_COMPILE_OPTIONS)
# add compile options to all targets in module
get_property(all_opts GLOBAL PROPERTY ALL_PKG_OPTS)
add_compile_options(${all_opts})
# verbose output of compile definitions
if(DUNE_ENABLE_ALL_PACKAGES_VERBOSE)
message("Compile options for this project: ${all_opts}")
endif(DUNE_ENABLE_ALL_PACKAGES_VERBOSE)
# handle libraries
# this is a little tricky because the libraries defined within the current module require special
# handling to avoid tripping over CMake policies CMP022 and CMP038
......@@ -178,6 +236,14 @@ Update the cmake_minimum_required() call in your main CMakeLists.txt file to get
# ...and add it to all future targets in the module
link_libraries(${module_lib})
endforeach(module_lib ${DUNE_ENABLE_ALL_PACKAGES_MODULE_LIBRARIES})
# export the DUNE_ENABLE_ALL_PACKAGES_MODULE_LIBRARIES variable to the parent scope
# this is required to make dune_library_add_sources() work (see further down)
set(
DUNE_ENABLE_ALL_PACKAGES_MODULE_LIBRARIES
${DUNE_ENABLE_ALL_PACKAGES_MODULE_LIBRARIES}
PARENT_SCOPE
)
endif(DUNE_ENABLE_ALL_PACKAGES_MODULE_LIBRARIES)
if(DUNE_ENABLE_ALL_PACKAGES_VERBOSE)
......@@ -185,10 +251,38 @@ Update the cmake_minimum_required() call in your main CMakeLists.txt file to get
message("Libraries for this project: ${all_libs}")
endif(DUNE_ENABLE_ALL_PACKAGES_VERBOSE)
endmacro(dune_enable_all_packages)
endfunction(dune_enable_all_packages)
function(dune_target_enable_all_packages)
if (CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "dune_target_enable_all_packages() needs CMake 2.8.12+")
elseif(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(WARNING
"You are using dune_target_enable_all_packages().
This requires at least CMake 2.8.12, but your Dune module only requires ${CMAKE_MINIMUM_REQUIRED_VERSION}.
Update the cmake_minimum_required() call in your main CMakeLists.txt file to get rid of this warning.")
endif()
foreach(_target ${ARGN})
get_property(all_incs GLOBAL PROPERTY ALL_PKG_INCS)
target_include_directories(${_target} PUBLIC ${all_incs})
get_property(all_defs GLOBAL PROPERTY ALL_PKG_DEFS)
target_compile_definitions(${_target} PUBLIC ${all_defs})
get_property(all_opts GLOBAL PROPERTY ALL_PKG_OPTS)
target_compile_options(${_target} PUBLIC ${all_opts})
get_property(all_libs GLOBAL PROPERTY ALL_PKG_LIBS)
target_link_libraries(${_target} PUBLIC ${DUNE_LIBS} ${all_libs})
endforeach()
endfunction(dune_target_enable_all_packages)
macro(dune_library_add_sources lib)
function(dune_library_add_sources lib)
# This only works for CMAKE 3.1+ because target_sources() - which we use to add sources to the
# libraries after creating them - was added in that version
......@@ -207,7 +301,6 @@ macro(dune_library_add_sources lib)
"Attempt to add sources to library ${lib}, which has not been defined in dune_enable_all_packages.
List of libraries defined in dune_enable_all_packages: ${DUNE_ENABLE_ALL_PACKAGES_MODULE_LIBRARIES}")
endif()
unset(lib_defined)
include(CMakeParseArguments)
cmake_parse_arguments(DUNE_LIBRARY_ADD_SOURCES "" "" "SOURCES" ${ARGN})
......@@ -219,4 +312,4 @@ List of libraries defined in dune_enable_all_packages: ${DUNE_ENABLE_ALL_PACKAGE
foreach(source ${DUNE_LIBRARY_ADD_SOURCES_SOURCES})
target_sources(${lib} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${source})
endforeach()
endmacro()
endfunction()
......@@ -76,10 +76,17 @@
# library BASENAME
#
# Make CMake use rpath on OS X
if(POLICY CMP0042)
# this policy only needed for CMake older then 2.8.12
cmake_policy(SET CMP0042 NEW)
endif()
enable_language(C) # Enable C to skip CXX bindings for some tests.
include(FeatureSummary)
include(DuneEnableAllPackages)
include(OverloadCompilerFlags)
include(DuneSymlinkOrCopy)
......@@ -212,9 +219,9 @@ macro(find_dune_package module)
set(DUNE_${module}_FOUND ${${module}_FOUND})
endmacro(find_dune_package module)
macro(extract_line HEADER OUTPUT FILE_CONTENT)
set(REGEX "${HEADER}[ ]*[^\n]+")
string(REGEX MATCH ${REGEX} OUTPUT1 "${FILE_CONTENT}")
macro(extract_line HEADER OUTPUT FILE_NAME)
set(REGEX "^${HEADER}[ ]*[^\\n]+")
file(STRINGS "${FILE_NAME}" OUTPUT1 REGEX "${REGEX}")
if(OUTPUT1)
set(REGEX "^[ ]*${HEADER}[ ]*(.+)[ ]*$")
string(REGEX REPLACE ${REGEX} "\\1" ${OUTPUT} "${OUTPUT1}")
......@@ -278,10 +285,8 @@ endfunction(extract_major_minor_version version_string varname)
# 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 strings
extract_line("Version:" MODULE_LINE "${DUNE_MODULE}")
extract_line("Version:" MODULE_LINE "${MODULE_DIR}/dune.module")
if(NOT MODULE_LINE MATCHES ".+")
message(FATAL_ERROR "${MODULE_DIR}/dune.module is missing a version.")
endif(NOT MODULE_LINE MATCHES ".+")
......@@ -291,19 +296,19 @@ macro(dune_module_information MODULE_DIR)
# find strings for module name, maintainer
# 1. Check for line starting with Module
extract_line("Module:" DUNE_MOD_NAME "${DUNE_MODULE}")
extract_line("Module:" DUNE_MOD_NAME "${MODULE_DIR}/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}")
extract_line("Maintainer:" DUNE_MAINTAINER "${MODULE_DIR}/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_MOD_NAME}_DEPENDS "${DUNE_MODULE}")
extract_line("Depends:" ${DUNE_MOD_NAME}_DEPENDS "${MODULE_DIR}/dune.module")
if(${DUNE_MOD_NAME}_DEPENDS)
split_module_version(${${DUNE_MOD_NAME}_DEPENDS} ${DUNE_MOD_NAME}_DEPENDS_MODULE ${DUNE_MOD_NAME}_DEPENDS_VERSION)
foreach(_mod ${${DUNE_MOD_NAME}_DEPENDS})
......@@ -316,7 +321,7 @@ macro(dune_module_information MODULE_DIR)
endif(${DUNE_MOD_NAME}_DEPENDS)
# 4. Check for line starting with Suggests
extract_line("Suggests:" ${DUNE_MOD_NAME}_SUGGESTS "${DUNE_MODULE}")
extract_line("Suggests:" ${DUNE_MOD_NAME}_SUGGESTS "${MODULE_DIR}/dune.module")
if(${DUNE_MOD_NAME}_SUGGESTS)
split_module_version(${${DUNE_MOD_NAME}_SUGGESTS} ${DUNE_MOD_NAME}_SUGGESTS_MODULE ${DUNE_MOD_NAME}_SUGGESTS_VERSION)
convert_deps_to_list(${DUNE_MOD_NAME}_SUGGESTS)
......@@ -546,6 +551,9 @@ macro(dune_project)
message(FATAL_ERROR "You need to specify an absolute path to your compiler instead of just the compiler name. cmake >= 3.0 fixes this issue.")
endif()
# check if CXX flag overloading has been enabled (see OverloadCompilerFlags.cmake)
initialize_compiler_script()
# extract information from dune.module
dune_module_information(${CMAKE_SOURCE_DIR})
set(ProjectName "${DUNE_MOD_NAME}")
......@@ -556,6 +564,14 @@ macro(dune_project)
set(ProjectVersionRevision "${DUNE_VERSION_REVISION}")
set(ProjectMaintainerEmail "${DUNE_MAINTAINER}")
# check whether this module has been explicitly disabled through the cmake flags.
# If so, stop the build. This is necessary because dunecontrol does not parse
# the given CMake flags for a disabled Dune modules.
if(CMAKE_DISABLE_FIND_PACKAGE_${ProjectName})
message("Module ${ProjectName} has been explicitly disabled through the cmake flags. Skipping build.")
return()
endif()
define_property(GLOBAL PROPERTY DUNE_MODULE_LIBRARIES
BRIEF_DOCS "List of libraries of the module. DO NOT EDIT!"
FULL_DOCS "List of libraries of the module. Used to generate CMake's package configuration files. DO NOT EDIT!")
......@@ -669,13 +685,6 @@ macro(dune_project)
include(Headercheck)
setup_headercheck()
# check whether the user wants to append compile flags upon calling make
if(ALLOW_EXTRA_CXXFLAGS AND (${CMAKE_GENERATOR} MATCHES ".*Unix Makefiles.*"))
file(WRITE ${CMAKE_BINARY_DIR}/compiler.sh
"#!/bin/bash\nif [ -n \"$VERBOSE\" ] ; then\necho 1>&2 \"Additional flags: \$EXTRA_CXXFLAGS\"\nfi\nexec ${CMAKE_CXX_COMPILER} \"\$@\" \$EXTRA_CXXFLAGS")
exec_program(chmod ARGS "+x ${CMAKE_BINARY_DIR}/compiler.sh")
set(CMAKE_CXX_COMPILER ${CMAKE_BINARY_DIR}/compiler.sh)
endif()
endmacro(dune_project)
# create a new config.h file and overwrite the existing one
......@@ -878,6 +887,10 @@ endif()
include(CPack)
feature_summary(WHAT ALL)
# check if CXX flag overloading has been enabled
# and write compiler script (see OverloadCompilerFlags.cmake)
finalize_compiler_script()
endmacro(finalize_dune_project)
macro(target_link_dune_default_libraries _target)
......
......@@ -27,16 +27,16 @@
# in the source tree. This file will be copied
# to the build tree.
#
# dune_symlink_to_source_tree()
# dune_symlink_to_source_tree([NAME name])
#
# add a symlink called src_dir to all directories in the build tree.
# add a symlink called NAME to all directories in the build tree (defaults to src_dir).
# That symlink points to the corresponding directory in the source tree.
# Call the macro from the toplevel CMakeLists.txt file of your project.
# You can also call it from some other directory, creating only symlinks
# in that directory and all directories below. A warning is issued on
# Windows systems.
#
# dune_symlink_to_source_files(files)
# dune_symlink_to_source_files(FILES files)
#
# add symlinks to the build tree, which point to files in the source tree.
# Foreach file given in "files", a symlink of that name is created in the
......@@ -63,7 +63,14 @@ macro(dune_add_copy_dependency target file_name)
add_dependencies(${target} "${target}_copy_${file_name}")
endmacro(dune_add_copy_dependency)
macro(dune_symlink_to_source_tree)
function(dune_symlink_to_source_tree)
# parse arguments
include(CMakeParseArguments)
cmake_parse_arguments(ARG "" "NAME" "" ${ARGN})
if(NOT ARG_NAME)
set(ARG_NAME "src_dir")
endif()
# check for Windows to issue a warning
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
if(NOT DEFINED DUNE_WINDOWS_SYMLINK_WARNING)
......@@ -78,15 +85,22 @@ macro(dune_symlink_to_source_tree)
foreach(f ${files})
get_filename_component(dir ${f} DIRECTORY)
if(NOT "${CMAKE_SOURCE_DIR}/${dir}" MATCHES "${CMAKE_BINARY_DIR}/*")
execute_process(COMMAND ${CMAKE_COMMAND} "-E" "create_symlink" "${CMAKE_SOURCE_DIR}/${dir}" "${CMAKE_BINARY_DIR}/${dir}/src_dir")
execute_process(COMMAND ${CMAKE_COMMAND} "-E" "create_symlink" "${CMAKE_SOURCE_DIR}/${dir}" "${CMAKE_BINARY_DIR}/${dir}/${ARG_NAME}")
endif(NOT "${CMAKE_SOURCE_DIR}/${dir}" MATCHES "${CMAKE_BINARY_DIR}/*")
endforeach()
endif()
endmacro(dune_symlink_to_source_tree)
endfunction(dune_symlink_to_source_tree)
function(dune_symlink_to_source_files)
# parse arguments
include(CMakeParseArguments)
cmake_parse_arguments(ARG "" "" "FILES" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(WARNING "You are using dune_symlink_to_source_files without named arguments (or have typos in your named arguments)!")
endif()
macro(dune_symlink_to_source_files files)
# create symlinks for all given files
foreach(f ${files})
foreach(f ${ARG_FILES})
# check for Windows to issue a warning
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
if(NOT DEFINED DUNE_WINDOWS_SYMLINK_WARNING)
......@@ -99,4 +113,4 @@ macro(dune_symlink_to_source_files files)
execute_process(COMMAND ${CMAKE_COMMAND} "-E" "create_symlink" "${CMAKE_CURRENT_SOURCE_DIR}/${f}" "${CMAKE_CURRENT_BINARY_DIR}/${f}")
endif()
endforeach()
endmacro(dune_symlink_to_source_files files)
endfunction(dune_symlink_to_source_files)
......@@ -7,7 +7,7 @@
#
include(DuneBoost)
if(BOOST_FOUND)
if(HAVE_DUNE_BOOST)
message(STATUS "Checking whether the Boost::FUSION library is available.")
check_cxx_source_compiles("
\#include <boost/fusion/container.hpp>
......@@ -18,6 +18,6 @@ int main(){
if(HAVE_BOOST_FUSION)
message(STATUS "Boost::FUSION is available")
endif(HAVE_BOOST_FUSION)
else(BOOST_FOUND)
else()
message(STATUS "Skipping check for Boost::FUSION as Boost is not available.")
endif(BOOST_FOUND)
endif()
......@@ -30,6 +30,7 @@ MODULES = \
FindUMFPack.cmake \
Headercheck.cmake \
LanguageSupport.cmake \
OverloadCompilerFlags.cmake \
UseInkscape.cmake \
UseLATEX.cmake
......
# check whether the user wants to overload compile flags upon calling make
#
# Provides the following macros:
#
# initialize_compiler_script() : needs to be called before further flags are added to CMAKE_CXX_FLAGS
# finalize_compiler_script() : needs to be called at the end of the cmake macros, e.g. in finalize_dune_project
#
# By default this feature is disabled. Use -DALLOW_CXXFLAGS_OVERWRITE=ON to activate.
# Then the following is possible:
#
# make CXXFLAGS="your flags" GRIDTYPE="grid type"
#
# GRIDTYPE can be anything defined in config.h via the dune_define_gridtype macro from dune-grid.
# Furthermore any CPP variable of the form -DVAR=VALUE can be overloaded on the command line.
#
# Note: If you don't know what this is or what it's good for, don't use it.
#
option(ALLOW_CXXFLAGS_OVERWRITE OFF)
# check whether the user wants to append compile flags upon calling make
if(ALLOW_EXTRA_CXXFLAGS AND (${CMAKE_GENERATOR} MATCHES ".*Unix Makefiles.*"))
message("ALLOW_EXTRA_CXXFLAGS is deprecated, please use -DALLOW_CXXFLAGS_OVERWRITE=ON")
set(ALLOW_CXXFLAGS_OVERWRITE ON)
endif()
macro(find_extended_unix_commands)
include(FindUnixCommands)
find_program (GREP_PROGRAM grep)
if(NOT GREP_PROGRAM)
message( SEND_ERROR "grep not found, please disable ALLOW_CXXFLAGS_OVERWRITE")
endif()
find_program (SED_PROGRAM sed)
if(NOT SED_PROGRAM)
message( SEND_ERROR "sed not found, please disable ALLOW_CXXFLAGS_OVERWRITE")
endif()
find_program (CUT_PROGRAM cut)
if(NOT CUT_PROGRAM)
message( SEND_ERROR "cut not found, please disable ALLOW_CXXFLAGS_OVERWRITE")
endif()
find_program (ENV_PROGRAM env)
if(NOT ENV_PROGRAM)
message( SEND_ERROR "env not found, please disable ALLOW_CXXFLAGS_OVERWRITE")
endif()
find_program (ECHO_PROGRAM echo)
if(NOT ECHO_PROGRAM)
message( SEND_ERROR "echo not found, please disable ALLOW_CXXFLAGS_OVERWRITE")
endif()
find_program (CHMOD_PROGRAM chmod)
if(NOT CHMOD_PROGRAM)
message( SEND_ERROR "chmod not found, please disable ALLOW_CXXFLAGS_OVERWRITE")
endif()
mark_as_advanced(GREP_PROGRAM)
mark_as_advanced(SED_PROGRAM)
mark_as_advanced(CUT_PROGRAM)
mark_as_advanced(ENV_PROGRAM)
mark_as_advanced(ECHO_PROGRAM)
mark_as_advanced(CHMOD_PROGRAM)
endmacro(find_extended_unix_commands)
# init compiler script and store CXX flags
macro(initialize_compiler_script)
if(ALLOW_CXXFLAGS_OVERWRITE AND (${CMAKE_GENERATOR} MATCHES ".*Unix Makefiles.*"))
# check for unix commands necessary
find_extended_unix_commands()
# set CXXFLAGS as environment variable
set( DEFAULT_CXXFLAGS ${CMAKE_CXX_FLAGS})
set( CMAKE_CXX_FLAGS "" )
set( DEFAULT_CXX_COMPILER ${CMAKE_CXX_COMPILER} )
set( COMPILER_SCRIPT_FILE "#!${BASH}\nexec ${CMAKE_CXX_COMPILER} \"\$@\"")
file(WRITE ${CMAKE_BINARY_DIR}/compiler.sh "${COMPILER_SCRIPT_FILE}")
exec_program(${CHMOD_PROGRAM} ARGS "+x ${CMAKE_BINARY_DIR}/compiler.sh")
set(CMAKE_CXX_COMPILER ${CMAKE_BINARY_DIR}/compiler.sh)
endif()
endmacro()
# finalize compiler script and write it
macro(finalize_compiler_script)
if(ALLOW_CXXFLAGS_OVERWRITE AND (${CMAKE_GENERATOR} MATCHES ".*Unix Makefiles.*"))
set( COMPILER_SCRIPT_FILE "#!${BASH}\nSED=${SED_PROGRAM}\nGREP=${GREP_PROGRAM}")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nCUT=${CUT_PROGRAM}\nENV=${ENV_PROGRAM}\nECHO=${ECHO_PROGRAM}")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n# store flags\nFLAGS=\"\$@\"")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nMAKE_EXECUTABLE_NEW=0\n")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nif [ \"\$CXXFLAGS\" == \"\" ]; then\n # default CXX flags\n CXXFLAGS=\"${DEFAULT_CXXFLAGS}\"\nfi\n")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nGRIDS=\nCONFIG_H=${CMAKE_BINARY_DIR}/config.h")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nif [ \"\$GRIDTYPE\" != \"\" ]; then")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n GRIDS=`\$GREP \"defined USED_[A-Z_]*_GRIDTYPE\" \$CONFIG_H | \$SED 's/\\(.*defined USED\\_\\)\\(.*\\)\\(\\_GRIDTYPE*\\)/\\2/g'`\nfi\n")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nOLDFLAGS=\$FLAGS\nFLAGS=")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nfor FLAG in \$OLDFLAGS; do")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n NEWFLAG=\$FLAG\n VARNAME=`\$ECHO \$FLAG | \$GREP \"\\-D\" | \$SED 's/-D//g'`")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n for GRID in \$GRIDS; do\n if [ \"\$VARNAME\" == \"\$GRID\" ]; then\n NEWFLAG=\"-D\$GRIDTYPE\"\n break\n fi\n done")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n VARNAME=`\$ECHO \$VARNAME | \$GREP \"=\" | \$CUT -d \"=\" -f 1`")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n if [ \"\$VARNAME\" != \"\" ]; then\n VAR=`\$ENV | \$GREP \$VARNAME`\n if [ \"\$VAR\" != \"\" ]; then")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n # add variable from environment to flags list\n NEWFLAG=\"-D\$VARNAME=\${!VARNAME}\"\n fi\n fi")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n FLAGS=\"\$FLAGS \$NEWFLAG\"\ndone")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\n\$ECHO \"${DEFAULT_CXX_COMPILER} \$CXXFLAGS \$FLAGS\"")
set( COMPILER_SCRIPT_FILE "${COMPILER_SCRIPT_FILE}\nexec ${DEFAULT_CXX_COMPILER} \$CXXFLAGS \$FLAGS")
file(WRITE ${CMAKE_BINARY_DIR}/compiler.sh "${COMPILER_SCRIPT_FILE}")
endif()
endmacro()
dune_add_latex_document(buildsystem.tex FATHER_TARGET doc DEFAULT_PDF INPUTS ../Makefile.am ../../configure.ac ../example.opts)
create_doc_install(${CMAKE_CURRENT_BINARY_DIR}/buildsystem.pdf ${CMAKE_INSTALL_DOCDIR}/buildsystem)
dune_add_latex_document(cmakefaq.tex FATHER_TARGET doc DEFAULT_PDF)
create_doc_install(${CMAKE_CURRENT_BINARY_DIR}/cmakefaq.pdf ${CMAKE_INSTALL_DOCDIR}/buildsystem)
......@@ -5,7 +5,7 @@ BASEDIR=../..
# install the html pages
docdir=$(datadir)/doc/dune-common/buildsystem
if BUILD_DOCS
DOCFILES=buildsystem.pdf
DOCFILES=buildsystem.pdf cmakefaq.pdf
EXTRA_DIST= CMakeLists.txt $(DOCFILES)
EXTRAINSTALL=$(DOCFILES)
endif
......
\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{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. So, 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}
# Where to search and which files to use
INPUT += @srcdir@/mainpage \
@srcdir@/modules \
@top_srcdir@/dune/common/modules \
INPUT += @srcdir@/mainpage.txt \
@srcdir@/modules.txt \
@top_srcdir@/dune/common/modules.txt \
@top_srcdir@/dune/common
EXCLUDE += @top_srcdir@/dune/common/test \
@top_srcdir@/dune/common/debugallocator.cc
......
File moved
File moved
......@@ -6,7 +6,9 @@
#include <iostream>
#include <limits>
#include <cstdint>
#include <cstdlib>
#include <type_traits>
#include <dune/common/exceptions.hh>
#include <dune/common/hash.hh>
......@@ -28,6 +30,33 @@ namespace Dune
struct MPITraits;
#endif
namespace {
// numeric_limits_helper provides std::numeric_limits access to the internals
// of bigunsignedint. Previously, the correct specialization of std::numeric_limits
// was a friend of bigunsignedint, but that creates problems on recent versions
// of clang with the alternative libc++ library, because that library declares the
// base template of std::numeric_limits as a class and clang subsequently complains
// if the friend declaration uses 'struct'. Unfortunately, libstdc++ uses a struct,
// making it impossible to keep clang happy for both standard libraries.
// So we move the access helper functionality into a custom struct and simply let
// the numeric_limits specialization inherit from the helper.
template<typename T>
struct numeric_limits_helper
{
protected:
static std::uint16_t& digit(T& big_unsigned_int, std::size_t i)
{
return big_unsigned_int.digit[i];
}
};
}
/**
* @brief Portable very large unsigned integers
*
......@@ -42,7 +71,7 @@ namespace Dune
public:
// unsigned short is 16 bits wide, n is the number of digits needed
enum { bits=std::numeric_limits<unsigned short>::digits, n=k/bits+(k%bits!=0),
enum { bits=std::numeric_limits<std::uint16_t>::digits, n=k/bits+(k%bits!=0),
hexdigits=4, bitmask=0xFFFF, compbitmask=0xFFFF0000,
overflowmask=0x1 };
......@@ -50,10 +79,11 @@ namespace Dune
bigunsignedint ();
//! Construct from signed int
bigunsignedint (int x);
template<typename Signed>
bigunsignedint (Signed x, typename std::enable_if<std::is_integral<Signed>::value && std::is_signed<Signed>::value>::type* = 0);
//! Construct from unsigned int
bigunsignedint (std::size_t x);
bigunsignedint (std::uintmax_t x);
//! Print number in hex notation
void print (std::ostream& s) const ;
......@@ -122,7 +152,7 @@ namespace Dune
//! export to other types
// operator unsigned int () const;
unsigned int touint() const;
std::uint_least32_t touint() const;
/**
* @brief Convert to a double.
*
......@@ -131,7 +161,7 @@ namespace Dune
double todouble() const;
friend class bigunsignedint<k/2>;
friend struct std::numeric_limits< bigunsignedint<k> >;
friend struct numeric_limits_helper< bigunsignedint<k> >;
inline friend std::size_t hash_value(const bigunsignedint& arg)
{
......@@ -139,11 +169,11 @@ namespace Dune
}
private:
unsigned short digit[n];
std::uint16_t digit[n];
#if HAVE_MPI
friend struct MPITraits<bigunsignedint<k> >;
#endif
inline void assign(std::size_t x);
inline void assign(std::uintmax_t x);
} ;
......@@ -156,22 +186,24 @@ namespace Dune
}
template<int k>
bigunsignedint<k>::bigunsignedint (int y)
template<typename Signed>
bigunsignedint<k>::bigunsignedint (Signed y, typename std::enable_if<std::is_integral<Signed>::value && std::is_signed<Signed>::value>::type*)
{
std::size_t x = std::abs(y);
assign(x);
if (y < 0)
DUNE_THROW(Dune::Exception, "Trying to construct a Dune::bigunsignedint from a negative integer: " << y);
assign(y);
}
template<int k>
bigunsignedint<k>::bigunsignedint (std::size_t x)
bigunsignedint<k>::bigunsignedint (std::uintmax_t x)
{
assign(x);
}
template<int k>
void bigunsignedint<k>::assign(std::size_t x)
void bigunsignedint<k>::assign(std::uintmax_t x)
{
int no=std::min(static_cast<int>(n),
static_cast<int>(std::numeric_limits<std::size_t>::digits/bits));
static const int no=std::min(static_cast<int>(n),
static_cast<int>(std::numeric_limits<std::uintmax_t>::digits/bits));
for(int i=0; i<no; ++i) {
digit[i] = (x&bitmask);
......@@ -182,7 +214,7 @@ namespace Dune
// export
template<int k>
inline unsigned int bigunsignedint<k>::touint () const
inline std::uint_least32_t bigunsignedint<k>::touint () const
{
return (digit[1]<<bits)+digit[0];
}
......@@ -242,11 +274,11 @@ namespace Dune
inline bigunsignedint<k> bigunsignedint<k>::operator+ (const bigunsignedint<k>& x) const
{
bigunsignedint<k> result;
int overflow=0;
std::uint_fast32_t overflow=0;
for (unsigned int i=0; i<n; i++)
{
int sum = ((int)digit[i]) + ((int)x.digit[i]) + overflow;
std::uint_fast32_t sum = static_cast<std::uint_fast32_t>(digit[i]) + static_cast<std::uint_fast32_t>(x.digit[i]) + overflow;
result.digit[i] = sum&bitmask;
overflow = (sum>>bits)&overflowmask;
}
......@@ -257,16 +289,19 @@ namespace Dune
inline bigunsignedint<k> bigunsignedint<k>::operator- (const bigunsignedint<k>& x) const
{
bigunsignedint<k> result;
int overflow=0;
std::int_fast32_t overflow=0;
for (unsigned int i=0; i<n; i++)
{
int diff = ((int)digit[i]) - (((int)x.digit[i]) + overflow);
std::int_fast32_t diff = static_cast<std::int_fast32_t>(digit[i]) - static_cast<std::int_fast32_t>(x.digit[i]) - overflow;
if (diff>=0)
result.digit[i] = (unsigned short) diff;
{
result.digit[i] = static_cast<std::uint16_t>(diff);
overflow = 0;
}
else
{
result.digit[i] = (unsigned short) (diff+bitmask);
result.digit[i] = static_cast<std::uint16_t>(diff+bitmask+1);
overflow = 1;
}
}
......@@ -281,11 +316,11 @@ namespace Dune
for (unsigned int m=0; m<n; m++) // digit in right factor
{
bigunsignedint<2*k> singleproduct(0);
unsigned int overflow(0);
std::uint_fast32_t overflow(0);
for (unsigned int i=0; i<n; i++)
{
unsigned int digitproduct = ((unsigned int)digit[i])*((unsigned int)x.digit[m])+overflow;
singleproduct.digit[i+m] = (unsigned short) (digitproduct&bitmask);
std::uint_fast32_t digitproduct = static_cast<std::uint_fast32_t>(digit[i])*static_cast<std::uint_fast32_t>(x.digit[m])+overflow;
singleproduct.digit[i+m] = static_cast<std::uint16_t>(digitproduct&bitmask);
overflow = (digitproduct>>bits)&bitmask;
}
finalproduct = finalproduct+singleproduct;
......@@ -299,11 +334,11 @@ namespace Dune
template <int k>
inline bigunsignedint<k>& bigunsignedint<k>::operator++ ()
{
int overflow=1;
std::uint_fast32_t overflow=1;
for (unsigned int i=0; i<n; i++)
{
int sum = ((int)digit[i]) + overflow;
std::uint_fast32_t sum = static_cast<std::uint_fast32_t>(digit[i]) + overflow;
digit[i] = sum&bitmask;
overflow = (sum>>bits)&overflowmask;
}
......@@ -334,11 +369,9 @@ namespace Dune
{
// better slow than nothing
bigunsignedint<k> temp(*this);
bigunsignedint<k> result(0);
while (temp>=x)
{
++result;
temp = temp-x;
}
......@@ -398,7 +431,7 @@ namespace Dune
{
unsigned int temp = result.digit[i];
temp = temp<<j;
result.digit[i] = (unsigned short) (temp&bitmask);
result.digit[i] = static_cast<std::uint16_t>(temp&bitmask);
temp = temp>>bits;
if (i+1<(int)n)
result.digit[i+1] = result.digit[i+1]|temp;
......@@ -421,9 +454,9 @@ namespace Dune
j=shift%bits;
for (unsigned int i=0; i<n; i++)
{
unsigned int temp = result.digit[i];
std::uint_fast32_t temp = result.digit[i];
temp = temp<<(bits-j);
result.digit[i] = (unsigned short) ((temp&compbitmask)>>bits);
result.digit[i] = static_cast<std::uint16_t>((temp&compbitmask)>>bits);
if (i>0)
result.digit[i-1] = result.digit[i-1] | (temp&bitmask);
}
......@@ -477,70 +510,70 @@ namespace Dune
template <int k>
inline bigunsignedint<k> operator+ (const bigunsignedint<k>& x, std::size_t y)
inline bigunsignedint<k> operator+ (const bigunsignedint<k>& x, std::uintmax_t y)
{
bigunsignedint<k> temp(y);
return x+temp;
}
template <int k>
inline bigunsignedint<k> operator- (const bigunsignedint<k>& x, std::size_t y)
inline bigunsignedint<k> operator- (const bigunsignedint<k>& x, std::uintmax_t y)
{
bigunsignedint<k> temp(y);
return x-temp;
}
template <int k>
inline bigunsignedint<k> operator* (const bigunsignedint<k>& x, std::size_t y)
inline bigunsignedint<k> operator* (const bigunsignedint<k>& x, std::uintmax_t y)
{
bigunsignedint<k> temp(y);
return x*temp;
}
template <int k>
inline bigunsignedint<k> operator/ (const bigunsignedint<k>& x, std::size_t y)
inline bigunsignedint<k> operator/ (const bigunsignedint<k>& x, std::uintmax_t y)
{
bigunsignedint<k> temp(y);
return x/temp;
}
template <int k>
inline bigunsignedint<k> operator% (const bigunsignedint<k>& x, std::size_t y)
inline bigunsignedint<k> operator% (const bigunsignedint<k>& x, std::uintmax_t y)
{
bigunsignedint<k> temp(y);
return x%temp;
}
template <int k>
inline bigunsignedint<k> operator+ (std::size_t x, const bigunsignedint<k>& y)
inline bigunsignedint<k> operator+ (std::uintmax_t x, const bigunsignedint<k>& y)
{
bigunsignedint<k> temp(x);
return temp+y;
}
template <int k>
inline bigunsignedint<k> operator- (std::size_t x, const bigunsignedint<k>& y)
inline bigunsignedint<k> operator- (std::uintmax_t x, const bigunsignedint<k>& y)
{
bigunsignedint<k> temp(x);
return temp-y;
}
template <int k>
inline bigunsignedint<k> operator* (std::size_t x, const bigunsignedint<k>& y)
inline bigunsignedint<k> operator* (std::uintmax_t x, const bigunsignedint<k>& y)
{
bigunsignedint<k> temp(x);
return temp*y;
}
template <int k>
inline bigunsignedint<k> operator/ (std::size_t x, const bigunsignedint<k>& y)
inline bigunsignedint<k> operator/ (std::uintmax_t x, const bigunsignedint<k>& y)
{
bigunsignedint<k> temp(x);
return temp/y;
}
template <int k>
inline bigunsignedint<k> operator% (std::size_t x, const bigunsignedint<k>& y)
inline bigunsignedint<k> operator% (std::uintmax_t x, const bigunsignedint<k>& y)
{
bigunsignedint<k> temp(x);
return temp%y;
......@@ -554,6 +587,7 @@ namespace std
{
template<int k>
struct numeric_limits<Dune::bigunsignedint<k> >
: private Dune::numeric_limits_helper<Dune::bigunsignedint<k> > // for access to internal state of bigunsignedint
{
public:
static const bool is_specialized = true;
......@@ -567,7 +601,9 @@ namespace std
{
Dune::bigunsignedint<k> max_;
for(std::size_t i=0; i < Dune::bigunsignedint<k>::n; ++i)
max_.digit[i]=std::numeric_limits<unsigned short>::max();
// access internal state via the helper base class
Dune::numeric_limits_helper<Dune::bigunsignedint<k> >::
digit(max_,i)=std::numeric_limits<std::uint16_t>::max();
return max_;
}
......
......@@ -9,6 +9,7 @@
#include <vector>
#include <iostream>
#include <cstring>
#include <cstdint>
#include <cstdlib>
#include <new>
#if HAVE_SYS_MMAN_H && HAVE_MPROTECT
......@@ -143,7 +144,7 @@ namespace Dune
// compute page address
void* page_ptr =
static_cast<void*>(
(char*)(ptr) - ((difference_type)(ptr) % page_size));
(char*)(ptr) - ((std::uintptr_t)(ptr) % page_size));
// search list
AllocationList::iterator it;
unsigned int i = 0;
......
......@@ -42,7 +42,8 @@ namespace Dune {
template<class K>
inline typename FieldTraits<K>::real_type absreal (const K& k)
{
return std::abs(k);
using std::abs;
return abs(k);
}
/**
......@@ -52,7 +53,8 @@ namespace Dune {
template<class K>
inline typename FieldTraits<K>::real_type absreal (const std::complex<K>& c)
{
return std::abs(c.real()) + std::abs(c.imag());
using std::abs;
return abs(c.real()) + abs(c.imag());
}
/**
......@@ -84,7 +86,8 @@ namespace Dune {
{
static inline typename FieldTraits<K>::real_type sqrt (const K& k)
{
return std::sqrt(k);
using std::sqrt;
return sqrt(k);
}
};
......@@ -97,7 +100,8 @@ namespace Dune {
{
static inline typename FieldTraits<K>::real_type sqrt (const K& k)
{
return typename FieldTraits<K>::real_type(std::sqrt(double(k)));
using std::sqrt;
return typename FieldTraits<K>::real_type(sqrt(double(k)));
}
};
......@@ -564,9 +568,10 @@ namespace Dune {
//! one norm (sum over absolute values of entries)
typename FieldTraits<value_type>::real_type one_norm() const {
using std::abs;
typename FieldTraits<value_type>::real_type result( 0 );
for (size_type i=0; i<size(); i++)
result += std::abs((*this)[i]);
result += abs((*this)[i]);
return result;
}
......@@ -601,29 +606,35 @@ namespace Dune {
//! infinity norm (maximum of absolute values of entries)
typename FieldTraits<value_type>::real_type infinity_norm () const
{
using std::abs;
using std::max;
typedef typename FieldTraits<value_type>::real_type real_type;
if (size() == 0)
return 0.0;
ConstIterator it = begin();
typename FieldTraits<value_type>::real_type max = std::abs(*it);
real_type max_val = abs(*it);
for (it = it + 1; it != end(); ++it)
max = std::max(max, std::abs(*it));
max_val = max(max_val, real_type(abs(*it)));
return max;
return max_val;
}
//! simplified infinity norm (uses Manhattan norm for complex values)
typename FieldTraits<value_type>::real_type infinity_norm_real () const
{
using std::max;
if (size() == 0)
return 0.0;
ConstIterator it = begin();
typename FieldTraits<value_type>::real_type max = fvmeta::absreal(*it);
typename FieldTraits<value_type>::real_type max_val = fvmeta::absreal(*it);
for (it = it + 1; it != end(); ++it)
max = std::max(max, fvmeta::absreal(*it));
max_val = max(max_val, fvmeta::absreal(*it));
return max;
return max_val;
}
//===== sizes
......
......@@ -17,6 +17,8 @@
#include "typetraits.hh"
#include "exceptions.hh"
#include "array.hh"
#include "ftraits.hh"
#include "densevector.hh"
#include "unused.hh"
......@@ -226,7 +228,14 @@ namespace Dune {
{}
/** \brief Constructor with a given scalar */
FieldVector (const K& k) : _data(k) {}
template<typename T,
typename EnableIf = typename std::enable_if<
std::is_convertible<T, K>::value &&
! std::is_same<K, DenseVector<typename FieldTraits<T>::field_type>
>::value
>::type
>
FieldVector (const T& k) : _data(k) {}
//! Constructor making vector with identical coordinates
template<class C>
......@@ -243,7 +252,14 @@ namespace Dune {
{}
//! Assignment operator for scalar
inline FieldVector& operator= (const K& k)
template<typename T,
typename EnableIf = typename std::enable_if<
std::is_convertible<T, K>::value &&
! std::is_same<K, DenseVector<typename FieldTraits<T>::field_type>
>::value
>::type
>
inline FieldVector& operator= (const T& k)
{
_data = k;
return *this;
......@@ -274,7 +290,35 @@ namespace Dune {
};
/* ----- FV / FV ----- */
/* not necessary as these operations are already covered via the cast operator */
/* mostly not necessary as these operations are already covered via the cast operator */
//! Binary compare, when using FieldVector<K,1> like K
template<class K>
inline bool operator> (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
{
return a[0]>b[0];
}
//! Binary compare, when using FieldVector<K,1> like K
template<class K>
inline bool operator>= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
{
return a[0]>=b[0];
}
//! Binary compare, when using FieldVector<K,1> like K
template<class K>
inline bool operator< (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
{
return a[0]<b[0];
}
//! Binary compare, when using FieldVector<K,1> like K
template<class K>
inline bool operator<= (const FieldVector<K,1>& a, const FieldVector<K,1>& b)
{
return a[0]<=b[0];
}
/* ----- FV / scalar ----- */
......