Cloned SEACAS for EXODUS library with extra build files for internal package management.
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.

791 lines
29 KiB

2 years ago
# @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_guard()
include(TribitsExternalPackageWriteConfigFile)
include(AdvancedSet)
include(AppendSet)
include(AssertDefined)
include(DualScopeSet)
include(GlobalNullSet)
include(GlobalSet)
include(MultilineSet)
include(CMakeParseArguments)
include(SetNotFound)
include(Split)
# @FUNCTION: tribits_tpl_allow_pre_find_package()
#
# Function that determines if a TriBITS find module file
# ``FindTPL<tplName>.cmake`` is allowed to call ``find_package(<tplName>
# ...)`` before calling `tribits_tpl_find_include_dirs_and_libraries()`_.
#
# Usage::
#
# tribits_tpl_allow_pre_find_package( <tplName>
# <allowPackagePrefindOut> )
#
# The required arguments are:
#
# ``<tplName>`` : The input name of the TriBITS TPL (e.g. ``HDF5``).
#
# ``<allowPackagePrefindOut>`` : Name of a variable which will be set to
# ``TRUE`` on output if ``find_package(<tplName> ...)`` should be called to
# find the TPL ``<tplName>`` or ``FALSE`` if it should not be called.
#
# This function will set ``<allowPackagePrefindOut>`` to ``FALSE`` if any of
# the variables ``TPL_<tplName>_INCLUDE_DIRS``, ``${TPL_<tplName>_LIBRARIES``,
# or ``TPL_<tplName>_LIBRARY_DIRS`` are set. This allows the user to override
# the search for the library components and just specify the absolute
# locations. The function will also set ``<allowPackagePrefindOut>`` to
# ``FALSE`` if ``<tplName>_INCLUDE_DIRS``, ``<tplName>_LIBRARY_NAMES``, or
# ``<tplName>_LIBRARY_DIRS`` is set and ``<tplName>_FORCE_PRE_FIND_PACKAGE``
# is set to ``FALSE``. Otherwise, if ``<tplName>_FORCE_PRE_FIND_PACKAGE`` is
# set to ``TRUE``, the function will not return ``FALSE`` for
# ``<allowPackagePrefindOut>`` no matter what the values of
# ``<tplName>_INCLUDE_DIRS``, ``<tplName>_LIBRARY_NAMES``, or
# ``<tplName>_LIBRARY_DIRS``. Finally, ``<allowPackagePrefindOut>`` is set to
# ``FALSE`` if ``<tplName>_ALLOW_PACKAGE_PREFIND=OFF`` is set in the cache.
#
# The variable ``<tplName>_FORCE_PRE_FIND_PACKAGE`` is needed to allow users
# (or the ``FindTPL<tplName>.cmake`` module itself) to avoid name clashes with
# the variables ``<tplName>_INCLUDE_DIRS`` or ``<tplName>_LIBRARY_DIRS`` in
# the usage of ``find_package(<tplName> ...)`` because a lot of default
# ``Find<tplName>.cmake`` modules also use these variables. This function
# sets ``<tplName>_FORCE_PRE_FIND_PACKAGE`` as a cache variable with default
# value ``FALSE`` to maintain backward compatibility with existing
# ``FindTPL<tplName>.cmake`` modules.
#
# The cache variable ``<tplName>_ALLOW_PACKAGE_PREFIND`` is to allow the user
# to disable the prefind call to ``find_package()`` even if it would be
# allowed otherwise.
#
# See `Creating FindTPL<tplName>.cmake using find_package() without IMPORTED
# targets`_ for details in how to use this function to create a
# ``FindTPL<tplName>.cmake`` module file.
#
function(tribits_tpl_allow_pre_find_package TPL_NAME ALLOW_PACKAGE_PREFIND_OUT)
if (TRIBITS_TPL_ALLOW_PRE_FIND_PACKAGE_DEBUG)
message("TRIBITS_TPL_ALLOW_PRE_FIND_PACKAGE: '${TPL_NAME}' '${ALLOW_PACKAGE_PREFIND_OUT}'")
print_var(${TPL_NAME}_INCLUDE_DIRS)
print_var(${TPL_NAME}_LIBRARY_NAMES)
print_var(${TPL_NAME}_LIBRARY_DIRS)
print_var(${TPL_NAME}_FORCE_PRE_FIND_PACKAGE)
endif()
advanced_set(${TPL_NAME}_FORCE_PRE_FIND_PACKAGE FALSE
CACHE BOOL
"Determines if the variables ${TPL_NAME}_[INCLUDE_DIRS,LIBRARY_NAMES,LIBRARY_DIRS] should be ignored and the pre-find find_package(${TPL_NAME} should be performed anyway. But this will *not* do the pre-find if any of the TPL_${TPL_NAME}_[INCLUDE_DIRS,LIBRARY_NAMES,LIBRARY_DIRS] vars are set." )
# Start out with TRUE and set to FALSE in logic below
set(${TPL_NAME}_ALLOW_PACKAGE_PREFIND TRUE CACHE BOOL
"Set to FALSE to skip find_package() prefind for the TriBITS TPL '${TPL_NAME}'")
# Start out with TRUE and set to FALSE in logic below
set(ALLOW_PACKAGE_PREFIND TRUE)
if (NOT ${TPL_NAME}_ALLOW_PACKAGE_PREFIND)
set(ALLOW_PACKAGE_PREFIND FALSE)
elseif (
(NOT "${TPL_${TPL_NAME}_INCLUDE_DIRS}" STREQUAL "")
OR (NOT "${TPL_${TPL_NAME}_LIBRARIES}" STREQUAL "")
OR (NOT "${TPL_${TPL_NAME}_LIBRARY_DIRS}" STREQUAL "")
)
# The user has selected one or more of the final vars so skip calling
# find_package(${TPL_NAME} ...) ...
set(ALLOW_PACKAGE_PREFIND FALSE)
elseif (
(NOT "${${TPL_NAME}_INCLUDE_DIRS}" STREQUAL "")
OR (NOT "${${TPL_NAME}_LIBRARY_NAMES}" STREQUAL "")
OR (NOT "${${TPL_NAME}_LIBRARY_DIRS}" STREQUAL "")
)
# One or more of the ${TPL_NAME}_XXX variables are set
if (${TPL_NAME}_FORCE_PRE_FIND_PACKAGE)
# Even with one or more of the ${TPL_NAME}_XXX vars set, we still want
# to do the find_package(${TPL_NAME} ...) search and ignore this
# override.
else()
# We will not ignore the override of these variables and will instead go
# ahead and skip the pre-find.
set(ALLOW_PACKAGE_PREFIND FALSE)
endif()
endif()
set(${ALLOW_PACKAGE_PREFIND_OUT} ${ALLOW_PACKAGE_PREFIND} PARENT_SCOPE)
endfunction()
# @FUNCTION: tribits_tpl_find_include_dirs_and_libraries()
#
# This function reads (cache) variables that specify where to find a `TriBITS
# TPL`_'s headers and libraries and then creates IMPORTED targets, the
# ``<tplName>::all_libs`` target, and writes the file
# ``<tplName>Config.cmake`` into the standard location in the build directory.
# This function is typically called inside of a ``FindTPL<tplName>.cmake``
# module file (see `${TPL_NAME}_FINDMOD`_).
#
# Usage::
#
# tribits_tpl_find_include_dirs_and_libraries(
# <tplName>
# [REQUIRED_HEADERS <header1> <header2> ...]
# [MUST_FIND_ALL_HEADERS]
# [REQUIRED_LIBS_NAMES <libname1> <libname2> ...]
# [MUST_FIND_ALL_LIBS]
# [NO_PRINT_ENABLE_SUCCESS_FAIL]
# )
#
# This function can be called to specify/require header files and include
# directories and/or a list of libraries.
#
# The input arguments to this function are:
#
# ``<tplName>``
#
# Name of the TPL that is listed in a `<repoDir>/TPLsList.cmake`_ file.
#
# ``REQUIRED_HEADERS``
#
# List of header files that are searched in order to find the TPL's
# include directories files using ``find_path()``.
#
# ``MUST_FIND_ALL_HEADERS``
#
# If set, then all of the header files listed in ``REQUIRED_HEADERS`` must
# be found (unless ``TPL_<tplName>_INCLUDE_DIRS`` is already set).
#
# ``REQUIRED_LIBS_NAMES``
#
# List of libraries that are searched for when looking for the TPL's
# libraries using ``find_library()``. This list can be overridden by the
# user by setting ``<tplName>_LIBRARY_NAMES`` (see below).
#
# ``MUST_FIND_ALL_LIBS``
#
# If set, then all of the library files listed in ``REQUIRED_LIBS_NAMES``
# must be found or the TPL is considered not found (unless
# ``TPL_<tplName>_LIBRARIES`` is already set). If the global cache var
# ``<Project>_MUST_FIND_ALL_TPL_LIBS`` is set to ``TRUE``, then this is
# turned on as well. WARNING: The default is not to require finding all
# of the listed libs. (This is to maintain backward compatibility with
# some older ``FindTPL<tplName>.cmake`` modules.)
#
# ``NO_PRINT_ENABLE_SUCCESS_FAIL``
#
# If set, then the final success/fail will not be printed
#
# This function implements the TPL find behavior described in `Enabling
# support for an optional Third-Party Library (TPL)`_.
#
# The following (cache) variables, if set, will be used by this function:
#
# ``<tplName>_INCLUDE_DIRS`` (type ``PATH``)
#
# List of paths to search first for header files defined in
# ``REQUIRED_HEADERS <header1> <header2> ...``.
#
# ``<tplName>_LIBRARY_DIRS`` (type ``PATH``)
#
# The list of directories to search first for libraries defined in
# ``REQUIRED_LIBS_NAMES <libname1> <libname2> ...``. If, for some reason,
# no libraries should be linked in for this particular configuration, then
# setting ``<tplName>_LIBRARY_DIRS=OFF`` or is empty will no special paths
# will be searched.
#
# ``<tplName>_LIBRARY_NAMES`` (type ``STRING``)
#
# List of library names to be looked for instead of what is specified in
# ``REQUIRED_LIBS_NAMES <libname1> <libname2> ...``.
#
# ``<tplName>_LIB_ENABLED_DEPENDENCIES``
#
# List of direct upstream external package/TPL dependencies that also
# define ``<upstreamTplName>::all_libs`` targets.
#
# An addition, the function will avoid calling the find operations if the
# following (cache) variables are set on input:
#
# ``TPL_<tplName>_INCLUDE_DIRS`` (type ``PATH``)
#
# A list of common-separated full directory paths that contain the TPL's
# header files.
#
# ``TPL_<tplName>_LIBRARIES`` (type ``FILEPATH``)
#
# A list of commons-separated full library names (i.e. output from
# ``find_library()``) for all of the libraries for the TPL.
#
# This function produces the following:
#
# ``TPL_<tplName>_NOT_FOUND`` (type ``BOOL``)
#
# Will be set to ``ON`` if all of the parts of the TPL could not be found.
#
# ``<tplName>::<libname>``
#
# Namespaced IMPORTED target for every library found or specified in
# ``TPL_<tplName>_LIBRARIES``. These IMPORTED targets will have the
# ``<upstreamTplName>::all_libs`` for the upstream external packages/TPLs
# listed in ``<tplName>_LIB_ENABLED_DEPENDENCIES``.
#
# ``<tplName>::all_libs``
#
# INTERFACE target that depends on all of the created IMPORTED targets.
#
# ``<buildDir>/external_packages/<tplName>/<tplName>Config.cmake``
#
# A package configure file that contains all of the generated IMPORTED
# targets ``<tplName>::<libname>`` and the ``<tplName>::all_libs`` target.
# This fill will also call ``find_dependency()`` to pull in
# ``<upstreamTplName>Config.cmake`` files for upstream TPLs that are
# listed in ``<tplName>_LIB_ENABLED_DEPENDENCIES``. (For more
# information, see `tribits_extpkg_write_config_file()`_.)
#
# Note, if ``TPL_TENTATIVE_ENABLE_<tplName>=ON``, then if all of the parts of
# the TPL can't be found, then ``TPL_ENABLE_<tplName>`` will be (forced) set
# to ``OFF`` in the cache. See `tribits_tpl_tentatively_enable()`_.
#
function(tribits_tpl_find_include_dirs_and_libraries TPL_NAME)
# Make sure the right name is used
assert_defined(TPL_ENABLE_${TPL_NAME})
cmake_parse_arguments(
#prefix
PARSE
#options
"MUST_FIND_ALL_LIBS;MUST_FIND_ALL_HEADERS;NO_PRINT_ENABLE_SUCCESS_FAIL"
#one_value_keywords
""
#multi_value_keywords
"REQUIRED_HEADERS;REQUIRED_LIBS_NAMES"
${ARGN}
)
tribits_check_for_unparsed_arguments()
if (${PROJECT_NAME}_VERBOSE_CONFIGURE)
set(TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE TRUE)
endif()
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
message("TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES: ${TPL_NAME}")
print_var(PARSE_REQUIRED_HEADERS)
print_var(PARSE_REQUIRED_LIBS_NAMES)
print_var(TPL_${TPL_NAME}_INCLUDE_DIRS)
print_var(TPL_${TPL_NAME}_LIBRARIES)
endif()
if (TPL_TENTATIVE_ENABLE_${TPL_NAME})
message("-- Attempting to tentatively enable TPL '${TPL_NAME}' ...")
set(ERROR_MSG_MODE)
else()
set(ERROR_MSG_MODE SEND_ERROR)
endif()
# Allow user override for finding libraries even if REQUIRED_LIBS_NAMES is
# empty on input
multiline_set(DOCSTR
"List of semi-colon separated names of libraries needed to link to for"
" the TPL ${TPL_NAME}. This list of libraries will be search for in"
" find_library(...) calls along with the directories specified with"
" ${TPL_NAME}_LIBRARY_DIRS. NOTE: This is not the final list of libraries"
" used for linking. That is specified by TPL_${TPL_NAME}_LIBRARIES!"
)
advanced_set(${TPL_NAME}_LIBRARY_NAMES ${PARSE_REQUIRED_LIBS_NAMES}
CACHE STRING ${DOCSTR})
split("${${TPL_NAME}_LIBRARY_NAMES}" "," ${TPL_NAME}_LIBRARY_NAMES)
print_var(${TPL_NAME}_LIBRARY_NAMES)
# Let the user override what the names of the libraries which might
# actually mean that no libraries are searched for.
set(REQUIRED_LIBS_NAMES ${${TPL_NAME}_LIBRARY_NAMES})
#
# User options
#
if (REQUIRED_LIBS_NAMES)
# Library directories
multiline_set(DOCSTR
"List of semi-colon separated paths to look for the TPL ${TPL_NAME}"
" libraries. This list of paths will be passed into a find_library(...)"
" command to find the libraries listed in ${TPL_NAME}_LIBRARY_NAMES."
" Note that this set of paths is also the default value used for"
" ${TPL_NAME}_LIBRARY_DIRS. Therefore, if the headers exist in the"
" same directories as the library, you do not need to set"
" ${TPL_NAME}_LIBRARY_DIRS."
)
advanced_set(${TPL_NAME}_LIBRARY_DIRS "" CACHE PATH ${DOCSTR})
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(${TPL_NAME}_LIBRARY_DIRS)
endif()
# Libraries
if (${PROJECT_NAME}_MUST_FIND_ALL_TPL_LIBS)
set(MUST_FIND_ALL_LIBS TRUE)
else()
set(MUST_FIND_ALL_LIBS ${PARSE_MUST_FIND_ALL_LIBS})
endif()
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(${TPL_NAME}_LIBRARY_NAMES)
print_var(REQUIRED_LIBS_NAMES)
endif()
else()
set(${TPL_NAME}_LIBRARY_DIRS "") # Just to ignore below!
endif()
# Include directories
if (PARSE_REQUIRED_HEADERS)
multiline_set(DOCSTR
"List of semi-colon separated paths to look for the TPL ${TPL_NAME}"
" headers. This list of paths will be passed into a find_path(...)"
" command to find the headers for ${TPL_NAME} (which are known in advance)."
)
advanced_set(${TPL_NAME}_INCLUDE_DIRS ${${TPL_NAME}_LIBRARY_DIRS}
CACHE PATH ${DOCSTR})
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(${TPL_NAME}_LIBRARY_DIRS)
print_var(${TPL_NAME}_INCLUDE_DIRS)
print_var(PARSE_REQUIRED_HEADERS)
endif()
endif()
#
# Set the lib extensions to find
#
# Save the default the first time through
if (NOT CMAKE_FIND_LIBRARY_SUFFIXES_DEFAULT)
set(TPL_CMAKE_FIND_LIBRARY_SUFFIXES_DEFAULT ${CMAKE_FIND_LIBRARY_SUFFIXES})
#print_var(TPL_CMAKE_FIND_LIBRARY_SUFFIXES_DEFAULT)
endif()
#print_var(TPL_FIND_SHARED_LIBS)
#print_var(CMAKE_FIND_LIBRARY_SUFFIXES)
# Set libraries to find
if (TPL_FIND_SHARED_LIBS)
# The default should be to find shared libs first
set(TPL_CMAKE_FIND_LIBRARY_SUFFIXES ${TPL_CMAKE_FIND_LIBRARY_SUFFIXES_DEFAULT})
else()
if (WIN32)
set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a)
else()
set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
endif()
endif()
#print_var(CMAKE_FIND_LIBRARY_SUFFIXES)
#
# Direct build options
#
set(_${TPL_NAME}_ENABLE_SUCCESS TRUE)
if (REQUIRED_LIBS_NAMES)
# Libraries
if (MUST_FIND_ALL_LIBS)
set(LIB_NOT_FOUND_MSG_PREFIX "ERROR:")
else()
set(LIB_NOT_FOUND_MSG_PREFIX "NOTE:")
endif()
if (NOT TPL_${TPL_NAME}_LIBRARIES)
if (MUST_FIND_ALL_LIBS)
message("-- Must find at least one lib in each of the"
" lib sets \"${REQUIRED_LIBS_NAMES}\"")
endif()
message( "-- Searching for libs in ${TPL_NAME}_LIBRARY_DIRS='${${TPL_NAME}_LIBRARY_DIRS}'")
set(LIBRARIES_FOUND)
foreach(LIBNAME_SET ${REQUIRED_LIBS_NAMES})
message("-- Searching for a lib in the set \"${LIBNAME_SET}\":")
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(LIBNAME_SET)
endif()
set(LIBNAME_LIST ${LIBNAME_SET})
separate_arguments(LIBNAME_LIST)
set(LIBNAME_SET_LIB)
foreach(LIBNAME ${LIBNAME_LIST})
message("-- Searching for lib '${LIBNAME}' ...")
if (${TPL_NAME}_LIBRARY_DIRS)
set(PATHS_ARG PATHS ${${TPL_NAME}_LIBRARY_DIRS})
else()
set(PATHS_ARG PATHS)
endif()
set_notfound(_${TPL_NAME}_${LIBNAME}_LIBRARY)
find_library( _${TPL_NAME}_${LIBNAME}_LIBRARY
NAMES ${LIBNAME}
${PATHS_ARG} NO_DEFAULT_PATH )
find_library( _${TPL_NAME}_${LIBNAME}_LIBRARY
NAMES ${LIBNAME} )
mark_as_advanced(_${TPL_NAME}_${LIBNAME}_LIBRARY)
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(_${TPL_NAME}_${LIBNAME}_LIBRARY)
endif()
if (_${TPL_NAME}_${LIBNAME}_LIBRARY)
message("-- Found lib '${_${TPL_NAME}_${LIBNAME}_LIBRARY}'")
set(LIBNAME_SET_LIB ${_${TPL_NAME}_${LIBNAME}_LIBRARY})
break()
endif()
endforeach()
if (NOT LIBNAME_SET_LIB)
message(
"-- ${LIB_NOT_FOUND_MSG_PREFIX} Did not find a lib in the lib set \"${LIBNAME_SET}\""
" for the TPL '${TPL_NAME}'!")
if (MUST_FIND_ALL_LIBS)
set(_${TPL_NAME}_ENABLE_SUCCESS FALSE)
else()
break()
endif()
endif()
append_set(LIBRARIES_FOUND ${LIBNAME_SET_LIB})
endforeach()
multiline_set(DOCSTR
"List of semi-colon separated full paths to the libraries for the TPL"
" ${TPL_NAME}. This is the final variable that is used in the link"
" commands. The user variable ${TPL_NAME}_LIBRARY_DIRS is used to look"
" for the know library names but but is just a suggestion."
" This variable, however, is the final value and will not be touched."
)
advanced_set( TPL_${TPL_NAME}_LIBRARIES ${LIBRARIES_FOUND}
CACHE FILEPATH ${DOCSTR} FORCE)
# Above, we have to force the set in case the find failed the last
# configure in which case this cache var will be empty. NOTE: If the
# user specified a non-empty TPL_${TPL_NAME}_LIBRARIES, then we would
# never get here in the first place!
if (NOT TPL_${TPL_NAME}_LIBRARIES OR NOT _${TPL_NAME}_ENABLE_SUCCESS)
message(
"-- ERROR: Could not find the libraries for the TPL '${TPL_NAME}'!")
message(
"-- TIP: If the TPL '${TPL_NAME}' is on your system then you can set:\n"
" -D${TPL_NAME}_LIBRARY_DIRS='<dir0>;<dir1>;...'\n"
" to point to the directories where these libraries may be found.\n"
" Or, just set:\n"
" -DTPL_${TPL_NAME}_LIBRARIES='<path-to-libs0>;<path-to-libs1>;...'\n"
" to point to the full paths for the libraries which will\n"
" bypass any search for libraries and these libraries will be used without\n"
" question in the build. (But this will result in a build-time error\n"
" if not all of the necessary symbols are found.)")
tribits_tpl_find_include_dirs_and_libraries_handle_fail()
endif()
endif()
# Print the final value to be used *always*
message("-- TPL_${TPL_NAME}_LIBRARIES='${TPL_${TPL_NAME}_LIBRARIES}'")
else()
# There are no libraries so set the libraries to null but don't
# change the cache which should not even have this variable in it.
# This set command is only to follow the standards for the package
# support CMake code.
global_null_set(TPL_${TPL_NAME}_LIBRARIES)
endif()
# Include directories
if (PARSE_REQUIRED_HEADERS)
if (NOT TPL_${TPL_NAME}_INCLUDE_DIRS)
if (PARSE_MUST_FIND_ALL_HEADERS)
message("-- Must find at least one header in each of the"
" header sets \"${PARSE_REQUIRED_HEADERS}\"")
endif()
message( "-- Searching for headers in ${TPL_NAME}_INCLUDE_DIRS='${${TPL_NAME}_INCLUDE_DIRS}'")
foreach(INCLUDE_FILE_SET ${PARSE_REQUIRED_HEADERS})
message("-- Searching for a header file in the set \"${INCLUDE_FILE_SET}\":")
set(INCLUDE_FILE_LIST ${INCLUDE_FILE_SET})
separate_arguments(INCLUDE_FILE_LIST)
set(INCLUDE_FILE_SET_PATH) # Start out as empty list
foreach(INCLUDE_FILE ${INCLUDE_FILE_LIST})
message("-- Searching for header '${INCLUDE_FILE}' ...")
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(INCLUDE_FILE)
endif()
set_notfound(_${TPL_NAME}_${INCLUDE_FILE}_PATH)
find_path( _${TPL_NAME}_${INCLUDE_FILE}_PATH
NAMES ${INCLUDE_FILE}
PATHS ${${TPL_NAME}_INCLUDE_DIRS}
NO_DEFAULT_PATH)
find_path( _${TPL_NAME}_${INCLUDE_FILE}_PATH
NAMES ${INCLUDE_FILE} )
mark_as_advanced(_${TPL_NAME}_${INCLUDE_FILE}_PATH)
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(_${TPL_NAME}_${INCLUDE_FILE}_PATH)
endif()
if(_${TPL_NAME}_${INCLUDE_FILE}_PATH)
message( "-- Found header '${_${TPL_NAME}_${INCLUDE_FILE}_PATH}/${INCLUDE_FILE}'")
append_set(INCLUDE_FILE_SET_PATH ${_${TPL_NAME}_${INCLUDE_FILE}_PATH})
break()
endif()
endforeach()
if(NOT INCLUDE_FILE_SET_PATH)
message("-- ERROR: Could not find a header file in"
" the set \"${INCLUDE_FILE_SET}\"")
if(PARSE_MUST_FIND_ALL_HEADERS)
set(_${TPL_NAME}_ENABLE_SUCCESS FALSE)
endif()
endif()
append_set(INCLUDES_FOUND ${INCLUDE_FILE_SET_PATH})
endforeach(INCLUDE_FILE_SET ${PARSE_REQUIRED_HEADERS})
if (INCLUDES_FOUND)
list(REMOVE_DUPLICATES INCLUDES_FOUND)
endif()
multiline_set(DOCSTR
"List of semi-colon separated paths to append to the compile invocations"
" to find the headers for the TPL ${TPL_NAME}. This is the final variable"
" that is used in the build commands. The user variable ${TPL_NAME}_INCLUDE_DIRS"
" is used to look for the given headers first but is just a suggestion."
" This variable, however, is the final value and will not be touched."
)
advanced_set(TPL_${TPL_NAME}_INCLUDE_DIRS ${INCLUDES_FOUND}
CACHE PATH ${DOCSTR} FORCE)
# Above, we have to force the set in case the find failed the last
# configure in which case this cache var will be empty. NOTE: If the
# user specified a non-empty TPL_${TPL_NAME}_INCLUDE_DIRS, then we would
# never get here in the first place!
if (NOT TPL_${TPL_NAME}_INCLUDE_DIRS OR NOT _${TPL_NAME}_ENABLE_SUCCESS)
message(
"-- ERROR: Could not find the include directories for TPL '${TPL_NAME}'!")
message(
"-- TIP: If the TPL '${TPL_NAME}' is on your system then you can set:\n"
" -D${TPL_NAME}_INCLUDE_DIRS='<dir0>;<dir1>;...'\n"
" to point to directories where these header files may be found.\n"
" Or, just set:\n"
" -DTPL_${TPL_NAME}_INCLUDE_DIRS='<dir0>;<dir1>;...'\n"
" to point to the include directories which will bypass any search for\n"
" header files and these include directories will be used without\n"
" question in the build. (But this will result in a build-time error\n"
" obviously if the necessary header files are not found in these\n"
" include directories.)")
tribits_tpl_find_include_dirs_and_libraries_handle_fail()
endif()
if (TPL_${TPL_NAME}_INCLUDE_DIRS)
message("-- Found TPL '${TPL_NAME}' include dirs '${TPL_${TPL_NAME}_INCLUDE_DIRS}'")
endif()
else()
# TPL_${TPL_NAME}_INCLUDE_DIRS is already in the cache so leave it alone!
endif()
# Print the final value to be used *always*
message("-- TPL_${TPL_NAME}_INCLUDE_DIRS='${TPL_${TPL_NAME}_INCLUDE_DIRS}'")
else()
if (${TPL_NAME}_INCLUDE_DIRS)
advanced_set(TPL_${TPL_NAME}_INCLUDE_DIRS ${${TPL_NAME}_INCLUDE_DIRS}
CACHE PATH "User provided include dirs in the absence of include files.")
else()
if ("${TPL_${TPL_NAME}_INCLUDE_DIRS}" STREQUAL "")
# Library has no header files, no user override, so just set them to
# null (unless the user has already set this).
global_null_set(TPL_${TPL_NAME}_INCLUDE_DIRS)
endif()
endif()
endif()
# Set library directories to null always. We do this because
# the package support code expects this variable and it is used
# for package dependencies. Therefore, we need it to allow
# TPLs and internal packages to be treated in the same way.
global_null_set(TPL_${TPL_NAME}_LIBRARY_DIRS)
if (TRIBITS_TPL_FIND_INCLUDE_DIRS_AND_LIBRARIES_VERBOSE)
print_var(TPL_${TPL_NAME}_LIBRARY_DIRS)
endif()
# 2011/05/09: rabartl: ToDo: Remove this above variable from everywhere!
#print_var(TPL_TENTATIVE_ENABLE_${TPL_NAME})
#print_var(_${TPL_NAME}_ENABLE_SUCCESS)
if (TPL_TENTATIVE_ENABLE_${TPL_NAME})
if (_${TPL_NAME}_ENABLE_SUCCESS)
if (NOT PARSE_NO_PRINT_ENABLE_SUCCESS_FAIL)
message("-- Attempt to tentatively enable TPL '${TPL_NAME}' passed!")
endif()
else()
if (NOT PARSE_NO_PRINT_ENABLE_SUCCESS_FAIL)
message("-- Attempt to tentatively enable TPL '${TPL_NAME}' failed!"
" Setting TPL_ENABLE_${TPL_NAME}=OFF")
endif()
set(TPL_ENABLE_${TPL_NAME} OFF CACHE STRING
"Forced off since tentative enable failed!" FORCE)
endif()
endif()
if (_${TPL_NAME}_ENABLE_SUCCESS)
global_set(TPL_${TPL_NAME}_NOT_FOUND FALSE)
endif()
set(buildDirExternalPkgsDir
"${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}")
set(tplConfigFileBaseDir "${buildDirExternalPkgsDir}/${TPL_NAME}")
set(tplConfigFile "${tplConfigFileBaseDir}/${TPL_NAME}Config.cmake")
tribits_extpkg_write_config_file(${TPL_NAME} "${tplConfigFile}")
if (NOT ${PROJECT_NAME}_ENABLE_INSTALLATION_TESTING)
include("${tplConfigFile}")
endif()
# NOTE: The file <tplName>ConfigVersion.cmake will get created elsewhere as
# will the install targets for the files <tplName>Config and
# <tplName>ConfigVersion.cmake.
endfunction()
# @FUNCTION: tribits_tpl_tentatively_enable()
#
# Function that sets up for an optionally enabled TPL that is attempted to be
# enabled but will be disabled if all of the parts are not found.
#
# Usage::
#
# tribits_tpl_tentatively_enable(<tplName>)
#
# This function can be called from any CMakeLists.txt file to put a TPL in
# tentative enable mode. But typically, it is called from an Package's
# `<packageDir>/cmake/Dependencies.cmake`_ file (see `How to tentatively
# enable an external package/TPL`_).
#
# This should only be used for optional TPLs. It will not work correctly for
# required TPLs because any enabled packages that require this TPL will not be
# disabled and instead will fail to configure or fail to build.
#
# All this function does is to force set ``TPL_ENABLE_<tplName>=ON`` if it has
# not already been set, and sets ``TPL_TENTATIVE_ENABLE_<tplName>=ON`` in the
# cache.
#
# NOTE: This function will only tentatively enable a TPL if its enable has not
# be explicitly set on input, i.e. if ``-D TPL_ENABLE_<tplName>=""``. If the
# TPL has been explicitly enabled (i.e. ``-D TPL_ENABLE_<tplName>=ON``) or
# disabled (i.e. ``-D TPL_ENABLE_<tplName>=OFF``), then this function has no
# effect and the TPL will be unconditionally enabled or disabled.
#
function(tribits_tpl_tentatively_enable TPL_NAME)
if ("${TPL_ENABLE_${TPL_NAME}}" STREQUAL "")
# The TPL's enable status has not been set so tentatively enable it.
set(TPL_ENABLE_${TPL_NAME} ON CACHE STRING
"Set by tribits_tpl_tentatively_enable()" FORCE)
advanced_set(TPL_TENTATIVE_ENABLE_${TPL_NAME} ON CACHE STRING
"Set by tribits_tpl_tentatively_enable()" FORCE)
else()
# The TPL's enable status has already be hard set to be ON or OFF so we
# will leave it alone.
endif()
endfunction()
# Set find error and print error message
#
macro(tribits_tpl_find_include_dirs_and_libraries_handle_fail)
set(_${TPL_NAME}_ENABLE_SUCCESS FALSE)
global_set(TPL_${TPL_NAME}_NOT_FOUND TRUE)
message(
"-- ERROR: Failed finding all of the parts of TPL '${TPL_NAME}' (see above), Aborting!\n" )
if ("${ERROR_MSG_MODE}" STREQUAL "SEND_ERROR")
#message("ERROR_MSG_MODE=SEND_ERROR, Aborting")
return()
endif()
endmacro()