Files
opm-core/CMakeLists.txt
Roland Kaufmann 12dfe529ff Don't distinguish between target and project variables
Since the project is only building one main target, the library, and
the other targets are just auxiliaries, then the distinction becomes
confusing and unnecessary.
2013-02-11 23:08:28 +01:00

495 lines
17 KiB
CMake

# -*- mode: cmake; tab-width: 2; indent-tabs-mode: t; truncate-lines: t; compile-command: "cmake -Wdev" -*-
# vim: set filetype=cmake autoindent tabstop=2 shiftwidth=2 noexpandtab softtabstop=2 nowrap:
cmake_minimum_required (VERSION 2.8)
set (opm-core_NAME "opm-core")
project (${opm-core_NAME})
set (opm-core_VERSION_MAJOR 1)
set (opm-core_VERSION_MINOR 0)
enable_language (C)
enable_language (CXX)
set (opm-core_DESCRIPTION "Open Porous Media Initiative Core Library")
# source is located under this directory
set (opm-core_DIR "opm/core")
# build debug by default
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE "Debug")
endif (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
message (STATUS "Build type: ${CMAKE_BUILD_TYPE}")
# all public header files are together with the source
set (opm-core_INCLUDE_DIR "${PROJECT_SOURCE_DIR}")
list (APPEND opm-core_INCLUDE_DIRS "${opm-core_INCLUDE_DIR}")
# additional search modules
set (opm-core_MODULE_DIR "${PROJECT_SOURCE_DIR}/cmake/Modules")
list (APPEND CMAKE_MODULE_PATH ${opm-core_MODULE_DIR})
# very early try to print repo id (to pinpoint version if something goes wrong)
include (UseVCSInfo)
vcs_info ()
# include special
if (CMAKE_VERSION VERSION_LESS "2.8.7")
message (STATUS "Enabling backward compatibility modules for CMake ${CMAKE_VERSION}")
list (APPEND CMAKE_MODULE_PATH "${opm-core_MODULE_DIR}/compat-2.8.7")
endif (CMAKE_VERSION VERSION_LESS "2.8.7")
# don't import more libraries than we need to
include (UseOnlyNeeded)
# use tricks to do faster builds
include (UseFastBuilds)
# precompiled headers
include (UsePrecompHeaders)
# macro to set standard variables (INCLUDE_DIRS, LIBRARIES etc.)
include (OpmFind)
# dependencies
list (APPEND opm-core_DEPS
# compile with C99 support if available
"C99"
# compile with C++0x/11 support if available
"CXX11Features"
# matrix library
"BLAS REQUIRED"
"LAPACK REQUIRED"
# Tim Davis' SuiteSparse archive
"SuiteSparse COMPONENTS umfpack"
# solver
"SUPERLU"
# xml processing (for config parsing)
"TinyXML"
# various runtime library enhancements
"Boost 1.39.0
COMPONENTS date_time filesystem system unit_test_framework REQUIRED"
# DUNE dependency
"dune-istl"
# Ensembles-based Reservoir Tools (ERT)
"ERT"
)
find_and_append_package_list_to (opm-core ${opm-core_DEPS})
# put debug information into every executable
include (UseDebugSymbols)
# optimize full if we're not doing a debug build
include (UseOptimization)
# turn on all warnings
include (UseWarnings)
# detect if Boost is in a shared library
include (UseDynamicBoost)
# needed for Debian installation scheme
include (UseMultiArch)
# put libraries in lib/ (no multi-arch support in build tree)
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
set (CMAKE_Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/CMakeFiles")
# find all the source code (note that these variables have name after
# the target library and not the project). the documentation recommends
# against using globs to enumerate source code, but if you list the
# files explicitly you'll change the build files every time you add to
# the project as well as having to rebuild completely anyway.
file (GLOB_RECURSE opm-core_C_SOURCES "${opm-core_DIR}/[^.]*.c")
file (GLOB_RECURSE opm-core_CXX_SOURCES "${opm-core_DIR}/[^.]*.cpp")
file (GLOB_RECURSE opm-core_C_HEADERS "${opm-core_DIR}/[^.]*.h")
file (GLOB_RECURSE opm-core_CXX_HEADERS "${opm-core_DIR}/[^.]*.hpp")
# remove pre-compile headers from output list
set (opm-core_PRECOMP_CXX_HEADER "${opm-core_DIR}/${opm-core_NAME}-pch.hpp")
list (REMOVE_ITEM opm-core_CXX_HEADERS
${PROJECT_SOURCE_DIR}/${opm-core_PRECOMP_CXX_HEADER}
)
# merge both languages into one compilation/installation
set (opm-core_SOURCES ${opm-core_C_SOURCES} ${opm-core_CXX_SOURCES})
set (opm-core_HEADERS ${opm-core_C_HEADERS} ${opm-core_CXX_HEADERS})
# Algebraic Multigrid must be compiled together with our program;
# if it is not available, then remove our corresponding component
find_package (AGMG)
if (AGMG_FOUND)
list (APPEND opm-core_SOURCES ${AGMG_SOURCES})
endif (AGMG_FOUND)
# these solvers are only compiled in if their dependency is found
if (NOT AGMG_FOUND)
list (REMOVE_ITEM opm-core_SOURCES
${PROJECT_SOURCE_DIR}/${opm-core_DIR}/linalg/LinearSolverAGMG.cpp
)
endif (NOT AGMG_FOUND)
if (NOT dune-istl_FOUND)
list (REMOVE_ITEM opm-core_SOURCES
${PROJECT_SOURCE_DIR}/${opm-core_DIR}/linalg/LinearSolverIstl.cpp
)
endif (NOT dune-istl_FOUND)
if (NOT SuiteSparse_FOUND)
list (REMOVE_ITEM opm-core_SOURCES
${PROJECT_SOURCE_DIR}/${opm-core_DIR}/linalg/call_umfpack.c
${PROJECT_SOURCE_DIR}/${opm-core_DIR}/linalg/LinearSolverUmfpack.cpp
)
endif (NOT SuiteSparse_FOUND)
# these files are provided in source control, but can only compile with Matlab
# available; we are not supposed to include the TinyXML test prog. regardless
list (REMOVE_ITEM opm-core_SOURCES
${PROJECT_SOURCE_DIR}/${opm-core_DIR}/grid/cpgpreprocess/mxgrdecl.c
${PROJECT_SOURCE_DIR}/${opm-core_DIR}/grid/cpgpreprocess/processgrid.c
${PROJECT_SOURCE_DIR}/${opm-core_DIR}/utility/parameters/tinyxml/xmltest.cpp
)
# remove inline TinyXML if a system version was found
if (TinyXML_FOUND)
file (GLOB_RECURSE _inline_tinyxml "${opm-core_DIR}/utility/parameters/tinyxml/*")
foreach (_file IN LISTS _inline_tinyxml)
list (REMOVE_ITEM opm-core_SOURCES ${_file})
endforeach (_file)
endif (TinyXML_FOUND)
# anyhow remove it from the header list (so it doesn't get installed)
list (REMOVE_ITEM opm-core_HEADERS "${opm-core_DIR}/utility/parameters/tinyxml/tinystr.h")
list (REMOVE_ITEM opm-core_HEADERS "${opm-core_DIR}/utility/parameters/tinyxml/tinyxml.h")
# HAVE_ERT is used as an #ifdef, not as an #if in the source code, if it
# is not true, then it should be unset altogether
if (NOT HAVE_ERT)
set (HAVE_ERT)
endif (NOT HAVE_ERT)
# create configuration header which describes available features
# necessary to compile this library. singular version is the names that
# is required by this project alone, plural version transitively
# includes the necessary defines by the dependencies
include (ConfigVars)
set (opm-core_CONFIG_VAR
HAVE_AGMG
HAVE_DUNE_ISTL
HAVE_DYNAMIC_BOOST_TEST
HAVE_ERT
HAVE_SUITESPARSE_UMFPACK_H
HAVE_NULLPTR
HAVE_STATIC_ASSERT
)
list (APPEND opm-core_CONFIG_VARS ${opm-core_CONFIG_VAR})
configure_vars (
FILE CXX "${PROJECT_BINARY_DIR}/config.h"
WRITE ${opm-core_CONFIG_VARS}
)
include (UseFortranWrappers)
define_fc_func (
APPEND "${PROJECT_BINARY_DIR}/config.h"
)
# some CMake properties do not do list expansion
string (REPLACE ";" " " opm-core_LINKER_FLAGS_STR "${opm-core_LINKER_FLAGS}")
# default to building a static library, but let user override
if (DEFINED BUILD_SHARED_LIBS)
set (_shared_def ${BUILD_SHARED_LIBS})
else (DEFINED BUILD_SHARED_LIBS)
set (_shared_def OFF)
endif (DEFINED BUILD_SHARED_LIBS)
option (BUILD_${opm-core_NAME}_SHARED "Build ${opm-core_NAME} as a shared library" ${_shared_def})
if (BUILD_${opm-core_NAME}_SHARED)
set (opm-core_LIBRARY_TYPE SHARED)
else (BUILD_${opm-core_NAME}_SHARED)
set (opm-core_LIBRARY_TYPE STATIC)
endif (BUILD_${opm-core_NAME}_SHARED)
# name of the library should not contain dashes, as CMake will
# define a symbol with that name, and those cannot contain dashes
string (REPLACE "-" "" opm-core_TARGET "${opm-core_NAME}")
# create this library
include_directories (${opm-core_INCLUDE_DIRS})
link_directories (${opm-core_LIBRARY_DIRS})
add_definitions (${opm-core_DEFINITIONS})
add_library (${opm-core_TARGET} ${opm-core_LIBRARY_TYPE} ${opm-core_SOURCES})
set (opm-core_VERSION "${opm-core_VERSION_MAJOR}.${opm-core_VERSION_MINOR}")
set_target_properties (${opm-core_TARGET} PROPERTIES
SOVERSION ${opm-core_VERSION_MAJOR}
VERSION ${opm-core_VERSION}
LINK_FLAGS "${opm-core_LINKER_FLAGS_STR}"
)
target_link_libraries (${opm-core_TARGET} ${opm-core_LIBRARIES})
# queue this executable to be stripped
strip_debug_symbols (${opm-core_TARGET} opm-core_DEBUG)
# pre-compile common headers; this is setup *after* the library to pick
# up extra options set there
option (PRECOMPILE_HEADERS "Precompile common headers for speed." ON)
mark_as_advanced (PRECOMPILE_HEADERS)
if (PRECOMPILE_HEADERS)
get_target_property (_type ${opm-core_TARGET} TYPE)
precompile_header (CXX ${_type}
HEADER "${opm-core_PRECOMP_CXX_HEADER}"
TARGET opm-core_CXX_pch
FLAGS opm-core_PRECOMP_CXX_FLAGS
)
# must set property on source files instead of entire target, because
# it only applies to C++ modules (and cannot be used for C)
set_source_files_properties (${opm-core_CXX_SOURCES} PROPERTIES
OBJECT_DEPENDS "${opm-core_CXX_pch}"
COMPILE_FLAGS "${opm-core_PRECOMP_CXX_FLAGS}"
)
message (STATUS "Precompiled headers: ${opm-core_CXX_pch}")
else (PRECOMPILE_HEADERS)
message (STATUS "Precompiled headers: disabled")
endif (PRECOMPILE_HEADERS)
### installation ###
foreach (_hdr IN LISTS opm-core_HEADERS)
get_filename_component (_dir ${_hdr} PATH)
file (RELATIVE_PATH _rel_dir "${PROJECT_SOURCE_DIR}" "${_dir}")
install (
FILES ${_hdr}
DESTINATION include/${_rel_dir}
)
endforeach (_hdr)
install (
TARGETS ${opm-core_TARGET}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
# only /usr/lib/debug seems to be searched for debug info; if we have
# write access to that directory (package installation), then default
# to use it; otherwise put the debug files together with the library
# (local installation). everything can be overridden by the option.
if (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
set (_sys_dbg_def ON)
else (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
set (_sys_dbg_def OFF)
endif (CMAKE_INSTALL_PREFIX STREQUAL "/usr")
option (SYSTEM_DEBUG "Put .debug files in GDB debug file directory" ${_sys_dbg_def})
set (DEBUG_FILE_DIRECTORY /usr/lib/debug CACHE LOCATION "GDB debug file directory")
mark_as_advanced (DEBUG_FILE_DIRECTORY)
if (SYSTEM_DEBUG)
set (_dbg_prefix "${DEBUG_FILE_DIRECTORY}/")
else (SYSTEM_DEBUG)
set (_dbg_prefix "")
endif (SYSTEM_DEBUG)
# static libraries don't have their debug info stripped, so there is
# only a separate file when we are building shared objects
if (opm-core_LIBRARY_TYPE STREQUAL "SHARED")
install (
FILES ${PROJECT_BINARY_DIR}/${opm-core_DEBUG}
DESTINATION ${_dbg_prefix}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}
)
endif (opm-core_LIBRARY_TYPE STREQUAL "SHARED")
install (
FILES ${PROJECT_SOURCE_DIR}/dune.module
DESTINATION ${CMAKE_INSTALL_LIBDIR_NOARCH}/dunecontrol/${opm-core_NAME}
)
message (STATUS "This build defaults to installing in ${CMAKE_INSTALL_PREFIX}")
# we need to know the name of the library which is generated
get_target_property (opm-core_LIBRARY ${opm-core_TARGET} LOCATION)
# installation of CMake modules to help user programs locate the library
include (OpmProject)
opm_cmake_config (opm-core)
### tutorials ###
# enumerate tutorials in project
file (GLOB tutorial_SOURCES "tutorials/tutorial[0-9].cpp")
# add each tutorial as a target of its own
add_custom_target (tutorials)
foreach (tutorial_FILE IN LISTS tutorial_SOURCES)
# get the name of the executable based on the source code file
get_filename_component (tutorial_NAME "${tutorial_FILE}" NAME_WE)
# setup an executable, linking to the main library
add_executable (${tutorial_NAME} EXCLUDE_FROM_ALL ${tutorial_FILE})
set_target_properties (${tutorial_NAME} PROPERTIES
LINK_FLAGS "${opm-core_LINKER_FLAGS_STR}"
)
target_link_libraries (${tutorial_NAME} ${opm-core_TARGET} ${opm-core_LIBRARIES})
strip_debug_symbols (${tutorial_NAME})
# add to list of tutorials to build
add_dependencies (tutorials ${tutorial_NAME})
endforeach (tutorial_FILE)
### test programs ###
enable_testing ()
include (CTest)
# enumerate all testing programs
file (GLOB_RECURSE tests_SOURCES "tests/test_*.cpp")
file (GLOB_RECURSE not_tests_SOURCES "tests/not-unit/test_*.cpp")
list (REMOVE_ITEM tests_SOURCES ${not_tests_SOURCES})
# conditionally disable tests when features aren't available
macro (cond_disable_test name)
if ((NOT DEFINED HAVE_${name}) OR (NOT HAVE_${name}))
message (STATUS "${name} test disabled, since ${name} is not found.")
string (TOLOWER "${name}" name_lower)
get_filename_component (test_${name}_FILE "tests/test_${name_lower}.cpp" ABSOLUTE)
list (REMOVE_ITEM tests_SOURCES "${test_${name}_FILE}")
endif ((NOT DEFINED HAVE_${name}) OR (NOT HAVE_${name}))
endmacro (cond_disable_test name)
cond_disable_test ("AGMG")
cond_disable_test ("ERT")
# if ever huge test datafiles are necessary, then change this
# into "create_symlink" (on UNIX only, apparently)
set (make_avail "copy")
# provide datafiles as inputs for the tests, by copying them
# to a tests/ directory in the output tree (if different)
set (test_INPUT_FILES)
file (GLOB test_DATA "tests/*.xml")
foreach (input_datafile IN LISTS test_DATA)
file (RELATIVE_PATH rel_datafile "${PROJECT_SOURCE_DIR}" ${input_datafile})
set (output_datafile "${PROJECT_BINARY_DIR}/${rel_datafile}")
if (NOT output_datafile STREQUAL input_datafile)
add_custom_command (
OUTPUT ${output_datafile}
COMMAND ${CMAKE_COMMAND}
ARGS -E ${make_avail} ${input_datafile} ${output_datafile}
DEPENDS ${input_datafile}
VERBATIM
)
endif (NOT output_datafile STREQUAL input_datafile)
list (APPEND test_INPUT_FILES "${output_datafile}")
endforeach (input_datafile)
add_custom_target (datafiles
DEPENDS ${test_INPUT_FILES}
COMMENT "Making test data available in output tree"
)
# compile each of these separately
add_custom_target (tests DEPENDS datafiles)
foreach (test_FILE IN LISTS tests_SOURCES)
get_filename_component (test_NAME "${test_FILE}" NAME_WE)
add_executable (${test_NAME} EXCLUDE_FROM_ALL ${test_FILE})
add_dependencies (tests ${test_NAME})
set_target_properties (${test_NAME} PROPERTIES
LINK_FLAGS "${opm-core_LINKER_FLAGS_STR}"
)
target_link_libraries (${test_NAME} ${opm-core_TARGET} ${opm-core_LIBRARIES})
strip_debug_symbols (${test_NAME})
string (REGEX REPLACE "^test_([^/]*)$" "\\1" test_FANCY "${test_NAME}")
get_target_property (test_LOC ${test_NAME} LOCATION)
add_test (${test_FANCY} ${test_LOC})
# run the test in the directory where the data files are
set_tests_properties (${test_FANCY} PROPERTIES
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/tests
)
endforeach (test_FILE)
# ideally this should run the tests, but for now we only test if they
# compile without errors
add_custom_target (check
COMMAND ${CMAKE_CTEST_COMMAND}
DEPENDS tests
COMMENT Checking if library is functional
VERBATIM
)
### documentation ###
set (docu_dir "Documentation")
configure_file (
${PROJECT_SOURCE_DIR}/Doxyfile.in
${PROJECT_BINARY_DIR}/Doxyfile
@ONLY
)
find_package (Doxygen)
if (DOXYGEN_FOUND)
add_custom_target (doc
COMMAND ${DOXYGEN_EXECUTABLE} ${PROJECT_BINARY_DIR}/Doxyfile
SOURCES ${PROJECT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${docu_dir}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)
set (_formats html)
foreach (format IN LISTS _formats)
string (TOUPPER ${format} FORMAT)
install (
DIRECTORY ${PROJECT_BINARY_DIR}/${docu_dir}/${format}
DESTINATION share/doc/${opm-core_NAME}/
COMPONENT ${format}
OPTIONAL
)
# target to install just HTML documentation
add_custom_target (install-${format}
COMMAND ${CMAKE_COMMAND} -DCOMPONENT=${format} -P cmake_install.cmake
COMMENT Installing ${FORMAT} documentation
VERBATIM
)
# since the documentation is optional, it is not automatically built
add_dependencies (install-${format} doc)
endforeach (format)
endif (DOXYGEN_FOUND)
# stylesheets must be specified with relative path in Doxyfile, or the
# full path (to the source directory!) will be put in the output HTML.
# thus, we'll need to copy the stylesheet to this path relative to where
# Doxygen will be run (in the output tree)
if (NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
file (COPY ${PROJECT_SOURCE_DIR}/${docu_dir}/style.css
DESTINATION ${PROJECT_BINARY_DIR}/${docu_dir}
)
set (opm-core_STYLESHEET_COPIED "${docu_dir}/style.css")
else (NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
set (opm-core_STYLESHEET_COPIED "")
endif (NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR)
# provide compatibility with using this build in dunecontrol
include (DuneCompat)
include (LibtoolArchives)
configure_la (opm-core ${opm-core_TARGET} opm-core_LIBTOOL_ARCHIVE)
message (STATUS "Writing libtool archive ${opm-core_LIBTOOL_ARCHIVE}")
### clean in-source builds ###
set (DISTCLEAN_FILES
CMakeCache.txt
cmake_install.cmake
Makefile
config.h
${opm-core_NAME}-config.cmake
${opm-core_NAME}-config-version.cmake
${opm-core_NAME}-install.cmake
${opm-core_NAME}.pc
${opm-core_NAME}-install.pc
Doxyfile
CTestTestfile.cmake
DartConfiguration.tcl
GNUmakefile
lib/${opm-core_LIBTOOL_ARCHIVE}
${opm-core_DEBUG}
install_manifest.txt
${opm-core_STYLESHEET_COPIED}
)
add_custom_target (distclean
COMMAND ${CMAKE_COMMAND} -E remove -f ${DISTCLEAN_FILES}
COMMAND ${CMAKE_COMMAND} -E remove_directory CMakeFiles/
COMMAND ${CMAKE_COMMAND} -E remove_directory Testing/
# cannot depend on clean because it is only defined in the master Makefile
# not in CMakeFiles/Makefile where this target will end up
# DEPENDS clean
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMENT Removing CMake-generated files
VERBATIM
)
# smart wrapper that auto-parallelizes builds
file (COPY
GNUmakefile
DESTINATION ${PROJECT_BINARY_DIR}
)