# @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 # Standard TriBITS system includes include(TribitsConstants) include(TribitsProcessExtraRepositoriesList) include(TribitsProcessPackagesAndDirsLists) include(TribitsProcessTplsLists) include(TribitsReadDepsFilesCreateDepsGraph) # Standard TriBITS utilities includes include(TimingUtils) # @MACRO: tribits_read_all_project_deps_files_create_deps_graph() # # Usage:: # # tribits_read_all_project_deps_files_create_deps_graph() # # Macro run at the top project-level scope that reads the lists of packages # and TPLs and creates the packages dependency graph. # # On output, this creates all of the package lists and dependency # data-structures described in the section `TriBITS System Data Structures`_ # and more specifically the sections: # # * `Lists of external and internal packages`_ # * `Variables defining the package dependencies graph`_ # * `TriBITS Package Top-Level Local Variables`_ # * `TriBITS Subpackage Top-Level Local Variables`_ # * `TriBITS Package Cache Variables`_ # # See `Function call tree for constructing package dependency graph`_. # macro(tribits_read_all_project_deps_files_create_deps_graph) tribits_config_code_start_timer(SET_UP_DEPENDENCIES_TIME_START_SECONDS) tribits_read_defined_external_and_internal_toplevel_packages_lists() tribits_read_deps_files_create_deps_graph() # ${PROJECT_NAME}_DEFINED_PACKAGES set(${PROJECT_NAME}_DEFINED_PACKAGES ${${PROJECT_NAME}_DEFINED_TPLS} ${${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES}) list(LENGTH ${PROJECT_NAME}_DEFINED_PACKAGES ${PROJECT_NAME}_NUM_DEFINED_PACKAGES) tribits_config_code_stop_timer(SET_UP_DEPENDENCIES_TIME_START_SECONDS "\nTotal time to read in all dependencies files and build dependencies graph") endmacro() # @MACRO: tribits_read_defined_external_and_internal_toplevel_packages_lists() # # Usage:: # # tribits_read_defined_external_and_internal_toplevel_packages_lists() # # Macro run at the top project-level scope that reads in the contents of all # of the `/TPLsList.cmake`_ and `/PackagesList.cmake`_ files # to get the list of defined external packages (TPLs) and internal top-level # (TriBITS) packages. # # On output, this produces the local variables: # # * `${PROJECT_NAME}_DEFINED_TPLS`_ # * `${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES`_ # * `${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES`_ # # and the length vars for these: # # * `${PROJECT_NAME}_NUM_DEFINED_TPLS`_ # * `${PROJECT_NAME}_NUM_DEFINED_INTERNAL_TOPLEVEL_PACKAGES`_ # * `${PROJECT_NAME}_NUM_DEFINED_TOPLEVEL_PACKAGES`_ # # This includes the files: # # * `/TPLsList.cmake`_ # * `/PackagesList.cmake`_ # # and calls the macros: # # * `tribits_process_tpls_lists()`_ # * `tribits_process_packages_and_dirs_lists()`_ # # which set their variables. # # See `Function call tree for constructing package dependency graph`_ # macro(tribits_read_defined_external_and_internal_toplevel_packages_lists) tribits_set_all_extra_repositories() # Set package list vars to empty set(${PROJECT_NAME}_DEFINED_TPLS "") set(${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES "") # # A) Read list of external packages/TPLs and top-level internal packages # from 'PRE' extra repos # set(READ_PRE_OR_POST_EXRAREPOS PRE) tribits_read_extra_repositories_lists() # # B) Read list of external packages/TPLs and top-level internal packages # from the native repos # foreach(NATIVE_REPO ${${PROJECT_NAME}_NATIVE_REPOSITORIES}) tribits_get_repo_name_dir(${NATIVE_REPO} NATIVE_REPO_NAME NATIVE_REPO_DIR) #print_var(NATIVE_REPO_NAME) #print_var(NATIVE_REPO_DIR) # Need to make sure this gets set because logic in Dependencies.cmake files # looks for the presents of this variable. tribits_set_base_repo_dir(${PROJECT_SOURCE_DIR} ${NATIVE_REPO_DIR} ${NATIVE_REPO_NAME}_SOURCE_DIR) #print_var(${NATIVE_REPO_NAME}_SOURCE_DIR) if (NATIVE_REPO STREQUAL ".") set(REPOSITORY_NAME ${PROJECT_NAME}) else() set(REPOSITORY_NAME ${NATIVE_REPO_NAME}) endif() # # B.1) Define the lists of all ${NATIVE_REPO_NAME} native packages and TPLs # # B.1.a) Read in the list of TPLs for this repo if (${NATIVE_REPO_NAME}_TPLS_FILE_OVERRIDE) if (IS_ABSOLUTE "${${NATIVE_REPO_NAME}_TPLS_FILE_OVERRIDE}") set(${NATIVE_REPO_NAME}_TPLS_FILE "${${NATIVE_REPO_NAME}_TPLS_FILE_OVERRIDE}") else() set(${NATIVE_REPO_NAME}_TPLS_FILE "${${NATIVE_REPO_NAME}_SOURCE_DIR}/${${NATIVE_REPO_NAME}_TPLS_FILE_OVERRIDE}") endif() else() set(${NATIVE_REPO_NAME}_TPLS_FILE "${${NATIVE_REPO_NAME}_SOURCE_DIR}/${${PROJECT_NAME}_TPLS_FILE_NAME}") endif() message("") message("Reading list of native TPLs from ${${NATIVE_REPO_NAME}_TPLS_FILE}") message("") tribits_trace_file_processing(REPOSITORY INCLUDE "${${NATIVE_REPO_NAME}_TPLS_FILE}") include(${${NATIVE_REPO_NAME}_TPLS_FILE}) tribits_process_tpls_lists(${NATIVE_REPO_NAME} ${NATIVE_REPO_DIR}) # B.1.b) Read in list of packages for this repo if (${NATIVE_REPO_NAME}_PACKAGES_FILE_OVERRIDE) if (IS_ABSOLUTE "${${NATIVE_REPO_NAME}_PACKAGES_FILE_OVERRIDE}") set(${NATIVE_REPO_NAME}_PACKAGES_FILE "${${NATIVE_REPO_NAME}_PACKAGES_FILE_OVERRIDE}") else() set(${NATIVE_REPO_NAME}_PACKAGES_FILE "${${NATIVE_REPO_NAME}_SOURCE_DIR}/${${NATIVE_REPO_NAME}_PACKAGES_FILE_OVERRIDE}") endif() else() set(${NATIVE_REPO_NAME}_PACKAGES_FILE "${${NATIVE_REPO_NAME}_SOURCE_DIR}/${${PROJECT_NAME}_PACKAGES_FILE_NAME}") endif() message("") message("Reading list of native packages from ${${NATIVE_REPO_NAME}_PACKAGES_FILE}") message("") tribits_trace_file_processing(REPOSITORY INCLUDE "${${NATIVE_REPO_NAME}_PACKAGES_FILE}") include(${${NATIVE_REPO_NAME}_PACKAGES_FILE}) tribits_process_packages_and_dirs_lists(${NATIVE_REPO_NAME} ${NATIVE_REPO_DIR}) endforeach() # # C) Read list of external packages/TPLs and top-level internal packages # from 'POST' extra repos # set(READ_PRE_OR_POST_EXRAREPOS POST) tribits_read_extra_repositories_lists() # # D) Compute lengths and other combined quantities # # ${PROJECT_NAME}_NUM_DEFINED_TPLS list(LENGTH ${PROJECT_NAME}_DEFINED_TPLS ${PROJECT_NAME}_NUM_DEFINED_TPLS) # ${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES set(${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES ${${PROJECT_NAME}_DEFINED_TPLS} ${${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES}) list(LENGTH ${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES ${PROJECT_NAME}_NUM_DEFINED_TOPLEVEL_PACKAGES) endmacro() # @FUNCTION: tribits_write_xml_dependency_files_if_supported() # # Usage:: # # tribits_write_xml_dependency_files_if_supported() # # Function that writes XML dependency files if support for that exists in this # instance of TriBITs. # # See `Function call tree for constructing package dependency graph`_ # function(tribits_write_xml_dependency_files_if_supported) set(TRIBITS_PROJECT_CI_SUPPORT_DIR "${${PROJECT_NAME}_TRIBITS_DIR}/${TRIBITS_CI_SUPPORT_DIR}") set(TRIBITS_DUMP_XML_DEPS_MODULE "${TRIBITS_PROJECT_CI_SUPPORT_DIR}/TribitsWriteXmlDependenciesFiles.cmake") if (EXISTS "${TRIBITS_DUMP_XML_DEPS_MODULE}") include(${TRIBITS_DUMP_XML_DEPS_MODULE}) tribits_write_xml_dependency_files() endif() endfunction() # Macro that sets ${PROJECT_NAME}_ALL_REPOSITORIES from # ${PROJECT_NAME}_PRE_REPOSITORIES and ${PROJECT_NAME}_EXTRA_REPOSITORIES if # it is not already set. Also, it replaces ',' with ';' in the latter. # # This function is needed in use cases where extra repos are used where the # extra repos are not read in through an ExtraRepositoriesList.cmake file and # instead are directly passed in by the user. # macro(tribits_set_all_extra_repositories) if ("${${PROJECT_NAME}_ALL_EXTRA_REPOSITORIES}" STREQUAL "") # Allow list to be separated by ',' instead of just by ';'. This is needed # by the unit test driver code split("${${PROJECT_NAME}_PRE_REPOSITORIES}" "," ${PROJECT_NAME}_PRE_REPOSITORIES) split("${${PROJECT_NAME}_EXTRA_REPOSITORIES}" "," ${PROJECT_NAME}_EXTRA_REPOSITORIES) set(${PROJECT_NAME}_ALL_EXTRA_REPOSITORIES ${${PROJECT_NAME}_PRE_REPOSITORIES} ${${PROJECT_NAME}_EXTRA_REPOSITORIES}) endif() endmacro() # Macro that processes the list of package and TPLs for the set of 'PRE' or # 'POST' extra repos. # macro(tribits_read_extra_repositories_lists) list(LENGTH ${PROJECT_NAME}_PRE_REPOSITORIES PRE_EXTRAREPOS_LEN) list(LENGTH ${PROJECT_NAME}_EXTRA_REPOSITORIES POST_EXTRAREPOS_LEN) math(EXPR ALL_EXTRAREPOS_LEN "${PRE_EXTRAREPOS_LEN} + ${POST_EXTRAREPOS_LEN}") # See if processing 'PRE' or 'POST' extra repos if (READ_PRE_OR_POST_EXRAREPOS STREQUAL "PRE") set(EXTRAREPO_IDX_START 0) set(EXTRAREPO_IDX_END ${PRE_EXTRAREPOS_LEN}) elseif (READ_PRE_OR_POST_EXRAREPOS STREQUAL "POST") set(EXTRAREPO_IDX_START ${PRE_EXTRAREPOS_LEN}) set(EXTRAREPO_IDX_END ${ALL_EXTRAREPOS_LEN}) else() message(FATAL_ERROR "Invalid value for READ_PRE_OR_POST_EXRAREPOS='${READ_PRE_OR_POST_EXRAREPOS}' ") endif() # NOTE: For some reason, we can't pass this argument to the function and # have it read. Instead, we have to pass it a local variable. I will never # understand CMake. set(EXTRAREPO_IDX ${EXTRAREPO_IDX_START}) while(EXTRAREPO_IDX LESS EXTRAREPO_IDX_END) list(GET ${PROJECT_NAME}_ALL_EXTRA_REPOSITORIES ${EXTRAREPO_IDX} EXTRA_REPO ) set(REPOSITORY_NAME ${EXTRA_REPO}) #print_var(EXTRA_REPO) #print_var(EXTRAREPO_IDX) #print_var(${PROJECT_NAME}_ALL_EXTRA_REPOSITORIES_HASPKGS) # Need to make sure this gets set because logic in Dependencies.cmake files # looks for the presents of this variable. set(${EXTRA_REPO}_SOURCE_DIR "${PROJECT_SOURCE_DIR}/${EXTRA_REPO}") if (${PROJECT_NAME}_VERBOSE_CONFIGURE) print_var(${EXTRA_REPO}_SOURCE_DIR) endif() # ToDo: TriBITS:73: Get ${EXTRA_REPO}_SOURCE_DIR from # ${PROJECT_NAME}_ALL_EXTRA_REPOSITORIES_DIR when it exists. set(EXTRAREPO_PACKSTAT "") if (${PROJECT_NAME}_ALL_EXTRA_REPOSITORIES_HASPKGS) list(GET ${PROJECT_NAME}_ALL_EXTRA_REPOSITORIES_HASPKGS ${EXTRAREPO_IDX} EXTRAREPO_PACKSTAT ) endif() if (EXTRAREPO_PACKSTAT STREQUAL NOPACKAGES) message("") message("Skipping reading packages and TPLs for ${READ_PRE_OR_POST_EXRAREPOS} extra repo ${EXTRA_REPO} because marked NOPACKAGES ... ") message("") # ToDo: TriBITS:73: Don't print the above message by default. It is # just clutter. else() # Read in the add-on TPLs from the extra repo set(${EXTRA_REPO}_TPLS_FILE "${${EXTRA_REPO}_SOURCE_DIR}/${${PROJECT_NAME}_EXTRA_TPLS_FILE_NAME}") print_var(${EXTRA_REPO}_SOURCE_DIR) print_var(${PROJECT_NAME}_EXTRA_TPLS_FILE_NAME) print_var(${EXTRA_REPO}_TPLS_FILE) message("") message("Reading list of ${READ_PRE_OR_POST_EXRAREPOS} extra TPLs from ${${EXTRA_REPO}_TPLS_FILE} ... ") message("") if (NOT EXISTS "${${EXTRA_REPO}_TPLS_FILE}") if (${PROJECT_NAME}_IGNORE_MISSING_EXTRA_REPOSITORIES) message("-- " "NOTE: Ignoring missing ${READ_PRE_OR_POST_EXRAREPOS} extra repo '${EXTRA_REPO}' TPLs list file '${${EXTRA_REPO}_TPLS_FILE}' on request!" ) else() message( SEND_ERROR "ERROR: Skipping missing ${READ_PRE_OR_POST_EXRAREPOS} extra repo '${EXTRA_REPO}' TPLs list file '${${EXTRA_REPO}_TPLS_FILE}'!") endif() else() tribits_trace_file_processing(REPOSITORY INCLUDE "${${EXTRA_REPO}_TPLS_FILE}") include("${${EXTRA_REPO}_TPLS_FILE}") set(APPEND_TO_TPLS_LIST TRUE) tribits_process_tpls_lists(${EXTRA_REPO} ${EXTRA_REPO}) endif() # Read in the add-on packages from the extra repo #print_var(${EXTRA_REPO}_PACKAGES_LIST_FILE) if (${EXTRA_REPO}_PACKAGES_LIST_FILE) set(EXTRAREPO_PACKAGES_FILE "${PROJECT_SOURCE_DIR}/${${EXTRA_REPO}_PACKAGES_LIST_FILE}") else() set(EXTRAREPO_PACKAGES_FILE "${${EXTRA_REPO}_SOURCE_DIR}/${${PROJECT_NAME}_EXTRA_PACKAGES_FILE_NAME}") endif() message("") message("Reading list of ${READ_PRE_OR_POST_EXRAREPOS} extra packages from ${EXTRAREPO_PACKAGES_FILE} ... ") message("") if (NOT EXISTS "${EXTRAREPO_PACKAGES_FILE}") if (${PROJECT_NAME}_IGNORE_MISSING_EXTRA_REPOSITORIES) message("-- " "NOTE: Ignoring missing ${READ_PRE_OR_POST_EXRAREPOS} extra repo '${EXTRA_REPO}' packages list file '${EXTRAREPO_PACKAGES_FILE}' on request!") else() message( SEND_ERROR "ERROR: Skipping missing ${READ_PRE_OR_POST_EXRAREPOS} extra repo '${EXTRA_REPO}' packages list file '${EXTRAREPO_PACKAGES_FILE}'!") # ToDo: TriBITS:73: Change to FATAL_ERROR to abort early endif() else() tribits_trace_file_processing(REPOSITORY INCLUDE "${EXTRAREPO_PACKAGES_FILE}") include("${EXTRAREPO_PACKAGES_FILE}") set(APPEND_TO_PACKAGES_LIST TRUE) tribits_process_packages_and_dirs_lists(${EXTRA_REPO} ${EXTRA_REPO}) endif() endif() math(EXPR EXTRAREPO_IDX "${EXTRAREPO_IDX}+1") endwhile() endmacro()