Ver Fonte

CPS: Get metadata from project

Modify {export,install}(PACKAGE_INFO) commands to inherit version
information from the current project in situations where it seems
reasonable to do so. Add an option to explicitly request inheritance
from a specific project.

This leverages the recently added project(COMPAT_VERSION).
Matthew Woehlke há 4 meses atrás
pai
commit
ecf81c1bc1
26 ficheiros alterados com 298 adições e 4 exclusões
  1. 1 0
      Help/command/export.rst
  2. 10 1
      Help/command/install.rst
  3. 3 2
      Source/cmExportCommand.cxx
  4. 1 1
      Source/cmInstallCommand.cxx
  5. 84 0
      Source/cmPackageInfoArguments.cxx
  6. 13 0
      Source/cmPackageInfoArguments.h
  7. 12 0
      Tests/RunCMake/ExportPackageInfo/BadArgs1-stderr.txt
  8. 2 0
      Tests/RunCMake/ExportPackageInfo/BadArgs1.cmake
  9. 6 0
      Tests/RunCMake/ExportPackageInfo/BadArgs2-stderr.txt
  10. 1 0
      Tests/RunCMake/ExportPackageInfo/BadArgs2.cmake
  11. 12 0
      Tests/RunCMake/ExportPackageInfo/BadArgs4-stderr.txt
  12. 2 0
      Tests/RunCMake/ExportPackageInfo/BadArgs4.cmake
  13. 8 0
      Tests/RunCMake/ExportPackageInfo/NoProjectMetadata-check.cmake
  14. 10 0
      Tests/RunCMake/ExportPackageInfo/NoProjectMetadata.cmake
  15. 18 0
      Tests/RunCMake/ExportPackageInfo/ProjectMetadata-check.cmake
  16. 25 0
      Tests/RunCMake/ExportPackageInfo/ProjectMetadata.cmake
  17. 2 0
      Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake
  18. 12 0
      Tests/RunCMake/InstallPackageInfo/BadArgs1-stderr.txt
  19. 2 0
      Tests/RunCMake/InstallPackageInfo/BadArgs1.cmake
  20. 6 0
      Tests/RunCMake/InstallPackageInfo/BadArgs2-stderr.txt
  21. 1 0
      Tests/RunCMake/InstallPackageInfo/BadArgs2.cmake
  22. 8 0
      Tests/RunCMake/InstallPackageInfo/NoProjectMetadata-check.cmake
  23. 11 0
      Tests/RunCMake/InstallPackageInfo/NoProjectMetadata.cmake
  24. 18 0
      Tests/RunCMake/InstallPackageInfo/ProjectMetadata-check.cmake
  25. 28 0
      Tests/RunCMake/InstallPackageInfo/ProjectMetadata.cmake
  26. 2 0
      Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake

+ 1 - 0
Help/command/export.rst

