浏览代码

add macro check_required_components() to configure_package_config_file()

As discussed on cmake-developers, this patch adds a macro
check_required_components() to the file configured via
configure_package_config_file(), so for proper handling
of components in Config.cmake files users can simply call

check_required_components(PackageName)

and this will do the right thing.

Alex
Alex Neundorf 13 年之前
父节点
当前提交
d81d83c218

+ 34 - 4
Modules/CMakePackageConfigHelpers.cmake

@@ -2,7 +2,8 @@
 #
 #    CONFIGURE_PACKAGE_CONFIG_FILE(<input> <output> INSTALL_DESTINATION <path>
 #                                                   [PATH_VARS <var1> <var2> ... <varN>]
-#                                                   [NO_SET_AND_CHECK_MACRO] )
+#                                                   [NO_SET_AND_CHECK_MACRO]
+#                                                   [NO_CHECK_REQUIRED_COMPONENTS_MACRO])
 #
 # CONFIGURE_PACKAGE_CONFIG_FILE() should be used instead of the plain
 # CONFIGURE_FILE() command when creating the <Name>Config.cmake or <Name>-config.cmake
@@ -49,8 +50,10 @@
 # For absolute locations it works only if the absolute location is a subdirectory
 # of CMAKE_INSTALL_PREFIX.
 #
-# By default configure_package_config_file() also generates a macro set_and_check()
-# into the FooConfig.cmake file. This should be used instead of the normal set()
+# By default configure_package_config_file() also generates two helper macros,
+# set_and_check() and check_required_components() into the FooConfig.cmake file.
+#
+# set_and_check() should be used instead of the normal set()
 # command for setting directories and file locations. Additionally to setting the
 # variable it also checks that the referenced file or directory actually exists
 # and fails with a FATAL_ERROR otherwise. This makes sure that the created
@@ -58,6 +61,16 @@
 # When using the NO_SET_AND_CHECK_MACRO, this macro is not generated into the
 # FooConfig.cmake file.
 #
+# check_required_components(<package_name>) should be called at the end of the
+# FooConfig.cmake file if the package supports components.
+# This macro checks whether all requested, non-optional components have been found,
+# and if this is not the case, sets the Foo_FOUND variable to FALSE, so that the package
+# is considered to be not found.
+# It does that by testing the Foo_<Component>_FOUND variables for all requested
+# required components.
+# When using the NO_CHECK_REQUIRED_COMPONENTS option, this macro is not generated
+# into the FooConfig.cmake file.
+#
 # For an example see below the documentation for WRITE_BASIC_PACKAGE_VERSION_FILE().
 #
 #
@@ -114,6 +127,8 @@
 #   ...
 #   set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
 #   set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
+#
+#   check_required_components(Foo)
 
 
 #=============================================================================
@@ -139,7 +154,7 @@ endmacro()
 
 
 function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
-  set(options NO_SET_AND_CHECK_MACRO)
+  set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO)
   set(oneValueArgs INSTALL_DESTINATION )
   set(multiValueArgs PATH_VARS )
 
@@ -189,6 +204,21 @@ endmacro()
 ")
   endif()
 
+
+  if(NOT CCF_NO_CHECK_REQUIRED_COMPONENTS_MACRO)
+    set(PACKAGE_INIT "${PACKAGE_INIT}
+macro(check_required_components _NAME)
+  foreach(comp \${\${_NAME}_FIND_COMPONENTS})
+    if(NOT \${_NAME}_\${comp}_FOUND)
+      if(\${_NAME}_FIND_REQUIRED_\${comp})
+        set(\${_NAME}_FOUND FALSE)
+      endif()
+    endif()
+  endforeach(comp)
+endmacro()
+")
+  endif()
+
   set(PACKAGE_INIT "${PACKAGE_INIT}
 ####################################################################################")
 

+ 10 - 0
Tests/FindPackageTest/CMakeLists.txt

@@ -336,6 +336,8 @@ configure_package_config_file(RelocatableConfig.cmake.in "${CMAKE_CURRENT_BINARY
                               PATH_VARS INCLUDE_INSTALL_DIR SHARE_INSTALL_DIR CURRENT_BUILD_DIR
                              )
 
+set(Relocatable_FIND_COMPONENTS AComp BComp CComp)
+set(Relocatable_FIND_REQUIRED_BComp 1)
 include("${CMAKE_CURRENT_BINARY_DIR}/RelocatableConfig.cmake")
 
 if(NOT "${RELOC_INCLUDE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/include")
@@ -350,6 +352,14 @@ if(NOT "${RELOC_BUILD_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
   message(SEND_ERROR "RELOC_BUILD_DIR set by configure_package_config_file() is set to \"${RELOC_BUILD_DIR}\" (expected \"${CMAKE_CURRENT_BINARY_DIR}\")")
 endif()
 
+if(NOT DEFINED Relocatable_FOUND)
+  message(SEND_ERROR "Relocatable_FOUND not defined !")
+endif()
+
+if(Relocatable_FOUND)
+  message(SEND_ERROR "Relocatable_FOUND set to TRUE !")
+endif()
+
 #-----------------------------------------------------------------------------
 # Test write_basic_config_version_file().
 

+ 6 - 0
Tests/FindPackageTest/RelocatableConfig.cmake.in

@@ -3,3 +3,9 @@
 set(RELOC_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
 set(RELOC_SHARE_DIR "@PACKAGE_SHARE_INSTALL_DIR@")
 set_and_check(RELOC_BUILD_DIR "@PACKAGE_CURRENT_BUILD_DIR@")
+
+set(Relocatable_AComp_FOUND TRUE)
+set(Relocatable_BComp_FOUND FALSE)
+set(Relocatable_CComp_FOUND FALSE)
+
+check_required_components(Relocatable)