Browse Source

Merge topic 'package-dispatch-apple' into release-3.29

85d6d3b2e3 generate_apple_*_selection_file: Add option to capture errors
2149dbd379 generate_apple_architecture_selection_file: Document $(ARCHS_STANDARD) support
be642f6ed5 generate_apple_architecture_selection_file: Simplify signature
8959ad9db1 Tests/RunCMake/CMakePackage: Fix Apple architecture selection argument order
677f3d721b Tests/RunCMake/CMakePackage: Add architecture i386 for macOS on Xcode < 10

Acked-by: Kitware Robot <[email protected]>
Merge-request: !9349
Brad King 1 year ago
parent
commit
3135a99467

+ 76 - 18
Modules/CMakePackageConfigHelpers.cmake

@@ -210,6 +210,7 @@ Generating an Apple Platform Selection File
       [WATCHOS_SIMULATOR_INCLUDE_FILE <file>]
       [VISIONOS_INCLUDE_FILE <file>]
       [VISIONOS_SIMULATOR_INCLUDE_FILE <file>]
+      [ERROR_VARIABLE <variable>]
       )
 
   Write a file that includes an Apple-platform-specific ``.cmake`` file,
@@ -256,9 +257,16 @@ Generating an Apple Platform Selection File
   ``VISIONOS_SIMULATOR_INCLUDE_FILE <file>``
     File to include if the platform is visionOS Simulator.
 
+  ``ERROR_VARIABLE <variable>``
+    If the consuming project is built for an unsupported platform,
+    set ``<variable>`` to an error message.  The includer may use this
+    information to pretend the package was not found.  If this option
+    is not given, the default behavior is to issue a fatal error.
+
   If any of the optional include files is not specified, and the consuming
-  project is built for its corresponding platform, an error will be thrown
-  when including the generated file.
+  project is built for its corresponding platform, the generated file will
+  consider the platform to be unsupported.  The behavior is determined
+  by the ``ERROR_VARIABLE`` option.
 
 .. command:: generate_apple_architecture_selection_file
 
@@ -271,10 +279,11 @@ Generating an Apple Platform Selection File
     generate_apple_architecture_selection_file(<filename>
       INSTALL_DESTINATION <path>
       [INSTALL_PREFIX <path>]
-      [SINGLE_ARCHITECTURES <archs>
-       SINGLE_ARCHITECTURE_INCLUDE_FILES <files>]
-      [UNIVERSAL_ARCHITECTURES <archs>
+      [SINGLE_ARCHITECTURES <arch>...
+       SINGLE_ARCHITECTURE_INCLUDE_FILES <file>...]
+      [UNIVERSAL_ARCHITECTURES <arch>...
        UNIVERSAL_INCLUDE_FILE <file>]
+      [ERROR_VARIABLE <variable>]
       )
 
   Write a file that includes an Apple-architecture-specific ``.cmake`` file
@@ -292,27 +301,33 @@ Generating an Apple Platform Selection File
     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_INCLUDE_FILES``.
+  ``SINGLE_ARCHITECTURES <arch>...``
+    Architectures provided by entries of ``SINGLE_ARCHITECTURE_INCLUDE_FILES``.
 
-  ``SINGLE_ARCHITECTURE_INCLUDE_FILES <files>``
-    A :ref:`semicolon-separated list <CMake Language Lists>` of
-    architecture-specific files.  One of them will be loaded
+  ``SINGLE_ARCHITECTURE_INCLUDE_FILES <file>...``
+    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_INCLUDE_FILE``.
+  ``UNIVERSAL_ARCHITECTURES <arch>...``
+    Architectures provided by the ``UNIVERSAL_INCLUDE_FILE``.
+
+    The list may include ``$(ARCHS_STANDARD)`` to support consumption using
+    the :generator:`Xcode` generator, but the architectures should always
+    be listed individually too.
 
   ``UNIVERSAL_INCLUDE_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``.
 
+  ``ERROR_VARIABLE <variable>``
+    If the consuming project is built for an unsupported architecture,
+    set ``<variable>`` to an error message.  The includer may use this
+    information to pretend the package was not found.  If this option
+    is not given, the default behavior is to issue a fatal error.
+
 Example Generating Package Files
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -486,6 +501,7 @@ function(generate_apple_platform_selection_file _output_file)
     INSTALL_DESTINATION
     INSTALL_PREFIX
     ${_config_file_options}
+    ERROR_VARIABLE
     )
   set(_multi)
   cmake_parse_arguments(PARSE_ARGV 0 _gpsf "${_options}" "${_single}" "${_multi}")