@@ -133,6 +133,7 @@ Exporting Targets to the |CPS|
 .. code-block:: cmake
 .. code-block:: cmake
 
 
   export(EXPORT <export-name> PACKAGE_INFO <package-name>
   export(EXPORT <export-name> PACKAGE_INFO <package-name>
+         [PROJECT <project-name>|NO_PROJECT_METADATA]
          [APPENDIX <appendix-name>]
          [APPENDIX <appendix-name>]
          [LOWER_CASE_FILE]
          [LOWER_CASE_FILE]
          [VERSION <version>
          [VERSION <version>

+ 10 - 1
Help/command/install.rst

@@ -992,6 +992,7 @@ Signatures
   .. code-block:: cmake
   .. code-block:: cmake
 
 
     install(PACKAGE_INFO <package-name> EXPORT <export-name>
     install(PACKAGE_INFO <package-name> EXPORT <export-name>
+            [PROJECT <project-name>|NO_PROJECT_METADATA]
             [APPENDIX <appendix-name>]
             [APPENDIX <appendix-name>]
             [DESTINATION <dir>]
             [DESTINATION <dir>]
             [LOWER_CASE_FILE]
             [LOWER_CASE_FILE]
@@ -1056,6 +1057,14 @@ Signatures
     configurations exists.  If not specified, CMake will fall back to the
     configurations exists.  If not specified, CMake will fall back to the
     package's available configurations in an unspecified order.
     package's available configurations in an unspecified order.
 
 
+  By default, if the specified ``<package-name>`` matches the current CMake
+  :variable:`PROJECT_NAME`, package metadata will be inherited from the
+  project.  The ``PROJECT <project-name>`` option may be used to specify a
+  different project from which to inherit metadata.  If ``NO_PROJECT_METADATA``
+  is specified, automatic inheritance of package metadata will be disabled.
+  In any case, any metadata values specified in the ``install`` command will
+  take precedence.
+
   If ``APPENDIX`` is specified, rather than generating a top level package
   If ``APPENDIX`` is specified, rather than generating a top level package
   specification, the specified targets will be exported as an appendix to the
   specification, the specified targets will be exported as an appendix to the
   named package.  Appendices may be used to separate less commonly used targets
   named package.  Appendices may be used to separate less commonly used targets
@@ -1065,7 +1074,7 @@ Signatures
   artifacts produced by multiple build trees.
   artifacts produced by multiple build trees.
 
 
   Appendices are not permitted to change basic package metadata; therefore,
   Appendices are not permitted to change basic package metadata; therefore,
-  none of ``VERSION``, ``COMPAT_VERSION``, ``VERSION_SCHEMA``,
+  none of ``PROJECT``, ``VERSION``, ``COMPAT_VERSION``, ``VERSION_SCHEMA``,
   ``DEFAULT_TARGETS`` or ``DEFAULT_CONFIGURATIONS`` may be specified in
   ``DEFAULT_TARGETS`` or ``DEFAULT_CONFIGURATIONS`` may be specified in
   combination with ``APPENDIX``.  Additionally, it is strongly recommended that
   combination with ``APPENDIX``.  Additionally, it is strongly recommended that
   use of ``LOWER_CASE_FILE`` should be consistent between the main package and
   use of ``LOWER_CASE_FILE`` should be consistent between the main package and

+ 3 - 2
Source/cmExportCommand.cxx

@@ -114,7 +114,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
   }
   }
 
 
   std::vector<std::string> unknownArgs;
   std::vector<std::string> unknownArgs;
-  Arguments const arguments = parser.Parse(args, &unknownArgs);
+  Arguments arguments = parser.Parse(args, &unknownArgs);
 
 
   if (!unknownArgs.empty()) {
   if (!unknownArgs.empty()) {
     status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
     status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
@@ -219,7 +219,8 @@ bool cmExportCommand(std::vector<std::string> const& args,
       status.SetError("PACKAGE_INFO and NAMESPACE are mutually exclusive.");
       status.SetError("PACKAGE_INFO and NAMESPACE are mutually exclusive.");
       return false;
       return false;
     }
     }
-    if (!arguments.Check(status)) {
+    if (!arguments.Check(status) ||
+        !arguments.SetMetadataFromProject(status)) {
       return false;
       return false;
     }
     }
   }
   }

+ 1 - 1
Source/cmInstallCommand.cxx

@@ -2202,7 +2202,7 @@ bool HandlePackageInfoMode(std::vector<std::string> const& args,
     return false;
     return false;
   }
   }
 
 
-  if (!arguments.Check(status)) {
+  if (!arguments.Check(status) || !arguments.SetMetadataFromProject(status)) {
     return false;
     return false;
   }
   }
 
 

+ 84 - 0
Source/cmPackageInfoArguments.cxx

@@ -2,10 +2,15 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmPackageInfoArguments.h"
 #include "cmPackageInfoArguments.h"
 
 
+#include <utility>
+
 #include "cmExecutionStatus.h"
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
+#include "cmMakefile.h"
+#include "cmStateSnapshot.h"
 #include "cmStringAlgorithms.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmSystemTools.h"
+#include "cmValue.h"
 
 
 template void cmPackageInfoArguments::Bind<void>(cmArgumentParser<void>&,
 template void cmPackageInfoArguments::Bind<void>(cmArgumentParser<void>&,
                                                  cmPackageInfoArguments*);
                                                  cmPackageInfoArguments*);
@@ -35,6 +40,14 @@ bool cmPackageInfoArguments::Check(cmExecutionStatus& status,
       status.SetError("DEFAULT_CONFIGURATIONS requires PACKAGE_INFO.");
       status.SetError("DEFAULT_CONFIGURATIONS requires PACKAGE_INFO.");
       return false;
       return false;
     }
     }
+    if (!this->ProjectName.empty()) {
+      status.SetError("PROJECT requires PACKAGE_INFO.");
+      return false;
+    }
+    if (this->NoProjectDefaults) {
+      status.SetError("NO_PROJECT_METADATA requires PACKAGE_INFO.");
+      return false;
+    }
   }
   }
 
 
   // Check for incompatible options.
   // Check for incompatible options.
