Browse Source

find_library(): Add support for .xcframework

Issue: #21752
Kyle Edwards 2 years ago
parent
commit
9bf8f7de06

+ 4 - 0
Help/command/find_library.rst

@@ -60,6 +60,10 @@ path to the framework ``<fullPath>/A.framework``.  When a full path to a
 framework is used as a library, CMake will use a ``-framework A``, and a
 ``-F<fullPath>`` to link the framework to the target.
 
+.. versionadded:: 3.28
+
+  The library found can now be a ``.xcframework`` folder.
+
 If the :variable:`CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX` variable is set all
 search paths will be tested as normal, with the suffix appended, and with
 all matches of ``lib/`` replaced with

+ 5 - 0
Help/release/dev/xcframework-find-library.rst

@@ -0,0 +1,5 @@
+xcframework-find-library
+------------------------
+
+* The :command:`find_library` command can now find ``.xcframework`` folders on
+  Apple platforms.

+ 16 - 0
Source/cmFindLibraryCommand.cxx

@@ -558,6 +558,14 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
   // Search for all names in each search path.
   for (std::string const& d : this->SearchPaths) {
     for (std::string const& n : this->Names) {
+      fwPath = cmStrCat(d, n, ".xcframework");
+      if (cmSystemTools::FileIsDirectory(fwPath)) {
+        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+        if (this->Validate(finalPath)) {
+          return finalPath;
+        }
+      }
+
       fwPath = cmStrCat(d, n, ".framework");
       if (cmSystemTools::FileIsDirectory(fwPath)) {
         auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
@@ -578,6 +586,14 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
   // Search for each name in all search paths.
   for (std::string const& n : this->Names) {
     for (std::string const& d : this->SearchPaths) {
+      fwPath = cmStrCat(d, n, ".xcframework");
+      if (cmSystemTools::FileIsDirectory(fwPath)) {
+        auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+        if (this->Validate(finalPath)) {
+          return finalPath;
+        }
+      }
+
       fwPath = cmStrCat(d, n, ".framework");
       if (cmSystemTools::FileIsDirectory(fwPath)) {
         auto finalPath = cmSystemTools::CollapseFullPath(fwPath);

+ 10 - 0
Tests/RunCMake/XcFramework/RunCMakeTest.cmake

@@ -81,3 +81,13 @@ if(RunCMake_GENERATOR STREQUAL "Xcode" AND CMAKE_C_COMPILER_VERSION VERSION_GREA
   create_executables(target-framework-link-phase framework)
   run_cmake_with_options(create-executable-target-incomplete-link-phase -DCMAKE_SYSTEM_NAME=Darwin "-DCMAKE_OSX_ARCHITECTURES=${macos_archs_1}" -DMYLIB_LIBRARY=${RunCMake_BINARY_DIR}/create-xcframework-incomplete-build/mylib.xcframework)
 endif()
+
+# Ensure that .xcframework is found before .framework
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/create-xcframework-framework-build)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(copy-framework ${CMAKE_COMMAND} -E copy_directory ${RunCMake_BINARY_DIR}/create-framework-macos-build/install/lib/mylib.framework ${RunCMake_TEST_BINARY_DIR}/mylib.framework)
+unset(RunCMake_TEST_NO_CLEAN)
+unset(RunCMake_TEST_BINARY_DIR)
+
+run_cmake(find-library)
+run_cmake_command(find-library-script ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/find-library.cmake)

+ 5 - 0
Tests/RunCMake/XcFramework/find-library.cmake

@@ -0,0 +1,5 @@
+find_library(MYLIB_XCFRAMEWORK mylib NO_DEFAULT_PATH PATHS "${CMAKE_BINARY_DIR}/../create-xcframework-framework-build")
+file(REAL_PATH "${CMAKE_BINARY_DIR}/../create-xcframework-framework-build/mylib.xcframework" expected_path)
+if(NOT MYLIB_XCFRAMEWORK STREQUAL expected_path)
+  message(FATAL_ERROR "Expected value of MYLIB_XCFRAMEWORK:\n  ${expected_path}\nActual value:\n  ${MYLIB_XCFRAMEWORK}")
+endif()