Browse Source

Merge topic 'package-dispatch-apple'

4ac5a2f866 CMakePackageConfigHelpers: Add generate_apple_architecture_selection_file()
b9f81ee9f9 CMakePackageConfigHelpers: Remove outdated documentation summary paragraph
68a03cf3d4 generate_apple_platform_selection_file: Add INSTALL_PREFIX option
ff21f0f70f Tests: Verify generate_apple_platform_selection_file file paths

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !9092
Brad King 2 years ago
parent
commit
e6cd118f02
22 changed files with 218 additions and 6 deletions
  1. 7 0
      Help/release/dev/package-dispatch-apple.rst
  2. 144 4
      Modules/CMakePackageConfigHelpers.cmake
  3. 8 0
      Modules/Internal/AppleArchitectureSelection.cmake.in
  4. 20 0
      Tests/RunCMake/CMakePackage/RunCMakeTest.cmake
  5. 8 1
      Tests/RunCMake/CMakePackage/apple-export-common.cmake
  6. 2 0
      Tests/RunCMake/CMakePackage/apple-export-ios-simulator-arm64.cmake
  7. 13 0
      Tests/RunCMake/CMakePackage/apple-export-ios-simulator-common.cmake
  8. 2 0
      Tests/RunCMake/CMakePackage/apple-export-ios-simulator-x86_64.cmake
  9. 1 1
      Tests/RunCMake/CMakePackage/apple-export-ios-simulator.cmake
  10. 1 0
      Tests/RunCMake/CMakePackage/apple-import-ios-simulator-arm64-stdout.txt
  11. 1 0
      Tests/RunCMake/CMakePackage/apple-import-ios-simulator-arm64.cmake
  12. 1 0
      Tests/RunCMake/CMakePackage/apple-import-ios-simulator-stdout.txt
  13. 1 0
      Tests/RunCMake/CMakePackage/apple-import-ios-simulator-x86_64-stdout.txt
  14. 1 0
      Tests/RunCMake/CMakePackage/apple-import-ios-simulator-x86_64.cmake
  15. 1 0
      Tests/RunCMake/CMakePackage/apple-import-ios-stdout.txt
  16. 1 0
      Tests/RunCMake/CMakePackage/apple-import-macos-stdout.txt
  17. 1 0
      Tests/RunCMake/CMakePackage/apple-import-tvos-simulator-stdout.txt
  18. 1 0
      Tests/RunCMake/CMakePackage/apple-import-tvos-stdout.txt
  19. 1 0
      Tests/RunCMake/CMakePackage/apple-import-visionos-simulator-stdout.txt
  20. 1 0
      Tests/RunCMake/CMakePackage/apple-import-visionos-stdout.txt
  21. 1 0
      Tests/RunCMake/CMakePackage/apple-import-watchos-simulator-stdout.txt
  22. 1 0
      Tests/RunCMake/CMakePackage/apple-import-watchos-stdout.txt

+ 7 - 0
Help/release/dev/package-dispatch-apple.rst

@@ -0,0 +1,7 @@
+package-dispatch-apple
+----------------------
+
+* The :module:`CMakePackageConfigHelpers` module gained a new
+  :command:`generate_apple_architecture_selection_file` function, which can be
+  used to generate a file that includes an architecture-specific implementation
+  of a package for an Apple platform.

+ 144 - 4
Modules/CMakePackageConfigHelpers.cmake

@@ -8,9 +8,6 @@ CMakePackageConfigHelpers
 Helpers functions for creating config files that can be included by other
 projects to find and use a package.
 