@@ -53,6 +66,17 @@ bool cmPackageInfoArguments::Check(cmExecutionStatus& status,
                       "are mutually exclusive.");
                       "are mutually exclusive.");
       return false;
       return false;
     }
     }
+    if (!this->ProjectName.empty()) {
+      status.SetError("APPENDIX and PROJECT are mutually exclusive.");
+      return false;
+    }
+  }
+  if (this->NoProjectDefaults) {
+    if (!this->ProjectName.empty()) {
+      status.SetError("PROJECT and NO_PROJECT_METADATA "
+                      "are mutually exclusive.");
+      return false;
+    }
   }
   }
 
 
   // Check for options that require other options.
   // Check for options that require other options.
@@ -81,6 +105,66 @@ bool cmPackageInfoArguments::Check(cmExecutionStatus& status,
   return true;
   return true;
 }
 }
 
 
+bool cmPackageInfoArguments::SetMetadataFromProject(cmExecutionStatus& status)
+{
+  // Determine what project to use for inherited metadata.
+  if (!this->SetEffectiveProject(status)) {
+    return false;
+  }
+
+  if (this->ProjectName.empty()) {
+    // We are not inheriting from a project.
+    return true;
+  }
+
+  cmMakefile& mf = status.GetMakefile();
+  if (this->Version.empty()) {
+    cmValue const& version =
+      mf.GetDefinition(cmStrCat(this->ProjectName, "_VERSION"_s));
+    if (version) {
+      this->Version = version;
+      cmValue const& compatVersion =
+        mf.GetDefinition(cmStrCat(this->ProjectName, "_COMPAT_VERSION"_s));
+      if (compatVersion) {
+        this->VersionCompat = compatVersion;
+      }
+    }
+  }
+
+  return true;
+}
+
+bool cmPackageInfoArguments::SetEffectiveProject(cmExecutionStatus& status)
+{
+  if (!this->Appendix.empty()) {
+    // Appendices are not allowed to specify package metadata.
+    return true;
+  }
+
+  if (this->NoProjectDefaults) {
+    // User requested that metadata not be inherited.
+    return true;
+  }
+
+  cmMakefile& mf = status.GetMakefile();
+  if (!this->ProjectName.empty()) {
+    // User specified a project; make sure it exists.
+    if (!mf.GetStateSnapshot().CheckProjectName(this->ProjectName)) {
+      status.SetError(cmStrCat(R"(PROJECT given invalid project name ")"_s,
+                               this->ProjectName, R"(".)"_s));
+      return false;
+    }
+  } else {
+    // No project was specified; check if the package name is also a project.
+    std::string project = mf.GetStateSnapshot().GetProjectName();
+    if (this->PackageName == project) {
+      this->ProjectName = std::move(project);
+    }
+  }
+
+  return true;
+}
+
 std::string cmPackageInfoArguments::GetNamespace() const
 std::string cmPackageInfoArguments::GetNamespace() const
 {
 {
   return cmStrCat(this->PackageName, "::"_s);
   return cmStrCat(this->PackageName, "::"_s);

+ 13 - 0
Source/cmPackageInfoArguments.h

@@ -47,6 +47,10 @@ public:
   /// \c false, forbid specifying any options whatsoever.
   /// \c false, forbid specifying any options whatsoever.
   bool Check(cmExecutionStatus& status, bool enable = true) const;
   bool Check(cmExecutionStatus& status, bool enable = true) const;
 
 
+  /// Set metadata (not already specified) from either the specified project,
+  /// or from the project which matches the package name.
+  bool SetMetadataFromProject(cmExecutionStatus& status);
+
   ArgumentParser::NonEmpty<std::string> PackageName;
   ArgumentParser::NonEmpty<std::string> PackageName;
   ArgumentParser::NonEmpty<std::string> Appendix;
   ArgumentParser::NonEmpty<std::string> Appendix;
   ArgumentParser::NonEmpty<std::string> Version;
   ArgumentParser::NonEmpty<std::string> Version;
@@ -56,7 +60,12 @@ public:
   ArgumentParser::NonEmpty<std::vector<std::string>> DefaultConfigs;
   ArgumentParser::NonEmpty<std::vector<std::string>> DefaultConfigs;
   bool LowerCase = false;
   bool LowerCase = false;
 
 
+  ArgumentParser::NonEmpty<std::string> ProjectName;
+  bool NoProjectDefaults = false;
+
 private:
 private:
+  bool SetEffectiveProject(cmExecutionStatus& status);
+
   template <typename T>
   template <typename T>
   static void Bind(cmArgumentParser<T>& parser, cmPackageInfoArguments* self)
   static void Bind(cmArgumentParser<T>& parser, cmPackageInfoArguments* self)
   {
   {
@@ -73,6 +82,10 @@ private:
          &cmPackageInfoArguments::DefaultTargets);
          &cmPackageInfoArguments::DefaultTargets);
     Bind(self, parser, "DEFAULT_CONFIGURATIONS"_s,
     Bind(self, parser, "DEFAULT_CONFIGURATIONS"_s,
          &cmPackageInfoArguments::DefaultConfigs);
          &cmPackageInfoArguments::DefaultConfigs);
+
+    Bind(self, parser, "PROJECT"_s, &cmPackageInfoArguments::ProjectName);
+    Bind(self, parser, "NO_PROJECT_METADATA"_s,
+         &cmPackageInfoArguments::NoProjectDefaults);
   }
   }
 
 
   template <typename T, typename U,
   template <typename T, typename U,

