Browse Source

macOS: Cache parsed xcframework plist content

Avoid repeating `plutil` calls on the same plist files.

Fixes: #27023
Eugene Zimichev 2 months ago
parent
commit
da330bcf88
4 changed files with 40 additions and 0 deletions
  1. 19 0
      Source/cmGlobalGenerator.cxx
  2. 9 0
      Source/cmGlobalGenerator.h
  3. 8 0
      Source/cmXcFramework.cxx
  4. 4 0
      Source/cmXcFramework.h

+ 19 - 0
Source/cmGlobalGenerator.cxx

@@ -61,6 +61,7 @@
 #include "cmValue.h"
 #include "cmVersion.h"
 #include "cmWorkingDirectory.h"
+#include "cmXcFramework.h"
 #include "cmake.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
@@ -2002,6 +2003,7 @@ void cmGlobalGenerator::ClearGeneratorMembers()
   this->ProjectMap.clear();
   this->RuleHashes.clear();
   this->DirectoryContentMap.clear();
+  this->XcFrameworkPListContentMap.clear();
   this->BinaryDirectories.clear();
   this->GeneratedFiles.clear();
   this->RuntimeDependencySets.clear();
@@ -3967,3 +3969,20 @@ bool cmGlobalGenerator::ShouldWarnExperimental(cm::string_view featureName,
     .emplace(cmStrCat(featureName, '-', featureUuid))
     .second;
 }
+
+cm::optional<cmXcFrameworkPlist> cmGlobalGenerator::GetXcFrameworkPListContent(
+  std::string const& path) const
+{
+  cm::optional<cmXcFrameworkPlist> result;
+  auto i = this->XcFrameworkPListContentMap.find(path);
+  if (i != this->XcFrameworkPListContentMap.end()) {
+    result = i->second;
+  }
+  return result;
+}
+
+void cmGlobalGenerator::SetXcFrameworkPListContent(
+  std::string const& path, cmXcFrameworkPlist const& content)
+{
+  this->XcFrameworkPListContentMap.emplace(path, content);
+}

+ 9 - 0
Source/cmGlobalGenerator.h

@@ -32,6 +32,7 @@
 #include "cmTarget.h"
 #include "cmTargetDepend.h"
 #include "cmValue.h"
+#include "cmXcFramework.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
 #  include <cm3p/json/value.h>
@@ -693,6 +694,11 @@ public:
   bool ShouldWarnExperimental(cm::string_view featureName,
                               cm::string_view featureUuid);
 
+  cm::optional<cmXcFrameworkPlist> GetXcFrameworkPListContent(
+    std::string const& path) const;
+  void SetXcFrameworkPListContent(std::string const& path,
+                                  cmXcFrameworkPlist const& content);
+
 protected:
   // for a project collect all its targets by following depend
   // information, and also collect all the targets
@@ -914,6 +920,9 @@ private:
   };
   std::map<std::string, DirectoryContent> DirectoryContentMap;
 
+  // Cache parsed PList files
+  std::map<std::string, cmXcFrameworkPlist> XcFrameworkPListContentMap;
+
   // Set of binary directories on disk.
   std::set<std::string> BinaryDirectories;
 

+ 8 - 0
Source/cmXcFramework.cxx

@@ -9,6 +9,7 @@
 
 #include <cm3p/json/value.h>
 
+#include "cmGlobalGenerator.h"
 #include "cmJSONHelpers.h"
 #include "cmJSONState.h"
 #include "cmMakefile.h"
@@ -124,6 +125,12 @@ cm::optional<cmXcFrameworkPlist> cmParseXcFrameworkPlist(
   std::string const& xcframeworkPath, cmMakefile const& mf,
   cmListFileBacktrace const& bt)
 {
+  cmGlobalGenerator* gen = mf.GetGlobalGenerator();
+  if (cm::optional<cmXcFrameworkPlist> cached =
+        gen->GetXcFrameworkPListContent(xcframeworkPath)) {
+    return cached;
+  }
+
   std::string plistPath = cmStrCat(xcframeworkPath, "/Info.plist");
 
   auto value = cmParsePlist(plistPath);
@@ -162,6 +169,7 @@ cm::optional<cmXcFrameworkPlist> cmParseXcFrameworkPlist(
     return cm::nullopt;
   }
   plist.Path = plistPath;
+  gen->SetXcFrameworkPListContent(xcframeworkPath, plist);
   return cm::optional<cmXcFrameworkPlist>(plist);
 }
 

+ 4 - 0
Source/cmXcFramework.h

@@ -47,6 +47,10 @@ struct cmXcFrameworkPlist
     cmListFileBacktrace const& bt = cmListFileBacktrace{}) const;
 };
 
+/**
+ * Parses Plist file of .xcframework.
+ * Expects normalized path as input
+ */
 cm::optional<cmXcFrameworkPlist> cmParseXcFrameworkPlist(
   std::string const& xcframeworkPath, cmMakefile const& mf,
   cmListFileBacktrace const& bt = cmListFileBacktrace{});