@@ -499,8 +515,15 @@ function(generate_apple_platform_selection_file _output_file)
     set(maybe_INSTALL_PREFIX "")
   endif()
 
+  if(_gpsf_ERROR_VARIABLE)
+    set(_branch_INIT "set(\"${_gpsf_ERROR_VARIABLE}\" \"\")")
+  else()
+    set(_branch_INIT "")
+  endif()
+
+  set(_else ELSE)
   set(_have_relative 0)
-  foreach(_opt IN LISTS _config_file_options)
+  foreach(_opt IN LISTS _config_file_options _else)
     if(_gpsf_${_opt})
       set(_config_file "${_gpsf_${_opt}}")
       if(NOT IS_ABSOLUTE "${_config_file}")
@@ -508,6 +531,8 @@ function(generate_apple_platform_selection_file _output_file)
         set(_have_relative 1)
       endif()
       set(_branch_${_opt} "include(\"${_config_file}\")")
+    elseif(_gpsf_ERROR_VARIABLE)
+      set(_branch_${_opt} "set(\"${_gpsf_ERROR_VARIABLE}\" \"Platform not supported\")")
     else()
       set(_branch_${_opt} "message(FATAL_ERROR \"Platform not supported\")")
     endif()
@@ -526,12 +551,14 @@ function(generate_apple_architecture_selection_file _output_file)
   set(_single
     INSTALL_DESTINATION
     INSTALL_PREFIX
+    UNIVERSAL_INCLUDE_FILE
+    ERROR_VARIABLE
+    )
+  set(_multi
     SINGLE_ARCHITECTURES
     SINGLE_ARCHITECTURE_INCLUDE_FILES
     UNIVERSAL_ARCHITECTURES
-    UNIVERSAL_INCLUDE_FILE
     )
-  set(_multi)
   cmake_parse_arguments(PARSE_ARGV 0 _gasf "${_options}" "${_single}" "${_multi}")
 
   if(NOT _gasf_INSTALL_DESTINATION)
@@ -551,6 +578,30 @@ function(generate_apple_architecture_selection_file _output_file)
 
   set(_branch_code "")
 
+  if(_gasf_ERROR_VARIABLE)
+    string(APPEND _branch_code
+      "set(\"${_gasf_ERROR_VARIABLE}\" \"\")\n"
+      )
+  endif()
+
+  string(APPEND _branch_code
+    "\n"
+    "if(NOT CMAKE_OSX_ARCHITECTURES)\n"
+    )
+  if(_gasf_ERROR_VARIABLE)
+    string(APPEND _branch_code
+      "  set(\"${_gasf_ERROR_VARIABLE}\" \"CMAKE_OSX_ARCHITECTURES must be explicitly set for this package\")\n"
+      "  return()\n"
+      )
+  else()
+    string(APPEND _branch_code
+      "  message(FATAL_ERROR \"CMAKE_OSX_ARCHITECTURES must be explicitly set for this package\")\n"
+      )
+  endif()
+  string(APPEND _branch_code
+    "endif()\n"
+    )
+
   foreach(pair IN ZIP_LISTS _gasf_SINGLE_ARCHITECTURES _gasf_SINGLE_ARCHITECTURE_INCLUDE_FILES)
     set(arch "${pair_0}")
     set(config_file "${pair_1}")
@@ -587,6 +638,13 @@ function(generate_apple_architecture_selection_file _output_file)
     message(FATAL_ERROR "UNIVERSAL_ARCHITECTURES requires UNIVERSAL_INCLUDE_FILE")
   endif()
 
+  string(APPEND _branch_code "\n")
+  if(_gasf_ERROR_VARIABLE)
+    string(APPEND _branch_code "set(\"${_gasf_ERROR_VARIABLE}\" \"Architecture not supported\")")
+  else()
+    string(APPEND _branch_code "message(FATAL_ERROR \"Architecture not supported\")")
+  endif()
+
   configure_package_config_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/Internal/AppleArchitectureSelection.cmake.in" "${_output_file}"
     INSTALL_DESTINATION "${_gasf_INSTALL_DESTINATION}"
     ${maybe_INSTALL_PREFIX}

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

@@ -1,8 +1,2 @@
 @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")

+ 2 - 1
Modules/Internal/ApplePlatformSelection.cmake.in

@@ -1,6 +1,7 @@
 @PACKAGE_INIT@
 
 string(TOLOWER "${CMAKE_OSX_SYSROOT}" _CMAKE_OSX_SYSROOT_LOWER)