+ 12 - 0
Tests/RunCMake/ExportPackageInfo/BadArgs1-stderr.txt

@@ -8,3 +8,15 @@ CMake Error at BadArgs1\.cmake:4 \(export\):
   export VERSION_SCHEMA requires VERSION\.
   export VERSION_SCHEMA requires VERSION\.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs1\.cmake:5 \(export\):
+  export PROJECT and NO_PROJECT_METADATA are mutually exclusive\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs1\.cmake:6 \(export\):
+  export PROJECT given invalid project name "bar"\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/ExportPackageInfo/BadArgs1.cmake

@@ -2,3 +2,5 @@ add_library(foo INTERFACE)
 install(TARGETS foo EXPORT foo DESTINATION .)
 install(TARGETS foo EXPORT foo DESTINATION .)
 export(EXPORT foo PACKAGE_INFO foo COMPAT_VERSION 1.0)
 export(EXPORT foo PACKAGE_INFO foo COMPAT_VERSION 1.0)
 export(EXPORT foo PACKAGE_INFO foo VERSION_SCHEMA simple)
 export(EXPORT foo PACKAGE_INFO foo VERSION_SCHEMA simple)
+export(EXPORT foo PACKAGE_INFO foo PROJECT foo NO_PROJECT_METADATA)
+export(EXPORT foo PACKAGE_INFO foo PROJECT bar)