-Adds the :command:`configure_package_config_file()` and
-:command:`write_basic_package_version_file()` commands.
-
 Generating a Package Configuration File
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -203,6 +200,7 @@ Generating an Apple Platform Selection File
 
     generate_apple_platform_selection_file(<filename>
       INSTALL_DESTINATION <path>
+      [INSTALL_PREFIX <path>]
       [MACOS_CONFIG_FILE <file>]
       [IOS_CONFIG_FILE <file>]
       [IOS_SIMULATOR_CONFIG_FILE <file>]
@@ -221,7 +219,15 @@ Generating an Apple Platform Selection File
   built for any Apple platform can use them.
 
   ``INSTALL_DESTINATION <path>``
-    Path that the file will be installed to.
+    Path to which the file will be installed by the caller, e.g., via
+    :command:`install(FILES)`.  The path may be either relative to the
+    ``INSTALL_PREFIX`` or absolute.
+
+  ``INSTALL_PREFIX <path>``
+    Path prefix to which the package will be installed by the caller.
+    The ``<path>`` argument must be an absolute path.  If this argument
+    is not passed, the :variable:`CMAKE_INSTALL_PREFIX` variable will be
+    used instead.
 
   ``MACOS_CONFIG_FILE <file>``
     File to include if the platform is macOS.
@@ -254,6 +260,59 @@ Generating an Apple Platform Selection File
   project is built for their corresponding platform, an error will be thrown
   when including the generated file.
 
+.. command:: generate_apple_architecture_selection_file
+
+  .. versionadded:: 3.29
+
+  Create an Apple architecture selection file:
+
+  .. code-block:: cmake
+
+    generate_apple_architecture_selection_file(<filename>
+      INSTALL_DESTINATION <path>
+      [INSTALL_PREFIX <path>]
+      [SINGLE_ARCHITECTURES <archs>
+       SINGLE_ARCHITECTURE_CONFIG_FILES <files>]
+      [UNIVERSAL_ARCHITECTURES <archs>
+       UNIVERSAL_CONFIG_FILE <file>]
+      )
+
+  Writes a file for use as ``<PackageName>Config.cmake`` on Apple platforms
+  which can include an architecture-specific ``<PackageName>Config.cmake``
+  from a different directory based on :variable:`CMAKE_OSX_ARCHITECTURES`.
+
+  ``INSTALL_DESTINATION <path>``
+    Path to which the file will be installed by the caller, e.g., via
+    :command:`install(FILES)`.  The path may be either relative to the
+    ``INSTALL_PREFIX`` or absolute.
+
+  ``INSTALL_PREFIX <path>``
+    Path prefix to which the package will be installed by the caller.
+    The ``<path>`` argument must be an absolute path.  If this argument
+    is not passed, the :variable:`CMAKE_INSTALL_PREFIX` variable will be
+    used instead.
+
+  ``SINGLE_ARCHITECTURES <archs>``
+    A :ref:`semicolon-separated list <CMake Language Lists>` of
+    architectures provided by entries of
+    ``SINGLE_ARCHITECTURE_CONFIG_FILES``.
+
+  ``SINGLE_ARCHITECTURE_CONFIG_FILES <files>``
+    A :ref:`semicolon-separated list <CMake Language Lists>` of
+    architecture-specific files.  One of them will be loaded
+    when :variable:`CMAKE_OSX_ARCHITECTURES` contains a single
+    architecture matching the corresponding entry of
+    ``SINGLE_ARCHITECTURES``.
+
+  ``UNIVERSAL_ARCHITECTURES <archs>``
+    A :ref:`semicolon-separated list <CMake Language Lists>` of
+    architectures provided by the ``UNIVERSAL_CONFIG_FILE``.
+
+  ``UNIVERSAL_CONFIG_FILE <file>``
+    A file to load when :variable:`CMAKE_OSX_ARCHITECTURES` contains
+    a (non-strict) subset of the ``UNIVERSAL_ARCHITECTURES`` and
+    does not match any one of the ``SINGLE_ARCHITECTURES``.
+
 Example Generating Package Files
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -425,6 +484,7 @@ function(generate_apple_platform_selection_file _output_file)
   set(_options)
   set(_single
     INSTALL_DESTINATION
+    INSTALL_PREFIX
     ${_config_file_options}
     )
   set(_multi)
@@ -433,6 +493,11 @@ function(generate_apple_platform_selection_file _output_file)
   if(NOT _gpsf_INSTALL_DESTINATION)
     message(FATAL_ERROR "No INSTALL_DESTINATION given to generate_apple_platform_selection_file()")
   endif()
+  if(_gpsf_INSTALL_PREFIX)
+    set(maybe_INSTALL_PREFIX INSTALL_PREFIX ${_gpsf_INSTALL_PREFIX})
+  else()
+    set(maybe_INSTALL_PREFIX "")
+  endif()
 
   set(_have_relative 0)
   foreach(_opt IN LISTS _config_file_options)
@@ -450,6 +515,81 @@ function(generate_apple_platform_selection_file _output_file)
 
   configure_package_config_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/Internal/ApplePlatformSelection.cmake.in" "${_output_file}"
     INSTALL_DESTINATION "${_gpsf_INSTALL_DESTINATION}"
+    ${maybe_INSTALL_PREFIX}
+    NO_SET_AND_CHECK_MACRO
+    NO_CHECK_REQUIRED_COMPONENTS_MACRO
+    )
+endfunction()
+
+function(generate_apple_architecture_selection_file _output_file)
+  set(_options)
+  set(_single
+    INSTALL_DESTINATION
+    INSTALL_PREFIX
+    SINGLE_ARCHITECTURES
+    SINGLE_ARCHITECTURE_CONFIG_FILES
+    UNIVERSAL_ARCHITECTURES
+    UNIVERSAL_CONFIG_FILE
+    )
+  set(_multi)
+  cmake_parse_arguments(PARSE_ARGV 0 _gasf "${_options}" "${_single}" "${_multi}")
+
+  if(NOT _gasf_INSTALL_DESTINATION)
+    message(FATAL_ERROR "No INSTALL_DESTINATION given to generate_apple_platform_selection_file()")
+  endif()
+  if(_gasf_INSTALL_PREFIX)
+    set(maybe_INSTALL_PREFIX INSTALL_PREFIX ${_gasf_INSTALL_PREFIX})
+  else()
+    set(maybe_INSTALL_PREFIX "")
+  endif()
+
+  list(LENGTH _gasf_SINGLE_ARCHITECTURES _gasf_SINGLE_ARCHITECTURES_len)
+  list(LENGTH _gasf_SINGLE_ARCHITECTURE_CONFIG_FILES _gasf_SINGLE_ARCHITECTURE_CONFIG_FILES_len)
+  if(NOT _gasf_SINGLE_ARCHITECTURES_len EQUAL _gasf_SINGLE_ARCHITECTURE_CONFIG_FILES_len)
+    message(FATAL_ERROR "SINGLE_ARCHITECTURES and SINGLE_ARCHITECTURE_CONFIG_FILES do not have the same number of entries.")
+  endif()
+
+  set(_branch_code "")
+
+  foreach(pair IN ZIP_LISTS _gasf_SINGLE_ARCHITECTURES _gasf_SINGLE_ARCHITECTURE_CONFIG_FILES)
+    set(arch "${pair_0}")
+    set(config_file "${pair_1}")
+    if(NOT IS_ABSOLUTE "${config_file}")
+      string(PREPEND config_file [[${PACKAGE_PREFIX_DIR}/]])
+    endif()
+    string(APPEND _branch_code
+      "\n"
+      "if(CMAKE_OSX_ARCHITECTURES STREQUAL \"${arch}\")\n"
+      "  include(\"${config_file}\")\n"
+      "  return()\n"
+      "endif()\n"
+      )
+  endforeach()
+
+  if(_gasf_UNIVERSAL_ARCHITECTURES AND _gasf_UNIVERSAL_CONFIG_FILE)
+    string(JOIN " " universal_archs "${_gasf_UNIVERSAL_ARCHITECTURES}")
+    set(config_file "${_gasf_UNIVERSAL_CONFIG_FILE}")
+    if(NOT IS_ABSOLUTE "${config_file}")
+      string(PREPEND config_file [[${PACKAGE_PREFIX_DIR}/]])
+    endif()
+    string(APPEND _branch_code
+      "\n"
+      "set(_cmake_apple_archs \"\${CMAKE_OSX_ARCHITECTURES}\")\n"
+      "list(REMOVE_ITEM _cmake_apple_archs ${universal_archs})\n"
+      "if(NOT _cmake_apple_archs)\n"
+      "  include(\"${config_file}\")\n"
+      "  return()\n"
+      "endif()\n"
+      )
+  elseif(_gasf_UNIVERSAL_ARCHITECTURES)
+    message(FATAL_ERROR "UNIVERSAL_CONFIG_FILE requires UNIVERSAL_ARCHITECTURES")
+  elseif(_gasf_UNIVERSAL_CONFIG_FILE)
+    message(FATAL_ERROR "UNIVERSAL_ARCHITECTURES requires UNIVERSAL_CONFIG_FILE")
+  endif()
+
+  configure_package_config_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/Internal/AppleArchitectureSelection.cmake.in" "${_output_file}"
+    INSTALL_DESTINATION "${_gasf_INSTALL_DESTINATION}"
+    ${maybe_INSTALL_PREFIX}
     NO_SET_AND_CHECK_MACRO
     NO_CHECK_REQUIRED_COMPONENTS_MACRO
     )