+@_branch_INIT@
 if(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)iphonesimulator")
   @_branch_IOS_SIMULATOR_INCLUDE_FILE@
 elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)iphoneos")
@@ -20,5 +21,5 @@ elseif(_CMAKE_OSX_SYSROOT_LOWER MATCHES "(^|/)xros")
 elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
   @_branch_MACOS_INCLUDE_FILE@
 else()
-  message(FATAL_ERROR "Platform not supported")
+  @_branch_ELSE@
 endif()

+ 23 - 4
Tests/RunCMake/CMakePackage/RunCMakeTest.cmake

@@ -37,6 +37,9 @@ function(apple_import platform system_name archs sysroot)
     ${maybe_CMAKE_BUILD_TYPE}
     )
   set(RunCMake_TEST_NO_CLEAN 1)
+  if(apple_import_no_build)
+    return()
+  endif()
   run_cmake_command(apple-import-${platform}-build ${CMAKE_COMMAND} --build . --config Release)
 endfunction()
 
@@ -50,10 +53,17 @@ 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(tvos_sim_archs "x86_64;arm64")
     set(watch_sim_archs "x86_64")
     set(select_archs "arm64;x86_64")
-  else()
+  elseif(CMake_TEST_XCODE_VERSION VERSION_GREATER_EQUAL 10)
     set(macos_archs "x86_64")
+    set(tvos_sim_archs "x86_64")
+    set(watch_sim_archs "i386")
+    set(select_archs "")
+  else()
+    set(macos_archs "i386;x86_64")
+    set(tvos_sim_archs "x86_64")
     set(watch_sim_archs "i386")
     set(select_archs "")
   endif()
@@ -81,12 +91,13 @@ if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
       apple_export(ios-simulator-${arch} iOS "${arch}" iphonesimulator)
     endforeach()
   endif()
-
-  apple_export(tvos-simulator tvOS "${macos_archs}" appletvsimulator)
+  apple_export(tvos-simulator tvOS "${tvos_sim_archs}" appletvsimulator)
   if(enable_visionos)
     apple_export(visionos-simulator visionOS "${macos_archs}" xrsimulator)
   endif()
   apple_export(watchos-simulator watchOS "${watch_sim_archs}" watchsimulator)
+  apple_export(unsupported-capture Darwin "${macos_archs}" macosx)
+  apple_export(unsupported-fatal Darwin "${macos_archs}" macosx)
 
   apple_import(macos Darwin "${macos_archs}" macosx)
   apple_import(ios iOS "arm64" iphoneos)
@@ -96,14 +107,22 @@ 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(RunCMake_GENERATOR STREQUAL "Xcode")
+    apple_import(ios-simulator-xcode iOS "$(ARCHS_STANDARD)" iphonesimulator)
+  endif()
   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)
+  apple_import(tvos-simulator tvOS "${tvos_sim_archs}" appletvsimulator)
   if(enable_visionos)
     apple_import(visionos-simulator visionOS "${macos_archs}" xrsimulator)
   endif()
   apple_import(watchos-simulator watchOS "${watch_sim_archs}" watchsimulator)
+  set(apple_import_no_build 1)
+  apple_import(unsupported-capture Darwin "${macos_archs}" macosx)
+  apple_import(unsupported-fatal-platform Darwin "${macos_archs}" macosx)
+  apple_import(unsupported-fatal-architecture Darwin "${macos_archs}" macosx)
+  unset(apple_import_no_build)
 endif()

+ 6 - 3
Tests/RunCMake/CMakePackage/apple-export-ios-simulator-common.cmake

@@ -1,12 +1,15 @@
 include(apple-export-common.cmake)
 
 if(IOS_SIMULATOR_SELECT_ARCHS)
+  set(IOS_SIMULATOR_SELECT_FILES "${IOS_SIMULATOR_SELECT_ARCHS}")
+  list(TRANSFORM IOS_SIMULATOR_SELECT_FILES PREPEND "lib/ios-simulator-")
+  list(TRANSFORM IOS_SIMULATOR_SELECT_FILES APPEND "/cmake/mylib/mylib-targets.cmake")
   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_INCLUDE_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}"
+    SINGLE_ARCHITECTURES ${IOS_SIMULATOR_SELECT_ARCHS}
+    SINGLE_ARCHITECTURE_INCLUDE_FILES ${IOS_SIMULATOR_SELECT_FILES}
+    UNIVERSAL_ARCHITECTURES ${IOS_SIMULATOR_SELECT_ARCHS} $(ARCHS_STANDARD)
     UNIVERSAL_INCLUDE_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)

