Преглед изворни кода

install(PACKAGE_INFO): Export required components

Modify cmExportPackageInfoGenerator to record not just what packages are
required, but what targets (components) are used by those requirements,
and to populate the requirements' component lists accordingly.
Matthew Woehlke пре 8 месеци
родитељ
комит
85721c4c56

+ 22 - 12
Source/cmExportPackageInfoGenerator.cxx

@@ -127,9 +127,22 @@ void cmExportPackageInfoGenerator::GeneratePackageRequires(
 {
 {
   if (!this->Requirements.empty()) {
   if (!this->Requirements.empty()) {
     Json::Value& requirements = package["requires"];
     Json::Value& requirements = package["requires"];
+
+    // Build description for each requirement.
     for (auto const& requirement : this->Requirements) {
     for (auto const& requirement : this->Requirements) {
+      auto data = Json::Value{ Json::objectValue };
+
+      // Add required components.
+      if (!requirement.second.empty()) {
+        auto components = Json::Value{ Json::arrayValue };
+        for (std::string const& component : requirement.second) {
+          components.append(component);
+        }
+        data["components"] = components;
+      }
+
       // TODO: version, hint
       // TODO: version, hint
-      requirements[requirement] = Json::Value{};
+      requirements[requirement.first] = data;
     }
     }
   }
   }
 }
 }
@@ -257,10 +270,10 @@ bool cmExportPackageInfoGenerator::NoteLinkedTarget(
       return false;
       return false;
     }
     }
 
 
+    std::string component = linkedName.substr(prefix.length());
+    this->LinkTargets.emplace(linkedName, cmStrCat(pkgName, ':', component));
     // TODO: Record package version, hint.
     // TODO: Record package version, hint.
-    this->Requirements.emplace(pkgName);
-    this->LinkTargets.emplace(
-      linkedName, cmStrCat(pkgName, ':', linkedName.substr(prefix.length())));
+    this->Requirements[pkgName].emplace(std::move(component));
     return true;
     return true;
   }
   }
 
 
@@ -278,16 +291,13 @@ bool cmExportPackageInfoGenerator::NoteLinkedTarget(
       return false;
       return false;
     }
     }
 
 
-    auto pkgName =
-      cm::string_view{ linkNamespace.data(), linkNamespace.size() - 2 };
-
+    std::string pkgName{ linkNamespace.data(), linkNamespace.size() - 2 };
+    std::string component = linkedTarget->GetExportName();
     if (pkgName == this->GetPackageName()) {
     if (pkgName == this->GetPackageName()) {
-      this->LinkTargets.emplace(linkedName,
-                                cmStrCat(':', linkedTarget->GetExportName()));
+      this->LinkTargets.emplace(linkedName, cmStrCat(':', component));
     } else {
     } else {
-      this->Requirements.emplace(pkgName);
-      this->LinkTargets.emplace(
-        linkedName, cmStrCat(pkgName, ':', linkedTarget->GetExportName()));
+      this->LinkTargets.emplace(linkedName, cmStrCat(pkgName, ':', component));
+      this->Requirements[pkgName].emplace(std::move(component));
     }
     }
     return true;
     return true;
   }
   }

+ 1 - 1
Source/cmExportPackageInfoGenerator.h

@@ -110,5 +110,5 @@ private:
   std::vector<std::string> DefaultConfigurations;
   std::vector<std::string> DefaultConfigurations;
 
 
   std::map<std::string, std::string> LinkTargets;
   std::map<std::string, std::string> LinkTargets;
-  std::set<std::string> Requirements;
+  std::map<std::string, std::set<std::string>> Requirements;
 };
 };

+ 4 - 2
Tests/RunCMake/PackageInfo/Requirements-check.cmake

@@ -8,8 +8,10 @@ expect_value("${content}" "interface" "components" "libb" "type")
 
 
 file(READ "${out_dir}/bar.cps" content)
 file(READ "${out_dir}/bar.cps" content)
 expect_value("${content}" "bar" "name")
 expect_value("${content}" "bar" "name")
-expect_null("${content}" "requires" "foo")
-expect_null("${content}" "requires" "test")
+expect_array("${content}"      1 "requires"  "foo" "components")
+expect_value("${content}" "libb" "requires"  "foo" "components" 0)
+expect_array("${content}"      1 "requires" "test" "components")
+expect_value("${content}" "liba" "requires" "test" "components" 0)
 expect_value("${content}" "interface" "components" "libc" "type")
 expect_value("${content}" "interface" "components" "libc" "type")
 expect_value("${content}" "interface" "components" "libd" "type")
 expect_value("${content}" "interface" "components" "libd" "type")