+ 6 - 0
Tests/RunCMake/ExportPackageInfo/BadArgs2-stderr.txt

@@ -14,3 +14,9 @@ CMake Error at BadArgs2\.cmake:5 \(export\):
   export APPENDIX and DEFAULT_CONFIGURATIONS are mutually exclusive\.
   export APPENDIX and DEFAULT_CONFIGURATIONS are mutually exclusive\.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs2\.cmake:6 \(export\):
+  export APPENDIX and PROJECT are mutually exclusive\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)

+ 1 - 0
Tests/RunCMake/ExportPackageInfo/BadArgs2.cmake

@@ -3,3 +3,4 @@ install(TARGETS foo EXPORT foo DESTINATION .)
 export(EXPORT foo PACKAGE_INFO foo APPENDIX test VERSION 1.0)
 export(EXPORT foo PACKAGE_INFO foo APPENDIX test VERSION 1.0)
 export(EXPORT foo PACKAGE_INFO foo APPENDIX test DEFAULT_TARGETS foo)
 export(EXPORT foo PACKAGE_INFO foo APPENDIX test DEFAULT_TARGETS foo)
 export(EXPORT foo PACKAGE_INFO foo APPENDIX test DEFAULT_CONFIGURATIONS Release)
 export(EXPORT foo PACKAGE_INFO foo APPENDIX test DEFAULT_CONFIGURATIONS Release)
+export(EXPORT foo PACKAGE_INFO foo APPENDIX test PROJECT foo)

+ 12 - 0
Tests/RunCMake/ExportPackageInfo/BadArgs4-stderr.txt

@@ -26,3 +26,15 @@ CMake Error at BadArgs4\.cmake:7 \(export\):
   export DEFAULT_CONFIGURATIONS requires PACKAGE_INFO\.
   export DEFAULT_CONFIGURATIONS requires PACKAGE_INFO\.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs4\.cmake:8 \(export\):
+  export PROJECT requires PACKAGE_INFO\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs4\.cmake:9 \(export\):
+  export NO_PROJECT_METADATA requires PACKAGE_INFO\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/ExportPackageInfo/BadArgs4.cmake

@@ -5,3 +5,5 @@ export(EXPORT foo APPENDIX test)
 export(EXPORT foo VERSION 1.0)
 export(EXPORT foo VERSION 1.0)
 export(EXPORT foo DEFAULT_TARGETS foo)
 export(EXPORT foo DEFAULT_TARGETS foo)
 export(EXPORT foo DEFAULT_CONFIGURATIONS Release)
 export(EXPORT foo DEFAULT_CONFIGURATIONS Release)
+export(EXPORT foo PROJECT foo)
+export(EXPORT foo NO_PROJECT_METADATA)

+ 8 - 0
Tests/RunCMake/ExportPackageInfo/NoProjectMetadata-check.cmake

@@ -0,0 +1,8 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/NoProjectMetadata-build")
+
+file(READ "${out_dir}/foo.cps" content)
+expect_value("${content}" "foo" "name")
+expect_missing("${content}" "version")
+expect_missing("${content}" "compat_version")

+ 10 - 0
Tests/RunCMake/ExportPackageInfo/NoProjectMetadata.cmake

@@ -0,0 +1,10 @@
+project(foo VERSION 1.2.3 COMPAT_VERSION 1.1.0)
+
+add_library(foo INTERFACE)
+install(TARGETS foo EXPORT foo DESTINATION .)
+
+export(
+  EXPORT foo
+  PACKAGE_INFO foo
+  NO_PROJECT_METADATA
+  )

+ 18 - 0
Tests/RunCMake/ExportPackageInfo/ProjectMetadata-check.cmake

@@ -0,0 +1,18 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/ProjectMetadata-build")
+
+file(READ "${out_dir}/foo.cps" content)
+expect_value("${content}" "foo" "name")
+expect_value("${content}" "1.2.3" "version")
+expect_value("${content}" "1.1.0" "compat_version")
+
+file(READ "${out_dir}/test1.cps" content)
+expect_value("${content}" "test1" "name")
+expect_value("${content}" "1.2.3" "version")
+expect_value("${content}" "1.1.0" "compat_version")
+
+file(READ "${out_dir}/test2.cps" content)
+expect_value("${content}" "test2" "name")
+expect_value("${content}" "1.4.7" "version")
+expect_missing("${content}" "compat_version")

