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

Merge topic 'cps-modules'

3771471310 CPS: Support C++20 modules
b080922be6 cmake-cxxmodules: Note config limitations
e4cbf1c153 cmCxxModuleMetadata: Update PopulateTarget

Acked-by: Kitware Robot <[email protected]>
Tested-by: buildbot <[email protected]>
Merge-request: !11633
Brad King пре 3 недеља
родитељ
комит
4efe6d3a18
51 измењених фајлова са 537 додато и 194 уклоњено
  1. 2 1
      Help/command/export.rst
  2. 1 0
      Help/command/install.rst
  3. 6 0
      Help/manual/cmake-cxxmodules.7.rst
  4. 6 0
      Help/release/dev/cps-cxx-modules.rst
  5. 14 10
      Source/cmCxxModuleMetadata.cxx
  6. 4 3
      Source/cmExportBuildPackageInfoGenerator.cxx
  7. 0 1
      Source/cmExportBuildPackageInfoGenerator.h
  8. 18 8
      Source/cmExportInstallPackageInfoGenerator.cxx
  9. 1 1
      Source/cmExportInstallPackageInfoGenerator.h
  10. 19 0
      Source/cmExportPackageInfoGenerator.cxx
  11. 8 2
      Source/cmExportPackageInfoGenerator.h
  12. 1 1
      Source/cmInstallCommand.cxx
  13. 32 0
      Source/cmPackageInfoReader.cxx
  14. 3 0
      Source/cmPackageInfoReader.h
  15. 15 12
      Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
  16. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt
  17. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt
  18. 18 10
      Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/test/CMakeLists.txt
  19. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt
  20. 6 0
      Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt
  21. 18 10
      Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/test/CMakeLists.txt
  22. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt
  23. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt
  24. 47 34
      Tests/RunCMake/CXXModulesCompile/exp-iface-build/test/CMakeLists.txt
  25. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt
  26. 6 0
      Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt
  27. 41 34
      Tests/RunCMake/CXXModulesCompile/exp-iface-install/test/CMakeLists.txt
  28. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt
  29. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt
  30. 17 11
      Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/test/CMakeLists.txt
  31. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt
  32. 6 0
      Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt
  33. 16 10
      Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/test/CMakeLists.txt
  34. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt
  35. 23 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt
  36. 14 8
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/test/CMakeLists.txt
  37. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt
  38. 24 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt
  39. 14 8
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/test/CMakeLists.txt
  40. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt
  41. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt
  42. 10 4
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/test/CMakeLists.txt
  43. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt
  44. 6 0
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt
  45. 10 4
      Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/test/CMakeLists.txt
  46. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt
  47. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt
  48. 20 11
      Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/test/CMakeLists.txt
  49. 5 0
      Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt
  50. 6 0
      Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt
  51. 20 11
      Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/test/CMakeLists.txt

+ 2 - 1
Help/command/export.rst

@@ -149,7 +149,8 @@ Exporting Targets to the |CPS|
          [LICENSE <license-string>]
          [DEFAULT_LICENSE <license-string>]
          [DESCRIPTION <description-string>]
-         [HOMEPAGE_URL <url-string>])
+         [HOMEPAGE_URL <url-string>]
+         [CXX_MODULES_DIRECTORY <directory>])
 
 .. versionadded:: 4.3
 .. note::

+ 1 - 0
Help/command/install.rst

@@ -1000,6 +1000,7 @@ Signatures
             [HOMEPAGE_URL <url-string>]
             [PERMISSIONS <permission>...]
             [CONFIGURATIONS <config>...]
+            [CXX_MODULES_DIRECTORY <directory>]
             [COMPONENT <component>]
             [EXCLUDE_FROM_ALL])
 

+ 6 - 0
Help/manual/cmake-cxxmodules.7.rst

@@ -126,6 +126,12 @@ For the :ref:`Visual Studio Generators`:
 - Use of modules provided by ``PRIVATE`` sources from ``PUBLIC`` module
   sources is not diagnosed.
 
+Separately, as a design choice, CMake does not express configuration-agnostic
+module maps for imported targets. The :prop_tgt:`IMPORTED_CXX_MODULES_<CONFIG>`
+target property is always tied to a specific configuration. This can lead to
+some friction when importing/exporting targets from/to configuration-unaware
+build systems. Future work will alleviate this restriction.
+
 Usage
 =====
 

+ 6 - 0
Help/release/dev/cps-cxx-modules.rst

@@ -0,0 +1,6 @@
+cps-cxx-modules
+---------------
+
+* The :command:`install(PACKAGE_INFO)` and :command:`export(PACKAGE_INFO)`
+  commands now support specifying `CXX_MODULES_DIRECTORY` for exporting C++20
+  modules.

+ 14 - 10
Source/cmCxxModuleMetadata.cxx

