瀏覽代碼

Framework: Fix $<TARGET_SONAME_FILE:...> for imported frameworks

Kyle Edwards 4 年之前
父節點
當前提交
820d3afb28

+ 26 - 3
Source/cmGeneratorTarget.cxx

@@ -52,6 +52,11 @@
 
 class cmMessenger;
 
+namespace {
+const cmsys::RegularExpression FrameworkRegularExpression(
+  "^(.*/)?([^/]*)\\.framework/(.*)$");
+}
+
 template <>
 cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
   cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
@@ -2257,8 +2262,16 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
         return cmSystemTools::GetFilenameName(info->Location);
       }
       // Use the soname given if any.
+      if (this->IsFrameworkOnApple()) {
+        cmsys::RegularExpressionMatch match;
+        if (FrameworkRegularExpression.find(info->SOName.c_str(), match)) {
+          auto frameworkName = match.match(2);
+          auto fileName = match.match(3);
+          return cmStrCat(frameworkName, ".framework/", fileName);
+        }
+      }
       if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
-        return info->SOName.substr(6);
+        return info->SOName.substr(cmStrLen("@rpath/"));
       }
       return info->SOName;
     }
@@ -6459,9 +6472,19 @@ std::string cmGeneratorTarget::GetDirectory(
   const std::string& config, cmStateEnums::ArtifactType artifact) const
 {
   if (this->IsImported()) {
+    auto fullPath = this->Target->ImportedGetFullPath(config, artifact);
+    if (this->IsFrameworkOnApple()) {
+      cmsys::RegularExpressionMatch match;
+      if (FrameworkRegularExpression.find(fullPath.c_str(), match)) {
+        auto path = match.match(1);
+        if (!path.empty()) {
+          path.erase(path.length() - 1);
+        }
+        return path;
+      }
+    }
     // Return the directory from which the target is imported.
-    return cmSystemTools::GetFilenamePath(
-      this->Target->ImportedGetFullPath(config, artifact));
+    return cmSystemTools::GetFilenamePath(fullPath);
   }
   if (OutputInfo const* info = this->GetOutputInfo(config)) {
     // Return the directory in which the target will be built.

+ 1 - 0
Tests/RunCMake/Framework/ImportedFrameworkTest-build-stdout.txt

@@ -0,0 +1 @@
+xxx/no/exist/fw\.framework/Versions/A/fwxxx

+ 10 - 0
Tests/RunCMake/Framework/ImportedFrameworkTest.cmake

@@ -0,0 +1,10 @@
+add_library(fw SHARED IMPORTED)
+set_target_properties(fw PROPERTIES
+  FRAMEWORK TRUE
+  IMPORTED_LOCATION "/no/exist/fw.framework/Versions/A/fw"
+  IMPORTED_SONAME "@rpath/fw.framework/Versions/A/fw"
+  )
+
+add_custom_target(print_fw ALL COMMAND
+  ${CMAKE_COMMAND} -E echo "xxx$<TARGET_SONAME_FILE:fw>xxx"
+  )

+ 12 - 0
Tests/RunCMake/Framework/RunCMakeTest.cmake

@@ -81,3 +81,15 @@ function(framework_multi_config_postfix_test)
 endfunction()
 
 framework_multi_config_postfix_test()
+
+function(imported_framework_test)
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/ImportedFrameworkTest-build")
+  set(RunCMake_TEST_NO_CLEAN 1)
+
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  run_cmake(ImportedFrameworkTest)
+  run_cmake_command(ImportedFrameworkTest-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+imported_framework_test()