+ 25 - 0
Tests/RunCMake/ExportPackageInfo/ProjectMetadata.cmake

@@ -0,0 +1,25 @@
+project(foo VERSION 1.2.3 COMPAT_VERSION 1.1.0)
+
+add_library(foo INTERFACE)
+install(TARGETS foo EXPORT foo DESTINATION .)
+
+# Test inheriting from project matching package name.
+export(
+  EXPORT foo
+  PACKAGE_INFO foo
+  )
+
+# Test inheriting from a specified project.
+export(
+  EXPORT foo
+  PROJECT foo
+  PACKAGE_INFO test1
+  )
+
+# Test that inheriting doesn't override explicitly specified metadata.
+export(
+  EXPORT foo
+  PROJECT foo
+  PACKAGE_INFO test2
+  VERSION 1.4.7
+  )

+ 2 - 0
Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake

@@ -31,6 +31,8 @@ run_cmake(LinkOnlyRecursive)
 run_cmake(Appendix)
 run_cmake(Appendix)
 run_cmake(InterfaceProperties)
 run_cmake(InterfaceProperties)
 run_cmake(Metadata)
 run_cmake(Metadata)
+run_cmake(ProjectMetadata)
+run_cmake(NoProjectMetadata)
 run_cmake(Minimal)
 run_cmake(Minimal)
 run_cmake(MinimalVersion)
 run_cmake(MinimalVersion)
 run_cmake(LowerCaseFile)
 run_cmake(LowerCaseFile)

+ 12 - 0
Tests/RunCMake/InstallPackageInfo/BadArgs1-stderr.txt

@@ -8,3 +8,15 @@ CMake Error at BadArgs1.cmake:4 \(install\):
   install VERSION_SCHEMA requires VERSION.
   install VERSION_SCHEMA requires VERSION.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs1\.cmake:5 \(install\):
+  install PROJECT and NO_PROJECT_METADATA are mutually exclusive\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs1\.cmake:6 \(install\):
+  install PROJECT given invalid project name "bar"\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/InstallPackageInfo/BadArgs1.cmake

@@ -2,3 +2,5 @@ add_library(foo INTERFACE)
 install(TARGETS foo EXPORT foo DESTINATION .)
 install(TARGETS foo EXPORT foo DESTINATION .)
 install(PACKAGE_INFO test EXPORT foo COMPAT_VERSION 1.0)
 install(PACKAGE_INFO test EXPORT foo COMPAT_VERSION 1.0)
 install(PACKAGE_INFO test EXPORT foo VERSION_SCHEMA simple)
 install(PACKAGE_INFO test EXPORT foo VERSION_SCHEMA simple)
+install(PACKAGE_INFO test EXPORT foo PROJECT foo NO_PROJECT_METADATA)
+install(PACKAGE_INFO test EXPORT foo PROJECT bar)

+ 6 - 0
Tests/RunCMake/InstallPackageInfo/BadArgs2-stderr.txt

@@ -14,3 +14,9 @@ CMake Error at BadArgs2.cmake:5 \(install\):
   install APPENDIX and DEFAULT_CONFIGURATIONS are mutually exclusive.
   install APPENDIX and DEFAULT_CONFIGURATIONS are mutually exclusive.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs2.cmake:6 \(install\):
+  install APPENDIX and PROJECT are mutually exclusive.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)

+ 1 - 0
Tests/RunCMake/InstallPackageInfo/BadArgs2.cmake