@@ -439,10 +439,10 @@ void cmCxxModuleMetadata::PopulateTarget(
   cmTarget& target, cmCxxModuleMetadata const& meta,
   std::vector<std::string> const& configs)
 {
-  std::vector<cm::string_view> allIncludeDirectories;
-  std::vector<cm::string_view> allCompileOptions;
-  std::vector<cm::string_view> allCompileFeatures;
-  std::vector<std::string> allCompileDefinitions;
+  std::set<cm::string_view> allIncludeDirectories;
+  std::set<cm::string_view> allCompileOptions;
+  std::set<cm::string_view> allCompileFeatures;
+  std::set<std::string> allCompileDefinitions;
   std::set<std::string> baseDirs;
 
   std::string metadataDir =
@@ -457,6 +457,8 @@ void cmCxxModuleMetadata::PopulateTarget(
       sourcePath = cmStrCat(metadataDir, '/', sourcePath);
     }
 
+    sourcePath = cmSystemTools::ToNormalizedPathOnDisk(std::move(sourcePath));
+
     // Module metadata files can reference files in different roots,
     // just use the immediate parent directory as a base directory
     baseDirs.insert(cmSystemTools::GetFilenamePath(sourcePath));
@@ -465,26 +467,26 @@ void cmCxxModuleMetadata::PopulateTarget(
 
     if (module.LocalArguments) {
       for (auto const& incDir : module.LocalArguments->IncludeDirectories) {
-        allIncludeDirectories.push_back(incDir);
+        allIncludeDirectories.emplace(incDir);
       }
       for (auto const& sysIncDir :
            module.LocalArguments->SystemIncludeDirectories) {
-        allIncludeDirectories.push_back(sysIncDir);
+        allIncludeDirectories.emplace(sysIncDir);
       }
       for (auto const& opt : module.LocalArguments->CompileOptions) {
-        allCompileOptions.push_back(opt);
+        allCompileOptions.emplace(opt);
       }
       for (auto const& opt : module.LocalArguments->CompileFeatures) {
-        allCompileFeatures.push_back(opt);
+        allCompileFeatures.emplace(opt);
       }
 
       for (auto const& def : module.LocalArguments->Definitions) {
         if (!def.Undef) {
           if (def.Value) {
-            allCompileDefinitions.push_back(
+            allCompileDefinitions.emplace(
               cmStrCat(def.Name, "="_s, *def.Value));
           } else {
-            allCompileDefinitions.push_back(def.Name);
+            allCompileDefinitions.emplace(def.Name);
           }
         }
       }
@@ -523,6 +525,8 @@ void cmCxxModuleMetadata::PopulateTarget(
         if (!cmSystemTools::FileIsFullPath(sourcePath)) {
           sourcePath = cmStrCat(metadataDir, '/', sourcePath);
         }
+        sourcePath =
+          cmSystemTools::ToNormalizedPathOnDisk(std::move(sourcePath));
         moduleList.push_back(cmStrCat(module.LogicalName, "="_s, sourcePath));
       }
     }

+ 4 - 3
Source/cmExportBuildPackageInfoGenerator.cxx

@@ -114,6 +114,9 @@ void cmExportBuildPackageInfoGenerator::GenerateInterfacePropertiesConfig(
 
   Json::Value component =
     this->GenerateInterfaceConfigProperties(suffix, properties);
+
+  this->GenerateCxxModules(component, target, this->FileDir, config);
+
   if (!component.empty()) {
     configurations[config.empty() ? std::string{ "noconfig" } : config] =
       std::move(component);
@@ -122,7 +125,5 @@ void cmExportBuildPackageInfoGenerator::GenerateInterfacePropertiesConfig(
 
 std::string cmExportBuildPackageInfoGenerator::GetCxxModulesDirectory() const
 {
-  // TODO: Implement a not-CMake-specific mechanism for providing module
-  // information.
-  return {};
+  return this->CxxModulesDirectory;
 }

+ 0 - 1
Source/cmExportBuildPackageInfoGenerator.h

@@ -46,5 +46,4 @@ protected:
                                          std::string const& config);
 
   std::string GetCxxModulesDirectory() const override;
-  // TODO: Generate C++ module info in a not-CMake-specific format.
 };

+ 18 - 8
Source/cmExportInstallPackageInfoGenerator.cxx

@@ -112,7 +112,7 @@ bool cmExportInstallPackageInfoGenerator::GenerateMainFile(std::ostream& os)
 
     // Set configuration-agnostic properties for component.
     this->GenerateInterfaceProperties(*component, gt, properties);
-    if (!this->GenerateFileSetProperties(*component, gt, te)) {
+    if (!this->GenerateFileSetProperties(*component, gt, te, packagePath)) {
       return false;
     }
   }
@@ -143,6 +143,8 @@ void cmExportInstallPackageInfoGenerator::GenerateImportTargetsConfig(
   root["name"] = this->GetPackageName();
   root["configuration"] = (config.empty() ? "noconfig" : config);
 
+  std::string const& packagePath = this->GenerateImportPrefix();
+
   Json::Value& components = root["components"];
 
   for (auto const& te : this->GetExportSet()->GetTargetExports()) {
@@ -158,7 +160,8 @@ void cmExportInstallPackageInfoGenerator::GenerateImportTargetsConfig(
 
     Json::Value component =
       this->GenerateInterfaceConfigProperties(suffix, properties);
-    this->GenerateFileSetProperties(component, te->Target, te.get(), config);
+    this->GenerateFileSetProperties(component, te->Target, te.get(),
+                                    packagePath, config);
 
     if (!component.empty()) {
       components[te->Target->GetExportName()] = std::move(component);
@@ -212,10 +215,7 @@ std::string cmExportInstallPackageInfoGenerator::InstallNameDir(
 
 std::string cmExportInstallPackageInfoGenerator::GetCxxModulesDirectory() const
 {
-  // TODO: Implement a not-CMake-specific mechanism for providing module
-  // information.
-  // return IEGen->GetCxxModuleDirectory();
-  return {};
+  return IEGen->GetCxxModuleDirectory();
 }
 
 cm::optional<std::string>
@@ -265,8 +265,9 @@ cmExportInstallPackageInfoGenerator::GetFileSetDirectory(
 
 bool cmExportInstallPackageInfoGenerator::GenerateFileSetProperties(
   Json::Value& component, cmGeneratorTarget* gte, cmTargetExport const* te,
-  cm::optional<std::string> config)
+  std::string const& packagePath, cm::optional<std::string> config)
 {
+  bool hasModules = false;
   std::set<std::string> seenIncludeDirectories;
   for (auto const& name : gte->Target->GetAllInterfaceFileSets()) {
     cmFileSet* fileSet = gte->Target->GetFileSet(name);
@@ -290,9 +291,18 @@ bool cmExportInstallPackageInfoGenerator::GenerateFileSetProperties(
         seenIncludeDirectories.insert(*fileSetDirectory);
       }
     } else if (fileSet->GetType() == "CXX_MODULES"_s) {
-      /* TODO: Handle the CXX_MODULE directory */
+      hasModules = true;
+      this->RequiresConfigFiles = true;
     }
   }
 
+  if (hasModules && config) {
+    std::string const manifestPath =
+      this->GenerateCxxModules(component, gte, packagePath, *config);
+    if (!manifestPath.empty()) {
+      this->ConfigCxxModuleFiles[*config] =
+        cmStrCat(this->FileDir, '/', manifestPath);
+    }
+  }
   return true;
 }

+ 1 - 1
Source/cmExportInstallPackageInfoGenerator.h

@@ -69,7 +69,6 @@ protected:
                              std::string const& config) override;
 
   std::string GetCxxModulesDirectory() const override;
-  // TODO: Generate C++ module info in a not-CMake-specific format.
 
   cm::optional<std::string> GetFileSetDirectory(
     cmGeneratorTarget* gte, cmTargetExport const* te, cmFileSet* fileSet,
@@ -78,5 +77,6 @@ protected:
   bool GenerateFileSetProperties(Json::Value& component,
                                  cmGeneratorTarget* gte,
                                  cmTargetExport const* te,
+                                 std::string const& packagePath,
                                  cm::optional<std::string> config = {});
 };

+ 19 - 0
Source/cmExportPackageInfoGenerator.cxx

@@ -576,3 +576,22 @@ Json::Value cmExportPackageInfoGenerator::GenerateInterfaceConfigProperties(
 
   return component;
 }
+
+std::string cmExportPackageInfoGenerator::GenerateCxxModules(
+  Json::Value& component, cmGeneratorTarget* target,
+  std::string const& packagePath, std::string const& config)
+{
+  std::string manifestPath;
+
+  std::string const cxxModulesDirName = this->GetCxxModulesDirectory();
+  if (cxxModulesDirName.empty() || !target->HaveCxx20ModuleSources()) {
+    return manifestPath;
+  }
+
+  manifestPath =
+    cmStrCat(cxxModulesDirName, "/target-", target->GetFilesystemExportName(),
+             '-', config.empty() ? "noconfig" : config, ".modules.json");
+
+  component["cpp_module_metadata"] = cmStrCat(packagePath, '/', manifestPath);
+  return manifestPath;
+}

+ 8 - 2
Source/cmExportPackageInfoGenerator.h

@@ -70,16 +70,22 @@ protected:
 
   std::string GetCxxModuleFile(std::string const& /*name*/) const override
   {
-    // TODO
+    // CPS does not have a general CxxModuleFile, we use the config-specific
+    // manifests directly
     return {};
   }
 
   void GenerateCxxModuleConfigInformation(std::string const& /*name*/,
                                           std::ostream& /*os*/) const override
   {
-    // TODO
+    // We embed this directly in the CPS json
   }
 
+  std::string GenerateCxxModules(Json::Value& component,
+                                 cmGeneratorTarget* target,
+                                 std::string const& packagePath,
+                                 std::string const& config);
+
   bool NoteLinkedTarget(cmGeneratorTarget const* target,
                         std::string const& linkedName,
                         cmGeneratorTarget const* linkedTarget) override;

+ 1 - 1
Source/cmInstallCommand.cxx

@@ -2339,7 +2339,7 @@ bool HandlePackageInfoMode(std::vector<std::string> const& args,
 
   arguments.Bind(ica);
   ica.Bind("EXPORT"_s, exportName);
-  // ica.Bind("CXX_MODULES_DIRECTORY"_s, cxxModulesDirectory); TODO?
+  ica.Bind("CXX_MODULES_DIRECTORY"_s, cxxModulesDirectory);
 
   std::vector<std::string> unknownArgs;
   ArgumentParser::ParseResult result = ica.Parse(args, &unknownArgs);

+ 32 - 0
Source/cmPackageInfoReader.cxx

@@ -18,6 +18,7 @@
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
 
+#include "cmCxxModuleMetadata.h"
 #include "cmExecutionStatus.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
@@ -780,6 +781,12 @@ void cmPackageInfoReader::SetTargetProperties(
     AppendProperty(makefile, target, "LINK_LIBRARIES"_s, configuration, lib);
   }
 
+  // TODO: Handle non-configuration modules
+  // once IMPORTED_CXX_MODULES supports it
+  if (!configuration.empty()) {
+    this->ReadCxxModulesMetadata(makefile, target, configuration, data);
+  }
+
   // Add other information.
   if (configuration.empty()) {
     this->SetMetaProperty(makefile, target, "SPDX_LICENSE", data, "license",
@@ -787,6 +794,31 @@ void cmPackageInfoReader::SetTargetProperties(
   }
 }
 
+void cmPackageInfoReader::ReadCxxModulesMetadata(
+  cmMakefile* makefile, cmTarget* target, cm::string_view configuration,
+  Json::Value const& object) const
+{
+#ifndef CMAKE_BOOTSTRAP
+  Json::Value const& path = object["cpp_module_metadata"];
+
+  if (!path.isString()) {
+    return;
+  }
+
+  cmCxxModuleMetadata::ParseResult result =
+    cmCxxModuleMetadata::LoadFromFile(this->ResolvePath(path.asString()));
+
+  if (!result) {
+    makefile->IssueMessage(
+      MessageType::WARNING,
+      cmStrCat("Error parsing module manifest:\n"_s, result.Error));
+    return;
+  }
+
+  cmCxxModuleMetadata::PopulateTarget(*target, *result.Meta, configuration);
+#endif
+}
+
 cmTarget* cmPackageInfoReader::AddLibraryComponent(
   cmMakefile* makefile, cmStateEnums::TargetType type, std::string const& name,
   Json::Value const& data, std::string const& package, bool global) const

+ 3 - 0
Source/cmPackageInfoReader.h

@@ -108,6 +108,9 @@ private:
                        std::string const& property, Json::Value const& object,
                        std::string const& attribute,
                        std::string const& defaultValue = {}) const;
+  void ReadCxxModulesMetadata(cmMakefile* makefile, cmTarget* target,
+                              cm::string_view configuration,
+                              Json::Value const& object) const;
 
   std::string ResolvePath(std::string path) const;
 

+ 15 - 12
Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake

@@ -274,19 +274,22 @@ function (run_cxx_module_import_test type name)
   run_cxx_module_test(imp-mods "imp-mods-${name}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/${name}-${type}" ${ARGN})
 endfunction ()
 
+set(export_cps "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=7fa7d13b-8308-4dc7-af39-9e450456d68f")
+set(import_cps "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261")
+
 # Tests which install BMIs
 if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
   run_cxx_module_test(exp-iface-no-props-build)
-  run_cxx_module_test(exp-iface-build)
-  run_cxx_module_test(exp-incdirs-build)
+  run_cxx_module_test(exp-iface-build exp-iface-build ${export_cps})
+  run_cxx_module_test(exp-incdirs-build exp-incdirs-build ${export_cps})
   run_cxx_module_test(exp-incdirs-old-cmake-build)
   run_cxx_module_test(exp-usage-build)
   run_cxx_module_test(exp-bmi-and-iface-build)
-  run_cxx_module_test(exp-command-sepdir-build)
+  run_cxx_module_test(exp-command-sepdir-build exp-command-sepdir-build ${export_cps})
   run_cxx_module_test(exp-trans-targets-build)
-  run_cxx_module_test(exp-trans-mods1-build)
-  run_cxx_module_test(exp-trans-mods-build exp-trans-mods-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" )
-  run_cxx_module_test(exp-with-headers-build)
+  run_cxx_module_test(exp-trans-mods1-build exp-trans-mods1-build ${export_cps})
+  run_cxx_module_test(exp-trans-mods-build exp-trans-mods-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" ${export_cps} ${import_cps})
+  run_cxx_module_test(exp-with-headers-build exp-with-headers-build ${export_cps})
 
   if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
       "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
@@ -319,16 +322,16 @@ if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
 
   if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
     run_cxx_module_test(exp-iface-no-props-install)
-    run_cxx_module_test(exp-iface-install)
-    run_cxx_module_test(exp-incdirs-install)
+    run_cxx_module_test(exp-iface-install exp-iface-install ${export_cps})
+    run_cxx_module_test(exp-incdirs-install exp-incdirs-install ${export_cps})
     run_cxx_module_test(exp-incdirs-old-cmake-install)
     run_cxx_module_test(exp-usage-install)
     run_cxx_module_test(exp-bmi-and-iface-install)
-    run_cxx_module_test(exp-command-sepdir-install)
+    run_cxx_module_test(exp-command-sepdir-install exp-command-sepdir-install ${export_cps})
     run_cxx_module_test(exp-trans-targets-install)
-    run_cxx_module_test(exp-trans-mods1-install)
-    run_cxx_module_test(exp-trans-mods-install exp-trans-mods-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install" )
-    run_cxx_module_test(exp-with-headers-install)
+    run_cxx_module_test(exp-trans-mods1-install exp-trans-mods1-install ${export_cps})
+    run_cxx_module_test(exp-trans-mods-install exp-trans-mods-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install/lib/cmake/export_transitive_modules1_cps" ${export_cps} ${import_cps})
+    run_cxx_module_test(exp-with-headers-install exp-with-headers-install ${export_cps})
 
     if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
         "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt

@@ -11,6 +11,9 @@ install(TARGETS export_sepdir
 export(EXPORT CXXModules
   NAMESPACE CXXModules::
   FILE "${CMAKE_CURRENT_BINARY_DIR}/export_sepdir-targets.cmake")
+export(PACKAGE_INFO export_sepdir_cps
+  EXPORT CXXModules
+  CXX_MODULES_DIRECTORY "export_sepdir-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_sepdir-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_sepdir-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -32,6 +35,8 @@ add_test(NAME export_sepdir_build
     "${CMAKE_COMMAND}"
     "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}"
     "-Dexport_sepdir_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-Dexport_sepdir_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 18 - 10
Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/test/CMakeLists.txt

@@ -2,15 +2,23 @@ cmake_minimum_required(VERSION 3.24...3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_sepdir REQUIRED)
+find_package(export_sepdir_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_sepdir)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+function(test_target target)
 
-get_property(modules TARGET CXXModules::export_sepdir
-  PROPERTY "IMPORTED_CXX_MODULES_NOCONFIG")
-if (modules STREQUAL "")
-  message(SEND_ERROR
-    "Expected non-empty property value for IMPORTED_CXX_MODULES_NOCONFIG")
-endif ()
+  if (NOT TARGET ${target})
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+
+  get_property(modules TARGET ${target}
+    PROPERTY "IMPORTED_CXX_MODULES_NOCONFIG")
+  if (modules STREQUAL "")
+    message(SEND_ERROR
+      "Expected non-empty property value for IMPORTED_CXX_MODULES_NOCONFIG")
+  endif ()
+
+endfunction()
+
+test_target(CXXModules::export_sepdir)
+test_target(export_sepdir_cps::export_sepdir)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 6 - 0
Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt

@@ -12,6 +12,10 @@ install(EXPORT CXXModules
   NAMESPACE CXXModules::
   DESTINATION "lib/cmake/export_sepdir"
   FILE "export_sepdir-targets.cmake")
+install(PACKAGE_INFO "export_sepdir_cps"
+  EXPORT CXXModules
+  DESTINATION "lib/cmake/export_sepdir_cps"
+  CXX_MODULES_DIRECTORY "export_sepdir-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_sepdir-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_sepdir-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -35,6 +39,8 @@ add_test(NAME export_sepdir_build
     "${CMAKE_COMMAND}"
     "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
     "-Dexport_sepdir_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_sepdir"
+    "-Dexport_sepdir_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_sepdir_cps"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 18 - 10
Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/test/CMakeLists.txt

@@ -2,15 +2,23 @@ cmake_minimum_required(VERSION 3.24...3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_sepdir REQUIRED)
+find_package(export_sepdir_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_sepdir)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+function(test_target target)
 
-get_property(modules TARGET CXXModules::export_sepdir
-  PROPERTY "IMPORTED_CXX_MODULES_NOCONFIG")
-if (modules STREQUAL "")
-  message(SEND_ERROR
-    "Expected non-empty property value for IMPORTED_CXX_MODULES_NOCONFIG")
-endif ()
+  if (NOT TARGET ${target})
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+
+  get_property(modules TARGET ${target}
+    PROPERTY "IMPORTED_CXX_MODULES_NOCONFIG")
+  if (modules STREQUAL "")
+    message(SEND_ERROR
+      "Expected non-empty property value for IMPORTED_CXX_MODULES_NOCONFIG")
+  endif ()
+
+endfunction()
+
+test_target(CXXModules::export_sepdir)
+test_target(export_sepdir_cps::export_sepdir)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt

@@ -32,6 +32,9 @@ export(EXPORT CXXModules
   NAMESPACE CXXModules::
   FILE "${CMAKE_CURRENT_BINARY_DIR}/export_interfaces-targets.cmake"
   CXX_MODULES_DIRECTORY "export_interfaces-cxx-modules")
+export(PACKAGE_INFO export_interfaces_cps
+  EXPORT CXXModules
+  CXX_MODULES_DIRECTORY "export_interfaces-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_interfaces-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_interfaces-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -54,6 +57,8 @@ add_test(NAME export_interfaces_build
     "-Dexpected_source_dir=${CMAKE_CURRENT_SOURCE_DIR}"
     "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_interfaces_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-Dexport_interfaces_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 47 - 34
Tests/RunCMake/CXXModulesCompile/exp-iface-build/test/CMakeLists.txt

@@ -2,41 +2,54 @@ cmake_minimum_required(VERSION 3.24...3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_interfaces REQUIRED)
+find_package(export_interfaces_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_interfaces)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+function(test_target target set_name has_bmi)
+  if (NOT TARGET ${target})
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
 
-get_property(file_sets TARGET CXXModules::export_interfaces
-  PROPERTY INTERFACE_CXX_MODULE_SETS)
-if (NOT file_sets STREQUAL "modules")
-  message(FATAL_ERROR
-    "Incorrect exported file sets in CXXModules::export_interfaces:\n  ${file_sets}")
-endif ()
+  get_property(file_sets TARGET ${target}
+    PROPERTY INTERFACE_CXX_MODULE_SETS)
+  if (NOT file_sets STREQUAL "${set_name}")
+    message(FATAL_ERROR
+      "Incorrect exported file sets in ${target}:\n  ${file_sets}")
+  endif ()
 
-get_property(file_set_files TARGET CXXModules::export_interfaces
-  PROPERTY CXX_MODULE_SET_modules)
-set(expected_file_set_files
-  "${expected_source_dir}/importable.cxx"
-  "${expected_source_dir}/subdir/importable.cxx"
-  )
-if (NOT file_set_files STREQUAL "${expected_file_set_files}")
-  message(FATAL_ERROR
-    "Incorrect exported file set paths in CXXModules::export_interfaces:\n  ${file_set_files}")
-endif ()
+  get_property(file_set_files TARGET ${target}
+    PROPERTY CXX_MODULE_SET_${set_name})
+  set(expected_file_set_files
+    "${expected_source_dir}/importable.cxx"
+    "${expected_source_dir}/subdir/importable.cxx"
+    )
+  if (NOT file_set_files STREQUAL "${expected_file_set_files}")
+    message(FATAL_ERROR
+      "Incorrect exported file set paths in ${target}:\n  ${file_set_files}")
+  endif ()
 
-get_property(imported_modules TARGET CXXModules::export_interfaces
-  PROPERTY IMPORTED_CXX_MODULES_DEBUG)
-set(expected_imported_modules
-  "importable=${expected_source_dir}/importable.cxx,${expected_binary_dir}/CMakeFiles/export_interfaces.dir(/Debug)?/importable.(gcm|pcm|ifc)"
-  "subdir_importable=${expected_source_dir}/subdir/importable.cxx,${expected_binary_dir}/CMakeFiles/export_interfaces.dir(/Debug)?/subdir_importable.(gcm|pcm|ifc)"
-  )
-if (NOT imported_modules MATCHES "^${expected_imported_modules}$")
-  message(FATAL_ERROR
-    "Incorrect exported modules in CXXModules::export_interfaces:\n"
-    "  ${imported_modules}\n"
-    "does not match:\n"
-    "  ${expected_imported_modules}"
-  )
-endif ()
+  get_property(imported_modules TARGET ${target}
+    PROPERTY IMPORTED_CXX_MODULES_DEBUG)
+  if(has_bmi)
+    set(expected_imported_modules
+      "importable=${expected_source_dir}/importable.cxx,${expected_binary_dir}/CMakeFiles/export_interfaces.dir(/Debug)?/importable.(gcm|pcm|ifc)"
+      "subdir_importable=${expected_source_dir}/subdir/importable.cxx,${expected_binary_dir}/CMakeFiles/export_interfaces.dir(/Debug)?/subdir_importable.(gcm|pcm|ifc)"
+      )
+  else()
+    set(expected_imported_modules
+      "importable=${expected_source_dir}/importable.cxx"
+      "subdir_importable=${expected_source_dir}/subdir/importable.cxx"
+      )
+  endif()
+  if (NOT imported_modules MATCHES "^${expected_imported_modules}$")
+    message(FATAL_ERROR
+      "Incorrect exported modules in ${target}:\n"
+      "  ${imported_modules}\n"
+      "does not match:\n"
+      "  ${expected_imported_modules}"
+    )
+  endif ()
+endfunction()
+
+test_target(CXXModules::export_interfaces "modules" TRUE)
+test_target(export_interfaces_cps::export_interfaces "CXX_MODULES" FALSE)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 6 - 0
Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt

@@ -33,6 +33,10 @@ install(EXPORT CXXModules
   DESTINATION "lib/cmake/export_interfaces"
   FILE "export_interfaces-targets.cmake"
   CXX_MODULES_DIRECTORY "export_interfaces-cxx-modules")
+install(PACKAGE_INFO "export_interfaces_cps"
+  EXPORT CXXModules
+  DESTINATION "lib/cmake/export_interfaces_cps"
+  CXX_MODULES_DIRECTORY "export_interfaces-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_interfaces-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_interfaces-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -57,6 +61,8 @@ add_test(NAME export_interfaces_build
     "-Dexpected_source_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
     "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
     "-Dexport_interfaces_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_interfaces"
+    "-Dexport_interfaces_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_interfaces_cps"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 41 - 34
Tests/RunCMake/CXXModulesCompile/exp-iface-install/test/CMakeLists.txt

@@ -2,41 +2,48 @@ cmake_minimum_required(VERSION 3.24...3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_interfaces REQUIRED)
+find_package(export_interfaces_cps CONFIG REQUIRED)
 
-if (NOT TARGET CXXModules::export_interfaces)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+function(test_target target set_name)
+  if (NOT TARGET ${target})
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
 
-get_property(file_sets TARGET CXXModules::export_interfaces
-  PROPERTY INTERFACE_CXX_MODULE_SETS)
-if (NOT file_sets STREQUAL "modules")
-  message(FATAL_ERROR
-    "Incorrect exported file sets in CXXModules::export_interfaces:\n  ${file_sets}")
-endif ()
+  get_property(file_sets TARGET ${target}
+    PROPERTY INTERFACE_CXX_MODULE_SETS)
 
-get_property(file_set_files TARGET CXXModules::export_interfaces
-  PROPERTY CXX_MODULE_SET_modules)
-set(expected_file_set_files
-  "${expected_source_dir}/importable.cxx"
-  "${expected_source_dir}/subdir/importable.cxx"
-  )
-if (NOT file_set_files STREQUAL "${expected_file_set_files}")
-  message(FATAL_ERROR
-    "Incorrect exported file set paths in CXXModules::export_interfaces:\n  ${file_set_files}")
-endif ()
+  if (NOT file_sets STREQUAL set_name)
+    message(FATAL_ERROR
+      "Incorrect exported file sets in ${target}:\n  ${file_sets}")
+  endif ()
 
-get_property(imported_modules TARGET CXXModules::export_interfaces
-  PROPERTY IMPORTED_CXX_MODULES_DEBUG)
-set(expected_imported_modules
-  "importable=${expected_source_dir}/importable.cxx"
-  "subdir_importable=${expected_source_dir}/subdir/importable.cxx"
-  )
-if (NOT imported_modules STREQUAL "${expected_imported_modules}")
-  message(FATAL_ERROR
-    "Incorrect exported modules in CXXModules::export_interfaces:\n"
-    "  ${imported_modules}\n"
-    "does not match:\n"
-    "  ${expected_imported_modules}"
-  )
-endif ()
+  get_property(file_set_files TARGET ${target}
+    PROPERTY CXX_MODULE_SET_${set_name})
+  set(expected_file_set_files
+    "${expected_source_dir}/importable.cxx"
+    "${expected_source_dir}/subdir/importable.cxx"
+    )
+  if (NOT file_set_files STREQUAL "${expected_file_set_files}")
+    message(FATAL_ERROR
+      "Incorrect exported file set paths in ${target}:\n  ${file_set_files}")
+  endif ()
+
+  get_property(imported_modules TARGET ${target}
+    PROPERTY IMPORTED_CXX_MODULES_DEBUG)
+  set(expected_imported_modules
+    "importable=${expected_source_dir}/importable.cxx"
+    "subdir_importable=${expected_source_dir}/subdir/importable.cxx"
+    )
+  if (NOT imported_modules STREQUAL "${expected_imported_modules}")
+    message(FATAL_ERROR
+      "Incorrect exported modules in ${target}:\n"
+      "  ${imported_modules}\n"
+      "does not match:\n"
+      "  ${expected_imported_modules}"
+    )
+  endif ()
+endfunction()
+
+test_target(CXXModules::export_interfaces "modules")
+test_target(export_interfaces_cps::export_interfaces "CXX_MODULES")

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt

@@ -38,6 +38,9 @@ export(EXPORT CXXModules
   NAMESPACE CXXModules::
   FILE "${CMAKE_CURRENT_BINARY_DIR}/export_include_directories-targets.cmake"
   CXX_MODULES_DIRECTORY "export_include_directories-cxx-modules")
+export(PACKAGE_INFO export_include_directories_cps
+  EXPORT CXXModules
+  CXX_MODULES_DIRECTORY "export_include_directories-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_include_directories-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_include_directories-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -60,6 +63,8 @@ add_test(NAME export_include_directories_build
     "-Dexpected_source_dir=${CMAKE_CURRENT_SOURCE_DIR}"
     "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_include_directories_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-Dexport_include_directories_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 17 - 11
Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/test/CMakeLists.txt

@@ -2,17 +2,23 @@ cmake_minimum_required(VERSION 3.24)
 project(cxx_modules_library NONE)
 
 find_package(export_include_directories REQUIRED)
+find_package(export_include_directories_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_include_directories)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
-
-get_property(include_directories TARGET CXXModules::export_include_directories
-  PROPERTY IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES)
-foreach (include_directory IN LISTS include_directories)
-  if (NOT EXISTS "${include_directory}")
+function(test_target target)
+  if (NOT TARGET ${target})
     message(FATAL_ERROR
-      "Missing include directory in C++ module interface CXXModules::export_include_directories:\n  ${include_directory}")
+      "Missing imported target")
   endif ()
-endforeach ()
+
+  get_property(include_directories TARGET ${target}
+    PROPERTY IMPORTED_CXX_MODULES_INCLUDE_DIRECTORIES)
+  foreach (include_directory IN LISTS include_directories)
+    if (NOT EXISTS "${include_directory}")
+      message(FATAL_ERROR
+        "Missing include directory in C++ module interface ${target}:\n  ${include_directory}")
+    endif ()
+  endforeach ()
+endfunction()
+
+test_target(CXXModules::export_include_directories)
+test_target(export_include_directories_cps::export_include_directories)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 6 - 0
Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt

@@ -45,6 +45,10 @@ install(EXPORT CXXModules
   DESTINATION "lib/cmake/export_include_directories"
   FILE "export_include_directories-targets.cmake"
   CXX_MODULES_DIRECTORY "export_include_directories-cxx-modules")
+install(PACKAGE_INFO export_include_directories_cps
+  EXPORT CXXModules
+  DESTINATION "lib/cmake/export_include_directories_cps"
+  CXX_MODULES_DIRECTORY "export_include_directories-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_include_directories-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_include_directories-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -69,6 +73,8 @@ add_test(NAME export_include_directories_build
     "-Dexpected_source_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
     "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
     "-Dexport_include_directories_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_include_directories"
+    "-Dexport_include_directories_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_include_directories_cps"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 16 - 10
Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/test/CMakeLists.txt

@@ -2,15 +2,21 @@ cmake_minimum_required(VERSION 3.24...3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_include_directories REQUIRED)
+find_package(export_include_directories_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_include_directories)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+function(test_target target set_name)
+  if (NOT TARGET ${target})
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
 
-get_property(file_sets TARGET CXXModules::export_include_directories
-  PROPERTY INTERFACE_CXX_MODULE_SETS)
-if (NOT file_sets STREQUAL "modules")
-  message(FATAL_ERROR
-    "Incorrect exported file sets in CXXModules::export_include_directories:\n  ${file_sets}")
-endif ()
+  get_property(file_sets TARGET ${target}
+    PROPERTY INTERFACE_CXX_MODULE_SETS)
+  if (NOT file_sets STREQUAL ${set_name})
+    message(FATAL_ERROR
+      "Incorrect exported file sets in ${target}:\n  ${file_sets}")
+  endif ()
+endfunction()
+
+test_target(CXXModules::export_include_directories "modules")
+test_target(export_include_directories_cps::export_include_directories "CXX_MODULES")

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 23 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt

@@ -4,6 +4,7 @@ project(cxx_modules_export_transitive_modules CXX)
 include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
 
 find_package(export_transitive_modules1 REQUIRED)
+find_package(export_transitive_modules1_cps REQUIRED)
 
 add_library(export_transitive_modules STATIC)
 target_sources(export_transitive_modules
@@ -17,13 +18,32 @@ target_sources(export_transitive_modules
 target_compile_features(export_transitive_modules PUBLIC cxx_std_20)
 target_link_libraries(export_transitive_modules PRIVATE CXXModules::export_transitive_modules1)
 
+add_library(export_transitive_modules_cps STATIC)
+target_sources(export_transitive_modules_cps
+  PUBLIC
+    FILE_SET modules TYPE CXX_MODULES
+      BASE_DIRS
+        "${CMAKE_CURRENT_SOURCE_DIR}"
+      FILES
+        importable.cxx
+  )
+target_compile_features(export_transitive_modules_cps PUBLIC cxx_std_20)
+target_link_libraries(export_transitive_modules_cps PRIVATE export_transitive_modules1_cps::export_transitive_modules1)
+set_target_properties(export_transitive_modules_cps PROPERTIES EXPORT_NAME export_transitive_modules)
+
 install(TARGETS export_transitive_modules
   EXPORT CXXModules
   FILE_SET modules DESTINATION "lib/cxx/miu")
+install(TARGETS export_transitive_modules_cps
+  EXPORT CXXModules_cps
+  FILE_SET modules DESTINATION "lib/cxx/miu")
 export(EXPORT CXXModules
   NAMESPACE CXXModules::
   FILE "${CMAKE_CURRENT_BINARY_DIR}/export_transitive_modules-targets.cmake"
   CXX_MODULES_DIRECTORY "export_transitive_modules-cxx-modules")
+export(PACKAGE_INFO export_transitive_modules_cps
+  EXPORT CXXModules_cps
+  CXX_MODULES_DIRECTORY "export_transitive_modules-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_transitive_modules-config.cmake"
   "include(CMakeFindDependencyMacro)
 set(export_transitive_modules1_DIR \"${export_transitive_modules1_DIR}\")
@@ -49,6 +69,9 @@ add_test(NAME export_transitive_modules_build
     "-Dexpected_source_dir=${CMAKE_CURRENT_SOURCE_DIR}"
     "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_transitive_modules_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-Dexport_transitive_modules1_cps_DIR=${CMAKE_PREFIX_PATH}"
+    "-Dexport_transitive_modules_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 14 - 8
Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/test/CMakeLists.txt

@@ -2,13 +2,19 @@ cmake_minimum_required(VERSION 3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_transitive_modules REQUIRED)
+find_package(export_transitive_modules_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_transitive_modules1)
-  message(FATAL_ERROR
-    "Missing transitive imported target")
-endif ()
+function(test_namespace namespace namespace1)
+  if (NOT TARGET ${namespace1}::export_transitive_modules1)
+    message(FATAL_ERROR
+      "Missing transitive imported target")
+  endif ()
 
-if (NOT TARGET CXXModules::export_transitive_modules)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+  if (NOT TARGET ${namespace}::export_transitive_modules)
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+endfunction()
+
+test_namespace(CXXModules CXXModules)
+test_namespace(export_transitive_modules_cps export_transitive_modules1_cps)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 24 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt

@@ -4,6 +4,7 @@ project(cxx_modules_export_transitive_modules CXX)
 include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
 
 find_package(export_transitive_modules1 REQUIRED)
+find_package(export_transitive_modules1_cps REQUIRED)
 
 add_library(export_transitive_modules STATIC)
 target_sources(export_transitive_modules
@@ -17,14 +18,34 @@ target_sources(export_transitive_modules
 target_compile_features(export_transitive_modules PUBLIC cxx_std_20)
 target_link_libraries(export_transitive_modules PRIVATE CXXModules::export_transitive_modules1)
 
+add_library(export_transitive_modules_cps STATIC)
+target_sources(export_transitive_modules_cps
+  PUBLIC
+    FILE_SET modules TYPE CXX_MODULES
+      BASE_DIRS
+        "${CMAKE_CURRENT_SOURCE_DIR}"
+      FILES
+        importable.cxx
+  )
+target_compile_features(export_transitive_modules_cps PUBLIC cxx_std_20)
+target_link_libraries(export_transitive_modules_cps PRIVATE export_transitive_modules1_cps::export_transitive_modules1)
+set_target_properties(export_transitive_modules_cps PROPERTIES EXPORT_NAME export_transitive_modules)
+
 install(TARGETS export_transitive_modules
   EXPORT CXXModules
   FILE_SET modules DESTINATION "lib/cxx/miu")
+install(TARGETS export_transitive_modules_cps
+  EXPORT CXXModules_cps
+  FILE_SET modules DESTINATION "lib/cxx/miu")
 install(EXPORT CXXModules
   NAMESPACE CXXModules::
   DESTINATION "lib/cmake/export_transitive_modules"
   FILE "export_transitive_modules-targets.cmake"
   CXX_MODULES_DIRECTORY "export_transitive_modules-cxx-modules")
+install(PACKAGE_INFO "export_transitive_modules_cps"
+  EXPORT CXXModules_cps
+  DESTINATION "lib/cmake/export_transitive_modules_cps"
+  CXX_MODULES_DIRECTORY "export_transitive_modules-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_transitive_modules-config.cmake"
   "include(CMakeFindDependencyMacro)
 set(export_transitive_modules1_DIR \"${export_transitive_modules1_DIR}\")
@@ -52,6 +73,9 @@ add_test(NAME export_transitive_modules_build
     "-Dexpected_source_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
     "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
     "-Dexport_transitive_modules_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules"
+    "-Dexport_transitive_modules1_cps_DIR=${CMAKE_PREFIX_PATH}/lib/cmake/export_transitive_modules1_cps"
+    "-Dexport_transitive_modules_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules_cps"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 14 - 8
Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/test/CMakeLists.txt

@@ -2,13 +2,19 @@ cmake_minimum_required(VERSION 3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_transitive_modules REQUIRED)
+find_package(export_transitive_modules_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_transitive_modules1)
-  message(FATAL_ERROR
-    "Missing transitive imported target")
-endif ()
+function(test_namespace namespace namespace1)
+  if (NOT TARGET ${namespace1}::export_transitive_modules1)
+    message(FATAL_ERROR
+      "Missing transitive imported target")
+  endif ()
 
-if (NOT TARGET CXXModules::export_transitive_modules)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+  if (NOT TARGET ${namespace}::export_transitive_modules)
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+endfunction()
+
+test_namespace(CXXModules CXXModules)
+test_namespace(export_transitive_modules_cps export_transitive_modules1_cps)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt

@@ -21,6 +21,9 @@ export(EXPORT CXXModules
   NAMESPACE CXXModules::
   FILE "${CMAKE_CURRENT_BINARY_DIR}/export_transitive_modules1-targets.cmake"
   CXX_MODULES_DIRECTORY "export_transitive_modules1-cxx-modules")
+export(PACKAGE_INFO export_transitive_modules1_cps
+  EXPORT CXXModules
+  CXX_MODULES_DIRECTORY "export_transitive_modules1-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_transitive_modules1-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_transitive_modules1-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -43,6 +46,8 @@ add_test(NAME export_transitive_modules1_build
     "-Dexpected_source_dir=${CMAKE_CURRENT_SOURCE_DIR}"
     "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_transitive_modules1_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-Dexport_transitive_modules1_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 10 - 4
Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/test/CMakeLists.txt

@@ -2,8 +2,14 @@ cmake_minimum_required(VERSION 3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_transitive_modules1 REQUIRED)
+find_package(export_transitive_modules1_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_transitive_modules1)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+function(test_namespace namespace)
+  if (NOT TARGET ${namespace}::export_transitive_modules1)
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+endfunction()
+
+test_namespace(CXXModules)
+test_namespace(export_transitive_modules1_cps)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 6 - 0
Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt

@@ -22,6 +22,10 @@ install(EXPORT CXXModules
   DESTINATION "lib/cmake/export_transitive_modules1"
   FILE "export_transitive_modules1-targets.cmake"
   CXX_MODULES_DIRECTORY "export_transitive_modules1-cxx-modules")
+install(PACKAGE_INFO "export_transitive_modules1_cps"
+  EXPORT CXXModules
+  DESTINATION "lib/cmake/export_transitive_modules1_cps"
+  CXX_MODULES_DIRECTORY "export_transitive_modules1-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_transitive_modules1-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_transitive_modules1-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -46,6 +50,8 @@ add_test(NAME export_transitive_modules1_build
     "-Dexpected_source_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
     "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
     "-Dexport_transitive_modules1_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules1"
+    "-Dexport_transitive_modules1_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules1_cps"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 10 - 4
Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/test/CMakeLists.txt

@@ -2,8 +2,14 @@ cmake_minimum_required(VERSION 3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_transitive_modules1 REQUIRED)
+find_package(export_transitive_modules1_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_transitive_modules1)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
+function(test_namespace namespace)
+  if (NOT TARGET ${namespace}::export_transitive_modules1)
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+endfunction()
+
+test_namespace(CXXModules)
+test_namespace(export_transitive_modules1_cps)

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt

@@ -24,6 +24,9 @@ export(EXPORT CXXModules
   NAMESPACE CXXModules::
   FILE "${CMAKE_CURRENT_BINARY_DIR}/export_with_headers-targets.cmake"
   CXX_MODULES_DIRECTORY "export_with_headers-cxx-modules")
+export(PACKAGE_INFO export_with_headers_cps
+  EXPORT CXXModules
+  CXX_MODULES_DIRECTORY "export_with_headers-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_with_headers-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_with_headers-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -44,6 +47,8 @@ add_test(NAME export_with_headers_build
   COMMAND
     "${CMAKE_COMMAND}"
     "-Dexport_with_headers_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-Dexport_with_headers_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 20 - 11
Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/test/CMakeLists.txt

@@ -2,18 +2,27 @@ cmake_minimum_required(VERSION 3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_with_headers REQUIRED)
+find_package(export_with_headers_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_with_headers)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
-
-get_property(iface_includes TARGET CXXModules::export_with_headers
-  PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
 set(include_dir "${CMAKE_CURRENT_SOURCE_DIR}")
 cmake_path(GET include_dir PARENT_PATH include_dir)
 string(APPEND include_dir "/include")
-if (NOT iface_includes STREQUAL "${include_dir};$<BUILD_INTERFACE:${include_dir}>")
-  message(FATAL_ERROR
-    "Incorrect include interface for CXXModules::export_with_headers:\n  ${iface_includes}")
-endif ()
+
+function(test_target target incdir)
+
+  if (NOT TARGET ${target})
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+
+  get_property(iface_includes TARGET ${target}
+    PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
+  if (NOT iface_includes STREQUAL incdir)
+    message(FATAL_ERROR
+      "Incorrect include interface for ${target}:\n  ${iface_includes}")
+  endif ()
+
+endfunction(test_target)
+
+test_target(CXXModules::export_with_headers "${include_dir};$<BUILD_INTERFACE:${include_dir}>")
+test_target(export_with_headers_cps::export_with_headers "${include_dir}")

+ 5 - 0
Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt

@@ -0,0 +1,5 @@
+CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
+  CMake's support for exporting package information in the Common Package
+  Specification format is experimental\.  It is meant only for experimentation
+  and feedback to CMake developers\.
+This warning is for project developers\.  Use -Wno-dev to suppress it

+ 6 - 0
Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt

@@ -24,6 +24,10 @@ install(EXPORT CXXModules
   NAMESPACE CXXModules::
   DESTINATION "lib/cmake/export_with_headers"
   FILE "export_with_headers-targets.cmake")
+install(PACKAGE_INFO "export_with_headers_cps"
+  EXPORT CXXModules
+  DESTINATION "lib/cmake/export_with_headers_cps"
+  CXX_MODULES_DIRECTORY "export_with_headers-cxx-modules-cps")
 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_with_headers-config.cmake"
   "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_with_headers-targets.cmake\")
 set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
@@ -46,6 +50,8 @@ add_test(NAME export_with_headers_build
   COMMAND
     "${CMAKE_COMMAND}"
     "-Dexport_with_headers_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_with_headers"
+    "-Dexport_with_headers_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_with_headers_cps"
+    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")

+ 20 - 11
Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/test/CMakeLists.txt

@@ -2,20 +2,29 @@ cmake_minimum_required(VERSION 3.28)
 project(cxx_modules_library NONE)
 
 find_package(export_with_headers REQUIRED)
+find_package(export_with_headers_cps REQUIRED)
 
-if (NOT TARGET CXXModules::export_with_headers)
-  message(FATAL_ERROR
-    "Missing imported target")
-endif ()
-
-get_property(iface_includes TARGET CXXModules::export_with_headers
-  PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
 set(include_dir "${export_with_headers_DIR}")
 cmake_path(GET include_dir PARENT_PATH include_dir)
 cmake_path(GET include_dir PARENT_PATH include_dir)
 cmake_path(GET include_dir PARENT_PATH include_dir)
 string(APPEND include_dir "/include")
-if (NOT iface_includes STREQUAL "$<BUILD_INTERFACE:${include_dir}>")
-  message(FATAL_ERROR
-    "Incorrect include interface for CXXModules::export_with_headers:\n  ${iface_includes}")
-endif ()
+
+function(test_target target incdir)
+
+  if (NOT TARGET ${target})
+    message(FATAL_ERROR
+      "Missing imported target")
+  endif ()
+
+  get_property(iface_includes TARGET ${target}
+    PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
+  if (NOT iface_includes STREQUAL incdir)
+    message(FATAL_ERROR
+      "Incorrect include interface for ${target}:\n  ${iface_includes}")
+  endif ()
+
+endfunction(test_target)
+
+test_target(CXXModules::export_with_headers "$<BUILD_INTERFACE:${include_dir}>")
+test_target(export_with_headers_cps::export_with_headers "${include_dir}")