+ 16 - 0
Tests/RunCMake/CMakePackage/apple-export-unsupported-capture.cmake

@@ -0,0 +1,16 @@
+include(apple-common.cmake)
+
+include(CMakePackageConfigHelpers)
+generate_apple_platform_selection_file(bad-platform-capture-config-install.cmake
+  INSTALL_DESTINATION lib/cmake/bad-platform-capture
+  INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
+  ERROR_VARIABLE bad-platform-capture_unsupported
+  )
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bad-platform-capture-config-install.cmake DESTINATION lib/cmake/bad-platform-capture RENAME bad-platform-capture-config.cmake)
+
+generate_apple_architecture_selection_file(bad-arch-capture-config-install.cmake
+  INSTALL_DESTINATION lib/cmake/bad-arch-capture
+  INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
+  ERROR_VARIABLE bad-arch-capture_unsupported
+  )
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bad-arch-capture-config-install.cmake DESTINATION lib/cmake/bad-arch-capture RENAME bad-arch-capture-config.cmake)

+ 14 - 0
Tests/RunCMake/CMakePackage/apple-export-unsupported-fatal.cmake

@@ -0,0 +1,14 @@
+include(apple-common.cmake)
+
+include(CMakePackageConfigHelpers)
+generate_apple_platform_selection_file(bad-platform-fatal-config-install.cmake
+  INSTALL_DESTINATION lib/cmake/bad-platform-fatal
+  INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
+  )
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bad-platform-fatal-config-install.cmake DESTINATION lib/cmake/bad-platform-fatal RENAME bad-platform-fatal-config.cmake)
+
+generate_apple_architecture_selection_file(bad-arch-fatal-config-install.cmake
+  INSTALL_DESTINATION lib/cmake/bad-arch-fatal
+  INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
+  )
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/bad-arch-fatal-config-install.cmake DESTINATION lib/cmake/bad-arch-fatal RENAME bad-arch-fatal-config.cmake)

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-ios-simulator-xcode-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-xcode.cmake

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

+ 2 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-capture-stdout.txt

@@ -0,0 +1,2 @@
+-- Platform not supported
+-- Architecture not supported

+ 11 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-capture.cmake

@@ -0,0 +1,11 @@
+include(apple-common.cmake)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER)
+find_package(bad-platform-capture CONFIG REQUIRED)
+find_package(bad-arch-capture CONFIG REQUIRED)
+
+# The above packages capture their own error messages.
+# In real packages they would then set _FOUND to false.
+# For testing here, just print the messages.
+message(STATUS "${bad-platform-capture_unsupported}")
+message(STATUS "${bad-arch-capture_unsupported}")

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-fatal-architecture-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-fatal-architecture-stderr.txt

@@ -0,0 +1,6 @@
+^CMake Error at [^
+]*/Tests/RunCMake/CMakePackage/apple-install/lib/cmake/bad-arch-fatal/bad-arch-fatal-config.cmake:[0-9]+ \(message\):
+  Architecture not supported
+Call Stack \(most recent call first\):
+  apple-import-unsupported-fatal-architecture\.cmake:[0-9]+ \(find_package\)
+  CMakeLists\.txt:[0-9]+ \(include\)$

+ 4 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-fatal-architecture.cmake

@@ -0,0 +1,4 @@
+include(apple-common.cmake)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER)
+find_package(bad-arch-fatal CONFIG REQUIRED)

+ 1 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-fatal-platform-result.txt

@@ -0,0 +1 @@
+1

+ 6 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-fatal-platform-stderr.txt

@@ -0,0 +1,6 @@
+^CMake Error at [^
+]*/Tests/RunCMake/CMakePackage/apple-install/lib/cmake/bad-platform-fatal/bad-platform-fatal-config.cmake:[0-9]+ \(message\):
+  Platform not supported
+Call Stack \(most recent call first\):
+  apple-import-unsupported-fatal-platform\.cmake:[0-9]+ \(find_package\)
+  CMakeLists\.txt:[0-9]+ \(include\)$

+ 4 - 0
Tests/RunCMake/CMakePackage/apple-import-unsupported-fatal-platform.cmake

@@ -0,0 +1,4 @@
+include(apple-common.cmake)
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER)
+find_package(bad-platform-fatal CONFIG REQUIRED)