+ 8 - 0
Modules/Internal/AppleArchitectureSelection.cmake.in

@@ -0,0 +1,8 @@
+@PACKAGE_INIT@
+
+if(NOT CMAKE_OSX_ARCHITECTURES)
+  message(FATAL_ERROR "CMAKE_OSX_ARCHITECTURES must be explicitly set for this package")
+endif()
+@_branch_code@
+
+message(FATAL_ERROR "Architecture not supported")

+ 20 - 0
Tests/RunCMake/CMakePackage/RunCMakeTest.cmake

@@ -7,16 +7,23 @@ endif()
 function(apple_export platform system_name archs sysroot)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/apple-export-${platform}-build)
   string(REPLACE ";" "\\;" archs "${archs}")
+  if(select_archs)
+    string(REPLACE ";" "\\\\;" maybe_IOS_SIMULATOR_SELECT_ARCHS "-DIOS_SIMULATOR_SELECT_ARCHS=${select_archs}")
+  endif()
   run_cmake_with_options(apple-export-${platform}
     "-DCMAKE_SYSTEM_NAME=${system_name}"
     "-DCMAKE_OSX_ARCHITECTURES=${archs}"
     "-DCMAKE_OSX_SYSROOT=${sysroot}"
     "-DCMAKE_INSTALL_PREFIX=${apple_install}"
     ${maybe_CMAKE_BUILD_TYPE}
+    ${maybe_IOS_SIMULATOR_SELECT_ARCHS}
     )
   set(RunCMake_TEST_NO_CLEAN 1)
   run_cmake_command(apple-export-${platform}-build ${CMAKE_COMMAND} --build . --config Release)
   run_cmake_command(apple-export-${platform}-install ${CMAKE_COMMAND} --install . --config Release)
