# @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.cmake`` is allowed to call ``find_package( # ...)`` before calling `tribits_tpl_find_include_dirs_and_libraries()`_. # # Usage:: # # tribits_tpl_allow_pre_find_package( # ) # # The required arguments are: # # ```` : The input name of the TriBITS TPL (e.g. ``HDF5``). # # ```` : Name of a variable which will be set to # ``TRUE`` on output if ``find_package( ...)`` should be called to # find the TPL ```` or ``FALSE`` if it should not be called. # # This function will set ```` to ``FALSE`` if any of # the variables ``TPL__INCLUDE_DIRS``, ``${TPL__LIBRARIES``, # or ``TPL__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 ```` to # ``FALSE`` if ``_INCLUDE_DIRS``, ``_LIBRARY_NAMES``, or # ``_LIBRARY_DIRS`` is set and ``_FORCE_PRE_FIND_PACKAGE`` # is set to ``FALSE``. Otherwise, if ``_FORCE_PRE_FIND_PACKAGE`` is # set to ``TRUE``, the function will not return ``FALSE`` for # ```` no matter what the values of # ``_INCLUDE_DIRS``, ``_LIBRARY_NAMES``, or # ``_LIBRARY_DIRS``. Finally, ```` is set to # ``FALSE`` if ``_ALLOW_PACKAGE_PREFIND=OFF`` is set in the cache. # # The variable ``_FORCE_PRE_FIND_PACKAGE`` is needed to allow users # (or the ``FindTPL.cmake`` module itself) to avoid name clashes with # the variables ``_INCLUDE_DIRS`` or ``_LIBRARY_DIRS`` in # the usage of ``find_package( ...)`` because a lot of default # ``Find.cmake`` modules also use these variables. This function # sets ``_FORCE_PRE_FIND_PACKAGE`` as a cache variable with default # value ``FALSE`` to maintain backward compatibility with existing # ``FindTPL.cmake`` modules. # # The cache variable ``_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.cmake using find_package() without IMPORTED # targets`_ for details in how to use this function to create a # ``FindTPL.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 # ``::all_libs`` target, and writes the file # ``Config.cmake`` into the standard location in the build directory. # This function is typically called inside of a ``FindTPL.cmake`` # module file (see `${TPL_NAME}_FINDMOD`_). # # Usage:: # # tribits_tpl_find_include_dirs_and_libraries( # # [REQUIRED_HEADERS ...] # [MUST_FIND_ALL_HEADERS] # [REQUIRED_LIBS_NAMES ...] # [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: # # ```` # # Name of the TPL that is listed in a `/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__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 ``_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__LIBRARIES`` is already set). If the global cache var # ``_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.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: # # ``_INCLUDE_DIRS`` (type ``PATH``) # # List of paths to search first for header files defined in # ``REQUIRED_HEADERS ...``. # # ``_LIBRARY_DIRS`` (type ``PATH``) # # The list of directories to search first for libraries defined in # ``REQUIRED_LIBS_NAMES ...``. If, for some reason, # no libraries should be linked in for this particular configuration, then # setting ``_LIBRARY_DIRS=OFF`` or is empty will no special paths # will be searched. # # ``_LIBRARY_NAMES`` (type ``STRING``) # # List of library names to be looked for instead of what is specified in # ``REQUIRED_LIBS_NAMES ...``. # # ``_LIB_ENABLED_DEPENDENCIES`` # # List of direct upstream external package/TPL dependencies that also # define ``::all_libs`` targets. # # An addition, the function will avoid calling the find operations if the # following (cache) variables are set on input: # # ``TPL__INCLUDE_DIRS`` (type ``PATH``) # # A list of common-separated full directory paths that contain the TPL's # header files. # # ``TPL__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__NOT_FOUND`` (type ``BOOL``) # # Will be set to ``ON`` if all of the parts of the TPL could not be found. # # ``::`` # # Namespaced IMPORTED target for every library found or specified in # ``TPL__LIBRARIES``. These IMPORTED targets will have the # ``::all_libs`` for the upstream external packages/TPLs # listed in ``_LIB_ENABLED_DEPENDENCIES``. # # ``::all_libs`` # # INTERFACE target that depends on all of the created IMPORTED targets. # # ``/external_packages//Config.cmake`` # # A package configure file that contains all of the generated IMPORTED # targets ``::`` and the ``::all_libs`` target. # This fill will also call ``find_dependency()`` to pull in # ``Config.cmake`` files for upstream TPLs that are # listed in ``_LIB_ENABLED_DEPENDENCIES``. (For more # information, see `tribits_extpkg_write_config_file()`_.) # # Note, if ``TPL_TENTATIVE_ENABLE_=ON``, then if all of the parts of # the TPL can't be found, then ``TPL_ENABLE_`` 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=';;...'\n" " to point to the directories where these libraries may be found.\n" " Or, just set:\n" " -DTPL_${TPL_NAME}_LIBRARIES=';;...'\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=';;...'\n" " to point to directories where these header files may be found.\n" " Or, just set:\n" " -DTPL_${TPL_NAME}_INCLUDE_DIRS=';;...'\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 ConfigVersion.cmake will get created elsewhere as # will the install targets for the files Config and # 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() # # 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 # `/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_=ON`` if it has # not already been set, and sets ``TPL_TENTATIVE_ENABLE_=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_=""``. If the # TPL has been explicitly enabled (i.e. ``-D TPL_ENABLE_=ON``) or # disabled (i.e. ``-D TPL_ENABLE_=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()