瀏覽代碼

Xcode: Don't hard-code SDK-provided implicit framework search paths

When a framework is linked to a target by its full path and that
framework is located in one of the implicit framework search directories,
CMake 3.18.5 and earlier discarded that path.
ce2dee9e5ba (Xcode: Don't add framework as -framework argument in
linker info list, 2020-09-28) introduced a regression which resulted in
the framework path always being added to the search path even if it
matched one of the implicit search paths. This broke the ability to do
device and simulator builds from the same configured project.

Fixes: #21678
Craig Scott 4 年之前
父節點
當前提交
5389bb4274
共有 3 個文件被更改,包括 21 次插入1 次删除
  1. 6 0
      Source/cmComputeLinkInformation.cxx
  2. 1 0
      Source/cmComputeLinkInformation.h
  3. 14 1
      Source/cmGlobalXCodeGenerator.cxx

+ 6 - 0
Source/cmComputeLinkInformation.cxx

@@ -474,6 +474,12 @@ std::vector<std::string> const& cmComputeLinkInformation::GetFrameworkPaths()
   return this->FrameworkPaths;
   return this->FrameworkPaths;
 }
 }
 
 
+std::set<std::string> const&
+cmComputeLinkInformation::GetFrameworkPathsEmitted() const
+{
+  return this->FrameworkPathsEmitted;
+}
+
 const std::set<const cmGeneratorTarget*>&
 const std::set<const cmGeneratorTarget*>&
 cmComputeLinkInformation::GetSharedLibrariesLinked() const
 cmComputeLinkInformation::GetSharedLibrariesLinked() const
 {
 {

+ 1 - 0
Source/cmComputeLinkInformation.h

@@ -55,6 +55,7 @@ public:
   std::vector<BT<std::string>> GetDirectoriesWithBacktraces();
   std::vector<BT<std::string>> GetDirectoriesWithBacktraces();
   std::vector<std::string> const& GetDepends() const;
   std::vector<std::string> const& GetDepends() const;
   std::vector<std::string> const& GetFrameworkPaths() const;
   std::vector<std::string> const& GetFrameworkPaths() const;
+  std::set<std::string> const& GetFrameworkPathsEmitted() const;
   std::string GetLinkLanguage() const { return this->LinkLanguage; }
   std::string GetLinkLanguage() const { return this->LinkLanguage; }
   std::vector<std::string> const& GetRuntimeSearchPath() const;
   std::vector<std::string> const& GetRuntimeSearchPath() const;
   std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
   std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }

+ 14 - 1
Source/cmGlobalXCodeGenerator.cxx

@@ -3620,6 +3620,15 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
 
 
     // now add the left-over link libraries
     // now add the left-over link libraries
     {
     {
+      // Keep track of framework search paths we've already added or that are
+      // part of the set of implicit search paths. We don't want to repeat
+      // them and we also need to avoid hard-coding any SDK-specific paths.
+      // This is essential for getting device-and-simulator builds to work,
+      // otherwise we end up hard-coding a path to the wrong SDK for
+      // SDK-provided frameworks that are added by their full path.
+      std::set<std::string> emitted(cli->GetFrameworkPathsEmitted());
+      const auto& fwPaths = cli->GetFrameworkPaths();
+      emitted.insert(fwPaths.begin(), fwPaths.end());
       BuildObjectListOrString libPaths(this, true);
       BuildObjectListOrString libPaths(this, true);
       for (auto const& libItem : configItemMap[configName]) {
       for (auto const& libItem : configItemMap[configName]) {
         auto const& libName = *libItem;
         auto const& libName = *libItem;
@@ -3633,7 +3642,11 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
             const auto fwName =
             const auto fwName =
               cmSystemTools::GetFilenameWithoutExtension(libPath);
               cmSystemTools::GetFilenameWithoutExtension(libPath);
             const auto fwDir = cmSystemTools::GetParentDirectory(libPath);
             const auto fwDir = cmSystemTools::GetParentDirectory(libPath);
-            libPaths.Add("-F " + this->XCodeEscapePath(fwDir));
+            if (emitted.insert(fwDir).second) {
+              // This is a search path we had not added before and it isn't an
+              // implicit search path, so we need it
+              libPaths.Add("-F " + this->XCodeEscapePath(fwDir));
+            }
             libPaths.Add("-framework " + fwName);
             libPaths.Add("-framework " + fwName);
           } else {
           } else {
             libPaths.Add(this->XCodeEscapePath(cleanPath));
             libPaths.Add(this->XCodeEscapePath(cleanPath));