+  file(APPEND "${apple_install}/lib/${platform}/cmake/mylib/mylib-targets.cmake" "\n"
+    "message(STATUS \"loaded: '\${CMAKE_CURRENT_LIST_FILE}'\")\n"
+    )
 endfunction()
 
 function(apple_import platform system_name archs sysroot)
@@ -44,9 +51,11 @@ if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
   if(CMake_TEST_XCODE_VERSION VERSION_GREATER_EQUAL 12)
     set(macos_archs "x86_64;arm64")
     set(watch_sim_archs "x86_64")
+    set(select_archs "arm64;x86_64")
   else()
     set(macos_archs "x86_64")
     set(watch_sim_archs "i386")
+    set(select_archs "")
   endif()
 
   if(CMake_TEST_XCODE_VERSION VERSION_GREATER_EQUAL 9)
@@ -68,6 +77,12 @@ if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
   endif()
   apple_export(watchos watchOS "${watch_archs}" watchos)
   apple_export(ios-simulator iOS "${macos_archs}" iphonesimulator)
+  if(select_archs)
+    foreach(arch IN LISTS macos_archs)
+      apple_export(ios-simulator-${arch} iOS "${arch}" iphonesimulator)
+    endforeach()
+  endif()
+
   apple_export(tvos-simulator tvOS "${macos_archs}" appletvsimulator)
   if(enable_visionos)
     apple_export(visionos-simulator visionOS "${macos_archs}" xrsimulator)
@@ -82,6 +97,11 @@ if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
   endif()
   apple_import(watchos watchOS "${watch_archs}" watchos)
   apple_import(ios-simulator iOS "${macos_archs}" iphonesimulator)
+  if(select_archs)
+    foreach(arch IN LISTS macos_archs)
+      apple_import(ios-simulator-${arch} iOS "${arch}" iphonesimulator)
+    endforeach()
+  endif()
   apple_import(tvos-simulator tvOS "${macos_archs}" appletvsimulator)
   if(enable_visionos)
     apple_import(visionos-simulator visionOS "${macos_archs}" xrsimulator)

+ 8 - 1
Tests/RunCMake/CMakePackage/apple-export-common.cmake

