From 181ece4d6b879e0dfcff2ba462b70dd0ef9eda92 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Fri, 19 Aug 2022 20:24:20 -0600 Subject: [PATCH 1/7] Factor out code that checks for call context (#200) That code just clutters up the main macros() and makes them hard to reason about and maintain. --- .../package_arch/TribitsPackageMacros.cmake | 95 +++++++++++-------- .../TribitsSubPackageMacros.cmake | 18 ++-- 2 files changed, 65 insertions(+), 48 deletions(-) diff --git a/tribits/core/package_arch/TribitsPackageMacros.cmake b/tribits/core/package_arch/TribitsPackageMacros.cmake index de132128c..68f2f5937 100644 --- a/tribits/core/package_arch/TribitsPackageMacros.cmake +++ b/tribits/core/package_arch/TribitsPackageMacros.cmake @@ -180,25 +180,7 @@ macro(tribits_package_decl PACKAGE_NAME_IN) message("\nTRIBITS_PACKAGE_DECL: ${PACKAGE_NAME_IN}") endif() - if (CURRENTLY_PROCESSING_SUBPACKAGE) - tribits_report_invalid_tribits_usage( - "Cannot call tribits_package_decl() in a subpackage." - " Use tribits_subpackage() instead" - " error in ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}") - endif() - - if(${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED) - tribits_report_invalid_tribits_usage( - "tribits_package_decl() called more than once in Package ${PACKAGE_NAME}" - " This may be because tribits_package_decl() was explicitly called more than once or" - " TRIBITS_PACKAGE_DECL was called after TRIBITS_PACKAGE. You do not need both." - " If your package has subpackages then do not call tribits_package() instead call:" - " tribits_pacakge_decl() then tribits_process_subpackages() then tribits package_def()" - ) - endif() - - # Set flag to check that macros are called in the correct order - set(${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED TRUE) + tribits_package_decl_assert_call_context() # # A) Parse the input arguments @@ -268,6 +250,31 @@ macro(tribits_package_decl PACKAGE_NAME_IN) endmacro() +macro(tribits_package_decl_assert_call_context) + + if (CURRENTLY_PROCESSING_SUBPACKAGE) + tribits_report_invalid_tribits_usage( + "Cannot call tribits_package_decl() in a subpackage." + " Use tribits_subpackage() instead" + " error in ${CURRENT_SUBPACKAGE_CMAKELIST_FILE}") + endif() + + if(${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED) + tribits_report_invalid_tribits_usage( + "tribits_package_decl() called more than once in Package ${PACKAGE_NAME}" + " This may be because tribits_package_decl() was explicitly called more than once or" + " TRIBITS_PACKAGE_DECL was called after TRIBITS_PACKAGE. You do not need both." + " If your package has subpackages then do not call tribits_package() instead call:" + " tribits_pacakge_decl() then tribits_process_subpackages() then tribits package_def()" + ) + endif() + + # Set flag to check that macros are called in the correct order + set(${PACKAGE_NAME}_TRIBITS_PACKAGE_DECL_CALLED TRUE) + +endmacro() + + # @MACRO: tribits_package_def() # # Macro called in `/CMakeLists.txt`_ after subpackages are @@ -291,6 +298,30 @@ endmacro() # macro(tribits_package_def) + if (${PROJECT_NAME}_VERBOSE_CONFIGURE) + message("\nTRIBITS_PACKAGE_DEF: ${PACKAGE_NAME}") + endif() + + tribits_package_def_assert_call_context() + + if (NOT ${PROJECT_NAME}_ENABLE_${PACKAGE_NAME}) + if (${PROJECT_NAME}_VERBOSE_CONFIGURE) + message("\n${PACKAGE_NAME} not enabled so exiting package processing") + endif() + return() + endif() + + # Reset in case were changed by subpackages + tribits_set_common_vars(${PACKAGE_NAME}) + + # Define package linkage variables + tribits_define_linkage_vars(${PACKAGE_NAME}) + +endmacro() + + +macro(tribits_package_def_assert_call_context) + # check that this is not being called from a subpackage if(NOT ${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED) if (CURRENTLY_PROCESSING_SUBPACKAGE) @@ -311,23 +342,6 @@ macro(tribits_package_def) "${CURRENT_SUBPACKAGE_CMAKELIST_FILE}") endif() - if (${PROJECT_NAME}_VERBOSE_CONFIGURE) - message("\nTRIBITS_PACKAGE_DEF: ${PACKAGE_NAME}") - endif() - - if (NOT ${PROJECT_NAME}_ENABLE_${PACKAGE_NAME}) - if (${PROJECT_NAME}_VERBOSE_CONFIGURE) - message("\n${PACKAGE_NAME} not enabled so exiting package processing") - endif() - return() - endif() - - # Reset in case were changed by subpackages - tribits_set_common_vars(${PACKAGE_NAME}) - - # Define package linkage variables - tribits_define_linkage_vars(${PACKAGE_NAME}) - set(${PACKAGE_NAME}_TRIBITS_PACKAGE_DEF_CALLED TRUE) endmacro() @@ -353,6 +367,13 @@ endmacro() # side-effects (and variables set) after calling this macro. # macro(tribits_package PACKAGE_NAME_IN) + tribits_package_assert_call_context() + tribits_package_decl(${PACKAGE_NAME_IN} ${ARGN}) + tribits_package_def() +endmacro() + + +macro(tribits_package_assert_call_context) if (CURRENTLY_PROCESSING_SUBPACKAGE) if (NOT ${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED) @@ -381,8 +402,6 @@ macro(tribits_package PACKAGE_NAME_IN) set(${PACKAGE_NAME}_TRIBITS_PACKAGE_CALLED TRUE) - tribits_package_decl(${PACKAGE_NAME_IN} ${ARGN}) - tribits_package_def() endmacro() diff --git a/tribits/core/package_arch/TribitsSubPackageMacros.cmake b/tribits/core/package_arch/TribitsSubPackageMacros.cmake index 316063528..4db15ba65 100644 --- a/tribits/core/package_arch/TribitsSubPackageMacros.cmake +++ b/tribits/core/package_arch/TribitsSubPackageMacros.cmake @@ -139,7 +139,6 @@ function(tribits_subpackage_assert_call_context) endfunction() - # @MACRO: tribits_subpackage_postprocess() # # Macro that performs standard post-processing after defining a `TriBITS @@ -158,20 +157,22 @@ endfunction() # this macro but limitations of the CMake language make it necessary to do so. # macro(tribits_subpackage_postprocess) + tribits_subpackage_postprocess_assert_call_context() + tribits_package_postprocess_common() +endmacro() - # check that this is not being called from a package - if (NOT CURRENTLY_PROCESSING_SUBPACKAGE) - # This is being called from a package +macro(tribits_subpackage_postprocess_assert_call_context) + # check that this is not being called from a package + if (NOT CURRENTLY_PROCESSING_SUBPACKAGE) + # This is being called from a package tribits_report_invalid_tribits_usage( "Cannot call tribits_subpackage_postprocess() from a package." " Use tribits_package_postprocess() instead" " ${CURRENT_PACKAGE_CMAKELIST_FILE}") - else() - # This is being caleld from a subpackage - + # This is being caleld from a subpackage # check to make sure this has not already been called if (${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED) tribits_report_invalid_tribits_usage( @@ -185,12 +186,9 @@ macro(tribits_subpackage_postprocess) "tribits_subpackage() must be called before tribits_subpackage_postprocess()" " for the ${PARENT_PACKAGE_NAME} subpackage ${TRIBITS_SUBPACKAGE}") endif() - endif() # Set flags that are used to check that macros are called in the correct order dual_scope_set(${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED TRUE) - tribits_package_postprocess_common() - endmacro() From 5e26300ee34bf8e9a671e77ebff83b36ffeacf49 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 22 Aug 2022 18:17:34 -0600 Subject: [PATCH 2/7] Skip WORKING_DIRECTORY in cmake -E copy_directory . (#516) This started failing for some reason and I have no idea why. This refactored command is better anyway. --- .../TribitsExampleApp_Tests.cmake | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake index ac2f06400..8cf56562d 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake @@ -302,8 +302,8 @@ function(TribitsExampleApp_NoFortran fullOrComponents sharedOrStatic) MESSAGE "Copy source for TribitsExampleProject" CMND ${CMAKE_COMMAND} ARGS -E copy_directory - ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject . - WORKING_DIRECTORY TribitsExampleProject + ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject + TribitsExampleProject TEST_1 MESSAGE "Do the configure of TribitsExampleProject" @@ -428,8 +428,8 @@ function(TribitsExampleApp_EnableSingleSubpackage fullOrComponents sharedOrStati MESSAGE "Copy source for TribitsExampleProject" CMND ${CMAKE_COMMAND} ARGS -E copy_directory - ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject . - WORKING_DIRECTORY TribitsExampleProject + ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject + TribitsExampleProject TEST_1 MESSAGE "Make Withsubpackages OPTIONAL subpackages REQUIRED" @@ -567,8 +567,8 @@ function(TribitsExampleApp_ALL_ST byProjectOrPackage sharedOrStatic serialOrM MESSAGE "Copy source for TribitsExampleProject" CMND ${CMAKE_COMMAND} ARGS -E copy_directory - ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject . - WORKING_DIRECTORY TribitsExampleProject + ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject + TribitsExampleProject TEST_1 MESSAGE "Do the configure of TribitsExampleProject" @@ -963,8 +963,8 @@ function(TribitsExampleApp_ALL_ST_tpl_link_options byProjectOrPackage sharedOrSt MESSAGE "Copy source for TribitsExampleProject" CMND ${CMAKE_COMMAND} ARGS -E copy_directory - ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject . - WORKING_DIRECTORY TribitsExampleProject + ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject + TribitsExampleProject TEST_1 MESSAGE "Write configuration fragment file to deal with semi-colon problem" From 042006e4942b23449154ea0b257e758fd3d73e9b Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 22 Aug 2022 18:39:14 -0600 Subject: [PATCH 3/7] WIP: Add basic tests for exporting package cache vars (#516) This updates some existing tests for the export of selected package cache vars, including vars from parent package in subpackage Config.cmake files. --- .../TribitsExampleApp_Tests.cmake | 1 + .../TribitsExampleProject_Tests.cmake | 26 ++++++++++++++----- .../examples/TribitsExampleApp/CMakeLists.txt | 3 +++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake index 8cf56562d..1b38f6e3b 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleApp_Tests.cmake @@ -344,6 +344,7 @@ function(TribitsExampleApp_NoFortran fullOrComponents sharedOrStatic) ${tribitsExProjUseComponentsArg} ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleApp PASS_REGULAR_EXPRESSION_ALL + "WithSubpackagesA_SPECIAL_VALUE = '3'" "-- Configuring done" "-- Generating done" "-- Build files have been written to: .*/${testName}/app_build" diff --git a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake index adfe735fa..9806ec5fd 100644 --- a/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake +++ b/test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake @@ -136,6 +136,7 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) -DTribitsExProj_DUMP_CPACK_SOURCE_IGNORE_FILES=ON -DTribitsExProj_DUMP_PACKAGE_DEPENDENCIES=ON -DTribitsExProj_ENABLE_INSTALL_CMAKE_CONFIG_FILES=ON + -DWithSubpackagesA_SPECIAL_VALUE=5 -DCMAKE_CXX_FLAGS=-DSIMPLECXX_SHOW_DEPRECATED_WARNINGS=1 -DCMAKE_INSTALL_PREFIX=install ${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject @@ -310,6 +311,17 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) ALWAYS_FAIL_ON_NONZERO_RETURN TEST_5 + MESSAGE "Grep the contents of the WithSubpackagesAConfig.cmake file in build dir" + CMND cat ARGS cmake_packages/WithSubpackagesA/WithSubpackagesAConfig.cmake + PASS_REGULAR_EXPRESSION_ALL + "# Enables/Disables for upstream package dependencies" + "set[(]WithSubpackagesA_ENABLE_SimpleCxx ON[)]" + "# Exported cache variables" + "set[(]WithSubpackages_ENABLE_DEBUG .OFF.[)]" + "set[(]HAVE_WITHSUBPACKAGES_DEBUG .OFF.[)]" + "set[(]WithSubpackagesA_SPECIAL_VALUE .5.[)]" + + TEST_6 MESSAGE "Build 'install' target using raw 'make'" CMND make ARGS install ${CTEST_BUILD_FLAGS} PASS_REGULAR_EXPRESSION_ALL @@ -343,7 +355,7 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) "Installing: .+/install/lib/cmake/WithSubpackagesC/WithSubpackagesCTargets-release.cmake" ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_6 + TEST_7 MESSAGE "Create and configure a dummy project that calls" " find_package(WithSubpackages) from the install tree" CMND ${CMAKE_COMMAND} @@ -390,7 +402,7 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) "WithSubpackages::all_libs INTERFACE_LINK_LIBRARIES: 'WithSubpackagesA::pws_a[;]WithSubpackagesB::pws_b[;]WithSubpackagesC::pws_c'" ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_7 + TEST_8 MESSAGE "Create and configure a dummy project that calls" " find_package(TribitsExProj) with no components" CMND ${CMAKE_COMMAND} @@ -448,7 +460,7 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) "-- Generating done" ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_8 + TEST_9 MESSAGE "Create and configure a dummy project that calls find_package(TribitsExProj)" " with required and optional components" CMND ${CMAKE_COMMAND} @@ -478,7 +490,7 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) "-- Generating done" ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_9 + TEST_10 MESSAGE "Run find_package() from two different subdirs with related packages" WORKING_DIRECTORY find_package_two_dirs CMND ${CMAKE_COMMAND} @@ -492,7 +504,7 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) "-- Generating done" ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_10 + TEST_11 MESSAGE "Create the tarball" CMND make ARGS package_source PASS_REGULAR_EXPRESSION_ALL @@ -509,12 +521,12 @@ function(TribitsExampleProject_ALL_ST_NoFortran sharedOrStatic serialOrMpi) "CPack: - package: .*/ExamplesUnitTests/${testName}/tribitsexproj-1.1-Source.tar.bz2 generated." ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_11 + TEST_12 MESSAGE "Untar the tarball" CMND tar ARGS -xzf tribitsexproj-1.1-Source.tar.gz ALWAYS_FAIL_ON_NONZERO_RETURN - TEST_12 + TEST_13 MESSAGE "Make sure right directories are excluded" CMND diff ARGS -qr diff --git a/tribits/examples/TribitsExampleApp/CMakeLists.txt b/tribits/examples/TribitsExampleApp/CMakeLists.txt index 4de561d8a..562a38ffd 100644 --- a/tribits/examples/TribitsExampleApp/CMakeLists.txt +++ b/tribits/examples/TribitsExampleApp/CMakeLists.txt @@ -17,6 +17,9 @@ include(AppHelperFuncs) getTribitsExProjStuffForApp() +# Show that we can see exported cache vars +message("-- WithSubpackagesA_SPECIAL_VALUE = '${WithSubpackagesA_SPECIAL_VALUE}'") + # Enable the compilers now that we have gotten them from the *Config.cmake file enable_language(C) enable_language(CXX) From ea526c94356a1e824e16cd5e4c93967a608fdc43 Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Mon, 22 Aug 2022 16:40:53 -0600 Subject: [PATCH 4/7] Add support exporting package cache vars in Config.cmake (#516) This provides a mechanism for packages to provide information about how they were configured to downstream CMake projects. Any cache vars set with tribits_add_option_and_define() are exported automatically but TriBITS packages can call tribits_pkg_export_cache_var() to export any cache vars. See updated documentation for details. --- tribits/CHANGELOG.md | 6 +++ .../TribitsAddOptionAndDefine.cmake | 7 +++ .../package_arch/TribitsPackageMacros.cmake | 45 +++++++++++++++++++ .../TribitsSubPackageMacros.cmake | 1 + .../TribitsWriteClientExportFiles.cmake | 14 ++++++ .../TribitsMacroFunctionDocTemplate.rst | 1 + .../packages/simple_cxx/CMakeLists.txt | 1 + .../packages/with_subpackages/a/A.cpp | 5 +++ .../packages/with_subpackages/a/A.hpp | 3 ++ .../with_subpackages/a/CMakeLists.txt | 12 +++-- .../a/cmake/WithSubpackagesA_config.h.in | 6 +++ .../with_subpackages/a/tests/CMakeLists.txt | 1 + .../with_subpackages/a/tests/a_test.cpp | 8 ++-- 13 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 tribits/examples/TribitsExampleProject/packages/with_subpackages/a/cmake/WithSubpackagesA_config.h.in diff --git a/tribits/CHANGELOG.md b/tribits/CHANGELOG.md index 7e3e02001..558c787b1 100644 --- a/tribits/CHANGELOG.md +++ b/tribits/CHANGELOG.md @@ -2,6 +2,12 @@ ChangeLog for TriBITS ---------------------------------------- +## 2022-08-22: + +* **Added:** Added support for exporting cache variables for packages in their + `Config.cmake` files using the new function + `tribits_pkg_export_cache_var()`. + ## 2022-08-18: * **Changed:** Made setting parent package tests/examples enable/disable diff --git a/tribits/core/package_arch/TribitsAddOptionAndDefine.cmake b/tribits/core/package_arch/TribitsAddOptionAndDefine.cmake index 8c98b1717..7ad7eff08 100644 --- a/tribits/core/package_arch/TribitsAddOptionAndDefine.cmake +++ b/tribits/core/package_arch/TribitsAddOptionAndDefine.cmake @@ -58,6 +58,9 @@ include(GlobalSet) # # #cmakedefine # +# NOTE: This also calls `tribits_pkg_export_cache_var()`_ to export the +# variables ```` and ````. +# macro(tribits_add_option_and_define USER_OPTION_NAME MACRO_DEFINE_NAME DOCSTRING DEFAULT_VALUE ) @@ -70,6 +73,10 @@ macro(tribits_add_option_and_define USER_OPTION_NAME MACRO_DEFINE_NAME global_set(${MACRO_DEFINE_NAME} OFF) endif() endif() + if (COMMAND tribits_pkg_export_cache_var) + tribits_pkg_export_cache_var(${USER_OPTION_NAME}) + tribits_pkg_export_cache_var(${MACRO_DEFINE_NAME}) + endif() endmacro() # 2008/10/05: rabartl: ToDo: Add an option to automatically add the macro diff --git a/tribits/core/package_arch/TribitsPackageMacros.cmake b/tribits/core/package_arch/TribitsPackageMacros.cmake index 68f2f5937..62a025a12 100644 --- a/tribits/core/package_arch/TribitsPackageMacros.cmake +++ b/tribits/core/package_arch/TribitsPackageMacros.cmake @@ -78,6 +78,47 @@ macro(tribits_define_linkage_vars PACKAGE_NAME_IN) endmacro() +# Macro that sets up data-structures for variables to be exported +# +macro(tribits_pkg_init_exported_vars PACKAGE_NAME_IN) + global_set(${PACKAGE_NAME_IN}_PKG_VARS_TO_EXPORT "") +endmacro() + + +# @MACRO: tribits_pkg_export_cache_var() +# +# Macro that registers a package-level cache var to be exported in the +# ``Config.cmake`` file +# +# Usage:: +# +# tribits_pkg_export_cache_var() +# +# where ```` must be the name of a cache variable (or an error +# will occur). +# +# NOTE: This will also export this variable to the +# ``Config.cmake`` file for every enabled subpackage (if this +# is called from a ``CMakeLists.txt`` file of a top-level package that has +# subpackages). That way, any top-level package cache vars are provided by +# any of the subpackages' ``Config.cmake`` files. +# +macro(tribits_pkg_export_cache_var cacheVarName) + if (DEFINED ${PACKAGE_NAME}_PKG_VARS_TO_EXPORT) + # Assert this is a cache var + get_property(cacheVarIsCacheVar CACHE ${cacheVarName} PROPERTY VALUE SET) + if (NOT cacheVarIsCacheVar) + message(SEND_ERROR + "ERROR: The variable ${cacheVarName} is NOT a cache var and cannot" + " be exported!") + endif() + # Add to the list of package cache vars to export + append_global_set(${PACKAGE_NAME}_PKG_VARS_TO_EXPORT + ${cacheVarName}) + endif() +endmacro() + + # Macro that defines variables that create global targets # macro(tribits_define_target_vars PARENT_PACKAGE_NAME_IN) @@ -218,6 +259,7 @@ macro(tribits_package_decl PACKAGE_NAME_IN) # tribits_set_common_vars(${PACKAGE_NAME_IN}) + tribits_pkg_init_exported_vars(${PACKAGE_NAME_IN}) set(${PACKAGE_NAME_IN}_DISABLE_STRONG_WARNINGS OFF CACHE BOOL @@ -459,6 +501,9 @@ endmacro() # typically called in the package's `/CMakeLists.txt`_ file (see # the example ``SimpleCxx/CMakeLists.txt``). # +# NOTE: This also calls `tribits_pkg_export_cache_var()`_ to export the +# variable ``${PACKAGE_NAME}_ENABLE_DEBUG``. +# macro(tribits_add_debug_option) tribits_add_option_and_define( ${PACKAGE_NAME}_ENABLE_DEBUG diff --git a/tribits/core/package_arch/TribitsSubPackageMacros.cmake b/tribits/core/package_arch/TribitsSubPackageMacros.cmake index 4db15ba65..52c3b7aff 100644 --- a/tribits/core/package_arch/TribitsSubPackageMacros.cmake +++ b/tribits/core/package_arch/TribitsSubPackageMacros.cmake @@ -88,6 +88,7 @@ macro(tribits_subpackage SUBPACKAGE_NAME_IN) # Now override the package-like variables tribits_set_common_vars(${SUBPACKAGE_FULLNAME}) tribits_define_linkage_vars(${SUBPACKAGE_FULLNAME}) + tribits_pkg_init_exported_vars(${SUBPACKAGE_FULLNAME}) tribits_append_package_specific_compiler_flags() if(${PROJECT_NAME}_VERBOSE_CONFIGURE) diff --git a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake index 6321f6d93..4a0213f4d 100644 --- a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake +++ b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake @@ -577,6 +577,20 @@ function(tribits_append_dependent_package_config_file_includes_and_enables packa "set(${EXPORT_FILE_VAR_PREFIX}_ENABLE_${depPkg} ${enableVal})\n") endforeach() + # Put in set() statements for exported cache vars + string(APPEND configFileStr + "\n# Exported cache variables\n") + if (NOT "${${packageName}_PARENT_PACKAGE}" STREQUAL "") + foreach(exportedCacheVar IN LISTS ${${packageName}_PARENT_PACKAGE}_PKG_VARS_TO_EXPORT) + string(APPEND configFileStr + "set(${exportedCacheVar} \"${${exportedCacheVar}}\")\n") + endforeach() + endif() + foreach(exportedCacheVar IN LISTS ${packageName}_PKG_VARS_TO_EXPORT) + string(APPEND configFileStr + "set(${exportedCacheVar} \"${${exportedCacheVar}}\")\n") + endforeach() + # Include configurations of dependent packages string(APPEND configFileStr "\n# Include configuration of dependent packages\n") diff --git a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst index b87a485d8..3ad983471 100644 --- a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst +++ b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst @@ -30,6 +30,7 @@ @FUNCTION: tribits_find_most_recent_source_file_timestamp() + @FUNCTION: tribits_install_headers() + @MACRO: tribits_include_directories() + +@MACRO: tribits_pkg_export_cache_var() + @MACRO: tribits_package() + @MACRO: tribits_package_decl() + @MACRO: tribits_package_def() + diff --git a/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt index d9e5c1c2b..4eb715a09 100644 --- a/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/simple_cxx/CMakeLists.txt @@ -8,6 +8,7 @@ tribits_package( SimpleCxx ENABLE_SHADOWING_WARNINGS CLEANED ) # include(CheckFor__int64) check_for___int64(HAVE_SIMPLECXX___INT64) +tribits_pkg_export_cache_var(HAVE_SIMPLECXX___INT64) # # C) Set up package-specific options diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.cpp b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.cpp index f9db8c90a..85286e850 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.cpp +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.cpp @@ -1,4 +1,5 @@ #include "A.hpp" +#include "WithSubpackagesA_config.h" #include "SimpleCxx_HelloWorld.hpp" @@ -9,3 +10,7 @@ std::string WithSubpackages::getA() { std::string WithSubpackages::depsA() { return "SimpleCxx "+SimpleCxx::deps(); } + +int WithSubpackages::specialValue() { + return WITHSUBPACKAGESA_SPECIAL_VALUE; +} diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp index 3476ee5b1..68fac5c16 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp @@ -11,6 +11,9 @@ namespace WithSubpackages { // return a string describing the dependencies of "A", recursively std::string depsA(); + // return speical value + int specialValue(); + } diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/CMakeLists.txt index f9ede481a..e7cdf9cf6 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/CMakeLists.txt @@ -6,18 +6,22 @@ tribits_subpackage(A) # # B) Set up subpackage-specific options # -# Typically there are none or are few as most options are picked up from the -# parent package's CMakeLists.txt file! + +set(${PACKAGE_NAME}_SPECIAL_VALUE 3 CACHE STRING "Integer special value") +tribits_pkg_export_cache_var(${PACKAGE_NAME}_SPECIAL_VALUE) # # C) Add the libraries, tests, and examples # +tribits_configure_file(${PACKAGE_NAME}_config.h) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}) tribits_add_library(pws_a SOURCES A.cpp - HEADERS A.hpp - NOINSTALLHEADERS + HEADERS A.hpp ${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_NAME}_config.h ) tribits_add_test_directories(tests) diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/cmake/WithSubpackagesA_config.h.in b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/cmake/WithSubpackagesA_config.h.in new file mode 100644 index 000000000..4536208a0 --- /dev/null +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/cmake/WithSubpackagesA_config.h.in @@ -0,0 +1,6 @@ +#ifndef WITHSUBPACKAGESA_CONFIG_H +#define WITHSUBPACKAGESA_CONFIG_H + +#define WITHSUBPACKAGESA_SPECIAL_VALUE ${WithSubpackagesA_SPECIAL_VALUE} + +#endif // WITHSUBPACKAGESA_CONFIG_H diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt index 788b93eac..b9d2e2af4 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt @@ -6,4 +6,5 @@ tribits_add_advanced_test( test_of_a PASS_REGULAR_EXPRESSION_ALL "A label is: A" "A deps are: ${EXPECTED_SIMPLECXX_AND_DEPS}" + "A speical value: ${WithSubpackagesA_SPECIAL_VALUE}" ) diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp index 4c48a7838..0d1cd6b0f 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp @@ -3,13 +3,11 @@ #include "A.hpp" -using namespace WithSubpackages; - int main() { - std::string label_A = getA(); - std::string deps_A = depsA(); + std::string label_A = WithSubpackages::getA(); + std::string deps_A = WithSubpackages::depsA(); std::cout << "A label is: " << label_A << std::endl; std::cout << "A deps are: " << deps_A << std::endl; - + std::cout << "A speical value: " << WithSubpackages::specialValue() << std::endl; return 0; } From b26f5ac73332cc247e7d94b19431663dd761077d Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 23 Aug 2022 08:23:47 -0600 Subject: [PATCH 5/7] Fixed few typos from the review of #520 (#516) These were pointed out by @KyleFromKitware in the review of PR #520. --- tribits/core/package_arch/TribitsSubPackageMacros.cmake | 2 +- .../TribitsExampleProject/packages/with_subpackages/a/A.hpp | 2 +- .../packages/with_subpackages/a/tests/CMakeLists.txt | 2 +- .../packages/with_subpackages/a/tests/a_test.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tribits/core/package_arch/TribitsSubPackageMacros.cmake b/tribits/core/package_arch/TribitsSubPackageMacros.cmake index 52c3b7aff..27383b190 100644 --- a/tribits/core/package_arch/TribitsSubPackageMacros.cmake +++ b/tribits/core/package_arch/TribitsSubPackageMacros.cmake @@ -173,7 +173,7 @@ macro(tribits_subpackage_postprocess_assert_call_context) " Use tribits_package_postprocess() instead" " ${CURRENT_PACKAGE_CMAKELIST_FILE}") else() - # This is being caleld from a subpackage + # This is being called from a subpackage # check to make sure this has not already been called if (${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED) tribits_report_invalid_tribits_usage( diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp index 68fac5c16..36364a10a 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/A.hpp @@ -11,7 +11,7 @@ namespace WithSubpackages { // return a string describing the dependencies of "A", recursively std::string depsA(); - // return speical value + // return special value int specialValue(); } diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt index b9d2e2af4..c891750a7 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/CMakeLists.txt @@ -6,5 +6,5 @@ tribits_add_advanced_test( test_of_a PASS_REGULAR_EXPRESSION_ALL "A label is: A" "A deps are: ${EXPECTED_SIMPLECXX_AND_DEPS}" - "A speical value: ${WithSubpackagesA_SPECIAL_VALUE}" + "A special value: ${WithSubpackagesA_SPECIAL_VALUE}" ) diff --git a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp index 0d1cd6b0f..6497b4d8e 100644 --- a/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp +++ b/tribits/examples/TribitsExampleProject/packages/with_subpackages/a/tests/a_test.cpp @@ -8,6 +8,6 @@ int main() { std::string deps_A = WithSubpackages::depsA(); std::cout << "A label is: " << label_A << std::endl; std::cout << "A deps are: " << deps_A << std::endl; - std::cout << "A speical value: " << WithSubpackages::specialValue() << std::endl; + std::cout << "A special value: " << WithSubpackages::specialValue() << std::endl; return 0; } From 8f322d448e7aeb290b3c3ca5d4e7a5d7b5ecf87a Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 23 Aug 2022 08:34:44 -0600 Subject: [PATCH 6/7] Compress vertical lines in args to cmake_parse_arguments() (#516) I saw this while working on #516. --- tribits/core/package_arch/TribitsWriteClientExportFiles.cmake | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake index 4a0213f4d..587698f7d 100644 --- a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake +++ b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake @@ -545,8 +545,7 @@ function(tribits_append_dependent_package_config_file_includes_and_enables packa # Parse input cmake_parse_arguments( - PARSE #prefix - "" #options + 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 From 903b9a1cd298d87b52550dd6ef420f75e9e3502e Mon Sep 17 00:00:00 2001 From: "Roscoe A. Bartlett" Date: Tue, 23 Aug 2022 08:37:42 -0600 Subject: [PATCH 7/7] Assert exported cache and local vars have same value (#516) Added macro tribits_assert_cache_and_local_vars_same_value() (with strong unit tests) to ensure that if any exported cache vars also has local vars of the same name that they also have the same value. This was done in response to review of PR #520 from @KyleFromKitware. --- test/core/CMakeLists.txt | 2 +- ...bitsWriteClientExportFiles_UnitTests.cmake | 45 ++++++++++++++++++- .../package_arch/TribitsGeneralMacros.cmake | 24 ++++++++++ .../TribitsWriteClientExportFiles.cmake | 2 + .../TribitsMacroFunctionDocTemplate.rst | 1 + 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/test/core/CMakeLists.txt b/test/core/CMakeLists.txt index 89d3fe518..88e5143c4 100644 --- a/test/core/CMakeLists.txt +++ b/test/core/CMakeLists.txt @@ -131,7 +131,7 @@ tribits_add_advanced_test( TribitsWriteClientExportFiles_UnitTests -DCMAKE_CURRENT_LIST_DIR=${CMAKE_CURRENT_SOURCE_DIR} -P "${CMAKE_CURRENT_SOURCE_DIR}/TribitsWriteClientExportFiles_UnitTests.cmake" PASS_REGULAR_EXPRESSION_ALL - "Final UnitTests Result: num_run = 30" + "Final UnitTests Result: num_run = 33" "Final UnitTests Result: PASSED" ) diff --git a/test/core/TribitsWriteClientExportFiles_UnitTests.cmake b/test/core/TribitsWriteClientExportFiles_UnitTests.cmake index ccef8a934..82eaf0f16 100644 --- a/test/core/TribitsWriteClientExportFiles_UnitTests.cmake +++ b/test/core/TribitsWriteClientExportFiles_UnitTests.cmake @@ -75,7 +75,46 @@ endmacro() # -# A) Test basic package processing and reading dependencies +# A) Misc unit tests +# + +function(unittest_tribits_assert_cache_and_local_vars_same_value) + + message("\n***") + message("*** tribits_assert_cache_and_local_vars_same_value()") + message("***\n") + + set(MESSAGE_WRAPPER_UNIT_TEST_MODE TRUE) + + message("\nOnly cache var exists") + global_set(MESSAGE_WRAPPER_INPUT) + set(cacheVar1 "1st value" CACHE STRING "") + tribits_assert_cache_and_local_vars_same_value(cacheVar1) + unittest_compare_const(MESSAGE_WRAPPER_INPUT "") + unset(cacheVar1 CACHE) + + message("\nCache var and local var with same values exist") + global_set(MESSAGE_WRAPPER_INPUT) + set(cacheVar2 "2nd value" CACHE STRING "") + set(cacheVar2 "2nd value") + tribits_assert_cache_and_local_vars_same_value(cacheVar2) + unittest_compare_const(MESSAGE_WRAPPER_INPUT "") + unset(cacheVar2 CACHE) + + message("\nCache var and local var with different values exist") + global_set(MESSAGE_WRAPPER_INPUT) + set(cacheVar3 "3rd value" CACHE STRING "") + set(cacheVar3 "3rd value diff") + tribits_assert_cache_and_local_vars_same_value(cacheVar3) + unittest_compare_const(MESSAGE_WRAPPER_INPUT + "SEND_ERROR;ERROR: The cache variable cacheVar3 with the; cache var value '3rd value' is not the same value as the local; variable cacheVar3 with value '3rd value diff'!") + unset(cacheVar3 CACHE) + +endfunction() + + +# +# B) Test basic package processing and reading dependencies # @@ -255,8 +294,10 @@ unittest_initialize_vars() # Run the unit tests # +unittest_tribits_assert_cache_and_local_vars_same_value() + unittest_write_specialized_package_export_makefile_rtop_before_libs() unittest_write_specialized_package_export_makefile_rtop_after_libs() # Pass in the number of expected tests that must pass! -unittest_final_result(30) +unittest_final_result(33) diff --git a/tribits/core/package_arch/TribitsGeneralMacros.cmake b/tribits/core/package_arch/TribitsGeneralMacros.cmake index cf2a680cb..971052abe 100644 --- a/tribits/core/package_arch/TribitsGeneralMacros.cmake +++ b/tribits/core/package_arch/TribitsGeneralMacros.cmake @@ -426,3 +426,27 @@ function(tribits_trace_file_processing TYPE_IN PROCESSING_TYPE_IN FILE_PATH) endif() endfunction() + + +# @MACRO: tribits_assert_cache_and_local_vars_same_value() +# +# Asset that a cache variable and a possible local variable (if it exists) +# have the same value. +# +# Usage:: +# +# tribits_assert_cache_and_local_vars_same_value() +# +# If the local var ```` and the cache var ```` +# both exist but have different values, then ``message(SEND_ERROR ...)`` is +# called with an informative error message. +# +macro(tribits_assert_cache_and_local_vars_same_value cacheVarName) + set(cacheVarValue "$CACHE{${cacheVarName}}") + set(localValue "${${cacheVarName}}") + if (NOT localValue STREQUAL cacheVarValue) + message_wrapper(SEND_ERROR "ERROR: The cache variable ${cacheVarName} with the" + " cache var value '${cacheVarValue}' is not the same value as the local" + " variable ${cacheVarName} with value '${localValue}'!") + endif() +endmacro() diff --git a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake index 587698f7d..1da48dfce 100644 --- a/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake +++ b/tribits/core/package_arch/TribitsWriteClientExportFiles.cmake @@ -581,11 +581,13 @@ function(tribits_append_dependent_package_config_file_includes_and_enables packa "\n# Exported cache variables\n") if (NOT "${${packageName}_PARENT_PACKAGE}" STREQUAL "") foreach(exportedCacheVar IN LISTS ${${packageName}_PARENT_PACKAGE}_PKG_VARS_TO_EXPORT) + tribits_assert_cache_and_local_vars_same_value(${exportedCacheVar}) string(APPEND configFileStr "set(${exportedCacheVar} \"${${exportedCacheVar}}\")\n") endforeach() endif() foreach(exportedCacheVar IN LISTS ${packageName}_PKG_VARS_TO_EXPORT) + tribits_assert_cache_and_local_vars_same_value(${exportedCacheVar}) string(APPEND configFileStr "set(${exportedCacheVar} \"${${exportedCacheVar}}\")\n") endforeach() diff --git a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst index 3ad983471..c045c1962 100644 --- a/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst +++ b/tribits/doc/guides/TribitsMacroFunctionDocTemplate.rst @@ -14,6 +14,7 @@ @FUNCTION: tribits_add_test() + @MACRO: tribits_add_test_directories() + @FUNCTION: tribits_allow_missing_external_packages() + +@MACRO: tribits_assert_cache_and_local_vars_same_value() + @FUNCTION: tribits_configure_file() + @FUNCTION: tribits_copy_files_to_binary_dir() + @FUNCTION: tribits_ctest_driver() +