You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
968 lines
32 KiB
968 lines
32 KiB
# @HEADER
|
|
# ************************************************************************
|
|
#
|
|
# TriBITS: Tribal Build, Integrate, and Test System
|
|
# Copyright 2013 Sandia Corporation
|
|
#
|
|
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
|
# the U.S. Government retains certain rights in this software.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met:
|
|
#
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
#
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# 3. Neither the name of the Corporation nor the names of the
|
|
# contributors may be used to endorse or promote products derived from
|
|
# this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
|
|
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
|
|
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
# ************************************************************************
|
|
# @HEADER
|
|
|
|
include(TribitsPackageSetupCompilerFlags)
|
|
include(TribitsInternalPackageWriteConfigFile)
|
|
include(TribitsGeneralMacros)
|
|
include(TribitsLibIsTestOnly)
|
|
|
|
include(CMakeParseArguments)
|
|
include(GlobalNullSet)
|
|
include(AppendGlobalSet)
|
|
include(PrintVar)
|
|
include(PrependSet)
|
|
include(PrependGlobalSet)
|
|
include(RemoveGlobalDuplicates)
|
|
include(TribitsGatherBuildTargets)
|
|
|
|
include(TribitsAddOptionAndDefine)
|
|
include(TribitsPkgExportCacheVars)
|
|
include(TribitsLibraryMacros)
|
|
include(TribitsAddExecutable)
|
|
include(TribitsAddExecutableAndTest)
|
|
include(TribitsAddTest)
|
|
include(TribitsAddAdvancedTest)
|
|
include(TribitsCopyFilesToBinaryDir)
|
|
include(TribitsReportInvalidTribitsUsage)
|
|
|
|
|
|
#
|
|
# Utility macros
|
|
#
|
|
|
|
|
|
# Macro that defines the package architecture system variables used to link
|
|
# different packages together
|
|
#
|
|
# See README.DEPENDENCIES for information on what these variables mean and how
|
|
# they are used.
|
|
#
|
|
macro(tribits_define_linkage_vars PACKAGE_NAME_IN)
|
|
global_null_set(${PACKAGE_NAME_IN}_LIBRARIES "")
|
|
global_set(${PACKAGE_NAME_IN}_HAS_NATIVE_LIBRARIES_TO_INSTALL FALSE)
|
|
endmacro()
|
|
|
|
|
|
# Macro that defines variables that create global targets
|
|
#
|
|
macro(tribits_define_target_vars PARENT_PACKAGE_NAME_IN)
|
|
global_null_set(${PARENT_PACKAGE_NAME_IN}_LIB_TARGETS)
|
|
global_null_set(${PARENT_PACKAGE_NAME_IN}_ALL_TARGETS)
|
|
endmacro()
|
|
|
|
|
|
# Set up some common variables used in the creation of an package
|
|
#
|
|
macro(tribits_set_common_vars PACKAGE_NAME_IN)
|
|
|
|
string(TOUPPER ${PACKAGE_NAME_IN} PACKAGE_NAME_UC)
|
|
|
|
# Write TRIBITS_PACKAGE versions of common variables
|
|
set(PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
set(PACKAGE_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
|
|
|
# Get the name of the directory this ${PROJECT_NAME} package is in
|
|
file(TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR} STANDARD_PACKAGE_SOURCE_DIR)
|
|
string(REGEX REPLACE "/.+/(.+)" "\\1" PACKAGE_DIR_NAME "${STANDARD_PACKAGE_SOURCE_DIR}")
|
|
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_package_decl()
|
|
#
|
|
# Macro called at the very beginning of a package's top-level
|
|
# `<packageDir>/CMakeLists.txt`_ file when a package has subpackages.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_package_decl(
|
|
# <packageName>
|
|
# [ENABLE_SHADOWING_WARNINGS]
|
|
# [DISABLE_STRONG_WARNINGS]
|
|
# [CLEANED]
|
|
# [DISABLE_CIRCULAR_REF_DETECTION_FAILURE]
|
|
# )
|
|
#
|
|
# The arguments are:
|
|
#
|
|
# ``<packageName>``
|
|
#
|
|
# Gives the name of the Package, mostly just for checking and
|
|
# documentation purposes. This must match the name of the package
|
|
# provided in the `<repoDir>/PackagesList.cmake`_ or an error is issued.
|
|
#
|
|
# ``ENABLE_SHADOWING_WARNINGS``
|
|
#
|
|
# If specified, then shadowing warnings for the package's sources will be
|
|
# turned on for supported platforms/compilers. The default is for
|
|
# shadowing warnings to be turned off. Note that this can be overridden
|
|
# globally by setting the cache variable
|
|
# ``${PROJECT_NAME}_ENABLE_SHADOWING_WARNINGS``.
|
|
#
|
|
# ``DISABLE_STRONG_WARNINGS``
|
|
#
|
|
# If specified, then all strong warnings for the package's sources will be
|
|
# turned off, if they are not already turned off by global cache
|
|
# variables. Strong warnings are turned on by default in development
|
|
# mode.
|
|
#
|
|
# ``CLEANED``
|
|
#
|
|
# If specified, then warnings will be promoted to errors for compiling the
|
|
# package's sources for all defined warnings.
|
|
#
|
|
# ``DISABLE_CIRCULAR_REF_DETECTION_FAILURE``
|
|
#
|
|
# If specified, then the standard grep looking for RCPNode circular
|
|
# references in `tribits_add_test()`_ and `tribits_add_advanced_test()`_
|
|
# that causes tests to fail will be disabled. Note that if these warnings
|
|
# are being produced then it means that the test is leaking memory and
|
|
# user like may also be leaking memory.
|
|
#
|
|
# There are several side-effects of calling this macro:
|
|
#
|
|
# * The variables ``${PACKAGE_NAME}_LIB_TARGETS`` (lists all of the package's
|
|
# targets) and ``${PACKAGE_NAME}_ALL_TARGETS`` (lists all of the package's
|
|
# libraries) and are initialized to empty.
|
|
#
|
|
# * The local variables ``PACKAGE_SOURCE_DIR`` and ``PACKAGE_BINARY_DIR`` are
|
|
# set for this package's use in its CMakeLists.txt files.
|
|
#
|
|
# * Package-specific compiler options are set up in package-scope (i.e., the
|
|
# package's subdirs) in ``CMAKE_<LANG>_FLAG``.
|
|
#
|
|
# * This packages's cmake subdir ``${PACKAGE_SOURCE_DIR}/cmake`` is added to
|
|
# ``CMAKE_MODULE_PATH`` locally so that the package's try-compile modules
|
|
# can be read in with just a raw ``include()`` leaving off the full path and
|
|
# the ``*.cmake`` extension.
|
|
#
|
|
# If the package does not have subpackages, just call `tribits_package()`_
|
|
# which calls this macro.
|
|
#
|
|
macro(tribits_package_decl PACKAGE_NAME_IN)
|
|
|
|
if (${PROJECT_NAME}_VERBOSE_CONFIGURE)
|
|
message("\nTRIBITS_PACKAGE_DECL: ${PACKAGE_NAME_IN}")
|
|
endif()
|
|
|
|
tribits_package_decl_assert_call_context()
|
|
|
|
#
|
|
# A) Parse the input arguments
|
|
#
|
|
|
|
cmake_parse_arguments(
|
|
#prefix
|
|
PARSE
|
|
#options
|
|
"CLEANED;ENABLE_SHADOWING_WARNINGS;DISABLE_STRONG_WARNINGS;DISABLE_CIRCULAR_REF_DETECTION_FAILURE"
|
|
#one_value_keywords
|
|
""
|
|
#multi_value_keywords
|
|
""
|
|
${ARGN}
|
|
)
|
|
|
|
tribits_check_for_unparsed_arguments()
|
|
|
|
#
|
|
# B) Assert that the global and local package names are the same!
|
|
#
|
|
|
|
if (DEFINED PACKAGE_NAME)
|
|
if (NOT ${PACKAGE_NAME_IN} STREQUAL ${PACKAGE_NAME})
|
|
message(FATAL_ERROR "Error, the package-defined package name"
|
|
" '${PACKAGE_NAME_IN}' is not the same as the package name"
|
|
" defined at the global level '${PACKAGE_NAME}'")
|
|
endif()
|
|
endif()
|
|
|
|
#
|
|
# C) Set up the CMake support for this ${PROJECT_NAME} package and define some
|
|
# top-level variables.
|
|
#
|
|
|
|
tribits_set_common_vars(${PACKAGE_NAME_IN})
|
|
tribits_pkg_init_exported_vars(${PACKAGE_NAME_IN})
|
|
|
|
set(${PACKAGE_NAME_IN}_DISABLE_STRONG_WARNINGS OFF
|
|
CACHE BOOL
|
|
"If set to true, then strong warnings for package ${PACKAGE_NAME_IN} will be disabled."
|
|
)
|
|
|
|
# Set up the compile flags for the package
|
|
tribits_setup_compiler_flags(${PACKAGE_NAME_IN})
|
|
|
|
# Set up circular reference detection test failure
|
|
if (PARSE_DISABLE_CIRCULAR_REF_DETECTION_FAILURE)
|
|
set(${PACKAGE_NAME}_ENABLE_CIRCULAR_REF_DETECTION_FAILURE OFF)
|
|
else()
|
|
set(${PACKAGE_NAME}_ENABLE_CIRCULAR_REF_DETECTION_FAILURE ON)
|
|
endif()
|
|
|
|
# Set up parent package linkage variables
|
|
tribits_define_target_vars(${PACKAGE_NAME})
|
|
|
|
# Define this as a CMake/CTest "Subproject"
|
|
set_directory_properties(PROPERTIES LABELS "${PACKAGE_NAME}")
|
|
|
|
#
|
|
# Append the local package's cmake directory in order to help pull in
|
|
# configure-time testing macros
|
|
#
|
|
|
|
prepend_set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
|
|
|
endmacro()
|
|
|
|
|
|
macro(tribits_package_decl_assert_call_context)
|
|
|
|
if (CURRENTLY_PROCESSING_SUBPACKAGE)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Cannot call tribits_package_decl() in a subpackage."
|
|
" Use tribits_subpackage() instead"
|
|
" error in ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
if(${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"tribits_package_decl() called more than once in Package ${PACKAGE_NAME}"
|
|
" This may be because tribits_package_decl() was explicitly called more than once or"
|
|
" TRIBITS_PACKAGE_DECL was called after TRIBITS_PACKAGE. You do not need both."
|
|
" If your package has subpackages then do not call tribits_package() instead call:"
|
|
" tribits_pacakge_decl() then tribits_process_subpackages() then tribits package_def()"
|
|
)
|
|
endif()
|
|
|
|
# Set flag to check that macros are called in the correct order
|
|
set(${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED TRUE)
|
|
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_package_def()
|
|
#
|
|
# Macro called in `<packageDir>/CMakeLists.txt`_ after subpackages are
|
|
# processed in order to handle the libraries, tests, and examples of the
|
|
# parent package.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_package_def()
|
|
#
|
|
# If the package does not have subpackages, just call `tribits_package()`_
|
|
# which calls this macro.
|
|
#
|
|
# This macro has several side effects:
|
|
#
|
|
# * The variable ``PACKAGE_NAME`` is set in the local scope for usage by the
|
|
# package's ``CMakeLists.txt`` files.
|
|
#
|
|
# * The intra-package dependency variables (i.e. list of include directories,
|
|
# list of libraries, etc.) are initialized to empty.
|
|
#
|
|
macro(tribits_package_def)
|
|
|
|
if (${PROJECT_NAME}_VERBOSE_CONFIGURE)
|
|
message("\nTRIBITS_PACKAGE_DEF: ${PACKAGE_NAME}")
|
|
endif()
|
|
|
|
tribits_package_def_assert_call_context()
|
|
|
|
if (NOT ${PROJECT_NAME}_ENABLE_${PACKAGE_NAME})
|
|
if (${PROJECT_NAME}_VERBOSE_CONFIGURE)
|
|
message("\n${PACKAGE_NAME} not enabled so exiting package processing")
|
|
endif()
|
|
return()
|
|
endif()
|
|
|
|
# Reset in case were changed by subpackages
|
|
tribits_set_common_vars(${PACKAGE_NAME})
|
|
|
|
# Define package linkage variables
|
|
tribits_define_linkage_vars(${PACKAGE_NAME})
|
|
|
|
endmacro()
|
|
|
|
|
|
macro(tribits_package_def_assert_call_context)
|
|
|
|
# check that this is not being called from a subpackage
|
|
if(NOT ${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED)
|
|
if (CURRENTLY_PROCESSING_SUBPACKAGE)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Cannot call tribits_package_def() in a subpackage."
|
|
" Use tribits_subpackage() instead"
|
|
" error in ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
endif()
|
|
|
|
# Reset since it was changed by the subpackages
|
|
set(PACKAGE_NAME ${PARENT_PACKAGE_NAME})
|
|
|
|
# check that this is not called morethan once in a package
|
|
if (${PACKAGE_NAME}_TRIBITS_PACKAGE_DEF_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"tribits_package_def() was called more than once in"
|
|
"${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
set(${PACKAGE_NAME}_TRIBITS_PACKAGE_DEF_CALLED TRUE)
|
|
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_package()
|
|
#
|
|
# Macro called at the very beginning of a package's top-level
|
|
# `<packageDir>/CMakeLists.txt`_ file.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_package(
|
|
# <packageName>
|
|
# [ENABLE_SHADOWING_WARNINGS]
|
|
# [DISABLE_STRONG_WARNINGS]
|
|
# [CLEANED]
|
|
# [DISABLE_CIRCULAR_REF_DETECTION_FAILURE]
|
|
# )
|
|
#
|
|
# See `tribits_package_decl()`_ for the documentation for the arguments and
|
|
# `tribits_package_decl()`_ and `tribits_package()`_ for a description the
|
|
# side-effects (and variables set) after calling this macro.
|
|
#
|
|
macro(tribits_package PACKAGE_NAME_IN)
|
|
tribits_package_assert_call_context()
|
|
tribits_package_decl(${PACKAGE_NAME_IN} ${ARGN})
|
|
tribits_package_def()
|
|
endmacro()
|
|
|
|
|
|
macro(tribits_package_assert_call_context)
|
|
|
|
if (CURRENTLY_PROCESSING_SUBPACKAGE)
|
|
if (NOT ${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Cannot call tribits_package() in a subpackage."
|
|
" Use tribits_subpackage() instead"
|
|
" error in ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
endif()
|
|
|
|
if(${PACKAGE_NAME}_SUBPACKAGES)
|
|
tribits_report_invalid_tribits_usage(
|
|
"This package has subpackages so you cannot use tribits_package()"
|
|
"\n Instead use the following call order:"
|
|
"\n tribits_project_decl(${PACKAGE_NAME})"
|
|
"\n tribits_process_subpackages()"
|
|
"\n [do other things you want to do]"
|
|
"\n tribits_package_def()"
|
|
"\n tribits_package_postprocess()" )
|
|
endif()
|
|
|
|
if(${PACKAGE_NAME}_TRIBITS_PACKAGE_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Package ${PACKAGE_NAME} declared more than once!")
|
|
endif()
|
|
|
|
set(${PACKAGE_NAME}_TRIBITS_PACKAGE_CALLED TRUE)
|
|
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_disable_optional_dependency()
|
|
#
|
|
# Macro called to disable an optional dependency in the current package for an
|
|
# optional (internal or external) upstream package.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_disable_optional_dependency(<upstreamPackageName> "<reasonStr>")
|
|
#
|
|
# This macro can be called from a top-level package's
|
|
# ``<packageDir>/CMakeLists.txt`` file to disable an optional dependency that
|
|
# may have been enabled by the user or through automated enable/disable logic.
|
|
#
|
|
# This is most useful in cases where multiple criteria must be considered
|
|
# before support for some upstream dependency can really be supported. In
|
|
# that case, the dependency can be disabled in the current package and
|
|
# telegraphed to all downstream packages. See `How to tweak downstream
|
|
# TriBITS "ENABLE" variables during package configuration`_ for more details.
|
|
#
|
|
macro(tribits_disable_optional_dependency upstreamPackageName reasonStr)
|
|
# Assert called in the correct context
|
|
if (NOT "${${PACKAGE_NAME}_PARENT_PACKAGE}" STREQUAL "")
|
|
message(FATAL_ERROR "ERROR: Calling tribits_disable_optional_dependency() from"
|
|
" a subpackage it not allowed. It must be called from the parent package's"
|
|
" ${${PACKAGE_NAME}_PARENT_PACKAGE} CMakeLists.txt file")
|
|
endif()
|
|
if (NOT "${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${${PACKAGE_NAME}_SOURCE_DIR}")
|
|
message(FATAL_ERROR "ERROR: Calling tribits_disable_optional_dependency() from"
|
|
" a subdirectory CMakeLists.txt file under '${CMAKE_CURRENT_SOURCE_DIR}' is not allowed."
|
|
" Instead, please call this from the package's base CMakeLists.txt file"
|
|
" '${${PACKAGE_NAME}_SOURCE_DIR}/CMakeLists.txt'" )
|
|
endif()
|
|
# Get the variable names that are going to be set assert they exist already
|
|
set(packageEnableVarName ${PACKAGE_NAME}_ENABLE_${upstreamPackageName})
|
|
assert_defined(${packageEnableVarName})
|
|
string(TOUPPER ${upstreamPackageName} upstreamPackageName_UC)
|
|
set(havePackageUpstreamPackageMacroVarName
|
|
HAVE_${PACKAGE_NAME_UC}_${upstreamPackageName_UC})
|
|
assert_defined(${havePackageUpstreamPackageMacroVarName})
|
|
# Set the variables to OFF in local and project-level scopes
|
|
if (NOT "${reasonStr}" STREQUAL "")
|
|
message("-- ${reasonStr}")
|
|
endif()
|
|
dual_scope_set(${packageEnableVarName} OFF)
|
|
dual_scope_set(${havePackageUpstreamPackageMacroVarName} OFF)
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_add_test_directories()
|
|
#
|
|
# Macro called to add a set of test directories for an package.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_add_test_directories(<dir1> <dir2> ...)
|
|
#
|
|
# This macro only needs to be called from the top most ``CMakeLists.txt`` file
|
|
# for which all subdirectories are all "tests".
|
|
#
|
|
# This macro can be called several times within a package and it will have the
|
|
# right effect.
|
|
#
|
|
# Currently, all this macro does macro is to call ``add_subdirectory(<diri>)``
|
|
# if ``${PACKAGE_NAME}_ENABLE_TESTS`` is ``TRUE``.
|
|
#
|
|
macro(tribits_add_test_directories)
|
|
|
|
tribits_add_test_example_directories_assert_call_context(
|
|
tribits_add_test_directories)
|
|
|
|
if(${PACKAGE_NAME}_ENABLE_TESTS)
|
|
foreach(TEST_DIR ${ARGN})
|
|
tribits_trace_file_processing(PACKAGE ADD_SUBDIR
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/${TEST_DIR}/CMakeLists.txt")
|
|
add_subdirectory(${TEST_DIR})
|
|
endforeach()
|
|
endif()
|
|
|
|
endmacro()
|
|
|
|
|
|
#
|
|
# Macros to add common options to add to an package
|
|
#
|
|
|
|
|
|
# @MACRO: tribits_add_debug_option()
|
|
#
|
|
# Add the standard cache variable option ``${PACKAGE_NAME}_ENABLE_DEBUG`` for
|
|
# the package.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_add_debug_option()
|
|
#
|
|
# This option is given the default value ``${${PROJECT_NAME}_ENABLE_DEBUG}``,
|
|
# and if true, this macro will set the variable
|
|
# ``HAVE_${PACKAGE_NAME_UC}_DEBUG`` (to be used in the package's configured
|
|
# header file `<packageDir>/cmake/<packageName>_config.h.in`_). This macro is
|
|
# typically called in the package's `<packageDir>/CMakeLists.txt`_ file (see
|
|
# the example ``SimpleCxx/CMakeLists.txt``).
|
|
#
|
|
# NOTE: This also calls `tribits_pkg_export_cache_var()`_ to export the
|
|
# variable ``${PACKAGE_NAME}_ENABLE_DEBUG``.
|
|
#
|
|
macro(tribits_add_debug_option)
|
|
tribits_add_option_and_define(
|
|
${PACKAGE_NAME}_ENABLE_DEBUG
|
|
HAVE_${PACKAGE_NAME_UC}_DEBUG
|
|
"Enable a host of runtime debug checking."
|
|
${${PROJECT_NAME}_ENABLE_DEBUG}
|
|
)
|
|
endmacro()
|
|
|
|
|
|
macro(tribits_add_enable_teuchos_time_monitor_option)
|
|
option(
|
|
${PACKAGE_NAME}_ENABLE_TEUCHOS_TIME_MONITOR
|
|
"Enable Teuchos time monitors for package ${PACKAGE_NAME}"
|
|
${${PROJECT_NAME}_ENABLE_TEUCHOS_TIME_MONITOR}
|
|
)
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_add_show_deprecated_warnings_option()
|
|
#
|
|
# Add the standard option ``${PACKAGE_NAME}_SHOW_DEPRECATED_WARNINGS`` for the
|
|
# package.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_add_show_deprecated_warnings_option()
|
|
#
|
|
# This macro should be called in the package's <packageDir>/CMakeLists.txt`_
|
|
# file. This option is given the default value
|
|
# ``${${PROJECT_NAME}_SHOW_DEPRECATED_WARNINGS}``. This option is then looked
|
|
# for in `tribits_configure_file()`_ to add macros to add deprecated warnings
|
|
# to deprecated parts of a package.
|
|
#
|
|
macro(tribits_add_show_deprecated_warnings_option)
|
|
advanced_set(
|
|
${PACKAGE_NAME}_SHOW_DEPRECATED_WARNINGS ${${PROJECT_NAME}_SHOW_DEPRECATED_WARNINGS}
|
|
CACHE BOOL
|
|
"Show warnings about deprecated code in ${PACKAGE_NAME}"
|
|
)
|
|
advanced_set(
|
|
${PACKAGE_NAME}_HIDE_DEPRECATED_CODE ${${PROJECT_NAME}_HIDE_DEPRECATED_CODE}
|
|
CACHE BOOL
|
|
"Fully exclude deprecated code in ${PACKAGE_NAME}"
|
|
)
|
|
endmacro()
|
|
|
|
|
|
macro(tribits_add_explicit_instantiation_option)
|
|
tribits_add_option_and_define(
|
|
${PACKAGE_NAME}_ENABLE_EXPLICIT_INSTANTIATION
|
|
HAVE_${PACKAGE_NAME_UC}_EXPLICIT_INSTANTIATION
|
|
"Enable the use of explicit template instantiation."
|
|
${${PROJECT_NAME}_ENABLE_EXPLICIT_INSTANTIATION}
|
|
)
|
|
endmacro()
|
|
|
|
|
|
macro(tribits_add_eti_support)
|
|
append_global_set(${PROJECT_NAME}_ETI_PACKAGES ${PACKAGE_NAME})
|
|
global_null_set(${PACKAGE_NAME}_ETI_LIBRARYSET)
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_add_example_directories()
|
|
#
|
|
# Macro called to conditionally add a set of example directories for an
|
|
# package.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_add_example_directories(<dir1> <dir2> ...)
|
|
#
|
|
# This macro typically is called from the top-level
|
|
# `<packageDir>/CMakeLists.txt`_ file for which all subdirectories are all
|
|
# "examples" according to standard package layout.
|
|
#
|
|
# This macro can be called several times within a package as desired to break
|
|
# up example directories any way one would like.
|
|
#
|
|
# Currently, all it does macro does is to call ``add_subdirectory(<diri>)`` if
|
|
# `${PACKAGE_NAME}_ENABLE_EXAMPLES`_ ``= TRUE``.
|
|
#
|
|
macro(tribits_add_example_directories)
|
|
|
|
tribits_add_test_example_directories_assert_call_context(
|
|
tribits_add_example_directories)
|
|
|
|
if(${PACKAGE_NAME}_ENABLE_EXAMPLES)
|
|
foreach(EXAMPLE_DIR ${ARGN})
|
|
tribits_trace_file_processing(PACKAGE ADD_SUBDIR
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/${EXAMPLE_DIR}/CMakeLists.txt")
|
|
add_subdirectory(${EXAMPLE_DIR})
|
|
endforeach()
|
|
endif()
|
|
|
|
endmacro()
|
|
|
|
|
|
macro(tribits_add_test_example_directories_assert_call_context macroName)
|
|
|
|
if (CURRENTLY_PROCESSING_SUBPACKAGE)
|
|
|
|
# This is a subpackage being processed
|
|
|
|
if(NOT ${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_subpackage() before ${macroName}()"
|
|
" in ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
if(${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call ${macroName}() before"
|
|
" tribits_subpackage_postprocess() in"
|
|
" ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
else()
|
|
|
|
# This is a package being processed
|
|
|
|
if(NOT ${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_package() or tribits_package_decl() before"
|
|
" ${macroName}() in ${TRIBITS_PACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
if(${PACKAGE_NAME}_TRIBITS_PACKAGE_POSTPROCESS_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call ${macroName}() before "
|
|
" tribits_package_postprocess() in ${TRIBITS_PACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
endif()
|
|
|
|
endmacro()
|
|
|
|
|
|
# Utility function that sets up package linkage linkage variables in case the
|
|
# package has no libraries.
|
|
#
|
|
function(tribits_package_finalize_dependency_vars)
|
|
|
|
if(${PACKAGE_NAME}_SUBPACKAGES)
|
|
|
|
# A package with subpackages should get all of its dependency vars from
|
|
# its enabled subpackages.
|
|
|
|
set(PARENT_PACKAGE_LIBRARIES "")
|
|
|
|
set(SUBPACKAGE_IDX 0)
|
|
foreach(TRIBITS_SUBPACKAGE ${${PARENT_PACKAGE_NAME}_SUBPACKAGES})
|
|
|
|
set(SUBPACKAGE_NAME ${TRIBITS_SUBPACKAGE})
|
|
set(SUBPACKAGE_FULLNAME ${PARENT_PACKAGE_NAME}${TRIBITS_SUBPACKAGE})
|
|
|
|
if (${PROJECT_NAME}_ENABLE_${SUBPACKAGE_FULLNAME})
|
|
prepend_set(PARENT_PACKAGE_LIBRARIES
|
|
${${SUBPACKAGE_FULLNAME}_LIBRARIES})
|
|
endif()
|
|
|
|
math(EXPR SUBPACKAGE_IDX "${SUBPACKAGE_IDX}+1")
|
|
|
|
endforeach()
|
|
|
|
# NOTE: There can't be any duplicate libraries in PARENT_PACKAGE_LIBRARIES
|
|
# so no need to remove them.
|
|
global_set(${PACKAGE_NAME}_LIBRARIES "${PARENT_PACKAGE_LIBRARIES}")
|
|
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
|
|
# Helper macro for [SUB]tribits_package_postprocess()
|
|
#
|
|
macro(tribits_package_postprocess_common)
|
|
|
|
if (${PROJECT_NAME}_VERBOSE_CONFIGURE)
|
|
message("\nTRIBITS_PACKAGE_POSTPROCESS_COMMON: ${PACKAGE_NAME}")
|
|
print_var(${PACKAGE_NAME}_LIBRARIES)
|
|
endif()
|
|
|
|
tribits_package_create_all_libs_interface_library()
|
|
|
|
if (${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES)
|
|
# Create the configure file so external projects can find packages with a
|
|
# call to find_package(<package_name>).
|
|
tribits_write_package_client_export_files(${PACKAGE_NAME})
|
|
endif()
|
|
|
|
set(${PACKAGE_NAME}_FINISHED_FIRST_CONFIGURE TRUE
|
|
CACHE INTERNAL "")
|
|
|
|
endmacro()
|
|
|
|
|
|
# Macro to create the ${PACKAGE_NAME}::all_libs INTERFACE target
|
|
#
|
|
macro(tribits_package_create_all_libs_interface_library)
|
|
|
|
if (NOT TARGET ${PACKAGE_NAME}_all_libs)
|
|
|
|
# Find all of the non-TESTONLY library targets
|
|
tribits_get_all_build_targets_including_in_subdirs("${CMAKE_CURRENT_SOURCE_DIR}"
|
|
"STATIC_LIBRARY;SHARED_LIBRARY"
|
|
allPackageBuildableLibTargetsList )
|
|
#print_var(allPackageBuildableLibTargetsList)
|
|
set(packageLibsInAllLibsList)
|
|
foreach (libTarget IN LISTS allPackageBuildableLibTargetsList)
|
|
tribits_lib_is_testonly(${libTarget} isTestOnlyLib)
|
|
#print_var(isTestOnlyLib)
|
|
if (NOT isTestOnlyLib)
|
|
list(APPEND packageLibsInAllLibsList ${libTarget})
|
|
endif()
|
|
endforeach()
|
|
global_set(${PACKAGE_NAME}_EXPORTED_PACKAGE_LIBS_NAMES
|
|
${packageLibsInAllLibsList})
|
|
|
|
# Create the ${PACKAGE_NAME}_all_libs INTERFACE interface target
|
|
add_library(${PACKAGE_NAME}_all_libs INTERFACE)
|
|
target_link_libraries(${PACKAGE_NAME}_all_libs
|
|
INTERFACE ${packageLibsInAllLibsList} )
|
|
set_target_properties(${PACKAGE_NAME}_all_libs PROPERTIES
|
|
EXPORT_NAME all_libs)
|
|
if (${PROJECT_NAME}_IMPORTED_NO_SYSTEM)
|
|
set_target_properties(${PACKAGE_NAME}_all_libs PROPERTIES IMPORTED_NO_SYSTEM TRUE)
|
|
endif()
|
|
|
|
# Install the interface target (makes sure it gets put in
|
|
# <Package>Targets.cmake file)
|
|
install(
|
|
TARGETS ${PACKAGE_NAME}_all_libs
|
|
EXPORT ${PACKAGE_NAME}
|
|
INCLUDES DESTINATION "${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}"
|
|
RUNTIME DESTINATION "${${PROJECT_NAME}_INSTALL_RUNTIME_DIR}"
|
|
LIBRARY DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}"
|
|
ARCHIVE DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}"
|
|
COMPONENT ${PACKAGE_NAME}
|
|
)
|
|
|
|
if (NOT TARGET ${PACKAGE_NAME}::all_libs)
|
|
# Create ALIAS ${PACKAGE_NAME}::all_libs target
|
|
add_library(${PACKAGE_NAME}::all_libs ALIAS ${PACKAGE_NAME}_all_libs)
|
|
endif()
|
|
|
|
endif()
|
|
|
|
#include(CMakePrintHelpers)
|
|
#cmake_print_properties(TARGETS ${PACKAGE_NAME}_all_libs ${PACKAGE_NAME}::all_libs
|
|
# PROPERTIES TYPE ALIASED_TARGET INTERFACE_LINK_LIBRARIES)
|
|
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_package_postprocess()
|
|
#
|
|
# Macro called at the very end of a package's top-level
|
|
# `<packageDir>/CMakeLists.txt`_ file that performs some critical
|
|
# post-processing activities.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_package_postprocess()
|
|
#
|
|
# NOTE: This creates the aliased target ``${PACKAGE_NAME}::all_libs`` for all
|
|
# libraries in all subdirectories that don't have the TRIBITS_TESTONLY_LIB
|
|
# target property set on them.
|
|
#
|
|
# NOTE: It is unfortunate that this macro must be called in a package's
|
|
# top-level ``CMakeLists.txt`` file but limitations of the CMake language make
|
|
# it necessary to do so.
|
|
#
|
|
macro(tribits_package_postprocess)
|
|
|
|
# check that this is not being called from inside a subpackage
|
|
if (CURRENTLY_PROCESSING_SUBPACKAGE)
|
|
if(NOT ${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Cannot call tribits_package_postprocess() in a subpackage."
|
|
" Use tribits_subpackage_postprocess() instead"
|
|
" ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
endif()
|
|
|
|
if(${PACKAGE_NAME}_SUBPACKAGES)
|
|
|
|
# This is a package that has subpackages
|
|
if(NOT ${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED OR
|
|
NOT ${PACKAGE_NAME}_TRIBITS_PACKAGE_DEF_CALLED OR
|
|
NOT ${PACKAGE_NAME}_TRIBITS_PROCESS_SUBPACKAGES_CALLED )
|
|
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_package_decl(), tribits_process_subpackages()"
|
|
" and tribits_package_def() before tribits_package_postprocess()."
|
|
" Because this package has subpackages you cannot use tribits_package()"
|
|
" you must call these in the following order:"
|
|
" tribits_package_decl()"
|
|
" tribits_process_subpackages()"
|
|
" tribits_package_def()"
|
|
" tribits_package_postprocess()"
|
|
" in: "
|
|
"${TRIBITS_PACKAGE_CMAKELIST_FILE}"
|
|
)
|
|
endif()
|
|
|
|
else()
|
|
|
|
# This is a package without subpackages
|
|
|
|
if (
|
|
(NOT ${PACKAGE_NAME}_TRIBITS_PACKAGE_CALLED)
|
|
AND
|
|
(NOT ${PACKAGE_NAME}_TRIBITS_PACKAGE_DEF_CALLED)
|
|
)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_package() or tribits_package_def() before"
|
|
" tribits_package_postprocess()"
|
|
" at the top of the file:\n"
|
|
" ${TRIBITS_PACKAGE_CMAKELIST_FILE}"
|
|
)
|
|
endif()
|
|
|
|
endif()
|
|
|
|
if(NOT ${PACKAGE_NAME}_TRIBITS_PACKAGE_DEF_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_package() before tribits_package_postprocess()."
|
|
" Or if your package has subpackages you must first call tribits_package_decl(),"
|
|
" then tribits_process_subpackages(), then tribits_package_def(), then"
|
|
" tribits_package_postprocess() in"
|
|
" ${TRIBITS_PACKAGE_CMAKELIST_FILE}"
|
|
)
|
|
endif()
|
|
|
|
if(${PACKAGE_NAME}_TRIBITS_PACKAGE_POSTPROCESS_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"tribits_package_postprocess() has been called more than once in"
|
|
" ${TRIBITS_PACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
# Only parent packages have the targets (${PACKAGE_NAME}_libs and
|
|
# (${PACKAGE_NAME}_all
|
|
if (${PROJECT_NAME}_VERBOSE_CONFIGURE)
|
|
message("\nTRIBITS_PACKAGE_POSTPROCESS: ${PACKAGE_NAME}")
|
|
print_var(${PACKAGE_NAME}_LIB_TARGETS)
|
|
print_var(${PACKAGE_NAME}_ALL_TARGETS)
|
|
endif()
|
|
add_custom_target(${PACKAGE_NAME}_libs DEPENDS ${${PACKAGE_NAME}_LIB_TARGETS})
|
|
add_custom_target(${PACKAGE_NAME}_all DEPENDS ${${PACKAGE_NAME}_ALL_TARGETS})
|
|
|
|
tribits_package_finalize_dependency_vars()
|
|
tribits_package_postprocess_common()
|
|
|
|
if (${PACKAGE_NAME}_SOURCE_DIR STREQUAL ${PROJECT_NAME}_SOURCE_DIR)
|
|
set(${PACKAGE_NAME}_TRIBITS_PACKAGE_POSTPROCESS TRUE)
|
|
else()
|
|
set(${PACKAGE_NAME}_TRIBITS_PACKAGE_POSTPROCESS TRUE PARENT_SCOPE)
|
|
endif()
|
|
|
|
set(${PACKAGE_NAME}_TRIBITS_PACKAGE_POSTPROCESS_CALLED TRUE)
|
|
|
|
endmacro()
|
|
|
|
|
|
# @MACRO: tribits_process_subpackages()
|
|
#
|
|
# Macro that processes the `TriBITS Subpackages`_ for a parent `TriBITS
|
|
# package`_ for packages that are broken down into subpackages. This is
|
|
# called in the parent packages top-level `<packageDir>/CMakeLists.txt`_ file.
|
|
#
|
|
# Usage::
|
|
#
|
|
# tribits_process_subpackages()
|
|
#
|
|
# This macro must be called after `tribits_package_decl()`_ but before
|
|
# `tribits_package_def()`_.
|
|
#
|
|
macro(tribits_process_subpackages)
|
|
|
|
if (CURRENTLY_PROCESSING_SUBPACKAGE)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Cannot call tribits_process_subpackages() in a subpackage."
|
|
" subpackages cannot contain other subpackages"
|
|
" ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
if (${PACKAGE_NAME}_TRIBITS_PACKAGE_POSTPROCESS_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_process_subpackages() before tribits_package_postprocess()"
|
|
" in ${TRIBITS_PACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
if (NOT ${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_package_decl() before tribits_process_subpackages()"
|
|
" in ${TRIBITS_PACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
if (${PACKAGE_NAME}_TRIBITS_PACKAGE_DEF_CALLED)
|
|
tribits_report_invalid_tribits_usage(
|
|
"Must call tribits_package_def() after tribits_process_subpackages()"
|
|
" in ${TRIBITS_PACKAGE_CMAKELIST_FILE}")
|
|
endif()
|
|
|
|
if (NOT ${PARENT_PACKAGE_NAME}_SUBPACKAGES)
|
|
tribits_report_invalid_tribits_usage(
|
|
"The TriBITS Package '${PACKAGE_NAME}' does not have any subpackages."
|
|
" Therefore, you are not allowed to call tribits_process_subpackages()!")
|
|
endif()
|
|
|
|
set(SUBPACKAGE_IDX 0)
|
|
foreach(TRIBITS_SUBPACKAGE ${${PARENT_PACKAGE_NAME}_SUBPACKAGES})
|
|
|
|
#message("")
|
|
#print_var(SUBPACKAGE_IDX)
|
|
#print_var(TRIBITS_SUBPACKAGE)
|
|
|
|
set(SUBPACKAGE_NAME ${TRIBITS_SUBPACKAGE})
|
|
set(SUBPACKAGE_FULLNAME ${PARENT_PACKAGE_NAME}${TRIBITS_SUBPACKAGE})
|
|
#print_var(SUBPACKAGE_FULLNAME)
|
|
|
|
if (${PROJECT_NAME}_ENABLE_${SUBPACKAGE_FULLNAME})
|
|
|
|
list(GET ${PARENT_PACKAGE_NAME}_SUBPACKAGE_DIRS ${SUBPACKAGE_IDX} SUBPACKAGE_DIR)
|
|
#print_var(SUBPACKAGE_DIR)
|
|
|
|
if (NOT ${PROJECT_NAME}_BINARY_DIR STREQUAL ${PARENT_PACKAGE_NAME}_BINARY_DIR)
|
|
dual_scope_set(${SUBPACKAGE_FULLNAME}_BINARY_DIR
|
|
${${PARENT_PACKAGE_NAME}_BINARY_DIR}/${SUBPACKAGE_DIR})
|
|
else()
|
|
set(${SUBPACKAGE_FULLNAME}_BINARY_DIR
|
|
${${PARENT_PACKAGE_NAME}_BINARY_DIR}/${SUBPACKAGE_DIR})
|
|
endif()
|
|
|
|
set(CURRENT_SUBPACKAGE_CMAKELIST_FILE
|
|
"${${SUBPACKAGE_FULLNAME}_SOURCE_DIR}/CMakeLists.txt")
|
|
tribits_trace_file_processing(PACKAGE ADD_SUBDIR
|
|
${CURRENT_SUBPACKAGE_CMAKELIST_FILE} )
|
|
set(CURRENTLY_PROCESSING_SUBPACKAGE ${SUBPACKAGE_FULLNAME})
|
|
add_subdirectory(${${SUBPACKAGE_FULLNAME}_SOURCE_DIR}
|
|
${${SUBPACKAGE_FULLNAME}_BINARY_DIR})
|
|
|
|
endif()
|
|
|
|
math(EXPR SUBPACKAGE_IDX "${SUBPACKAGE_IDX}+1")
|
|
|
|
endforeach()
|
|
|
|
set(CURRENTLY_PROCESSING_SUBPACKAGE FALSE)
|
|
set(${PACKAGE_NAME}_TRIBITS_PROCESS_SUBPACKAGES_CALLED TRUE)
|
|
|
|
endmacro()
|
|
|