@@ -6,12 +6,19 @@ install(TARGETS mylib EXPORT mylib-targets FILE_SET HEADERS ARCHIVE DESTINATION
 
 install(EXPORT mylib-targets DESTINATION lib/${platform_name}/cmake/mylib)
 
+if(IOS_SIMULATOR_SELECT_ARCHS)
+  set(IOS_SIMULATOR_CONFIG_FILE lib/ios-simulator/cmake/mylib/mylib-select-arch.cmake)
+else()
+  set(IOS_SIMULATOR_CONFIG_FILE lib/ios-simulator/cmake/mylib/mylib-targets.cmake)
+endif()
+
 include(CMakePackageConfigHelpers)
 generate_apple_platform_selection_file(mylib-config-install.cmake
   INSTALL_DESTINATION lib/cmake/mylib
+  INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
   MACOS_CONFIG_FILE lib/macos/cmake/mylib/mylib-targets.cmake
   IOS_CONFIG_FILE lib/ios/cmake/mylib/mylib-targets.cmake
-  IOS_SIMULATOR_CONFIG_FILE lib/ios-simulator/cmake/mylib/mylib-targets.cmake
+  IOS_SIMULATOR_CONFIG_FILE ${IOS_SIMULATOR_CONFIG_FILE}
   TVOS_CONFIG_FILE lib/tvos/cmake/mylib/mylib-targets.cmake
   TVOS_SIMULATOR_CONFIG_FILE lib/tvos-simulator/cmake/mylib/mylib-targets.cmake
   VISIONOS_CONFIG_FILE lib/watchos/cmake/mylib/mylib-targets.cmake

+ 2 - 0
Tests/RunCMake/CMakePackage/apple-export-ios-simulator-arm64.cmake

@@ -0,0 +1,2 @@
+set(platform_name ios-simulator-arm64)
+include(apple-export-ios-simulator-common.cmake)

+ 13 - 0
Tests/RunCMake/CMakePackage/apple-export-ios-simulator-common.cmake

@@ -0,0 +1,13 @@
+include(apple-export-common.cmake)
+
+if(IOS_SIMULATOR_SELECT_ARCHS)
+  generate_apple_architecture_selection_file(mylib-select-arch-install.cmake
+    INSTALL_DESTINATION lib/ios-simulator/cmake/mylib
+    INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
+    SINGLE_ARCHITECTURES "${IOS_SIMULATOR_SELECT_ARCHS}"
+    SINGLE_ARCHITECTURE_CONFIG_FILES "lib/ios-simulator-arm64/cmake/mylib/mylib-targets.cmake;lib/ios-simulator-x86_64/cmake/mylib/mylib-targets.cmake"
+    UNIVERSAL_ARCHITECTURES "${IOS_SIMULATOR_SELECT_ARCHS}"
+    UNIVERSAL_CONFIG_FILE "lib/ios-simulator/cmake/mylib/mylib-targets.cmake"
+    )
+  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mylib-select-arch-install.cmake DESTINATION lib/ios-simulator/cmake/mylib RENAME mylib-select-arch.cmake)
+endif()

+ 2 - 0
Tests/RunCMake/CMakePackage/apple-export-ios-simulator-x86_64.cmake

@@ -0,0 +1,2 @@
+set(platform_name ios-simulator-x86_64)
+include(apple-export-ios-simulator-common.cmake)

+ 1 - 1
Tests/RunCMake/CMakePackage/apple-export-ios-simulator.cmake

@@ -1,2 +1,2 @@
 set(platform_name ios-simulator)
-include(apple-export-common.cmake)
+include(apple-export-ios-simulator-common.cmake)

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-ios-simulator-arm64-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/ios-simulator-arm64/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-ios-simulator-arm64.cmake

@@ -0,0 +1 @@
+include(apple-import-common.cmake)

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-ios-simulator-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/ios-simulator/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-ios-simulator-x86_64-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/ios-simulator-x86_64/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-ios-simulator-x86_64.cmake

@@ -0,0 +1 @@
+include(apple-import-common.cmake)

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-ios-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/ios/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-macos-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/macos/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-tvos-simulator-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/tvos-simulator/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-tvos-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/tvos/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-visionos-simulator-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/visionos-simulator/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-visionos-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/visionos/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-watchos-simulator-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/watchos-simulator/cmake/mylib/mylib-targets.cmake'

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-watchos-stdout.txt

@@ -0,0 +1 @@
+loaded: '[^']*/Tests/RunCMake/CMakePackage/apple-install/lib/watchos/cmake/mylib/mylib-targets.cmake'