From ccb222aa7795785925392d257537308712fdbd6a Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Thu, 22 Dec 2022 14:52:10 -0700 Subject: [PATCH 01/45] Add printing of _PACAKGE_BUILD_STATUS (#63) The test for this is being added in the next commit. --- .../TribitsPrintEnabledPackagesLists.cmake | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index b49d96372..cce62d5dd 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -61,7 +61,10 @@ function(tribits_print_enables_before_adjust_package_enables) tribits_print_tpl_list_enable_status( "\nExplicitly enabled external packages/TPLs on input (by user)" ON FALSE) tribits_print_tpl_list_enable_status( - "\nExplicitly disabled external packages/TPLs on input (by user or by default)" OFF FALSE) + "\nExplicitly disabled external packages/TPLs on input (by user or by default)" + OFF FALSE) + tribits_print_package_build_status("\nInitial package build status:\n" + "-- Initial: " PRINT_ALL) endfunction() @@ -89,6 +92,8 @@ function(tribits_print_enables_after_adjust_package_enables) "\nFinal set of enabled external packages/TPLs" ON FALSE) tribits_print_tpl_list_enable_status( "\nFinal set of non-enabled external packages/TPLs" OFF TRUE) + tribits_print_package_build_status("\nFinal package build status (enabled only):\n" + "-- Final: " PRINT_ONLY_ENABLED) endfunction() @@ -183,3 +188,29 @@ function(tribits_print_prefix_string_and_list DOCSTRING LIST_TO_PRINT) message("${DOCSTRING}: ${NUM_ELEMENTS}") endif() endfunction() + + +# Print out the `_PACKAGE_BUILD_STATUS` vars +function(tribits_print_package_build_status summaryHeaderStr prefixStr + printEnabledOpt + ) + if (printEnabledOpt STREQUAL "PRINT_ALL") + set(printAll ON) + elseif (printEnabledOpt STREQUAL "PRINT_ONLY_ENABLED") + set(printAll OFF) + else() + message(FATAL_ERROR + "Error, invalid value for printEnabledOpt='${printEnabledOpt}'") + endif() + + if (${PROJECT_NAME}_DUMP_PACKAGE_BUILD_STATUS) + message("${summaryHeaderStr}") + foreach(packageName IN LISTS ${PROJECT_NAME}_DEFINED_PACKAGES) + tribits_get_package_enable_status(${packageName} packageEnable "") + if (printAll OR packageEnable) + message("${prefixStr}${packageName}_PACKAGE_BUILD_STATUS=" + "${${packageName}_PACKAGE_BUILD_STATUS}") + endif() + endforeach() + endif() +endfunction() From afcea28b20127eb94334c57d9062d84dc2d9431e Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Thu, 12 Jan 2023 07:44:36 -0700 Subject: [PATCH 02/45] Add documentation for _SUBPACKAGES varaible (#63) This was not documented anywhere. --- tribits/doc/guides/TribitsGuidesBody.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index 3b790406c..9351b0bfd 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -1798,6 +1798,17 @@ defined: what contexts the package is enabled or not for testing-related purposes (see `Nested Layers of TriBITS Project Testing`_) + .. _${PACKAGE_NAME}_SUBPACKAGES: + + ``${PACKAGE_NAME}_SUBPACKAGES`` + + Defines the list of subpackage names for a top-level parent package. This + gives the unique subpackage name without the parent package prefix. For + example, the `ReducedMockTrilinos`_ package ``Thyra`` has the subpackages + ``CoreLibs``, ``GoodStuff``, etc. (which forms the full package names + ``ThyraCoreLibs``, ``ThyraGoodStuff``, etc.). If a top-level package is + not broken down into subpackages, then this list is empty. + .. _TriBITS Package Cache Variables: In addition, the following user-settable **TriBITS Package Cache Variables** From ee5f2ce75a364dd3d5d71f4d9129e09464a3ed1a Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 13 Jan 2023 09:12:13 -0700 Subject: [PATCH 03/45] Small doc update (#63) --- tribits/core/package_arch/TribitsAdjustPackageEnables.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake index 53bbb1f2b..84135b1a1 100644 --- a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake +++ b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake @@ -276,8 +276,7 @@ endmacro() # @MACRO: tribits_sweep_backward_enable_upstream_packages() # -# Sweep backwards and enable required and (optionally) optional upstream -# packages. +# Sweep backwards and enable required (and optional) upstream packages. # # This sets the final value for: # From 0fc3973f15d09ae43e79c950babaed056ecd7d1c Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 16 Jan 2023 17:02:45 -0700 Subject: [PATCH 04/45] Change tribits_print_prefix_string_and_list() to pass in list name (#63) This should be a little more efficient and it uses less text to call it --- .../TribitsPrintEnabledPackagesLists.cmake | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index cce62d5dd..7cb04f08f 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -80,10 +80,10 @@ endfunction() function(tribits_print_enables_after_adjust_package_enables) tribits_print_prefix_string_and_list( "\nFinal set of enabled top-level packages" - "${${PROJECT_NAME}_ENABLED_INTERNAL_TOPLEVEL_PACKAGES}") + ${PROJECT_NAME}_ENABLED_INTERNAL_TOPLEVEL_PACKAGES) tribits_print_prefix_string_and_list( "\nFinal set of enabled packages" - "${${PROJECT_NAME}_ENABLED_INTERNAL_PACKAGES}") + ${PROJECT_NAME}_ENABLED_INTERNAL_PACKAGES) tribits_print_internal_toplevel_package_list_enable_status( "\nFinal set of non-enabled top-level packages" OFF TRUE) tribits_print_internal_package_list_enable_status( @@ -131,7 +131,7 @@ function(tribits_print_internal_package_list_enable_status internalPackagesEnableStatusList "") endif() tribits_print_prefix_string_and_list("${DOCSTRING}" - "${internalPackagesEnableStatusList}") + internalPackagesEnableStatusList) endfunction() @@ -151,7 +151,7 @@ function(tribits_print_tpl_list_enable_status DOCSTRING ENABLED_FLAG INCLUDE_ tribits_get_sublist_nonenabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") endif() - tribits_print_prefix_string_and_list("${DOCSTRING}" "${tplsEnableStatusList}") + tribits_print_prefix_string_and_list("${DOCSTRING}" tplsEnableStatusList) endfunction() @@ -173,19 +173,19 @@ function(tribits_print_packages_list_enable_status_from_var PACKAGES_LIST_VAR tribits_get_sublist_nonenabled(${PACKAGES_LIST_VAR} enableStatusList "") endif() - tribits_print_prefix_string_and_list("${DOCSTRING}" "${enableStatusList}") + tribits_print_prefix_string_and_list("${DOCSTRING}" enableStatusList) endfunction() # Print out a list with white-space separators with an initial doc string # -function(tribits_print_prefix_string_and_list DOCSTRING LIST_TO_PRINT) - string(REPLACE ";" " " LIST_TO_PRINT_STR "${LIST_TO_PRINT}") - list(LENGTH LIST_TO_PRINT NUM_ELEMENTS) - if (NUM_ELEMENTS GREATER "0") - message("${DOCSTRING}: ${LIST_TO_PRINT_STR} ${NUM_ELEMENTS}") +function(tribits_print_prefix_string_and_list docString listNameToPrint) + string(REPLACE ";" " " listToPrintStr "${${listNameToPrint}}") + list(LENGTH ${listNameToPrint} numElements) + if (numElements GREATER "0") + message("${docString}: ${listToPrintStr} ${numElements}") else() - message("${DOCSTRING}: ${NUM_ELEMENTS}") + message("${docString}: ${numElements}") endif() endfunction() From f3f935677c6a9313d92e95452cd6760b3b232f39 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 24 Jan 2023 10:41:51 -0700 Subject: [PATCH 05/45] WIP: Add basic logic for setting _PACKAGE_BUILD_STATUS=EXTERNAL (#63) This sets an INTERNAL package to EXTERNAL if TPL_ENABLE_=ON or if a downstream dependent package is EXTERNAL. NOTE: This is missing the changes needed to affect the processing of internal vs. external packages but this should complete the dependency-based logic on what packages need to be treated as EXTERNAL based on the setting of TPL_ENABLE_=ON. This also changes the logic so that the backward sweep to enable upstream external packages only does so explicitly if the downstream dependent package has _SOURCE_DIR!="" so it if it was initially defined as an internal package then it will not change the enable/disable behavior. This is important because we don't (yet) want an external TPL enable to trigger the enable of an upstream TPL. We only want that logic to apply to initially internal packages. (The dependency logic can be pretty confusing if we are not careful.) I also removed the documentation that setting: -D _ROOT= will make an initially internal package be treated as an external package/TPL. I think that is too subtle. The user can still set to change where find_package() will find the Config.cmake file, but that will be the only impact of setting _ROOT. (We may change our minds on this latter and the logic for making that decision is pretty encapsulated.) I had to make some tweaks to get this logic to work correctly: * tribits_get_package_enable_status(): Changed logic to first just look for non-empty vars ${PROJECT_NAME}_ENABLE_${packageName} and TPL_ENABLE_${packageName} to determine if the package should be treated as internal or external. If both of those are null, then use ${packageName}_PACKAGE_BUILD_STATUS. This is needed for the logic where ${packageName}_PACKAGE_BUILD_STATUS is not changed from INTERNAL to EXTERNAL until later in the process. --- test/core/DependencyUnitTests/CMakeLists.txt | 294 ++++++++++++++++++ .../TribitsAdjustPackageEnables.cmake | 207 +++++++++++- .../TribitsGetPackageEnableStatus.cmake | 23 +- ...itsSystemDataStructuresMacrosFunctions.rst | 13 +- 4 files changed, 508 insertions(+), 29 deletions(-) diff --git a/test/core/DependencyUnitTests/CMakeLists.txt b/test/core/DependencyUnitTests/CMakeLists.txt index df4e5ce95..5719366d7 100644 --- a/test/core/DependencyUnitTests/CMakeLists.txt +++ b/test/core/DependencyUnitTests/CMakeLists.txt @@ -631,6 +631,155 @@ create_reduced_dependency_handling_test_case( # HDF5 (and that is a valid configuration when Netcdf is built without HDF5). +# +# Test treating internal packages as TPLs with ReducedMockTrilinos +# + + +create_reduced_dependency_handling_test_case( + ST_TplEnableRTOpOn_EnableAllPackages_EnableTests + ARGS + -DTPL_ENABLE_RTOp=ON + -DTrilinos_ENABLE_ALL_PACKAGES=ON + -DTrilinos_ENABLE_SECONDARY_TESTED_CODE=ON + -DTrilinos_ENABLE_TESTS=ON + -DTrilinos_DUMP_PACKAGE_BUILD_STATUS=ON + PASS_REGULAR_EXPRESSION_ALL + + "Initial package build status:" + "-- Initial: MPI_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Initial: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Initial: LAPACK_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Initial: Boost_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Initial: UMFPACK_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Initial: AMD_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Initial: PETSC_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Initial: Teuchos_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: RTOp_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: Epetra_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: Triutils_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: EpetraExt_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: ThyraCoreLibs_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: ThyraGoodStuff_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: ThyraCrazyStuff_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: ThyraEpetra_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: ThyraEpetraExt_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Initial: Thyra_PACKAGE_BUILD_STATUS=INTERNAL" + + "Adjust the set of internal and external packages:" + "-- Treating internal package RTOp as EXTERNAL because TPL_ENABLE_RTOp=ON" + "-- Treating internal package Teuchos as EXTERNAL because downstream package RTOp being treated as EXTERNAL" + + "Final package build status [(]enabled only[)]:" + "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: LAPACK_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Teuchos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: RTOp_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Epetra_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Triutils_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: EpetraExt_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: ThyraCoreLibs_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: ThyraGoodStuff_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: ThyraEpetra_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: ThyraEpetraExt_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Thyra_PACKAGE_BUILD_STATUS=INTERNAL" + + "Getting information for all enabled external packages/TPLs ..." + "Processing enabled external package/TPL: BLAS [(]enabled by Epetra, disable with -DTPL_ENABLE_BLAS=OFF[)]" + "Processing enabled external package/TPL: LAPACK [(]enabled by Epetra, disable with -DTPL_ENABLE_LAPACK=OFF[)]" +# "Processing enabled external package/TPL: Teuchos [(]enabled by RTOp, disable with -DTPL_ENABLE_Teuchos=OFF[)]" +# "Processing enabled external package/TPL: RTOp [(]enabled by TPL_ENABLE_RTOp=ON[)]" +# ToDo: Get above to be printed out! + + "Configuring individual enabled Trilinos packages ..." + "Processing enabled top-level package: Epetra [(]Libs, Tests, Examples[)]" + "Processing enabled top-level package: Triutils [(]Libs, Tests, Examples[)]" + "Processing enabled top-level package: EpetraExt [(]Libs, Tests, Examples[)]" + "Processing enabled top-level package: Thyra [(]CoreLibs, GoodStuff, Epetra, EpetraExt, Tests, Examples[)]" + + ) + + +create_reduced_dependency_handling_test_case( + ST_TplEnableThyraCoreLibsOn_EnableAllPackages_EnableTests + ARGS + -DTPL_ENABLE_ThyraCoreLibs=ON + -DTrilinos_ENABLE_ALL_PACKAGES=ON + -DTrilinos_ENABLE_SECONDARY_TESTED_CODE=ON + -DTrilinos_ENABLE_TESTS=ON + -DTrilinos_DUMP_PACKAGE_BUILD_STATUS=ON + PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package Thyra as EXTERNAL because subpackage ThyraCoreLibs being treated as EXTERNAL [(]TPL_ENABLE_ThyraCoreLibs=ON[)]" + "-- Treating internal package ThyraCoreLibs as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraGoodStuff as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraEpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraEpetraExt as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package EpetraExt as EXTERNAL because downstream package ThyraEpetraExt being treated as EXTERNAL" + "-- Treating internal package Epetra as EXTERNAL because downstream package ThyraEpetra being treated as EXTERNAL" + "-- Treating internal package Teuchos as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package Triutils as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + + "Final package build status [(]enabled only[)]:" + "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: LAPACK_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Teuchos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: RTOp_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Epetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Triutils_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: EpetraExt_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraCoreLibs_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraGoodStuff_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraEpetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraEpetraExt_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Thyra_PACKAGE_BUILD_STATUS=EXTERNAL" + + "Final set of enabled top-level packages: Teuchos RTOp Epetra Triutils EpetraExt Thyra 6" + "Final set of enabled packages: Teuchos RTOp Epetra Triutils EpetraExt ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt Thyra 10" + + ) + + +create_reduced_dependency_handling_test_case( + TplEnableThyraCoreLibsOn + ARGS + -DTPL_ENABLE_ThyraCoreLibs=ON + -DTrilinos_DUMP_PACKAGE_BUILD_STATUS=ON + PASS_REGULAR_EXPRESSION_ALL + "Enabling all required [(]and optional since Trilinos_ENABLE_ALL_OPTIONAL_PACKAGES=ON[)] upstream packages for current set of enabled packages [(]Trilinos_ENABLE_SECONDARY_TESTED_CODE=OFF[)] ..." + "-- Setting Trilinos_ENABLE_Teuchos=ON because ThyraCoreLibs has a required dependence on Teuchos" + "-- Setting Trilinos_ENABLE_RTOp=ON because ThyraCoreLibs has a required dependence on RTOp" + "-- Setting TPL_ENABLE_BLAS=ON because Teuchos has a required dependence on BLAS" + "-- Setting TPL_ENABLE_LAPACK=ON because Teuchos has a required dependence on LAPACK" + + "Enabling the shell of non-enabled parent packages [(]mostly for show[)] that have at least one subpackage enabled ..." + "-- Setting Trilinos_ENABLE_Thyra=ON because TPL_ENABLE_ThyraCoreLibs=ON" + + "Adjust the set of internal and external packages:" + "-- Treating internal package Thyra as EXTERNAL because subpackage ThyraCoreLibs being treated as EXTERNAL [(]TPL_ENABLE_ThyraCoreLibs=ON[)]" + "-- Treating internal package ThyraCoreLibs as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package Teuchos as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + + "Final package build status [(]enabled only[)]:" + "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: LAPACK_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Teuchos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: RTOp_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraCoreLibs_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Thyra_PACKAGE_BUILD_STATUS=EXTERNAL" + + "Final set of enabled top-level packages: Teuchos RTOp Thyra 3" + "Final set of enabled packages: Teuchos RTOp ThyraCoreLibs Thyra 4" + "Final set of enabled external packages/TPLs: BLAS LAPACK 2" + + ) + + +# ??? + + ##################################################################### # # Unit tests for dependency handling for full set of packages @@ -1626,3 +1775,148 @@ create_dependency_handling_test_case( "Final set of enabled top-level packages: Teuchos RTOp Epetra Zoltan Triutils Tpetra EpetraExt Thyra Isorropia AztecOO Galeri Amesos Ifpack ML Stratimikos Teko ExtraPack 17" "Final set of non-enabled top-level packages: TrilinosFramework Shards Stokhos Sacado Intrepid Belos RBGen Phalanx Panzer Stalix 10" ) + + +# +# Test treating internal packages as TPLs with MockTrilinos +# + +create_dependency_handling_test_case( + ST_TplEnableThyraCoreLibsOn_EnableAllPackages_EnableTests + ARGS + -DTPL_ENABLE_ThyraCoreLibs=ON + -DTrilinos_ENABLE_ALL_PACKAGES=ON + -DTrilinos_ENABLE_SECONDARY_TESTED_CODE=ON + -DTrilinos_ENABLE_TESTS=ON + -DTrilinos_DUMP_PACKAGE_BUILD_STATUS=ON + PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package Thyra as EXTERNAL because subpackage ThyraCoreLibs being treated as EXTERNAL [(]TPL_ENABLE_ThyraCoreLibs=ON[)]" + "-- Treating internal package ThyraCoreLibs as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraGoodStuff as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraEpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraEpetraExt as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraTpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package Tpetra as EXTERNAL because downstream package ThyraTpetra being treated as EXTERNAL" + "-- Treating internal package EpetraExt as EXTERNAL because downstream package ThyraEpetraExt being treated as EXTERNAL" + "-- Treating internal package Epetra as EXTERNAL because downstream package ThyraEpetra being treated as EXTERNAL" + "-- Treating internal package Teuchos as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package Triutils as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + "-- Treating internal package Zoltan as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + + "Final package build status [(]enabled only[)]:" + "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: LAPACK_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Boost_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: DUMMY_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: TrilinosFramework_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Teuchos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: RTOp_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Epetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Zoltan_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Shards_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Triutils_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Tpetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: EpetraExt_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Sacado_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: ThyraCoreLibs_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraGoodStuff_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraEpetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraEpetraExt_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraTpetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Thyra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Isorropia_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: AztecOO_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Galeri_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Amesos_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Intrepid_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Ifpack_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: ML_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Belos_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Stratimikos_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: RBGen_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Phalanx_PACKAGE_BUILD_STATUS=INTERNAL" + + "Final set of enabled top-level packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack ML Belos Stratimikos RBGen Phalanx 22" + "Final set of enabled packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt ThyraTpetra Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack ML Belos Stratimikos RBGen Phalanx 27" + "Final set of enabled external packages/TPLs: BLAS LAPACK Boost DUMMY 4" + + ) + + +create_dependency_handling_test_case( + ST_TplEnableStratimikosOn_EnableMLOff_EnableAllPackages_EnableTests + ARGS + -DTPL_ENABLE_Stratimikos=ON + -DTrilinos_ENABLE_ML=OFF + -DTrilinos_ENABLE_ALL_PACKAGES=ON + -DTrilinos_ENABLE_SECONDARY_TESTED_CODE=ON + -DTrilinos_ENABLE_TESTS=ON + -DTrilinos_DUMP_PACKAGE_BUILD_STATUS=ON + PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package Stratimikos as EXTERNAL because TPL_ENABLE_Stratimikos=ON" + "-- Treating internal package ThyraEpetraExt as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package ThyraCoreLibs as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Amesos as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package AztecOO as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Belos as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Ifpack as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Teuchos as EXTERNAL because downstream package Belos being treated as EXTERNAL" + "-- Treating internal package Epetra as EXTERNAL because downstream package Belos being treated as EXTERNAL" + "-- Treating internal package Tpetra as EXTERNAL because downstream package Belos being treated as EXTERNAL" + "-- Treating internal package EpetraExt as EXTERNAL because downstream package Amesos being treated as EXTERNAL" + "-- Treating internal package Triutils as EXTERNAL because downstream package AztecOO being treated as EXTERNAL" + "-- Treating internal package Thyra as EXTERNAL because subpackage ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package ThyraGoodStuff as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraEpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraTpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package Zoltan as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + + "Final package build status [(]enabled only[)]:" + "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: LAPACK_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Boost_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: DUMMY_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: TrilinosFramework_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Teuchos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: RTOp_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Epetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Zoltan_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Shards_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Triutils_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Tpetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: EpetraExt_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Sacado_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: ThyraCoreLibs_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraGoodStuff_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraEpetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraEpetraExt_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: ThyraTpetra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Thyra_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Isorropia_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: AztecOO_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Galeri_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Amesos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Intrepid_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Ifpack_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Belos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: Stratimikos_PACKAGE_BUILD_STATUS=EXTERNAL" + "-- Final: RBGen_PACKAGE_BUILD_STATUS=INTERNAL" + "-- Final: Phalanx_PACKAGE_BUILD_STATUS=INTERNAL" + + "Final set of enabled top-level packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack Belos Stratimikos RBGen Phalanx 21" + "Final set of enabled packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt ThyraTpetra Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack Belos Stratimikos RBGen Phalanx 26" + "Final set of non-enabled top-level packages: Stokhos ML Panzer 3" + "Final set of enabled external packages/TPLs: BLAS LAPACK Boost DUMMY 4" + + ) +# NOTE: The above test implicitly makes ThyraCoreLibs and ThyraEpetraExt +# EXTERNAL due to Stratimikos being EXTERNAL and makes sure that all of the +# Thyra subpackages get changed to EXTERNAL. This above test also disables ML +# to turn off the dependency between Stratimikos and Isorropia so that the +# Isorropia package stays INTERNAL. That is, we don't want to make more +# packages EXTERNAL that we need to based on the final set of enables and +# disables and the enabled optional dependencies between packages. diff --git a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake index 84135b1a1..778e0aea9 100644 --- a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake +++ b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake @@ -87,6 +87,7 @@ macro(tribits_adjust_package_enables) tribits_sweep_backward_enable_upstream_packages() tribits_set_cache_vars_for_current_enabled_packages() tribits_do_final_parent_packages_enables_for_subpackage_enables() + tribits_adjust_internal_external_packages() tribits_setup_enabled_lists_and_pkg_idxs() tribits_setup_direct_packages_dependencies_lists_and_lib_required_enable_vars() tribits_print_direct_packages_dependencies_lists() @@ -350,6 +351,30 @@ macro(tribits_do_final_parent_packages_enables_for_subpackage_enables) endmacro() +# @MACRO: tribits_adjust_internal_external_packages() +# +# Macro to adjust the set of internal and external packages by changing +# `_PACKAGE_BUILD_STATUS`. +# +# This macro sweeps backwards over the dependency graph setting. +# +# NOTE: This is called **after** all of the logic that determines what +# packages are enabled or disabled. This is because we don't want to change +# the enable/disable logic when one or more initially internal packages are +# made external. We are going to just assume that if an initially internal +# package that is declared external should be disabled, then the user will +# need to make that decision explicitly. +# +macro(tribits_adjust_internal_external_packages) + tribits_create_reverse_list(${PROJECT_NAME}_DEFINED_PACKAGES + ${PROJECT_NAME}_REVERSE_DEFINED_PACKAGES) + message("\nAdjust the set of internal and external packages:\n") + foreach(packageName IN LISTS ${PROJECT_NAME}_REVERSE_DEFINED_PACKAGES) + tribits_set_package_and_related_upstream_packages_to_external(${packageName}) + endforeach() +endmacro() + + # Macro that sets up the basic lists of enabled packages and packages. # macro(tribits_setup_enabled_lists_and_pkg_idxs) @@ -662,7 +687,9 @@ endmacro() # macro(tribits_enable_upstream_packages packageName) - if (${PROJECT_NAME}_ENABLE_${packageName}) + tribits_get_package_enable_status(${packageName} packageEnable packageEnableVar) + + if (packageEnable) foreach(depPkg IN LISTS ${packageName}_LIB_DEFINED_DEPENDENCIES) tribits_private_enable_dep_package(${packageName} ${depPkg} LIB) @@ -768,13 +795,15 @@ endmacro() macro(tribits_enable_parent_package_for_subpackage_enables toplevelPackageName) foreach(tap2_subPkgName IN LISTS ${toplevelPackageName}_SUBPACKAGES) set(subpkgFullName ${toplevelPackageName}${tap2_subPkgName}) - if (${PROJECT_NAME}_ENABLE_${subpkgFullName} - AND (NOT ${PROJECT_NAME}_ENABLE_${toplevelPackageName}) - ) + tribits_get_package_enable_status(${toplevelPackageName} + toplevelPackageEnable toplevelPackageEnableVarName) + tribits_get_package_enable_status(${subpkgFullName} + subpkgEnable subpkgEnableVarName) + if (subpkgEnable AND (NOT toplevelPackageEnable)) message("-- " - "Setting ${PROJECT_NAME}_ENABLE_${toplevelPackageName}=ON" - " because ${PROJECT_NAME}_ENABLE_${subpkgFullName}=ON") - set(${PROJECT_NAME}_ENABLE_${toplevelPackageName} ON) + "Setting ${toplevelPackageEnableVarName}=ON because" + " ${subpkgEnableVarName}=${subpkgEnable}") + set(${toplevelPackageEnableVarName} ON) tribits_set_parent_package_subpackage_enable_for_enabled_subpackages( ${toplevelPackageName}) tribits_set_parent_package_test_example_enable_for_enabled_subpackages( @@ -793,6 +822,49 @@ macro(tribits_enable_parent_package_for_subpackage_enables toplevelPackageName) endmacro() +# Macro that sets $``{packageName}_PACKAGE_BUILD_STATUS=EXTERNAL and direct +# upstream dependent packages ``${depPkg}_PACKAGE_BUILD_STATUS=EXTERNAL`` if +# required. +# +# * Set an INTERNAL package as EXTERNAL if ``TPL_ENABLE_${packageName}`` is +# ``TRUE`` +# +# * Set a top-level package to EXTERNAL if any of its subpackages are EXTERNAL +# (or ``TPL_ENABLE_${subpkgFullName}`` is TRUE). +# +# This macro must be called in a backward/reverse sweep over the dependency +# graph to work correctly. It sets upstream packages as EXTERNAL if the given +# downstream package ```` is EXTERNAL. There is also special +# logic for handling a package that has subpackages. That is, if any +# subpackage of ```` is determined is EXTERNAL, then the parent +# package is set to EXTERNAL and all of the other subpackages in parent +# package ```` are set as EXTERNAL as well. (We don't allow a +# subset of subpackages in a parent package to be EXTERNAL and the other +# subpackages to be INTERNAL. That would be way too complicated to implement +# and be way too confusing for implementors and users.) +# +macro(tribits_set_package_and_related_upstream_packages_to_external packageName) + + tribits_set_parent_package_external_if_subpackage_external(${packageName} + subpackageTriggeredParentPackageExternal) + + tribits_set_package_to_external_if_requested_by_user(${packageName}) + + tribits_set_upstream_dep_packages_as_external(${packageName} + ${subpackageTriggeredParentPackageExternal}) + +endmacro() +# NOTE: In the above macro, if ${packageName} is made EXTERNAL because it one +# of its subpackages is considered EXTERNAL, then the loop over all of the +# package's upstream dependencies listed in +# ${packageName}_LIB_DEFINED_DEPENDENCIES results in all of the other +# subpackages in that package to also be treated as external. (I.e., there is +# no need for a special loop over subpackages for the parent package. And the +# only direct dependencies for a parent package should be its subpackages. If +# that is not the case, then, technically, this would be setting more packages +# as EXTERNAL than need to be.) + + # Macro that sets up the flat list of direct package dependencies and enabled # package dependencies and sets ${packageName}_ENABLE_${depPkg} for LIB # dependencies @@ -1048,9 +1120,11 @@ macro(tribits_private_enable_dep_package packageName depPkgName libOrTest) tribits_get_package_enable_status(${depPkgName} depPkgEnable depPkgEnableVar) if (depPkgEnable) #message("The package is already enabled so there is nothing to enable!") - elseif (${depPkgEnableVar} STREQUAL "") + elseif ("${depPkgEnable}" STREQUAL "") set(tpedp_enableDepPkg "") - if (${packageName}_${libOrTest}_DEP_REQUIRED_${depPkgName}) + if (${packageName}_${libOrTest}_DEP_REQUIRED_${depPkgName} + AND (NOT "${${packageName}_SOURCE_DIR}" STREQUAL "") + ) message("-- " "Setting ${depPkgEnableVar}=ON" " because ${packageName} has a required dependence on ${depPkgName}") set(tpedp_enableDepPkg ON) @@ -1163,6 +1237,84 @@ macro(tribits_private_add_optional_package_enable packageName optionalDepPkgNa endmacro() +# Set the parent package as EXTERNAL if any of its subpackages are being +# treated as EXTERNAL and return bool if that is the case. +# +# On output, ``_PACKAGE_BUILD_STATUS`` will have been set +# to ``EXTERNAL`` if the returned var +# ``subpackageTriggeredParentPackageExternalOut`` is ``TRUE``. +# +macro(tribits_set_parent_package_external_if_subpackage_external parentPackageName + subpackageTriggeredParentPackageExternalOut + ) + + set(subpackageTriggeredParentPackageExternal FALSE) + + if (NOT ${parentPackageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") + foreach (tap2_subPkgName IN LISTS ${parentPackageName}_SUBPACKAGES) + set(subpkgFullName ${parentPackageName}${tap2_subPkgName}) + tribits_package_is_external(${subpkgFullName} subpkgIsExternal) + if (subpkgIsExternal) + set(becauseMsgStr "subpackage ${subpkgFullName} being treated as EXTERNAL") + if (TPL_ENABLE_${subpkgFullName}) + string(APPEND becauseMsgStr + " (TPL_ENABLE_${subpkgFullName}=${TPL_ENABLE_${subpkgFullName}})") + endif() + tribits_set_internal_package_to_external(${parentPackageName} "${becauseMsgStr}") + set(subpackageTriggeredParentPackageExternal TRUE) + break() + endif() + endforeach() + endif() + + set(${subpackageTriggeredParentPackageExternalOut} + ${subpackageTriggeredParentPackageExternal}) + +endmacro() + + +# Macro that sets ``_PACKAGE_BUILD_STATUS`` to ``EXTERNAL`` if +# requested by the user (e.g. by setting ``TPL_ENABLE_``). +# +macro(tribits_set_package_to_external_if_requested_by_user packageName) + if (NOT ${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") + if (TPL_ENABLE_${packageName}) + tribits_set_internal_package_to_external(${packageName} + "TPL_ENABLE_${packageName}=${TPL_ENABLE_${packageName}}") + endif() + endif() +endmacro() + + +# Macro that sets all of the direct upstream dependent packages as EXTERNAL if +# they should be. +# +# NOTE: We only bother setting upstream dependencies as EXTERNAL if the +# package ```` is enabled or if it is a parent package (enabled +# or not) where at least one of its subpackages is enabled and is being +# treated as EXTERNAL. (In the latter case, any subpackages that are not +# enabled will still be set as EXTERNAL.) +# +macro(tribits_set_upstream_dep_packages_as_external packageName + subpackageTriggeredParentPackageExternal + ) + + tribits_get_package_enable_status(${packageName} packageEnable "") + + if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") + foreach(depPkg IN LISTS ${packageName}_LIB_DEFINED_DEPENDENCIES) + if ((NOT ${depPkg}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") AND + (subpackageTriggeredParentPackageExternal OR packageEnable) + ) + tribits_set_internal_package_to_external(${depPkg} + "downstream package ${packageName} being treated as EXTERNAL") + endif() + endforeach() + endif() + +endmacro() + + # Macro that sets ``_ENABLE_=ON`` if not already # enabled for all enabled subpackages of a parent package. # @@ -1203,4 +1355,41 @@ macro(tribits_set_parent_package_test_example_enable_for_enabled_subpackages endmacro() +# Macro that sets an internal package to EXTERNAL and print so and why (if the +# package is actually enabled) +# +# Usage:: +# +# tribits_set_internal_package_to_external( "" +# "" ...) +# +# This always sets ``_PACKAGE_BUILD_STATUS=EXTERNAL`` but only +# prints the message if ```` is enabled. +# +macro(tribits_set_internal_package_to_external packageName) + tribits_get_package_enable_status(${packageName} packageEnable packageEnableVar) + if (packageEnable) + message("-- " + "Treating internal package ${packageName} as EXTERNAL because" + " " ${ARGN}) + endif() + set(${packageName}_PACKAGE_BUILD_STATUS EXTERNAL) +endmacro() + + +# Function to return if is to be treated as an EXTERNAL package +# in processing of the package +# +function(tribits_package_is_external packageName packageIsExternalOut) + if (TPL_ENABLE_${packageName}) + set(packageIsExternal TRUE) + elseif (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") + set(packageIsExternal TRUE) + else() + set(packageIsExternal FALSE) + endif() + set(${packageIsExternalOut} ${packageIsExternal} PARENT_SCOPE) +endfunction() + + # LocalWords: tribits TriBITS foreach endmacro endfunction diff --git a/tribits/core/package_arch/TribitsGetPackageEnableStatus.cmake b/tribits/core/package_arch/TribitsGetPackageEnableStatus.cmake index 3fac736a7..3d7c425d7 100644 --- a/tribits/core/package_arch/TribitsGetPackageEnableStatus.cmake +++ b/tribits/core/package_arch/TribitsGetPackageEnableStatus.cmake @@ -69,24 +69,19 @@ function(tribits_get_package_enable_status packageName packageEnableOut tribits_assert_package_enable_status(${packageName}) # Determine which variable, if any, to extract enable status from set(packageEnableVarName "") - if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "INTERNAL") + if (NOT "${${PROJECT_NAME}_ENABLE_${packageName}}" STREQUAL "") + set(packageEnableVarName ${PROJECT_NAME}_ENABLE_${packageName}) + elseif (NOT "${TPL_ENABLE_${packageName}}" STREQUAL "") + set(packageEnableVarName TPL_ENABLE_${packageName}) + elseif (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "INTERNAL") set(packageEnableVarName ${PROJECT_NAME}_ENABLE_${packageName}) elseif (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") - if (NOT "${TPL_ENABLE_${packageName}}" STREQUAL "") - set(packageEnableVarName TPL_ENABLE_${packageName}) - elseif (NOT "${${PROJECT_NAME}_ENABLE_${packageName}}" STREQUAL "") - set(packageEnableVarName ${PROJECT_NAME}_ENABLE_${packageName}) - else() - # If neither is set, select the default var TPL name - set(packageEnableVarName TPL_ENABLE_${packageName}) - endif() - endif() - if (packageEnableVarName) - set(packageEnable ${${packageEnableVarName}}) + set(packageEnableVarName TPL_ENABLE_${packageName}) else() - set(packageEnable "") + message(FATAL_ERROR "Could not determine status of package ${packageName}") endif() - # Set output args + # Extract the enable status, set output args + set(packageEnable ${${packageEnableVarName}}) if (packageEnableOut) set(${packageEnableOut} ${packageEnable} PARENT_SCOPE) endif() diff --git a/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst b/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst index f4661403f..f207dbe3a 100644 --- a/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst +++ b/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst @@ -428,7 +428,7 @@ Logic`_. Determining if a package is internal or external ++++++++++++++++++++++++++++++++++++++++++++++++ -As mentioned above, some subset of packages listed in +As mentioned above, some subset of initially internal packages listed in `${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES`_ (which all have ``${PACKAGE_NAME}_SOURCE_DIR != ""``) may be chosen to be external packages. Packages that could be built internally may be chosen to be treated as @@ -437,10 +437,6 @@ external packages (and therefore located on the system using -D TPL_ENABLE_=ON -or:: - - -D _ROOT= - .. _${PACKAGE_NAME}_PACKAGE_BUILD_STATUS: .. _${TPL_NAME}_PACKAGE_BUILD_STATUS: @@ -449,10 +445,15 @@ external package is provided by the variable:: ${PACKAGE_NAME}_PACKAGE_BUILD_STATUS=[INTERNAL|EXTERNAL] +(NOT: The value of ``${PACKAGE_NAME}_PACKAGE_BUILD_STATUS`` is only changed +after all of the enable/disable dependency logic is complete.) + As a result, every other package upstream from any of these ```` packages must therefore also be treated as external packages automatically and will have -``${PACKAGE_NAME}_PACKAGE_BUILD_STATUS=EXTERNAL`` set accordingly. +``${PACKAGE_NAME}_PACKAGE_BUILD_STATUS=EXTERNAL`` set accordingly. Also, if +any subpackage is determined to be EXTERNAL, then the parent package of that +subpackage and every other peer subpackage will also be set to EXTERNAL. Other package-related variables From 09e61e5da5195ec7f4e948ea043e8bfb36db12df Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 18 Jan 2023 08:19:10 -0700 Subject: [PATCH 06/45] WIP: rename some local vars away from UPPPER-CASE (#63) --- .../TribitsPrintEnabledPackagesLists.cmake | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index 7cb04f08f..bbb3c4380 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -100,80 +100,80 @@ endfunction() # Function that prints the current set of enabled internal top-level packages # function(tribits_print_internal_toplevel_package_list_enable_status - DOCSTRING ENABLED_FLAG INCLUDE_EMPTY + docString enabledFlag includeEmpty ) tribits_print_packages_list_enable_status_from_var( ${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES - "${DOCSTRING}" ${ENABLED_FLAG} ${INCLUDE_EMPTY} ) + "${docString}" ${enabledFlag} ${includeEmpty} ) endfunction() # Prints the current set of enabled/disabled internal packages # function(tribits_print_internal_package_list_enable_status - DOCSTRING ENABLED_FLAG INCLUDE_EMPTY + docString enabledFlag includeEmpty ) - if (ENABLED_FLAG AND NOT INCLUDE_EMPTY) + if (enabledFlag AND NOT includeEmpty) tribits_get_sublist_enabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES internalPackagesEnableStatusList "") - elseif (ENABLED_FLAG AND INCLUDE_EMPTY) + elseif (enabledFlag AND includeEmpty) tribits_get_sublist_nondisabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES ${PROJECT_NAME} internalPackagesEnableStatusList "") - elseif (NOT ENABLED_FLAG AND NOT INCLUDE_EMPTY) + elseif (NOT enabledFlag AND NOT includeEmpty) tribits_get_sublist_disabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES internalPackagesEnableStatusList "") - else() # NOT ENABLED_FLAG AND INCLUDE_EMPTY + else() # NOT enabledFlag AND includeEmpty tribits_get_sublist_nonenabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES internalPackagesEnableStatusList "") endif() - tribits_print_prefix_string_and_list("${DOCSTRING}" + tribits_print_prefix_string_and_list("${docString}" internalPackagesEnableStatusList) endfunction() # Print the current set of enabled/disabled TPLs # -function(tribits_print_tpl_list_enable_status DOCSTRING ENABLED_FLAG INCLUDE_EMPTY) - if (ENABLED_FLAG AND NOT INCLUDE_EMPTY) +function(tribits_print_tpl_list_enable_status docString enabledFlag includeEmpty) + if (enabledFlag AND NOT includeEmpty) tribits_get_sublist_enabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") - elseif (ENABLED_FLAG AND INCLUDE_EMPTY) + elseif (enabledFlag AND includeEmpty) tribits_get_sublist_nondisabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") - elseif (NOT ENABLED_FLAG AND NOT INCLUDE_EMPTY) + elseif (NOT enabledFlag AND NOT includeEmpty) tribits_get_sublist_disabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") - else() # NOT ENABLED_FLAG AND INCLUDE_EMPTY + else() # NOT enabledFlag AND includeEmpty tribits_get_sublist_nonenabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") endif() - tribits_print_prefix_string_and_list("${DOCSTRING}" tplsEnableStatusList) + tribits_print_prefix_string_and_list("${docString}" tplsEnableStatusList) endfunction() # Print the current set of enabled/disabled packages given input list of # packages # -function(tribits_print_packages_list_enable_status_from_var PACKAGES_LIST_VAR - DOCSTRING ENABLED_FLAG INCLUDE_EMPTY +function(tribits_print_packages_list_enable_status_from_var packageListVarName + docString enabledFlag includeEmpty ) - if (ENABLED_FLAG AND NOT INCLUDE_EMPTY) - tribits_get_sublist_enabled(${PACKAGES_LIST_VAR} + if (enabledFlag AND NOT includeEmpty) + tribits_get_sublist_enabled(${packageListVarName} enableStatusList "") - elseif (ENABLED_FLAG AND INCLUDE_EMPTY) - tribits_get_sublist_nondisabled(${PACKAGES_LIST_VAR} enableStatusList "") - elseif (NOT ENABLED_FLAG AND NOT INCLUDE_EMPTY) - tribits_get_sublist_disabled(${PACKAGES_LIST_VAR} + elseif (enabledFlag AND includeEmpty) + tribits_get_sublist_nondisabled(${packageListVarName} enableStatusList "") + elseif (NOT enabledFlag AND NOT includeEmpty) + tribits_get_sublist_disabled(${packageListVarName} enableStatusList "") - else() # NOT ENABLED_FLAG AND INCLUDE_EMPTY - tribits_get_sublist_nonenabled(${PACKAGES_LIST_VAR} + else() # NOT enabledFlag AND includeEmpty + tribits_get_sublist_nonenabled(${packageListVarName} enableStatusList "") endif() - tribits_print_prefix_string_and_list("${DOCSTRING}" enableStatusList) + tribits_print_prefix_string_and_list("${docString}" enableStatusList) endfunction() From 5648cf76c4283b5e9d954ba91fe18e1593ba7a52 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 18 Jan 2023 09:59:38 -0700 Subject: [PATCH 07/45] WIP: Replace bool arg includeEmpty with enum arg enableEmptyStatus (#63) This avoids passing two bools side-by-side in these functions. This will make it safter to add another enum argument for INTERNAL, EXTERNAL or "" (so any). --- .../TribitsPrintEnabledPackagesLists.cmake | 87 ++++++++++++------- .../ctest_driver/TribitsCTestDriverCore.cmake | 5 +- .../TribitsCTestDriverCoreHelpers.cmake | 2 +- 3 files changed, 58 insertions(+), 36 deletions(-) diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index bbb3c4380..6c50343aa 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -51,18 +51,18 @@ include(TribitsGetEnabledSublists) # function(tribits_print_enables_before_adjust_package_enables) tribits_print_internal_toplevel_package_list_enable_status( - "\nExplicitly enabled top-level packages on input (by user)" ON FALSE) + "\nExplicitly enabled top-level packages on input (by user)" ON NONEMPTY) tribits_print_internal_package_list_enable_status( - "\nExplicitly enabled packages on input (by user)" ON FALSE) + "\nExplicitly enabled packages on input (by user)" ON NONEMPTY) tribits_print_internal_toplevel_package_list_enable_status( - "\nExplicitly disabled top-level packages on input (by user or by default)" OFF FALSE) + "\nExplicitly disabled top-level packages on input (by user or by default)" OFF NONEMPTY) tribits_print_internal_package_list_enable_status( - "\nExplicitly disabled packages on input (by user or by default)" OFF FALSE) + "\nExplicitly disabled packages on input (by user or by default)" OFF NONEMPTY) tribits_print_tpl_list_enable_status( - "\nExplicitly enabled external packages/TPLs on input (by user)" ON FALSE) + "\nExplicitly enabled external packages/TPLs on input (by user)" ON NONEMPTY) tribits_print_tpl_list_enable_status( "\nExplicitly disabled external packages/TPLs on input (by user or by default)" - OFF FALSE) + OFF NONEMPTY) tribits_print_package_build_status("\nInitial package build status:\n" "-- Initial: " PRINT_ALL) endfunction() @@ -78,20 +78,20 @@ endfunction() # tribits_print_enables_after_adjust_package_enables() # function(tribits_print_enables_after_adjust_package_enables) - tribits_print_prefix_string_and_list( - "\nFinal set of enabled top-level packages" - ${PROJECT_NAME}_ENABLED_INTERNAL_TOPLEVEL_PACKAGES) - tribits_print_prefix_string_and_list( - "\nFinal set of enabled packages" - ${PROJECT_NAME}_ENABLED_INTERNAL_PACKAGES) + tribits_print_packages_list_enable_status_from_var( + ${PROJECT_NAME}_ENABLED_INTERNAL_TOPLEVEL_PACKAGES + "\nFinal set of enabled top-level packages" ON NONEMPTY) + tribits_print_packages_list_enable_status_from_var( + ${PROJECT_NAME}_ENABLED_INTERNAL_PACKAGES + "\nFinal set of enabled packages" ON NONEMPTY) tribits_print_internal_toplevel_package_list_enable_status( - "\nFinal set of non-enabled top-level packages" OFF TRUE) + "\nFinal set of non-enabled top-level packages" OFF INCLUDE_EMPTY) tribits_print_internal_package_list_enable_status( - "\nFinal set of non-enabled packages" OFF TRUE) + "\nFinal set of non-enabled packages" OFF INCLUDE_EMPTY) tribits_print_tpl_list_enable_status( - "\nFinal set of enabled external packages/TPLs" ON FALSE) + "\nFinal set of enabled external packages/TPLs" ON NONEMPTY) tribits_print_tpl_list_enable_status( - "\nFinal set of non-enabled external packages/TPLs" OFF TRUE) + "\nFinal set of non-enabled external packages/TPLs" OFF INCLUDE_EMPTY) tribits_print_package_build_status("\nFinal package build status (enabled only):\n" "-- Final: " PRINT_ONLY_ENABLED) endfunction() @@ -100,35 +100,38 @@ endfunction() # Function that prints the current set of enabled internal top-level packages # function(tribits_print_internal_toplevel_package_list_enable_status - docString enabledFlag includeEmpty + docString enabledFlag enableEmptyStatus ) tribits_print_packages_list_enable_status_from_var( ${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES - "${docString}" ${enabledFlag} ${includeEmpty} ) + "${docString}" ${enabledFlag} ${enableEmptyStatus} ) endfunction() # Prints the current set of enabled/disabled internal packages # function(tribits_print_internal_package_list_enable_status - docString enabledFlag includeEmpty + docString enabledFlag enableEmptyStatus ) - if (enabledFlag AND NOT includeEmpty) + tribits_assert_include_empty_param(${enableEmptyStatus}) + if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) tribits_get_sublist_enabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES internalPackagesEnableStatusList "") - elseif (enabledFlag AND includeEmpty) + elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) tribits_get_sublist_nondisabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES ${PROJECT_NAME} internalPackagesEnableStatusList "") - elseif (NOT enabledFlag AND NOT includeEmpty) + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) tribits_get_sublist_disabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES internalPackagesEnableStatusList "") - else() # NOT enabledFlag AND includeEmpty + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) tribits_get_sublist_nonenabled( ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES internalPackagesEnableStatusList "") + else() + message(FATAL_ERROR "Should not get here!") endif() tribits_print_prefix_string_and_list("${docString}" internalPackagesEnableStatusList) @@ -137,19 +140,24 @@ endfunction() # Print the current set of enabled/disabled TPLs # -function(tribits_print_tpl_list_enable_status docString enabledFlag includeEmpty) - if (enabledFlag AND NOT includeEmpty) +function(tribits_print_tpl_list_enable_status docString enabledFlag + enableEmptyStatus + ) + tribits_assert_include_empty_param(${enableEmptyStatus}) + if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) tribits_get_sublist_enabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") - elseif (enabledFlag AND includeEmpty) + elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) tribits_get_sublist_nondisabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") - elseif (NOT enabledFlag AND NOT includeEmpty) + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) tribits_get_sublist_disabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") - else() # NOT enabledFlag AND includeEmpty + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) tribits_get_sublist_nonenabled( ${PROJECT_NAME}_DEFINED_TPLS tplsEnableStatusList "") + else() + message(FATAL_ERROR "Should not get here!") endif() tribits_print_prefix_string_and_list("${docString}" tplsEnableStatusList) endfunction() @@ -159,24 +167,37 @@ endfunction() # packages # function(tribits_print_packages_list_enable_status_from_var packageListVarName - docString enabledFlag includeEmpty + docString enabledFlag enableEmptyStatus ) - if (enabledFlag AND NOT includeEmpty) + tribits_assert_include_empty_param(${enableEmptyStatus}) + if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) tribits_get_sublist_enabled(${packageListVarName} enableStatusList "") - elseif (enabledFlag AND includeEmpty) + elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) tribits_get_sublist_nondisabled(${packageListVarName} enableStatusList "") - elseif (NOT enabledFlag AND NOT includeEmpty) + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) tribits_get_sublist_disabled(${packageListVarName} enableStatusList "") - else() # NOT enabledFlag AND includeEmpty + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) tribits_get_sublist_nonenabled(${packageListVarName} enableStatusList "") + else() + message(FATAL_ERROR "Should never get here!") endif() tribits_print_prefix_string_and_list("${docString}" enableStatusList) endfunction() +function(tribits_assert_include_empty_param enableEmptyStatus) + if ((NOT enableEmptyStatus STREQUAL "NONEMPTY") AND + (NOT enableEmptyStatus STREQUAL "INCLUDE_EMPTY") + ) + message(FATAL_ERROR "Error, argument enableEmptyStatus='${enableEmptyStatus}'" + " is invalid! Use 'NONEMPTY' or 'INCLUDE_EMPTY'.") + endif() +endfunction() + + # Print out a list with white-space separators with an initial doc string # function(tribits_print_prefix_string_and_list docString listNameToPrint) diff --git a/tribits/ctest_driver/TribitsCTestDriverCore.cmake b/tribits/ctest_driver/TribitsCTestDriverCore.cmake index 500dd0bf9..f148dfc8f 100644 --- a/tribits/ctest_driver/TribitsCTestDriverCore.cmake +++ b/tribits/ctest_driver/TribitsCTestDriverCore.cmake @@ -2274,8 +2274,9 @@ function(tribits_ctest_driver) select_final_set_of_packages_to_directly_test() # Above sets ${PROJECT_NAME}_PACKAGES_TO_DIRECTLY_TEST - tribits_print_packages_list_enable_status_from_var( ${PROJECT_NAME}_PACKAGES_TO_DIRECTLY_TEST - "\nFinal set of packages to be explicitly processed by CTest/CDash" ON FALSE) + tribits_print_packages_list_enable_status_from_var( + ${PROJECT_NAME}_PACKAGES_TO_DIRECTLY_TEST + "\nFinal set of packages to be explicitly processed by CTest/CDash" ON NONEMPTY) message( "\n***" diff --git a/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake b/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake index 837ddf05e..60c29f291 100644 --- a/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake +++ b/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake @@ -515,7 +515,7 @@ macro(enable_only_modified_packages) else() tribits_print_internal_package_list_enable_status( "\nDirectly modified or failing non-disabled packages that need to be tested" - ON FALSE ) + ON NONEMPTY ) endif() endmacro() From abd846a12c94fd4f19dcee4db42688efdd8f9fd1 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 18 Jan 2023 10:36:41 -0700 Subject: [PATCH 08/45] WIP: Small doc and format changes (#63) Noticed this while looking over this code. --- .../core/package_arch/TribitsGetEnabledSublists.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tribits/core/package_arch/TribitsGetEnabledSublists.cmake b/tribits/core/package_arch/TribitsGetEnabledSublists.cmake index 0444ba3dd..53b88f8b0 100644 --- a/tribits/core/package_arch/TribitsGetEnabledSublists.cmake +++ b/tribits/core/package_arch/TribitsGetEnabledSublists.cmake @@ -47,13 +47,13 @@ include(TribitsGetPackageEnableStatus) # Usage:: # # tribits_get_sublist_enabled( -# ) +# [] ) # # On output, ```` contains the sublist of entries in # ```` which evaluate to ``TRUE`` in an ``if ()`` statement. # function(tribits_get_sublist_enabled enableListName - enabledSublistNameOut numEnabledVarOut + enabledSublistNameOut numEnabledVarOut ) set(enabledSublist) foreach(pkgName IN LISTS ${enableListName}) @@ -77,7 +77,7 @@ endfunction() # Usage:: # # tribits_get_sublist_nondisabled( -# ) +# [] ) # # On output, ```` contains the sublist of entries from # ```` for which evaluate to ``TRUE`` or empty ``""`` in an @@ -108,7 +108,7 @@ endfunction() # Usage:: # # tribits_get_sublist_disabled( -# ) +# [] ) # # On output, ```` contains the sublist of entries # ```` which evaluate to ``FALSE`` and is not empty ``""`` in @@ -139,7 +139,7 @@ endfunction() # Usage:: # # tribits_get_sublist_nonenabled( -# ) +# [] ) # # On output, ```` contains the subset of entries in # ```` that evaluate to ``FALSE`` (which can also be empty From cc8d5b7bd636061a6d4a1d24b12c3360c72ffd1e Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 18 Jan 2023 17:56:24 -0700 Subject: [PATCH 09/45] WIP: Add internalOrExternal arg to tribits_print_packages_list_enable_status_from_var() (#63) This will be used to refactor the functions in TribitsPrintEnabledPackagesLists.cmake to display the set of internal and external packages according to _PACKAGE_BUILD_STATUS instead of fixed lists formed when the package are first defined. This included adding a new filtering function tribits_get_sublist_internal_external() --- .../TribitsGetEnabledSublists.cmake | 50 +++++++++++++++++++ .../TribitsPrintEnabledPackagesLists.cmake | 18 ++++--- .../ctest_driver/TribitsCTestDriverCore.cmake | 2 +- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/tribits/core/package_arch/TribitsGetEnabledSublists.cmake b/tribits/core/package_arch/TribitsGetEnabledSublists.cmake index 53b88f8b0..43df51f89 100644 --- a/tribits/core/package_arch/TribitsGetEnabledSublists.cmake +++ b/tribits/core/package_arch/TribitsGetEnabledSublists.cmake @@ -161,3 +161,53 @@ function(tribits_get_sublist_nonenabled enableListName set(${numNonenabledVarOut} ${numNonenabled} PARENT_SCOPE) endif() endfunction() + + +# @FUNCTION: tribits_get_sublist_internal_external() +# +# Get sub-list of packages that are INTERNAL, EXTERNAL, or either. +# +# Usage:: +# +# tribits_get_sublist_internal_external( +# [] ) +# +# where: +# +# * `` is either `INTERNAL`, `EXTERNAL` or empty "". +# +# On output, ```` contains the sublist of entries in +# ```` which are either `INTERNAL` or `EXTERNAL` or both +# (if `` is "") based on `_PACKAGE_BUILD_STATUS` +# for each element package name. +# +function(tribits_get_sublist_internal_external inputPackageListName internalOrExternal + sublistNameOut sizeSublistOut + ) + tribits_assert_internal_or_external_arg("${internalOrExternal}") + if (NOT internalOrExternal STREQUAL "") + set(sublist "") + foreach(pkgName IN LISTS ${inputPackageListName}) + if (${pkgName}_PACKAGE_BUILD_STATUS STREQUAL internalOrExternal) + list(APPEND sublist ${pkgName}) + endif() + endforeach() + else() + set(sublist ${${inputPackageListName}}) + endif() + set(${sublistNameOut} ${sublist} PARENT_SCOPE) + if (numEnabledVarOut) + list(LENGTH sublist sizeSublist) + set(${sizeSublistOut} ${sizeSublist} PARENT_SCOPE) + endif() +endfunction() + + +function(tribits_assert_internal_or_external_arg internalOrExternal) + set(allowedValuesList "INTERNAL" "EXTERNAL" "") + if (NOT internalOrExternal IN_LIST allowedValuesList) + message(FATAL_ERROR "ERROR, the argument internalOrExternal=" + "'${internalOrExternal}' is not in the list of allowed values" + ${allowedValuesList} ) + endif() +endfunction() diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index 6c50343aa..076e31e67 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -80,10 +80,10 @@ endfunction() function(tribits_print_enables_after_adjust_package_enables) tribits_print_packages_list_enable_status_from_var( ${PROJECT_NAME}_ENABLED_INTERNAL_TOPLEVEL_PACKAGES - "\nFinal set of enabled top-level packages" ON NONEMPTY) + "\nFinal set of enabled top-level packages" "" ON NONEMPTY) tribits_print_packages_list_enable_status_from_var( ${PROJECT_NAME}_ENABLED_INTERNAL_PACKAGES - "\nFinal set of enabled packages" ON NONEMPTY) + "\nFinal set of enabled packages" "" ON NONEMPTY) tribits_print_internal_toplevel_package_list_enable_status( "\nFinal set of non-enabled top-level packages" OFF INCLUDE_EMPTY) tribits_print_internal_package_list_enable_status( @@ -104,7 +104,7 @@ function(tribits_print_internal_toplevel_package_list_enable_status ) tribits_print_packages_list_enable_status_from_var( ${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES - "${docString}" ${enabledFlag} ${enableEmptyStatus} ) + "${docString}" "" ${enabledFlag} ${enableEmptyStatus} ) endfunction() @@ -167,19 +167,21 @@ endfunction() # packages # function(tribits_print_packages_list_enable_status_from_var packageListVarName - docString enabledFlag enableEmptyStatus + docString internalOrExternal enabledFlag enableEmptyStatus ) tribits_assert_include_empty_param(${enableEmptyStatus}) + tribits_get_sublist_internal_external(${packageListVarName} "${internalOrExternal}" + packageListTmp "") if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_enabled(${packageListVarName} + tribits_get_sublist_enabled(packageListTmp enableStatusList "") elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nondisabled(${packageListVarName} enableStatusList "") + tribits_get_sublist_nondisabled(${packageListTmp} enableStatusList "") elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_disabled(${packageListVarName} + tribits_get_sublist_disabled(packageListTmp enableStatusList "") elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nonenabled(${packageListVarName} + tribits_get_sublist_nonenabled(packageListTmp enableStatusList "") else() message(FATAL_ERROR "Should never get here!") diff --git a/tribits/ctest_driver/TribitsCTestDriverCore.cmake b/tribits/ctest_driver/TribitsCTestDriverCore.cmake index f148dfc8f..f084e6e10 100644 --- a/tribits/ctest_driver/TribitsCTestDriverCore.cmake +++ b/tribits/ctest_driver/TribitsCTestDriverCore.cmake @@ -2276,7 +2276,7 @@ function(tribits_ctest_driver) tribits_print_packages_list_enable_status_from_var( ${PROJECT_NAME}_PACKAGES_TO_DIRECTLY_TEST - "\nFinal set of packages to be explicitly processed by CTest/CDash" ON NONEMPTY) + "\nFinal set of packages to be explicitly processed by CTest/CDash" "" ON NONEMPTY) message( "\n***" From f85cc177dcb1b0b5cada7d51ef48cefee25424ac Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 18 Jan 2023 18:06:42 -0700 Subject: [PATCH 10/45] WIP: Change name from TribitsGetEnabledSublists.cmake to TribitsPackageSublists.cmake (#63) This is a better name for this module now that includes functions for more that just filtering based on enable/disable status. --- ...GetEnabledSublists.cmake => TribitsGetPackageSublists.cmake} | 0 .../core/package_arch/TribitsPrintEnabledPackagesLists.cmake | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tribits/core/package_arch/{TribitsGetEnabledSublists.cmake => TribitsGetPackageSublists.cmake} (100%) diff --git a/tribits/core/package_arch/TribitsGetEnabledSublists.cmake b/tribits/core/package_arch/TribitsGetPackageSublists.cmake similarity index 100% rename from tribits/core/package_arch/TribitsGetEnabledSublists.cmake rename to tribits/core/package_arch/TribitsGetPackageSublists.cmake diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index 076e31e67..56932a307 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -37,7 +37,7 @@ # ************************************************************************ # @HEADER -include(TribitsGetEnabledSublists) +include(TribitsGetPackageSublists) # @FUNCTION: tribits_print_enables_before_adjust_package_enables() From e30b5bf28e686b4ed097041e43ee8b99ee14237d Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 20 Jan 2023 14:30:53 -0700 Subject: [PATCH 11/45] WIP: Change printing of package set lists based in INTERNAL/EXTERNAL (#63) Now printing of the final sets of internal and external packages is based on _PACKAGE_BUILD_STATUS and so initially internal packages that are treated as external packages are not listed under: "Final set of [enabled|non-enabled] [toplevel] packages:" but instead are listed under: "Final set of [enabled|non-enabled] external packages/TPLs:" Hopefully this will make it more clear to the user how these packages are being treated. The new tests were updated to adjust to this different output. (NOTE: We could remove the direct printing and checking of _PACKAGE_BUILD_STATUS but I will leave that in for now.) This also helped to remove some code by doing: * The functions tribits_print_internal_[toplevel_]package_list_enable_status() were renamed to tribits_print_[toplevel_]package_list_enable_status() and the argument internalOrExternal was added. * The function tribits_print_tpl_list_enable_status() was deleted. --- test/core/DependencyUnitTests/CMakeLists.txt | 36 ++++-- .../TribitsPrintEnabledPackagesLists.cmake | 119 ++++++------------ .../TribitsCTestDriverCoreHelpers.cmake | 4 +- 3 files changed, 65 insertions(+), 94 deletions(-) diff --git a/test/core/DependencyUnitTests/CMakeLists.txt b/test/core/DependencyUnitTests/CMakeLists.txt index 5719366d7..14a105003 100644 --- a/test/core/DependencyUnitTests/CMakeLists.txt +++ b/test/core/DependencyUnitTests/CMakeLists.txt @@ -735,8 +735,12 @@ create_reduced_dependency_handling_test_case( "-- Final: ThyraEpetraExt_PACKAGE_BUILD_STATUS=EXTERNAL" "-- Final: Thyra_PACKAGE_BUILD_STATUS=EXTERNAL" - "Final set of enabled top-level packages: Teuchos RTOp Epetra Triutils EpetraExt Thyra 6" - "Final set of enabled packages: Teuchos RTOp Epetra Triutils EpetraExt ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt Thyra 10" + "Final set of enabled top-level packages: 0" + "Final set of enabled packages: 0" + "Final set of non-enabled top-level packages: 0" + "Final set of non-enabled packages: 0" + "Final set of enabled external packages/TPLs: BLAS LAPACK Teuchos RTOp Epetra Triutils EpetraExt ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt Thyra 12" + "Final set of non-enabled external packages/TPLs: MPI Boost UMFPACK AMD PETSC ThyraCrazyStuff 6" ) @@ -770,9 +774,12 @@ create_reduced_dependency_handling_test_case( "-- Final: ThyraCoreLibs_PACKAGE_BUILD_STATUS=EXTERNAL" "-- Final: Thyra_PACKAGE_BUILD_STATUS=EXTERNAL" - "Final set of enabled top-level packages: Teuchos RTOp Thyra 3" - "Final set of enabled packages: Teuchos RTOp ThyraCoreLibs Thyra 4" - "Final set of enabled external packages/TPLs: BLAS LAPACK 2" + "Final set of enabled top-level packages: 0" + "Final set of enabled packages: 0" + "Final set of non-enabled top-level packages: Epetra Triutils EpetraExt 3" + "Final set of non-enabled packages: Epetra Triutils EpetraExt 3" + "Final set of enabled external packages/TPLs: BLAS LAPACK Teuchos RTOp ThyraCoreLibs Thyra 6" + "Final set of non-enabled external packages/TPLs: MPI Boost UMFPACK AMD PETSC ThyraGoodStuff ThyraCrazyStuff ThyraEpetra ThyraEpetraExt 9" ) @@ -1838,9 +1845,12 @@ create_dependency_handling_test_case( "-- Final: RBGen_PACKAGE_BUILD_STATUS=INTERNAL" "-- Final: Phalanx_PACKAGE_BUILD_STATUS=INTERNAL" - "Final set of enabled top-level packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack ML Belos Stratimikos RBGen Phalanx 22" - "Final set of enabled packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt ThyraTpetra Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack ML Belos Stratimikos RBGen Phalanx 27" - "Final set of enabled external packages/TPLs: BLAS LAPACK Boost DUMMY 4" + "Final set of enabled top-level packages: TrilinosFramework Shards Sacado Isorropia AztecOO Galeri Amesos Intrepid Ifpack ML Belos Stratimikos RBGen Phalanx 14" + "Final set of enabled packages: TrilinosFramework Shards Sacado Isorropia AztecOO Galeri Amesos Intrepid Ifpack ML Belos Stratimikos RBGen Phalanx 14" + "Final set of non-enabled top-level packages: Stokhos Panzer 2" + "Final set of non-enabled packages: Stokhos Panzer 2" + "Final set of enabled external packages/TPLs: BLAS LAPACK Boost DUMMY Teuchos RTOp Epetra Zoltan Triutils Tpetra EpetraExt ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt ThyraTpetra Thyra 17" + "Final set of non-enabled external packages/TPLs: MPI Scotch METIS ParMETIS CppUnit ADOLC ADIC TVMET y12m SuperLUDist SuperLU UMFPACK AMD PETSC MUMPS ThyraCrazyStuff 16" ) @@ -1907,10 +1917,12 @@ create_dependency_handling_test_case( "-- Final: RBGen_PACKAGE_BUILD_STATUS=INTERNAL" "-- Final: Phalanx_PACKAGE_BUILD_STATUS=INTERNAL" - "Final set of enabled top-level packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack Belos Stratimikos RBGen Phalanx 21" - "Final set of enabled packages: TrilinosFramework Teuchos RTOp Epetra Zoltan Shards Triutils Tpetra EpetraExt Sacado ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt ThyraTpetra Thyra Isorropia AztecOO Galeri Amesos Intrepid Ifpack Belos Stratimikos RBGen Phalanx 26" - "Final set of non-enabled top-level packages: Stokhos ML Panzer 3" - "Final set of enabled external packages/TPLs: BLAS LAPACK Boost DUMMY 4" + "Final set of enabled top-level packages: TrilinosFramework Shards Sacado Isorropia Galeri Intrepid RBGen Phalanx 8" + "Final set of enabled packages: TrilinosFramework Shards Sacado Isorropia Galeri Intrepid RBGen Phalanx 8" + "Final set of non-enabled top-level packages: Stokhos Panzer 2" + "Final set of non-enabled packages: Stokhos Panzer 2" + "Final set of enabled external packages/TPLs: BLAS LAPACK Boost DUMMY Teuchos RTOp Epetra Zoltan Triutils Tpetra EpetraExt ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt ThyraTpetra Thyra AztecOO Amesos Ifpack Belos Stratimikos 22" + "Final set of non-enabled external packages/TPLs: MPI Scotch METIS ParMETIS CppUnit ADOLC ADIC TVMET y12m SuperLUDist SuperLU UMFPACK AMD PETSC MUMPS ThyraCrazyStuff ML 17" ) # NOTE: The above test implicitly makes ThyraCoreLibs and ThyraEpetraExt diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index 56932a307..b1070d2b8 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -50,19 +50,22 @@ include(TribitsGetPackageSublists) # tribits_print_enables_before_adjust_package_enables() # function(tribits_print_enables_before_adjust_package_enables) - tribits_print_internal_toplevel_package_list_enable_status( - "\nExplicitly enabled top-level packages on input (by user)" ON NONEMPTY) - tribits_print_internal_package_list_enable_status( - "\nExplicitly enabled packages on input (by user)" ON NONEMPTY) - tribits_print_internal_toplevel_package_list_enable_status( - "\nExplicitly disabled top-level packages on input (by user or by default)" OFF NONEMPTY) - tribits_print_internal_package_list_enable_status( - "\nExplicitly disabled packages on input (by user or by default)" OFF NONEMPTY) - tribits_print_tpl_list_enable_status( - "\nExplicitly enabled external packages/TPLs on input (by user)" ON NONEMPTY) - tribits_print_tpl_list_enable_status( + tribits_print_toplevel_package_list_enable_status( + "\nExplicitly enabled top-level packages on input (by user)" + INTERNAL ON NONEMPTY) + tribits_print_package_list_enable_status( + "\nExplicitly enabled packages on input (by user)" INTERNAL ON NONEMPTY) + tribits_print_toplevel_package_list_enable_status( + "\nExplicitly disabled top-level packages on input (by user or by default)" + INTERNAL OFF NONEMPTY) + tribits_print_package_list_enable_status( + "\nExplicitly disabled packages on input (by user or by default)" + INTERNAL OFF NONEMPTY) + tribits_print_package_list_enable_status( + "\nExplicitly enabled external packages/TPLs on input (by user)" EXTERNAL ON NONEMPTY) + tribits_print_package_list_enable_status( "\nExplicitly disabled external packages/TPLs on input (by user or by default)" - OFF NONEMPTY) + EXTERNAL OFF NONEMPTY) tribits_print_package_build_status("\nInitial package build status:\n" "-- Initial: " PRINT_ALL) endfunction() @@ -78,88 +81,43 @@ endfunction() # tribits_print_enables_after_adjust_package_enables() # function(tribits_print_enables_after_adjust_package_enables) - tribits_print_packages_list_enable_status_from_var( - ${PROJECT_NAME}_ENABLED_INTERNAL_TOPLEVEL_PACKAGES - "\nFinal set of enabled top-level packages" "" ON NONEMPTY) - tribits_print_packages_list_enable_status_from_var( - ${PROJECT_NAME}_ENABLED_INTERNAL_PACKAGES - "\nFinal set of enabled packages" "" ON NONEMPTY) - tribits_print_internal_toplevel_package_list_enable_status( - "\nFinal set of non-enabled top-level packages" OFF INCLUDE_EMPTY) - tribits_print_internal_package_list_enable_status( - "\nFinal set of non-enabled packages" OFF INCLUDE_EMPTY) - tribits_print_tpl_list_enable_status( - "\nFinal set of enabled external packages/TPLs" ON NONEMPTY) - tribits_print_tpl_list_enable_status( - "\nFinal set of non-enabled external packages/TPLs" OFF INCLUDE_EMPTY) + tribits_print_toplevel_package_list_enable_status( + "\nFinal set of enabled top-level packages" INTERNAL ON NONEMPTY) + tribits_print_package_list_enable_status( + "\nFinal set of enabled packages" INTERNAL ON NONEMPTY) + tribits_print_toplevel_package_list_enable_status( + "\nFinal set of non-enabled top-level packages" INTERNAL OFF INCLUDE_EMPTY) + tribits_print_package_list_enable_status( + "\nFinal set of non-enabled packages" INTERNAL OFF INCLUDE_EMPTY) + tribits_print_package_list_enable_status( + "\nFinal set of enabled external packages/TPLs" EXTERNAL ON NONEMPTY) + tribits_print_package_list_enable_status( + "\nFinal set of non-enabled external packages/TPLs" EXTERNAL OFF INCLUDE_EMPTY) tribits_print_package_build_status("\nFinal package build status (enabled only):\n" "-- Final: " PRINT_ONLY_ENABLED) endfunction() -# Function that prints the current set of enabled internal top-level packages +# Function that prints the current set of enabled internal or external +# top-level packages # -function(tribits_print_internal_toplevel_package_list_enable_status - docString enabledFlag enableEmptyStatus +function(tribits_print_toplevel_package_list_enable_status + docString internalOrExternal enabledFlag enableEmptyStatus ) tribits_print_packages_list_enable_status_from_var( - ${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES - "${docString}" "" ${enabledFlag} ${enableEmptyStatus} ) + ${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES + "${docString}" "${internalOrExternal}" ${enabledFlag} ${enableEmptyStatus} ) endfunction() # Prints the current set of enabled/disabled internal packages # -function(tribits_print_internal_package_list_enable_status - docString enabledFlag enableEmptyStatus - ) - tribits_assert_include_empty_param(${enableEmptyStatus}) - if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_enabled( - ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES - internalPackagesEnableStatusList "") - elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nondisabled( - ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES ${PROJECT_NAME} - internalPackagesEnableStatusList "") - elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_disabled( - ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES - internalPackagesEnableStatusList "") - elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nonenabled( - ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES - internalPackagesEnableStatusList "") - else() - message(FATAL_ERROR "Should not get here!") - endif() - tribits_print_prefix_string_and_list("${docString}" - internalPackagesEnableStatusList) -endfunction() - - -# Print the current set of enabled/disabled TPLs -# -function(tribits_print_tpl_list_enable_status docString enabledFlag - enableEmptyStatus +function(tribits_print_package_list_enable_status + docString internalOrExternal enabledFlag enableEmptyStatus ) - tribits_assert_include_empty_param(${enableEmptyStatus}) - if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_enabled( ${PROJECT_NAME}_DEFINED_TPLS - tplsEnableStatusList "") - elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nondisabled( ${PROJECT_NAME}_DEFINED_TPLS - tplsEnableStatusList "") - elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_disabled( ${PROJECT_NAME}_DEFINED_TPLS - tplsEnableStatusList "") - elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nonenabled( ${PROJECT_NAME}_DEFINED_TPLS - tplsEnableStatusList "") - else() - message(FATAL_ERROR "Should not get here!") - endif() - tribits_print_prefix_string_and_list("${docString}" tplsEnableStatusList) + tribits_print_packages_list_enable_status_from_var( + ${PROJECT_NAME}_DEFINED_PACKAGES + "${docString}" "${internalOrExternal}" ${enabledFlag} ${enableEmptyStatus} ) endfunction() @@ -214,6 +172,7 @@ endfunction() # Print out the `_PACKAGE_BUILD_STATUS` vars +# function(tribits_print_package_build_status summaryHeaderStr prefixStr printEnabledOpt ) diff --git a/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake b/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake index 60c29f291..08c621ed4 100644 --- a/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake +++ b/tribits/ctest_driver/TribitsCTestDriverCoreHelpers.cmake @@ -513,9 +513,9 @@ macro(enable_only_modified_packages) message("\nDirectly modified or failing non-disabled packages that need" " to be tested: ALL_PACKAGES") else() - tribits_print_internal_package_list_enable_status( + tribits_print_package_list_enable_status( "\nDirectly modified or failing non-disabled packages that need to be tested" - ON NONEMPTY ) + INTERNAL ON NONEMPTY ) endif() endmacro() From e14b0d232c4393cbb4059993e64b2f7a6fa4873f Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 20 Jan 2023 14:55:27 -0700 Subject: [PATCH 12/45] WIP: Add printing of Final set of [non-]enabled top-level external packages/TPL (#63) This should hopefully make things less confusing when dealing with internal packages that have subpackages that are treated as external packages. At some point, I will need to add some documentation that explains these tricky aspects of new external package support. --- test/core/DependencyUnitTests/CMakeLists.txt | 2 ++ .../core/package_arch/TribitsPrintEnabledPackagesLists.cmake | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/test/core/DependencyUnitTests/CMakeLists.txt b/test/core/DependencyUnitTests/CMakeLists.txt index 14a105003..c40e6cbc3 100644 --- a/test/core/DependencyUnitTests/CMakeLists.txt +++ b/test/core/DependencyUnitTests/CMakeLists.txt @@ -739,7 +739,9 @@ create_reduced_dependency_handling_test_case( "Final set of enabled packages: 0" "Final set of non-enabled top-level packages: 0" "Final set of non-enabled packages: 0" + "Final set of enabled top-level external packages/TPLs: BLAS LAPACK Teuchos RTOp Epetra Triutils EpetraExt Thyra 8" "Final set of enabled external packages/TPLs: BLAS LAPACK Teuchos RTOp Epetra Triutils EpetraExt ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt Thyra 12" + "Final set of non-enabled top-level external packages/TPLs: MPI Boost UMFPACK AMD PETSC 5" "Final set of non-enabled external packages/TPLs: MPI Boost UMFPACK AMD PETSC ThyraCrazyStuff 6" ) diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index b1070d2b8..f867510cb 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -89,8 +89,12 @@ function(tribits_print_enables_after_adjust_package_enables) "\nFinal set of non-enabled top-level packages" INTERNAL OFF INCLUDE_EMPTY) tribits_print_package_list_enable_status( "\nFinal set of non-enabled packages" INTERNAL OFF INCLUDE_EMPTY) + tribits_print_toplevel_package_list_enable_status( + "\nFinal set of enabled top-level external packages/TPLs" EXTERNAL ON NONEMPTY) tribits_print_package_list_enable_status( "\nFinal set of enabled external packages/TPLs" EXTERNAL ON NONEMPTY) + tribits_print_toplevel_package_list_enable_status( + "\nFinal set of non-enabled top-level external packages/TPLs" EXTERNAL OFF INCLUDE_EMPTY) tribits_print_package_list_enable_status( "\nFinal set of non-enabled external packages/TPLs" EXTERNAL OFF INCLUDE_EMPTY) tribits_print_package_build_status("\nFinal package build status (enabled only):\n" From 864ad9fb418836ae59fe4e5c8d8e09cbc9215f05 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 20 Jan 2023 15:21:30 -0700 Subject: [PATCH 13/45] Factor out tribits_filter_package_list_from_var() (#63) This also required moving the function tribits_assert_include_empty_param(). This will make it easier to implement more logic. --- .../TribitsGetPackageSublists.cmake | 57 +++++++++++++++++++ .../TribitsPrintEnabledPackagesLists.cmake | 31 +--------- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/tribits/core/package_arch/TribitsGetPackageSublists.cmake b/tribits/core/package_arch/TribitsGetPackageSublists.cmake index 43df51f89..192af2b3b 100644 --- a/tribits/core/package_arch/TribitsGetPackageSublists.cmake +++ b/tribits/core/package_arch/TribitsGetPackageSublists.cmake @@ -40,6 +40,53 @@ include(TribitsGetPackageEnableStatus) +# @FUNCTION: tribits_filter_package_list_from_var() +# +# Filter a list of packages based on several criteria including +# internal/external, enable status (with empty or non-empty) +# +# Usage:: +# +# tribits_filter_package_list_from_var( +# +# ) +# +# Where: +# +# * ````: Name of input list var of packages +# * ````: ``INTERNAL``, ``EXTERNAL`` or "" (i.e. +# INTERNAL or EXTERNAL) (matches ``_PACKAGE_BUILD_STATUS``) +# * ````: ``ON`` for elements that match ``TRUE`` , ``OFF`` +# for elements that match ``FALSE`` +# * ````: Determines if allowed enable status is ``NONEMPTY`` +# or ``INCLUDE_EMPTY``. +# * ````: The name of the var that will store the filtered +# sublist of packages. +# +function(tribits_filter_package_list_from_var packageListVarName + internalOrExternal enabledFlag enableEmptyStatus packageSublistOut + ) + tribits_assert_include_empty_param(${enableEmptyStatus}) + tribits_get_sublist_internal_external(${packageListVarName} "${internalOrExternal}" + packageListTmp "") + if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) + tribits_get_sublist_enabled(packageListTmp + packageSublist "") + elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) + tribits_get_sublist_nondisabled(${packageListTmp} packageSublist "") + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) + tribits_get_sublist_disabled(packageListTmp + packageSublist "") + elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) + tribits_get_sublist_nonenabled(packageListTmp + packageSublist "") + else() + message(FATAL_ERROR "Should never get here!") + endif() + set(${packageSublistOut} ${packageSublist} PARENT_SCOPE) +endfunction() + + # @FUNCTION: tribits_get_sublist_enabled() # # Get sub-list of enabled packages @@ -211,3 +258,13 @@ function(tribits_assert_internal_or_external_arg internalOrExternal) ${allowedValuesList} ) endif() endfunction() + + +function(tribits_assert_include_empty_param enableEmptyStatus) + if ((NOT enableEmptyStatus STREQUAL "NONEMPTY") AND + (NOT enableEmptyStatus STREQUAL "INCLUDE_EMPTY") + ) + message(FATAL_ERROR "Error, argument enableEmptyStatus='${enableEmptyStatus}'" + " is invalid! Use 'NONEMPTY' or 'INCLUDE_EMPTY'.") + endif() +endfunction() diff --git a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake index f867510cb..eb42f8be3 100644 --- a/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake +++ b/tribits/core/package_arch/TribitsPrintEnabledPackagesLists.cmake @@ -131,34 +131,9 @@ endfunction() function(tribits_print_packages_list_enable_status_from_var packageListVarName docString internalOrExternal enabledFlag enableEmptyStatus ) - tribits_assert_include_empty_param(${enableEmptyStatus}) - tribits_get_sublist_internal_external(${packageListVarName} "${internalOrExternal}" - packageListTmp "") - if (enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_enabled(packageListTmp - enableStatusList "") - elseif (enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nondisabled(${packageListTmp} enableStatusList "") - elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "NONEMPTY")) - tribits_get_sublist_disabled(packageListTmp - enableStatusList "") - elseif (NOT enabledFlag AND (enableEmptyStatus STREQUAL "INCLUDE_EMPTY")) - tribits_get_sublist_nonenabled(packageListTmp - enableStatusList "") - else() - message(FATAL_ERROR "Should never get here!") - endif() - tribits_print_prefix_string_and_list("${docString}" enableStatusList) -endfunction() - - -function(tribits_assert_include_empty_param enableEmptyStatus) - if ((NOT enableEmptyStatus STREQUAL "NONEMPTY") AND - (NOT enableEmptyStatus STREQUAL "INCLUDE_EMPTY") - ) - message(FATAL_ERROR "Error, argument enableEmptyStatus='${enableEmptyStatus}'" - " is invalid! Use 'NONEMPTY' or 'INCLUDE_EMPTY'.") - endif() + tribits_filter_package_list_from_var(${packageListVarName} + "${internalOrExternal}" "${enabledFlag}" ${enableEmptyStatus} packageSublist) + tribits_print_prefix_string_and_list("${docString}" packageSublist) endfunction() From 7ab38090cf4fd0719fae6c642e997d314342c7a4 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Sat, 21 Jan 2023 08:00:24 -0700 Subject: [PATCH 14/45] MockTrilinos: Set _TRACE_DEPENDENCY_HANDLING_ONLY=ON (#63) This allows tests with MockTrilinos to print what packages are being processed. I therefore removed _SHORTCIRCUIT_AFTER_DEPENDENCY_HANDLING=ON from the MockTrilinos depenency test so that we can check the processing of internal and external packages. --- test/core/DependencyUnitTests/CMakeLists.txt | 1 - tribits/examples/MockTrilinos/CMakeLists.txt | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/DependencyUnitTests/CMakeLists.txt b/test/core/DependencyUnitTests/CMakeLists.txt index c40e6cbc3..cd99afb2f 100644 --- a/test/core/DependencyUnitTests/CMakeLists.txt +++ b/test/core/DependencyUnitTests/CMakeLists.txt @@ -816,7 +816,6 @@ function(create_dependency_handling_test_case TEST_NAME) TEST_0 CMND "${CMAKE_COMMAND}" ARGS -D${MOCK_PROJECT_NAME}_TRIBITS_DIR:FILEPATH=${${PROJECT_NAME}_TRIBITS_DIR} - -D${MOCK_PROJECT_NAME}_SHORTCIRCUIT_AFTER_DEPENDENCY_HANDLING:BOOL=ON -D${MOCK_PROJECT_NAME}_DEPS_XML_OUTPUT_FILE:STRING= -D${MOCK_PROJECT_NAME}_DEPS_HTML_OUTPUT_FILE:STRING= -D${MOCK_PROJECT_NAME}_ENABLE_C:BOOL=OFF diff --git a/tribits/examples/MockTrilinos/CMakeLists.txt b/tribits/examples/MockTrilinos/CMakeLists.txt index c089891ca..db538234e 100644 --- a/tribits/examples/MockTrilinos/CMakeLists.txt +++ b/tribits/examples/MockTrilinos/CMakeLists.txt @@ -41,5 +41,6 @@ cmake_minimum_required(VERSION 3.17.0 FATAL_ERROR) include(${CMAKE_SOURCE_DIR}/ProjectName.cmake) project(${PROJECT_NAME} NONE) set(${PROJECT_NAME}_TRIBITS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../.." CACHE PATH "") +set(${PROJECT_NAME}_TRACE_DEPENDENCY_HANDLING_ONLY ON CACHE BOOL "") include("${${PROJECT_NAME}_TRIBITS_DIR}/TriBITS.cmake") tribits_project() From aaec2103ec2d42c33fa3e2ce535e4d02c2394a02 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 20 Jan 2023 18:05:24 -0700 Subject: [PATCH 15/45] WIP: Adjust processing of internal and external packages (#63) This changes the loops for processing the lists of external and internal packages to loop over {PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES instead of seprate lists ${PROJECT_NAME}_DEFINED_TPLS and ${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES by looking at _PACKAGE_BUILD_STATUS. I had to fix some logic related to extra link flags and the dummy external package/TPL TribitsLastLib. This simplified that logic some. --- test/core/DependencyUnitTests/CMakeLists.txt | 80 ++++++++++++++++++- .../package_arch/TribitsGlobalMacros.cmake | 41 +++++----- 2 files changed, 96 insertions(+), 25 deletions(-) diff --git a/test/core/DependencyUnitTests/CMakeLists.txt b/test/core/DependencyUnitTests/CMakeLists.txt index cd99afb2f..c5f14bbd8 100644 --- a/test/core/DependencyUnitTests/CMakeLists.txt +++ b/test/core/DependencyUnitTests/CMakeLists.txt @@ -687,9 +687,8 @@ create_reduced_dependency_handling_test_case( "Getting information for all enabled external packages/TPLs ..." "Processing enabled external package/TPL: BLAS [(]enabled by Epetra, disable with -DTPL_ENABLE_BLAS=OFF[)]" "Processing enabled external package/TPL: LAPACK [(]enabled by Epetra, disable with -DTPL_ENABLE_LAPACK=OFF[)]" -# "Processing enabled external package/TPL: Teuchos [(]enabled by RTOp, disable with -DTPL_ENABLE_Teuchos=OFF[)]" -# "Processing enabled external package/TPL: RTOp [(]enabled by TPL_ENABLE_RTOp=ON[)]" -# ToDo: Get above to be printed out! + "Processing enabled external package/TPL: Teuchos [(]enabled explicitly, disable with -DTPL_ENABLE_Teuchos=OFF[)]" + "Processing enabled external package/TPL: RTOp [(]enabled explicitly, disable with -DTPL_ENABLE_RTOp=OFF[)]" "Configuring individual enabled Trilinos packages ..." "Processing enabled top-level package: Epetra [(]Libs, Tests, Examples[)]" @@ -1789,6 +1788,7 @@ create_dependency_handling_test_case( # Test treating internal packages as TPLs with MockTrilinos # + create_dependency_handling_test_case( ST_TplEnableThyraCoreLibsOn_EnableAllPackages_EnableTests ARGS @@ -1856,6 +1856,80 @@ create_dependency_handling_test_case( ) +create_dependency_handling_test_case( + ST_EnableMPI_TplEnableStratimikosOn_EnablePanzerOn_EnableMLOff_EnableTests + ARGS + -DTrilinos_ENABLE_SECONDARY_TESTED_CODE=ON + -DTPL_ENABLE_MPI=ON + -DTPL_ENABLE_Stratimikos=ON + -DTrilinos_ENABLE_Panzer=ON + -DTrilinos_ENABLE_ML=OFF + -DTrilinos_ENABLE_TESTS=ON + -DTrilinos_DUMP_PACKAGE_BUILD_STATUS=ON + PASS_REGULAR_EXPRESSION_ALL + "Explicitly enabled top-level packages on input [(]by user[)]: Stratimikos Panzer 2" + "Explicitly disabled top-level packages on input [(]by user or by default[)]: Stokhos ML 2" + + "Adjust the set of internal and external packages:" + "-- Treating internal package Stratimikos as EXTERNAL because TPL_ENABLE_Stratimikos=ON" + "-- Treating internal package ThyraEpetraExt as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package ThyraCoreLibs as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Amesos as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package AztecOO as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Belos as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Ifpack as EXTERNAL because downstream package Stratimikos being treated as EXTERNAL" + "-- Treating internal package Teuchos as EXTERNAL because downstream package Belos being treated as EXTERNAL" + "-- Treating internal package Epetra as EXTERNAL because downstream package Belos being treated as EXTERNAL" + "-- Treating internal package Tpetra as EXTERNAL because downstream package Belos being treated as EXTERNAL" + "-- Treating internal package EpetraExt as EXTERNAL because downstream package Amesos being treated as EXTERNAL" + "-- Treating internal package Triutils as EXTERNAL because downstream package AztecOO being treated as EXTERNAL" + "-- Treating internal package Thyra as EXTERNAL because subpackage ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package ThyraGoodStuff as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraEpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package ThyraTpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" + "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" + "-- Treating internal package Zoltan as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + + "Final set of enabled packages: Shards Sacado Galeri Intrepid Phalanx Panzer 6" + "Final set of non-enabled top-level packages: TrilinosFramework Stokhos Isorropia RBGen 4" + "Final set of non-enabled packages: TrilinosFramework Stokhos Isorropia RBGen 4" + "Final set of enabled top-level external packages/TPLs: MPI BLAS LAPACK Boost Teuchos RTOp Epetra Zoltan Triutils Tpetra EpetraExt Thyra AztecOO Amesos Ifpack Belos Stratimikos 17" + "Final set of enabled external packages/TPLs: MPI BLAS LAPACK Boost Teuchos RTOp Epetra Zoltan Triutils Tpetra EpetraExt ThyraCoreLibs ThyraGoodStuff ThyraEpetra ThyraEpetraExt ThyraTpetra Thyra AztecOO Amesos Ifpack Belos Stratimikos 22" + "Final set of non-enabled top-level external packages/TPLs: Scotch METIS ParMETIS CppUnit ADOLC ADIC TVMET y12m SuperLUDist SuperLU UMFPACK AMD PETSC MUMPS DUMMY ML 16" + "Final set of non-enabled external packages/TPLs: Scotch METIS ParMETIS CppUnit ADOLC ADIC TVMET y12m SuperLUDist SuperLU UMFPACK AMD PETSC MUMPS DUMMY ThyraCrazyStuff ML 17" + + "Getting information for all enabled external packages/TPLs ..." + "Processing enabled external package/TPL: MPI [(]enabled explicitly, disable with -DTPL_ENABLE_MPI=OFF[)]" + "Processing enabled external package/TPL: BLAS [(]enabled by Epetra, disable with -DTPL_ENABLE_BLAS=OFF[)]" + "Processing enabled external package/TPL: LAPACK [(]enabled by Epetra, disable with -DTPL_ENABLE_LAPACK=OFF[)]" + "Processing enabled external package/TPL: Boost [(]enabled by Panzer, disable with -DTPL_ENABLE_Boost=OFF[)]" + "Processing enabled external package/TPL: Teuchos [(]enabled by Panzer, disable with -DTPL_ENABLE_Teuchos=OFF[)]" + "Processing enabled external package/TPL: RTOp [(]enabled by ThyraCoreLibs, disable with -DTPL_ENABLE_RTOp=OFF[)]" + "Processing enabled external package/TPL: Epetra [(]enabled by Panzer, disable with -DTPL_ENABLE_Epetra=OFF[)]" + "Processing enabled external package/TPL: Zoltan [(]enabled by EpetraExt, disable with -DTPL_ENABLE_Zoltan=OFF[)]" + "Processing enabled external package/TPL: Triutils [(]enabled by Stratimikos, disable with -DTPL_ENABLE_Triutils=OFF[)]" + "Processing enabled external package/TPL: Tpetra [(]enabled by Panzer, disable with -DTPL_ENABLE_Tpetra=OFF[)]" + "Processing enabled external package/TPL: EpetraExt [(]enabled by Panzer, disable with -DTPL_ENABLE_EpetraExt=OFF[)]" + "Processing enabled external package/TPL: Thyra [(]enabled by Panzer, disable with -DTPL_ENABLE_Thyra=OFF[)]" + "Processing enabled external package/TPL: AztecOO [(]enabled by Stratimikos, disable with -DTPL_ENABLE_AztecOO=OFF[)]" + "Processing enabled external package/TPL: Amesos [(]enabled by Stratimikos, disable with -DTPL_ENABLE_Amesos=OFF[)]" + "Processing enabled external package/TPL: Ifpack [(]enabled by Phalanx, disable with -DTPL_ENABLE_Ifpack=OFF[)]" + "Processing enabled external package/TPL: Belos [(]enabled by Phalanx, disable with -DTPL_ENABLE_Belos=OFF[)]" + "Processing enabled external package/TPL: Stratimikos [(]enabled explicitly, disable with -DTPL_ENABLE_Stratimikos=OFF[)]" + + "Configuring individual enabled Trilinos packages ..." + "Processing enabled top-level package: Shards [(]Libs[)]" + "Processing enabled top-level package: Sacado [(]Libs[)]" + "Processing enabled top-level package: Galeri [(]Libs[)]" + "Processing enabled top-level package: Intrepid [(]Libs[)]" + "Processing enabled top-level package: Phalanx [(]Libs[)]" + "Processing enabled top-level package: Panzer [(]Libs, Tests, Examples[)]" + + ) +# NOTE: The above test checks that internal packages that are treated as +# external packages correctly express what enabled them. + + create_dependency_handling_test_case( ST_TplEnableStratimikosOn_EnableMLOff_EnableAllPackages_EnableTests ARGS diff --git a/tribits/core/package_arch/TribitsGlobalMacros.cmake b/tribits/core/package_arch/TribitsGlobalMacros.cmake index 63e0930da..fb18d81fb 100644 --- a/tribits/core/package_arch/TribitsGlobalMacros.cmake +++ b/tribits/core/package_arch/TribitsGlobalMacros.cmake @@ -1453,29 +1453,22 @@ macro(tribits_handle_project_extra_link_flags_as_a_tpl) set(${lastLibTplName}_FINDMOD "${${PROJECT_NAME}_TRIBITS_DIR}/common_tpls/FindTPLProjectLastLib.cmake") - # Tack on ${PROJECT_NAME}TribitsLastLib as a dependency to all enabled - # external packages/TPLs - foreach(TPL_NAME ${${PROJECT_NAME}_DEFINED_TPLS}) - list(APPEND ${TPL_NAME}_LIB_DEFINED_DEPENDENCIES ${lastLibTplName}) - if (TPL_ENABLE_${TPL_NAME}) - list(APPEND ${TPL_NAME}_LIB_ENABLED_DEPENDENCIES ${lastLibTplName}) + # Tack on ${PROJECT_NAME}TribitsLastLib as a dependency to all packages + foreach(packageName ${${PROJECT_NAME}_DEFINED_PACKAGES}) + tribits_get_package_enable_status(${packageName} packageEnable "") + list(APPEND ${packageName}_LIB_DEFINED_DEPENDENCIES ${lastLibTplName}) + if (packageEnable) + list(APPEND ${packageName}_LIB_ENABLED_DEPENDENCIES ${lastLibTplName}) endif() endforeach() - # Prepend ${PROJECT_NAME}TribitsLastLib to the list of external packages/TPLs + # Prepend ${PROJECT_NAME}TribitsLastLib to the list of packages list(PREPEND ${PROJECT_NAME}_DEFINED_TPLS ${lastLibTplName}) + list(PREPEND ${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES ${lastLibTplName}) + list(PREPEND ${PROJECT_NAME}_DEFINED_PACKAGES ${lastLibTplName}) set(TPL_ENABLE_${lastLibTplName} ON) set(${lastLibTplName}_PACKAGE_BUILD_STATUS EXTERNAL) - # Tack on ${PROJECT_NAME}TribitsLastLib as a dependency to all enabled - # internal packages - foreach(PACKAGE_NAME ${${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES}) - list(APPEND ${PACKAGE_NAME}_LIB_DEFINED_DEPENDENCIES ${lastLibTplName}) - if (${PROJECT_NAME}_ENABLE_${PACKAGE_NAME}) - list(APPEND ${PACKAGE_NAME}_LIB_ENABLED_DEPENDENCIES ${lastLibTplName}) - endif() - endforeach() - endif() endmacro() @@ -1487,10 +1480,11 @@ macro(tribits_process_enabled_tpls) tribits_config_code_start_timer(CONFIGURE_TPLS_TIME_START_SECONDS) - foreach(TPL_NAME ${${PROJECT_NAME}_DEFINED_TPLS}) - if (TPL_ENABLE_${TPL_NAME}) - tribits_process_enabled_tpl(${TPL_NAME}) - endif() + tribits_filter_package_list_from_var(${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES + EXTERNAL ON NONEMPTY ${PROJECT_NAME}_enabledExternalTopLevelPackages) + + foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) + tribits_process_enabled_tpl(${TPL_NAME}) endforeach() tribits_config_code_stop_timer(CONFIGURE_TPLS_TIME_START_SECONDS @@ -2102,7 +2096,10 @@ macro(tribits_configure_enabled_packages) # other even downstream packages (which is pretty messed up really). # - foreach(TRIBITS_PACKAGE ${${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES}) + tribits_filter_package_list_from_var(${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES + INTERNAL ON NONEMPTY ${PROJECT_NAME}_enabledInternalTopLevelPackages) + + foreach(TRIBITS_PACKAGE IN LISTS ${PROJECT_NAME}_enabledInternalTopLevelPackages) # Get all the package sources independent of whether they are enabled or not. # There are some messed up packages that grab parts out of unrelated @@ -2153,7 +2150,7 @@ macro(tribits_configure_enabled_packages) # Tell packages that are also repos they are being processed as a package. set(TRIBITS_PROCESSING_PACKAGE TRUE) - foreach(TRIBITS_PACKAGE ${${PROJECT_NAME}_DEFINED_INTERNAL_TOPLEVEL_PACKAGES}) + foreach(TRIBITS_PACKAGE IN LISTS ${PROJECT_NAME}_enabledInternalTopLevelPackages) tribits_determine_if_process_package(${TRIBITS_PACKAGE} PROCESS_PACKAGE PACKAGE_ENABLE_STR) From b9b456750699744a5e24d57f80b502275c6bee30 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 24 Jan 2023 11:28:34 -0700 Subject: [PATCH 16/45] Finish basic implentation for building against external packages (#63) This demonstates the basic use case building and installing an internal package and then building the reaming packages against it as an external package. This adds a first test to get TribitsExampleProject to build against external SimpleCxx. Just a few things had to be tweaked to get this to work: * Set _FINDMOD to "TRIBITS_PKG": There was existing, no-tested logic in TriBITS added a long time ago to treat pre-installed TriBITS packages as TPLs. Therefore, I just needed to set _FINDMOD to "TRIBITS_PKG" for internal packages being treated as external packages and that was it! * Cleaned up the existing code to call find_package(${TPL_NAME}). (This code will be refactored to clean it up some.) * Aggregated logic for expected output from TribitsExampeProject tests into a single file ExpectedDepsStrings.cmake so that it works even when a package's CMakeLists.txt file is not processed (because it is being treated as external). --- .../TribitsExampleProject_Tests.cmake | 138 ++++++++++++++++++ .../TribitsAdjustPackageEnables.cmake | 3 +- .../TribitsProcessEnabledTpl.cmake | 3 +- .../TribitsExampleProject/CMakeLists.txt | 3 + .../cmake/ExpectedDepsStrings.cmake | 49 +++++++ .../packages/simple_cxx/CMakeLists.txt | 11 +- .../with_subpackages/b/CMakeLists.txt | 21 +-- .../with_subpackages/c/CMakeLists.txt | 2 + 8 files changed, 197 insertions(+), 33 deletions(-) create mode 100644 tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index 5851b9f36..08a7aa778 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -3209,3 +3209,141 @@ if (TribitsExampleProject_extra_link_flags_NAME) set_tests_properties(${TribitsExampleProject_extra_link_flags_NAME} PROPERTIES DEPENDS ${SimpleTpl_install_STATIC_NAME} ) endif() + + +################################################################################### + + +tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx + OVERALL_WORKING_DIRECTORY TEST_NAME + OVERALL_NUM_MPI_PROCS 1 + EXCLUDE_IF_NOT_TRUE ${PROJECT_NAME}_ENABLE_Fortran IS_REAL_LINUX_SYSTEM + + TEST_0 + MESSAGE "Copy TribitsExampleProject so we can change it" + CMND cp + ARGS -r ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject . +# CMND ln +# ARGS -s ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject . + + TEST_1 + MESSAGE "Configure to just build and install just SimpleCxx" + CMND ${CMAKE_COMMAND} + WORKING_DIRECTORY Build_SimpleCxx + ARGS + ${TribitsExampleProject_COMMON_CONFIG_ARGS} + -DTribitsExProj_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj_ENABLE_SimpleCxx=ON + -DCMAKE_INSTALL_PREFIX=../install/simple_cxx + # ToDo: Add option to stop install of TribitsExProjConfig.cmake ... + -DTPL_ENABLE_MPI=OFF + -DTPL_ENABLE_SimpleTpl=ON + -DSimpleTpl_INCLUDE_DIRS=${SimpleTpl_install_STATIC_DIR}/install/include + -DSimpleTpl_LIBRARY_DIRS=${SimpleTpl_install_STATIC_DIR}/install/lib + ../TribitsExampleProject + PASS_REGULAR_EXPRESSION_ALL + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + + TEST_2 + MESSAGE "Build just SimpleCxx" + CMND make ARGS ${CTEST_BUILD_FLAGS} + WORKING_DIRECTORY Build_SimpleCxx + SKIP_CLEAN_WORKING_DIRECTORY + + TEST_3 + MESSAGE "Install just SimpleCxx" + CMND make ARGS ${CTEST_BUILD_FLAGS} install + WORKING_DIRECTORY Build_SimpleCxx + SKIP_CLEAN_WORKING_DIRECTORY + + TEST_4 + MESSAGE "Remove the build directory for SimpleCxx" + CMND ${CMAKE_COMMAND} ARGS -E rm -R Build_SimpleCxx + + TEST_5 + MESSAGE "Remove the source directory for SimpleCxx" + CMND ${CMAKE_COMMAND} ARGS -E rm -R + TribitsExampleProject/packages/simple_cxx/CMakeLists.txt + TribitsExampleProject/packages/simple_cxx/src + TribitsExampleProject/packages/simple_cxx/test + + TEST_6 + MESSAGE "Configure rest of TribitsExampleProject against pre-installed SimpleCxx" + CMND ${CMAKE_COMMAND} + WORKING_DIRECTORY Build + ARGS + ${TribitsExampleProject_COMMON_CONFIG_ARGS} + -DTribitsExProj_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj_ENABLE_ALL_PACKAGES=ON + -DTribitsExProj_ENABLE_TESTS=ON + #-DTribitsExProj_ENABLE_INSTALL_CMAKE_CONFIG_FILES=OFF # Allow WrapExternal enable + -DTPL_ENABLE_SimpleCxx=ON + -DCMAKE_PREFIX_PATH=../install/simple_cxx + -DTPL_ENABLE_MPI=OFF + -DTPL_ENABLE_SimpleTpl=ON + -DSimpleTpl_INCLUDE_DIRS=${SimpleTpl_install_STATIC_DIR}/install/include + -DSimpleTpl_LIBRARY_DIRS=${SimpleTpl_install_STATIC_DIR}/install/lib + # ToDo: Remove how to find SimpleTpl because SimpleCxx should already + # have that found and we should just use what it found! + ../TribitsExampleProject + PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package SimpleCxx as EXTERNAL because TPL_ENABLE_SimpleCxx=ON" + + "Final set of enabled top-level packages: MixedLang WithSubpackages 2" + "Final set of enabled packages: MixedLang WithSubpackagesA WithSubpackagesB WithSubpackagesC WithSubpackages 5" + "Final set of non-enabled top-level packages: WrapExternal 1" + "Final set of non-enabled packages: WrapExternal 1" + "Final set of enabled top-level external packages/TPLs: HeaderOnlyTpl SimpleTpl SimpleCxx 3" + "Final set of enabled external packages/TPLs: HeaderOnlyTpl SimpleTpl SimpleCxx 3" + "Final set of non-enabled top-level external packages/TPLs: MPI 1" + "Final set of non-enabled external packages/TPLs: MPI 1" + + "Getting information for all enabled external packages/TPLs ..." + "Processing enabled external package/TPL: HeaderOnlyTpl [(]enabled by SimpleCxx, disable with -DTPL_ENABLE_HeaderOnlyTpl=OFF[)]" + "-- TPL_HeaderOnlyTpl_INCLUDE_DIRS='.*/tribits/examples/tpls/HeaderOnlyTpl'" + "Processing enabled external package/TPL: SimpleTpl [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleTpl=OFF[)]" + "-- TPL_SimpleTpl_LIBRARIES='.*/TriBITS_SimpleTpl_install_STATIC/install/lib/libsimpletpl.a'" + "-- TPL_SimpleTpl_INCLUDE_DIRS='.*/TriBITS_SimpleTpl_install_STATIC/install/include'" + "Processing enabled external package/TPL: SimpleCxx [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleCxx=OFF[)]" + "-- Calling find_package[(]SimpleCxx[)] for TriBITS-compatible package ..." + + "Configuring individual enabled TribitsExProj packages ..." + "Processing enabled top-level package: MixedLang [(]Libs, Tests, Examples[)]" + "Processing enabled top-level package: WithSubpackages [(]A, B, C, Tests, Examples[)]" + + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + + TEST_7 + MESSAGE "Build TribitsExampleProject" + CMND make ARGS ${CTEST_BUILD_FLAGS} + WORKING_DIRECTORY Build + SKIP_CLEAN_WORKING_DIRECTORY + + TEST_8 + MESSAGE "Run all the tests with ctest" + WORKING_DIRECTORY Build + SKIP_CLEAN_WORKING_DIRECTORY + CMND ${CMAKE_CTEST_COMMAND} + PASS_REGULAR_EXPRESSION_ALL + "100% tests passed, 0 tests failed out of 7" + ALWAYS_FAIL_ON_NONZERO_RETURN + + ADDED_TEST_NAME_OUT TribitsExampleProject_External_SimpleCxx_NAME + ) +# NOTE: The above test is a strong check that SimpleCxx is built and installed +# first and then is used in the later build of the rest of +# TribitsExampleProject. If you comment out -DTPL_ENABLE_SimpleCxx=ON, then +# it will not build! + + +if (TribitsExampleProject_External_SimpleCxx_NAME) + set_tests_properties(${TribitsExampleProject_External_SimpleCxx_NAME} + PROPERTIES DEPENDS ${SimpleTpl_install_STATIC_NAME} ) +endif() + + diff --git a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake index 778e0aea9..172888759 100644 --- a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake +++ b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake @@ -1373,7 +1373,8 @@ macro(tribits_set_internal_package_to_external packageName) "Treating internal package ${packageName} as EXTERNAL because" " " ${ARGN}) endif() - set(${packageName}_PACKAGE_BUILD_STATUS EXTERNAL) + set(${packageName}_PACKAGE_BUILD_STATUS EXTERNAL) + set(${packageName}_FINDMOD TRIBITS_PKG) endmacro() diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake index f6925f208..170b3dc45 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake @@ -77,11 +77,10 @@ function(tribits_process_enabled_tpl TPL_NAME) print_var(${TPL_NAME}_FINDMOD) endif() if (${TPL_NAME}_FINDMOD STREQUAL "TRIBITS_PKG") + message("-- Calling find_package(${TPL_NAME}) for TriBITS-compatible package ...") set(TPL_${TPL_NAME}_PARTS_ALREADY_SET FALSE) # ToDo: Take out? if (NOT TPL_${TPL_NAME}_PARTS_ALREADY_SET) find_package(${TPL_NAME} CONFIG REQUIRED) - global_set(TPL_${TPL_NAME}_LIBRARIES - "${${TPL_NAME}_LIBRARIES}" "${${TPL_NAME}_TPL_LIBRARIES}") global_set(TPL_${TPL_NAME}_PARTS_ALREADY_SET TRUE) endif() return() diff --git a/tribits/examples/TribitsExampleProject/CMakeLists.txt b/tribits/examples/TribitsExampleProject/CMakeLists.txt index f413d381b..8fddc3217 100644 --- a/tribits/examples/TribitsExampleProject/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/CMakeLists.txt @@ -44,5 +44,8 @@ set(HeaderOnlyTpl_INCLUDE_DIRS "${${PROJECT_NAME}_TRIBITS_DIR}/examples/tpls/HeaderOnlyTpl" CACHE PATH "Default set by TriBITS/CMakeLists.txt" ) +# This does not get set by TriBITS when this is the TriBITS project :-( +set(TribitsExampleProject_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + # Do all of the processing for this Tribits project tribits_project() diff --git a/tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake b/tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake new file mode 100644 index 000000000..ac4d53047 --- /dev/null +++ b/tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake @@ -0,0 +1,49 @@ +# This file contains logic for the expected dependencies for each package and +# TPLs used in TribitsExampleProject. This logic is contained here instead of +# in the packages's CMakeLists.txt files in case some of these are pulled in +# as external packages and that package's CMakeLists.txt files are not +# actually processed. CMakeLists.txt files that need this info just include +# this file at the point of where it is needed. +# +# NOTE: A file like this that gets included in the individual TriBITS packages +# would be a bad idea in real TriBITS packages. A TriBITS package should be +# self-contained and not refer to any files outside of its base package +# directory. But in this case, we do this so that we can avoid duplication in +# this logic. If we really wanted to, we could put this info into the +# Config.cmake files that get installed so that this info was +# self-contained in each package like it was before. + +tribits_get_package_enable_status(SimpleCxx SimpleCxx_enabled "") +if (SimpleCxx_enabled) + if (SimpleCxx_ENABLE_SimpleTpl) + set(simpletplText "simpletpl ") + else() + set(simpletplText) + endif() + set(EXPECTED_SIMPLECXX_AND_DEPS + "SimpleCxx ${simpletplText}headeronlytpl") +endif() + +tribits_get_package_enable_status(InsertedPkg InsertedPkg_enabled "") +if (InsertedPkg_enabled) + set(EXPECTED_INSERTEDPKG_AND_DEPS "InsertedPkg ${EXPECTED_SIMPLECXX_AND_DEPS}") + set(EXPECTED_INSERTEDPKG_AND_DEPS_STR "${EXPECTED_INSERTEDPKG_AND_DEPS} ") +else() + set(EXPECTED_INSERTEDPKG_DEPS "") + set(EXPECTED_INSERTEDPKG_DEPS_STR "") +endif() + +tribits_get_package_enable_status(WithSubpackagesA WithSubpackagesA_enabled "") +if (WithSubpackagesA_enabled) + set(EXPECTED_A_AND_DEPS "A ${EXPECTED_SIMPLECXX_AND_DEPS}") + set(EXPECTED_A_AND_DEPS_STR "${EXPECTED_A_AND_DEPS} ") +else() + set(EXPECTED_A_AND_DEPS "") + set(EXPECTED_A_AND_DEPS_STR "") +endif() + +tribits_get_package_enable_status(WithSubpackagesB WithSubpackagesB_enabled "") +if (WithSubpackagesB_enabled) + set(EXPECTED_B_DEPS + "${EXPECTED_A_AND_DEPS_STR}${EXPECTED_INSERTEDPKG_AND_DEPS_STR}${EXPECTED_SIMPLECXX_AND_DEPS}") +endif() diff --git a/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt index 4eb715a09..2d1325e65 100644 --- a/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt @@ -22,16 +22,7 @@ tribits_add_show_deprecated_warnings_option() add_subdirectory(src) tribits_add_test_directories(test) -# Set a variable that will be used in downstream packages - -if (SimpleCxx_ENABLE_SimpleTpl) - set(simpletplText "simpletpl ") -else() - set(simpletplText) -endif() - -global_set(EXPECTED_SIMPLECXX_AND_DEPS - "SimpleCxx ${simpletplText}headeronlytpl") +include("${TribitsExampleProject_SOURCE_DIR}/cmake/ExpectedDepsStrings.cmake") # # E) Do standard post processing diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt index 200d869b1..6508cd652 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt @@ -2,26 +2,7 @@ tribits_subpackage(B) add_subdirectory(src) -# Set variables that will be used in this package and downstream packages - -if (${PROJECT_NAME}_ENABLE_InsertedPkg) - global_set(EXPECTED_INSERTEDPKG_AND_DEPS "InsertedPkg ${EXPECTED_SIMPLECXX_AND_DEPS}") - global_set(EXPECTED_INSERTEDPKG_AND_DEPS_STR "${EXPECTED_INSERTEDPKG_AND_DEPS} ") -else() - global_set(EXPECTED_INSERTEDPKG_DEPS "") - global_set(EXPECTED_INSERTEDPKG_DEPS_STR "") -endif() - -if (${PROJECT_NAME}_ENABLE_WithSubpackagesA) - global_set(EXPECTED_A_AND_DEPS "A ${EXPECTED_SIMPLECXX_AND_DEPS}") - global_set(EXPECTED_A_AND_DEPS_STR "${EXPECTED_A_AND_DEPS} ") -else() - global_set(EXPECTED_A_AND_DEPS "") - global_set(EXPECTED_A_AND_DEPS_STR "") -endif() - -global_set(EXPECTED_B_DEPS - "${EXPECTED_A_AND_DEPS_STR}${EXPECTED_INSERTEDPKG_AND_DEPS_STR}${EXPECTED_SIMPLECXX_AND_DEPS}") +include("${TribitsExampleProject_SOURCE_DIR}/cmake/ExpectedDepsStrings.cmake") tribits_add_test_directories(tests) diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt index 696a5815c..26266ce10 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt @@ -15,6 +15,8 @@ tribits_add_library(pws_c ${TAL_EXTRALIB_ARGS} # Used to show warnings and errors ) +include("${TribitsExampleProject_SOURCE_DIR}/cmake/ExpectedDepsStrings.cmake") + tribits_add_test_directories(tests) tribits_subpackage_postprocess() From 33902f7a23e7b394267d56c8fee1a68e714fdb4c Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Thu, 26 Jan 2023 19:36:01 -0700 Subject: [PATCH 17/45] Process TPLs at base project level, pass info through Config.cmake files (#63) This changes to process TPLs at the base project level instead of in a function() scope so that local vars set in find_package() calls are available in the base project scope. This technically breaks backward compatibility but this is more similar to how a raw CMake project would call find_package() to get external packages. Hopefully this will not break anything. To accomplish this, this changed the function tribits_process_enabled_tpl() to a macro. Also, the macro tribits_process_enabled_tpl() was refactored into smaller macros and functions to make it easier to understand and maintain. To test this, this commit includes changes to TribitsExampleProject to pass info about expected dependencies through the Config.cmake files to downstream packages instead of using the hacked ExpectedDepsStrings.cmake file. (For many reasons, a TriBITS package should not refer to anything outside of the base package source dir.) This fixes all of the tests in TriBITS. --- tribits/CHANGELOG.md | 13 ++ .../TribitsProcessEnabledTpl.cmake | 176 +++++++++++------- .../TribitsMacroFunctionDocTemplate.rst | 2 +- .../TribitsExampleProject/CMakeLists.txt | 3 - .../cmake/ExpectedDepsStrings.cmake | 49 ----- .../packages/simple_cxx/CMakeLists.txt | 12 +- .../with_subpackages/b/CMakeLists.txt | 22 ++- .../with_subpackages/c/CMakeLists.txt | 2 - 8 files changed, 151 insertions(+), 128 deletions(-) delete mode 100644 tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake diff --git a/tribits/CHANGELOG.md b/tribits/CHANGELOG.md index a03ba918a..fefa42336 100644 --- a/tribits/CHANGELOG.md +++ b/tribits/CHANGELOG.md @@ -2,6 +2,19 @@ ChangeLog for TriBITS ---------------------------------------- +## 2023-10-25: + +* **Changed:** External packages/TPLs are now processed at the base project + scope level. This allows simple `set()` statements in package module files + or config files included by `find_package()` to have project-level scope for + the entire TriBITS project. This is more similar to how a raw CMake project + would usually behave that calls `find_package()` in the base + `CMakeLists.txt` file. Before, calls to `find_package()` were wrapped in a + CMake `function()` called from the base project directory scope. So while + IMPORTED targets created from a `find_package()` command where visible at + the base directory project-level scope, local variables were not. With this + change, now they are. + ## 2023-01-10: * **Added:** Added back support for deprecated variable diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake index 170b3dc45..52f925abb 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake @@ -49,26 +49,14 @@ include(AppendStringVar) include(TribitsStandardizePaths) -# @FUNCTION: tribits_process_enabled_tpl() +# @MACRO: tribits_process_enabled_tpl() # # Process an enabled TPL's FindTPL${TPL_NAME}.cmake module. # -function(tribits_process_enabled_tpl TPL_NAME) +macro(tribits_process_enabled_tpl TPL_NAME) - # Setup the processing string - set(PROCESSING_MSG_STRING "Processing enabled external package/TPL: ${TPL_NAME} (") - if (${TPL_NAME}_ENABLING_PKG) - string(APPEND PROCESSING_MSG_STRING - "enabled by ${${TPL_NAME}_ENABLING_PKG}," ) - else() - string(APPEND PROCESSING_MSG_STRING - "enabled explicitly," ) - endif() - string(APPEND PROCESSING_MSG_STRING - " disable with -DTPL_ENABLE_${TPL_NAME}=OFF)" ) - - # Print the processing header - message("${PROCESSING_MSG_STRING}") + tribits_get_enabled_tpl_processing_string(${TPL_NAME} tplProcessingString) + message("${tplProcessingString}") if (NOT ${PROJECT_NAME}_TRACE_DEPENDENCY_HANDLING_ONLY) @@ -76,15 +64,54 @@ function(tribits_process_enabled_tpl TPL_NAME) if (${PROJECT_NAME}_VERBOSE_CONFIGURE) print_var(${TPL_NAME}_FINDMOD) endif() + if (${TPL_NAME}_FINDMOD STREQUAL "TRIBITS_PKG") - message("-- Calling find_package(${TPL_NAME}) for TriBITS-compatible package ...") - set(TPL_${TPL_NAME}_PARTS_ALREADY_SET FALSE) # ToDo: Take out? - if (NOT TPL_${TPL_NAME}_PARTS_ALREADY_SET) - find_package(${TPL_NAME} CONFIG REQUIRED) - global_set(TPL_${TPL_NAME}_PARTS_ALREADY_SET TRUE) - endif() - return() - elseif (IS_ABSOLUTE ${${TPL_NAME}_FINDMOD}) + tribits_process_enabled_tribits_compatible_tpl(${TPL_NAME}) + else() + tribits_process_enabled_tribits_find_tpl_mod_file(${TPL_NAME}) + tribits_address_failed_tpl_find(${TPL_NAME}) + tribits_generate_tpl_version_file_and_add_package_config_install_targets( + ${TPL_NAME}) + endif() + + endif() + +endmacro() + + +# Get external package/TPL processing string +# +function(tribits_get_enabled_tpl_processing_string TPL_NAME tplProcessingStringOut) + set(tplProcessingString "Processing enabled external package/TPL: ${TPL_NAME} (") + if (${TPL_NAME}_ENABLING_PKG) + string(APPEND tplProcessingString "enabled by ${${TPL_NAME}_ENABLING_PKG}," ) + else() + string(APPEND tplProcessingString "enabled explicitly," ) + endif() + string(APPEND tplProcessingString " disable with -DTPL_ENABLE_${TPL_NAME}=OFF)" ) + set(${tplProcessingStringOut} "${tplProcessingString}" PARENT_SCOPE) +endfunction() + + +# Process an enabled TPL defined using a fully TriBITS-compatible +# Config.cmake file +# +macro(tribits_process_enabled_tribits_compatible_tpl TPL_NAME) + message("-- " + "Calling find_package(${TPL_NAME}) for TriBITS-compatible package ...") + set(TPL_${TPL_NAME}_PARTS_ALREADY_SET FALSE) # ToDo: Take out? + if (NOT TPL_${TPL_NAME}_PARTS_ALREADY_SET) + find_package(${TPL_NAME} CONFIG REQUIRED) + set(TPL_${TPL_NAME}_PARTS_ALREADY_SET TRUE) + endif() +endmacro() + + +# Process an enabled TPL defined using a FindTPL.cmake module +# +macro(tribits_process_enabled_tribits_find_tpl_mod_file TPL_NAME) + + if (IS_ABSOLUTE ${${TPL_NAME}_FINDMOD}) #message("${${TPL_NAME}_FINDMOD} is absolute!") set(CURRENT_TPL_PATH "${${TPL_NAME}_FINDMOD}") else() @@ -112,56 +139,63 @@ function(tribits_process_enabled_tpl TPL_NAME) print_var(TPL_${TPL_NAME}_NOT_FOUND) endif() - # Address failed find of the TPL - if (TPL_${TPL_NAME}_NOT_FOUND AND NOT TPL_TENTATIVE_ENABLE_${TPL_NAME}) +endmacro() + + +function(tribits_address_failed_tpl_find TPL_NAME) + # Address failed find of the TPL + if (TPL_${TPL_NAME}_NOT_FOUND AND NOT TPL_TENTATIVE_ENABLE_${TPL_NAME}) + message( + "-- NOTE: The find module file for this failed TPL '${TPL_NAME}' is:\n" + " ${CURRENT_TPL_PATH}\n" + " which is pointed to in the file:\n" + " ${${TPL_NAME}_TPLS_LIST_FILE}\n" + ) + if (${TPL_NAME}_ENABLING_PKG) message( - "-- NOTE: The find module file for this failed TPL '${TPL_NAME}' is:\n" - " ${CURRENT_TPL_PATH}\n" - " which is pointed to in the file:\n" - " ${${TPL_NAME}_TPLS_LIST_FILE}\n" + "TIP: One way to get past the configure failure for the\n" + "TPL '${TPL_NAME}' is to simply disable it with:\n" + " -DTPL_ENABLE_${TPL_NAME}=OFF\n" + "which will disable it and will recursively disable all of the\n" + "downstream packages that have required dependencies on it, including\n" + "the package '${${TPL_NAME}_ENABLING_PKG}' which triggered its enable.\n" + "When you reconfigure, just grep the cmake stdout for '${TPL_NAME}'\n" + "and then follow the disables that occur as a result to see what impact\n" + "this TPL disable has on the configuration of ${PROJECT_NAME}.\n" + ) + else() + message( + "TIP: Even though the TPL '${TPL_NAME}' was explicitly enabled in input,\n" + "it can be disabled with:\n" + " -DTPL_ENABLE_${TPL_NAME}=OFF\n" + "which will disable it and will recursively disable all of the\n" + "downstream packages that have required dependencies on it.\n" + "When you reconfigure, just grep the cmake stdout for '${TPL_NAME}'\n" + "and then follow the disables that occur as a result to see what impact\n" + "this TPL disable has on the configuration of ${PROJECT_NAME}.\n" ) - if (${TPL_NAME}_ENABLING_PKG) - message( - "TIP: One way to get past the configure failure for the\n" - "TPL '${TPL_NAME}' is to simply disable it with:\n" - " -DTPL_ENABLE_${TPL_NAME}=OFF\n" - "which will disable it and will recursively disable all of the\n" - "downstream packages that have required dependencies on it, including\n" - "the package '${${TPL_NAME}_ENABLING_PKG}' which triggered its enable.\n" - "When you reconfigure, just grep the cmake stdout for '${TPL_NAME}'\n" - "and then follow the disables that occur as a result to see what impact\n" - "this TPL disable has on the configuration of ${PROJECT_NAME}.\n" - ) - else() - message( - "TIP: Even though the TPL '${TPL_NAME}' was explicitly enabled in input,\n" - "it can be disabled with:\n" - " -DTPL_ENABLE_${TPL_NAME}=OFF\n" - "which will disable it and will recursively disable all of the\n" - "downstream packages that have required dependencies on it.\n" - "When you reconfigure, just grep the cmake stdout for '${TPL_NAME}'\n" - "and then follow the disables that occur as a result to see what impact\n" - "this TPL disable has on the configuration of ${PROJECT_NAME}.\n" - ) - endif() - message(FATAL_ERROR - "ERROR: TPL_${TPL_NAME}_NOT_FOUND=${TPL_${TPL_NAME}_NOT_FOUND}, aborting!") endif() - - # Generate the ConfigVersion.cmake file if it has not been - # created yet and add install targets for Config[Version].cmake - set(buildDirExternalPkgsDir - "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}") - set(tplConfigFile - "${buildDirExternalPkgsDir}/${TPL_NAME}/${TPL_NAME}Config.cmake") - set(tplConfigVersionFile - "${buildDirExternalPkgsDir}/${TPL_NAME}/${TPL_NAME}ConfigVersion.cmake") - tribits_extpkg_write_config_version_file(${TPL_NAME} - "${tplConfigVersionFile}") - tribits_extpkg_install_config_file(${TPL_NAME} "${tplConfigFile}") - tribits_extpkg_install_config_version_file(${TPL_NAME} - "${tplConfigVersionFile}") - + message(FATAL_ERROR + "ERROR: TPL_${TPL_NAME}_NOT_FOUND=${TPL_${TPL_NAME}_NOT_FOUND}, aborting!") endif() +endfunction() + +# Generate the ConfigVersion.cmake file for a TriBITS TPL and install +# the already generated Config.cmake file +# +function(tribits_generate_tpl_version_file_and_add_package_config_install_targets + TPL_NAME + ) + set(buildDirExternalPkgsDir + "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}") + set(tplConfigFile + "${buildDirExternalPkgsDir}/${TPL_NAME}/${TPL_NAME}Config.cmake") + set(tplConfigVersionFile + "${buildDirExternalPkgsDir}/${TPL_NAME}/${TPL_NAME}ConfigVersion.cmake") + tribits_extpkg_write_config_version_file(${TPL_NAME} + "${tplConfigVersionFile}") + tribits_extpkg_install_config_file(${TPL_NAME} "${tplConfigFile}") + tribits_extpkg_install_config_version_file(${TPL_NAME} + "${tplConfigVersionFile}") endfunction() diff --git a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst index c0916454d..5f0f3259b 100644 --- a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst +++ b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst @@ -38,7 +38,7 @@ @MACRO: tribits_package_define_dependencies() + @MACRO: tribits_package_postprocess() + @MACRO: tribits_process_subpackages() + -@FUNCTION: tribits_process_enabled_tpl() + +@MACRO: tribits_process_enabled_tpl() + @MACRO: tribits_project() + @MACRO: tribits_project_define_extra_repositories() + @MACRO: tribits_project_enable_all() + diff --git a/tribits/examples/TribitsExampleProject/CMakeLists.txt b/tribits/examples/TribitsExampleProject/CMakeLists.txt index 8fddc3217..f413d381b 100644 --- a/tribits/examples/TribitsExampleProject/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/CMakeLists.txt @@ -44,8 +44,5 @@ set(HeaderOnlyTpl_INCLUDE_DIRS "${${PROJECT_NAME}_TRIBITS_DIR}/examples/tpls/HeaderOnlyTpl" CACHE PATH "Default set by TriBITS/CMakeLists.txt" ) -# This does not get set by TriBITS when this is the TriBITS project :-( -set(TribitsExampleProject_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") - # Do all of the processing for this Tribits project tribits_project() diff --git a/tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake b/tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake deleted file mode 100644 index ac4d53047..000000000 --- a/tribits/examples/TribitsExampleProject/cmake/ExpectedDepsStrings.cmake +++ /dev/null @@ -1,49 +0,0 @@ -# This file contains logic for the expected dependencies for each package and -# TPLs used in TribitsExampleProject. This logic is contained here instead of -# in the packages's CMakeLists.txt files in case some of these are pulled in -# as external packages and that package's CMakeLists.txt files are not -# actually processed. CMakeLists.txt files that need this info just include -# this file at the point of where it is needed. -# -# NOTE: A file like this that gets included in the individual TriBITS packages -# would be a bad idea in real TriBITS packages. A TriBITS package should be -# self-contained and not refer to any files outside of its base package -# directory. But in this case, we do this so that we can avoid duplication in -# this logic. If we really wanted to, we could put this info into the -# Config.cmake files that get installed so that this info was -# self-contained in each package like it was before. - -tribits_get_package_enable_status(SimpleCxx SimpleCxx_enabled "") -if (SimpleCxx_enabled) - if (SimpleCxx_ENABLE_SimpleTpl) - set(simpletplText "simpletpl ") - else() - set(simpletplText) - endif() - set(EXPECTED_SIMPLECXX_AND_DEPS - "SimpleCxx ${simpletplText}headeronlytpl") -endif() - -tribits_get_package_enable_status(InsertedPkg InsertedPkg_enabled "") -if (InsertedPkg_enabled) - set(EXPECTED_INSERTEDPKG_AND_DEPS "InsertedPkg ${EXPECTED_SIMPLECXX_AND_DEPS}") - set(EXPECTED_INSERTEDPKG_AND_DEPS_STR "${EXPECTED_INSERTEDPKG_AND_DEPS} ") -else() - set(EXPECTED_INSERTEDPKG_DEPS "") - set(EXPECTED_INSERTEDPKG_DEPS_STR "") -endif() - -tribits_get_package_enable_status(WithSubpackagesA WithSubpackagesA_enabled "") -if (WithSubpackagesA_enabled) - set(EXPECTED_A_AND_DEPS "A ${EXPECTED_SIMPLECXX_AND_DEPS}") - set(EXPECTED_A_AND_DEPS_STR "${EXPECTED_A_AND_DEPS} ") -else() - set(EXPECTED_A_AND_DEPS "") - set(EXPECTED_A_AND_DEPS_STR "") -endif() - -tribits_get_package_enable_status(WithSubpackagesB WithSubpackagesB_enabled "") -if (WithSubpackagesB_enabled) - set(EXPECTED_B_DEPS - "${EXPECTED_A_AND_DEPS_STR}${EXPECTED_INSERTEDPKG_AND_DEPS_STR}${EXPECTED_SIMPLECXX_AND_DEPS}") -endif() diff --git a/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt index 2d1325e65..295e359fa 100644 --- a/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt @@ -22,7 +22,17 @@ tribits_add_show_deprecated_warnings_option() add_subdirectory(src) tribits_add_test_directories(test) -include("${TribitsExampleProject_SOURCE_DIR}/cmake/ExpectedDepsStrings.cmake") +# Set a variable that will be used in downstream packages + +if (SimpleCxx_ENABLE_SimpleTpl) + set(simpletplText "simpletpl ") +else() + set(simpletplText) +endif() + +global_set(EXPECTED_SIMPLECXX_AND_DEPS + "SimpleCxx ${simpletplText}headeronlytpl") +tribits_pkg_export_cache_var(EXPECTED_SIMPLECXX_AND_DEPS) # # E) Do standard post processing diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt index 6508cd652..717246f3c 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/b/CMakeLists.txt @@ -2,7 +2,27 @@ tribits_subpackage(B) add_subdirectory(src) -include("${TribitsExampleProject_SOURCE_DIR}/cmake/ExpectedDepsStrings.cmake") +# Set variables that will be used in this package and downstream packages + +if (${PROJECT_NAME}_ENABLE_InsertedPkg) + global_set(EXPECTED_INSERTEDPKG_AND_DEPS "InsertedPkg ${EXPECTED_SIMPLECXX_AND_DEPS}") + global_set(EXPECTED_INSERTEDPKG_AND_DEPS_STR "${EXPECTED_INSERTEDPKG_AND_DEPS} ") +else() + global_set(EXPECTED_INSERTEDPKG_DEPS "") + global_set(EXPECTED_INSERTEDPKG_DEPS_STR "") +endif() + +if (${PROJECT_NAME}_ENABLE_WithSubpackagesA) + global_set(EXPECTED_A_AND_DEPS "A ${EXPECTED_SIMPLECXX_AND_DEPS}") + global_set(EXPECTED_A_AND_DEPS_STR "${EXPECTED_A_AND_DEPS} ") +else() + global_set(EXPECTED_A_AND_DEPS "") + global_set(EXPECTED_A_AND_DEPS_STR "") +endif() + +global_set(EXPECTED_B_DEPS + "${EXPECTED_A_AND_DEPS_STR}${EXPECTED_INSERTEDPKG_AND_DEPS_STR}${EXPECTED_SIMPLECXX_AND_DEPS}") +tribits_pkg_export_cache_var(EXPECTED_B_DEPS) tribits_add_test_directories(tests) diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt index 26266ce10..696a5815c 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/c/CMakeLists.txt @@ -15,8 +15,6 @@ tribits_add_library(pws_c ${TAL_EXTRALIB_ARGS} # Used to show warnings and errors ) -include("${TribitsExampleProject_SOURCE_DIR}/cmake/ExpectedDepsStrings.cmake") - tribits_add_test_directories(tests) tribits_subpackage_postprocess() From a2790c86b840f0aeced66deb7464d8b6240dd34c Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 24 Jan 2023 19:31:14 -0700 Subject: [PATCH 18/45] Make WrapExernal work with external TribitsExProj packages (#63) So for there is just one test for this. To make this work, I had to grab the include directories off of the upstream targets, which are returned as generator expressions. And with that, I had to switch the generation of the makefile for external_func to build time with a custom command so it would evaluate the generator expressions. (There is no way to run a general command at generation time.) --- .../TribitsExampleProject_Tests.cmake | 12 ++-- .../packages/wrap_external/CMakeLists.txt | 56 +++++++++---------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index 08a7aa778..49b9f3c4d 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -3279,7 +3279,7 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON -DTribitsExProj_ENABLE_ALL_PACKAGES=ON -DTribitsExProj_ENABLE_TESTS=ON - #-DTribitsExProj_ENABLE_INSTALL_CMAKE_CONFIG_FILES=OFF # Allow WrapExternal enable + -DTribitsExProj_ENABLE_INSTALL_CMAKE_CONFIG_FILES=OFF # Allow WrapExternal enable -DTPL_ENABLE_SimpleCxx=ON -DCMAKE_PREFIX_PATH=../install/simple_cxx -DTPL_ENABLE_MPI=OFF @@ -3293,10 +3293,10 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx "Adjust the set of internal and external packages:" "-- Treating internal package SimpleCxx as EXTERNAL because TPL_ENABLE_SimpleCxx=ON" - "Final set of enabled top-level packages: MixedLang WithSubpackages 2" - "Final set of enabled packages: MixedLang WithSubpackagesA WithSubpackagesB WithSubpackagesC WithSubpackages 5" - "Final set of non-enabled top-level packages: WrapExternal 1" - "Final set of non-enabled packages: WrapExternal 1" + "Final set of enabled top-level packages: MixedLang WithSubpackages WrapExternal 3" + "Final set of enabled packages: MixedLang WithSubpackagesA WithSubpackagesB WithSubpackagesC WithSubpackages WrapExternal 6" + "Final set of non-enabled top-level packages: 0" + "Final set of non-enabled packages: 0" "Final set of enabled top-level external packages/TPLs: HeaderOnlyTpl SimpleTpl SimpleCxx 3" "Final set of enabled external packages/TPLs: HeaderOnlyTpl SimpleTpl SimpleCxx 3" "Final set of non-enabled top-level external packages/TPLs: MPI 1" @@ -3330,7 +3330,7 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx SKIP_CLEAN_WORKING_DIRECTORY CMND ${CMAKE_CTEST_COMMAND} PASS_REGULAR_EXPRESSION_ALL - "100% tests passed, 0 tests failed out of 7" + "100% tests passed, 0 tests failed out of 8" ALWAYS_FAIL_ON_NONZERO_RETURN ADDED_TEST_NAME_OUT TribitsExampleProject_External_SimpleCxx_NAME diff --git a/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt index 0efcd994f..ea7161b61 100644 --- a/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt @@ -7,21 +7,6 @@ # provides libraries that need to be cast as TriBITS CMake libraries. To # make this even more interesting, the external software has dependencies on # upstream TriBITS packages. -# -# An overview of the basic tasks required are: -# -# a) Enumerate the upstream packages and TPLs needed (this is done in the -# cmake/Dependencies.cmake file). -# -# b) Generate an export makefile for the upstream packages and TPLs -# -# c) Call the configure script for the external package passing the compilers, -# compiler flags, and a pointer to the export makefile (which is just used to -# lift the include dirs and libs). -# -# d) Define library targets for the external project and define a build rule -# for generating those libraries given the list of header and source files in -# the external project. tribits_package(WrapExternal) @@ -66,41 +51,51 @@ endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" upperBuildType) -set(includeDirsList - -I ${WithSubpackagesA_SOURCE_DIR} - -I ${SimpleCxx_SOURCE_DIR}/src - -I ${SimpleCxx_BINARY_DIR}/src - ) +get_target_property(simpleCxx_IncludeDirs + SimpleCxx::simplecxx INTERFACE_INCLUDE_DIRECTORIES) + +get_target_property(withSubpackagesA_IncludeDirs + WithSubpackagesA::pws_a INTERFACE_INCLUDE_DIRECTORIES) + +set(includeDirsList ${withSubpackagesA_IncludeDirs} ${simpleCxx_IncludeDirs}) + if (${PACKAGE_NAME}_ENABLE_MixedLang) - list(PREPEND includeDirsList - -I ${MixedLang_SOURCE_DIR}/src - -I ${MixedLang_BINARY_DIR}/src - ) + get_target_property(mixedLang_IncludeDirs + MixedLang::mixedlang INTERFACE_INCLUDE_DIRECTORIES) + list(PREPEND includeDirsList ${mixedLang_IncludeDirs}) endif() -list(JOIN includeDirsList " " includeDirs) -# NOTE: TriBITS export Makefile support used to handle the above stuff -# automatically but that is what you give up when moving to modern CMake. +list(JOIN includeDirsList " -I" includeDirsCompileOptions) +set(includeDirsCompileOptions "-I${includeDirsCompileOptions}") # -# C) Do configuration of the external project +# C) Do configuration of the external project as a build target # set(EXTERNAL_FUNC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external_func) set(EXTERNAL_FUNC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/external_func) set(EXTERNAL_FUNC_LIB_FILE ${EXTERNAL_FUNC_BINARY_DIR}/libexternal_func.a) +set(EXTERNAL_FUNC_MAKEFILE ${EXTERNAL_FUNC_BINARY_DIR}/Makefile) file(MAKE_DIRECTORY ${EXTERNAL_FUNC_BINARY_DIR}) -execute_process( +add_custom_command( + OUTPUT ${EXTERNAL_FUNC_MAKEFILE} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${EXTERNAL_FUNC_SOURCE_DIR}/configure.py COMMAND ${PYTHON_EXECUTABLE} ${EXTERNAL_FUNC_SOURCE_DIR}/configure.py "--cxx=${CMAKE_CXX_COMPILER}" "--cxx-flags=${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${upperBuildType}}" "--ar=${CMAKE_AR}" - "--include-dirs=${includeDirs}" + "--include-dirs=${includeDirsCompileOptions}" "--src-dir=${EXTERNAL_FUNC_SOURCE_DIR}" "--build-dir=${EXTERNAL_FUNC_BINARY_DIR}" ) +# NOTE: Above, we have to run the configure.py script at build time after +# generation because ${includeDirsCompileOptions} contains generation +# expressions that are evaluated at generation time by the +# add_custom_command() call. + # # D) Define a custom build rule and target to create external_func library # @@ -109,6 +104,7 @@ add_custom_command( OUTPUT ${EXTERNAL_FUNC_LIB_FILE} DEPENDS ${EXTERNAL_FUNC_SOURCE_DIR}/external_func.hpp ${EXTERNAL_FUNC_SOURCE_DIR}/external_func.cpp + ${EXTERNAL_FUNC_MAKEFILE} COMMAND make ${CTEST_BUILD_FLAGS} WORKING_DIRECTORY ${EXTERNAL_FUNC_BINARY_DIR} ) From 3065298c1623e72cc6c2686ad89e2589686c541b Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 25 Jan 2023 10:03:45 -0700 Subject: [PATCH 19/45] Add option _SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES (#63) See updated documentation --- .../TribitsExampleProject_Tests.cmake | 26 ++++++++++++++----- tribits/CHANGELOG.md | 5 ++++ .../CMakeLists.txt | 3 ++- .../package_arch/TribitsGlobalMacros.cmake | 10 ++++++- .../build_ref/TribitsBuildReferenceBody.rst | 13 ++++++++++ .../guides/TribitsCoreDetailedReference.rst | 14 ++++++++++ 6 files changed, 62 insertions(+), 9 deletions(-) diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index 49b9f3c4d..7bb303c22 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -3236,7 +3236,7 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON -DTribitsExProj_ENABLE_SimpleCxx=ON -DCMAKE_INSTALL_PREFIX=../install/simple_cxx - # ToDo: Add option to stop install of TribitsExProjConfig.cmake ... + -DTribitsExProj_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=TRUE -DTPL_ENABLE_MPI=OFF -DTPL_ENABLE_SimpleTpl=ON -DSimpleTpl_INCLUDE_DIRS=${SimpleTpl_install_STATIC_DIR}/install/include @@ -3259,17 +3259,26 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx SKIP_CLEAN_WORKING_DIRECTORY TEST_4 + MESSAGE "Make sure only SimpleCxxConfig.cmake was installed" + CMND ls ARGS install/simple_cxx/lib/cmake + PASS_REGULAR_EXPRESSION_ALL + "SimpleCxx" + FAIL_REGULAR_EXPRESSION + "TribitsExProj" + ALWAYS_FAIL_ON_NONZERO_RETURN + + TEST_5 MESSAGE "Remove the build directory for SimpleCxx" CMND ${CMAKE_COMMAND} ARGS -E rm -R Build_SimpleCxx - TEST_5 + TEST_6 MESSAGE "Remove the source directory for SimpleCxx" CMND ${CMAKE_COMMAND} ARGS -E rm -R TribitsExampleProject/packages/simple_cxx/CMakeLists.txt TribitsExampleProject/packages/simple_cxx/src TribitsExampleProject/packages/simple_cxx/test - TEST_6 + TEST_7 MESSAGE "Configure rest of TribitsExampleProject against pre-installed SimpleCxx" CMND ${CMAKE_COMMAND} WORKING_DIRECTORY Build @@ -3318,13 +3327,13 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx "Configuring done" ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_7 + TEST_8 MESSAGE "Build TribitsExampleProject" CMND make ARGS ${CTEST_BUILD_FLAGS} WORKING_DIRECTORY Build SKIP_CLEAN_WORKING_DIRECTORY - TEST_8 + TEST_9 MESSAGE "Run all the tests with ctest" WORKING_DIRECTORY Build SKIP_CLEAN_WORKING_DIRECTORY @@ -3338,8 +3347,11 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx # NOTE: The above test is a strong check that SimpleCxx is built and installed # first and then is used in the later build of the rest of # TribitsExampleProject. If you comment out -DTPL_ENABLE_SimpleCxx=ON, then -# it will not build! - +# it will not build! This test also uniquely tests a few other TriBITS features: +# +# * _SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES (ensures the directory +# * install/simple_cxx/lib/cmake/TribitsExProj does not get created and +# * therefore the file TribitsExProjConfig.cmake does not get installed). if (TribitsExampleProject_External_SimpleCxx_NAME) set_tests_properties(${TribitsExampleProject_External_SimpleCxx_NAME} diff --git a/tribits/CHANGELOG.md b/tribits/CHANGELOG.md index fefa42336..cafcd92eb 100644 --- a/tribits/CHANGELOG.md +++ b/tribits/CHANGELOG.md @@ -4,6 +4,11 @@ ChangeLog for TriBITS ## 2023-10-25: +* **Added:** New option `_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES` + skips the install of the project-level `Config.cmake` file. The + default value is ``FALSE`` so as to maintain backward compatibility. (The + project can change the default.) + * **Changed:** External packages/TPLs are now processed at the base project scope level. This allows simple `set()` statements in package module files or config files included by `find_package()` to have project-level scope for diff --git a/tribits/core/installation/add_project_install_commands/CMakeLists.txt b/tribits/core/installation/add_project_install_commands/CMakeLists.txt index 14054ad19..e6d18a739 100644 --- a/tribits/core/installation/add_project_install_commands/CMakeLists.txt +++ b/tribits/core/installation/add_project_install_commands/CMakeLists.txt @@ -2,7 +2,8 @@ set(tribits_install_src "${${PROJECT_NAME}_TRIBITS_DIR}/${TRIBITS_CMAKE_INSTALLATION_FILES_DIR}") if ( ${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES - AND NOT ${PROJECT_NAME}_ENABLE_INSTALLATION_TESTING + AND (NOT ${PROJECT_NAME}_ENABLE_INSTALLATION_TESTING) + AND (NOT ${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES) ) include(TribitsWriteClientExportFiles) diff --git a/tribits/core/package_arch/TribitsGlobalMacros.cmake b/tribits/core/package_arch/TribitsGlobalMacros.cmake index fb18d81fb..dda34b977 100644 --- a/tribits/core/package_arch/TribitsGlobalMacros.cmake +++ b/tribits/core/package_arch/TribitsGlobalMacros.cmake @@ -597,13 +597,21 @@ macro(tribits_define_global_options_and_define_extra_repos) if ("${${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES_DEFAULT}" STREQUAL "") set(${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES_DEFAULT OFF) endif() - advanced_set(${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES ${${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES_DEFAULT} CACHE BOOL "Determines if ${PROJECT_NAME}Config.cmake and Config.cmake files are created or not." ) + if ("${${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES_DEFAULT}" STREQUAL "") + set(${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES_DEFAULT OFF) + endif() + advanced_set(${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES + ${${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES_DEFAULT} + CACHE BOOL + "Skip installing the file ${PROJECT_NAME}Config.cmake." + ) + if (NOT ${PROJECT_NAME}_GENERATE_EXPORT_FILE_DEPENDENCIES_DEFAULT) # We need to generate the dependency logic for export dependency files if # asked. diff --git a/tribits/doc/build_ref/TribitsBuildReferenceBody.rst b/tribits/doc/build_ref/TribitsBuildReferenceBody.rst index 07f0570a2..ad3878827 100644 --- a/tribits/doc/build_ref/TribitsBuildReferenceBody.rst +++ b/tribits/doc/build_ref/TribitsBuildReferenceBody.rst @@ -2816,6 +2816,12 @@ of packages the files are requested for with:: -D _GENERATE_EXPORT_FILES_FOR_ONLY_LISTED_PACKAGES=";" +To only install the package ``Config.cmake`` files and **not** the +project-level ``Config.cmake`` file, configure with:: + + -D _ENABLE_INSTALL_CMAKE_CONFIG_FILES=ON \ + -D _SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=ON \ + NOTES: * Only enabled packages will have their export files generated. @@ -2823,6 +2829,13 @@ NOTES: * One would only want to limit the export files generated for very large projects where the cost my be high for doing so. +* One would want to skip the installation of the project-level + ``Config.cmake`` file in cases where the TriBITS project's packages + may be built in smaller subsets of packages in different individual CMake + project builds where there is no clear completion to the installation of the + packages for a given TriBITS project containing a larger collection of + packages. + Generating a project repo version file -------------------------------------- diff --git a/tribits/doc/guides/TribitsCoreDetailedReference.rst b/tribits/doc/guides/TribitsCoreDetailedReference.rst index 2cc0fb95e..50a90c79a 100644 --- a/tribits/doc/guides/TribitsCoreDetailedReference.rst +++ b/tribits/doc/guides/TribitsCoreDetailedReference.rst @@ -89,6 +89,7 @@ a given TriBITS project are: * `${PROJECT_NAME}_REQUIRES_PYTHON`_ * `${PROJECT_NAME}_SET_INSTALL_RPATH`_ * `${PROJECT_NAME}_SHOW_TEST_START_END_DATE_TIME`_ +* `${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES`_ * `${PROJECT_NAME}_TEST_CATEGORIES`_ * `${PROJECT_NAME}_TPL_SYSTEM_INCLUDE_DIRS`_ * `${PROJECT_NAME}_TRACE_ADD_TEST`_ @@ -671,6 +672,19 @@ These options are described below. date/time for regular tests added with `tribits_add_test()`_ (which uses a raw command with ``add_test()``). +.. _${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES: + +**${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES** + + To change the default value of the + ``${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES`` to ``TRUE``, for + example, for a TriBITS project, set:: + + set(${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES_DEFAULT TRUE) + + in the project's `/CMakeLists.txt`_ or + `/ProjectName.cmake`_ files. + .. _${PROJECT_NAME}_SKIP_EXTRAREPOS_FILE: **${PROJECT_NAME}_SKIP_EXTRAREPOS_FILE** From aa843a40170f2a02e2f2b5d1fc3362590eb011b0 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Thu, 26 Jan 2023 19:54:23 -0700 Subject: [PATCH 20/45] WIP: Rename TribitsProcessEnabledTpl.cmake to TribitsProcessEnabledTpls.cmake (#63) This is setting up for a refactoring to put tribits_process_eanbled_tpls() into this module. --- tribits/core/package_arch/TribitsGlobalMacros.cmake | 2 +- ...sProcessEnabledTpl.cmake => TribitsProcessEnabledTpls.cmake} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tribits/core/package_arch/{TribitsProcessEnabledTpl.cmake => TribitsProcessEnabledTpls.cmake} (100%) diff --git a/tribits/core/package_arch/TribitsGlobalMacros.cmake b/tribits/core/package_arch/TribitsGlobalMacros.cmake index dda34b977..94c82c494 100644 --- a/tribits/core/package_arch/TribitsGlobalMacros.cmake +++ b/tribits/core/package_arch/TribitsGlobalMacros.cmake @@ -44,7 +44,7 @@ include(TribitsTestCategories) include(TribitsGeneralMacros) include(TribitsAddTestHelpers) include(TribitsVerbosePrintVar) -include(TribitsProcessEnabledTpl) +include(TribitsProcessEnabledTpls) include(TribitsInstallHeaders) include(TribitsGetVersionDate) include(TribitsReportInvalidTribitsUsage) diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpl.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake similarity index 100% rename from tribits/core/package_arch/TribitsProcessEnabledTpl.cmake rename to tribits/core/package_arch/TribitsProcessEnabledTpls.cmake From 8e112e0222a46aefdabd267d74d2c701697a44a3 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Thu, 26 Jan 2023 16:45:08 -0700 Subject: [PATCH 21/45] Add basic special handling for fully TriBITS-compliant external packages (#63) Now we don't need to find upstream TPLs already found in upstream TriBITS package configure and build. In this case, we don't need to find HeaderOnlyTpl or SimpleTpl already found in the configure and build of SimpleCxx. But this does not yet support stagged sets of package installs. That will come next. --- .../TribitsExampleProject_Tests.cmake | 22 +++--- test/core/ProcessEnabledTpls/CMakeLists.txt | 18 ++--- ...ibitsProcessEnabledTplTesterCMakeLists.txt | 4 +- .../TribitsAdjustPackageEnables.cmake | 72 +++++++++++++++--- .../package_arch/TribitsGlobalMacros.cmake | 19 ----- .../TribitsProcessEnabledTpls.cmake | 76 ++++++++++++++++--- .../TribitsProcessPackagesAndDirsLists.cmake | 2 + .../TribitsProcessTplsLists.cmake | 9 +++ .../package_arch/TribitsProjectImpl.cmake | 4 - ...itsSystemDataStructuresMacrosFunctions.rst | 76 +++++++++++++++++++ tribits/core/std_tpls/FindTPLMPI.cmake | 6 +- tribits/doc/guides/TribitsGuidesBody.rst | 9 ++- .../TribitsMacroFunctionDocTemplate.rst | 2 +- 13 files changed, 249 insertions(+), 70 deletions(-) diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index 7bb303c22..69a74ab11 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -2569,7 +2569,7 @@ tribits_add_advanced_test( TribitsExampleProject_HeaderOnlyTpl_FailThenPass "When you reconfigure, just grep the cmake stdout for 'HeaderOnlyTpl'" "and then follow the disables that occur as a result to see what impact" "this TPL disable has on the configuration of TribitsExProj." - "CMake Error at .+/TribitsProcessEnabledTpl[.]cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" " ERROR: TPL_HeaderOnlyTpl_NOT_FOUND=TRUE, aborting!" "Call Stack .most recent call first.:" "-- Configuring incomplete, errors occurred!" @@ -2624,7 +2624,7 @@ tribits_add_advanced_test( TribitsExampleProject_HeaderOnlyTpl_HardEnable_Fail "and then follow the disables that occur as a result to see what impact" "this TPL disable has on the configuration of TribitsExProj." "-- ERROR: Failed finding all of the parts of TPL 'HeaderOnlyTpl' .see above., Aborting!" - "CMake Error at .+/TribitsProcessEnabledTpl[.]cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" " ERROR: TPL_HeaderOnlyTpl_NOT_FOUND=TRUE, aborting!" "Call Stack .most recent call first.:" "-- Configuring incomplete, errors occurred!" @@ -3293,14 +3293,12 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx -DCMAKE_PREFIX_PATH=../install/simple_cxx -DTPL_ENABLE_MPI=OFF -DTPL_ENABLE_SimpleTpl=ON - -DSimpleTpl_INCLUDE_DIRS=${SimpleTpl_install_STATIC_DIR}/install/include - -DSimpleTpl_LIBRARY_DIRS=${SimpleTpl_install_STATIC_DIR}/install/lib - # ToDo: Remove how to find SimpleTpl because SimpleCxx should already - # have that found and we should just use what it found! ../TribitsExampleProject PASS_REGULAR_EXPRESSION_ALL "Adjust the set of internal and external packages:" "-- Treating internal package SimpleCxx as EXTERNAL because TPL_ENABLE_SimpleCxx=ON" + "-- NOTE: HeaderOnlyTpl is directly downstream from an fully TriBITS-compatible external package SimpleCxx" + "-- NOTE: SimpleTpl is directly downstream from an fully TriBITS-compatible external package SimpleCxx" "Final set of enabled top-level packages: MixedLang WithSubpackages WrapExternal 3" "Final set of enabled packages: MixedLang WithSubpackagesA WithSubpackagesB WithSubpackagesC WithSubpackages WrapExternal 6" @@ -3311,18 +3309,20 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx "Final set of non-enabled top-level external packages/TPLs: MPI 1" "Final set of non-enabled external packages/TPLs: MPI 1" - "Getting information for all enabled external packages/TPLs ..." + "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." "Processing enabled external package/TPL: HeaderOnlyTpl [(]enabled by SimpleCxx, disable with -DTPL_ENABLE_HeaderOnlyTpl=OFF[)]" - "-- TPL_HeaderOnlyTpl_INCLUDE_DIRS='.*/tribits/examples/tpls/HeaderOnlyTpl'" + "-- The external package/TPL HeaderOnlyTpl will be read in by a downstream fully TriBITS-compliant external package" "Processing enabled external package/TPL: SimpleTpl [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleTpl=OFF[)]" - "-- TPL_SimpleTpl_LIBRARIES='.*/TriBITS_SimpleTpl_install_STATIC/install/lib/libsimpletpl.a'" - "-- TPL_SimpleTpl_INCLUDE_DIRS='.*/TriBITS_SimpleTpl_install_STATIC/install/include'" + "-- The external package/TPL SimpleTpl will be read in by a downstream fully TriBITS-compliant external package" "Processing enabled external package/TPL: SimpleCxx [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleCxx=OFF[)]" - "-- Calling find_package[(]SimpleCxx[)] for TriBITS-compatible package ..." + "-- Calling find_package[(]SimpleCxx[)] for TriBITS-compatible package" + + "Getting information for all enabled external packages/TPLs ..." "Configuring individual enabled TribitsExProj packages ..." "Processing enabled top-level package: MixedLang [(]Libs, Tests, Examples[)]" "Processing enabled top-level package: WithSubpackages [(]A, B, C, Tests, Examples[)]" + "Processing enabled top-level package: WrapExternal [(]Libs, Tests, Examples[)]" "Configuring done" ALWAYS_FAIL_ON_NONZERO_RETURN diff --git a/test/core/ProcessEnabledTpls/CMakeLists.txt b/test/core/ProcessEnabledTpls/CMakeLists.txt index a7bb7e0c0..743bc410e 100644 --- a/test/core/ProcessEnabledTpls/CMakeLists.txt +++ b/test/core/ProcessEnabledTpls/CMakeLists.txt @@ -223,7 +223,7 @@ create_process_enabled_tpls_test_case( "When you reconfigure, just grep the cmake stdout for 'HeaderOnlyTpl'" "and then follow the disables that occur as a result to see what impact" "this TPL disable has on the configuration of DummyProj." - "CMake Error at .+/TribitsProcessEnabledTpl[.]cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeaderOnlyTpl_NOT_FOUND=TRUE, aborting!" ) @@ -244,7 +244,7 @@ create_process_enabled_tpls_test_case( "and then follow the disables that occur as a result to see what impact" "this TPL disable has on the configuration of ${MOCK_PROJECT_NAME}." "-- ERROR: Failed finding all of the parts of TPL 'HeaderOnlyTpl' .see above., Aborting!" - "CMake Error at .+/TribitsProcessEnabledTpl[.]cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeaderOnlyTpl_NOT_FOUND=TRUE, aborting!" ) @@ -481,7 +481,7 @@ create_process_enabled_tpls_test_case( "When you reconfigure, just grep the cmake stdout for 'HeadersAndLibsTpl'" "and then follow the disables that occur as a result to see what impact" "this TPL disable has on the configuration of DummyProj." - "CMake Error at .+/TribitsProcessEnabledTpl.cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeadersAndLibsTpl_NOT_FOUND=TRUE, aborting!" ) @@ -503,7 +503,7 @@ create_process_enabled_tpls_test_case( "-- TIP: If the TPL 'HeadersAndLibsTpl' is on your system then you can set:" "-- ERROR: Failed finding all of the parts of TPL 'HeadersAndLibsTpl' .see above., Aborting!" "TIP: One way to get past the configure failure for the" - "CMake Error at .+/TribitsProcessEnabledTpl.cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeadersAndLibsTpl_NOT_FOUND=TRUE, aborting!" ) @@ -526,7 +526,7 @@ create_process_enabled_tpls_test_case( "-- TIP: If the TPL 'HeadersAndLibsTpl' is on your system then you can set:" "-- ERROR: Failed finding all of the parts of TPL 'HeadersAndLibsTpl' .see above., Aborting!" "TIP: One way to get past the configure failure for the" - "CMake Error at .+/TribitsProcessEnabledTpl.cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeadersAndLibsTpl_NOT_FOUND=TRUE, aborting!" ) @@ -545,7 +545,7 @@ create_process_enabled_tpls_test_case( "-- Searching for libs in HeadersAndLibsTpl_LIBRARY_DIRS='.+/HeadersAndLibsTpl/lib'" "-- Searching for a lib in the set .badlibname.:" "-- NOTE: Did not find a lib in the lib set .badlibname. for the TPL 'HeadersAndLibsTpl'!" - "CMake Error at .+/TribitsProcessEnabledTpl.cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeadersAndLibsTpl_NOT_FOUND=TRUE, aborting!" ) @@ -563,7 +563,7 @@ create_process_enabled_tpls_test_case( "-- Searching for libs in HeadersAndLibsTpl_LIBRARY_DIRS='.+/HeadersAndLibsTpl/lib'" "-- Searching for a lib in the set .badlibname.:" "-- ERROR: Did not find a lib in the lib set .badlibname. for the TPL 'HeadersAndLibsTpl'!" - "CMake Error at .+/TribitsProcessEnabledTpl.cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeadersAndLibsTpl_NOT_FOUND=TRUE, aborting!" ) @@ -603,7 +603,7 @@ create_process_enabled_tpls_test_case( "-- Searching for libs in HeadersAndLibsTpl_LIBRARY_DIRS='.+/HeadersAndLibsTpl/lib'" "-- Searching for a lib in the set .badlibname.:" "-- ERROR: Did not find a lib in the lib set .badlibname. for the TPL 'HeadersAndLibsTpl'!" - "CMake Error at .+/TribitsProcessEnabledTpl.cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeadersAndLibsTpl_NOT_FOUND=TRUE, aborting!" ) @@ -626,7 +626,7 @@ create_process_enabled_tpls_test_case( "-- TIP: If the TPL 'HeadersAndLibsTpl' is on your system then you can set:" "-- ERROR: Failed finding all of the parts of TPL 'HeadersAndLibsTpl' .see above., Aborting!" "TIP: Even though the TPL 'HeadersAndLibsTpl' was explicitly enabled in input," - "CMake Error at .+/TribitsProcessEnabledTpl.cmake:[0-9]+ [(]message[)]:" + "CMake Error at .+/TribitsProcessEnabledTpls[.]cmake:[0-9]+ [(]message[)]:" "ERROR: TPL_HeadersAndLibsTpl_NOT_FOUND=TRUE, aborting!" ) diff --git a/test/core/ProcessEnabledTpls/TribitsProcessEnabledTplTesterCMakeLists.txt b/test/core/ProcessEnabledTpls/TribitsProcessEnabledTplTesterCMakeLists.txt index f80450482..ac1956339 100644 --- a/test/core/ProcessEnabledTpls/TribitsProcessEnabledTplTesterCMakeLists.txt +++ b/test/core/ProcessEnabledTpls/TribitsProcessEnabledTplTesterCMakeLists.txt @@ -56,7 +56,7 @@ set( CMAKE_MODULE_PATH "${${PROJECT_NAME}_TRIBITS_DIR}/core/package_arch" ) -include(TribitsProcessEnabledTpl) +include(TribitsProcessEnabledTpls) # Passed in on command-line print_var("TPL_NAME") @@ -72,7 +72,7 @@ endif() # Do the processing of the TPL message("") -tribits_process_enabled_tpl(${TPL_NAME}) +tribits_process_enabled_standard_tpl(${TPL_NAME}) message("") message("Exported TPL_ENABLE_${TPL_NAME}='${TPL_ENABLE_${TPL_NAME}}'") message("Exported TPL_${TPL_NAME}_NOT_FOUND='${TPL_${TPL_NAME}_NOT_FOUND}'") diff --git a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake index 172888759..e99e6161b 100644 --- a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake +++ b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake @@ -853,6 +853,11 @@ macro(tribits_set_package_and_related_upstream_packages_to_external packageName tribits_set_upstream_dep_packages_as_external(${packageName} ${subpackageTriggeredParentPackageExternal}) + if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") + tribits_set_package_and_deps_as_processed_by_downstream_tribits_external_package( + ${packageName}) + endif() + endmacro() # NOTE: In the above macro, if ${packageName} is made EXTERNAL because it one # of its subpackages is considered EXTERNAL, then the loop over all of the @@ -1315,6 +1320,48 @@ macro(tribits_set_upstream_dep_packages_as_external packageName endmacro() +# Macro that sets all of the direct upstream dependent packages as being +# processed by a downstream fully TriBITS compliant external package. +macro(tribits_set_package_and_deps_as_processed_by_downstream_tribits_external_package + packageName + ) + + if ("${${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE}" + STREQUAL "" + ) + set(${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE FALSE) + endif() + + tribits_get_package_enable_status(${packageName} packageEnable "") + + if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL" + AND (${packageName}_IS_FULLY_TRIBITS_COMPLIANT + OR ${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) + ) + + if (${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) + set(directOrIndirectStr "indirectly") + set(downstreamPkgStr "") + else() + set(directOrIndirectStr "directly") + set(downstreamPkgStr " ${packageName}") + endif() + + foreach(depPkg IN LISTS ${packageName}_LIB_DEFINED_DEPENDENCIES) + tribits_get_package_enable_status(${depPkg} depPkgEnable "") + if (depPkgEnable) + message("-- " + "NOTE: ${depPkg} is ${directOrIndirectStr} downstream from an fully" + " TriBITS-compatible external package${downstreamPkgStr}") + endif() + set(${depPkg}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE TRUE) + endforeach() + + endif() + +endmacro() + + # Macro that sets ``_ENABLE_=ON`` if not already # enabled for all enabled subpackages of a parent package. # @@ -1360,21 +1407,28 @@ endmacro() # # Usage:: # -# tribits_set_internal_package_to_external( "" +# tribits_set_internal_package_to_external( "" # "" ...) # -# This always sets ``_PACKAGE_BUILD_STATUS=EXTERNAL`` but only -# prints the message if ```` is enabled. +# This always sets ``_PACKAGE_BUILD_STATUS=EXTERNAL`` but only +# prints the message if ```` is enabled. # -macro(tribits_set_internal_package_to_external packageName) - tribits_get_package_enable_status(${packageName} packageEnable packageEnableVar) - if (packageEnable) +macro(tribits_set_internal_package_to_external depPkgName) + tribits_get_package_enable_status(${depPkgName} depPkgEnable "") + if (depPkgEnable) message("-- " - "Treating internal package ${packageName} as EXTERNAL because" + "Treating internal package ${depPkgName} as EXTERNAL because" " " ${ARGN}) endif() - set(${packageName}_PACKAGE_BUILD_STATUS EXTERNAL) - set(${packageName}_FINDMOD TRIBITS_PKG) + set(${depPkgName}_PACKAGE_BUILD_STATUS EXTERNAL) + set(${depPkgName}_FINDMOD TRIBITS_PKG) +endmacro() + + +macro(tribits_set_as_processed_by_downstream_tribits_external_package packageName + depPkgName + ) + endmacro() diff --git a/tribits/core/package_arch/TribitsGlobalMacros.cmake b/tribits/core/package_arch/TribitsGlobalMacros.cmake index 94c82c494..3ebfa7d9b 100644 --- a/tribits/core/package_arch/TribitsGlobalMacros.cmake +++ b/tribits/core/package_arch/TribitsGlobalMacros.cmake @@ -1482,25 +1482,6 @@ macro(tribits_handle_project_extra_link_flags_as_a_tpl) endmacro() -# Gather information from enabled TPLs -# -macro(tribits_process_enabled_tpls) - - tribits_config_code_start_timer(CONFIGURE_TPLS_TIME_START_SECONDS) - - tribits_filter_package_list_from_var(${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES - EXTERNAL ON NONEMPTY ${PROJECT_NAME}_enabledExternalTopLevelPackages) - - foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) - tribits_process_enabled_tpl(${TPL_NAME}) - endforeach() - - tribits_config_code_stop_timer(CONFIGURE_TPLS_TIME_START_SECONDS - "\nTotal time to configure enabled external packages/TPLs") - -endmacro() - - # # Macros for setting up the standard environment # diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake index 52f925abb..303697bb8 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake @@ -49,11 +49,69 @@ include(AppendStringVar) include(TribitsStandardizePaths) -# @MACRO: tribits_process_enabled_tpl() +# Gather information from enabled TPLs +# +macro(tribits_process_enabled_tpls) + + tribits_config_code_start_timer(CONFIGURE_TPLS_TIME_START_SECONDS) + + tribits_filter_package_list_from_var(${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES + EXTERNAL ON NONEMPTY ${PROJECT_NAME}_enabledExternalTopLevelPackages) + + message("") + message("Getting information for all enabled fully TriBITS-compatible" + " or upstream external packages/TPLs ...") + message("") + + foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) + if (${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT + OR ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE + ) + tribits_process_enabled_fully_tribits_compatible_or_upstream_tpl(${TPL_NAME}) + endif() + endforeach() + + message("") + message("Getting information for all enabled external packages/TPLs ...") + message("") + + foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) + if ((NOT ${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT) + AND (NOT ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) + ) + tribits_process_enabled_standard_tpl(${TPL_NAME}) + endif() + endforeach() + + tribits_config_code_stop_timer(CONFIGURE_TPLS_TIME_START_SECONDS + "\nTotal time to configure enabled external packages/TPLs") + +endmacro() + + +macro(tribits_process_enabled_fully_tribits_compatible_or_upstream_tpl TPL_NAME) + + tribits_get_enabled_tpl_processing_string(${TPL_NAME} tplProcessingString) + message("${tplProcessingString}") + + if (NOT ${PROJECT_NAME}_TRACE_DEPENDENCY_HANDLING_ONLY) + if (NOT ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) + tribits_process_enabled_tribits_compatible_tpl(${TPL_NAME}) + else() + message("-- " + "The external package/TPL ${TPL_NAME} will be read in by a downstream" + " fully TriBITS-compliant external package") + endif() + endif() + +endmacro() + + +# @MACRO: tribits_process_enabled_standard_tpl() # # Process an enabled TPL's FindTPL${TPL_NAME}.cmake module. # -macro(tribits_process_enabled_tpl TPL_NAME) +macro(tribits_process_enabled_standard_tpl TPL_NAME) tribits_get_enabled_tpl_processing_string(${TPL_NAME} tplProcessingString) message("${tplProcessingString}") @@ -65,14 +123,10 @@ macro(tribits_process_enabled_tpl TPL_NAME) print_var(${TPL_NAME}_FINDMOD) endif() - if (${TPL_NAME}_FINDMOD STREQUAL "TRIBITS_PKG") - tribits_process_enabled_tribits_compatible_tpl(${TPL_NAME}) - else() - tribits_process_enabled_tribits_find_tpl_mod_file(${TPL_NAME}) - tribits_address_failed_tpl_find(${TPL_NAME}) - tribits_generate_tpl_version_file_and_add_package_config_install_targets( - ${TPL_NAME}) - endif() + tribits_process_enabled_tribits_find_tpl_mod_file(${TPL_NAME}) + tribits_address_failed_tpl_find(${TPL_NAME}) + tribits_generate_tpl_version_file_and_add_package_config_install_targets( + ${TPL_NAME}) endif() @@ -98,7 +152,7 @@ endfunction() # macro(tribits_process_enabled_tribits_compatible_tpl TPL_NAME) message("-- " - "Calling find_package(${TPL_NAME}) for TriBITS-compatible package ...") + "Calling find_package(${TPL_NAME}) for TriBITS-compatible package") set(TPL_${TPL_NAME}_PARTS_ALREADY_SET FALSE) # ToDo: Take out? if (NOT TPL_${TPL_NAME}_PARTS_ALREADY_SET) find_package(${TPL_NAME} CONFIG REQUIRED) diff --git a/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake b/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake index d045fdedf..76bc1e7f8 100644 --- a/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake +++ b/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake @@ -572,6 +572,7 @@ macro(tribits_process_packages_and_dirs_lists REPOSITORY_NAME REPOSITORY_DIR) set(${TRIBITS_PACKAGE}_PARENT_REPOSITORY ${REPOSITORY_NAME}) tribits_insert_standard_package_options(${TRIBITS_PACKAGE} ${PACKAGE_TESTGROUP}) set(${TRIBITS_PACKAGE}_PACKAGE_BUILD_STATUS INTERNAL) + set(${TRIBITS_PACKAGE}_IS_FULLY_TRIBITS_COMPLIANT TRUE) else() if (${PROJECT_NAME}_VERBOSE_CONFIGURE) message( @@ -593,6 +594,7 @@ macro(tribits_process_packages_and_dirs_lists REPOSITORY_NAME REPOSITORY_DIR) print_var(${TRIBITS_PACKAGE}_PARENT_PACKAGE) print_var(${TRIBITS_PACKAGE}_PARENT_REPOSITORY) print_var(${TRIBITS_PACKAGE}_PACKAGE_BUILD_STATUS) + print_var(${TRIBITS_PACKAGE}_IS_FULLY_TRIBITS_COMPLIANT) endif() if (TRIBITS_PROCESS_PACKAGES_AND_DIRS_LISTS_VERBOSE) diff --git a/tribits/core/package_arch/TribitsProcessTplsLists.cmake b/tribits/core/package_arch/TribitsProcessTplsLists.cmake index 611dcf3f7..711169cb9 100644 --- a/tribits/core/package_arch/TribitsProcessTplsLists.cmake +++ b/tribits/core/package_arch/TribitsProcessTplsLists.cmake @@ -275,6 +275,14 @@ macro(tribits_process_tpls_lists REPOSITORY_NAME REPOSITORY_DIR) set(${TPL_NAME}_PACKAGE_BUILD_STATUS EXTERNAL) + # Set ${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT + + if (${TPL_NAME}_FINDMOD STREQUAL "TRIBITS_PKG") + set(${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT TRUE) + else() + set(${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT FALSE) + endif() + # Print variables/properties for the TPL if (${PROJECT_NAME}_VERBOSE_CONFIGURE OR TRIBITS_PROCESS_TPLS_LISTS_VERBOSE) @@ -283,6 +291,7 @@ macro(tribits_process_tpls_lists REPOSITORY_NAME REPOSITORY_DIR) print_var(${TPL_NAME}_DEPENDENCIES_FILE) print_var(${TPL_NAME}_TPLS_LIST_FILE) print_var(${TPL_NAME}_PACKAGE_BUILD_STATUS) + print_var(${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT) endif() # Set cache var TPL_ENABLE_${TPL_NAME} with default "" diff --git a/tribits/core/package_arch/TribitsProjectImpl.cmake b/tribits/core/package_arch/TribitsProjectImpl.cmake index 892cecc6b..f27caa3e6 100644 --- a/tribits/core/package_arch/TribitsProjectImpl.cmake +++ b/tribits/core/package_arch/TribitsProjectImpl.cmake @@ -190,10 +190,6 @@ macro(tribits_project_impl) # G) Go get the information for all enabled TPLS # - message("") - message("Getting information for all enabled external packages/TPLs ...") - message("") - tribits_process_enabled_tpls() # diff --git a/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst b/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst index f207dbe3a..1c58dffee 100644 --- a/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst +++ b/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst @@ -456,6 +456,82 @@ any subpackage is determined to be EXTERNAL, then the parent package of that subpackage and every other peer subpackage will also be set to EXTERNAL. +Processing of external packages/TPLs and fully TriBITS compatible external packages ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The processing of external packages/TPLs is influenced by whether the external +package is a regular TriBITS TPL or is a fully TriBITS-compliant external +package. Here, a **Fully TriBITS-Compliant External Package** has a +``Config.cmake`` file that satisfies the following properties: + +* Has the target ``::all_libs``. +* Calls ``find_dependency()`` for all upstream packages it depends on. +* Every upstream dependent package ```` has the target + ``::all_libs``. + +That means that when calling ``find_package()`` for a fully TriBITS compliant +external package, there is no need to worry about finding any of its upstream +dependent external packages. That means that any external packages/TPLs +defined a TriBITS project which is upstream from a fully TriBITS compliant +external package will be uniquely defined by calling ``find_package()`` on the +most downstream fully TriBITS-compliant external package that depends on it. +Therefore, defining the external packages and their targets in this set of +external packages just involves calling ``find_package()`` on the terminal +fully TriBITS-compliant external packages (i.e. fully TriBITS-compliant +external packages that don't have any downstream dependencies that are +external packages). Then the remaining subset of external packages/TPLs that +don't have a downstream fully TriBITS-compliant external package dependency +will be defined as usual. (ToDo: Put in a more detailed examples explaining +how this works.) + +The variables that are set internally to define these different subsets of +external packages/TPLs are: + +* ``_IS_FULLY_TRIBITS_COMPLIANT``: Set the ``TRUE`` if the package + ```` provides the ``::all_libs`` target for itself and all + of its upstream dependent (internal or external) packages (whether this + package is treated as an internal or external package). + +* ``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE``: Set to + ``TRUE`` if the external package/TPL will be processed by downstream TriBITS + complient package. In this case, we just print that we are skipping the + find operation and explain why. + +An external package with ``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` **AND** +``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=FALSE`` is the +one for which ``find_package( CONFIG REQUIRED)`` will be called and +does not have any downstream packages that are being treated as external +packages. + +The variable ``_IS_FULLY_TRIBITS_COMPLIANT`` is set right when the +packages are initially defined by reading in the various input files. That +is, all initially internal packages that are listed in a +`/PackagesList.cmake`_ file will have +``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` set. While all external +packages/TPLs listed in a `/TPLsList.cmake`_ file will have +``_IS_FULLY_TRIBITS_COMPLIANT=FALSE`` set (except for those tagged +with ``TRIBITS_PKG`` which will have +``_IS_FULLY_TRIBITS_COMPLIANT=FALSE`` set). + +NOTE: When a TriBITS TPL (i.e. ``_IS_FULLY_TRIBITS_COMPLIANT=FALSE``) +is being processed, we can't assume where its +``Config.cmake`` file exists so we must find upstream +dependencies using ``set(_DIR ...)`` and +``find_dependency( CONFIG REQUIRED)``. + +So the first loop over external packages/TPLs will be those external +packages/TPLs that have ``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` **OR** +``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=TRUE``. And we +only call ``find_package()`` for those fully TriBITS-complient external +packages that have ``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` **AND** +``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=FALSE``. + +The second loop are those external packages/TPLs that don't have a downstream +fully TriBITS-compliant external package which are all of those external +packages for which ``_IS_FULLY_TRIBITS_COMPLIANT=FALSE`` **AND** +``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=FALSE``. + + Other package-related variables +++++++++++++++++++++++++++++++ diff --git a/tribits/core/std_tpls/FindTPLMPI.cmake b/tribits/core/std_tpls/FindTPLMPI.cmake index f4917fd6a..dd555efd7 100644 --- a/tribits/core/std_tpls/FindTPLMPI.cmake +++ b/tribits/core/std_tpls/FindTPLMPI.cmake @@ -39,9 +39,9 @@ # Either the MPI compiler wrappers take care of these or the user has to set # the explicitly using basic compile flags and ${PROJECT_NAME}_EXTRA_LINK_FLAGS. -global_set(TPL_MPI_INCLUDE_DIRS) -global_set(TPL_MPI_LIBRARIES) -global_set(TPL_MPI_LIBRARY_DIRS) +global_set(TPL_MPI_INCLUDE_DIRS "") +global_set(TPL_MPI_LIBRARIES "") +global_set(TPL_MPI_LIBRARY_DIRS "") if(WIN32 AND TPL_ENABLE_MPI) find_package(MPI) diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index 9351b0bfd..ea02544d5 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -2307,7 +2307,14 @@ defined TPL ``TPL_NAME`` is assigned the following global non-cache variables: ``Repo1/TPLsList.cmake`` and ``Repo2/TPLsList.cmake`` both list the TPL ``SomeTpl``, then if ``Repo2`` is processed after ``Repo1``, then ``SomeTpl_FINDMOD`` is determined by ``Repo2/TPLsList.cmake`` and the find - module listed in ``Repo1/TPLsList.cmake`` is ignored. + module listed in ``Repo1/TPLsList.cmake`` is ignored. NOTE: The special + value ``TRIBITS_PKG`` is also recognized for external packages/TPLs that + are *fully TriBITS compliant* (i.e. defines a ``${TPL_NAME}Config.cmake`` + file provides the ``${TPL_NAME}::all_libs`` target, calls + ``find_dependency()`` on all of its upstream dependencies, + and each of those dependencies defines the ``::all_libs`` + target.) A pre-installed TriBITS package meets this definition, + obviously. .. __DEPENDENCIES_FILE: .. _${TPL_NAME}_DEPENDENCIES_FILE: diff --git a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst index 5f0f3259b..eda331f48 100644 --- a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst +++ b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst @@ -38,7 +38,7 @@ @MACRO: tribits_package_define_dependencies() + @MACRO: tribits_package_postprocess() + @MACRO: tribits_process_subpackages() + -@MACRO: tribits_process_enabled_tpl() + +@MACRO: tribits_process_enabled_standard_tpl() + @MACRO: tribits_project() + @MACRO: tribits_project_define_extra_repositories() + @MACRO: tribits_project_enable_all() + From 56b0845254bf1105d5a79bdb55f2403cde5227b1 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 27 Jan 2023 09:19:21 -0700 Subject: [PATCH 22/45] WIP: Add initial failing test case for stagged package installs (#63) This shows the need to address external pre-installed packages. --- .../TribitsExampleProject_Tests.cmake | 207 +++++++++++++++++- .../packages/wrap_external/CMakeLists.txt | 4 +- 2 files changed, 208 insertions(+), 3 deletions(-) diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index 69a74ab11..402cc85ca 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -2448,7 +2448,7 @@ tribits_add_advanced_test( TribitsExampleProject_ALL_NoFortran_WrapExternal_Verb "WithSubpackages_LIBRARIES='WithSubpackagesC::pws_c[;]WithSubpackagesB::pws_b[;]WithSubpackagesA::pws_a'" - "WrapExternal_LIBRARIES='external_func[;]pws_a'" + "WrapExternal_LIBRARIES='external_func[;]WithSubpackagesA::pws_a'" "pws_b_TARGET_NAME='pws_b'" "b_test_TARGET_NAME='WithSubpackagesB_b_test'" @@ -3353,9 +3353,214 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx # * install/simple_cxx/lib/cmake/TribitsExProj does not get created and # * therefore the file TribitsExProjConfig.cmake does not get installed). + if (TribitsExampleProject_External_SimpleCxx_NAME) set_tests_properties(${TribitsExampleProject_External_SimpleCxx_NAME} PROPERTIES DEPENDS ${SimpleTpl_install_STATIC_NAME} ) endif() +################################################################################ + + +tribits_add_advanced_test( TribitsExampleProject_External_Package_by_Package + OVERALL_WORKING_DIRECTORY TEST_NAME + OVERALL_NUM_MPI_PROCS 1 + EXCLUDE_IF_NOT_TRUE ${PROJECT_NAME}_ENABLE_Fortran IS_REAL_LINUX_SYSTEM + LIST_SEPARATOR + + TEST_0 + MESSAGE "Link TribitsExampleProject so it is easy to access" + CMND ln + ARGS -s ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject . + + TEST_1 + MESSAGE "Configure to build and install just SimpleCxx" + WORKING_DIRECTORY Build_SimpleCxx + CMND ${CMAKE_COMMAND} + ARGS + ${TribitsExampleProject_COMMON_CONFIG_ARGS} + -DTribitsExProj_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj_ENABLE_SimpleCxx=ON + -DCMAKE_INSTALL_PREFIX=../install_simplecxx + -DTribitsExProj_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=TRUE + -DTPL_ENABLE_MPI=OFF + -DTPL_ENABLE_SimpleTpl=ON + -DSimpleTpl_INCLUDE_DIRS=${SimpleTpl_install_STATIC_DIR}/install/include + -DSimpleTpl_LIBRARY_DIRS=${SimpleTpl_install_STATIC_DIR}/install/lib + ../TribitsExampleProject + PASS_REGULAR_EXPRESSION_ALL + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + + TEST_2 + MESSAGE "Build and install just SimpleCxx" + CMND make ARGS ${CTEST_BUILD_FLAGS} install + WORKING_DIRECTORY Build_SimpleCxx + SKIP_CLEAN_WORKING_DIRECTORY + + TEST_3 + MESSAGE "Configure to build and install just MixedLang" + WORKING_DIRECTORY Build_MixedLang + CMND ${CMAKE_COMMAND} + ARGS + ${TribitsExampleProject_COMMON_CONFIG_ARGS} + -DTribitsExProj_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj_ENABLE_MixedLang=ON + -DCMAKE_INSTALL_PREFIX=../install_mixedlang + -DTribitsExProj_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=TRUE + -DTPL_ENABLE_MPI=OFF + ../TribitsExampleProject + PASS_REGULAR_EXPRESSION_ALL + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + + TEST_4 + MESSAGE "Build and install just MixedLang" + CMND make ARGS ${CTEST_BUILD_FLAGS} install + WORKING_DIRECTORY Build_MixedLang + SKIP_CLEAN_WORKING_DIRECTORY + + TEST_5 + MESSAGE "Configure to build and install just WithSubpackages against pre-installed SimpleCxx and MixedLang" + CMND ${CMAKE_COMMAND} + WORKING_DIRECTORY Build_WithSubpackages + ARGS + ${TribitsExampleProject_COMMON_CONFIG_ARGS} + -DTribitsExProj_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj_ENABLE_WithSubpackages=ON + -DTribitsExProj_ENABLE_TESTS=ON + -DCMAKE_INSTALL_PREFIX=../install_withsubpackages + -DTribitsExProj_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=TRUE + -DTPL_ENABLE_MPI=OFF + -DTPL_ENABLE_SimpleTpl=ON + -DTPL_ENABLE_SimpleCxx=ON + -DTPL_ENABLE_MixedLang=ON + -DCMAKE_PREFIX_PATH=../install_simplecxx../install_mixedlang + ../TribitsExampleProject + PASS_REGULAR_EXPRESSION_ALL + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + + TEST_6 + MESSAGE "Build and install just WithSubpackages" + CMND make ARGS ${CTEST_BUILD_FLAGS} install + WORKING_DIRECTORY Build_WithSubpackages + SKIP_CLEAN_WORKING_DIRECTORY + + TEST_7 + MESSAGE "Test WithSubpackages" + WORKING_DIRECTORY Build_WithSubpackages + SKIP_CLEAN_WORKING_DIRECTORY + CMND ${CMAKE_CTEST_COMMAND} + PASS_REGULAR_EXPRESSION_ALL + "WithSubpackagesA_test_of_a [.]* +Passed" + "WithSubpackagesB_test_of_b [.]* +Passed" + "WithSubpackagesB_test_of_b_mixed_lang [.]* +Passed" + "WithSubpackagesC_test_of_c_util [.]* +Passed" + "WithSubpackagesC_test_of_c [.]* Passed" + "WithSubpackagesC_test_of_c_b_mixed_lang ... Passed" + "100% tests passed, 0 tests failed out of 6" + ALWAYS_FAIL_ON_NONZERO_RETURN + + TEST_8 + MESSAGE "Configure rest of TribitsExampleProject against pre-installed SimpleCxx, MixedLang, and WithSubpackages" + CMND ${CMAKE_COMMAND} + WORKING_DIRECTORY Build + ARGS + ${TribitsExampleProject_COMMON_CONFIG_ARGS} + -DTribitsExProj_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj_ENABLE_ALL_PACKAGES=ON + -DTribitsExProj_ENABLE_TESTS=ON + -DTribitsExProj_ENABLE_INSTALL_CMAKE_CONFIG_FILES=OFF # Allow WrapExternal enable + -DTPL_ENABLE_MixedLang=ON + -DTPL_ENABLE_WithSubpackages=ON + -DCMAKE_PREFIX_PATH=../install_withsubpackages../install_mixedlang + -DTPL_ENABLE_MPI=OFF + -DTPL_ENABLE_SimpleTpl=ON + ../TribitsExampleProject + PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package WithSubpackages as EXTERNAL because TPL_ENABLE_WithSubpackages=ON" + "-- Treating internal package WithSubpackagesA as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" + "-- Treating internal package WithSubpackagesB as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" + "-- Treating internal package WithSubpackagesC as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" + "-- NOTE: WithSubpackagesA is directly downstream from an fully TriBITS-compatible external package WithSubpackages" + "-- NOTE: WithSubpackagesB is directly downstream from an fully TriBITS-compatible external package WithSubpackages" + "-- NOTE: WithSubpackagesC is directly downstream from an fully TriBITS-compatible external package WithSubpackages" + "-- NOTE: WithSubpackagesA is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: WithSubpackagesB is indirectly downstream from an fully TriBITS-compatible external package" + "-- Treating internal package SimpleCxx as EXTERNAL because downstream package WithSubpackagesB being treated as EXTERNAL" + "-- NOTE: SimpleCxx is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: WithSubpackagesA is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: SimpleCxx is indirectly downstream from an fully TriBITS-compatible external package" + "-- Treating internal package MixedLang as EXTERNAL because TPL_ENABLE_MixedLang=ON" + "-- NOTE: HeaderOnlyTpl is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: SimpleTpl is indirectly downstream from an fully TriBITS-compatible external package" + + "Final set of enabled top-level packages: WrapExternal 1" + "Final set of enabled packages: WrapExternal 1" + "Final set of non-enabled top-level packages: 0" + "Final set of non-enabled packages: 0" + "Final set of enabled top-level external packages/TPLs: HeaderOnlyTpl SimpleTpl SimpleCxx MixedLang WithSubpackages 5" + "Final set of enabled external packages/TPLs: HeaderOnlyTpl SimpleTpl SimpleCxx MixedLang WithSubpackagesA WithSubpackagesB WithSubpackagesC WithSubpackages 8" + "Final set of non-enabled top-level external packages/TPLs: MPI 1" + "Final set of non-enabled external packages/TPLs: MPI 1" + + "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." + "Processing enabled external package/TPL: HeaderOnlyTpl [(]enabled by SimpleCxx, disable with -DTPL_ENABLE_HeaderOnlyTpl=OFF[)]" + "-- The external package/TPL HeaderOnlyTpl will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: SimpleTpl [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleTpl=OFF[)]" + "-- The external package/TPL SimpleTpl will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: SimpleCxx [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleCxx=OFF[)]" + "-- The external package/TPL SimpleCxx will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: MixedLang [(]enabled explicitly, disable with -DTPL_ENABLE_MixedLang=OFF[)]" + "-- Calling find_package[(]MixedLang[)] for TriBITS-compatible package" + "Processing enabled external package/TPL: WithSubpackages [(]enabled explicitly, disable with -DTPL_ENABLE_WithSubpackages=OFF[)]" + "-- Calling find_package[(]WithSubpackages[)] for TriBITS-compatible package" + + "Getting information for all enabled external packages/TPLs ..." + + "Configuring individual enabled TribitsExProj packages ..." + "Processing enabled top-level package: WrapExternal [(]Libs, Tests, Examples[)]" + + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + # NOTE: Above, we don't need to look in install_simplecxx for SimpleCxx + # because that will get found through WithSubpackages. But we do need to + # look for MixedLang because the libraries for WithSubpackages does not + # actually depend on MixedLang so we need to add where to find it. + + TEST_9 + MESSAGE "Build rest of TribitsExampleProject" + CMND make ARGS ${CTEST_BUILD_FLAGS} + WORKING_DIRECTORY Build + SKIP_CLEAN_WORKING_DIRECTORY + + TEST_10 + MESSAGE "Run all the remaining tests with ctest" + WORKING_DIRECTORY Build + SKIP_CLEAN_WORKING_DIRECTORY + CMND ${CMAKE_CTEST_COMMAND} + PASS_REGULAR_EXPRESSION_ALL + "WrapExternal_run_external_func [.]* +Passed" + "100% tests passed, 0 tests failed out of 1" + ALWAYS_FAIL_ON_NONZERO_RETURN + + ADDED_TEST_NAME_OUT TribitsExampleProject_External_Package_by_Package_NAME + ) +# NOTE: The above test is a strong check that packages can be installed +# individually in stages on top of each other and that we are correctly +# writing wrapper Config.cmake files for fully TriBITS-compatible +# external packages (in this case for WithSubpackagesAConfig.cmake to +# include). + + +if (TribitsExampleProject_External_Package_by_Package_NAME) + set_tests_properties(${TribitsExampleProject_External_Package_by_Package_NAME} + PROPERTIES DEPENDS ${SimpleTpl_install_STATIC_NAME} ) +endif() diff --git a/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt index ea7161b61..a9f8b0a37 100644 --- a/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/wrap_external/CMakeLists.txt @@ -133,13 +133,13 @@ add_dependencies(external_func build_external_func) # E.2) Make sure before we build the external library, we first build the # libraries. -add_dependencies(build_external_func pws_a) +add_dependencies(build_external_func WithSubpackagesA::pws_a) # NOTE: You have to put the lib dependencies on build target, not the imported # library target! # E.3) Update the TriBITS variables append_set(${PACKAGE_NAME}_LIB_TARGETS external_func) -global_set(${PACKAGE_NAME}_LIBRARIES external_func pws_a) +global_set(${PACKAGE_NAME}_LIBRARIES external_func WithSubpackagesA::pws_a) global_set(${PACKAGE_NAME}_HAS_NATIVE_LIBRARIES ON) tribits_include_directories(${EXTERNAL_FUNC_SOURCE_DIR}) # NOTE: Above, you have to add the upstream dependent libraries to the current From cddd9f145ad75db4eea00128413a4311d80d86d2 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 27 Jan 2023 16:24:11 -0700 Subject: [PATCH 23/45] Initial implementation of pre-building/pre-installing stages of packages (#63) This commit in an initial completion of for sub-use cases for #63 "Use Case 3: Configure/build pointing to a subset of already installed TriBITS packages in same repo". To make the initial tests for the TribitsExampleProject project to pass, this commit geneates wrapper Config.cmake files for TriBITS-compatible external packages. This provides the info needed for downstream internal TriBITS package's Config.camke files to get the upstream TriBITS-compatible external package. This commit makes the earlier test: TriBITS_TribitsExampleProject_External_Package_by_Package fully pass. However, we need to still add more tests, documentation and error checking but at least this is a start and all of the tests pass. --- .../TribitsProcessEnabledTpls.cmake | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake index 303697bb8..03560a006 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake @@ -156,6 +156,9 @@ macro(tribits_process_enabled_tribits_compatible_tpl TPL_NAME) set(TPL_${TPL_NAME}_PARTS_ALREADY_SET FALSE) # ToDo: Take out? if (NOT TPL_${TPL_NAME}_PARTS_ALREADY_SET) find_package(${TPL_NAME} CONFIG REQUIRED) + tribits_write_tribits_compatible_external_package_config_file(${TPL_NAME}) + tribits_generate_tpl_version_file_and_add_package_config_install_targets( + ${TPL_NAME}) set(TPL_${TPL_NAME}_PARTS_ALREADY_SET TRUE) endif() endmacro() @@ -253,3 +256,28 @@ function(tribits_generate_tpl_version_file_and_add_package_config_install_target tribits_extpkg_install_config_version_file(${TPL_NAME} "${tplConfigVersionFile}") endfunction() + + +# Generate a Config.cmake wrapper file for a fully TriBITS-compliant +# external package and put it in the external_packages/ directory so it can be +# included like any external package/TPL. +# +function(tribits_write_tribits_compatible_external_package_config_file tplName) + # Create Config.cmake file + set(configFileStr "") + string(APPEND configFileStr + "include(CMakeFindDependencyMacro)\n" ) + if (${externalPkg}_DIR) + string(APPEND configFileStr + "set(${tplName}_DIR \"${${tplName}_DIR}\")\n" ) + endif() + string(APPEND configFileStr + "find_dependency(${tplName} CONFIG REQUIRED)\n" + ) + set(buildDirExternalPkgsDir + "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}") + set(tplConfigFile + "${buildDirExternalPkgsDir}/${tplName}/${tplName}Config.cmake") + file(WRITE "${tplConfigFile}" "${configFileStr}") + +endfunction() From 0c959bb7e37ef89d314b37eb6df3ecf1bbf6f3a4 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Sat, 28 Jan 2023 12:44:48 -0700 Subject: [PATCH 24/45] Revise how internal and external Config.cmake files are linked together (#63) As of this commit, we should have a 100% complete implementation of "Use Case 3: Configure/build pointing to a subset of already installed TriBITS packages in same repo" in TriBITSPub/TriBITS#63. This added a new test TribitsExampleProject2_External_Package_by_Package which exercises some new sub-use-cases, like having a TriBITS TPL depend on one that was already found by an upstream package. This includes TriBITS TPLs with a) using find_package() and imported targets with tribits_extpkg_create_imported_all_libs_target_and_config_file() and b) without external imported targets using tribits_tpl_find_include_dirs_and_libraries(). This exposed a few weaknesses in the implementation that needed to be fixed. This commit resolves these use cases by introducing some new TriBITS variables set in the TriBITS-generated Config.cmake files and changes to do only include() of Config.cmake files. (NOTE: This is not the final implementation for how Config.cmake files should be linked together but it gets these tests to pass.) Things that had to be done to get this to work: * Updated tribits_extpkg_create_package_config_file_with_imported_targets() to include upstream Config.cmake files and link the ::all_libs target to the ::all_libs targets of all of its direct upstream TPLs (so that these Config.cmake files are TriBITS-compatible external packages that provide all of the ::all_libs targets). * Removed the code for calling find_dependency() for getting upstream TriBITS-compatible packages (i.e. Config.cmake files created by TriBITS). This also got rid of a bunch of variables for restricting where find_dependency() can look. * Created TribitsExternalPackageWriteConfigFile.cmake and moved out some functions for reuse. * Factored out several functions from tribits_extpkg_create_package_config_file_with_imported_targets() to make that function tighter. * Created function tribits_append_tribits_compliant_package_config_vars() that appends some new standard TriBITS-compliant package varaibles. * Removed strange logic involving TPL_${TPL_NAME}_PARTS_ALREADY_SET. (That logic got added way back in 2017. I think with the refactoring to modern CMake and the ::all_libs targets, this is all of the logic we need.) * Added/updated some internal documentation * Updated a little user documentation (a lot more is needed) --- .../TribitsExampleProject2_Tests.cmake | 299 ++++++++++++++++++ ...rnalPackageWriteConfigFile_UnitTests.cmake | 65 ++-- ...TribitsExternalPackageFindTplHelpers.cmake | 124 ++++++-- ...ribitsExternalPackageWriteConfigFile.cmake | 87 +++-- .../TribitsProcessEnabledTpls.cmake | 38 +-- ...ribitsTplFindIncludeDirsAndLibraries.cmake | 2 - .../TribitsWriteClientExportFiles.cmake | 23 +- ...TribitsWritePackageConfigFileHelpers.cmake | 65 ++++ tribits/doc/guides/TribitsGuidesBody.rst | 75 +++-- 9 files changed, 589 insertions(+), 189 deletions(-) create mode 100644 tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake index d1f9a1f2f..7b8140689 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake @@ -771,3 +771,302 @@ if (${testNameBase}_NAME) set_tests_properties(${${testNameBase}_NAME} PROPERTIES DEPENDS ${TribitsExampleProject2_Tpls_install_STATIC_NAME} ) endif() + + +################################################################################ + + +function(TribitsExampleProject2_External_Package_by_Package + sharedOrStatic findingTplsMethod + ) + + TribitsExampleProject2_test_setup_header() + + set(tplInstallBaseDir + "${TribitsExampleProject2_Tpls_install_${sharedOrStatic}_DIR}") + + set(allTplsNoPrefindArgs + "-DTpl1_ALLOW_PACKAGE_PREFIND=OFF" + "-DTpl2_ALLOW_PACKAGE_PREFIND=OFF" + "-DTpl3_ALLOW_PACKAGE_PREFIND=OFF" + "-DTpl4_ALLOW_PACKAGE_PREFIND=OFF" + ) + + if (sharedOrStatic STREQUAL "STATIC") + set(libExt "a") + elseif (sharedOrStatic STREQUAL "SHARED") + set(libExt "so") + else() + message(FATAL_ERROR "Error: Invalid value of" + " sharedOrStatic='${sharedOrStatic}'!") + endif() + + if (findingTplsMethod STREQUAL "TPL_LIBRARY_AND_INCLUDE_DIRS") + set(tpl1LibAndIncDirsArgs + "-DTpl1_INCLUDE_DIRS=${tplInstallBaseDir}/install_tpl1/include" + "-DTpl1_LIBRARY_DIRS=${tplInstallBaseDir}/install_tpl1/lib" + "-DTpl1_ALLOW_PACKAGE_PREFIND=OFF") + set(tpl2LibAndIncDirsArgs + "-DTpl2_INCLUDE_DIRS=${tplInstallBaseDir}/install_tpl2/include" + "-DTpl2_LIBRARY_DIRS=${tplInstallBaseDir}/install_tpl2/lib" + "-DTpl2_ALLOW_PACKAGE_PREFIND=OFF") + set(tpl3LibAndIncDirsArgs + "-DTpl3_INCLUDE_DIRS=${tplInstallBaseDir}/install_tpl3/include" + "-DTpl3_LIBRARY_DIRS=${tplInstallBaseDir}/install_tpl3/lib" + "-DTpl3_ALLOW_PACKAGE_PREFIND=OFF") + set(tpl4LibAndIncDirsArgs + "-DTpl4_INCLUDE_DIRS=${tplInstallBaseDir}/install_tpl4/include" + "-DTpl4_ALLOW_PACKAGE_PREFIND=OFF") + set(tpl1CMakePrefixPath "") + set(tpl2CMakePrefixPath "") + set(tpl3CMakePrefixPath "") + set(tpl4CMakePrefixPath "") + set(tpl1FoundRegexes + "TPL_Tpl1_LIBRARIES='.*/install_tpl1/lib/libtpl1[.]${libExt}'" + "TPL_Tpl1_INCLUDE_DIRS='.*/install_tpl1/include'") + set(tpl2FoundRegexes + "TPL_Tpl2_LIBRARIES='.*/install_tpl2/lib/libtpl2b[.]${libExt}[;].*/install_tpl2/lib/libtpl2a[.]${libExt}'" + "TPL_Tpl2_INCLUDE_DIRS='.*/install_tpl2/include'") + set(tpl3FoundRegexes + "TPL_Tpl3_LIBRARIES='.*/install_tpl3/lib/libtpl3[.]${libExt}'" + "TPL_Tpl3_INCLUDE_DIRS='.*/install_tpl3/include'") + set(tpl4FoundRegexes + "-- TPL_Tpl4_INCLUDE_DIRS='.*/install_tpl4/include'") + elseif (findingTplsMethod STREQUAL "CMAKE_PREFIX_PATH_CACHE") + set(testNameSuffix "_CMAKE_PREFIX_PATH_CACHE") + set(tpl1LibAndIncDirsArgs "-DTpl1_ALLOW_PACKAGE_PREFIND=ON") + set(tpl2LibAndIncDirsArgs "-DTpl2_ALLOW_PACKAGE_PREFIND=ON") + set(tpl3LibAndIncDirsArgs "-DTpl3_ALLOW_PACKAGE_PREFIND=ON") + set(tpl4LibAndIncDirsArgs "-DTpl4_ALLOW_PACKAGE_PREFIND=ON") + set(tpl1CMakePrefixPath "${tplInstallBaseDir}/install_tpl1") + set(tpl2CMakePrefixPath "${tplInstallBaseDir}/install_tpl2") + set(tpl3CMakePrefixPath "${tplInstallBaseDir}/install_tpl3") + set(tpl4CMakePrefixPath "${tplInstallBaseDir}/install_tpl4") + set(tpl1FoundRegexes + "-- Using find_package[(]Tpl1 ...[)] ..." + "-- Found Tpl1_DIR='.*/install_tpl1/lib/cmake/Tpl1'" + "-- Generating Tpl1::all_libs and Tpl1Config.cmake") + set(tpl2FoundRegexes + "-- Using find_package[(]Tpl2 ...[)] ..." + "-- Found Tpl2_DIR='.*/install_tpl2/lib/cmake/Tpl2'" + "-- Generating Tpl2::all_libs and Tpl2Config.cmake") + set(tpl3FoundRegexes + "-- Using find_package[(]Tpl3 ...[)] ..." + "-- Found Tpl3_DIR='.*/install_tpl3/lib/cmake/Tpl3'" + "-- Generating Tpl3::all_libs and Tpl3Config.cmake") + set(tpl4FoundRegexes + "-- Using find_package[(]Tpl4 ...[)] ..." + "-- Found Tpl4_DIR='.*/install_tpl4/lib/cmake/Tpl4'" + "-- Generating Tpl4::all_libs and Tpl4Config.cmake") + else() + message(FATAL_ERROR + "Error, findingTplsMethod='${findingTplsMethod}' is invalid!") + endif() + + set(testNameBase ${CMAKE_CURRENT_FUNCTION}_${sharedOrStatic}${testNameSuffix}) + set(testName ${PACKAGE_NAME}_${testNameBase}) + set(testDir "${CMAKE_CURRENT_BINARY_DIR}/${testName}") + + tribits_add_advanced_test( ${testNameBase} + OVERALL_WORKING_DIRECTORY TEST_NAME + OVERALL_NUM_MPI_PROCS 1 + EXCLUDE_IF_NOT_TRUE ${PROJECT_NAME}_ENABLE_Fortran IS_REAL_LINUX_SYSTEM + LIST_SEPARATOR + + TEST_0 + MESSAGE "Link TribitsExampleProject2 so it is easy to access" + CMND ln + ARGS -s ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject2 . + + TEST_1 + MESSAGE "Configure to build and install just Package1" + WORKING_DIRECTORY Build_Package1 + CMND ${CMAKE_COMMAND} + ARGS + ${TribitsExampleProject2_COMMON_CONFIG_ARGS} + -DTribitsExProj2_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj2_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj2_ENABLE_Package1=ON + -DCMAKE_INSTALL_PREFIX=../install_package1 + -DTribitsExProj2_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=TRUE + -DTPL_ENABLE_Tpl1=ON + ${tpl1LibAndIncDirsArgs} + -DCMAKE_PREFIX_PATH=${tpl1CMakePrefixPath} + ../TribitsExampleProject2 + PASS_REGULAR_EXPRESSION_ALL + "Final set of enabled top-level packages: Package1 1" + "Final set of non-enabled top-level packages: Package2 Package3 2" + "Final set of enabled top-level external packages/TPLs: Tpl1 1" + "Final set of non-enabled top-level external packages/TPLs: Tpl2 Tpl3 Tpl4 3" + + "Getting information for all enabled external packages/TPLs ..." + "Processing enabled external package/TPL: Tpl1 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl1=OFF[)]" + ${tpl1FoundRegexes} + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + # NOTE: Above Tpl1 is found and the wrapper file Tpl1Config.cmake is + # created and installed. This Tpl1Config.cmake file gets used in + # downstream CMake project configures. + + TEST_2 + MESSAGE "Build and install just Package1" + WORKING_DIRECTORY Build_Package1 + SKIP_CLEAN_WORKING_DIRECTORY + CMND ${CMAKE_COMMAND} ARGS --build . --target install + + TEST_3 + MESSAGE "Configure to build and install just Package2" + WORKING_DIRECTORY Build_Package2 + CMND ${CMAKE_COMMAND} + ARGS + ${TribitsExampleProject2_COMMON_CONFIG_ARGS} + -DTribitsExProj2_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj2_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj2_ENABLE_Package2=ON + -DCMAKE_INSTALL_PREFIX=../install_package2 + -DTribitsExProj2_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=TRUE + -DTPL_ENABLE_Package1=ON # Pull in already installed Package! + -DTPL_ENABLE_Tpl2=ON + ${tpl2LibAndIncDirsArgs} + -DTPL_ENABLE_Tpl3=ON + ${tpl3LibAndIncDirsArgs} + -DCMAKE_PREFIX_PATH=../install_package1${tpl2CMakePrefixPath}${tpl3CMakePrefixPath} + ../TribitsExampleProject2 + PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package Package1 as EXTERNAL because TPL_ENABLE_Package1=ON" + "-- NOTE: Tpl1 is directly downstream from an fully TriBITS-compatible external package Package1" + + "Final set of enabled top-level packages: Package2 1" + "Final set of non-enabled top-level packages: Package3 1" + "Final set of enabled top-level external packages/TPLs: Tpl1 Tpl2 Tpl3 Package1 4" + "Final set of non-enabled top-level external packages/TPLs: Tpl4 1" + + "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." + "Processing enabled external package/TPL: Tpl1 [(]enabled by Package1, disable with -DTPL_ENABLE_Tpl1=OFF[)]" + "-- The external package/TPL Tpl1 will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: Package1 [(]enabled explicitly, disable with -DTPL_ENABLE_Package1=OFF[)]" + "-- Calling find_package[(]Package1[)] for TriBITS-compatible package" + + "Getting information for all enabled external packages/TPLs ..." + "Processing enabled external package/TPL: Tpl2 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl2=OFF[)]" + ${tpl2FoundRegexes} + "Processing enabled external package/TPL: Tpl3 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl3=OFF[)]" + ${tpl3FoundRegexes} + + "Configuring individual enabled TribitsExProj2 packages ..." + "Processing enabled top-level package: Package2 [(]Libs[)]" + + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + # NOTE: Above shows how a TriBITS TPL can depend on an upstream TriBITS + # TPL found by earlier TriBITS package build and install. In this case, + # Tpl1 is found and the Tpl1Config.cmake wrapper file is created as part + # of the upstream configure and build of Package1 and the definition of + # Tpl1 is pulled in when find_package(Package1) is called on the + # TriBITS-compliant external package Package1. Then Tpl2 and Tpl2 are + # found and Tpl2Config.cmake and Tpl3Config.cmake are created that point + # to pre-installed Tpl1Config.cmake. + + TEST_4 + MESSAGE "Build and install just Package2" + WORKING_DIRECTORY Build_Package2 + SKIP_CLEAN_WORKING_DIRECTORY + CMND ${CMAKE_COMMAND} ARGS --build . --target install + + TEST_5 + MESSAGE "Configure to build, test, and install the rest of TribitsExampleProject2 (Package2)" + WORKING_DIRECTORY Build + CMND ${CMAKE_COMMAND} + ARGS + ${TribitsExampleProject2_COMMON_CONFIG_ARGS} + -DTribitsExProj2_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} + -DTribitsExProj2_ENABLE_SECONDARY_TESTED_CODE=ON + -DTribitsExProj2_ENABLE_ALL_PACKAGES=ON + -DTribitsExProj2_ENABLE_TESTS=ON + -DCMAKE_INSTALL_PREFIX=../install + -DTribitsExProj2_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES=TRUE + -DTPL_ENABLE_Package2=ON # Pull in already installed Package! + -DTPL_ENABLE_Tpl1=ON + -DTPL_ENABLE_Tpl2=ON + -DTPL_ENABLE_Tpl3=ON + -DTPL_ENABLE_Tpl4=ON + ${tpl4LibAndIncDirsArgs} + -DCMAKE_PREFIX_PATH=../install_package2${tpl4CMakePrefixPath} + ../TribitsExampleProject2 + PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package Package2 as EXTERNAL because TPL_ENABLE_Package2=ON" + "-- Treating internal package Package1 as EXTERNAL because downstream package Package2 being treated as EXTERNAL" + "-- NOTE: Package1 is directly downstream from an fully TriBITS-compatible external package Package2" + "-- NOTE: Tpl3 is directly downstream from an fully TriBITS-compatible external package Package2" + "-- NOTE: Tpl1 is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: Tpl2 is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: Tpl1 is indirectly downstream from an fully TriBITS-compatible external package" + + "Final set of enabled top-level packages: Package3 1" + "Final set of non-enabled top-level packages: 0" + "Final set of enabled top-level external packages/TPLs: Tpl1 Tpl2 Tpl3 Tpl4 Package1 Package2 6" + "Final set of non-enabled top-level external packages/TPLs: 0" + + "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." + "Processing enabled external package/TPL: Tpl1 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl1=OFF[)]" + "-- The external package/TPL Tpl1 will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: Tpl2 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl2=OFF[)]" + "-- The external package/TPL Tpl2 will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: Tpl3 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl3=OFF[)]" + "-- The external package/TPL Tpl3 will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: Package1 [(]enabled explicitly, disable with -DTPL_ENABLE_Package1=OFF[)]" + "-- The external package/TPL Package1 will be read in by a downstream fully TriBITS-compliant external package" + "Processing enabled external package/TPL: Package2 [(]enabled explicitly, disable with -DTPL_ENABLE_Package2=OFF[)]" + "-- Calling find_package[(]Package2[)] for TriBITS-compatible package" + "Getting information for all enabled external packages/TPLs ..." + + "Processing enabled external package/TPL: Tpl4 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl4=OFF[)]" + ${tpl4FoundRegexes} + + "Configuring done" + ALWAYS_FAIL_ON_NONZERO_RETURN + # NOTE: Above, only the newly enabled TPL Tpl4 is found and its + # Tpl4Config.cmake file is linked to the pre-installed + # Tpl1Config.comake, Tpl2Config.cmake and Tpl3Config.cmake files. And + # the needed info from Tpl1, Tpl2, and Tpl3 is pulled in from + # find_package(Package2). + + TEST_6 + MESSAGE "Build and install the rest of TribitsExampleProject2 (Package3)" + WORKING_DIRECTORY Build + SKIP_CLEAN_WORKING_DIRECTORY + CMND ${CMAKE_COMMAND} ARGS --build . --target install + + TEST_7 + MESSAGE "Run remaining tests for TribitsExampleProject2 (Package3)" + WORKING_DIRECTORY Build + SKIP_CLEAN_WORKING_DIRECTORY + CMND ${CMAKE_CTEST_COMMAND} + PASS_REGULAR_EXPRESSION_ALL + "Package3_Prg [.]+ *Passed" + "100% tests passed, 0 tests failed out of 1" + ALWAYS_FAIL_ON_NONZERO_RETURN + + ADDED_TEST_NAME_OUT ${testNameBase}_NAME + ) + + if (${testNameBase}_NAME) + set(${testNameBase}_NAME ${${testNameBase}_NAME} PARENT_SCOPE) + set(${testNameBase}_INSTALL_DIR "${testDir}/install" PARENT_SCOPE) + set_tests_properties(${${testNameBase}_NAME} + PROPERTIES DEPENDS ${TribitsExampleProject2_Tpls_install_${sharedOrStatic}_NAME} ) + endif() + +endfunction() + + +TribitsExampleProject2_External_Package_by_Package(STATIC TPL_LIBRARY_AND_INCLUDE_DIRS) +TribitsExampleProject2_External_Package_by_Package(SHARED TPL_LIBRARY_AND_INCLUDE_DIRS) +TribitsExampleProject2_External_Package_by_Package(STATIC CMAKE_PREFIX_PATH_CACHE) +TribitsExampleProject2_External_Package_by_Package(SHARED CMAKE_PREFIX_PATH_CACHE) + +# NOTE: The above tests check a few different use cases for building and +# installing TriBITS packages from a single TriBITS project incrementally. It also tests the case where + diff --git a/test/core/TribitsExternalPackageWriteConfigFile_UnitTests.cmake b/test/core/TribitsExternalPackageWriteConfigFile_UnitTests.cmake index b9f98c474..960dcbbc3 100644 --- a/test/core/TribitsExternalPackageWriteConfigFile_UnitTests.cmake +++ b/test/core/TribitsExternalPackageWriteConfigFile_UnitTests.cmake @@ -840,6 +840,11 @@ target_link_libraries(SomeTpl::all_libs INTERFACE tribits::SomeTpl::somelib ) + +# Standard TriBITS-compliant external package variables +set(SomeTpl_IS_TRIBITS_COMPLIANT TRUE) +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}") ]=] ) @@ -876,6 +881,11 @@ target_include_directories(SomeTpl::all_libs SYSTEM INTERFACE "/some/other/path/to/include/e" ) + +# Standard TriBITS-compliant external package variables +set(SomeTpl_IS_TRIBITS_COMPLIANT TRUE) +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}") ]=] ) @@ -918,6 +928,11 @@ target_include_directories(SomeTpl::all_libs SYSTEM INTERFACE "/some/path/to/include/C" ) + +# Standard TriBITS-compliant external package variables +set(SomeTpl_IS_TRIBITS_COMPLIANT TRUE) +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}") ]=] ) @@ -961,6 +976,11 @@ target_include_directories(SomeTpl::all_libs SYSTEM INTERFACE "/some/other/path/to/include/b" ) + +# Standard TriBITS-compliant external package variables +set(SomeTpl_IS_TRIBITS_COMPLIANT TRUE) +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}") ]=] ) @@ -1020,6 +1040,11 @@ target_link_options(SomeTpl::all_libs INTERFACE "-L/some/explicit/path1" ) + +# Standard TriBITS-compliant external package variables +set(SomeTpl_IS_TRIBITS_COMPLIANT TRUE) +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}") ]=] ) @@ -1095,6 +1120,11 @@ target_link_options(SomeTpl::all_libs INTERFACE "-L/some/explicit/path1" ) + +# Standard TriBITS-compliant external package variables +set(SomeTpl_IS_TRIBITS_COMPLIANT TRUE) +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}") ]=] ) @@ -1135,42 +1165,18 @@ if (TARGET SomeTpl::all_libs) return() endif() -include(CMakeFindDependencyMacro) - -# Don't allow find_dependency() to search anything other than _DIR -set(SomeTpl_SearchNoOtherPathsArgs - NO_DEFAULT_PATH - NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH - NO_CMAKE_ENVIRONMENT_PATH - NO_SYSTEM_ENVIRONMENT_PATH - NO_CMAKE_PACKAGE_REGISTRY - NO_CMAKE_SYSTEM_PATH - NO_CMAKE_SYSTEM_PACKAGE_REGISTRY - CMAKE_FIND_ROOT_PATH_BOTH - ONLY_CMAKE_FIND_ROOT_PATH - NO_CMAKE_FIND_ROOT_PATH - ) - if (NOT TARGET PublicTpl::all_libs) - set(PublicTpl_DIR "${CMAKE_CURRENT_LIST_DIR}/../PublicTpl") - find_dependency(PublicTpl REQUIRED CONFIG ${SomeTpl_SearchNoOtherPathsArgs}) - unset(PublicTpl_DIR) + include("${CMAKE_CURRENT_LIST_DIR}/../PublicTpl/PublicTplConfig.cmake") endif() if (NOT TARGET PrivateTpl::all_libs) - set(PrivateTpl_DIR "${CMAKE_CURRENT_LIST_DIR}/../PrivateTpl") - find_dependency(PrivateTpl REQUIRED CONFIG ${SomeTpl_SearchNoOtherPathsArgs}) - unset(PrivateTpl_DIR) + include("${CMAKE_CURRENT_LIST_DIR}/../PrivateTpl/PrivateTplConfig.cmake") endif() if (NOT TARGET DefaultVisTpl::all_libs) - set(DefaultVisTpl_DIR "${CMAKE_CURRENT_LIST_DIR}/../DefaultVisTpl") - find_dependency(DefaultVisTpl REQUIRED CONFIG ${SomeTpl_SearchNoOtherPathsArgs}) - unset(DefaultVisTpl_DIR) + include("${CMAKE_CURRENT_LIST_DIR}/../DefaultVisTpl/DefaultVisTplConfig.cmake") endif() -unset(SomeTpl_SearchNoOtherPathsArgs) - add_library(tribits::SomeTpl::lib1 IMPORTED INTERFACE) set_target_properties(tribits::SomeTpl::lib1 PROPERTIES IMPORTED_LIBNAME "lib1") @@ -1200,6 +1206,11 @@ target_link_options(SomeTpl::all_libs INTERFACE "-L/some/explicit/path1" ) + +# Standard TriBITS-compliant external package variables +set(SomeTpl_IS_TRIBITS_COMPLIANT TRUE) +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_LIST_FILE}") +set(SomeTpl_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR "${CMAKE_CURRENT_LIST_DIR}") ]=] ) diff --git a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake b/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake index 1873267bd..b124a7a92 100644 --- a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake @@ -38,11 +38,16 @@ # @HEADER +include(TribitsExternalPackageWriteConfigFile) + + # @FUNCTION: tribits_extpkg_create_imported_all_libs_target_and_config_file() # -# Call from a ``FindTPL.cmake`` module that calls inner -# ``find_package()`` for external package that uses modern CMake -# IMPORTED targets. +# Called from a `FindTPL.cmake`_ module which first calls +# ``find_package()``and the calls this function to get and +# external package that uses modern CMake IMPORTED targets. This function +# creates the ``::all_libs`` target and creates a TriBITS-compliant +# external package wrapper file `Config.cmake`. # # Usage:: # @@ -51,18 +56,21 @@ # INNER_FIND_PACKAGE_NAME # IMPORTED_TARGETS_FOR_ALL_LIBS ... ) # -# This function is called in a TriBITS ``FindTPL.cmake`` wrapper -# module after it calls ``find_package()`` and then creates the -# IMPORTED target ``::all_libs`` from the list of IMPORTED targets -# `` ...`` which are defined from the call -# ``find_package()``. This function also takes care of -# generating the correct ``Config.cmake`` file under the directory:: +# This function is called from a TriBITS ``FindTPL.cmake`` wrapper +# module after it calls ``find_package()`` and then this function +# creates the IMPORTED target ``::all_libs`` from the list of +# IMPORTED targets `` ...`` which are +# defined from the call ``find_package()``. This function also +# takes care of generating the correct ``Config.cmake`` file under +# the directory:: # # ${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR} # -# The generated ``Config.cmake`` file calls -# ``find_dependency()`` (with no other argument) and then, again, -# defines the correct imported library dependency. +# The generated ``Config.cmake`` file pulls in the upstream +# TriBITS-compliant ``Config.cmake` files, calls +# ``find_dependency()`` (with no other arguments), defines the +# `::all_libs`` target, and then sets up the correct dependencies +# between these targets. # # For more details, see `Creating FindTPL.cmake using find_package() # with IMPORTED targets`_. @@ -87,7 +95,7 @@ function(tribits_extpkg_create_imported_all_libs_target_and_config_file target_link_libraries(${tplName}::all_libs INTERFACE ${importedTarget}) endforeach() - # Create Config.cmake file + # Create the TriBITS-compliant Config.cmake wrapper file tribits_extpkg_create_package_config_file_with_imported_targets( ${tplName} INNER_FIND_PACKAGE_NAME ${PARSE_INNER_FIND_PACKAGE_NAME} @@ -96,10 +104,19 @@ function(tribits_extpkg_create_imported_all_libs_target_and_config_file endfunction() -function(tribits_extpkg_create_package_config_file_with_imported_targets - tplName - ) - +# @FUNCTION: tribits_extpkg_create_package_config_file_with_imported_targets() +# +# Create the ``Config.cmake`` file for a TriBITS external package/TPL +# that is defined by a set of IMPORTED targets by call to +# ``find_package()`` +# +# Usage:: +# +# tribits_extpkg_create_package_config_file_with_imported_targets( +# INNER_FIND_PACKAGE_NAME +# IMPORTED_TARGETS_FOR_ALL_LIBS ... ) +# +function(tribits_extpkg_create_package_config_file_with_imported_targets tplName) # Parse arguments cmake_parse_arguments( PARSE_ARGV 1 @@ -108,31 +125,48 @@ function(tribits_extpkg_create_package_config_file_with_imported_targets ) tribits_check_for_unparsed_arguments(PARSE) tribits_assert_parse_arg_one_value(PARSE INNER_FIND_PACKAGE_NAME) - tribits_assert_parse_arg_one_or_more_values(PARSE IMPORTED_TARGETS_FOR_ALL_LIBS) + tribits_assert_parse_arg_one_or_more_values(PARSE IMPORTED_TARGETS_FOR_ALL_LIBS) set(externalPkg ${PARSE_INNER_FIND_PACKAGE_NAME}) - # Create Config.cmake file + # Create header for Config.cmake file set(configFileStr "") - string(APPEND configFileStr - "include(CMakeFindDependencyMacro)\n" ) + tribits_extpkg_append_package_config_file_header_with_imported_targets_str( + ${tplName} ${externalPkg} configFileStr) + + # Get ${externalPkg} from where you found it before (see note below) + tribits_extpkg_append_find_dependency_external_package_with_imported_targets( + ${tplName} ${externalPkg} configFileStr) + + # Pull in upstream Config.cmake files + tribits_extpkg_add_find_upstream_dependencies_str(${tplName} configFileStr) + + # Add the ${tplName}::all_libs target and link to this ${externalPkg} + # package's native IMPORTED targets + tribits_extpkg_create_all_libs_target( ${tplName} + LIB_TARGETS_LIST ${PARSE_IMPORTED_TARGETS_FOR_ALL_LIBS} + CONFIG_FILE_STR_INOUT configFileStr ) + + # Also link against upstream package's `::all_libs` targets + tribits_extpkg_append_upstream_target_link_libraries_str(${tplName} + ${tplName}::all_libs configFileStr) + + tribits_append_tribits_compliant_package_config_vars(${tplName} configFileStr) + + tribits_extpkg_write_package_config_file_from_str(${tplName} "${configFileStr}") +endfunction() + + +function(tribits_extpkg_append_find_dependency_external_package_with_imported_targets + tplName externalPkg configFileStrVarInOut + ) + set(configFileStr "${${configFileStrVarInOut}}") if (${externalPkg}_DIR) string(APPEND configFileStr "set(${externalPkg}_DIR \"${${externalPkg}_DIR}\")\n" ) endif() string(APPEND configFileStr - "find_dependency(${externalPkg})\n" - "add_library(${tplName}::all_libs INTERFACE IMPORTED GLOBAL)\n" - ) - foreach (importedTarget IN LISTS PARSE_IMPORTED_TARGETS_FOR_ALL_LIBS) - string(APPEND configFileStr - "target_link_libraries(${tplName}::all_libs INTERFACE ${importedTarget})\n") - endforeach() - set(buildDirExternalPkgsDir - "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}") - set(tplConfigFile - "${buildDirExternalPkgsDir}/${tplName}/${tplName}Config.cmake") - file(WRITE "${tplConfigFile}" "${configFileStr}") - + "find_dependency(${externalPkg})\n\n") + set(${configFileStrVarInOut} "${configFileStr}" PARENT_SCOPE) endfunction() # # NOTE: Above, ${externalPkg}_DIR is only set when @@ -140,3 +174,25 @@ endfunction() # ${externalPkg}Config.cmake and **not** when it uses a # Find${externalPkg}.cmake module. Therefore, there is no reason to set # ${externalPkg}_DIR in this file if it will not be used. + + +function(tribits_extpkg_append_package_config_file_header_with_imported_targets_str + tplName externalPkg configFileStrVarInOut + ) + set(configFileStr "${${configFileStrVarInOut}}") + string(APPEND configFileStr + "# TriBITS-compliant Package config file for external package/TPL '${tplName}'\n" + "# based on non fully TriBITS-compliant external package '${externalPkg}' that uses\n" + "# modern IMPORTED targets\n" + "#\n" + "# Generated by CMake, do not edit!\n" + "\n" + "# Guard against multiple inclusion\n" + "if (TARGET ${tplName}::all_libs)\n" + " return()\n" + "endif()\n" + "\n" + "include(CMakeFindDependencyMacro)\n\n" + ) + set(${configFileStrVarInOut} "${configFileStr}" PARENT_SCOPE) +endfunction() diff --git a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake index fd4adb86a..f1b6a8e9f 100644 --- a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake @@ -42,6 +42,7 @@ include_guard() include(TribitsGeneralMacros) include(TribitsPackageDependencies) +include(TribitsWritePackageConfigFileHelpers) include(MessageWrapper) @@ -281,7 +282,7 @@ function(tribits_extpkg_write_config_file_str tplName tplConfigFileStrOut) "\n" ) - # B) Call find_dependency() for all direct dependent upstream TPLs + # B) Pull in upstream packages tribits_extpkg_add_find_upstream_dependencies_str(${tplName} configFileStr) @@ -301,7 +302,10 @@ function(tribits_extpkg_write_config_file_str tplName tplConfigFileStrOut) CONFIG_FILE_STR_INOUT configFileStr ) - # E) Set the output + # E) Add standard TriBITS-compliant external package vars + tribits_append_tribits_compliant_package_config_vars(${tplName} configFileStr) + + # F) Set the output set(${tplConfigFileStrOut} "${configFileStr}" PARENT_SCOPE) endfunction() @@ -309,15 +313,16 @@ endfunction() # @FUNCTION: tribits_extpkg_add_find_upstream_dependencies_str() # -# Add code to call find_dependency() for all upstream external packages/TPLs -# listed in ``_LIB_ENABLED_DEPENDENCIES``. +# Add includes for all upstream external packages/TPLs listed in +# ``_LIB_ENABLED_DEPENDENCIES``. # # Usage:: # # tribits_extpkg_add_find_upstream_dependencies_str(tplName # configFileFragStrInOut) # -# NOTE: This also requires that ``_DIR`` be set for each +# NOTE: This also requires that +# ``_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE`` be set for each # external package/TPL listed in ``_LIB_ENABLED_DEPENDENCIES``. # function(tribits_extpkg_add_find_upstream_dependencies_str @@ -325,63 +330,35 @@ function(tribits_extpkg_add_find_upstream_dependencies_str ) if (NOT "${${tplName}_LIB_ENABLED_DEPENDENCIES}" STREQUAL "") set(configFileFragStr "${${configFileFragStrInOut}}") - string(APPEND configFileFragStr - "include(CMakeFindDependencyMacro)\n" - "\n" - "# Don't allow find_dependency() to search anything other than _DIR\n" - "set(${tplName}_SearchNoOtherPathsArgs\n" - " NO_DEFAULT_PATH\n" - " NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH\n" - " NO_CMAKE_ENVIRONMENT_PATH\n" - " NO_SYSTEM_ENVIRONMENT_PATH\n" - " NO_CMAKE_PACKAGE_REGISTRY\n" - " NO_CMAKE_SYSTEM_PATH\n" - " NO_CMAKE_SYSTEM_PACKAGE_REGISTRY\n" - " CMAKE_FIND_ROOT_PATH_BOTH\n" - " ONLY_CMAKE_FIND_ROOT_PATH\n" - " NO_CMAKE_FIND_ROOT_PATH\n" - " )\n" - "\n" - ) foreach (upstreamTplDepEntry IN LISTS ${tplName}_LIB_ENABLED_DEPENDENCIES) tribits_extpkg_get_dep_name_and_vis( "${upstreamTplDepEntry}" upstreamTplDepName upstreamTplDepVis) - if ("${${upstreamTplDepName}_DIR}" STREQUAL "") - message(FATAL_ERROR "ERROR: ${upstreamTplDepName}_DIR is empty!") + if (NOT "${${upstreamTplDepName}_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR}" + STREQUAL "" + ) + set(upstreamTplPackageConfigFileDir + "${${upstreamTplDepName}_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR}") + else() + set(upstreamTplPackageConfigFileDir + "\${CMAKE_CURRENT_LIST_DIR}/../${upstreamTplDepName}") endif() string(APPEND configFileFragStr "if (NOT TARGET ${upstreamTplDepName}::all_libs)\n" - " set(${upstreamTplDepName}_DIR \"\${CMAKE_CURRENT_LIST_DIR}/../${upstreamTplDepName}\")\n" - " find_dependency(${upstreamTplDepName} REQUIRED CONFIG \${${tplName}_SearchNoOtherPathsArgs})\n" - " unset(${upstreamTplDepName}_DIR)\n" + " include(\"${upstreamTplPackageConfigFileDir}/${upstreamTplDepName}Config.cmake\")\n" "endif()\n" "\n" ) endforeach() - string(APPEND configFileFragStr - "unset(${tplName}_SearchNoOtherPathsArgs)\n" - "\n" - ) set(${configFileFragStrInOut} "${configFileFragStr}" PARENT_SCOPE) endif() endfunction() # -# NOTE: Above, to be the most flexible, we have to set -# `_DIR` and then call `find_dependency()` instead of just -# including the file: -# -# include("${_DIR}/Config.cmake") -# -# This is to allow finding and depending on external packages/TPLs that may -# have different names than Config.cmake. The CMake -# command find_package() only returns _DIR, not the full -# path to the config file or even the config file name. It is a little bit -# dangerous to use find_dependency() in case the config fire is not found in -# the directory `_DIR` but I am not sure how else to do -# this. -# -# ToDo: It would be great to make the above find_dependency() call **only ** -# search the directory _DIR and no others. That would make +# NOTE: Above, we include the upstream ${upstreamTplDepName}Config.cmake file +# from either beside the current location (in the build tree or the install +# tree) or we use the location set in +# ${upstreamTplDepName}_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR which would +# have been set by the ${upstreamTplDepName}Config.cmake file itself from an +# upstream install as pulled in from a TriBITS-compliant external package. # @FUNCTION: tribits_extpkg_process_libraries_list() @@ -446,7 +423,6 @@ function(tribits_extpkg_process_libraries_list tplName) list(REVERSE reverseLibraries) foreach (libentry IN LISTS reverseLibraries) - #print_var(libentry) tribits_tpl_libraries_entry_type(${libentry} libEntryType) if (libEntryType STREQUAL "UNSUPPORTED_LIB_ENTRY") message_wrapper(SEND_ERROR @@ -551,11 +527,14 @@ function(tribits_extpkg_process_libraries_list_library_entry tribits_extpkg_append_add_library_str (${libname} ${prefixed_libname} ${libEntryType} "${libpath}" configFileStr) if (lastLibProcessed) + # This is not the first lib so we only need to link to the previous lib string(APPEND configFileStr "target_link_libraries(${prefixed_libname}\n" " INTERFACE tribits::${tplName}::${lastLibProcessed})\n" ) else() + # Only on the first lib do we add dependencies on all of the + # `::all_libs` targets tribits_extpkg_append_upstream_target_link_libraries_str( ${tplName} ${prefixed_libname} configFileStr ) endif() @@ -714,6 +693,13 @@ function(tribits_print_invalid_lib_link_option tplName liblinkoption) endfunction() +# @FUNCTION: tribits_extpkg_append_upstream_target_link_libraries_str() +# +# Append text calling `target_link_libraries( ... )` against +# the `::all_libs` targets for all of the direct enabled upstream +# dependencies listed in '_LIB_ENABLED_DEPENDENCIES` (taking into +# account `PUBLIC` and `PRIVATE` dependencies). +# function(tribits_extpkg_append_upstream_target_link_libraries_str tplName prefix_libname configFileStrInOut ) @@ -791,7 +777,7 @@ function(tribits_extpkg_create_all_libs_target tplName) tribits_check_for_unparsed_arguments() # Set short-hand local vars - set(libTarget "${PARSE_LIB_TARGETS_LIST}") + set(libTargets "${PARSE_LIB_TARGETS_LIST}") set(libLinkFlags "${PARSE_LIB_LINK_FLAGS_LIST}") # Capture the initial input string in case the name of the var @@ -845,4 +831,3 @@ function(tribits_extpkg_create_all_libs_target tplName) PARENT_SCOPE) endfunction() - diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake index 03560a006..928463168 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake @@ -147,20 +147,13 @@ function(tribits_get_enabled_tpl_processing_string TPL_NAME tplProcessingStrin endfunction() -# Process an enabled TPL defined using a fully TriBITS-compatible -# Config.cmake file +# Process an enabled TPL defined using a fully TriBITS-compatible external +# packages Config.cmake file # macro(tribits_process_enabled_tribits_compatible_tpl TPL_NAME) message("-- " "Calling find_package(${TPL_NAME}) for TriBITS-compatible package") - set(TPL_${TPL_NAME}_PARTS_ALREADY_SET FALSE) # ToDo: Take out? - if (NOT TPL_${TPL_NAME}_PARTS_ALREADY_SET) - find_package(${TPL_NAME} CONFIG REQUIRED) - tribits_write_tribits_compatible_external_package_config_file(${TPL_NAME}) - tribits_generate_tpl_version_file_and_add_package_config_install_targets( - ${TPL_NAME}) - set(TPL_${TPL_NAME}_PARTS_ALREADY_SET TRUE) - endif() + find_package(${TPL_NAME} CONFIG REQUIRED) endmacro() @@ -256,28 +249,3 @@ function(tribits_generate_tpl_version_file_and_add_package_config_install_target tribits_extpkg_install_config_version_file(${TPL_NAME} "${tplConfigVersionFile}") endfunction() - - -# Generate a Config.cmake wrapper file for a fully TriBITS-compliant -# external package and put it in the external_packages/ directory so it can be -# included like any external package/TPL. -# -function(tribits_write_tribits_compatible_external_package_config_file tplName) - # Create Config.cmake file - set(configFileStr "") - string(APPEND configFileStr - "include(CMakeFindDependencyMacro)\n" ) - if (${externalPkg}_DIR) - string(APPEND configFileStr - "set(${tplName}_DIR \"${${tplName}_DIR}\")\n" ) - endif() - string(APPEND configFileStr - "find_dependency(${tplName} CONFIG REQUIRED)\n" - ) - set(buildDirExternalPkgsDir - "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}") - set(tplConfigFile - "${buildDirExternalPkgsDir}/${tplName}/${tplName}Config.cmake") - file(WRITE "${tplConfigFile}" "${configFileStr}") - -endfunction() diff --git a/tribits/core/package_arch/TribitsTplFindIncludeDirsAndLibraries.cmake b/tribits/core/package_arch/TribitsTplFindIncludeDirsAndLibraries.cmake index ad2621289..490d204ec 100644 --- a/tribits/core/package_arch/TribitsTplFindIncludeDirsAndLibraries.cmake +++ b/tribits/core/package_arch/TribitsTplFindIncludeDirsAndLibraries.cmake @@ -724,8 +724,6 @@ function(tribits_tpl_find_include_dirs_and_libraries TPL_NAME) tribits_extpkg_write_config_file(${TPL_NAME} "${tplConfigFile}") if (NOT ${PROJECT_NAME}_ENABLE_INSTALLATION_TESTING) include("${tplConfigFile}") - set(${TPL_NAME}_DIR "${tplConfigFileBaseDir}" CACHE INTERNAL - "TriBITS-generated ${TPL_NAME}Config.cmake file used from this dir") endif() # NOTE: The file ConfigVersion.cmake will get created elsewhere as # will the install targets for the files Config and diff --git a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake index 7ef8f2666..8bb9affc7 100644 --- a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake +++ b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake @@ -39,6 +39,7 @@ include(TribitsGeneralMacros) include(TribitsPkgExportCacheVars) +include(TribitsWritePackageConfigFileHelpers) ### ### WARNING: See "NOTES TO DEVELOPERS" at the bottom of the file @@ -280,9 +281,12 @@ function(tribits_generate_package_config_file_for_build_tree packageName) "${PACKAGE_CONFIG_FOR_BUILD_BASE_DIR}" packageConfigBuildDirTargetsFile ) string(APPEND PACKAGE_CONFIG_CODE "\n# Import ${packageName} targets\n" - "include(\"${packageConfigBuildDirTargetsFile}\")") + "include(\"${packageConfigBuildDirTargetsFile}\")\n") endif() + tribits_append_tribits_compliant_package_config_vars(${packageName} + PACKAGE_CONFIG_CODE) + tribits_set_compiler_vars_for_config_file(BUILD_DIR) if ("${CMAKE_CXX_FLAGS}" STREQUAL "") @@ -381,7 +385,10 @@ function(tribits_generate_package_config_file_for_install_tree packageName) # Import install targets string(APPEND PACKAGE_CONFIG_CODE "\n# Import ${packageName} targets\n" - "include(\"\${CMAKE_CURRENT_LIST_DIR}/${packageName}Targets.cmake\")") + "include(\"\${CMAKE_CURRENT_LIST_DIR}/${packageName}Targets.cmake\")\n") + + tribits_append_tribits_compliant_package_config_vars(${packageName} + PACKAGE_CONFIG_CODE) # Write the specification of the rpath if necessary. This is only needed if # we're building shared libraries. @@ -474,11 +481,17 @@ function(tribits_append_dependent_package_config_file_includes_and_enables packa foreach(depPkg IN LISTS ${packageName}_LIB_ENABLED_DEPENDENCIES) set(packageConfigBaseDir "") # Initially, no add include() if (${depPkg}_PACKAGE_BUILD_STATUS STREQUAL "INTERNAL") - set(packageConfigBaseDir "${pkgConfigFileBaseDir}/${depPkg}") + set(packageConfigBaseDir "\${CMAKE_CURRENT_LIST_DIR}/../${depPkg}") elseif (${depPkg}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") - set(packageConfigBaseDir "${extPkgConfigFileBaseDir}/${depPkg}") + if (NOT "${${depPkg}_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR}" STREQUAL "") + set(packageConfigBaseDir "${${depPkg}_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR}") + else() + set(packageConfigBaseDir + "\${CMAKE_CURRENT_LIST_DIR}/../../${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}/${depPkg}") + endif() else() - message(FATAL_ERROR "ERROR: ${depPkg}_PACKAGE_BUILD_STATUS='${${depPkg}_PACKAGE_BUILD_STATUS}' invalid!") + message(FATAL_ERROR "ERROR:" + " ${depPkg}_PACKAGE_BUILD_STATUS='${${depPkg}_PACKAGE_BUILD_STATUS}' invalid!") endif() if (packageConfigBaseDir) string(APPEND configFileStr diff --git a/tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake b/tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake new file mode 100644 index 000000000..18edba9bb --- /dev/null +++ b/tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake @@ -0,0 +1,65 @@ +# @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 + + +# @FUNCTION: tribits_append_tribits_compliant_package_config_vars() +# +# Append the standard TriBITS-compliant external package variables +# +function(tribits_append_tribits_compliant_package_config_vars packageName + packageConfigCodeStrVarInOut + ) + set(packageConfigCodeStr "${${packageConfigCodeStrVarInOut}}") + string(APPEND packageConfigCodeStr + "\n# Standard TriBITS-compliant external package variables\n" + "set(${packageName}_IS_TRIBITS_COMPLIANT TRUE)\n" + "set(${packageName}_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE \"\${CMAKE_CURRENT_LIST_FILE}\")\n" + "set(${packageName}_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR \"\${CMAKE_CURRENT_LIST_DIR}\")\n" + ) + set(${packageConfigCodeStrVarInOut} "${packageConfigCodeStr}" PARENT_SCOPE) +endfunction() + + +function(tribits_extpkg_write_package_config_file_from_str tplName configFileStr) + set(buildDirExternalPkgsDir + "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}") + set(tplConfigFile + "${buildDirExternalPkgsDir}/${tplName}/${tplName}Config.cmake") + file(WRITE "${tplConfigFile}" "${configFileStr}") +endfunction() \ No newline at end of file diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index ea02544d5..f1fc6d939 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -5699,10 +5699,9 @@ For cases where ``find_package()`` provides complete and proper modern (namespaced) IMPORTED targets (but is missing the ``::all_libs`` target or the name ```` and ```` name are different), these ``FindTPL.cmake`` modules can call the -function -`tribits_extpkg_create_imported_all_libs_target_and_config_file()`_ -after calling ``find_package()`` to create a very thin wrapper -``FindTPL.cmake`` module. In these cases, such a +function `tribits_extpkg_create_imported_all_libs_target_and_config_file()`_ +after calling ``find_package()`` to create a very thin find +module file ``FindTPL.cmake``. In these cases, such a ``FindTPL.cmake`` module file is nothing more than:: find_package( REQUIRED) @@ -5712,27 +5711,30 @@ after calling ``find_package()`` to create a very thin wrapper IMPORTED_TARGETS_FOR_ALL_LIBS ... ) The function -`tribits_extpkg_create_imported_all_libs_target_and_config_file()`_ -creates the target ``::all_libs`` and the wrapper file +`tribits_extpkg_create_imported_all_libs_target_and_config_file()`_ creates +the target ``::all_libs`` and the wrapper file ``Config.cmake`` which is installed by TriBITS. The only unique information required to create this glue module is the name of the external package ```` and the exact full names of the IMPORTED targets `` ...`` provided by the -``find_package( ...)`` call. +``find_package( ...)`` call. The TriBITS function +``tribits_extpkg_create_imported_all_libs_target_and_config_file()`` takes +care of all of the rest of the details. Such simple ``FindTPL.cmake`` modules do not follow the legacy TriBITS TPL convention of allowing users to specify a TPL by setting the cache variables ``_INCLUDE_DIRS``, ``_LIBRARY_DIRS``, and ``_LIBRARY_NAMES`` or by setting ``TPL__INCLUDE_DIRS`` and ``_LIBRARIES``. But as the ecosystem of CMake software transitions -to modern CMake and uniform usage of complete ``Config.cmake`` files, -that is the reasonable thing to do. +to modern CMake along with the proper usage of complete +``Config.cmake`` files, this is the reasonable thing to do. However, to maintain backwards compatibility with the legacy TriBITS TPL system (such as when upgrading a existing ``FindTPL.cmake`` file), a ``FindTPL.cmake`` file can be extended to use the -`tribits_tpl_allow_pre_find_package()`_ in combination with the function -`tribits_tpl_find_include_dirs_and_libraries()`_ function as follows:: +`tribits_tpl_allow_pre_find_package()`_ in combination with the functions +``tribits_extpkg_create_imported_all_libs_target_and_config_file()`` and +`tribits_tpl_find_include_dirs_and_libraries()`_ as follows:: set(REQUIRED_HEADERS ...) set(REQUIRED_LIBS_NAMES ...) @@ -6953,38 +6955,41 @@ Tricky considerations for TriBITS-generated Config.cmake files ----------------------------------------------------------------------- An issue that comes up with external packages/TPLs like HDF5 that needs to be -discussed here is the fact that ``FindTPL.cmake`` files create (See -`How to add a new TriBITS TPL`_) and TriBITS installs files of the name -``Config.cmake`` and that could potentially be found by calls to -``find_package()`` (when `` == `` like with -HDF5). These TriBITS-generated ``Config.cmake`` files are primarily -meant to provide the ``::all_libs`` targets for downstream -TriBITS-compatible ``Config.cmake`` files. These TriBITS-generated -``Config.cmake`` files will usually not behave the same way that a -more general ``Find.config`` modules or native -``Config.cmake`` configure files would behave as expected when found -by ``find_package()`` commands called in some arbitrary downstream -raw CMake project. Therefore, to avoid having an installed TriBITS-generated -``HDF5Config.cmake`` file, for example, being found by the inner call to -``find_package(HDF5 ...)`` in the file ``FindTPLHDF5.cmake`` (which would be -disastrous), TriBITS employs two safeguards. First, TriBITS-generated -``Config.cmake`` files are placed into the build directory under:: +discussed here is the fact that ``FindTPL.cmake`` module files create +(See `How to add a new TriBITS TPL`_) and TriBITS installs package config +files of the name ``Config.cmake``. These TriBITS-generated package +config files ``Config.cmake`` could potentially be found by calls to +``find_package()`` (i.e. when `` == `` like +with HDF5). These TriBITS-generated ``Config.cmake`` files are +primarily meant to provide the ``::all_libs`` targets and pull in +upstream dependencies for downstream TriBITS-compliant +``Config.cmake`` files. These TriBITS-generated +``Config.cmake`` files will usually not behave the same way existing +``Find.config`` find modules or native ``Config.cmake`` +package config files would behave as expected by downstream projects when +found by ``find_package()`` commands called in some arbitrary +downstream raw CMake project. Therefore, to avoid having an installed +TriBITS-generated ``HDF5Config.cmake`` file, for example, being found by the +inner call to ``find_package(HDF5 ...)`` in the file ``FindTPLHDF5.cmake`` +(which would be disastrous), TriBITS employs two safeguards. + +First, TriBITS-generated ``Config.cmake`` package config files are +placed into the build directory under:: /external_packages//Config.cmake -and installed into the directory under:: +and installed into the installation directory under:: /lib/external_packages//Config.cmake so they will not be found by ``find_package()`` by default when ``/cmake_packages`` and/or ````, respectively, are added -to ``CMAKE_PREFIX_PATH``. Also, even if -``/lib/external_packages`` or ``/external_packages`` do -get added to the search path somehow (e.g. by appending those to -``CMAKE_INSTALL_PREFIX``), the TriBITS framework will set the variable -``TRIBITS_FINDING_RAW__PACKAGE_FIRST=TRUE`` before including -``FindTPL.cmake`` and there is special logic in the TriBITS-generated -``ConfigVersion.cmake`` file that will set +to ``CMAKE_PREFIX_PATH``. + +Second, even if the directories ``/lib/external_packages`` or +``/external_packages`` do get added to the search path somehow +(e.g. by appending those to ``CMAKE_INSTALL_PREFIX``), the companion +TriBITS-generated ``ConfigVersion.cmake`` files will set ``PACKAGE_VERSION_COMPATIBLE=OFF`` and result in ``find_package()`` not selecting the TriBITS-generated ``Config.cmake`` file. (It turns out that CMake's ``find_package()`` command always includes the file From 2075dd6d94226fd82e89c508e27a1494e6a565d0 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 6 Feb 2023 14:48:51 -0700 Subject: [PATCH 25/45] WIP: Improve names of functions and variables (#63) This is a commit that contains a bunch of renamings without moving code around: * Renamed functions with `_with_imported_targets` in the name from `tribits_extpkg_X_with_imported_targets_Y()` to `tribits_extpkgwit_X_Y()`. * Rename function `tribits_extpkg_add_find_upstream_dependencies_str()` to `tribits_extpkg_append_find_upstream_dependencies_str()` * Rename function `tribits_extpkg_create_all_libs_target()` to ` tribits_extpkg_append_create_all_libs_target_str()` * Rename of function `tribits_extpkg_append_upstream_target_link_libraries_str()` to `tribits_extpkg_append_target_link_libraries_to_upstream_all_libs_targets_str()` * Rename function `tribits_append_tribits_compliant_package_config_vars()` to `tribits_extpkg_append_tribits_compliant_package_config_vars_str()` * Rename function `tribits_tpl_libraries_entry_type()` to `tribits_extpkg_tpl_libraries_entry_type()` * Rename function `tribits_print_invalid_lib_name()` to `tribits_extpkg_print_invalid_lib_name()` * Improve the names of some internal vars --- ...TribitsExternalPackageFindTplHelpers.cmake | 40 ++++++++---- ...ribitsExternalPackageWriteConfigFile.cmake | 62 +++++++++---------- .../TribitsWriteClientExportFiles.cmake | 4 +- ...TribitsWritePackageConfigFileHelpers.cmake | 4 +- .../TribitsMacroFunctionDocTemplate.rst | 2 +- .../TribitsSystemMacroFunctionDocTemplate.rst | 4 +- 6 files changed, 66 insertions(+), 50 deletions(-) diff --git a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake b/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake index b124a7a92..aff44a368 100644 --- a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake @@ -38,9 +38,24 @@ # @HEADER +################################################################################ +# +# Module TribitsExternalPackageFindTplHelpers.cmake +# +# Contains functions for implementing FindTPL.cmake files for +# external packages using find_package() that producing modern +# IMPORTED targets. +# +# NOTE: The acronym 'extpkgwit' stands for "External Package With Imported +# Targets". +# +################################################################################ + + include(TribitsExternalPackageWriteConfigFile) + # @FUNCTION: tribits_extpkg_create_imported_all_libs_target_and_config_file() # # Called from a `FindTPL.cmake`_ module which first calls @@ -96,7 +111,7 @@ function(tribits_extpkg_create_imported_all_libs_target_and_config_file endforeach() # Create the TriBITS-compliant Config.cmake wrapper file - tribits_extpkg_create_package_config_file_with_imported_targets( + tribits_extpkgwit_create_package_config_file( ${tplName} INNER_FIND_PACKAGE_NAME ${PARSE_INNER_FIND_PACKAGE_NAME} IMPORTED_TARGETS_FOR_ALL_LIBS ${PARSE_IMPORTED_TARGETS_FOR_ALL_LIBS} ) @@ -104,7 +119,7 @@ function(tribits_extpkg_create_imported_all_libs_target_and_config_file endfunction() -# @FUNCTION: tribits_extpkg_create_package_config_file_with_imported_targets() +# @FUNCTION: tribits_extpkgwit_create_package_config_file() # # Create the ``Config.cmake`` file for a TriBITS external package/TPL # that is defined by a set of IMPORTED targets by call to @@ -112,11 +127,11 @@ endfunction() # # Usage:: # -# tribits_extpkg_create_package_config_file_with_imported_targets( +# tribits_extpkgwit_create_package_config_file( # INNER_FIND_PACKAGE_NAME # IMPORTED_TARGETS_FOR_ALL_LIBS ... ) # -function(tribits_extpkg_create_package_config_file_with_imported_targets tplName) +function(tribits_extpkgwit_create_package_config_file tplName) # Parse arguments cmake_parse_arguments( PARSE_ARGV 1 @@ -130,33 +145,34 @@ function(tribits_extpkg_create_package_config_file_with_imported_targets tplNam # Create header for Config.cmake file set(configFileStr "") - tribits_extpkg_append_package_config_file_header_with_imported_targets_str( + tribits_extpkgwit_append_package_config_file_header_str( ${tplName} ${externalPkg} configFileStr) # Get ${externalPkg} from where you found it before (see note below) - tribits_extpkg_append_find_dependency_external_package_with_imported_targets( + tribits_extpkgwit_append_find_dependency_external_package_str( ${tplName} ${externalPkg} configFileStr) # Pull in upstream Config.cmake files - tribits_extpkg_add_find_upstream_dependencies_str(${tplName} configFileStr) + tribits_extpkg_append_find_upstream_dependencies_str(${tplName} configFileStr) # Add the ${tplName}::all_libs target and link to this ${externalPkg} # package's native IMPORTED targets - tribits_extpkg_create_all_libs_target( ${tplName} + tribits_extpkg_append_create_all_libs_target_str( ${tplName} LIB_TARGETS_LIST ${PARSE_IMPORTED_TARGETS_FOR_ALL_LIBS} CONFIG_FILE_STR_INOUT configFileStr ) # Also link against upstream package's `::all_libs` targets - tribits_extpkg_append_upstream_target_link_libraries_str(${tplName} + tribits_extpkg_append_target_link_libraries_to_upstream_all_libs_targets_str(${tplName} ${tplName}::all_libs configFileStr) - tribits_append_tribits_compliant_package_config_vars(${tplName} configFileStr) + tribits_extpkg_append_tribits_compliant_package_config_vars_str(${tplName} + configFileStr) tribits_extpkg_write_package_config_file_from_str(${tplName} "${configFileStr}") endfunction() -function(tribits_extpkg_append_find_dependency_external_package_with_imported_targets +function(tribits_extpkgwit_append_find_dependency_external_package_str tplName externalPkg configFileStrVarInOut ) set(configFileStr "${${configFileStrVarInOut}}") @@ -176,7 +192,7 @@ endfunction() # ${externalPkg}_DIR in this file if it will not be used. -function(tribits_extpkg_append_package_config_file_header_with_imported_targets_str +function(tribits_extpkgwit_append_package_config_file_header_str tplName externalPkg configFileStrVarInOut ) set(configFileStr "${${configFileStrVarInOut}}") diff --git a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake index f1b6a8e9f..ee1608511 100644 --- a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake @@ -243,7 +243,7 @@ endfunction() # regarded as an error. # # For more details on the handling of individual ``TPL__LIBRARIES`` -# arguments, see `tribits_tpl_libraries_entry_type()`_. +# arguments, see `tribits_extpkg_tpl_libraries_entry_type()`_. # # The list of directories given in ``TPL__INCLUDE_DIRS`` is added to # the ``::all_libs`` target using ``target_include_directories()``. @@ -283,7 +283,7 @@ function(tribits_extpkg_write_config_file_str tplName tplConfigFileStrOut) ) # B) Pull in upstream packages - tribits_extpkg_add_find_upstream_dependencies_str(${tplName} + tribits_extpkg_append_find_upstream_dependencies_str(${tplName} configFileStr) # C) Create IMPORTED library targets from TPL_${tplName}_LIBRARIES @@ -295,7 +295,7 @@ function(tribits_extpkg_write_config_file_str tplName tplConfigFileStrOut) ) # D) Create the ::all_libs target - tribits_extpkg_create_all_libs_target( + tribits_extpkg_append_create_all_libs_target_str( ${tplName} LIB_TARGETS_LIST ${libTargets} LIB_LINK_FLAGS_LIST ${libLinkFlags} @@ -303,7 +303,7 @@ function(tribits_extpkg_write_config_file_str tplName tplConfigFileStrOut) ) # E) Add standard TriBITS-compliant external package vars - tribits_append_tribits_compliant_package_config_vars(${tplName} configFileStr) + tribits_extpkg_append_tribits_compliant_package_config_vars_str(${tplName} configFileStr) # F) Set the output set(${tplConfigFileStrOut} "${configFileStr}" PARENT_SCOPE) @@ -311,21 +311,21 @@ function(tribits_extpkg_write_config_file_str tplName tplConfigFileStrOut) endfunction() -# @FUNCTION: tribits_extpkg_add_find_upstream_dependencies_str() +# @FUNCTION: tribits_extpkg_append_find_upstream_dependencies_str() # # Add includes for all upstream external packages/TPLs listed in # ``_LIB_ENABLED_DEPENDENCIES``. # # Usage:: # -# tribits_extpkg_add_find_upstream_dependencies_str(tplName +# tribits_extpkg_append_find_upstream_dependencies_str(tplName # configFileFragStrInOut) # # NOTE: This also requires that # ``_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE`` be set for each # external package/TPL listed in ``_LIB_ENABLED_DEPENDENCIES``. # -function(tribits_extpkg_add_find_upstream_dependencies_str +function(tribits_extpkg_append_find_upstream_dependencies_str tplName configFileFragStrInOut ) if (NOT "${${tplName}_LIB_ENABLED_DEPENDENCIES}" STREQUAL "") @@ -412,7 +412,7 @@ function(tribits_extpkg_process_libraries_list tplName) set(configFileStr "") set(libTargets "") - set(lastLibProcessed "") + set(previousLibProcessed "") # Iterate through libs in reverse order setting dependencies on the libs # that came before them so CMake will put in right order on the link line. @@ -423,7 +423,7 @@ function(tribits_extpkg_process_libraries_list tplName) list(REVERSE reverseLibraries) foreach (libentry IN LISTS reverseLibraries) - tribits_tpl_libraries_entry_type(${libentry} libEntryType) + tribits_extpkg_tpl_libraries_entry_type(${libentry} libEntryType) if (libEntryType STREQUAL "UNSUPPORTED_LIB_ENTRY") message_wrapper(SEND_ERROR "ERROR: Can't handle argument '${libentry}' in list TPL_${tplName}_LIBRARIES") @@ -434,7 +434,7 @@ function(tribits_extpkg_process_libraries_list tplName) list(APPEND libLinkFlagsList "${libentry}") else() tribits_extpkg_process_libraries_list_library_entry( - ${tplName} "${libentry}" ${libEntryType} libTargets lastLibProcessed + ${tplName} "${libentry}" ${libEntryType} libTargets previousLibProcessed configFileStr ) endif() endforeach() @@ -450,13 +450,13 @@ function(tribits_extpkg_process_libraries_list tplName) endfunction() -# @FUNCTION: tribits_tpl_libraries_entry_type() +# @FUNCTION: tribits_extpkg_tpl_libraries_entry_type() # # Returns the type of the library entry in the list TPL__LIBRARIES # # Usage:: # -# tribits_tpl_libraries_entry_type( ) +# tribits_extpkg_tpl_libraries_entry_type( ) # # Arguments: # @@ -481,7 +481,7 @@ endfunction() # # * ``UNSUPPORTED_LIB_ENTRY``: An unsupported lib option # -function(tribits_tpl_libraries_entry_type libentry libEntryTypeOut) +function(tribits_extpkg_tpl_libraries_entry_type libentry libEntryTypeOut) string(SUBSTRING "${libentry}" 0 1 firstCharLibEntry) string(SUBSTRING "${libentry}" 0 2 firstTwoCharsLibEntry) if (firstTwoCharsLibEntry STREQUAL "-l") @@ -512,11 +512,11 @@ endfunction() # function(tribits_extpkg_process_libraries_list_library_entry tplName libentry libEntryType - libTargetsInOut lastLibProcessedInOut configFileStrInOut + libTargetsInOut previousLibProcessedInOut configFileStrInOut ) # Set local vars for inout vars set(libTargets ${${libTargetsInOut}}) - set(lastLibProcessed ${${lastLibProcessedInOut}}) + set(previousLibProcessed ${${previousLibProcessedInOut}}) set(configFileStr ${${configFileStrInOut}}) # Get libname tribits_extpkg_get_libname_and_path_from_libentry( @@ -526,27 +526,27 @@ function(tribits_extpkg_process_libraries_list_library_entry if (NOT (prefixed_libname IN_LIST libTargets)) tribits_extpkg_append_add_library_str (${libname} ${prefixed_libname} ${libEntryType} "${libpath}" configFileStr) - if (lastLibProcessed) + if (previousLibProcessed) # This is not the first lib so we only need to link to the previous lib string(APPEND configFileStr "target_link_libraries(${prefixed_libname}\n" - " INTERFACE tribits::${tplName}::${lastLibProcessed})\n" + " INTERFACE tribits::${tplName}::${previousLibProcessed})\n" ) else() # Only on the first lib do we add dependencies on all of the # `::all_libs` targets - tribits_extpkg_append_upstream_target_link_libraries_str( ${tplName} + tribits_extpkg_append_target_link_libraries_to_upstream_all_libs_targets_str( ${tplName} ${prefixed_libname} configFileStr ) endif() string(APPEND configFileStr "\n") # Update for next loop - set(lastLibProcessed ${libname}) + set(previousLibProcessed ${libname}) list(APPEND libTargets ${prefixed_libname}) endif() # Set output vars set(${libTargetsInOut} ${libTargets} PARENT_SCOPE) - set(${lastLibProcessedInOut} ${lastLibProcessed} PARENT_SCOPE) + set(${previousLibProcessedInOut} ${previousLibProcessed} PARENT_SCOPE) set(${configFileStrInOut} ${configFileStr} PARENT_SCOPE) endfunction() # NOTE: Above, we only need to link the first library @@ -620,7 +620,7 @@ function(tribits_extpkg_get_libname_from_full_lib_path full_lib_path set(libname "") string(LENGTH "${full_libname}" full_libname_len) if (full_libname_len LESS 0) - tribits_print_invalid_lib_name(${tplName} "${full_lib_path}") + tribits_extpkg_print_invalid_lib_name(${tplName} "${full_lib_path}") endif() if (WIN32) # Native windows compilers does not prepend library names with 'lib' @@ -636,14 +636,14 @@ function(tribits_extpkg_get_libname_from_full_lib_path full_lib_path if (last_ext STREQUAL ".framework") set(libname "${full_libname}") else() - tribits_print_invalid_lib_name(${tplName} "${full_lib_path}") + tribits_extpkg_print_invalid_lib_name(${tplName} "${full_lib_path}") endif() endif() else() # I.e. Linux # Every other system (i.e. Linux) prepends the library name with 'lib' so # assert for that if (NOT beginsWithLib) - tribits_print_invalid_lib_name(${tplName} "${full_lib_path}") + tribits_extpkg_print_invalid_lib_name(${tplName} "${full_lib_path}") else() string(SUBSTRING "${full_libname}" 3 -1 libname) endif() @@ -672,7 +672,7 @@ function(tribits_extpkg_get_libname_from_lib_name_link_option # Assert begging part '-l' string(SUBSTRING "${lib_name_link_option}" 0 2 firstTwoCharsLibEntry) if ( ) - tribits_print_invalid_lib_link_option(${tplName} "${lib_name_link_option}") + tribits_extpkg_print_invalid_lib_link_option(${tplName} "${lib_name_link_option}") endif() # Get from -l string(SUBSTRING "${lib_name_link_option}" 2 -1 libname) @@ -681,26 +681,26 @@ function(tribits_extpkg_get_libname_from_lib_name_link_option endfunction() -function(tribits_print_invalid_lib_name tplName full_libname) +function(tribits_extpkg_print_invalid_lib_name tplName full_libname) message_wrapper(SEND_ERROR "ERROR: TPL_${tplName}_LIBRARIES entry '${full_libname}' not a valid lib file name!") endfunction() -function(tribits_print_invalid_lib_link_option tplName liblinkoption) +function(tribits_extpkg_print_invalid_lib_link_option tplName liblinkoption) message(SEND_ERROR "ERROR: TPL_${tplName}_LIBRARIES entry '${liblinkoption}' not a valid lib name link option!") endfunction() -# @FUNCTION: tribits_extpkg_append_upstream_target_link_libraries_str() +# @FUNCTION: tribits_extpkg_append_target_link_libraries_to_upstream_all_libs_targets_str() # # Append text calling `target_link_libraries( ... )` against # the `::all_libs` targets for all of the direct enabled upstream # dependencies listed in '_LIB_ENABLED_DEPENDENCIES` (taking into # account `PUBLIC` and `PRIVATE` dependencies). # -function(tribits_extpkg_append_upstream_target_link_libraries_str +function(tribits_extpkg_append_target_link_libraries_to_upstream_all_libs_targets_str tplName prefix_libname configFileStrInOut ) set(configFileStr "${${configFileStrInOut}}") @@ -736,14 +736,14 @@ endfunction() # libraries being listed on link lines for downstsream library and exec links. -# @FUNCTION: tribits_extpkg_create_all_libs_target() +# @FUNCTION: tribits_extpkg_append_create_all_libs_target_str() # # Creates the ``::all_libs`` target command text using input info and # from ``TPL__INCLUDE_DIRS``. # # Usage:: # -# tribits_extpkg_create_all_libs_target( +# tribits_extpkg_append_create_all_libs_target_str( # # LIB_TARGETS_LIST # LIB_LINK_FLAGS_LIST @@ -763,7 +763,7 @@ endfunction() # ````: [out] A string variable that will be # appended with the ``::all_libs`` target statements. # -function(tribits_extpkg_create_all_libs_target tplName) +function(tribits_extpkg_append_create_all_libs_target_str tplName) # Parse commandline arguments diff --git a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake index 8bb9affc7..2287ed02a 100644 --- a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake +++ b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake @@ -284,7 +284,7 @@ function(tribits_generate_package_config_file_for_build_tree packageName) "include(\"${packageConfigBuildDirTargetsFile}\")\n") endif() - tribits_append_tribits_compliant_package_config_vars(${packageName} + tribits_extpkg_append_tribits_compliant_package_config_vars_str(${packageName} PACKAGE_CONFIG_CODE) tribits_set_compiler_vars_for_config_file(BUILD_DIR) @@ -387,7 +387,7 @@ function(tribits_generate_package_config_file_for_install_tree packageName) "\n# Import ${packageName} targets\n" "include(\"\${CMAKE_CURRENT_LIST_DIR}/${packageName}Targets.cmake\")\n") - tribits_append_tribits_compliant_package_config_vars(${packageName} + tribits_extpkg_append_tribits_compliant_package_config_vars_str(${packageName} PACKAGE_CONFIG_CODE) # Write the specification of the rpath if necessary. This is only needed if diff --git a/tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake b/tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake index 18edba9bb..310e58876 100644 --- a/tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake +++ b/tribits/core/package_arch/TribitsWritePackageConfigFileHelpers.cmake @@ -38,11 +38,11 @@ # @HEADER -# @FUNCTION: tribits_append_tribits_compliant_package_config_vars() +# @FUNCTION: tribits_extpkg_append_tribits_compliant_package_config_vars_str() # # Append the standard TriBITS-compliant external package variables # -function(tribits_append_tribits_compliant_package_config_vars packageName +function(tribits_extpkg_append_tribits_compliant_package_config_vars_str packageName packageConfigCodeStrVarInOut ) set(packageConfigCodeStr "${${packageConfigCodeStrVarInOut}}") diff --git a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst index eda331f48..1288514bf 100644 --- a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst +++ b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst @@ -24,6 +24,7 @@ @MACRO: tribits_extpkg_define_dependencies() + @FUNCTION: tribits_extpkg_get_dep_name_and_vis() + @FUNCTION: tribits_extpkg_create_imported_all_libs_target_and_config_file() + +@FUNCTION: tribits_extpkg_tpl_libraries_entry_type() + @FUNCTION: tribits_extpkg_write_config_file() + @FUNCTION: tribits_extpkg_write_config_file_str() + @FUNCTION: tribits_find_most_recent_binary_file_timestamp() + @@ -50,7 +51,6 @@ @MACRO: tribits_subpackage_postprocess() + @FUNCTION: tribits_tpl_allow_pre_find_package() + @FUNCTION: tribits_tpl_find_include_dirs_and_libraries() + -@FUNCTION: tribits_tpl_libraries_entry_type() + @FUNCTION: tribits_tpl_tentatively_enable() + @FUNCTION: tribits_write_flexible_package_client_export_files() + @FUNCTION: tribits_verbose_print_var() + diff --git a/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst b/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst index a8c9f53d2..585609202 100644 --- a/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst +++ b/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst @@ -16,8 +16,8 @@ understand the internals of TriBITS. @MACRO: tribits_append_forward_dep_packages() + @MACRO: tribits_assert_read_dependency_vars() + @FUNCTION: tribits_dump_package_dependencies_info() + -@FUNCTION: tribits_extpkg_add_find_upstream_dependencies_str() + -@FUNCTION: tribits_extpkg_create_all_libs_target() + +@FUNCTION: tribits_extpkg_append_create_all_libs_target_str() + +@FUNCTION: tribits_extpkg_append_find_upstream_dependencies_str() + @FUNCTION: tribits_extpkg_install_config_file() + @FUNCTION: tribits_extpkg_install_config_version_file() + @FUNCTION: tribits_extpkg_process_libraries_list() + From 3b63fbd368425c47e7f93f934c11acca6c20c79c Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 6 Feb 2023 16:00:55 -0700 Subject: [PATCH 26/45] WIP: Improve documentation (#63) --- .../TribitsExternalPackageWriteConfigFile.cmake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake index ee1608511..d2602bcf4 100644 --- a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake @@ -49,8 +49,8 @@ include(MessageWrapper) # @FUNCTION: tribits_extpkg_write_config_file() # -# Write out a ``Config.cmake`` file given the list of include -# directories and libraries for an external package/TPL. +# Write out a ``Config.cmake`` file for a TriBITS TPL given the list +# of include directories and libraries for an external package/TPL. # # Usage:: # @@ -68,6 +68,9 @@ include(MessageWrapper) # and writes that text to the file ```` so see that function # for more details. # +# NOTE: This is used for a classic TriBITS TPL that does **not** use +# ``find_package()`` with modern IMPORTED targets. +# function(tribits_extpkg_write_config_file tplName tplConfigFile) tribits_extpkg_write_config_file_str(${tplName} tplConfigFileStr) file(WRITE "${tplConfigFile}" "${tplConfigFileStr}") From 3389cebc769bfc8a34e2daaf483c55542418279b Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 6 Feb 2023 16:04:04 -0700 Subject: [PATCH 27/45] WIP: Move functions writing Config.cmake files to TribitsExternalPackageWriteConfigFile.cmake (#63) --- ...TribitsExternalPackageFindTplHelpers.cmake | 95 --------------- ...ribitsExternalPackageWriteConfigFile.cmake | 109 ++++++++++++++++++ 2 files changed, 109 insertions(+), 95 deletions(-) diff --git a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake b/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake index aff44a368..8637591e6 100644 --- a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake @@ -117,98 +117,3 @@ function(tribits_extpkg_create_imported_all_libs_target_and_config_file IMPORTED_TARGETS_FOR_ALL_LIBS ${PARSE_IMPORTED_TARGETS_FOR_ALL_LIBS} ) endfunction() - - -# @FUNCTION: tribits_extpkgwit_create_package_config_file() -# -# Create the ``Config.cmake`` file for a TriBITS external package/TPL -# that is defined by a set of IMPORTED targets by call to -# ``find_package()`` -# -# Usage:: -# -# tribits_extpkgwit_create_package_config_file( -# INNER_FIND_PACKAGE_NAME -# IMPORTED_TARGETS_FOR_ALL_LIBS ... ) -# -function(tribits_extpkgwit_create_package_config_file tplName) - # Parse arguments - cmake_parse_arguments( - PARSE_ARGV 1 - PARSE "" "" # prefix, options, one_value_keywords - "INNER_FIND_PACKAGE_NAME;IMPORTED_TARGETS_FOR_ALL_LIBS" #multi_value_keywords - ) - tribits_check_for_unparsed_arguments(PARSE) - tribits_assert_parse_arg_one_value(PARSE INNER_FIND_PACKAGE_NAME) - tribits_assert_parse_arg_one_or_more_values(PARSE IMPORTED_TARGETS_FOR_ALL_LIBS) - set(externalPkg ${PARSE_INNER_FIND_PACKAGE_NAME}) - - # Create header for Config.cmake file - set(configFileStr "") - tribits_extpkgwit_append_package_config_file_header_str( - ${tplName} ${externalPkg} configFileStr) - - # Get ${externalPkg} from where you found it before (see note below) - tribits_extpkgwit_append_find_dependency_external_package_str( - ${tplName} ${externalPkg} configFileStr) - - # Pull in upstream Config.cmake files - tribits_extpkg_append_find_upstream_dependencies_str(${tplName} configFileStr) - - # Add the ${tplName}::all_libs target and link to this ${externalPkg} - # package's native IMPORTED targets - tribits_extpkg_append_create_all_libs_target_str( ${tplName} - LIB_TARGETS_LIST ${PARSE_IMPORTED_TARGETS_FOR_ALL_LIBS} - CONFIG_FILE_STR_INOUT configFileStr ) - - # Also link against upstream package's `::all_libs` targets - tribits_extpkg_append_target_link_libraries_to_upstream_all_libs_targets_str(${tplName} - ${tplName}::all_libs configFileStr) - - tribits_extpkg_append_tribits_compliant_package_config_vars_str(${tplName} - configFileStr) - - tribits_extpkg_write_package_config_file_from_str(${tplName} "${configFileStr}") -endfunction() - - -function(tribits_extpkgwit_append_find_dependency_external_package_str - tplName externalPkg configFileStrVarInOut - ) - set(configFileStr "${${configFileStrVarInOut}}") - if (${externalPkg}_DIR) - string(APPEND configFileStr - "set(${externalPkg}_DIR \"${${externalPkg}_DIR}\")\n" ) - endif() - string(APPEND configFileStr - "find_dependency(${externalPkg})\n\n") - set(${configFileStrVarInOut} "${configFileStr}" PARENT_SCOPE) -endfunction() -# -# NOTE: Above, ${externalPkg}_DIR is only set when -# find_package(${externalPkg}) finds a package configure file -# ${externalPkg}Config.cmake and **not** when it uses a -# Find${externalPkg}.cmake module. Therefore, there is no reason to set -# ${externalPkg}_DIR in this file if it will not be used. - - -function(tribits_extpkgwit_append_package_config_file_header_str - tplName externalPkg configFileStrVarInOut - ) - set(configFileStr "${${configFileStrVarInOut}}") - string(APPEND configFileStr - "# TriBITS-compliant Package config file for external package/TPL '${tplName}'\n" - "# based on non fully TriBITS-compliant external package '${externalPkg}' that uses\n" - "# modern IMPORTED targets\n" - "#\n" - "# Generated by CMake, do not edit!\n" - "\n" - "# Guard against multiple inclusion\n" - "if (TARGET ${tplName}::all_libs)\n" - " return()\n" - "endif()\n" - "\n" - "include(CMakeFindDependencyMacro)\n\n" - ) - set(${configFileStrVarInOut} "${configFileStr}" PARENT_SCOPE) -endfunction() diff --git a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake index d2602bcf4..63187899a 100644 --- a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake @@ -47,6 +47,13 @@ include(TribitsWritePackageConfigFileHelpers) include(MessageWrapper) +################################################################################ +# +# User-level functions +# +################################################################################ + + # @FUNCTION: tribits_extpkg_write_config_file() # # Write out a ``Config.cmake`` file for a TriBITS TPL given the list @@ -168,6 +175,108 @@ function(tribits_extpkg_install_config_version_file tplName endfunction() +################################################################################ +# +# TriBITS Implementation functions +# +################################################################################ + + +# @FUNCTION: tribits_extpkgwit_create_package_config_file() +# +# Create the ``Config.cmake`` file for a TriBITS external package/TPL +# that is defined by a set of IMPORTED targets by call to +# ``find_package()`` +# +# Usage:: +# +# tribits_extpkgwit_create_package_config_file( +# INNER_FIND_PACKAGE_NAME +# IMPORTED_TARGETS_FOR_ALL_LIBS ... ) +# +function(tribits_extpkgwit_create_package_config_file tplName) + # Parse arguments + cmake_parse_arguments( + PARSE_ARGV 1 + PARSE "" "" # prefix, options, one_value_keywords + "INNER_FIND_PACKAGE_NAME;IMPORTED_TARGETS_FOR_ALL_LIBS" #multi_value_keywords + ) + tribits_check_for_unparsed_arguments(PARSE) + tribits_assert_parse_arg_one_value(PARSE INNER_FIND_PACKAGE_NAME) + tribits_assert_parse_arg_one_or_more_values(PARSE IMPORTED_TARGETS_FOR_ALL_LIBS) + set(externalPkg ${PARSE_INNER_FIND_PACKAGE_NAME}) + + # Create header for Config.cmake file + set(configFileStr "") + tribits_extpkgwit_append_package_config_file_header_str( + ${tplName} ${externalPkg} configFileStr) + + # Get ${externalPkg} from where you found it before (see note below) + tribits_extpkgwit_append_find_dependency_external_package_str( + ${tplName} ${externalPkg} configFileStr) + + # Pull in upstream Config.cmake files + tribits_extpkg_append_find_upstream_dependencies_str(${tplName} configFileStr) + + # Add the ${tplName}::all_libs target and link to this ${externalPkg} + # package's native IMPORTED targets + tribits_extpkg_append_create_all_libs_target_str( ${tplName} + LIB_TARGETS_LIST ${PARSE_IMPORTED_TARGETS_FOR_ALL_LIBS} + CONFIG_FILE_STR_INOUT configFileStr ) + + # Also link against upstream package's `::all_libs` targets + tribits_extpkg_append_target_link_libraries_to_upstream_all_libs_targets_str(${tplName} + ${tplName}::all_libs configFileStr) + + tribits_extpkg_append_tribits_compliant_package_config_vars_str(${tplName} + configFileStr) + + tribits_extpkg_write_package_config_file_from_str(${tplName} "${configFileStr}") +endfunction() + + +function(tribits_extpkgwit_append_find_dependency_external_package_str + tplName externalPkg configFileStrVarInOut + ) + set(configFileStr "${${configFileStrVarInOut}}") + if (${externalPkg}_DIR) + string(APPEND configFileStr + "set(${externalPkg}_DIR \"${${externalPkg}_DIR}\")\n" ) + endif() + string(APPEND configFileStr + "find_dependency(${externalPkg})\n\n") + set(${configFileStrVarInOut} "${configFileStr}" PARENT_SCOPE) +endfunction() +# +# NOTE: Above, ${externalPkg}_DIR is only set when +# find_package(${externalPkg}) finds a package configure file +# ${externalPkg}Config.cmake and **not** when it uses a +# Find${externalPkg}.cmake module. Therefore, there is no reason to set +# ${externalPkg}_DIR in this file if it will not be used. + + +function(tribits_extpkgwit_append_package_config_file_header_str + tplName externalPkg configFileStrVarInOut + ) + set(configFileStr "${${configFileStrVarInOut}}") + string(APPEND configFileStr + "# TriBITS-compliant Package config file for external package/TPL '${tplName}'\n" + "# based on non fully TriBITS-compliant external package '${externalPkg}' that uses\n" + "# modern IMPORTED targets\n" + "#\n" + "# Generated by CMake, do not edit!\n" + "\n" + "# Guard against multiple inclusion\n" + "if (TARGET ${tplName}::all_libs)\n" + " return()\n" + "endif()\n" + "\n" + "include(CMakeFindDependencyMacro)\n\n" + ) + set(${configFileStrVarInOut} "${configFileStr}" PARENT_SCOPE) +endfunction() + + # @FUNCTION: tribits_extpkg_write_config_file_str() # # Create the text string for a ``Config.cmake`` file given the list From 28d1beb8be7b57d2bbc7bc2ddcea703dad637cfd Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 6 Feb 2023 16:10:02 -0700 Subject: [PATCH 28/45] WIP: Rename TribitsExternalPackageFindTplHelpers to TribitsExternalPackageWithImportedTargetsFindTplModuleHelpers (#63) --- ...xternalPackageWithImportedTargetsFindTplModuleHelpers.cmake} | 2 +- tribits/core/package_arch/TribitsProcessEnabledTpls.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename tribits/core/package_arch/{TribitsExternalPackageFindTplHelpers.cmake => TribitsExternalPackageWithImportedTargetsFindTplModuleHelpers.cmake} (98%) diff --git a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake b/tribits/core/package_arch/TribitsExternalPackageWithImportedTargetsFindTplModuleHelpers.cmake similarity index 98% rename from tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake rename to tribits/core/package_arch/TribitsExternalPackageWithImportedTargetsFindTplModuleHelpers.cmake index 8637591e6..d6f3fd7ae 100644 --- a/tribits/core/package_arch/TribitsExternalPackageFindTplHelpers.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageWithImportedTargetsFindTplModuleHelpers.cmake @@ -40,7 +40,7 @@ ################################################################################ # -# Module TribitsExternalPackageFindTplHelpers.cmake +# Module TribitsExternalPackageWithImportedTargetsFindTplModuleHelpers.cmake # # Contains functions for implementing FindTPL.cmake files for # external packages using find_package() that producing modern diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake index 928463168..8cda6a2f1 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake @@ -39,7 +39,7 @@ # Standard TriBITS Includes -include(TribitsExternalPackageFindTplHelpers) +include(TribitsExternalPackageWithImportedTargetsFindTplModuleHelpers) include(TribitsExternalPackageWriteConfigFile) include(TribitsTplFindIncludeDirsAndLibraries) include(TribitsGeneralMacros) From 9a1eba16cc9a27528e4270eaddc40240e80f2258 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 6 Feb 2023 17:51:27 -0700 Subject: [PATCH 29/45] WIP: Rename TribitsWriteClientExportFiles.cmake to TribitsInternalPackageWriteConfigFile.cmake (#63) --- test/core/CMakeLists.txt | 4 ++-- ...itsInternalPackageWriteConfigFile_UnitTests.cmake} | 4 ++-- .../add_project_install_commands/CMakeLists.txt | 2 +- ...ke => TribitsInternalPackageWriteConfigFile.cmake} | 11 +++++++++++ tribits/core/package_arch/TribitsPackageMacros.cmake | 2 +- 5 files changed, 17 insertions(+), 6 deletions(-) rename test/core/{TribitsWriteClientExportFiles_UnitTests.cmake => TribitsInternalPackageWriteConfigFile_UnitTests.cmake} (98%) rename tribits/core/package_arch/{TribitsWriteClientExportFiles.cmake => TribitsInternalPackageWriteConfigFile.cmake} (98%) diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt index b4ccb1e59..16506d4fc 100644 --- a/test/core/CMakeLists.txt +++ b/test/core/CMakeLists.txt @@ -121,7 +121,7 @@ tribits_add_advanced_test( TribitsAdjustPackageEnables_UnitTests ) -tribits_add_advanced_test( TribitsWriteClientExportFiles_UnitTests +tribits_add_advanced_test( TribitsInternalPackageWriteConfigFile_UnitTests OVERALL_WORKING_DIRECTORY TEST_NAME TEST_0 CMND ${CMAKE_COMMAND} ARGS @@ -129,7 +129,7 @@ tribits_add_advanced_test( TribitsWriteClientExportFiles_UnitTests -D${PROJECT_NAME}_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR} -DCURRENT_TEST_DIRECTORY=${CMAKE_CURRENT_BINARY_DIR} -DCMAKE_CURRENT_LIST_DIR=${CMAKE_CURRENT_SOURCE_DIR} - -P "${CMAKE_CURRENT_SOURCE_DIR}/TribitsWriteClientExportFiles_UnitTests.cmake" + -P "${CMAKE_CURRENT_SOURCE_DIR}/TribitsInternalPackageWriteConfigFile_UnitTests.cmake" PASS_REGULAR_EXPRESSION_ALL "Final UnitTests Result: num_run = 12" "Final UnitTests Result: PASSED" diff --git a/test/core/TribitsWriteClientExportFiles_UnitTests.cmake b/test/core/TribitsInternalPackageWriteConfigFile_UnitTests.cmake similarity index 98% rename from test/core/TribitsWriteClientExportFiles_UnitTests.cmake rename to test/core/TribitsInternalPackageWriteConfigFile_UnitTests.cmake index b0c823ca3..df9b0ee41 100644 --- a/test/core/TribitsWriteClientExportFiles_UnitTests.cmake +++ b/test/core/TribitsInternalPackageWriteConfigFile_UnitTests.cmake @@ -43,12 +43,12 @@ message("CURRENT_TEST_DIRECTORY = ${CURRENT_TEST_DIRECTORY}") include(${CMAKE_CURRENT_LIST_DIR}/TribitsAdjustPackageEnablesHelpers.cmake) include(TribitsPackageMacros) -include(TribitsWriteClientExportFiles) +include(TribitsInternalPackageWriteConfigFile) ##################################################################### # -# Unit tests for code in TribitsWriteClientExportFiles.cmake +# Unit tests for code in TribitsInternalPackageWriteConfigFile.cmake # ##################################################################### diff --git a/tribits/core/installation/add_project_install_commands/CMakeLists.txt b/tribits/core/installation/add_project_install_commands/CMakeLists.txt index e6d18a739..d1ece7e23 100644 --- a/tribits/core/installation/add_project_install_commands/CMakeLists.txt +++ b/tribits/core/installation/add_project_install_commands/CMakeLists.txt @@ -6,7 +6,7 @@ if ( ${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES AND (NOT ${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES) ) - include(TribitsWriteClientExportFiles) + include(TribitsInternalPackageWriteConfigFile) tribits_write_project_client_export_files() diff --git a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake similarity index 98% rename from tribits/core/package_arch/TribitsWriteClientExportFiles.cmake rename to tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake index 2287ed02a..3365f84e2 100644 --- a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake +++ b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake @@ -37,6 +37,17 @@ # ************************************************************************ # @HEADER + +################################################################################ +# +# Module TribitsInternalPackageWriteConfigFile.cmake +# +# This module contains code for generating Config.cmake files for +# internal TriBITS packages. +# +################################################################################ + + include(TribitsGeneralMacros) include(TribitsPkgExportCacheVars) include(TribitsWritePackageConfigFileHelpers) diff --git a/tribits/core/package_arch/TribitsPackageMacros.cmake b/tribits/core/package_arch/TribitsPackageMacros.cmake index a0c53f512..8411b39f5 100644 --- a/tribits/core/package_arch/TribitsPackageMacros.cmake +++ b/tribits/core/package_arch/TribitsPackageMacros.cmake @@ -38,7 +38,7 @@ # @HEADER include(TribitsPackageSetupCompilerFlags) -include(TribitsWriteClientExportFiles) +include(TribitsInternalPackageWriteConfigFile) include(TribitsGeneralMacros) include(TribitsLibIsTestOnly) From d8d60aee2e4e4a3f4d6c6a2626d338bc4ed3133d Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 6 Feb 2023 18:23:46 -0700 Subject: [PATCH 30/45] WIP: Factor out TribitsProjectWriteConfigFile.cmake, reorder funcs (#63) This commit pulls out the function tribits_write_project_client_export_files() and puts it in the new module TribitsProjectWriteConfigFile.cmake. This commit also rearranges the remaining functions in TribitsInternalPackageWriteConfigFile.cmake to be close to Clean Code ordering. --- .../CMakeLists.txt | 2 +- ...ribitsInternalPackageWriteConfigFile.cmake | 663 +++++++----------- .../TribitsProjectWriteConfigFile.cmake | 228 ++++++ 3 files changed, 470 insertions(+), 423 deletions(-) create mode 100644 tribits/core/package_arch/TribitsProjectWriteConfigFile.cmake diff --git a/tribits/core/installation/add_project_install_commands/CMakeLists.txt b/tribits/core/installation/add_project_install_commands/CMakeLists.txt index d1ece7e23..67c74c964 100644 --- a/tribits/core/installation/add_project_install_commands/CMakeLists.txt +++ b/tribits/core/installation/add_project_install_commands/CMakeLists.txt @@ -6,7 +6,7 @@ if ( ${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES AND (NOT ${PROJECT_NAME}_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES) ) - include(TribitsInternalPackageWriteConfigFile) + include(TribitsProjectWriteConfigFile) tribits_write_project_client_export_files() diff --git a/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake index 3365f84e2..525e67bbb 100644 --- a/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake @@ -52,174 +52,100 @@ include(TribitsGeneralMacros) include(TribitsPkgExportCacheVars) include(TribitsWritePackageConfigFileHelpers) -### -### WARNING: See "NOTES TO DEVELOPERS" at the bottom of the file -### TribitsPackageMacros.cmake! -### -# This function will take a list and turn it into a space separated string -# adding the prefix to the front of every entry. +# Generate the ${PACKAGE_NAME}Config.cmake file for package PACKAGE_NAME. # -function(tribits_list_to_string LIST PREFIX OUTPUT_STRING) - set(LIST_STRING "") +# ToDo: Finish documentation! +# +function(tribits_write_package_client_export_files PACKAGE_NAME) - foreach(ITEM ${LIST}) - set(LIST_STRING "${LIST_STRING} ${PREFIX}${ITEM}") - endforeach() + if(${PROJECT_NAME}_VERBOSE_CONFIGURE) + message("\nTRIBITS_WRITE_PACKAGE_CLIENT_EXPORT_FILES: ${PACKAGE_NAME}") + endif() - set(${OUTPUT_STRING} ${LIST_STRING} PARENT_SCOPE) -endfunction() + set(buildDirCMakePkgsDir + "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_CMAKE_PKGS_DIR}") -# This function will take a list of libraries and turn it into a space -# separated string. In this case though the prefix is not always added -# to the front of each entry as libraries can be specified either as a -# name of a library to find or the absolute path to the library file -# with any decorations the system uses. When an absolute path is given -# the entry is used verbatim. -# -function(tribits_library_list_to_string LIST PREFIX OUTPUT_STRING) - set(LIST_STRING "") + set(EXPORT_FILES_ARGS PACKAGE_NAME ${PACKAGE_NAME}) - foreach(ITEM ${LIST}) - string(SUBSTRING ${ITEM} 0 1 OPTION_FLAG) - if(EXISTS ${ITEM} OR OPTION_FLAG STREQUAL "-") - set(LIST_STRING "${LIST_STRING} ${ITEM}") - else() - set(LIST_STRING "${LIST_STRING} ${PREFIX}${ITEM}") + if (${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES) + if(${PROJECT_NAME}_VERBOSE_CONFIGURE) + message("For package ${PACKAGE_NAME} creating ${PACKAGE_NAME}Config.cmake") endif() - endforeach() + set(PACKAGE_CONFIG_FOR_BUILD_BASE_DIR + "${buildDirCMakePkgsDir}/${PACKAGE_NAME}" ) + set(PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR + "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles" ) + append_set(EXPORT_FILES_ARGS + PACKAGE_CONFIG_FOR_BUILD_BASE_DIR "${PACKAGE_CONFIG_FOR_BUILD_BASE_DIR}" + PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR "${PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR}" + ) + endif() + + tribits_write_flexible_package_client_export_files(${EXPORT_FILES_ARGS}) + + tribits_write_package_client_export_files_install_targets(${EXPORT_FILES_ARGS}) - set(${OUTPUT_STRING} ${LIST_STRING} PARENT_SCOPE) endfunction() -# @FUNCTION: tribits_write_flexible_package_client_export_files() +# @FUNCTION: tribits_write_package_client_export_files_install_targets() # -# Utility function for writing ``${PACKAGE_NAME}Config.cmake`` files for -# package ``${PACKAGE_NAME}`` with some greater flexibility than what is -# provided by the function ``tribits_write_package_client_export_files()`` and -# to allow unit testing the generation of these files.. +# Create the ``ConfigTargets.cmake`` file and install rules and the +# install() target for the previously generated +# ``Config_install.cmake`` files generated by the +# `tribits_write_flexible_package_client_export_files()`_ function. # # Usage:: # -# tribits_write_flexible_package_client_export_files( +# tribits_write_package_client_export_files_install_targets( # PACKAGE_NAME -# [EXPORT_FILE_VAR_PREFIX ] -# [PACKAGE_CONFIG_FOR_BUILD_BASE_DIR ] -# [PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR ] +# PACKAGE_CONFIG_FOR_BUILD_BASE_DIR +# PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR # ) # -# The arguments are: -# -# ``PACKAGE_NAME `` -# -# Gives the name of the TriBITS package for which the export files should -# be created. -# -# ``EXPORT_FILE_VAR_PREFIX `` -# -# If specified, then all of the variables in the generated export files -# will be prefixed with ``_`` instead of -# ``_``. -# -# ``PACKAGE_CONFIG_FOR_BUILD_BASE_DIR `` -# -# If specified, then the package's ``Config.cmake`` file and -# supporting files will be written under the directory -# ``/`` (and any subdirs that does exist -# will be created). The generated file ``Config.cmake`` is -# for usage of the package in the build tree (not the install tree) and -# points to include directories and libraries in the build tree. -# -# ``PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR `` -# -# If specified, then the package's ``Config_install.cmake`` -# file and supporting files will be written under the directory -# ``/`` (and any subdirs that does exist -# will be created). The file ``${PACKAGE_NAME}Config_install.cmake`` is -# meant to be installed renamed as ``Config.cmake`` in the -# install tree and it points to installed include directories and -# libraries. -# -# NOTE: This function does *not* contain any ``install()`` command itself -# because CMake will not allow those to even be present in scripting mode that -# is used for unit testing this function. Instead, the commands to install -# the files are added by the function -# ``tribits_write_package_client_export_files_install_targets()``. +# The install() commands must be in a different subroutine or CMake will not +# allow you to call the routine, even if you if() it out! # -function(tribits_write_flexible_package_client_export_files) - - if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) - message("\ntribits_write_flexible_package_client_export_files(${ARGN})") - endif() - - # - # A) Process the command-line arguments - # +function(tribits_write_package_client_export_files_install_targets) cmake_parse_arguments( #prefix PARSE #options - "WRITE_INSTALL_CMAKE_CONFIG_FILE" + "" #one_value_keywords - "PACKAGE_NAME;EXPORT_FILE_VAR_PREFIX;PACKAGE_CONFIG_FOR_BUILD_BASE_DIR;PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR" + "PACKAGE_NAME;PACKAGE_CONFIG_FOR_BUILD_BASE_DIR;PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR" #multi_value_keywords "" ${ARGN} ) - tribits_check_for_unparsed_arguments() - - if (NOT ${PROJECT_NAME}_GENERATE_EXPORT_FILE_DEPENDENCIES) - message(SEND_ERROR "Error: Can't generate export dependency files because" - " ${PROJECT_NAME}_GENERATE_EXPORT_FILE_DEPENDENCIES is not ON!") - return() - endif() - set(PACKAGE_NAME ${PARSE_PACKAGE_NAME}) - if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) - print_var(PACKAGE_NAME) - endif() - set(EXPORT_FILE_VAR_PREFIX ${PACKAGE_NAME}) - if (PARSE_EXPORT_FILE_VAR_PREFIX) - set(EXPORT_FILE_VAR_PREFIX ${PARSE_EXPORT_FILE_VAR_PREFIX}) - endif() - if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) - print_var(EXPORT_FILE_VAR_PREFIX) + if (PARSE_PACKAGE_CONFIG_FOR_BUILD_BASE_DIR) + tribits_get_package_config_build_dir_targets_file(${PACKAGE_NAME} + "${PARSE_PACKAGE_CONFIG_FOR_BUILD_BASE_DIR}" packageConfigBuildDirTargetsFile ) + export( + EXPORT ${PACKAGE_NAME} + NAMESPACE ${PACKAGE_NAME}:: + FILE "${packageConfigBuildDirTargetsFile}" ) endif() - # Generate a note discouraging editing of the Config.cmake file - set(DISCOURAGE_EDITING "Do not edit: This file was generated automatically by CMake.") - - # - # B) Deal with the library rpath issues with shared libs - # - - # Write the specification of the rpath if necessary. This is only needed if - # we're building shared libraries. - - if(BUILD_SHARED_LIBS) - string(REPLACE ";" ":" SHARED_LIB_RPATH_COMMAND "${FULL_LIBRARY_DIRS_SET}") - set(SHARED_LIB_RPATH_COMMAND - ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}${SHARED_LIB_RPATH_COMMAND}) + if (PARSE_PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR) + install( + FILES + "${PARSE_PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR}/${PACKAGE_NAME}Config_install.cmake" + DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PACKAGE_NAME}" + RENAME ${PACKAGE_NAME}Config.cmake + ) + install( + EXPORT ${PACKAGE_NAME} + NAMESPACE ${PACKAGE_NAME}:: + DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PACKAGE_NAME}" + FILE "${PACKAGE_NAME}Targets.cmake" ) endif() - # - # C) Create the contents of the Config.cmake file for the build tree - # - - tribits_generate_package_config_file_for_build_tree(${PACKAGE_NAME} - EXPORT_FILE_VAR_PREFIX ${EXPORT_FILE_VAR_PREFIX}) - - # - # D) Create Config_install.cmake file for the install tree - # - - tribits_generate_package_config_file_for_install_tree(${PACKAGE_NAME} - EXPORT_FILE_VAR_PREFIX ${EXPORT_FILE_VAR_PREFIX}) - endfunction() @@ -425,35 +351,201 @@ function(tribits_generate_package_config_file_for_install_tree packageName) endfunction() -# @FUNCTION: tribits_append_dependent_package_config_file_includes_and_enables() +# @FUNCTION: tribits_write_flexible_package_client_export_files() # -# Append the includes for upstream external packages (TPLs) and internal -# packages as well as the enables/disables for upstream dependencies to an -# output `Config.cmake` file string. +# Utility function for writing ``${PACKAGE_NAME}Config.cmake`` files for +# package ``${PACKAGE_NAME}`` with some greater flexibility than what is +# provided by the function ``tribits_write_package_client_export_files()`` and +# to allow unit testing the generation of these files.. # # Usage:: # -# tribits_append_dependent_package_config_file_includes_and_enables( -# -# EXPORT_FILE_VAR_PREFIX -# EXT_PKG_CONFIG_FILE_BASE_DIR -# PKG_CONFIG_FILE_BASE_DIR -# CONFIG_FILE_STR_INOUT +# tribits_write_flexible_package_client_export_files( +# PACKAGE_NAME +# [EXPORT_FILE_VAR_PREFIX ] +# [PACKAGE_CONFIG_FOR_BUILD_BASE_DIR ] +# [PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR ] # ) # -function(tribits_append_dependent_package_config_file_includes_and_enables packageName) +# The arguments are: +# +# ``PACKAGE_NAME `` +# +# Gives the name of the TriBITS package for which the export files should +# be created. +# +# ``EXPORT_FILE_VAR_PREFIX `` +# +# If specified, then all of the variables in the generated export files +# will be prefixed with ``_`` instead of +# ``_``. +# +# ``PACKAGE_CONFIG_FOR_BUILD_BASE_DIR `` +# +# If specified, then the package's ``Config.cmake`` file and +# supporting files will be written under the directory +# ``/`` (and any subdirs that does exist +# will be created). The generated file ``Config.cmake`` is +# for usage of the package in the build tree (not the install tree) and +# points to include directories and libraries in the build tree. +# +# ``PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR `` +# +# If specified, then the package's ``Config_install.cmake`` +# file and supporting files will be written under the directory +# ``/`` (and any subdirs that does exist +# will be created). The file ``${PACKAGE_NAME}Config_install.cmake`` is +# meant to be installed renamed as ``Config.cmake`` in the +# install tree and it points to installed include directories and +# libraries. +# +# NOTE: This function does *not* contain any ``install()`` command itself +# because CMake will not allow those to even be present in scripting mode that +# is used for unit testing this function. Instead, the commands to install +# the files are added by the function +# ``tribits_write_package_client_export_files_install_targets()``. +# +function(tribits_write_flexible_package_client_export_files) if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) - message("tribits_append_dependent_package_config_file_includes_and_enables(${ARGV})") + message("\ntribits_write_flexible_package_client_export_files(${ARGN})") endif() - # Parse input + # + # A) Process the command-line arguments + # cmake_parse_arguments( - PARSE "" # prefix, options - #one_value_keywords - "EXPORT_FILE_VAR_PREFIX;EXT_PKG_CONFIG_FILE_BASE_DIR;PKG_CONFIG_FILE_BASE_DIR;CONFIG_FILE_STR_INOUT" - "" #multi_value_keywords + #prefix + PARSE + #options + "WRITE_INSTALL_CMAKE_CONFIG_FILE" + #one_value_keywords + "PACKAGE_NAME;EXPORT_FILE_VAR_PREFIX;PACKAGE_CONFIG_FOR_BUILD_BASE_DIR;PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR" + #multi_value_keywords + "" + ${ARGN} + ) + + tribits_check_for_unparsed_arguments() + + if (NOT ${PROJECT_NAME}_GENERATE_EXPORT_FILE_DEPENDENCIES) + message(SEND_ERROR "Error: Can't generate export dependency files because" + " ${PROJECT_NAME}_GENERATE_EXPORT_FILE_DEPENDENCIES is not ON!") + return() + endif() + + set(PACKAGE_NAME ${PARSE_PACKAGE_NAME}) + if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) + print_var(PACKAGE_NAME) + endif() + + set(EXPORT_FILE_VAR_PREFIX ${PACKAGE_NAME}) + if (PARSE_EXPORT_FILE_VAR_PREFIX) + set(EXPORT_FILE_VAR_PREFIX ${PARSE_EXPORT_FILE_VAR_PREFIX}) + endif() + if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) + print_var(EXPORT_FILE_VAR_PREFIX) + endif() + + # Generate a note discouraging editing of the Config.cmake file + set(DISCOURAGE_EDITING "Do not edit: This file was generated automatically by CMake.") + + # + # B) Deal with the library rpath issues with shared libs + # + + # Write the specification of the rpath if necessary. This is only needed if + # we're building shared libraries. + + if(BUILD_SHARED_LIBS) + string(REPLACE ";" ":" SHARED_LIB_RPATH_COMMAND "${FULL_LIBRARY_DIRS_SET}") + set(SHARED_LIB_RPATH_COMMAND + ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}${SHARED_LIB_RPATH_COMMAND}) + endif() + + # + # C) Create the contents of the Config.cmake file for the build tree + # + + tribits_generate_package_config_file_for_build_tree(${PACKAGE_NAME} + EXPORT_FILE_VAR_PREFIX ${EXPORT_FILE_VAR_PREFIX}) + + # + # D) Create Config_install.cmake file for the install tree + # + + tribits_generate_package_config_file_for_install_tree(${PACKAGE_NAME} + EXPORT_FILE_VAR_PREFIX ${EXPORT_FILE_VAR_PREFIX}) + +endfunction() + + +# This function will take a list and turn it into a space separated string +# adding the prefix to the front of every entry. +# +function(tribits_list_to_string LIST PREFIX OUTPUT_STRING) + set(LIST_STRING "") + + foreach(ITEM ${LIST}) + set(LIST_STRING "${LIST_STRING} ${PREFIX}${ITEM}") + endforeach() + + set(${OUTPUT_STRING} ${LIST_STRING} PARENT_SCOPE) +endfunction() + +# This function will take a list of libraries and turn it into a space +# separated string. In this case though the prefix is not always added +# to the front of each entry as libraries can be specified either as a +# name of a library to find or the absolute path to the library file +# with any decorations the system uses. When an absolute path is given +# the entry is used verbatim. +# +function(tribits_library_list_to_string LIST PREFIX OUTPUT_STRING) + set(LIST_STRING "") + + foreach(ITEM ${LIST}) + string(SUBSTRING ${ITEM} 0 1 OPTION_FLAG) + if(EXISTS ${ITEM} OR OPTION_FLAG STREQUAL "-") + set(LIST_STRING "${LIST_STRING} ${ITEM}") + else() + set(LIST_STRING "${LIST_STRING} ${PREFIX}${ITEM}") + endif() + endforeach() + + set(${OUTPUT_STRING} ${LIST_STRING} PARENT_SCOPE) +endfunction() + + +# @FUNCTION: tribits_append_dependent_package_config_file_includes_and_enables() +# +# Append the includes for upstream external packages (TPLs) and internal +# packages as well as the enables/disables for upstream dependencies to an +# output `Config.cmake` file string. +# +# Usage:: +# +# tribits_append_dependent_package_config_file_includes_and_enables( +# +# EXPORT_FILE_VAR_PREFIX +# EXT_PKG_CONFIG_FILE_BASE_DIR +# PKG_CONFIG_FILE_BASE_DIR +# CONFIG_FILE_STR_INOUT +# ) +# +function(tribits_append_dependent_package_config_file_includes_and_enables packageName) + + if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) + message("tribits_append_dependent_package_config_file_includes_and_enables(${ARGV})") + endif() + + # Parse input + + cmake_parse_arguments( + PARSE "" # prefix, options + #one_value_keywords + "EXPORT_FILE_VAR_PREFIX;EXT_PKG_CONFIG_FILE_BASE_DIR;PKG_CONFIG_FILE_BASE_DIR;CONFIG_FILE_STR_INOUT" + "" #multi_value_keywords ${ARGN} ) tribits_check_for_unparsed_arguments() @@ -519,66 +611,6 @@ function(tribits_append_dependent_package_config_file_includes_and_enables packa endfunction() -# @FUNCTION: tribits_write_package_client_export_files_install_targets() -# -# Create the ``ConfigTargets.cmake`` file and install rules and the -# install() target for the previously generated -# ``Config_install.cmake`` files generated by the -# `tribits_write_flexible_package_client_export_files()`_ function. -# -# Usage:: -# -# tribits_write_package_client_export_files_install_targets( -# PACKAGE_NAME -# PACKAGE_CONFIG_FOR_BUILD_BASE_DIR -# PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR -# ) -# -# The install() commands must be in a different subroutine or CMake will not -# allow you to call the routine, even if you if() it out! -# -function(tribits_write_package_client_export_files_install_targets) - - cmake_parse_arguments( - #prefix - PARSE - #options - "" - #one_value_keywords - "PACKAGE_NAME;PACKAGE_CONFIG_FOR_BUILD_BASE_DIR;PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR" - #multi_value_keywords - "" - ${ARGN} - ) - - set(PACKAGE_NAME ${PARSE_PACKAGE_NAME}) - - if (PARSE_PACKAGE_CONFIG_FOR_BUILD_BASE_DIR) - tribits_get_package_config_build_dir_targets_file(${PACKAGE_NAME} - "${PARSE_PACKAGE_CONFIG_FOR_BUILD_BASE_DIR}" packageConfigBuildDirTargetsFile ) - export( - EXPORT ${PACKAGE_NAME} - NAMESPACE ${PACKAGE_NAME}:: - FILE "${packageConfigBuildDirTargetsFile}" ) - endif() - - if (PARSE_PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR) - install( - FILES - "${PARSE_PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR}/${PACKAGE_NAME}Config_install.cmake" - DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PACKAGE_NAME}" - RENAME ${PACKAGE_NAME}Config.cmake - ) - install( - EXPORT ${PACKAGE_NAME} - NAMESPACE ${PACKAGE_NAME}:: - DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PACKAGE_NAME}" - FILE "${PACKAGE_NAME}Targets.cmake" ) - endif() - -endfunction() - - # Function to return the full path the targets file for the # Config.cmake file in the build tree. # @@ -591,219 +623,6 @@ function(tribits_get_package_config_build_dir_targets_file PACKAGE_NAME endfunction() -# Generate the ${PACKAGE_NAME}Config.cmake file for package PACKAGE_NAME. -# -# ToDo: Finish documentation! -# -function(tribits_write_package_client_export_files PACKAGE_NAME) - - if(${PROJECT_NAME}_VERBOSE_CONFIGURE) - message("\nTRIBITS_WRITE_PACKAGE_CLIENT_EXPORT_FILES: ${PACKAGE_NAME}") - endif() - - set(buildDirCMakePkgsDir - "${${PROJECT_NAME}_BINARY_DIR}/${${PROJECT_NAME}_BUILD_DIR_CMAKE_PKGS_DIR}") - - set(EXPORT_FILES_ARGS PACKAGE_NAME ${PACKAGE_NAME}) - - if (${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES) - if(${PROJECT_NAME}_VERBOSE_CONFIGURE) - message("For package ${PACKAGE_NAME} creating ${PACKAGE_NAME}Config.cmake") - endif() - set(PACKAGE_CONFIG_FOR_BUILD_BASE_DIR - "${buildDirCMakePkgsDir}/${PACKAGE_NAME}" ) - set(PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR - "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles" ) - append_set(EXPORT_FILES_ARGS - PACKAGE_CONFIG_FOR_BUILD_BASE_DIR "${PACKAGE_CONFIG_FOR_BUILD_BASE_DIR}" - PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR "${PACKAGE_CONFIG_FOR_INSTALL_BASE_DIR}" - ) - endif() - - tribits_write_flexible_package_client_export_files(${EXPORT_FILES_ARGS}) - - tribits_write_package_client_export_files_install_targets(${EXPORT_FILES_ARGS}) - -endfunction() - - -# Write the outer TriBITS Config.cmake file -# -# If ${PROJECT_NAME}_VERSION is not set or is '' on input, then it will be set -# to 0.0.0 in order to create the ${PROJECT_NAME}ConfigVersion.cmake file. -# -# ToDo: Finish documentation! -# -function(tribits_write_project_client_export_files) - - set(EXPORT_FILE_VAR_PREFIX ${PROJECT_NAME}) - - # Reversing the package list so that libraries will be produced in order of - # most dependent to least dependent. - set(PACKAGE_LIST ${${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES}) - if (PACKAGE_LIST) - list(REVERSE PACKAGE_LIST) - endif() - - # Loop over all packages to determine which were enabled. Then build a list - # of all their libraries/includes in the proper order for linking - set(FULL_PACKAGE_SET "") - set(FULL_LIBRARY_SET "") - foreach(TRIBITS_PACKAGE ${PACKAGE_LIST}) - if(${PROJECT_NAME}_ENABLE_${TRIBITS_PACKAGE}) - list(APPEND FULL_PACKAGE_SET ${TRIBITS_PACKAGE}) - list(APPEND FULL_LIBRARY_SET ${${TRIBITS_PACKAGE}_LIBRARIES}) - endif() - endforeach() - - set(${PROJECT_NAME}_CONFIG_LIBRARIES ${FULL_LIBRARY_SET}) - - # Reversing the tpl list so that the list of tpls will be produced in - # order of most dependent to least dependent. - if (${PROJECT_NAME}_DEFINED_TPLS) - set(TPL_LIST ${${PROJECT_NAME}_DEFINED_TPLS}) - list(REVERSE TPL_LIST) - endif() - - # Loop over all TPLs to determine which were enabled. Then build a list - # of all their libraries/includes in the proper order for linking - set(FULL_TPL_SET "") - set(FULL_TPL_LIBRARY_SET "") - foreach(TPL ${TPL_LIST}) - if(TPL_ENABLE_${TPL}) - list(APPEND FULL_TPL_SET ${TPL}) - list(APPEND FULL_TPL_LIBRARY_SET ${TPL_${TPL}_LIBRARIES}) - endif() - endforeach() - - set(${PROJECT_NAME}_CONFIG_TPL_LIBRARIES ${FULL_TPL_LIBRARY_SET}) - - # - # Configure two files for finding ${PROJECT_NAME}. One for the build tree - # and one for installing - # - - # Generate a note discouraging editing of the Config.cmake file - set(DISCOURAGE_EDITING "Do not edit: This file was generated automatically by CMake.") - - # Write the specification of the rpath if necessary. This is only needed if - # we're building shared libraries. - if(BUILD_SHARED_LIBS) - string(REPLACE ";" ":" SHARED_LIB_RPATH_COMMAND - "${${PROJECT_NAME}_CONFIG_LIBRARY_DIRS}") - set(SHARED_LIB_RPATH_COMMAND ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}${SHARED_LIB_RPATH_COMMAND}) - endif() - - # Custom code in configuration file. - set(PROJECT_CONFIG_CODE "") - - # Appending the logic to include each package's config file. - set(LOAD_CODE "# Load configurations from enabled packages") - foreach(TRIBITS_PACKAGE ${FULL_PACKAGE_SET}) - set(LOAD_CODE "${LOAD_CODE} -include(\"${${TRIBITS_PACKAGE}_BINARY_DIR}/${TRIBITS_PACKAGE}Config.cmake\")") - endforeach() - set(PROJECT_CONFIG_CODE "${PROJECT_CONFIG_CODE}\n${LOAD_CODE}") - - tribits_set_compiler_vars_for_config_file(INSTALL_DIR) - - if (${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES) - # In TribitsProjectConfigTemplate.cmake.in, we would like to preserve - # ${}-variables after the conversion to TribitsProjectConfigTemplate.cmake. - # To this end, one typically uses the @-syntax for variables. That doesn't - # support nested variables, however. Use ${PDOLLAR} as a workaround, cf. - # . - set(PDOLLAR "$") - set(tribitsInstallationDir - "${${PROJECT_NAME}_TRIBITS_DIR}/${TRIBITS_CMAKE_INSTALLATION_FILES_DIR}") - set(TRIBITS_PROJECT_INSTALL_INCLUDE_DIR "") - configure_file( - "${tribitsInstallationDir}/TribitsProjectConfigTemplate.cmake.in" - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" ) - endif() - - ###### - # Create a configure file for the install tree and set the install target for it. This - # file isn't generally useful inside the build tree. It will be placed in the base - # install directory for ${PROJECT_NAME} when installed. - ###### - - # Set the include and library directories relative to the location - # at which the ${PROJECT_NAME}Config.cmake file is going to be - # installed. Note the variable reference below is escaped so it - # won't be replaced until a client project attempts to locate - # directories using the installed config file. This is to deal with - # installers that allow relocation of the install tree at *install* - # time. - # The export files are typically installed in - # //cmake//. - # The relative path to the installation dir is hence k*(../) + ../../, where - # k is the number of components in . Extract those here. - # This doesn't work if ${${PROJECT_NAME}_INSTALL_LIB_DIR} contains "./" or - # "../" components, but really, it never did. All of this should actually be - # handled by CMake's configure_package_config_file(). - string(REPLACE "/" ";" PATH_LIST ${${PROJECT_NAME}_INSTALL_LIB_DIR}) - set(RELATIVE_PATH "../..") - foreach(PATH ${PATH_LIST}) - set(RELATIVE_PATH "${RELATIVE_PATH}/..") - endforeach() - - # Write the specification of the rpath if necessary. This is only needed if - # we're building shared libraries. - if(BUILD_SHARED_LIBS) - set(SHARED_LIB_RPATH_COMMAND - "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_LIB_DIR}" - ) - endif() - - if (${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES) - - tribits_set_compiler_vars_for_config_file(INSTALL_DIR) - - # Custom code in configuration file. - set(PROJECT_CONFIG_CODE "") - - set(PDOLLAR "$") # Hack used in configure file below - - if (IS_ABSOLUTE "${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}") - set(TRIBITS_PROJECT_INSTALL_INCLUDE_DIR "${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}") - else() - set(TRIBITS_PROJECT_INSTALL_INCLUDE_DIR - "${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}") - endif() - - configure_file( - "${${PROJECT_NAME}_TRIBITS_DIR}/${TRIBITS_CMAKE_INSTALLATION_FILES_DIR}/TribitsProjectConfigTemplate.cmake.in" - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config_install.cmake" - ) - - install( - FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config_install.cmake" - DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PROJECT_NAME}" - RENAME ${PROJECT_NAME}Config.cmake - ) - endif() - - # - # Configure the version file for ${PROJECT_NAME} - # - include(CMakePackageConfigHelpers) - if ("${${PROJECT_NAME}_VERSION}" STREQUAL "") - set(${PROJECT_NAME}_VERSION 0.0.0) - endif() - write_basic_package_version_file( - ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - VERSION ${${PROJECT_NAME}_VERSION} - COMPATIBILITY SameMajorVersion - ) - install( - FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PROJECT_NAME}" - ) - -endfunction() - - macro(tribits_set_compiler_var_for_config_file LANG FOR_DIR) if (NOT "${CMAKE_${LANG}_COMPILER_FOR_CONFIG_FILE_${FOR_DIR}}" STREQUAL "") set(CMAKE_${LANG}_COMPILER_FOR_CONFIG_FILE diff --git a/tribits/core/package_arch/TribitsProjectWriteConfigFile.cmake b/tribits/core/package_arch/TribitsProjectWriteConfigFile.cmake new file mode 100644 index 000000000..5f4fa7089 --- /dev/null +++ b/tribits/core/package_arch/TribitsProjectWriteConfigFile.cmake @@ -0,0 +1,228 @@ +# @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 + + +################################################################################ +# +# Module TribitsInternalPackageWriteConfigFile.cmake +# +# This module contains code for generating Config.cmake files for +# TriBITS projects. +# +################################################################################ + + +include(TribitsInternalPackageWriteConfigFile) + + +# Write the outer TriBITS Config.cmake file +# +# If ${PROJECT_NAME}_VERSION is not set or is '' on input, then it will be set +# to 0.0.0 in order to create the ${PROJECT_NAME}ConfigVersion.cmake file. +# +# ToDo: Finish documentation! +# +function(tribits_write_project_client_export_files) + + set(EXPORT_FILE_VAR_PREFIX ${PROJECT_NAME}) + + # Reversing the package list so that libraries will be produced in order of + # most dependent to least dependent. + set(PACKAGE_LIST ${${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES}) + if (PACKAGE_LIST) + list(REVERSE PACKAGE_LIST) + endif() + + # Loop over all packages to determine which were enabled. Then build a list + # of all their libraries/includes in the proper order for linking + set(FULL_PACKAGE_SET "") + set(FULL_LIBRARY_SET "") + foreach(TRIBITS_PACKAGE ${PACKAGE_LIST}) + if(${PROJECT_NAME}_ENABLE_${TRIBITS_PACKAGE}) + list(APPEND FULL_PACKAGE_SET ${TRIBITS_PACKAGE}) + list(APPEND FULL_LIBRARY_SET ${${TRIBITS_PACKAGE}_LIBRARIES}) + endif() + endforeach() + + set(${PROJECT_NAME}_CONFIG_LIBRARIES ${FULL_LIBRARY_SET}) + + # Reversing the tpl list so that the list of tpls will be produced in + # order of most dependent to least dependent. + if (${PROJECT_NAME}_DEFINED_TPLS) + set(TPL_LIST ${${PROJECT_NAME}_DEFINED_TPLS}) + list(REVERSE TPL_LIST) + endif() + + # Loop over all TPLs to determine which were enabled. Then build a list + # of all their libraries/includes in the proper order for linking + set(FULL_TPL_SET "") + set(FULL_TPL_LIBRARY_SET "") + foreach(TPL ${TPL_LIST}) + if(TPL_ENABLE_${TPL}) + list(APPEND FULL_TPL_SET ${TPL}) + list(APPEND FULL_TPL_LIBRARY_SET ${TPL_${TPL}_LIBRARIES}) + endif() + endforeach() + + set(${PROJECT_NAME}_CONFIG_TPL_LIBRARIES ${FULL_TPL_LIBRARY_SET}) + + # + # Configure two files for finding ${PROJECT_NAME}. One for the build tree + # and one for installing + # + + # Generate a note discouraging editing of the Config.cmake file + set(DISCOURAGE_EDITING "Do not edit: This file was generated automatically by CMake.") + + # Write the specification of the rpath if necessary. This is only needed if + # we're building shared libraries. + if(BUILD_SHARED_LIBS) + string(REPLACE ";" ":" SHARED_LIB_RPATH_COMMAND + "${${PROJECT_NAME}_CONFIG_LIBRARY_DIRS}") + set(SHARED_LIB_RPATH_COMMAND ${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}${SHARED_LIB_RPATH_COMMAND}) + endif() + + # Custom code in configuration file. + set(PROJECT_CONFIG_CODE "") + + # Appending the logic to include each package's config file. + set(LOAD_CODE "# Load configurations from enabled packages") + foreach(TRIBITS_PACKAGE ${FULL_PACKAGE_SET}) + set(LOAD_CODE "${LOAD_CODE} +include(\"${${TRIBITS_PACKAGE}_BINARY_DIR}/${TRIBITS_PACKAGE}Config.cmake\")") + endforeach() + set(PROJECT_CONFIG_CODE "${PROJECT_CONFIG_CODE}\n${LOAD_CODE}") + + tribits_set_compiler_vars_for_config_file(INSTALL_DIR) + + if (${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES) + # In TribitsProjectConfigTemplate.cmake.in, we would like to preserve + # ${}-variables after the conversion to TribitsProjectConfigTemplate.cmake. + # To this end, one typically uses the @-syntax for variables. That doesn't + # support nested variables, however. Use ${PDOLLAR} as a workaround, cf. + # . + set(PDOLLAR "$") + set(tribitsInstallationDir + "${${PROJECT_NAME}_TRIBITS_DIR}/${TRIBITS_CMAKE_INSTALLATION_FILES_DIR}") + set(TRIBITS_PROJECT_INSTALL_INCLUDE_DIR "") + configure_file( + "${tribitsInstallationDir}/TribitsProjectConfigTemplate.cmake.in" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" ) + endif() + + ###### + # Create a configure file for the install tree and set the install target for it. This + # file isn't generally useful inside the build tree. It will be placed in the base + # install directory for ${PROJECT_NAME} when installed. + ###### + + # Set the include and library directories relative to the location + # at which the ${PROJECT_NAME}Config.cmake file is going to be + # installed. Note the variable reference below is escaped so it + # won't be replaced until a client project attempts to locate + # directories using the installed config file. This is to deal with + # installers that allow relocation of the install tree at *install* + # time. + # The export files are typically installed in + # //cmake//. + # The relative path to the installation dir is hence k*(../) + ../../, where + # k is the number of components in . Extract those here. + # This doesn't work if ${${PROJECT_NAME}_INSTALL_LIB_DIR} contains "./" or + # "../" components, but really, it never did. All of this should actually be + # handled by CMake's configure_package_config_file(). + string(REPLACE "/" ";" PATH_LIST ${${PROJECT_NAME}_INSTALL_LIB_DIR}) + set(RELATIVE_PATH "../..") + foreach(PATH ${PATH_LIST}) + set(RELATIVE_PATH "${RELATIVE_PATH}/..") + endforeach() + + # Write the specification of the rpath if necessary. This is only needed if + # we're building shared libraries. + if(BUILD_SHARED_LIBS) + set(SHARED_LIB_RPATH_COMMAND + "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_LIB_DIR}" + ) + endif() + + if (${PROJECT_NAME}_ENABLE_INSTALL_CMAKE_CONFIG_FILES) + + tribits_set_compiler_vars_for_config_file(INSTALL_DIR) + + # Custom code in configuration file. + set(PROJECT_CONFIG_CODE "") + + set(PDOLLAR "$") # Hack used in configure file below + + if (IS_ABSOLUTE "${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}") + set(TRIBITS_PROJECT_INSTALL_INCLUDE_DIR "${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}") + else() + set(TRIBITS_PROJECT_INSTALL_INCLUDE_DIR + "${CMAKE_INSTALL_PREFIX}/${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}") + endif() + + configure_file( + "${${PROJECT_NAME}_TRIBITS_DIR}/${TRIBITS_CMAKE_INSTALLATION_FILES_DIR}/TribitsProjectConfigTemplate.cmake.in" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config_install.cmake" + ) + + install( + FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config_install.cmake" + DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PROJECT_NAME}" + RENAME ${PROJECT_NAME}Config.cmake + ) + endif() + + # + # Configure the version file for ${PROJECT_NAME} + # + include(CMakePackageConfigHelpers) + if ("${${PROJECT_NAME}_VERSION}" STREQUAL "") + set(${PROJECT_NAME}_VERSION 0.0.0) + endif() + write_basic_package_version_file( + ${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + VERSION ${${PROJECT_NAME}_VERSION} + COMPATIBILITY SameMajorVersion + ) + install( + FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + DESTINATION "${${PROJECT_NAME}_INSTALL_LIB_DIR}/cmake/${PROJECT_NAME}" + ) + +endfunction() From f14bba24cd92a4c9e1a5aa22c91068a956df0638 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 6 Feb 2023 18:50:23 -0700 Subject: [PATCH 31/45] WIP: Rename func, remove unused funcs (#63) Renamed the function tribits_append_dependent_package_config_file_includes_and_enables() to tribits_append_dependent_package_config_file_includes_and_enables_str() to make it clear this is appending a string. Removed the functions tribits_list_to_string() and tribits_library_list_to_string() as they were no longer being used. (An earlier refactoring removed the need for these functions but I just forgot to remove them after that refactoring.) --- ...ribitsInternalPackageWriteConfigFile.cmake | 48 +++---------------- 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake index 525e67bbb..9d6691402 100644 --- a/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake @@ -198,7 +198,7 @@ function(tribits_generate_package_config_file_for_build_tree packageName) # below) set(PACKAGE_CONFIG_CODE "") - tribits_append_dependent_package_config_file_includes_and_enables(${packageName} + tribits_append_dependent_package_config_file_includes_and_enables_str(${packageName} EXPORT_FILE_VAR_PREFIX ${EXPORT_FILE_VAR_PREFIX} EXT_PKG_CONFIG_FILE_BASE_DIR "${buildDirExtPkgsDir}" PKG_CONFIG_FILE_BASE_DIR "${buildDirCMakePkgsDir}" @@ -312,7 +312,7 @@ function(tribits_generate_package_config_file_for_install_tree packageName) # Custom code in configuration file. set(PACKAGE_CONFIG_CODE "") - tribits_append_dependent_package_config_file_includes_and_enables(${packageName} + tribits_append_dependent_package_config_file_includes_and_enables_str(${packageName} EXPORT_FILE_VAR_PREFIX ${EXPORT_FILE_VAR_PREFIX} EXT_PKG_CONFIG_FILE_BASE_DIR "\${CMAKE_CURRENT_LIST_DIR}/../../${${PROJECT_NAME}_BUILD_DIR_EXTERNAL_PKGS_DIR}" @@ -481,43 +481,7 @@ function(tribits_write_flexible_package_client_export_files) endfunction() -# This function will take a list and turn it into a space separated string -# adding the prefix to the front of every entry. -# -function(tribits_list_to_string LIST PREFIX OUTPUT_STRING) - set(LIST_STRING "") - - foreach(ITEM ${LIST}) - set(LIST_STRING "${LIST_STRING} ${PREFIX}${ITEM}") - endforeach() - - set(${OUTPUT_STRING} ${LIST_STRING} PARENT_SCOPE) -endfunction() - -# This function will take a list of libraries and turn it into a space -# separated string. In this case though the prefix is not always added -# to the front of each entry as libraries can be specified either as a -# name of a library to find or the absolute path to the library file -# with any decorations the system uses. When an absolute path is given -# the entry is used verbatim. -# -function(tribits_library_list_to_string LIST PREFIX OUTPUT_STRING) - set(LIST_STRING "") - - foreach(ITEM ${LIST}) - string(SUBSTRING ${ITEM} 0 1 OPTION_FLAG) - if(EXISTS ${ITEM} OR OPTION_FLAG STREQUAL "-") - set(LIST_STRING "${LIST_STRING} ${ITEM}") - else() - set(LIST_STRING "${LIST_STRING} ${PREFIX}${ITEM}") - endif() - endforeach() - - set(${OUTPUT_STRING} ${LIST_STRING} PARENT_SCOPE) -endfunction() - - -# @FUNCTION: tribits_append_dependent_package_config_file_includes_and_enables() +# @FUNCTION: tribits_append_dependent_package_config_file_includes_and_enables_str() # # Append the includes for upstream external packages (TPLs) and internal # packages as well as the enables/disables for upstream dependencies to an @@ -525,7 +489,7 @@ endfunction() # # Usage:: # -# tribits_append_dependent_package_config_file_includes_and_enables( +# tribits_append_dependent_package_config_file_includes_and_enables_str( # # EXPORT_FILE_VAR_PREFIX # EXT_PKG_CONFIG_FILE_BASE_DIR @@ -533,10 +497,10 @@ endfunction() # CONFIG_FILE_STR_INOUT # ) # -function(tribits_append_dependent_package_config_file_includes_and_enables packageName) +function(tribits_append_dependent_package_config_file_includes_and_enables_str packageName) if (TRIBITS_WRITE_FLEXIBLE_PACKAGE_CLIENT_EXPORT_FILES_DEBUG_DUMP) - message("tribits_append_dependent_package_config_file_includes_and_enables(${ARGV})") + message("tribits_append_dependent_package_config_file_includes_and_enables_str(${ARGV})") endif() # Parse input From bdd12c9fac6965263c5d7e8464037fee16c578ad Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 7 Feb 2023 06:29:42 -0700 Subject: [PATCH 32/45] WIP: Remove 'Fully' from 'Fully TriBITS-Compliant' (and variations) (#63) * Replaced "fully TriBITS-compliant" with "TriBITS-compliant" (all capitalizations and with or without '-') * Replaced "TriBITS-compatible" with "TriBITS-compliant" (all capitalizations and with or without '-') * Renamed `tribits_process_enabled_fully_tribits_compatible_or_upstream_tpl()` to `tribits_process_enabled_tribits_compliant_or_upstream_tpl()` * Renamed `tribits_process_enabled_tribits_compatible_tpl()` to `tribits_process_enabled_tribits_compliant_tpl()` * Updated some documentaiton I noticed while making these replacements --- .../TribitsExampleProject2_Tests.cmake | 30 ++++++------ .../TribitsExampleProject_Tests.cmake | 46 +++++++++---------- .../TribitsAdjustPackageEnables.cmake | 10 ++-- ...ribitsExternalPackageWriteConfigFile.cmake | 2 +- .../TribitsProcessEnabledTpls.cmake | 20 ++++---- .../TribitsProcessPackagesAndDirsLists.cmake | 4 +- .../TribitsProcessTplsLists.cmake | 11 +++-- .../TribitsReadDepsFilesCreateDepsGraph.cmake | 4 +- ...itsSystemDataStructuresMacrosFunctions.rst | 40 ++++++++-------- tribits/doc/guides/TribitsGuidesBody.rst | 8 ++-- 10 files changed, 88 insertions(+), 87 deletions(-) diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake index 7b8140689..9f66911f5 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake @@ -935,18 +935,18 @@ function(TribitsExampleProject2_External_Package_by_Package PASS_REGULAR_EXPRESSION_ALL "Adjust the set of internal and external packages:" "-- Treating internal package Package1 as EXTERNAL because TPL_ENABLE_Package1=ON" - "-- NOTE: Tpl1 is directly downstream from an fully TriBITS-compatible external package Package1" + "-- NOTE: Tpl1 is directly downstream from an TriBITS-compliant external package Package1" "Final set of enabled top-level packages: Package2 1" "Final set of non-enabled top-level packages: Package3 1" "Final set of enabled top-level external packages/TPLs: Tpl1 Tpl2 Tpl3 Package1 4" "Final set of non-enabled top-level external packages/TPLs: Tpl4 1" - "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." + "Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs ..." "Processing enabled external package/TPL: Tpl1 [(]enabled by Package1, disable with -DTPL_ENABLE_Tpl1=OFF[)]" - "-- The external package/TPL Tpl1 will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL Tpl1 will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: Package1 [(]enabled explicitly, disable with -DTPL_ENABLE_Package1=OFF[)]" - "-- Calling find_package[(]Package1[)] for TriBITS-compatible package" + "-- Calling find_package[(]Package1[)] for TriBITS-compliant package" "Getting information for all enabled external packages/TPLs ..." "Processing enabled external package/TPL: Tpl2 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl2=OFF[)]" @@ -998,28 +998,28 @@ function(TribitsExampleProject2_External_Package_by_Package "Adjust the set of internal and external packages:" "-- Treating internal package Package2 as EXTERNAL because TPL_ENABLE_Package2=ON" "-- Treating internal package Package1 as EXTERNAL because downstream package Package2 being treated as EXTERNAL" - "-- NOTE: Package1 is directly downstream from an fully TriBITS-compatible external package Package2" - "-- NOTE: Tpl3 is directly downstream from an fully TriBITS-compatible external package Package2" - "-- NOTE: Tpl1 is indirectly downstream from an fully TriBITS-compatible external package" - "-- NOTE: Tpl2 is indirectly downstream from an fully TriBITS-compatible external package" - "-- NOTE: Tpl1 is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: Package1 is directly downstream from an TriBITS-compliant external package Package2" + "-- NOTE: Tpl3 is directly downstream from an TriBITS-compliant external package Package2" + "-- NOTE: Tpl1 is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: Tpl2 is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: Tpl1 is indirectly downstream from an TriBITS-compliant external package" "Final set of enabled top-level packages: Package3 1" "Final set of non-enabled top-level packages: 0" "Final set of enabled top-level external packages/TPLs: Tpl1 Tpl2 Tpl3 Tpl4 Package1 Package2 6" "Final set of non-enabled top-level external packages/TPLs: 0" - "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." + "Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs ..." "Processing enabled external package/TPL: Tpl1 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl1=OFF[)]" - "-- The external package/TPL Tpl1 will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL Tpl1 will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: Tpl2 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl2=OFF[)]" - "-- The external package/TPL Tpl2 will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL Tpl2 will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: Tpl3 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl3=OFF[)]" - "-- The external package/TPL Tpl3 will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL Tpl3 will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: Package1 [(]enabled explicitly, disable with -DTPL_ENABLE_Package1=OFF[)]" - "-- The external package/TPL Package1 will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL Package1 will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: Package2 [(]enabled explicitly, disable with -DTPL_ENABLE_Package2=OFF[)]" - "-- Calling find_package[(]Package2[)] for TriBITS-compatible package" + "-- Calling find_package[(]Package2[)] for TriBITS-compliant package" "Getting information for all enabled external packages/TPLs ..." "Processing enabled external package/TPL: Tpl4 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl4=OFF[)]" diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index 402cc85ca..73f105f6c 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -3297,8 +3297,8 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx PASS_REGULAR_EXPRESSION_ALL "Adjust the set of internal and external packages:" "-- Treating internal package SimpleCxx as EXTERNAL because TPL_ENABLE_SimpleCxx=ON" - "-- NOTE: HeaderOnlyTpl is directly downstream from an fully TriBITS-compatible external package SimpleCxx" - "-- NOTE: SimpleTpl is directly downstream from an fully TriBITS-compatible external package SimpleCxx" + "-- NOTE: HeaderOnlyTpl is directly downstream from an TriBITS-compliant external package SimpleCxx" + "-- NOTE: SimpleTpl is directly downstream from an TriBITS-compliant external package SimpleCxx" "Final set of enabled top-level packages: MixedLang WithSubpackages WrapExternal 3" "Final set of enabled packages: MixedLang WithSubpackagesA WithSubpackagesB WithSubpackagesC WithSubpackages WrapExternal 6" @@ -3309,13 +3309,13 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx "Final set of non-enabled top-level external packages/TPLs: MPI 1" "Final set of non-enabled external packages/TPLs: MPI 1" - "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." + "Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs ..." "Processing enabled external package/TPL: HeaderOnlyTpl [(]enabled by SimpleCxx, disable with -DTPL_ENABLE_HeaderOnlyTpl=OFF[)]" - "-- The external package/TPL HeaderOnlyTpl will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL HeaderOnlyTpl will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: SimpleTpl [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleTpl=OFF[)]" - "-- The external package/TPL SimpleTpl will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL SimpleTpl will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: SimpleCxx [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleCxx=OFF[)]" - "-- Calling find_package[(]SimpleCxx[)] for TriBITS-compatible package" + "-- Calling find_package[(]SimpleCxx[)] for TriBITS-compliant package" "Getting information for all enabled external packages/TPLs ..." @@ -3489,18 +3489,18 @@ tribits_add_advanced_test( TribitsExampleProject_External_Package_by_Package "-- Treating internal package WithSubpackagesA as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" "-- Treating internal package WithSubpackagesB as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" "-- Treating internal package WithSubpackagesC as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" - "-- NOTE: WithSubpackagesA is directly downstream from an fully TriBITS-compatible external package WithSubpackages" - "-- NOTE: WithSubpackagesB is directly downstream from an fully TriBITS-compatible external package WithSubpackages" - "-- NOTE: WithSubpackagesC is directly downstream from an fully TriBITS-compatible external package WithSubpackages" - "-- NOTE: WithSubpackagesA is indirectly downstream from an fully TriBITS-compatible external package" - "-- NOTE: WithSubpackagesB is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: WithSubpackagesA is directly downstream from an TriBITS-compliant external package WithSubpackages" + "-- NOTE: WithSubpackagesB is directly downstream from an TriBITS-compliant external package WithSubpackages" + "-- NOTE: WithSubpackagesC is directly downstream from an TriBITS-compliant external package WithSubpackages" + "-- NOTE: WithSubpackagesA is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: WithSubpackagesB is indirectly downstream from an TriBITS-compliant external package" "-- Treating internal package SimpleCxx as EXTERNAL because downstream package WithSubpackagesB being treated as EXTERNAL" - "-- NOTE: SimpleCxx is indirectly downstream from an fully TriBITS-compatible external package" - "-- NOTE: WithSubpackagesA is indirectly downstream from an fully TriBITS-compatible external package" - "-- NOTE: SimpleCxx is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: SimpleCxx is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: WithSubpackagesA is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: SimpleCxx is indirectly downstream from an TriBITS-compliant external package" "-- Treating internal package MixedLang as EXTERNAL because TPL_ENABLE_MixedLang=ON" - "-- NOTE: HeaderOnlyTpl is indirectly downstream from an fully TriBITS-compatible external package" - "-- NOTE: SimpleTpl is indirectly downstream from an fully TriBITS-compatible external package" + "-- NOTE: HeaderOnlyTpl is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: SimpleTpl is indirectly downstream from an TriBITS-compliant external package" "Final set of enabled top-level packages: WrapExternal 1" "Final set of enabled packages: WrapExternal 1" @@ -3511,17 +3511,17 @@ tribits_add_advanced_test( TribitsExampleProject_External_Package_by_Package "Final set of non-enabled top-level external packages/TPLs: MPI 1" "Final set of non-enabled external packages/TPLs: MPI 1" - "Getting information for all enabled fully TriBITS-compatible or upstream external packages/TPLs ..." + "Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs ..." "Processing enabled external package/TPL: HeaderOnlyTpl [(]enabled by SimpleCxx, disable with -DTPL_ENABLE_HeaderOnlyTpl=OFF[)]" - "-- The external package/TPL HeaderOnlyTpl will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL HeaderOnlyTpl will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: SimpleTpl [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleTpl=OFF[)]" - "-- The external package/TPL SimpleTpl will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL SimpleTpl will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: SimpleCxx [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleCxx=OFF[)]" - "-- The external package/TPL SimpleCxx will be read in by a downstream fully TriBITS-compliant external package" + "-- The external package/TPL SimpleCxx will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: MixedLang [(]enabled explicitly, disable with -DTPL_ENABLE_MixedLang=OFF[)]" - "-- Calling find_package[(]MixedLang[)] for TriBITS-compatible package" + "-- Calling find_package[(]MixedLang[)] for TriBITS-compliant package" "Processing enabled external package/TPL: WithSubpackages [(]enabled explicitly, disable with -DTPL_ENABLE_WithSubpackages=OFF[)]" - "-- Calling find_package[(]WithSubpackages[)] for TriBITS-compatible package" + "-- Calling find_package[(]WithSubpackages[)] for TriBITS-compliant package" "Getting information for all enabled external packages/TPLs ..." @@ -3555,7 +3555,7 @@ tribits_add_advanced_test( TribitsExampleProject_External_Package_by_Package ) # NOTE: The above test is a strong check that packages can be installed # individually in stages on top of each other and that we are correctly -# writing wrapper Config.cmake files for fully TriBITS-compatible +# writing wrapper Config.cmake files for TriBITS-compliant # external packages (in this case for WithSubpackagesAConfig.cmake to # include). diff --git a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake index e99e6161b..346cd650f 100644 --- a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake +++ b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake @@ -225,7 +225,7 @@ endmacro() # NOTE: Above, we are sweeping over *all* of the not-disabled packages listed # in ${PROJECT_NAME}_DEFINED_INTERNAL_PACKAGES, including those package that # might have _PACKAGE_BUILD_STATUS=EXTERNAL. That makes sense -# because these are TriBITS (or TriBITS compatible) packages so we should +# because these are TriBITS (or TriBITS-compliant) packages so we should # assume that all of their downstream packages, whether internal or external, # should be enabled as well. If we find this is not the desirable behavior, # then we can change this later. @@ -1321,7 +1321,7 @@ endmacro() # Macro that sets all of the direct upstream dependent packages as being -# processed by a downstream fully TriBITS compliant external package. +# processed by a downstream TriBITS-compliant external package. macro(tribits_set_package_and_deps_as_processed_by_downstream_tribits_external_package packageName ) @@ -1335,7 +1335,7 @@ macro(tribits_set_package_and_deps_as_processed_by_downstream_tribits_external_p tribits_get_package_enable_status(${packageName} packageEnable "") if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL" - AND (${packageName}_IS_FULLY_TRIBITS_COMPLIANT + AND (${packageName}_IS_TRIBITS_COMPLIANT OR ${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) ) @@ -1351,8 +1351,8 @@ macro(tribits_set_package_and_deps_as_processed_by_downstream_tribits_external_p tribits_get_package_enable_status(${depPkg} depPkgEnable "") if (depPkgEnable) message("-- " - "NOTE: ${depPkg} is ${directOrIndirectStr} downstream from an fully" - " TriBITS-compatible external package${downstreamPkgStr}") + "NOTE: ${depPkg} is ${directOrIndirectStr} downstream from an" + " TriBITS-compliant external package${downstreamPkgStr}") endif() set(${depPkg}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE TRUE) endforeach() diff --git a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake index 63187899a..85f37f3df 100644 --- a/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsExternalPackageWriteConfigFile.cmake @@ -261,7 +261,7 @@ function(tribits_extpkgwit_append_package_config_file_header_str set(configFileStr "${${configFileStrVarInOut}}") string(APPEND configFileStr "# TriBITS-compliant Package config file for external package/TPL '${tplName}'\n" - "# based on non fully TriBITS-compliant external package '${externalPkg}' that uses\n" + "# based on non TriBITS-compliant external package '${externalPkg}' that uses\n" "# modern IMPORTED targets\n" "#\n" "# Generated by CMake, do not edit!\n" diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake index 8cda6a2f1..7423606b3 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake @@ -59,15 +59,15 @@ macro(tribits_process_enabled_tpls) EXTERNAL ON NONEMPTY ${PROJECT_NAME}_enabledExternalTopLevelPackages) message("") - message("Getting information for all enabled fully TriBITS-compatible" + message("Getting information for all enabled TriBITS-compliant" " or upstream external packages/TPLs ...") message("") foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) - if (${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT + if (${TPL_NAME}_IS_TRIBITS_COMPLIANT OR ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE ) - tribits_process_enabled_fully_tribits_compatible_or_upstream_tpl(${TPL_NAME}) + tribits_process_enabled_tribits_compliant_or_upstream_tpl(${TPL_NAME}) endif() endforeach() @@ -76,7 +76,7 @@ macro(tribits_process_enabled_tpls) message("") foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) - if ((NOT ${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT) + if ((NOT ${TPL_NAME}_IS_TRIBITS_COMPLIANT) AND (NOT ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) ) tribits_process_enabled_standard_tpl(${TPL_NAME}) @@ -89,18 +89,18 @@ macro(tribits_process_enabled_tpls) endmacro() -macro(tribits_process_enabled_fully_tribits_compatible_or_upstream_tpl TPL_NAME) +macro(tribits_process_enabled_tribits_compliant_or_upstream_tpl TPL_NAME) tribits_get_enabled_tpl_processing_string(${TPL_NAME} tplProcessingString) message("${tplProcessingString}") if (NOT ${PROJECT_NAME}_TRACE_DEPENDENCY_HANDLING_ONLY) if (NOT ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) - tribits_process_enabled_tribits_compatible_tpl(${TPL_NAME}) + tribits_process_enabled_tribits_compliant_tpl(${TPL_NAME}) else() message("-- " "The external package/TPL ${TPL_NAME} will be read in by a downstream" - " fully TriBITS-compliant external package") + " TriBITS-compliant external package") endif() endif() @@ -147,12 +147,12 @@ function(tribits_get_enabled_tpl_processing_string TPL_NAME tplProcessingStrin endfunction() -# Process an enabled TPL defined using a fully TriBITS-compatible external +# Process an enabled TPL defined using a TriBITS-compliant external # packages Config.cmake file # -macro(tribits_process_enabled_tribits_compatible_tpl TPL_NAME) +macro(tribits_process_enabled_tribits_compliant_tpl TPL_NAME) message("-- " - "Calling find_package(${TPL_NAME}) for TriBITS-compatible package") + "Calling find_package(${TPL_NAME}) for TriBITS-compliant package") find_package(${TPL_NAME} CONFIG REQUIRED) endmacro() diff --git a/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake b/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake index 76bc1e7f8..447f98265 100644 --- a/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake +++ b/tribits/core/package_arch/TribitsProcessPackagesAndDirsLists.cmake @@ -572,7 +572,7 @@ macro(tribits_process_packages_and_dirs_lists REPOSITORY_NAME REPOSITORY_DIR) set(${TRIBITS_PACKAGE}_PARENT_REPOSITORY ${REPOSITORY_NAME}) tribits_insert_standard_package_options(${TRIBITS_PACKAGE} ${PACKAGE_TESTGROUP}) set(${TRIBITS_PACKAGE}_PACKAGE_BUILD_STATUS INTERNAL) - set(${TRIBITS_PACKAGE}_IS_FULLY_TRIBITS_COMPLIANT TRUE) + set(${TRIBITS_PACKAGE}_IS_TRIBITS_COMPLIANT TRUE) else() if (${PROJECT_NAME}_VERBOSE_CONFIGURE) message( @@ -594,7 +594,7 @@ macro(tribits_process_packages_and_dirs_lists REPOSITORY_NAME REPOSITORY_DIR) print_var(${TRIBITS_PACKAGE}_PARENT_PACKAGE) print_var(${TRIBITS_PACKAGE}_PARENT_REPOSITORY) print_var(${TRIBITS_PACKAGE}_PACKAGE_BUILD_STATUS) - print_var(${TRIBITS_PACKAGE}_IS_FULLY_TRIBITS_COMPLIANT) + print_var(${TRIBITS_PACKAGE}_IS_TRIBITS_COMPLIANT) endif() if (TRIBITS_PROCESS_PACKAGES_AND_DIRS_LISTS_VERBOSE) diff --git a/tribits/core/package_arch/TribitsProcessTplsLists.cmake b/tribits/core/package_arch/TribitsProcessTplsLists.cmake index 711169cb9..1229e1769 100644 --- a/tribits/core/package_arch/TribitsProcessTplsLists.cmake +++ b/tribits/core/package_arch/TribitsProcessTplsLists.cmake @@ -95,7 +95,8 @@ include(Split) # This allows downstream repos to add additional requirements for a given TPL # (i.e. add more libraries, headers, etc.). However, the downstream repo's # find module file must find the TPL components that are fully compatible with -# the upstream's find module. +# the upstream's find module in terms of what it provides for packages in +# upstream repos. # # This macro just sets the variable:: # @@ -275,12 +276,12 @@ macro(tribits_process_tpls_lists REPOSITORY_NAME REPOSITORY_DIR) set(${TPL_NAME}_PACKAGE_BUILD_STATUS EXTERNAL) - # Set ${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT + # Set ${TPL_NAME}_IS_TRIBITS_COMPLIANT if (${TPL_NAME}_FINDMOD STREQUAL "TRIBITS_PKG") - set(${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT TRUE) + set(${TPL_NAME}_IS_TRIBITS_COMPLIANT TRUE) else() - set(${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT FALSE) + set(${TPL_NAME}_IS_TRIBITS_COMPLIANT FALSE) endif() # Print variables/properties for the TPL @@ -291,7 +292,7 @@ macro(tribits_process_tpls_lists REPOSITORY_NAME REPOSITORY_DIR) print_var(${TPL_NAME}_DEPENDENCIES_FILE) print_var(${TPL_NAME}_TPLS_LIST_FILE) print_var(${TPL_NAME}_PACKAGE_BUILD_STATUS) - print_var(${TPL_NAME}_IS_FULLY_TRIBITS_COMPLIANT) + print_var(${TPL_NAME}_IS_TRIBITS_COMPLIANT) endif() # Set cache var TPL_ENABLE_${TPL_NAME} with default "" diff --git a/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake b/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake index bd5f09e61..b5e8b3b90 100644 --- a/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake +++ b/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake @@ -554,10 +554,10 @@ endfunction() # Implementation macro for tribits_set_dep_packages() to deal with a package # that is not defined by TriBITS. # -# ToDo #63: This may need to be modified when dealing with TriBITS-compatible +# ToDo #63: This may need to be modified when dealing with TriBITS-compliant # packages already installed out on the system. We may need a mode where we # don't assert packages that are not defined but instead just assume they are -# TriBITS-compatible packages already installed. +# TriBITS-compliant packages already installed. # macro(tribits_set_dep_packages__handle_undefined_pkg packageName depPkg requiredOrOptional pkgsOrTpls packageEnableVar diff --git a/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst b/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst index 1c58dffee..861ccc835 100644 --- a/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst +++ b/tribits/core/package_arch/TribitsSystemDataStructuresMacrosFunctions.rst @@ -456,12 +456,12 @@ any subpackage is determined to be EXTERNAL, then the parent package of that subpackage and every other peer subpackage will also be set to EXTERNAL. -Processing of external packages/TPLs and fully TriBITS compatible external packages +Processing of external packages/TPLs and TriBITS-compliant external packages +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The processing of external packages/TPLs is influenced by whether the external -package is a regular TriBITS TPL or is a fully TriBITS-compliant external -package. Here, a **Fully TriBITS-Compliant External Package** has a +package is a regular TriBITS TPL or is a TriBITS-compliant external +package. Here, a **TriBITS-Compliant External Package** has a ``Config.cmake`` file that satisfies the following properties: * Has the target ``::all_libs``. @@ -469,25 +469,25 @@ package. Here, a **Fully TriBITS-Compliant External Package** has a * Every upstream dependent package ```` has the target ``::all_libs``. -That means that when calling ``find_package()`` for a fully TriBITS compliant +That means that when calling ``find_package()`` for a TriBITS-compliant external package, there is no need to worry about finding any of its upstream dependent external packages. That means that any external packages/TPLs -defined a TriBITS project which is upstream from a fully TriBITS compliant +defined a TriBITS project which is upstream from a TriBITS-compliant external package will be uniquely defined by calling ``find_package()`` on the -most downstream fully TriBITS-compliant external package that depends on it. +most downstream TriBITS-compliant external package that depends on it. Therefore, defining the external packages and their targets in this set of external packages just involves calling ``find_package()`` on the terminal -fully TriBITS-compliant external packages (i.e. fully TriBITS-compliant +TriBITS-compliant external packages (i.e. TriBITS-compliant external packages that don't have any downstream dependencies that are external packages). Then the remaining subset of external packages/TPLs that -don't have a downstream fully TriBITS-compliant external package dependency +don't have a downstream TriBITS-compliant external package dependency will be defined as usual. (ToDo: Put in a more detailed examples explaining how this works.) The variables that are set internally to define these different subsets of external packages/TPLs are: -* ``_IS_FULLY_TRIBITS_COMPLIANT``: Set the ``TRUE`` if the package +* ``_IS_TRIBITS_COMPLIANT``: Set the ``TRUE`` if the package ```` provides the ``::all_libs`` target for itself and all of its upstream dependent (internal or external) packages (whether this package is treated as an internal or external package). @@ -497,38 +497,38 @@ external packages/TPLs are: complient package. In this case, we just print that we are skipping the find operation and explain why. -An external package with ``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` **AND** +An external package with ``_IS_TRIBITS_COMPLIANT=TRUE`` **AND** ``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=FALSE`` is the one for which ``find_package( CONFIG REQUIRED)`` will be called and does not have any downstream packages that are being treated as external packages. -The variable ``_IS_FULLY_TRIBITS_COMPLIANT`` is set right when the +The variable ``_IS_TRIBITS_COMPLIANT`` is set right when the packages are initially defined by reading in the various input files. That is, all initially internal packages that are listed in a `/PackagesList.cmake`_ file will have -``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` set. While all external +``_IS_TRIBITS_COMPLIANT=TRUE`` set. While all external packages/TPLs listed in a `/TPLsList.cmake`_ file will have -``_IS_FULLY_TRIBITS_COMPLIANT=FALSE`` set (except for those tagged +``_IS_TRIBITS_COMPLIANT=FALSE`` set (except for those tagged with ``TRIBITS_PKG`` which will have -``_IS_FULLY_TRIBITS_COMPLIANT=FALSE`` set). +``_IS_TRIBITS_COMPLIANT=FALSE`` set). -NOTE: When a TriBITS TPL (i.e. ``_IS_FULLY_TRIBITS_COMPLIANT=FALSE``) +NOTE: When a TriBITS TPL (i.e. ``_IS_TRIBITS_COMPLIANT=FALSE``) is being processed, we can't assume where its ``Config.cmake`` file exists so we must find upstream dependencies using ``set(_DIR ...)`` and ``find_dependency( CONFIG REQUIRED)``. So the first loop over external packages/TPLs will be those external -packages/TPLs that have ``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` **OR** +packages/TPLs that have ``_IS_TRIBITS_COMPLIANT=TRUE`` **OR** ``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=TRUE``. And we -only call ``find_package()`` for those fully TriBITS-complient external -packages that have ``_IS_FULLY_TRIBITS_COMPLIANT=TRUE`` **AND** +only call ``find_package()`` for those TriBITS-compliant external +packages that have ``_IS_TRIBITS_COMPLIANT=TRUE`` **AND** ``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=FALSE``. The second loop are those external packages/TPLs that don't have a downstream -fully TriBITS-compliant external package which are all of those external -packages for which ``_IS_FULLY_TRIBITS_COMPLIANT=FALSE`` **AND** +TriBITS-compliant external package which are all of those external +packages for which ``_IS_TRIBITS_COMPLIANT=FALSE`` **AND** ``_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE=FALSE``. diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index f1fc6d939..e6a8b3e3f 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -2309,7 +2309,7 @@ defined TPL ``TPL_NAME`` is assigned the following global non-cache variables: ``SomeTpl_FINDMOD`` is determined by ``Repo2/TPLsList.cmake`` and the find module listed in ``Repo1/TPLsList.cmake`` is ignored. NOTE: The special value ``TRIBITS_PKG`` is also recognized for external packages/TPLs that - are *fully TriBITS compliant* (i.e. defines a ``${TPL_NAME}Config.cmake`` + are *TriBITS-compliant* (i.e. defines a ``${TPL_NAME}Config.cmake`` file provides the ``${TPL_NAME}::all_libs`` target, calls ``find_dependency()`` on all of its upstream dependencies, and each of those dependencies defines the ``::all_libs`` @@ -5675,16 +5675,16 @@ usage requirements (such as the target properties ``INTERFACE_INCLUDE_DIRECTORIES`` and ``INTERFACE_LINK_LIBRARIES``) and use ``find_dependency()`` to get all of their required external upstream package dependencies, many do not. Also, many of these don't provide a complete -``::all_libs`` target which is required for a TriBITS-compatible +``::all_libs`` target which is required for a TriBITS-compliant external package/TPL. In this case, the ``FindTPL.cmake`` file provides a thin "glue" layer to adapt the information and objects provided by the ``find_package( ...)`` call into a complete ``::all_libs`` target and a wrapper ``Config.cmake`` file -for consumption by downstream TriBITS-compatible packages. +for consumption by downstream TriBITS-compliant packages. -The following subsections will describe how to create these TriBITS-compatible +The following subsections will describe how to create these TriBITS-compliant ``FindTPL.cmake`` modules for all of the various cases using an internal call to ``find_package( ...)``: From a2a5b998f9b6ea6847f19e6c703d499f0dbf16c8 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 8 Feb 2023 19:35:21 -0700 Subject: [PATCH 33/45] Move 'CMake Language Overview and Gotchas' to appendix With books like "Professional CMake" out now, there should be less need to explain the basics of the CMaka langauge. --- ...TribitsCMakeLangaugeOverviewAndGotchas.rst | 238 ++++++++++++++++ tribits/doc/guides/TribitsGuidesBody.rst | 261 +----------------- .../TribitsMaintainersGuide.rst | 2 + .../guides/users_guide/TribitsUsersGuide.rst | 2 + 4 files changed, 254 insertions(+), 249 deletions(-) create mode 100644 tribits/doc/guides/TribitsCMakeLangaugeOverviewAndGotchas.rst diff --git a/tribits/doc/guides/TribitsCMakeLangaugeOverviewAndGotchas.rst b/tribits/doc/guides/TribitsCMakeLangaugeOverviewAndGotchas.rst new file mode 100644 index 000000000..885229038 --- /dev/null +++ b/tribits/doc/guides/TribitsCMakeLangaugeOverviewAndGotchas.rst @@ -0,0 +1,238 @@ +CMake Language Overview and Gotchas +----------------------------------- + +TriBITS removes a lot of the boiler plate code needed to write a CMake +project. As a result, many people can come into a project that uses TriBITS +and quickly start to contribute by adding new source files, adding new +libraries, adding new tests, and even adding new TriBITS packages and external +packages/TPLs; all without really having learned anything about CMake. Often +one can use existing example CMake code as a guide and be successful using +basic functionality. As long as nothing out of the ordinary happens, many +people can get along just fine in this mode for a time. + +However, we have observed that most mistakes and problems that people run into when +using TriBITS are due to lack of basic knowledge of the CMake language. One can find +basic tutorials and references on the CMake language in various locations online for free. +One can also purchase the `official CMake reference book`_. Also, documentation +for any built-in CMake command is available locally by running:: + + $ cmake --help-command + +Because tutorials and detailed documentation for the CMake language already +exists, this document does not attempt to provide a first reference to CMake +(which is a large topic in itself). However, what we try to provide below is +a short overview of the more quirky or surprising aspects of the CMake +language that a programmer experienced in another language might get tripped +up or surprised by. Some of the more unique features of the language are +described in order to help avoid some of these common mistakes and provide +greater understanding of how TriBITS works. + +.. _Official CMake reference book: http://www.cmake.org/cmake/help/book.html + +The CMake language is used to write CMake projects with TriBITS. In fact the +core TriBITS functionality itself is implemented in the CMake language (see +`TriBITS System Project Dependencies`_). CMake is a fairly simple programming +language with relatively simple rules (for the most part). However, compared +to other programming languages, there are a few peculiar aspects to the CMake +language that can make working with it difficult if you don't understand these +rules. For example there are unexpected variable scoping rules and how arguments +are passed to macros and functions can be tricky. Also, CMake has some interesting +gotchas. In order to effectively use TriBITS (or just raw CMake) to construct +and maintain a project's CMake files, one must know the basic rules of CMake +and be aware of these gotchas. + +The first thing to understand about the CMake language is that nearly every +line of CMake code is just a command taking a string (or an array of strings) +and functions that operate on strings. An array argument is just a single +string literal with elements separated by semi-colons ``";;..."``. +CMake is a bit odd in how it deals with these arrays, which are just +represented as a string with elements separated with semi-colons ``';'``. For +example, all of the following are equivalent and pass in a CMake array with 3 +elements [``A``], [``B``], and [``C``]:: + + some_func(A B C) + some_func("A" "B" "C") + some_func("A;B;C") + +However, the above is *not* the same as:: + + some_func("A B C") + +which just passes in a single element with value [``A B C``]. Raw quotes in +CMake basically escape the interpretation of space characters as array element +boundaries. Quotes around arguments with no spaces does nothing (as seen +above, except for the interpretation as variable names in an ``if()`` +statement). In order to get a quote char [``"``] into string, you must escape +it as:: + + some_func(\"A\") + +which passes an array with the single argument [``\"A\"``]. + +Variables are set using the built-in CMake ``set()`` command that just takes +string arguments like:: + + set(SOME_VARIABLE "some_value") + +In CMake, the above is identical, in every way, to:: + + set(SOME_VARIABLE some_value) + set("SOME_VARIABLE";"some_value") + set("SOME_VARIABLE;some_value") + +The function ``set()`` simply interprets the first argument to as the name of +a variable to set in the local scope. Many other built-in and user-defined +CMake functions work the same way. That is, some of the string arguments are +interpreted as the names of variables. There is no special language feature +that interprets them as variables (except in an ``if()`` statement). + +However, CMake appears to parse arguments differently for built-in CMake +control structure functions like ``foreach()`` and ``if()`` and does not just +interpret them as a string array. For example:: + + foreach (SOME_VAR "a;b;c") + message("SOME_VAR='${SOME_VAR}'") + endforeach() + +prints ```SOME_VAR='a;b;c'`` instead of printing ``SOME_VAR='a'`` followed by +``SOME_VAR='b'``, etc., as you would otherwise expect. Therefore, this simple +rule for the handling of function arguments as string arrays does not hold for +CMake logic control commands. Just follow the CMake documentation for these +control structures (i.e. see ``cmake --help-command if`` and ``cmake +--help-command foreach``). + +CMake offers a rich assortment of built-in commands for doing all sorts of +things. Two of these are the built-in ``macro()`` and the ``function()`` +commands which allow you to create user-defined macros and functions. TriBITS +is actually built on CMake functions and macros. All of the built-in and +user-defined macros, and some functions take an array of string arguments. +Some functions take in positional arguments. In fact, most functions take a +combination of positional and keyword arguments. + +Variable names are translated into their stored values using +``${SOME_VARIABLE}``. The value that is extracted depends on if the variable +is set in the local or global (cache) scope. The local scopes for CMake start +in the base project directory in its base ``CMakeLists.txt`` file. Any +variables that are created by macros in that base local scope are seen across +an entire project but are *not* persistent across multiple successive +``cmake`` configure invocations where the cache file ``CMakeCache.txt`` is not +deleted in between. + +The handling of variables is one area where CMake is radically different from +most other languages. First, a variable that is not defined simply returns +nothing. What is surprising to most people about this is that it does not +even return an empty string that would register as an array element! For +example, the following set statement:: + + set(SOME_VAR a ${SOME_UNDEFINED_VAR} c) + +(where ``SOME_UNDEFINED_VAR`` is an undefined variable) produces +``SOME_VAR='a;c'`` and *not* ``'a;;c'``! The same thing occurs when an empty +variable is de-references such as with:: + + set(EMPTY_VAR "") + set(SOME_VAR a ${EMPTY_VAR} c) + +which produces ``SOME_VAR='a;c'`` and *not* ``'a;;c'``. In order to always +produce an element in the array even if the variable is empty, one must quote +the argument as with:: + + set(EMPTY_VAR "") + set(SOME_VAR a "${EMPTY_VAR}" c) + +which produces ``SOME_VAR='a;;c'``, or three elements as one might assume. + +This is a common error that people make when they call CMake functions +(built-in or TriBITS-defined) involving variables that might be undefined or +empty. For example, for the macro:: + + macro(some_macro A_ARG B_ARG C_ARG) + ... + endmacro() + +if someone tries to call it with (misspelled variable?):: + + some_macro(a ${SOME_OHTER_VAR} c) + +and if ``SOME_OHTER_VAR=""`` or if it is undefined, then CMake will error out +with the error message saying that the macro ``some_macro()`` takes 3 +arguments but only 2 were provided. If a variable might be empty but that is +still a valid argument to the command, then it must be quoted as:: + + some_macro(a "${SOME_OHTER_VAR}" c) + +Related to this problem is that if you misspell the name of a variable in a +CMake ``if()`` statement like:: + + if (SOME_VARBLE) + ... + endif() + +then it will always be false and the code inside the if statement will never +be executed! To avoid this problem, use the utility function +`assert_defined()`_ as:: + + assert_defined(SOME_VARBLE) + if (SOME_VARBLE) + ... + endif() + +In this case, the misspelled variable would be caught. + +While on the subject of ``if()`` statements, CMake has a strange convention. +When you say:: + + if (SOME_VAR) + do_something() + endif() + +then ``SOME_VAR`` is interpreted as a variable and will be considered true and +``do_something()`` will be called if ``${SOME_VAR}`` does *not* evaluate to +``0``, ``OFF``, ``NO``, ``FALSE``, ``N``, ``IGNORE``, ``""``, or ends in the +suffix ``-NOTFOUND``. How about that for a true/false rule! To be safe, use +``ON/OFF`` and ``TRUE/FALSE`` pairs for setting variables. Look up native +CMake documentation on ``if()`` for all the interesting details and all the +magical things it can do. + +**WARNING:** If you mistype ``"ON"`` as ``"NO"``, it evaluates to +``FALSE``/``OFF``! (That is a fun defect to track down!) + +CMake language behavior with respect to case sensitivity is also strange: + +* Calls of built-in and user-defined macros and functions is *case + insensitive*! That is ``set(...)``, ``set(...)``, ``set()``, and all other + combinations of upper and lower case characters for 'S', 'E', 'T' all call + the built-in ``set()`` function. The convention in TriBITS is to use + ``lower_case_with_underscores()`` for functions and macros. + +* However, the names of CMake (local or cache/global) variables are *case + sensitive*! That is, ``SOME_VAR`` and ``some_var`` are *different* + variables. Built-in CMake variables tend use all caps with underscores + (e.g. ``CMAKE_CURRENT_SOURCE_DIR``) but other built-in CMake variables tend + to use mixed case with underscores (e.g. ``CMAKE_Fortran_FLAGS``). TriBITS + tends to use a similar naming convention where project-level and cache + variables have mostly upper-case letters except for parts that are proper + nouns like the project, package or external package/TPL name + (e.g. ``TribitsExProj_TRIBITS_DIR``, ``TriBITS_SOURCE_DIR``, + ``Boost_INCLUDE_DIRS``). Local variables and function/macro parameters can + use camelCase or lower_case_with_underscores. + +I don't know of any other programming language that uses different case +sensitivity rules for variables and functions. However, because we must parse +macro and function arguments when writing user-defined macros and functions, +it is a good thing that CMake variables are case sensitive. Case insensitivity +would make it much harder and more expensive to parse argument lists that take +keyword-based arguments. + +Other mistakes that people make result from not understanding how CMake scopes +variables and other entities. CMake defines a global scope (i.e. "cache" +variables) and several nested local scopes that are created by +``add_subdirectory()`` and entering functions. See `dual_scope_set()`_ for a +short discussion of these scoping rules. And it is not just variables that +can have local and global scoping rules. Other entities, like defines set +with the built-in command ``add_definitions()`` only apply to the local scope +and child scopes. That means that if you call ``add_definitions()`` to set a +define that affects the meaning of a header-file in C or C++, for example, +that definition will *not* carry over to a peer subdirectory and those +definitions will not be set (see warning in `Miscellaneous Notes +(tribits_add_library())`_). diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index e6a8b3e3f..b3a101e86 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -110,259 +110,21 @@ may not be necessary and the `TriBITS Overview`_ or the above roles and discussion help the reader select the right document to start with. +NOTE: Before getting started with TriBITS, if a reader is unfamiliar with +CMake, please review the `CMake Language Overview and Gotchas`_. Once those +CMake basics and common gotchas have been reviewed, we now get into the meat +of TriBITS starting with software engineering principles that lie at the +foundation of TriBITS. That is followed by with and overall of the structure +of a TriBITS project. -CMake Language Overview and Gotchas ------------------------------------ - -TriBITS removes a lot of the boiler plate code needed to write a CMake -project. As a result, many people can come into a project that uses TriBITS -and quickly start to contribute by adding new source files, adding new -libraries, adding new tests, and even adding new TriBITS packages and external -packages/TPLs; all without really having learned anything about CMake. Often -one can use existing example CMake code as a guide and be successful using -basic functionality. As long as nothing out of the ordinary happens, many -people can get along just fine in this mode for a time. - -However, we have observed that most mistakes and problems that people run into when -using TriBITS are due to lack of basic knowledge of the CMake language. One can find -basic tutorials and references on the CMake language in various locations online for free. -One can also purchase the `official CMake reference book`_. Also, documentation -for any built-in CMake command is available locally by running:: - - $ cmake --help-command - -Because tutorials and detailed documentation for the CMake language already -exists, this document does not attempt to provide a first reference to CMake -(which is a large topic in itself). However, what we try to provide below is -a short overview of the more quirky or surprising aspects of the CMake -language that a programmer experienced in another language might get tripped -up or surprised by. Some of the more unique features of the language are -described in order to help avoid some of these common mistakes and provide -greater understanding of how TriBITS works. - -.. _Official CMake reference book: http://www.cmake.org/cmake/help/book.html - -The CMake language is used to write CMake projects with TriBITS. In fact the -core TriBITS functionality itself is implemented in the CMake language (see -`TriBITS System Project Dependencies`_). CMake is a fairly simple programming -language with relatively simple rules (for the most part). However, compared -to other programming languages, there are a few peculiar aspects to the CMake -language that can make working with it difficult if you don't understand these -rules. For example there are unexpected variable scoping rules and how arguments -are passed to macros and functions can be tricky. Also, CMake has some interesting -gotchas. In order to effectively use TriBITS (or just raw CMake) to construct -and maintain a project's CMake files, one must know the basic rules of CMake -and be aware of these gotchas. - -The first thing to understand about the CMake language is that nearly every -line of CMake code is just a command taking a string (or an array of strings) -and functions that operate on strings. An array argument is just a single -string literal with elements separated by semi-colons ``";;..."``. -CMake is a bit odd in how it deals with these arrays, which are just -represented as a string with elements separated with semi-colons ``';'``. For -example, all of the following are equivalent and pass in a CMake array with 3 -elements [``A``], [``B``], and [``C``]:: - - some_func(A B C) - some_func("A" "B" "C") - some_func("A;B;C") - -However, the above is *not* the same as:: - - some_func("A B C") - -which just passes in a single element with value [``A B C``]. Raw quotes in -CMake basically escape the interpretation of space characters as array element -boundaries. Quotes around arguments with no spaces does nothing (as seen -above, except for the interpretation as variable names in an ``if()`` -statement). In order to get a quote char [``"``] into string, you must escape -it as:: - - some_func(\"A\") - -which passes an array with the single argument [``\"A\"``]. - -Variables are set using the built-in CMake ``set()`` command that just takes -string arguments like:: - - set(SOME_VARIABLE "some_value") - -In CMake, the above is identical, in every way, to:: - - set(SOME_VARIABLE some_value) - set("SOME_VARIABLE";"some_value") - set("SOME_VARIABLE;some_value") - -The function ``set()`` simply interprets the first argument to as the name of -a variable to set in the local scope. Many other built-in and user-defined -CMake functions work the same way. That is, some of the string arguments are -interpreted as the names of variables. There is no special language feature -that interprets them as variables (except in an ``if()`` statement). - -However, CMake appears to parse arguments differently for built-in CMake -control structure functions like ``foreach()`` and ``if()`` and does not just -interpret them as a string array. For example:: - - foreach (SOME_VAR "a;b;c") - message("SOME_VAR='${SOME_VAR}'") - endforeach() - -prints ```SOME_VAR='a;b;c'`` instead of printing ``SOME_VAR='a'`` followed by -``SOME_VAR='b'``, etc., as you would otherwise expect. Therefore, this simple -rule for the handling of function arguments as string arrays does not hold for -CMake logic control commands. Just follow the CMake documentation for these -control structures (i.e. see ``cmake --help-command if`` and ``cmake ---help-command foreach``). - -CMake offers a rich assortment of built-in commands for doing all sorts of -things. Two of these are the built-in ``macro()`` and the ``function()`` -commands which allow you to create user-defined macros and functions. TriBITS -is actually built on CMake functions and macros. All of the built-in and -user-defined macros, and some functions take an array of string arguments. -Some functions take in positional arguments. In fact, most functions take a -combination of positional and keyword arguments. - -Variable names are translated into their stored values using -``${SOME_VARIABLE}``. The value that is extracted depends on if the variable -is set in the local or global (cache) scope. The local scopes for CMake start -in the base project directory in its base ``CMakeLists.txt`` file. Any -variables that are created by macros in that base local scope are seen across -an entire project but are *not* persistent across multiple successive -``cmake`` configure invocations where the cache file ``CMakeCache.txt`` is not -deleted in between. - -The handling of variables is one area where CMake is radically different from -most other languages. First, a variable that is not defined simply returns -nothing. What is surprising to most people about this is that it does not -even return an empty string that would register as an array element! For -example, the following set statement:: - - set(SOME_VAR a ${SOME_UNDEFINED_VAR} c) - -(where ``SOME_UNDEFINED_VAR`` is an undefined variable) produces -``SOME_VAR='a;c'`` and *not* ``'a;;c'``! The same thing occurs when an empty -variable is de-references such as with:: - - set(EMPTY_VAR "") - set(SOME_VAR a ${EMPTY_VAR} c) - -which produces ``SOME_VAR='a;c'`` and *not* ``'a;;c'``. In order to always -produce an element in the array even if the variable is empty, one must quote -the argument as with:: - - set(EMPTY_VAR "") - set(SOME_VAR a "${EMPTY_VAR}" c) - -which produces ``SOME_VAR='a;;c'``, or three elements as one might assume. - -This is a common error that people make when they call CMake functions -(built-in or TriBITS-defined) involving variables that might be undefined or -empty. For example, for the macro:: - - macro(some_macro A_ARG B_ARG C_ARG) - ... - endmacro() - -if someone tries to call it with (misspelled variable?):: - - some_macro(a ${SOME_OHTER_VAR} c) - -and if ``SOME_OHTER_VAR=""`` or if it is undefined, then CMake will error out -with the error message saying that the macro ``some_macro()`` takes 3 -arguments but only 2 were provided. If a variable might be empty but that is -still a valid argument to the command, then it must be quoted as:: - - some_macro(a "${SOME_OHTER_VAR}" c) - -Related to this problem is that if you misspell the name of a variable in a -CMake ``if()`` statement like:: - - if (SOME_VARBLE) - ... - endif() - -then it will always be false and the code inside the if statement will never -be executed! To avoid this problem, use the utility function -`assert_defined()`_ as:: - - assert_defined(SOME_VARBLE) - if (SOME_VARBLE) - ... - endif() - -In this case, the misspelled variable would be caught. - -While on the subject of ``if()`` statements, CMake has a strange convention. -When you say:: - - if (SOME_VAR) - do_something() - endif() - -then ``SOME_VAR`` is interpreted as a variable and will be considered true and -``do_something()`` will be called if ``${SOME_VAR}`` does *not* evaluate to -``0``, ``OFF``, ``NO``, ``FALSE``, ``N``, ``IGNORE``, ``""``, or ends in the -suffix ``-NOTFOUND``. How about that for a true/false rule! To be safe, use -``ON/OFF`` and ``TRUE/FALSE`` pairs for setting variables. Look up native -CMake documentation on ``if()`` for all the interesting details and all the -magical things it can do. - -**WARNING:** If you mistype ``"ON"`` as ``"NO"``, it evaluates to -``FALSE``/``OFF``! (That is a fun defect to track down!) - -CMake language behavior with respect to case sensitivity is also strange: - -* Calls of built-in and user-defined macros and functions is *case - insensitive*! That is ``set(...)``, ``set(...)``, ``set()``, and all other - combinations of upper and lower case characters for 'S', 'E', 'T' all call - the built-in ``set()`` function. The convention in TriBITS is to use - ``lower_case_with_underscores()`` for functions and macros. - -* However, the names of CMake (local or cache/global) variables are *case - sensitive*! That is, ``SOME_VAR`` and ``some_var`` are *different* - variables. Built-in CMake variables tend use all caps with underscores - (e.g. ``CMAKE_CURRENT_SOURCE_DIR``) but other built-in CMake variables tend - to use mixed case with underscores (e.g. ``CMAKE_Fortran_FLAGS``). TriBITS - tends to use a similar naming convention where project-level and cache - variables have mostly upper-case letters except for parts that are proper - nouns like the project, package or external package/TPL name - (e.g. ``TribitsExProj_TRIBITS_DIR``, ``TriBITS_SOURCE_DIR``, - ``Boost_INCLUDE_DIRS``). Local variables and function/macro parameters can - use camelCase or lower_case_with_underscores. - -I don't know of any other programming language that uses different case -sensitivity rules for variables and functions. However, because we must parse -macro and function arguments when writing user-defined macros and functions, -it is a good thing that CMake variables are case sensitive. Case insensitivity -would make it much harder and more expensive to parse argument lists that take -keyword-based arguments. - -Other mistakes that people make result from not understanding how CMake scopes -variables and other entities. CMake defines a global scope (i.e. "cache" -variables) and several nested local scopes that are created by -``add_subdirectory()`` and entering functions. See `dual_scope_set()`_ for a -short discussion of these scoping rules. And it is not just variables that -can have local and global scoping rules. Other entities, like defines set -with the built-in command ``add_definitions()`` only apply to the local scope -and child scopes. That means that if you call ``add_definitions()`` to set a -define that affects the meaning of a header-file in C or C++, for example, -that definition will *not* carry over to a peer subdirectory and those -definitions will not be set (see warning in `Miscellaneous Notes -(tribits_add_library())`_). - -Now that some CMake basics and common gotchas have been reviewed, we now get -into the meat of TriBITS starting with the overall structure of a TriBITS -project in the next section. Software Engineering Packaging Principles ----------------------------------------- -The term "software engineering" package is adopted in TriBITS nomenclature in -order to highlight and the role of defining and managing "Packages" according -to standard software engineering packaging principles. In his book [`Agile -Software Development, 2003`_], Robert Martin defines several object-oriented -(OO) software engineering principles related to packaging software which are -listed below: +The design of TriBITS takes into account standard software engineering +packaging principles. In his book [`Agile Software Development, 2003`_], +Robert Martin defines several software engineering principles related to +packaging software which are listed below: * *Package Cohesion OO Principles*: @@ -398,6 +160,7 @@ further. However, interested readers are strongly encouraged to read [`Agile Software Development, 2003`_] as one of the better software engineering books out there (see https://bartlettroscoe.github.io/reading-list/#most_recommended_se_books). + TriBITS Project Structure ========================= @@ -7021,7 +6784,7 @@ will be used). Also, there are cases were one cannot easily control the default file or directory creation permissions using ``umask``. And there are cases where one would like to recursively install a set of directories and files where some of these files may be scripts that need to have the execute -permission set on them for them to work. The only to flexiable accomplish +permission set on them for them to work. The only to flexible accomplish that with CMake (if one does not know the exist list of those files or extensions of those files) is to pass in the ``SOURCE_PERMISSIONS`` option to the ``install(DIRECTORY ...)`` command. An example of this is shown in: diff --git a/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst b/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst index c9c0b1b7c..b8abdc39e 100644 --- a/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst +++ b/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst @@ -71,6 +71,8 @@ Developers`_ and `TriBITS System Architects`_. Appendix ======== +.. include:: ../TribitsCMakeLangaugeOverviewAndGotchas.rst + .. include:: ../TribitsHistory.rst .. include:: ../TribitsPackageNotCMakePackage.rst diff --git a/tribits/doc/guides/users_guide/TribitsUsersGuide.rst b/tribits/doc/guides/users_guide/TribitsUsersGuide.rst index be4cee320..32decb289 100644 --- a/tribits/doc/guides/users_guide/TribitsUsersGuide.rst +++ b/tribits/doc/guides/users_guide/TribitsUsersGuide.rst @@ -90,6 +90,8 @@ in the `Appendix`_. Appendix ======== +.. include:: ../TribitsCMakeLangaugeOverviewAndGotchas.rst + .. include:: ../TribitsHistory.rst .. include:: ../TribitsPackageNotCMakePackage.rst From 61eaf6ac106f0a6a16c18ff5b95713dbb81a917b Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Thu, 9 Feb 2023 12:18:46 -0700 Subject: [PATCH 34/45] Remove debug print statement that got commited by accident This got added by accident in the commit: 6255e059 "WIP: Refactor tribits_dump_deps_xml_file() to use new deps files" Author: Roscoe A. Bartlett Date: Wed Nov 23 08:31:27 2022 -0700 (9 weeks ago) --- tribits/ci_support/TribitsWriteXmlDependenciesFiles.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/tribits/ci_support/TribitsWriteXmlDependenciesFiles.cmake b/tribits/ci_support/TribitsWriteXmlDependenciesFiles.cmake index 1091008e3..2360acf16 100644 --- a/tribits/ci_support/TribitsWriteXmlDependenciesFiles.cmake +++ b/tribits/ci_support/TribitsWriteXmlDependenciesFiles.cmake @@ -178,7 +178,6 @@ function(tribits_write_deps_to_xml_string packageName libOrTest requiredOrOpti set(listType ${libOrTest}_${requiredOrOptional}_DEP_${packagesOrTpls}) message("") - print_var(listType) tribits_get_legacy_package_deps_sublist(${packageName} ${libOrTest} ${requiredOrOptional} ${packagesOrTpls} legacyPackageDepsList) From ba9de2829b98365ae649fc015ca567b50c3f8c36 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Sat, 18 Feb 2023 16:58:19 -0700 Subject: [PATCH 35/45] Adjust logic and printing for setting INTTERNAL packages as EXTERNAL (#63) The basic logic is the same but the output is much improved. This also fixes a bug where `${SUBPACKAGE_FULLNAME}_IS_TRIBITS_COMPLIANT=TRUE` was not getting set. More specifically this commit: * Sets `${SUBPACKAGE_FULLNAME}_IS_TRIBITS_COMPLIANT=TRUE` for subpackages (bug fixed) * Only prints when an internal package is being switched to external once. This was done by adding a project-level var * Adjusts logic for setting and printing when an external package is downstream from a TriBITS-compliant external package. Now, the output is only done for non-TriBITS compliant packages (because we know that TriBITS-compliant package are already downstream from a TriBITS-compliant package). * Fixes an output typo of "an TriBITS-compliant" to "a TriBITS-compliant" * Updates the tests to check for the exact output --- test/core/DependencyUnitTests/CMakeLists.txt | 14 ++++ .../TribitsExampleProject2_Tests.cmake | 13 ++-- .../TribitsExampleProject_Tests.cmake | 21 +++-- .../TribitsAdjustPackageEnables.cmake | 77 +++++++++---------- .../TribitsReadDepsFilesCreateDepsGraph.cmake | 2 + 5 files changed, 68 insertions(+), 59 deletions(-) diff --git a/test/core/DependencyUnitTests/CMakeLists.txt b/test/core/DependencyUnitTests/CMakeLists.txt index c5f14bbd8..c042c8d42 100644 --- a/test/core/DependencyUnitTests/CMakeLists.txt +++ b/test/core/DependencyUnitTests/CMakeLists.txt @@ -669,6 +669,8 @@ create_reduced_dependency_handling_test_case( "Adjust the set of internal and external packages:" "-- Treating internal package RTOp as EXTERNAL because TPL_ENABLE_RTOp=ON" "-- Treating internal package Teuchos as EXTERNAL because downstream package RTOp being treated as EXTERNAL" + "-- NOTE: LAPACK is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: BLAS is indirectly downstream from a TriBITS-compliant external package" "Final package build status [(]enabled only[)]:" "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" @@ -719,6 +721,8 @@ create_reduced_dependency_handling_test_case( "-- Treating internal package Teuchos as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" "-- Treating internal package Triutils as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + "-- NOTE: LAPACK is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: BLAS is indirectly downstream from a TriBITS-compliant external package" "Final package build status [(]enabled only[)]:" "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" @@ -1812,6 +1816,9 @@ create_dependency_handling_test_case( "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" "-- Treating internal package Triutils as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" "-- Treating internal package Zoltan as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + "-- NOTE: Boost is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: LAPACK is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: BLAS is indirectly downstream from a TriBITS-compliant external package" "Final package build status [(]enabled only[)]:" "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" @@ -1889,6 +1896,10 @@ create_dependency_handling_test_case( "-- Treating internal package ThyraTpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" "-- Treating internal package Zoltan as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + "-- NOTE: Boost is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: LAPACK is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: BLAS is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: MPI is indirectly downstream from a TriBITS-compliant external package" "Final set of enabled packages: Shards Sacado Galeri Intrepid Phalanx Panzer 6" "Final set of non-enabled top-level packages: TrilinosFramework Stokhos Isorropia RBGen 4" @@ -1959,6 +1970,9 @@ create_dependency_handling_test_case( "-- Treating internal package ThyraTpetra as EXTERNAL because downstream package Thyra being treated as EXTERNAL" "-- Treating internal package RTOp as EXTERNAL because downstream package ThyraCoreLibs being treated as EXTERNAL" "-- Treating internal package Zoltan as EXTERNAL because downstream package EpetraExt being treated as EXTERNAL" + "-- NOTE: Boost is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: LAPACK is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: BLAS is indirectly downstream from a TriBITS-compliant external package" "Final package build status [(]enabled only[)]:" "-- Final: BLAS_PACKAGE_BUILD_STATUS=EXTERNAL" diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake index 9f66911f5..0a296e757 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake @@ -935,7 +935,7 @@ function(TribitsExampleProject2_External_Package_by_Package PASS_REGULAR_EXPRESSION_ALL "Adjust the set of internal and external packages:" "-- Treating internal package Package1 as EXTERNAL because TPL_ENABLE_Package1=ON" - "-- NOTE: Tpl1 is directly downstream from an TriBITS-compliant external package Package1" + "-- NOTE: Tpl1 is directly downstream from a TriBITS-compliant external package Package1" "Final set of enabled top-level packages: Package2 1" "Final set of non-enabled top-level packages: Package3 1" @@ -998,11 +998,9 @@ function(TribitsExampleProject2_External_Package_by_Package "Adjust the set of internal and external packages:" "-- Treating internal package Package2 as EXTERNAL because TPL_ENABLE_Package2=ON" "-- Treating internal package Package1 as EXTERNAL because downstream package Package2 being treated as EXTERNAL" - "-- NOTE: Package1 is directly downstream from an TriBITS-compliant external package Package2" - "-- NOTE: Tpl3 is directly downstream from an TriBITS-compliant external package Package2" - "-- NOTE: Tpl1 is indirectly downstream from an TriBITS-compliant external package" - "-- NOTE: Tpl2 is indirectly downstream from an TriBITS-compliant external package" - "-- NOTE: Tpl1 is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: Tpl3 is directly downstream from a TriBITS-compliant external package Package2" + "-- NOTE: Tpl2 is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: Tpl1 is indirectly downstream from a TriBITS-compliant external package" "Final set of enabled top-level packages: Package3 1" "Final set of non-enabled top-level packages: 0" @@ -1068,5 +1066,4 @@ TribitsExampleProject2_External_Package_by_Package(STATIC CMAKE_PREFIX_PATH_CAC TribitsExampleProject2_External_Package_by_Package(SHARED CMAKE_PREFIX_PATH_CACHE) # NOTE: The above tests check a few different use cases for building and -# installing TriBITS packages from a single TriBITS project incrementally. It also tests the case where - +# installing TriBITS packages from a single TriBITS project incrementally. diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index 73f105f6c..ff5b3e64c 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -3297,8 +3297,8 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx PASS_REGULAR_EXPRESSION_ALL "Adjust the set of internal and external packages:" "-- Treating internal package SimpleCxx as EXTERNAL because TPL_ENABLE_SimpleCxx=ON" - "-- NOTE: HeaderOnlyTpl is directly downstream from an TriBITS-compliant external package SimpleCxx" - "-- NOTE: SimpleTpl is directly downstream from an TriBITS-compliant external package SimpleCxx" + "-- NOTE: SimpleTpl is directly downstream from a TriBITS-compliant external package SimpleCxx" + "-- NOTE: HeaderOnlyTpl is directly downstream from a TriBITS-compliant external package SimpleCxx" "Final set of enabled top-level packages: MixedLang WithSubpackages WrapExternal 3" "Final set of enabled packages: MixedLang WithSubpackagesA WithSubpackagesB WithSubpackagesC WithSubpackages WrapExternal 6" @@ -3442,6 +3442,11 @@ tribits_add_advanced_test( TribitsExampleProject_External_Package_by_Package -DCMAKE_PREFIX_PATH=../install_simplecxx../install_mixedlang ../TribitsExampleProject PASS_REGULAR_EXPRESSION_ALL + "Adjust the set of internal and external packages:" + "-- Treating internal package MixedLang as EXTERNAL because TPL_ENABLE_MixedLang=ON" + "-- Treating internal package SimpleCxx as EXTERNAL because TPL_ENABLE_SimpleCxx=ON" + "-- NOTE: SimpleTpl is directly downstream from a TriBITS-compliant external package SimpleCxx" + "-- NOTE: HeaderOnlyTpl is directly downstream from a TriBITS-compliant external package SimpleCxx" "Configuring done" ALWAYS_FAIL_ON_NONZERO_RETURN @@ -3489,18 +3494,10 @@ tribits_add_advanced_test( TribitsExampleProject_External_Package_by_Package "-- Treating internal package WithSubpackagesA as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" "-- Treating internal package WithSubpackagesB as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" "-- Treating internal package WithSubpackagesC as EXTERNAL because downstream package WithSubpackages being treated as EXTERNAL" - "-- NOTE: WithSubpackagesA is directly downstream from an TriBITS-compliant external package WithSubpackages" - "-- NOTE: WithSubpackagesB is directly downstream from an TriBITS-compliant external package WithSubpackages" - "-- NOTE: WithSubpackagesC is directly downstream from an TriBITS-compliant external package WithSubpackages" - "-- NOTE: WithSubpackagesA is indirectly downstream from an TriBITS-compliant external package" - "-- NOTE: WithSubpackagesB is indirectly downstream from an TriBITS-compliant external package" "-- Treating internal package SimpleCxx as EXTERNAL because downstream package WithSubpackagesB being treated as EXTERNAL" - "-- NOTE: SimpleCxx is indirectly downstream from an TriBITS-compliant external package" - "-- NOTE: WithSubpackagesA is indirectly downstream from an TriBITS-compliant external package" - "-- NOTE: SimpleCxx is indirectly downstream from an TriBITS-compliant external package" "-- Treating internal package MixedLang as EXTERNAL because TPL_ENABLE_MixedLang=ON" - "-- NOTE: HeaderOnlyTpl is indirectly downstream from an TriBITS-compliant external package" - "-- NOTE: SimpleTpl is indirectly downstream from an TriBITS-compliant external package" + "-- NOTE: SimpleTpl is indirectly downstream from a TriBITS-compliant external package" + "-- NOTE: HeaderOnlyTpl is indirectly downstream from a TriBITS-compliant external package" "Final set of enabled top-level packages: WrapExternal 1" "Final set of enabled packages: WrapExternal 1" diff --git a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake index 346cd650f..cc6da7aba 100644 --- a/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake +++ b/tribits/core/package_arch/TribitsAdjustPackageEnables.cmake @@ -853,10 +853,7 @@ macro(tribits_set_package_and_related_upstream_packages_to_external packageName tribits_set_upstream_dep_packages_as_external(${packageName} ${subpackageTriggeredParentPackageExternal}) - if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") - tribits_set_package_and_deps_as_processed_by_downstream_tribits_external_package( - ${packageName}) - endif() + tribits_set_package_as_processed_by_downstream_tribits_external_package(${packageName}) endmacro() # NOTE: In the above macro, if ${packageName} is made EXTERNAL because it one @@ -1320,41 +1317,40 @@ macro(tribits_set_upstream_dep_packages_as_external packageName endmacro() -# Macro that sets all of the direct upstream dependent packages as being -# processed by a downstream TriBITS-compliant external package. -macro(tribits_set_package_and_deps_as_processed_by_downstream_tribits_external_package - packageName - ) +# Mark a package as being processed by a downstream TriBITS-compliant external +# package +# +macro(tribits_set_package_as_processed_by_downstream_tribits_external_package packageName) - if ("${${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE}" - STREQUAL "" - ) - set(${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE FALSE) - endif() + set_default(${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE FALSE) tribits_get_package_enable_status(${packageName} packageEnable "") - if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL" - AND (${packageName}_IS_TRIBITS_COMPLIANT - OR ${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) - ) + if (${packageName}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") - if (${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) - set(directOrIndirectStr "indirectly") - set(downstreamPkgStr "") - else() - set(directOrIndirectStr "directly") - set(downstreamPkgStr " ${packageName}") - endif() + foreach(fwdDepPkg IN LISTS ${packageName}_FORWARD_LIB_DEFINED_DEPENDENCIES) - foreach(depPkg IN LISTS ${packageName}_LIB_DEFINED_DEPENDENCIES) - tribits_get_package_enable_status(${depPkg} depPkgEnable "") - if (depPkgEnable) - message("-- " - "NOTE: ${depPkg} is ${directOrIndirectStr} downstream from an" - " TriBITS-compliant external package${downstreamPkgStr}") + if((${fwdDepPkg}_IS_TRIBITS_COMPLIANT + OR ${fwdDepPkg}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) + AND (${fwdDepPkg}_PACKAGE_BUILD_STATUS STREQUAL "EXTERNAL") + ) + tribits_get_package_enable_status(${fwdDepPkg} fwdDepPkgEnable "") + if (${fwdDepPkg}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE) + set(directOrIndirectStr "indirectly") + set(downstreamPkgStr "") + else() + set(directOrIndirectStr "directly") + set(downstreamPkgStr " ${fwdDepPkg}") + endif() + if (packageEnable AND (NOT ${packageName}_IS_TRIBITS_COMPLIANT)) + message("-- " + "NOTE: ${packageName} is ${directOrIndirectStr} downstream from a" + " TriBITS-compliant external package${downstreamPkgStr}") + endif() + set(${packageName}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE TRUE) + break() endif() - set(${depPkg}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE TRUE) + endforeach() endif() @@ -1414,14 +1410,17 @@ endmacro() # prints the message if ```` is enabled. # macro(tribits_set_internal_package_to_external depPkgName) - tribits_get_package_enable_status(${depPkgName} depPkgEnable "") - if (depPkgEnable) - message("-- " - "Treating internal package ${depPkgName} as EXTERNAL because" - " " ${ARGN}) + if (NOT ${depPkgName}_INTERNAL_PACKAGE_ALREADY_SET_EXTERNAL) + tribits_get_package_enable_status(${depPkgName} depPkgEnable "") + if (depPkgEnable) + message("-- " + "Treating internal package ${depPkgName} as EXTERNAL because" + " " ${ARGN}) + endif() + set(${depPkgName}_PACKAGE_BUILD_STATUS EXTERNAL) + set(${depPkgName}_FINDMOD TRIBITS_PKG) + set(${depPkgName}_INTERNAL_PACKAGE_ALREADY_SET_EXTERNAL TRUE) endif() - set(${depPkgName}_PACKAGE_BUILD_STATUS EXTERNAL) - set(${depPkgName}_FINDMOD TRIBITS_PKG) endmacro() diff --git a/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake b/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake index b5e8b3b90..c8c22505b 100644 --- a/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake +++ b/tribits/core/package_arch/TribitsReadDepsFilesCreateDepsGraph.cmake @@ -960,6 +960,8 @@ macro(tribits_read_subpackage_deps_file_add_to_graph PACKAGE_NAME tribits_process_package_dependencies_lists(${SUBPACKAGE_FULLNAME}) + set(${SUBPACKAGE_FULLNAME}_IS_TRIBITS_COMPLIANT TRUE) + set(${SUBPACKAGE_FULLNAME}_REGRESSION_EMAIL_LIST ${${PACKAGE_NAME}_REGRESSION_EMAIL_LIST}) From 80bd994ac19438524156d7468342cb11b457dd09 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Sun, 19 Feb 2023 07:51:32 -0700 Subject: [PATCH 36/45] Update some outputing for TriBITS-compliant external packages (#63) This makes a few changes: * Only print "Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs" if there are any to be processed. * Add the word "remaining" to "Getting information for all enabled external packages/TPLs" to "Getting information for all remaining enabled external packages/TPLs" when there any TriBITS-compliant external packages being processed above this. * Add the word "external" to "Calling find_package() for TriBITS-compliant package" to "Calling find_package() for TriBITS-compliant external package" Hopefully this will be a little more clear --- test/core/DependencyUnitTests/CMakeLists.txt | 8 ++- .../TribitsExampleProject2_Tests.cmake | 9 +-- .../TribitsExampleProject_Tests.cmake | 10 +-- .../TribitsProcessEnabledTpls.cmake | 61 +++++++++++++++---- 4 files changed, 64 insertions(+), 24 deletions(-) diff --git a/test/core/DependencyUnitTests/CMakeLists.txt b/test/core/DependencyUnitTests/CMakeLists.txt index c042c8d42..74384b65c 100644 --- a/test/core/DependencyUnitTests/CMakeLists.txt +++ b/test/core/DependencyUnitTests/CMakeLists.txt @@ -686,12 +686,14 @@ create_reduced_dependency_handling_test_case( "-- Final: ThyraEpetraExt_PACKAGE_BUILD_STATUS=INTERNAL" "-- Final: Thyra_PACKAGE_BUILD_STATUS=INTERNAL" - "Getting information for all enabled external packages/TPLs ..." + "Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs" "Processing enabled external package/TPL: BLAS [(]enabled by Epetra, disable with -DTPL_ENABLE_BLAS=OFF[)]" "Processing enabled external package/TPL: LAPACK [(]enabled by Epetra, disable with -DTPL_ENABLE_LAPACK=OFF[)]" "Processing enabled external package/TPL: Teuchos [(]enabled explicitly, disable with -DTPL_ENABLE_Teuchos=OFF[)]" "Processing enabled external package/TPL: RTOp [(]enabled explicitly, disable with -DTPL_ENABLE_RTOp=OFF[)]" + "Getting information for all remaining enabled external packages/TPLs" + "Configuring individual enabled Trilinos packages ..." "Processing enabled top-level package: Epetra [(]Libs, Tests, Examples[)]" "Processing enabled top-level package: Triutils [(]Libs, Tests, Examples[)]" @@ -1909,7 +1911,7 @@ create_dependency_handling_test_case( "Final set of non-enabled top-level external packages/TPLs: Scotch METIS ParMETIS CppUnit ADOLC ADIC TVMET y12m SuperLUDist SuperLU UMFPACK AMD PETSC MUMPS DUMMY ML 16" "Final set of non-enabled external packages/TPLs: Scotch METIS ParMETIS CppUnit ADOLC ADIC TVMET y12m SuperLUDist SuperLU UMFPACK AMD PETSC MUMPS DUMMY ThyraCrazyStuff ML 17" - "Getting information for all enabled external packages/TPLs ..." + "Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs" "Processing enabled external package/TPL: MPI [(]enabled explicitly, disable with -DTPL_ENABLE_MPI=OFF[)]" "Processing enabled external package/TPL: BLAS [(]enabled by Epetra, disable with -DTPL_ENABLE_BLAS=OFF[)]" "Processing enabled external package/TPL: LAPACK [(]enabled by Epetra, disable with -DTPL_ENABLE_LAPACK=OFF[)]" @@ -1928,6 +1930,8 @@ create_dependency_handling_test_case( "Processing enabled external package/TPL: Belos [(]enabled by Phalanx, disable with -DTPL_ENABLE_Belos=OFF[)]" "Processing enabled external package/TPL: Stratimikos [(]enabled explicitly, disable with -DTPL_ENABLE_Stratimikos=OFF[)]" + "Getting information for all remaining enabled external packages/TPLs" + "Configuring individual enabled Trilinos packages ..." "Processing enabled top-level package: Shards [(]Libs[)]" "Processing enabled top-level package: Sacado [(]Libs[)]" diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake index 0a296e757..fb00c204b 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject2_Tests.cmake @@ -946,9 +946,9 @@ function(TribitsExampleProject2_External_Package_by_Package "Processing enabled external package/TPL: Tpl1 [(]enabled by Package1, disable with -DTPL_ENABLE_Tpl1=OFF[)]" "-- The external package/TPL Tpl1 will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: Package1 [(]enabled explicitly, disable with -DTPL_ENABLE_Package1=OFF[)]" - "-- Calling find_package[(]Package1[)] for TriBITS-compliant package" + "-- Calling find_package[(]Package1[)] for TriBITS-compliant external package" - "Getting information for all enabled external packages/TPLs ..." + "Getting information for all remaining enabled external packages/TPLs ..." "Processing enabled external package/TPL: Tpl2 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl2=OFF[)]" ${tpl2FoundRegexes} "Processing enabled external package/TPL: Tpl3 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl3=OFF[)]" @@ -1017,8 +1017,9 @@ function(TribitsExampleProject2_External_Package_by_Package "Processing enabled external package/TPL: Package1 [(]enabled explicitly, disable with -DTPL_ENABLE_Package1=OFF[)]" "-- The external package/TPL Package1 will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: Package2 [(]enabled explicitly, disable with -DTPL_ENABLE_Package2=OFF[)]" - "-- Calling find_package[(]Package2[)] for TriBITS-compliant package" - "Getting information for all enabled external packages/TPLs ..." + "-- Calling find_package[(]Package2[)] for TriBITS-compliant external package" + + "Getting information for all remaining enabled external packages/TPLs ..." "Processing enabled external package/TPL: Tpl4 [(]enabled explicitly, disable with -DTPL_ENABLE_Tpl4=OFF[)]" ${tpl4FoundRegexes} diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index ff5b3e64c..c704cd636 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -3315,9 +3315,9 @@ tribits_add_advanced_test( TribitsExampleProject_External_SimpleCxx "Processing enabled external package/TPL: SimpleTpl [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleTpl=OFF[)]" "-- The external package/TPL SimpleTpl will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: SimpleCxx [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleCxx=OFF[)]" - "-- Calling find_package[(]SimpleCxx[)] for TriBITS-compliant package" + "-- Calling find_package[(]SimpleCxx[)] for TriBITS-compliant external package" - "Getting information for all enabled external packages/TPLs ..." + "Getting information for all remaining enabled external packages/TPLs ..." "Configuring individual enabled TribitsExProj packages ..." "Processing enabled top-level package: MixedLang [(]Libs, Tests, Examples[)]" @@ -3516,11 +3516,11 @@ tribits_add_advanced_test( TribitsExampleProject_External_Package_by_Package "Processing enabled external package/TPL: SimpleCxx [(]enabled explicitly, disable with -DTPL_ENABLE_SimpleCxx=OFF[)]" "-- The external package/TPL SimpleCxx will be read in by a downstream TriBITS-compliant external package" "Processing enabled external package/TPL: MixedLang [(]enabled explicitly, disable with -DTPL_ENABLE_MixedLang=OFF[)]" - "-- Calling find_package[(]MixedLang[)] for TriBITS-compliant package" + "-- Calling find_package[(]MixedLang[)] for TriBITS-compliant external package" "Processing enabled external package/TPL: WithSubpackages [(]enabled explicitly, disable with -DTPL_ENABLE_WithSubpackages=OFF[)]" - "-- Calling find_package[(]WithSubpackages[)] for TriBITS-compliant package" + "-- Calling find_package[(]WithSubpackages[)] for TriBITS-compliant external package" - "Getting information for all enabled external packages/TPLs ..." + "Getting information for all remaining enabled external packages/TPLs ..." "Configuring individual enabled TribitsExProj packages ..." "Processing enabled top-level package: WrapExternal [(]Libs, Tests, Examples[)]" diff --git a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake index 7423606b3..b161a9ede 100644 --- a/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake +++ b/tribits/core/package_arch/TribitsProcessEnabledTpls.cmake @@ -58,21 +58,34 @@ macro(tribits_process_enabled_tpls) tribits_filter_package_list_from_var(${PROJECT_NAME}_DEFINED_TOPLEVEL_PACKAGES EXTERNAL ON NONEMPTY ${PROJECT_NAME}_enabledExternalTopLevelPackages) - message("") - message("Getting information for all enabled TriBITS-compliant" - " or upstream external packages/TPLs ...") - message("") + tribits_project_has_tribits_compliant_external_packages( + ${PROJECT_NAME}_enabledExternalTopLevelPackages + projectHasTribitsCompliantExternalPackages ) + + if (projectHasTribitsCompliantExternalPackages) + message("") + message("Getting information for all enabled TriBITS-compliant" + " or upstream external packages/TPLs ...") + message("") + + foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) + if (${TPL_NAME}_IS_TRIBITS_COMPLIANT + OR ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE + ) + tribits_process_enabled_tribits_compliant_or_upstream_tpl(${TPL_NAME}) + endif() + endforeach() - foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) - if (${TPL_NAME}_IS_TRIBITS_COMPLIANT - OR ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE - ) - tribits_process_enabled_tribits_compliant_or_upstream_tpl(${TPL_NAME}) - endif() - endforeach() + set(remainingTplsTextStr " remaining") + + else() + + set(remainingTplsTextStr "") + + endif() message("") - message("Getting information for all enabled external packages/TPLs ...") + message("Getting information for all${remainingTplsTextStr} enabled external packages/TPLs ...") message("") foreach(TPL_NAME IN LISTS ${PROJECT_NAME}_enabledExternalTopLevelPackages) @@ -152,7 +165,7 @@ endfunction() # macro(tribits_process_enabled_tribits_compliant_tpl TPL_NAME) message("-- " - "Calling find_package(${TPL_NAME}) for TriBITS-compliant package") + "Calling find_package(${TPL_NAME}) for TriBITS-compliant external package") find_package(${TPL_NAME} CONFIG REQUIRED) endmacro() @@ -249,3 +262,25 @@ function(tribits_generate_tpl_version_file_and_add_package_config_install_target tribits_extpkg_install_config_version_file(${TPL_NAME} "${tplConfigVersionFile}") endfunction() + + +function(tribits_project_has_tribits_compliant_external_packages + enabledExternalTopLevelPackagesListName + projectHasTribitsCompliantExternalPackagesOut + ) + + set(projectHasTribitsCompliantExternalPackages FALSE) + + foreach(TPL_NAME IN LISTS ${enabledExternalTopLevelPackagesListName}) + if (${TPL_NAME}_IS_TRIBITS_COMPLIANT + OR ${TPL_NAME}_PROCESSED_BY_DOWNSTREAM_TRIBITS_EXTERNAL_PACKAGE + ) + set(projectHasTribitsCompliantExternalPackages TRUE) + break() + endif() + endforeach() + + set(${projectHasTribitsCompliantExternalPackagesOut} + ${projectHasTribitsCompliantExternalPackages} PARENT_SCOPE) + +endfunction() From 31de1fe7d1c6a00999008be2aa7940b02984298f Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 20 Feb 2023 14:05:24 -0700 Subject: [PATCH 37/45] Add definitions of TriBITS-compliant packages (#63) --- tribits/doc/guides/TribitsGuidesBody.rst | 169 ++++++++++++++++++++++- 1 file changed, 165 insertions(+), 4 deletions(-) diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index b3a101e86..7679a9557 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -1918,10 +1918,11 @@ A *TriBITS External Package/TPL*: interface to one or more downstream TriBITS Packages. * Has a globally unique name ```` (see `Globally unique TriBITS TPL names`_) that is declared in a `/TPLsList.cmake`_ file. -* Has as `FindTPL.cmake`_ module that finds the pieces of an external - package/TPL and provides them to downstream packages through a required - INTERFACE target ``::all_libs`` (which gives the libraries, include - directories, and other usage requirements). +* Has as `FindTPL.cmake`_ module (for non-`TriBITS-Compliant External + Packages`_) that finds the pieces of an external package/TPL and provides + them to downstream packages through a required INTERFACE target + ``::all_libs`` (which gives the libraries, include directories, and + other usage requirements, see `TriBITS-Compliant External Package`_). * Is listed as an explicit optional or required dependency in one or more downstream TriBITS packages' `/cmake/Dependencies.cmake`_ files. * Can be enabled automatically or can trigger the disable of dependent @@ -1940,6 +1941,14 @@ if an external package/TPL is explicitly disabled, all of the downstream packages that depend on it will be automatically disabled as well (see `Package disable triggers auto-disables of downstream dependencies`_). +NOTE: The TriBITS TPL system implements a mechanism to turn external +dependencies into both `TriBITS-compliant packages`_ for consumption by +downstream TriBITS internal packages and also writes ``Config.cmake`` +files that are `TriBITS-compliant external packages`_ for consumption by +downstream ``Config.cmake`` files (which are `TriBITS-compliant +external packages`_) generated by `TriBITS-compliant internal packages`_. + + .. _Globally unique TriBITS TPL names: **WARNING:** One must be very careful to pick **Globally unique TriBITS @@ -2545,6 +2554,158 @@ without having to define its own ``QT`` TPL in its repository's .. ToDo: Describe considerations on where to set variables ... +.. _TriBITS-Compliant Package: + +TriBITS-Compliant Packages +========================== + +At the CMake build-system level, there are just a few key requirements that a +TriBITS package has for its upstream dependent packages when it is being +configured to be built. These requirements apply whether the upstream package +is defined internally in the current CMake project or provided externally and +pulled in through ``find_package()``. + +The common requirements for both internal and external **TriBITS-compliant +packages** as imposed by downstream TriBITS internal packages are: + +* Provides the (INTERFACE) target ``::all_libs`` which provides all + usage requirements for the libraries of ```` through the target + properties: + + * ``INTERFACE_LINK_LIBRARIES``: The library files needed link against (or + upstream library targets including ``::all_libs`` for all + its upstream packages) + + * ``INTERFACE_INCLUDE_DIRECTORIES``: Include directories to all public header files + + * ``INTERFACE_COMPILE_OPTIONS``: Required compiler options + + * ``INTERFACE_COMPILE_DEFINITIONS``: Required compiler/macro definitions + + * ``INTERFACE_LINK_OPTIONS``: Required compiler/macro definitions + + * Any other ``INTERFACE_XXX`` or ``IMPORTED_XXX`` target property needed to + correctly use the libraries for package ````. + +* Provides namespaced variables ``_ENABLE_`` set to + ``TRUE`` or ``FALSE`` for all of the upstream required and optional + dependencies for the package ````. + +* [Optional] Provides namespaced variables of the form + ``_`` for any other information about the configuration + of package ```` that may need to be known by a downstream TriBITS + package. + +* [Optional] Provides any (namespaced by ``_`` or ``_``) + CMake macros or functions that downstream CMake packages may need to use the + upstream package ````. + +* All of the upstream dependencies (listed in the ``INTERFACE_LINK_LIBRARIES`` + property recursively) are also `TriBITS-compliant packages`_ + +The TriBITS system will also set the variable: + +* ``_IS_TRIBITS_COMPLIANT``: Set to ``TRUE`` + +for all packages that are determined to be TriBITS-compliant packages. + +The above are all that is needed by downstream TriBITS packages to build and +link against their upstream dependencies. + +If a TriBITS package provides any CTest tests/examples, then it must also +satsify the following requirements: + +* Test names must be prefixed with the package name ``_``. + +* Tests should only be added if the variable ``_ENABLE_TESTS`` is + true. + +* Examples (that run as CTest tests) should only be added if the variable + ``_ENABLE_EXAMPLES`` is true. + +* The test ``PROCESSORS`` and other test properties must be set in a way + consistent with `tribits_add_test()`_ so as to run in parallel with other + tests and not overwhelm the computing resources on the machine. + +Additional requirements are placed on TriBITS-compliant packages depending on +if they are defined as internal CMake packages (i.e. `TriBITS-compliant +internal packages`_) or are pulled in as external pre-built/pre-installed +packages (i.e. `TriBITS-compliant external packages`_). + + +.. _TriBITS-Compliant Internal Packages: + +TriBITS-Compliant Internal Packages +----------------------------------- + +For TriBITS packages that are defined, built, and installed from a TriBITS +CMake project, there are an additional set of requirements for them to +behavior correctly with respect to other TriBITS packages. + +The requirements for **TriBITS-compliant internal packages** are: + +* All of the requirements for a `TriBITS-Compliant Package`_. + +* At the end of configuration and generation, writes out a `TriBITS-Compliant + External Package`_ file ``Config.cmake`` and supporting files under + the build directory ``/cmake_packages//`` allowing the + built (but not installed) package to be used by downstream CMake + packages/projects. + +* Provides an install target to create a `TriBITS-Compliant External Package`_ + file ``Config.cmake`` and supporting files under the install + directory ``/lib/cmake//`` allowing the installed + package to be used by downstream CMake packages/projects. + +* All of the upstream dependencies (recursively) are also `TriBITS-compliant + packages`_ + +TriBITS internal packages that are defined using the TriBITS framework using +the TriBITS-provided macros and functions such as `tribits_add_library()`_ are +automatically `TriBITS-compliant internal packages`_ and when they are +installed they automatically provide `TriBITS-compliant external packages`_. +But it is possible for a CMake package to write its own raw CMake code to +satisfy these basic requirements for both internal and external packages. + + +.. _TriBITS-Compliant External Package: + +TriBITS-Compliant External Packages +----------------------------------- + +For packages that are installed on the system and not built in the current +CMake project, a streamlined type of `TriBITS External Package/TPL`_ is a +*TriBITS-compliant external package*. These special types of external +package's don't need to provide a `FindTPL.cmake`_ find module. +Instead, they are fully defined by calling ``find_package()`` to +locate and load their ``Config.cmake`` package config file. + +The requirements for **TriBITS-compliant external packages** are: + +* All of the requirements for a `TriBITS-Compliant Package`_. + +* Defined by an installed ``Config.cmake`` file that provides + IMPORTED targets and ``set()`` statements for all of the needed variables. + +* Provides CMake variables: + + * ``_CONFIG`` or + ``_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE``: Points to the file + ``Config.cmake`` (i.e. ``${CMAKE_CURRENT_LIST_FILE}``) + + * ``_DIR`` or + ``_TRIBITS_COMPLIANT_PACKAGE_CONFIG_FILE_DIR`` Points to the base + directory for ``Config.cmake`` + (i.e. ``${CMAKE_CURRENT_LIST_DIR}``) + +* All of the upstream dependencies (recursively) are also provided as + `TriBITS-compliant external packages`_ with + ``Config.cmake`` files (see above) and all of the targets + and variables for a TriBITS-compliant external package are defined when the + ``Config.cmake`` file is included (or pulled in with + ``find_package()`` or ``find_dependency()``). + + Example TriBITS Projects ========================= From 652d1895c4c1b5b948c89bc0895916c6b6d58f05 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 20 Feb 2023 16:34:58 -0700 Subject: [PATCH 38/45] Add links to TriBITS-compliant external package in requirements for FindTPL.cmake files (#63) --- tribits/doc/guides/TribitsGuidesBody.rst | 52 ++++++++++++++---------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index 7679a9557..976c8e634 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -5875,21 +5875,31 @@ header files and libraries that must be found. A simple Requirements for FindTPL.cmake modules +++++++++++++++++++++++++++++++++++++++++++++++ -It is possible to create a ``FindTPL.cmake`` module without using any -TriBITS functions. The only firm requirements for a -``FindTPL.cmake`` file after it is included are: +It is possible to create a ``FindTPL.cmake`` find module without +using any TriBITS functions. The only firm requirements for a +``FindTPL.cmake`` file are: * The target ``::all_libs`` must be created and it must contain all of the needed libraries, include directories, and other usage requirements - (including for all upstream external packages/TPLs). + (including for all upstream external packages/TPLs) to implement a + `TriBITS-compliant package`_ to be consumed by downstream TriBITS packages. * The file ``/external_packages//Config.cmake`` - must be created in the build directory and when including the file - ``Config.cmake`` it must define the equivalent target - ``::all_libs`` (and must call ``find_dependency()`` correctly on - all upstream external packages/TPLs). - -Some of issues to consider in this case are described in the section `Tricky + must be created in the build directory, and when included, it must define + the equivalent IMPORTED target ``::all_libs``, pull all of the + ``Config.cmake`` files for upstream external packages/TPLs, and + define the needed variables to provide a `TriBITS-compliant external + package`_. + +TriBITS will set the remaining variables to provide a complete +`TriBITS-Compliant Package`_ for the current CMake project and will add the +install target to install the file +``/external_packages//Config.cmake`` to create a +`TriBITS-compliant external package`_. TriBITS will also automatically create +an appropriate package version file ``ConfigVersion.cmake``. + +Some of issues to consider in this case (and the role of the +``ConfigVersion.cmake`` file) are described in the section `Tricky considerations for TriBITS-generated Config.cmake files`_. @@ -6885,17 +6895,17 @@ files of the name ``Config.cmake``. These TriBITS-generated package config files ``Config.cmake`` could potentially be found by calls to ``find_package()`` (i.e. when `` == `` like with HDF5). These TriBITS-generated ``Config.cmake`` files are -primarily meant to provide the ``::all_libs`` targets and pull in -upstream dependencies for downstream TriBITS-compliant -``Config.cmake`` files. These TriBITS-generated -``Config.cmake`` files will usually not behave the same way existing -``Find.config`` find modules or native ``Config.cmake`` -package config files would behave as expected by downstream projects when -found by ``find_package()`` commands called in some arbitrary -downstream raw CMake project. Therefore, to avoid having an installed -TriBITS-generated ``HDF5Config.cmake`` file, for example, being found by the -inner call to ``find_package(HDF5 ...)`` in the file ``FindTPLHDF5.cmake`` -(which would be disastrous), TriBITS employs two safeguards. +primarily meant to provide a `TriBITS-compliant external package`_ for +downstream TriBITS-compliant ``Config.cmake`` files. These +TriBITS-generated ``Config.cmake`` files will usually not behave the +same way existing ``Find.config`` find modules or native +``Config.cmake`` package config files would behave as expected by +downstream projects when found by ``find_package()`` commands called +in some arbitrary downstream raw CMake project. Therefore, to avoid having an +installed TriBITS-generated ``HDF5Config.cmake`` file, for example, being +found by the inner call to ``find_package(HDF5 ...)`` in the file +``FindTPLHDF5.cmake`` (which could be disastrous), TriBITS employs two +safeguards. First, TriBITS-generated ``Config.cmake`` package config files are placed into the build directory under:: From 8fc1e2522ba634956f6789c50af0d73a0a110173 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 20 Feb 2023 17:30:06 -0700 Subject: [PATCH 39/45] Add build ref item for treating internal packages as external (#634) --- .../build_ref/TribitsBuildReferenceBody.rst | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/tribits/doc/build_ref/TribitsBuildReferenceBody.rst b/tribits/doc/build_ref/TribitsBuildReferenceBody.rst index ad3878827..396ae1516 100644 --- a/tribits/doc/build_ref/TribitsBuildReferenceBody.rst +++ b/tribits/doc/build_ref/TribitsBuildReferenceBody.rst @@ -1965,6 +1965,81 @@ and module files. Therefore, don't enable this if Fortran code in your project is pulling in module files from TPLs. +Building against pre-installed packages +--------------------------------------- + +The project can build against any pre-installed packages defined in +the project and ignore the internally defined packages. To trigger the enable +of a pre-installed internal package treated as an external package, configure +with:: + + -D TPL_ENABLE_=ON + +That will cause the CMake project to pull in the pre-installed +package ```` as an external package using +``find_package()`` instead of configuring and building the +internally defined ```` package. + +Configuring and building against a pre-installed package treated as an +external packages has several consequences: + +* Any internal packages that are upstream from ```` from an + enabled set of dependencies will also be treated as external packages (and + therefore must be pre-installed as well). + +* The TriBITS package ``Dependencies.cmake`` files for the + ```` package and all of its upstream packages must still + exist and will still be read in by the CMake project and the same + enable/disable logic will be performed as if the packages were being treated + internal. (However, the base ``CMakeLists.txt`` and all of other files for + these internally defined packages being treated as external packages can be + missing and will be ignored.) + +* The same set of enabled and disabled upstream dependencies must be specified + to the CMake project that was used to pre-build and pre-install + these internally defined packages being treated as external packages. + (Otherwise, a configure error will result from the mismatch.) + +* The definition of any TriBITS external packages/TPLs that are enabled + upstream dependencies from any of these internally defined packages being + treated as external packages will be defined by the calls to + ``find_package()`` and will **not** be found again. + +The logic for treating internally defined packages as external packages will +be printed in the CMake configure output in the section ``Adjust the set of +internal and external packages`` with output like:: + + Adjust the set of internal and external packages ... + + -- Treating internal package as EXTERNAL because TPL_ENABLE_=ON + -- Treating internal package as EXTERNAL because downstream package being treated as EXTERNAL + -- NOTE: is indirectly downstream from a TriBITS-compliant external package + -- NOTE: is indirectly downstream from a TriBITS-compliant external package + +All of these internally defined being treated as external (and all of their +upstream dependencies) are processed in a loop over these just these +TriBITS-compliant external packages and ``find_package()`` is only called on +the terminal TriBITS-compliant external packages. This is shown in the CMake +output in the section ``Getting information for all enabled TriBITS-compliant +or upstream external packages/TPLs`` and looks like:: + + Getting information for all enabled TriBITS-compliant or upstream external packages/TPLs ... + + Processing enabled external package/TPL: (...) + -- The external package/TPL will be read in by a downstream TriBITS-compliant external package + Processing enabled external package/TPL: (...) + -- The external package/TPL will be read in by a downstream TriBITS-compliant external package + Processing enabled external package/TPL: (...) + -- The external package/TPL will be read in by a downstream TriBITS-compliant external package + Processing enabled external package/TPL: (...) + -- Calling find_package( for TriBITS-compliant external package + +In the above example ````, ```` and ```` are all direct or +indirect dependencies of ```` and therefore calling just +``find_package()`` fully defines those TriBITS-compliant external +packages as well. + + xSDK Configuration Options -------------------------- From 2bcc17f6e8c2660728678a5c912198295d7106b1 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 21 Feb 2023 08:16:21 -0700 Subject: [PATCH 40/45] Add CHANGLOG.md entry for -D_ENABLE_=ON (#63, #546) This documents a break in backwards compatibility that occurred with the merge of PR #546. --- tribits/CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tribits/CHANGELOG.md b/tribits/CHANGELOG.md index cafcd92eb..808f94fec 100644 --- a/tribits/CHANGELOG.md +++ b/tribits/CHANGELOG.md @@ -2,6 +2,20 @@ ChangeLog for TriBITS ---------------------------------------- +## 2022-12-07: + +* **Changed:** Setting `-D_ENABLE_=ON` now triggers the + enable an external package/TPL `` similar to the way that + `-DTPL_ENABLE_` has always done. This is technically a change in + backward compatibility because setting `_ENABLE_=ON` for + an external package/TPL used to be ignored. This change was done as part of + a general refactoring to unify the handling of internal and external + packages and is a side effect of that refactoring (see [TriBITS + #63](https://github.com/TriBITSPub/TriBITS/issues/63)). (Initially, setting + `-D_ENABLE_=ON` resulted in a failed configure because the + refactoring was not complete for the handling of external packages/TPL. But + this was fixed in a latter update.) + ## 2023-10-25: * **Added:** New option `_SKIP_INSTALL_PROJECT_CMAKE_CONFIG_FILES` From 68c83ef9b3e6dae9ac843b67f884239b6e6f3a32 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 21 Feb 2023 08:28:30 -0700 Subject: [PATCH 41/45] Add documentation for TriBITS-compliant external packages TRIBITS_PKG (#63) * Documented special value of `TRIBITS_PKG` for the FINDMOD proeprty * Updated some surrounding existing documentation to improve it some. * Updated howto "How to add a new TriBITS external package/TPL" to mention `TRIBITS_PKG` and not needing the `FindTpl.cmake` file in that case. * Documented how support for dependencies for TriBITS-compliant external packages listed in the TPLsList.cmake file with `TRIBITS_PKG` would be handled (e.g. `TRIBITS_PKG:`). This is currently speculative since there are not tests and no implementation for this yet. But it seemed best to document this while I was thinking about this. --- .../TribitsProcessTplsLists.cmake | 98 +++++++++---------- tribits/doc/guides/TribitsGuidesBody.rst | 79 ++++++++------- 2 files changed, 90 insertions(+), 87 deletions(-) diff --git a/tribits/core/package_arch/TribitsProcessTplsLists.cmake b/tribits/core/package_arch/TribitsProcessTplsLists.cmake index 1229e1769..f5e5a6e55 100644 --- a/tribits/core/package_arch/TribitsProcessTplsLists.cmake +++ b/tribits/core/package_arch/TribitsProcessTplsLists.cmake @@ -47,10 +47,10 @@ include(Split) # @MACRO: tribits_repository_define_tpls() # -# Define the list of `TriBITS TPLs`_ (external packages) for a given `TriBITS -# Repository`_ which includes the TPL name, find module, and classification . -# This macro is typically called from inside of the repository's -# `/TPLsList.cmake`_ file. +# Define the list of `TriBITS External Packages/TPLs`_ for a given `TriBITS +# Repository`_ which includes the external package/TPL name, TriBITS TPL find +# module, and classification . This macro is typically called from inside of +# a TriBITS Repository's `/TPLsList.cmake`_ file. # # Usage:: # @@ -62,59 +62,53 @@ include(Split) # # This macro sets up a 2D array of ``NumTPLS`` by ``NumColumns`` listing out # the `TriBITS TPLs`_ for a `TriBITS Repository`_. Each row (with 3 entries) -# specifies a TPL which contains the columns (ordered 0-2): +# specifies a different TriBITS exernal package/TPL which contains the columns +# (ordered 0-2): # -# 0. **TPL** (````): The name of the TriBITS TPL ````. -# This name must be unique across all other TriBITS TPLs in this or any -# other TriBITS repo that might be combined into a single TriBITS project -# meta-build (see `Globally unique TriBITS TPL names`_). However, a TPL -# can be redefined from an upstream repo (see below). The name should be a -# valid identifier (e.g. matches the regex ``[a-zA-Z_][a-zA-Z0-9_]*``). -# TPL names typically use mixed case (e.g. ``SomeTpl`` and not -# ``SOMETPL``). +# 0. **TPL** (````): The name of the TriBITS external package/TPL +# ````. This name must be unique across all other TriBITS TPLs in +# this or any other TriBITS repo that might be combined into a single +# TriBITS project meta-build (see `Globally unique TriBITS TPL names`_). +# However, a TPL can be redefined from an upstream repo (see below). The +# name should be a valid identifier (e.g. matches the regex +# ``[a-zA-Z_][a-zA-Z0-9_]*``). TPL names typically use mixed case +# (e.g. ``SomeTpl``, not ``SOMETPL``). # -# 1. **FINDMOD** (````): The relative or absolute path for the -# find module, usually with the name `FindTPL.cmake`_. If it is a -# relative path, it is considered relative to the repository base directory -# ````. If just the base path for the find module is given, -# ending with ``"/"`` (e.g. ``"cmake/tpls/"``), then the find module will -# be assumed to be under that this directory with the standard name +# 1. **FINDMOD** (````): For a TriBITS external package/TPL that +# **is not** a `TriBITS-compliant external package`_, this is set to the +# relative or absolute path for the TriBITS TPL find module, usually with +# the name `FindTPL.cmake`_. If it is a relative path, it is +# considered relative to the repository base directory ````. If +# just the base path for the find module is given, ending with ``"/"`` +# (e.g. ``"cmake/tpls/"``), then the find module will be assumed to be +# under that this directory with the standard name # ``FindTPL.cmake``. (See `Creating the FindTPL.cmake -# file`_.) +# file`_.) However, if the external package **is** a `TriBITS-compliant +# external package`_, provide the value ``TRIBITS_PKG`` instead and no +# ``FindTPL.cmake`` file is needed. If a +# ``FindTPLDependencies.cmake`` file is needed in this case, then +# provide the path to that file (relative or absolute, directory or file +# path) using ``TRIBITS_PKG:``. This field is used to +# set the variables `_FINDMOD`_ and +# `_DEPENDENCIES_FILE`_. # -# 2. **CLASSIFICATION** (````): Gives the `Package Test -# Group`_ `PT`_, `ST`_, or `EX`_ and the maturity level ``EP``, ``RS``, -# ``PG``, ``PM``, ``GRS``, ``GPG``, ``GPM``, ``UM``. These are separated -# by a coma with no space in between such as ``"RS,PT"`` for a "Research -# Stable", "Primary Tested" package. No spaces are allowed so that CMake -# treats this a one field in the array. The maturity level can be left off -# in which case it is assumed to be ``UM`` for "Unspecified Maturity". +# 2. **CLASSIFICATION** (````): Gives the `Package Test Group`_ +# `PT`_, `ST`_, or `EX`_ and the maturity level ``EP``, ``RS``, ``PG``, +# ``PM``, ``GRS``, ``GPG``, ``GPM``, ``UM``. These are separated by a coma +# with no space in between such as ``"RS,PT"`` for a "Research Stable", +# "Primary Tested" package. No spaces are allowed so that CMake treats +# this a one field in the array. The maturity level can be left off in +# which case it is assumed to be ``UM`` for "Unspecified Maturity". This +# field is used to set the variable `_TESTGROUP`_ and +# ``_MATURITY_LEVEL``. # -# A TPL defined in a upstream repo can listed again in a downstream repo, -# which allows redefining the find module that is used to specify the TPL. -# This allows downstream repos to add additional requirements for a given TPL -# (i.e. add more libraries, headers, etc.). However, the downstream repo's -# find module file must find the TPL components that are fully compatible with -# the upstream's find module in terms of what it provides for packages in -# upstream repos. -# -# This macro just sets the variable:: -# -# ${REPOSITORY_NAME}_TPLS_FINDMODS_CLASSIFICATIONS -# -# in the current scope. The advantages of using this macro instead of -# directly setting this variable are that the macro: -# -# * Asserts that the variable ``REPOSITORY_NAME`` is defined and set -# -# * Avoids having to hard-code the assumed repository name -# ``${REPOSITORY_NAME}``. This provides more flexibility for how other -# TriBITS projects choose to name a given TriBITS repo (i.e. the name of -# repo subdirs). -# -# * Avoids misspelling the name of the variable -# ``${REPOSITORY_NAME}_TPLS_FINDMODS_CLASSIFICATIONS``. If one misspells -# the name of a macro, it is an immediate error in CMake. +# A TPL defined in a upstream repo can be listed again in a downstream repo, +# which allows redefining the find module that is used to specify the external +# package/TPL. This allows downstream repos to add additional requirements +# for a given TPL (i.e. add more libraries, headers, etc.). However, the +# downstream repo's find module file must find the TPL components that are +# fully compatible with the upstream defined find module in terms of what it +# provides for packages in the upstream repos. # macro(tribits_repository_define_tpls) assert_defined(REPOSITORY_NAME) diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index 976c8e634..1ba012360 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -233,7 +233,7 @@ units are: * `TriBITS External Package/TPL`_: The specification for a particular external dependency that is required or can be used in one or more `TriBITS Packages`_. A modern TriBITS external package/TPL (Third Party Library) is - typically just a small file ``FindTPL.cmake`` that calls + typically just a small file ``FindTTPL.cmake`` that calls ``find_package()`` and defines the ``::all_libs`` target. More generally, an external package/TPL can be specificed as a list list of libraries and/or include directories for header files. Examples of @@ -1985,12 +1985,13 @@ below: .. _FindTPL.cmake: .. _/FindTPL.cmake: -**/FindTPL.cmake**: [Required] Defines how an external -package/TPL is found and provided for usage by a downstream TriBITS package by -providing the ``::all_libs`` target and a package config file -``Config.cmake`` that also defines the target -``::all_libs``. (The requirements for a ``FindTPL.cmake`` -file are given in `Requirements for FindTPL.cmake modules`_). +**/FindTPL.cmake**: [Required] *TriBITS TPL find module* +that defines how a TriBITS external package/TPL is found and provided for +usage by a downstream TriBITS package. This module must provide the +``::all_libs`` target and must create a `TriBITS-compliant external +package`_ wrapper package config file ``Config.cmake``. (See the +requirements for a ``FindTPL.cmake`` file in `Requirements for +FindTPL.cmake modules`_). The form of a simple ``FindTPL.cmake`` file that uses an internal call to ``find_package()`` which provides modern IMPORTED CMake @@ -2006,7 +2007,8 @@ In this case, the purpose for the ``FindTPL.cmake`` file (as apposed to a direct call to ``find_package()``) is to ensure the definition of the complete target ``::all_libs`` which contains all usage requirements for the external package/TPL (i.e. all of the libraries, -include directories, etc.). +include directories, etc.) and this also generates the wrapper package config +file ``Config.cmake``. The form of a simple ``FindTPL.cmake`` file that just provides a list of required header files and libraries that does **not** use an internal call @@ -2070,23 +2072,20 @@ defined TPL ``TPL_NAME`` is assigned the following global non-cache variables: ``${TPL_NAME}_FINDMOD`` - Relative path (w.r.t. ````) or absolute path for the external - package/TPL's find module (typically named `FindTPL.cmake`_): - This is set using the ``FINDMOD`` field in the call to - `tribits_repository_define_tpls()`_. The final value of the variable is - defined by the *last* `/TPLsList.cmake`_ file that is processed - that declares the TPL ``TPL_NAME``. For example, if - ``Repo1/TPLsList.cmake`` and ``Repo2/TPLsList.cmake`` both list the TPL - ``SomeTpl``, then if ``Repo2`` is processed after ``Repo1``, then - ``SomeTpl_FINDMOD`` is determined by ``Repo2/TPLsList.cmake`` and the find - module listed in ``Repo1/TPLsList.cmake`` is ignored. NOTE: The special - value ``TRIBITS_PKG`` is also recognized for external packages/TPLs that - are *TriBITS-compliant* (i.e. defines a ``${TPL_NAME}Config.cmake`` - file provides the ``${TPL_NAME}::all_libs`` target, calls - ``find_dependency()`` on all of its upstream dependencies, - and each of those dependencies defines the ``::all_libs`` - target.) A pre-installed TriBITS package meets this definition, - obviously. + For a **non-** `TriBITS-compliant external package`_, this is the relative + path (w.r.t. ````) or absolute path for the *TriBITS TPL find + module* (typically named `FindTPL.cmake`_). This is set using the + ``FINDMOD`` field in the call to `tribits_repository_define_tpls()`_. The + final value of the variable is defined by the **last** + `/TPLsList.cmake`_ file that is processed that declares the TPL + ``TPL_NAME``. For example, if ``Repo1/TPLsList.cmake`` and + ``Repo2/TPLsList.cmake`` both list the TPL ``SomeTpl``, then if ``Repo2`` + is processed after ``Repo1``, then ``SomeTpl_FINDMOD`` is determined by + ``Repo2/TPLsList.cmake`` and the find module listed in + ``Repo1/TPLsList.cmake`` is ignored. NOTE: for a `TriBITS-compliant + external package`_, the special value ``TRIBITS_PKG`` is also recognized. + (Any pre-installed TriBITS package is a `TriBITS-compliant external + package`_.) .. __DEPENDENCIES_FILE: .. _${TPL_NAME}_DEPENDENCIES_FILE: @@ -2096,10 +2095,15 @@ defined TPL ``TPL_NAME`` is assigned the following global non-cache variables: Relative path (w.r.t. ````) or absolute path for the external package/TPL's dependencies file (typically named `FindTPLDependencies.cmake`_). This is always beside the find - module `${TPL_NAME}_FINDMOD`_ (and in fact - ``${TPL_NAME}_DEPENDENCIES_FILE`` is constructed from - ``${TPL_NAME}_FINDMOD``). - + module `${TPL_NAME}_FINDMOD`_. (In fact, for a **non-** + `TriBITS-compliant external package`_, ``${TPL_NAME}_DEPENDENCIES_FILE`` + is constructed from ``${TPL_NAME}_FINDMOD``). NOTE: A `TriBITS-compliant + external package`_ with dependencies will also have this file set and the + path will be specified independent of the path to the non-existent + ``FindTPL.cmake`` file (see the ``FINDMOD`` field in the call to + `tribits_repository_define_tpls()`_). + + .. __TESTGROUP: .. _${TPL_NAME}_TESTGROUP: ``${TPL_NAME}_TESTGROUP`` @@ -5520,15 +5524,20 @@ To add a new TriBITS TPL, do the following: 3) **Create the FindTPL.cmake file** (or some other name, see `_FINDMOD`_) under ``/``. (See `Creating the - FindTPL.cmake file`_.) + FindTPL.cmake file`_.) However, if the external package/TPL is a + `TriBITS-compliant external package`_ this file is not needed and is + ignored. 4) **[Optional] Create the FindTPLDependencies.cmake file** in the same directory as the ``FindTPL.cmake`` file, ``/``. - (See `FindTPLDependencies.cmake`_.) - -5) **Add a row to the /TPLsList.cmake file** for the new TPL after - any TPLs that this new TPL may depend on. (See - `/TPLsList.cmake`_.) + (See `FindTPLDependencies.cmake`_.) NOTE: This file is need for a + `TriBITS-compliant external package`_ if it has upstream dependent external + packages/TPLs (where the file ``FindTPL.cmake`` is not needed). + +5) **Add a row to the /TPLsList.cmake file** for the new external + package/TPL after any upstream TPLs that this new TPL may depend on. NOTE: + For a `TriBITS-compliant external package`_, the special value + ``TRIBITS_PKG`` is used for the TPL (See `/TPLsList.cmake`_.) 6) **Configure the TriBITS project enabling the new TPL with TPL_ENABLE_=ON** and see that the TPL is found correctly at From f8c1ea56309c86b1187f725ab30a414816f0d970 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 21 Feb 2023 08:39:11 -0700 Subject: [PATCH 42/45] Add CHANGLOG.md entry for supporting pre-installed packages (#63) --- tribits/CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tribits/CHANGELOG.md b/tribits/CHANGELOG.md index 808f94fec..045347bd5 100644 --- a/tribits/CHANGELOG.md +++ b/tribits/CHANGELOG.md @@ -2,6 +2,23 @@ ChangeLog for TriBITS ---------------------------------------- +## 2023-02-21: + +* Add support for pre-installed internal packages treated as external + packages. Now, any set of internally defined TriBITS packages for a TriBITS + project can be pre-built and pre-installed and the remaining packages in the + TriBITS project can be configured to point to those by setting `-D + TPL_ENABLE_=ON`. This allows great flexibility in how a TriBITS + project's packages can be and built, installed, and deployed. This + technically implements "Use Case 3: Configure/build pointing to a subset of + already installed TriBITS packages in same repo" in [TriBITS + #63](https://github.com/TriBITSPub/TriBITS/issues/63). See the section + "Building against pre-installed packages" in the updated build reference + documentation for details. + +* **Fixed:** Setting `-D_ENABLE_=ON` for an external + package/TPL `` will not correctly enable and process the TPL. + ## 2022-12-07: * **Changed:** Setting `-D_ENABLE_=ON` now triggers the From 90b96ee5667a39fa68ad9a77efade16030dc79bf Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 29 Mar 2023 10:26:41 -0600 Subject: [PATCH 43/45] Fix some documentation and add new functions to generated docs (#63, #560) Some of these were flagged by @KyleFromKitware in the review of PR #560. --- .../core/package_arch/TribitsGetPackageSublists.cmake | 10 ++++++---- tribits/doc/guides/TribitsGuidesBody.rst | 4 ++-- .../guides/TribitsSystemMacroFunctionDocTemplate.rst | 2 ++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tribits/core/package_arch/TribitsGetPackageSublists.cmake b/tribits/core/package_arch/TribitsGetPackageSublists.cmake index 192af2b3b..ddc392e53 100644 --- a/tribits/core/package_arch/TribitsGetPackageSublists.cmake +++ b/tribits/core/package_arch/TribitsGetPackageSublists.cmake @@ -54,12 +54,14 @@ include(TribitsGetPackageEnableStatus) # Where: # # * ````: Name of input list var of packages -# * ````: ``INTERNAL``, ``EXTERNAL`` or "" (i.e. -# INTERNAL or EXTERNAL) (matches ``_PACKAGE_BUILD_STATUS``) +# * ````: ``INTERNAL``, ``EXTERNAL`` or "" (i.e. both +# INTERNAL and EXTERNAL packages) (matches +# ``_PACKAGE_BUILD_STATUS``) # * ````: ``ON`` for elements that match ``TRUE`` , ``OFF`` # for elements that match ``FALSE`` -# * ````: Determines if allowed enable status is ``NONEMPTY`` -# or ``INCLUDE_EMPTY``. +# * ````: Enable status is ``NONEMPTY`` (i.e. must have a +# value) or ``INCLUDE_EMPTY`` (matches those with a value and with empty +# ""). # * ````: The name of the var that will store the filtered # sublist of packages. # diff --git a/tribits/doc/guides/TribitsGuidesBody.rst b/tribits/doc/guides/TribitsGuidesBody.rst index 3c3115f27..0cbcf2c5a 100644 --- a/tribits/doc/guides/TribitsGuidesBody.rst +++ b/tribits/doc/guides/TribitsGuidesBody.rst @@ -233,9 +233,9 @@ units are: * `TriBITS External Package/TPL`_: The specification for a particular external dependency that is required or can be used in one or more `TriBITS Packages`_. A modern TriBITS external package/TPL (Third Party Library) is - typically just a small file ``FindTTPL.cmake`` that calls + typically just a small file ``FindTPL.cmake`` that calls ``find_package()`` and defines the ``::all_libs`` - target. More generally, an external package/TPL can be specificed as a list + target. More generally, an external package/TPL can be specified as a list list of libraries and/or include directories for header files. Examples of basic external packages/TPLs include ``BLAS``, ``LAPACK``, and ``Boost``. diff --git a/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst b/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst index 585609202..6a71292c4 100644 --- a/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst +++ b/tribits/doc/guides/TribitsSystemMacroFunctionDocTemplate.rst @@ -23,8 +23,10 @@ understand the internals of TriBITS. @FUNCTION: tribits_extpkg_process_libraries_list() + @MACRO: tribits_extpkg_setup_enabled_dependencies() + @FUNCTION: tribits_extpkg_write_config_version_file() + +@FUNCTION: tribits_filter_package_list_from_var() + @FUNCTION: tribits_get_sublist_disabled() + @FUNCTION: tribits_get_sublist_enabled() + +@FUNCTION: tribits_get_sublist_internal_external() + @FUNCTION: tribits_get_sublist_nondisabled() + @FUNCTION: tribits_get_sublist_nonenabled() + @FUNCTION: tribits_print_initial_dependency_info() + From 16b181719bf5a8385a678dfe67b0001c247aea45 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 29 Mar 2023 10:34:11 -0600 Subject: [PATCH 44/45] Fix spelling of TribitsCMakeLanguageOverviewAndGotchas.rst (#63, #560) This was caught by @KyleFromKitware in review of PR #560. --- ...ndGotchas.rst => TribitsCMakeLanguageOverviewAndGotchas.rst} | 0 .../doc/guides/maintainers_guide/TribitsMaintainersGuide.rst | 2 +- tribits/doc/guides/users_guide/TribitsUsersGuide.rst | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename tribits/doc/guides/{TribitsCMakeLangaugeOverviewAndGotchas.rst => TribitsCMakeLanguageOverviewAndGotchas.rst} (100%) diff --git a/tribits/doc/guides/TribitsCMakeLangaugeOverviewAndGotchas.rst b/tribits/doc/guides/TribitsCMakeLanguageOverviewAndGotchas.rst similarity index 100% rename from tribits/doc/guides/TribitsCMakeLangaugeOverviewAndGotchas.rst rename to tribits/doc/guides/TribitsCMakeLanguageOverviewAndGotchas.rst diff --git a/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst b/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst index b8abdc39e..f9d973495 100644 --- a/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst +++ b/tribits/doc/guides/maintainers_guide/TribitsMaintainersGuide.rst @@ -71,7 +71,7 @@ Developers`_ and `TriBITS System Architects`_. Appendix ======== -.. include:: ../TribitsCMakeLangaugeOverviewAndGotchas.rst +.. include:: ../TribitsCMakeLanguageOverviewAndGotchas.rst .. include:: ../TribitsHistory.rst diff --git a/tribits/doc/guides/users_guide/TribitsUsersGuide.rst b/tribits/doc/guides/users_guide/TribitsUsersGuide.rst index 32decb289..720a71c75 100644 --- a/tribits/doc/guides/users_guide/TribitsUsersGuide.rst +++ b/tribits/doc/guides/users_guide/TribitsUsersGuide.rst @@ -90,7 +90,7 @@ in the `Appendix`_. Appendix ======== -.. include:: ../TribitsCMakeLangaugeOverviewAndGotchas.rst +.. include:: ../TribitsCMakeLanguageOverviewAndGotchas.rst .. include:: ../TribitsHistory.rst From 014a1538939b783602d2af6033b2175edfb51a96 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Wed, 29 Mar 2023 10:41:41 -0600 Subject: [PATCH 45/45] Remove unused legacy RELATIVE_PATH code (#63, #560) Turns out this code was not even being used anymore after the previous refactorings. This removes a very long comment as well that is just not needed. --- ...ribitsInternalPackageWriteConfigFile.cmake | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake index 9d6691402..914825ffa 100644 --- a/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake +++ b/tribits/core/package_arch/TribitsInternalPackageWriteConfigFile.cmake @@ -289,26 +289,6 @@ function(tribits_generate_package_config_file_for_install_tree packageName) set(EXPORT_FILE_VAR_PREFIX ${packageName}) endif() - # Set the include and library directories relative to the location - # at which the ${PROJECT_NAME}Config.cmake file is going to be - # installed. Note the variable reference below is escaped so it - # won't be replaced until a client project attempts to locate - # directories using the installed config file. This is to deal with - # installers that allow relocation of the install tree at *install* - # time. - # The export files are typically installed in - # //cmake//. - # The relative path to the installation dir is hence k*(../) + ../../, where - # k is the number of components in . Extract those here. - # This doesn't work if ${${PROJECT_NAME}_INSTALL_LIB_DIR} contains "./" or - # "../" components, but really, it never did. All of this should actually be - # handled by CMake's configure_package_config_file(). - string(REPLACE "/" ";" PATH_LIST ${${PROJECT_NAME}_INSTALL_LIB_DIR}) - set(RELATIVE_PATH "../..") - foreach(PATH ${PATH_LIST}) - set(RELATIVE_PATH "${RELATIVE_PATH}/..") - endforeach() - # Custom code in configuration file. set(PACKAGE_CONFIG_CODE "")