@@ -3,3 +3,4 @@ install(TARGETS foo EXPORT foo DESTINATION .)
 install(PACKAGE_INFO test EXPORT foo APPENDIX test VERSION 1.0)
 install(PACKAGE_INFO test EXPORT foo APPENDIX test VERSION 1.0)
 install(PACKAGE_INFO test EXPORT foo APPENDIX test DEFAULT_TARGETS foo)
 install(PACKAGE_INFO test EXPORT foo APPENDIX test DEFAULT_TARGETS foo)
 install(PACKAGE_INFO test EXPORT foo APPENDIX test DEFAULT_CONFIGURATIONS test)
 install(PACKAGE_INFO test EXPORT foo APPENDIX test DEFAULT_CONFIGURATIONS test)
+install(PACKAGE_INFO test EXPORT foo APPENDIX test PROJECT foo)

+ 8 - 0
Tests/RunCMake/InstallPackageInfo/NoProjectMetadata-check.cmake

@@ -0,0 +1,8 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/NoProjectMetadata-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
+
+file(READ "${out_dir}/foo.cps" content)
+expect_value("${content}" "foo" "name")
+expect_missing("${content}" "version")
+expect_missing("${content}" "compat_version")

+ 11 - 0
Tests/RunCMake/InstallPackageInfo/NoProjectMetadata.cmake

@@ -0,0 +1,11 @@
+project(foo VERSION 1.2.3 COMPAT_VERSION 1.1.0)
+
+add_library(foo INTERFACE)
+install(TARGETS foo EXPORT foo DESTINATION .)
+
+install(
+  PACKAGE_INFO foo
+  DESTINATION cps
+  EXPORT foo
+  NO_PROJECT_METADATA
+  )

+ 18 - 0
Tests/RunCMake/InstallPackageInfo/ProjectMetadata-check.cmake

@@ -0,0 +1,18 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/ProjectMetadata-build/CMakeFiles/Export/510c5684a4a8a792eadfb55bc9744983")
+
+file(READ "${out_dir}/foo.cps" content)
+expect_value("${content}" "foo" "name")
+expect_value("${content}" "1.2.3" "version")
+expect_value("${content}" "1.1.0" "compat_version")
+
+file(READ "${out_dir}/test1.cps" content)
+expect_value("${content}" "test1" "name")
+expect_value("${content}" "1.2.3" "version")
+expect_value("${content}" "1.1.0" "compat_version")
+
+file(READ "${out_dir}/test2.cps" content)
+expect_value("${content}" "test2" "name")
+expect_value("${content}" "1.4.7" "version")
+expect_missing("${content}" "compat_version")

+ 28 - 0
Tests/RunCMake/InstallPackageInfo/ProjectMetadata.cmake

@@ -0,0 +1,28 @@
+project(foo VERSION 1.2.3 COMPAT_VERSION 1.1.0)
+
+add_library(foo INTERFACE)
+install(TARGETS foo EXPORT foo DESTINATION .)
+
+# Test inheriting from project matching package name.
+install(
+  PACKAGE_INFO foo
+  DESTINATION cps
+  EXPORT foo
+  )
+
+# Test inheriting from a specified project.
+install(
+  PACKAGE_INFO test1
+  DESTINATION cps
+  EXPORT foo
+  PROJECT foo
+  )
+
+# Test that inheriting doesn't override explicitly specified metadata.
+install(
+  PACKAGE_INFO test2
+  DESTINATION cps
+  EXPORT foo
+  PROJECT foo
+  VERSION 1.4.7
+  )

+ 2 - 0
Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake

@@ -39,6 +39,8 @@ run_cmake(DependsMultipleDifferentSets)
 run_cmake(Appendix)
 run_cmake(Appendix)
 run_cmake(InterfaceProperties)
 run_cmake(InterfaceProperties)
 run_cmake(Metadata)
 run_cmake(Metadata)
+run_cmake(ProjectMetadata)
+run_cmake(NoProjectMetadata)
 run_cmake(Minimal)
 run_cmake(Minimal)
 run_cmake(MinimalVersion)
 run_cmake(MinimalVersion)
 run_cmake(LowerCaseFile)
 run_cmake(LowerCaseFile)