Parcourir la source

Merge topic 'cps-export-components' into release-4.0

647633e961 Tests: Add CPS end-to-end test
85721c4c56 install(PACKAGE_INFO): Export required components

Acked-by: Kitware Robot <[email protected]>
Merge-request: !10339
Brad King il y a 8 mois
Parent
commit
bbbf373fe8

+ 22 - 12
Source/cmExportPackageInfoGenerator.cxx

@@ -127,9 +127,22 @@ void cmExportPackageInfoGenerator::GeneratePackageRequires(
 {
   if (!this->Requirements.empty()) {
     Json::Value& requirements = package["requires"];
+
+    // Build description for each requirement.
     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
-      requirements[requirement] = Json::Value{};
+      requirements[requirement.first] = data;
     }
   }
 }
@@ -257,10 +270,10 @@ bool cmExportPackageInfoGenerator::NoteLinkedTarget(
       return false;
     }
 
+    std::string component = linkedName.substr(prefix.length());
+    this->LinkTargets.emplace(linkedName, cmStrCat(pkgName, ':', component));
     // 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;
   }
 
@@ -278,16 +291,13 @@ bool cmExportPackageInfoGenerator::NoteLinkedTarget(
       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()) {
-      this->LinkTargets.emplace(linkedName,
-                                cmStrCat(':', linkedTarget->GetExportName()));
+      this->LinkTargets.emplace(linkedName, cmStrCat(':', component));
     } 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;
   }

+ 1 - 1
Source/cmExportPackageInfoGenerator.h

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

+ 1 - 0
Tests/RunCMake/CMakeLists.txt

@@ -396,6 +396,7 @@ set_property(TEST RunCMake.CompilerId APPEND PROPERTY LABELS "CUDA" "HIP" "ISPC"
 add_RunCMake_test(CompilerTest ${CMake_TEST_LANG_VARS})
 set_property(TEST RunCMake.CompilerTest APPEND PROPERTY LABELS "CUDA" "HIP" "ISPC" "Fortran")
 add_RunCMake_test(Configure -DMSVC_IDE=${MSVC_IDE})
+add_RunCMake_test(CpsExportImport)
 add_RunCMake_test(DisallowedCommands)
 if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
   add_RunCMake_test(ExportCompileCommands)

+ 3 - 0
Tests/RunCMake/CpsExportImport/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 4.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 24 - 0
Tests/RunCMake/CpsExportImport/RunCMakeTest.cmake

@@ -0,0 +1,24 @@
+include(RunCMake)
+
+set(RunCMake_TEST_OPTIONS
+  -Wno-dev
+  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=b80be207-778e-46ba-8080-b23bba22639e"
+  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
+  )
+
+function(build_project test)
+  set(RunCMake_TEST_NO_CLEAN FALSE)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+  if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    list(APPEND RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+  endif()
+
+  run_cmake(${test})
+
+  set(RunCMake_TEST_NO_CLEAN TRUE)
+  run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . --config Release)
+  run_cmake_command(${test}-install ${CMAKE_COMMAND} --install . --config Release)
+endfunction()
+
+build_project(TestLibrary)
+build_project(TestExecutable)

+ 12 - 0
Tests/RunCMake/CpsExportImport/TestExecutable.cmake

@@ -0,0 +1,12 @@
+project(TestLibrary C)
+
+set(CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}/../install")
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/../install")
+
+find_package(libb REQUIRED COMPONENTS libb)
+
+add_executable(app app.c)
+
+target_link_libraries(app PUBLIC libb::libb)
+
+install(TARGETS app DESTINATION bin)

+ 14 - 0
Tests/RunCMake/CpsExportImport/TestLibrary.cmake

@@ -0,0 +1,14 @@
+project(TestLibrary C)
+
+set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/../install")
+
+add_library(liba SHARED liba.c)
+add_library(libb SHARED libb.c)
+
+target_link_libraries(libb PUBLIC liba)
+
+install(TARGETS liba EXPORT liba DESTINATION lib)
+install(PACKAGE_INFO liba DESTINATION cps EXPORT liba)
+
+install(TARGETS libb EXPORT libb DESTINATION lib)
+install(PACKAGE_INFO libb DESTINATION cps EXPORT libb)

+ 13 - 0
Tests/RunCMake/CpsExportImport/app.c

@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+extern
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+int ask(void);
+
+int main(void)
+{
+  printf("%i\n", ask());
+  return 0;
+}

+ 7 - 0
Tests/RunCMake/CpsExportImport/liba.c

@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int answer(void)
+{
+  return 42;
+}

+ 13 - 0
Tests/RunCMake/CpsExportImport/libb.c

@@ -0,0 +1,13 @@
+extern
+#ifdef _WIN32
+__declspec(dllimport)
+#endif
+int answer(void);
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int ask(void)
+{
+  return answer();
+}

+ 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)
 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" "libd" "type")