Explorar o código

CPS: Add export support for [default_]license

Add `LICENSE` and `DEFAULT_LICENSE` arguments to the `PACKAGE_INFO`
modes of the `install` and `export` commands. If not otherwise
specified, the `LICENSE` will be taken from the project's
`SPDX_LICENSE`, if available.
Matthew Woehlke hai 7 meses
pai
achega
755a24ccae

+ 2 - 0
Help/command/export.rst

@@ -141,6 +141,8 @@ Exporting Targets to the |CPS|
           [VERSION_SCHEMA <string>]]
           [VERSION_SCHEMA <string>]]
          [DEFAULT_TARGETS <target>...]
          [DEFAULT_TARGETS <target>...]
          [DEFAULT_CONFIGURATIONS <config>...]
          [DEFAULT_CONFIGURATIONS <config>...]
+         [LICENSE <license-string>]
+         [DEFAULT_LICENSE <license-string>]
          [DESCRIPTION <description-string>]
          [DESCRIPTION <description-string>]
          [HOMEPAGE_URL <url-string>])
          [HOMEPAGE_URL <url-string>])
 
 

+ 26 - 0
Help/command/install.rst

@@ -1001,6 +1001,8 @@ Signatures
              [VERSION_SCHEMA <string>]]
              [VERSION_SCHEMA <string>]]
             [DEFAULT_TARGETS <target>...]
             [DEFAULT_TARGETS <target>...]
             [DEFAULT_CONFIGURATIONS <config>...]
             [DEFAULT_CONFIGURATIONS <config>...]
+            [LICENSE <license-string>]
+            [DEFAULT_LICENSE <license-string>]
             [DESCRIPTION <description-string>]
             [DESCRIPTION <description-string>]
             [HOMEPAGE_URL <url-string>]
             [HOMEPAGE_URL <url-string>]
             [PERMISSIONS <permission>...]
             [PERMISSIONS <permission>...]
@@ -1059,6 +1061,24 @@ 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.
 
 
+  ``LICENSE <license-string>``
+    .. versionadded:: 4.2
+
+    A |SPDX|_ (SPDX) `License Expression`_ that describes the license(s) of the
+    project as a whole, including documentation, resources, or other materials
+    distributed with the project, in addition to software artifacts.  See the
+    SPDX `License List`_ for a list of commonly used licenses and their
+    identifiers.
+
+    The license of individual components is taken from the
+    :prop_tgt:`SPDX_LICENSE` property of their respective targets.
+
+  ``DEFAULT_LICENSE <license-string>``
+    .. versionadded:: 4.2
+
+    A |SPDX|_ (SPDX) `License Expression`_ that describes the license(s) of any
+    components which do not otherwise specify their license(s).
+
   ``DESCRIPTION <description-string>``
   ``DESCRIPTION <description-string>``
     .. versionadded:: 4.1
     .. versionadded:: 4.1
 
 
@@ -1291,3 +1311,9 @@ and by CPack. You can also invoke this script manually with
 
 
 .. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema
 .. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema
 .. |cps-version_schema| replace:: ``version_schema``
 .. |cps-version_schema| replace:: ``version_schema``
+
+.. _SPDX: https://spdx.dev/
+.. |SPDX| replace:: System Package Data Exchange
+
+.. _License Expression: https://spdx.github.io/spdx-spec/v3.0.1/annexes/spdx-license-expressions/
+.. _License List: https://spdx.org/licenses/

+ 5 - 4
Help/command/project.rst

@@ -173,10 +173,11 @@ By default ``C`` and ``CXX`` are enabled if no language options are given.
 Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
 Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
 to skip enabling any languages.
 to skip enabling any languages.
 
 
-The variables set through the ``VERSION``, ``COMPAT_VERSION``, ``DESCRIPTION``
-and ``HOMEPAGE_URL`` options are intended for use as default values in package
-metadata and documentation. The :command:`export` and :command:`install`
-commands use these accordingly when generating |CPS| package descriptions.
+The variables set through the ``VERSION``, ``COMPAT_VERSION``,
+``SPDX_LICENSE``, ``DESCRIPTION`` and ``HOMEPAGE_URL`` options are
+intended for use as default values in package metadata and documentation.
+The :command:`export` and :command:`install` commands use these accordingly
+when generating |CPS| package descriptions.
 
 
 .. |CPS| replace:: Common Package Specification
 .. |CPS| replace:: Common Package Specification
 
 

+ 4 - 1
Source/cmExportPackageInfoGenerator.cxx

@@ -39,6 +39,8 @@ cmExportPackageInfoGenerator::cmExportPackageInfoGenerator(
   , PackageVersionSchema(std::move(arguments.VersionSchema))
   , PackageVersionSchema(std::move(arguments.VersionSchema))
   , PackageDescription(std::move(arguments.Description))
   , PackageDescription(std::move(arguments.Description))
   , PackageWebsite(std::move(arguments.Website))
   , PackageWebsite(std::move(arguments.Website))
+  , PackageLicense(std::move(arguments.License))
+  , DefaultLicense(std::move(arguments.DefaultLicense))
   , DefaultTargets(std::move(arguments.DefaultTargets))
   , DefaultTargets(std::move(arguments.DefaultTargets))
   , DefaultConfigurations(std::move(arguments.DefaultConfigs))
   , DefaultConfigurations(std::move(arguments.DefaultConfigs))
 {
 {
@@ -127,7 +129,8 @@ Json::Value cmExportPackageInfoGenerator::GeneratePackageInfo() const
 
 
   SetProperty(package, "description", this->PackageDescription);
   SetProperty(package, "description", this->PackageDescription);
   SetProperty(package, "website", this->PackageWebsite);
   SetProperty(package, "website", this->PackageWebsite);
-  // TODO: license
+  SetProperty(package, "license", this->PackageLicense);
+  SetProperty(package, "default_license", this->DefaultLicense);
 
 
   return package;
   return package;
 }
 }

+ 2 - 0
Source/cmExportPackageInfoGenerator.h

@@ -110,6 +110,8 @@ private:
   std::string const PackageVersionSchema;
   std::string const PackageVersionSchema;
   std::string const PackageDescription;
   std::string const PackageDescription;
   std::string const PackageWebsite;
   std::string const PackageWebsite;
+  std::string const PackageLicense;
+  std::string const DefaultLicense;
   std::vector<std::string> DefaultTargets;
   std::vector<std::string> DefaultTargets;
   std::vector<std::string> DefaultConfigurations;
   std::vector<std::string> DefaultConfigurations;
 
 

+ 7 - 0
Source/cmPackageInfoArguments.cxx

@@ -60,6 +60,8 @@ bool cmPackageInfoArguments::Check(cmExecutionStatus& status,
     ENFORCE_REQUIRES("PACKAGE_INFO", this->LowerCase, "LOWER_CASE_FILE");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->LowerCase, "LOWER_CASE_FILE");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Appendix, "APPENDIX");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Appendix, "APPENDIX");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Version, "VERSION");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Version, "VERSION");
+    ENFORCE_REQUIRES("PACKAGE_INFO", this->License, "LICENSE");
+    ENFORCE_REQUIRES("PACKAGE_INFO", this->DefaultLicense, "DEFAULT_LICENSE");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Description, "DESCRIPTION");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Description, "DESCRIPTION");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Website, "HOMEPAGE_URL");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->Website, "HOMEPAGE_URL");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->DefaultTargets, "DEFAULT_TARGETS");
     ENFORCE_REQUIRES("PACKAGE_INFO", this->DefaultTargets, "DEFAULT_TARGETS");
@@ -73,6 +75,7 @@ bool cmPackageInfoArguments::Check(cmExecutionStatus& status,
   // Check for incompatible options.
   // Check for incompatible options.
   if (!this->Appendix.empty()) {
   if (!this->Appendix.empty()) {
     ENFORCE_EXCLUSIVE("APPENDIX", this->Version, "VERSION");
     ENFORCE_EXCLUSIVE("APPENDIX", this->Version, "VERSION");
+    ENFORCE_EXCLUSIVE("APPENDIX", this->License, "LICENSE");
     ENFORCE_EXCLUSIVE("APPENDIX", this->Description, "DESCRIPTION");
     ENFORCE_EXCLUSIVE("APPENDIX", this->Description, "DESCRIPTION");
     ENFORCE_EXCLUSIVE("APPENDIX", this->Website, "HOMEPAGE_URL");
     ENFORCE_EXCLUSIVE("APPENDIX", this->Website, "HOMEPAGE_URL");
     ENFORCE_EXCLUSIVE("APPENDIX", this->DefaultTargets, "DEFAULT_TARGETS");
     ENFORCE_EXCLUSIVE("APPENDIX", this->DefaultTargets, "DEFAULT_TARGETS");
@@ -136,6 +139,10 @@ bool cmPackageInfoArguments::SetMetadataFromProject(cmExecutionStatus& status)
     }
     }
   }
   }
 
 
+  if (this->License.empty()) {
+    mapProjectValue(this->License, "SPDX_LICENSE"_s);
+  }
+
   if (this->Description.empty()) {
   if (this->Description.empty()) {
     mapProjectValue(this->Description, "DESCRIPTION"_s);
     mapProjectValue(this->Description, "DESCRIPTION"_s);
   }
   }

+ 5 - 0
Source/cmPackageInfoArguments.h

@@ -56,6 +56,8 @@ public:
   ArgumentParser::NonEmpty<std::string> Version;
   ArgumentParser::NonEmpty<std::string> Version;
   ArgumentParser::NonEmpty<std::string> VersionCompat;
   ArgumentParser::NonEmpty<std::string> VersionCompat;
   ArgumentParser::NonEmpty<std::string> VersionSchema;
   ArgumentParser::NonEmpty<std::string> VersionSchema;
+  ArgumentParser::NonEmpty<std::string> License;
+  ArgumentParser::NonEmpty<std::string> DefaultLicense;
   ArgumentParser::NonEmpty<std::string> Description;
   ArgumentParser::NonEmpty<std::string> Description;
   ArgumentParser::NonEmpty<std::string> Website;
   ArgumentParser::NonEmpty<std::string> Website;
   ArgumentParser::NonEmpty<std::vector<std::string>> DefaultTargets;
   ArgumentParser::NonEmpty<std::vector<std::string>> DefaultTargets;
@@ -84,6 +86,9 @@ private:
          &cmPackageInfoArguments::DefaultTargets);
          &cmPackageInfoArguments::DefaultTargets);
     Bind(self, parser, "DEFAULT_CONFIGURATIONS"_s,
     Bind(self, parser, "DEFAULT_CONFIGURATIONS"_s,
          &cmPackageInfoArguments::DefaultConfigs);
          &cmPackageInfoArguments::DefaultConfigs);
+    Bind(self, parser, "LICENSE"_s, &cmPackageInfoArguments::License);
+    Bind(self, parser, "DEFAULT_LICENSE"_s,
+         &cmPackageInfoArguments::DefaultLicense);
     Bind(self, parser, "DESCRIPTION"_s, &cmPackageInfoArguments::Description);
     Bind(self, parser, "DESCRIPTION"_s, &cmPackageInfoArguments::Description);
     Bind(self, parser, "HOMEPAGE_URL"_s, &cmPackageInfoArguments::Website);
     Bind(self, parser, "HOMEPAGE_URL"_s, &cmPackageInfoArguments::Website);
 
 

+ 2 - 0
Tests/RunCMake/ExportPackageInfo/Appendix-check.cmake

@@ -5,11 +5,13 @@ set(out_dir "${RunCMake_BINARY_DIR}/Appendix-build")
 file(READ "${out_dir}/foo.cps" content)
 file(READ "${out_dir}/foo.cps" content)
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "interface" "components" "mammal" "type")
 expect_value("${content}" "interface" "components" "mammal" "type")
+expect_value("${content}" "LGPL-3.0-or-later" "default_license")
 expect_value("${content}" "1.0" "version")
 expect_value("${content}" "1.0" "version")
 
 
 file(READ "${out_dir}/foo-dog.cps" content)
 file(READ "${out_dir}/foo-dog.cps" content)
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "interface" "components" "canine" "type")
 expect_value("${content}" "interface" "components" "canine" "type")
+expect_value("${content}" "GPL-3.0-or-later" "default_license")
 expect_missing("${content}" "version")
 expect_missing("${content}" "version")
 
 
 expect_array("${content}" 1 "components" "canine" "requires")
 expect_array("${content}" 1 "components" "canine" "requires")

+ 11 - 2
Tests/RunCMake/ExportPackageInfo/Appendix.cmake

@@ -5,5 +5,14 @@ target_link_libraries(canine INTERFACE mammal)
 install(TARGETS mammal EXPORT mammal DESTINATION .)
 install(TARGETS mammal EXPORT mammal DESTINATION .)
 install(TARGETS canine EXPORT canine DESTINATION .)
 install(TARGETS canine EXPORT canine DESTINATION .)
 
 
-export(EXPORT mammal PACKAGE_INFO foo VERSION 1.0)
-export(EXPORT canine PACKAGE_INFO foo APPENDIX dog)
+export(
+  EXPORT mammal
+  PACKAGE_INFO foo
+  VERSION 1.0
+  DEFAULT_LICENSE "LGPL-3.0-or-later")
+
+export(
+  EXPORT canine
+  PACKAGE_INFO foo
+  APPENDIX dog
+  DEFAULT_LICENSE "GPL-3.0-or-later")

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

@@ -4,6 +4,12 @@ Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
 
 
 
 
+CMake Error at BadArgs2\.cmake:[0-9]+ \(export\):
+  export APPENDIX and LICENSE are mutually exclusive\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+
+
 CMake Error at BadArgs2\.cmake:[0-9]+ \(export\):
 CMake Error at BadArgs2\.cmake:[0-9]+ \(export\):
   export APPENDIX and DESCRIPTION are mutually exclusive\.
   export APPENDIX and DESCRIPTION are mutually exclusive\.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):

+ 8 - 6
Tests/RunCMake/ExportPackageInfo/BadArgs2.cmake

@@ -1,8 +1,10 @@
 add_library(foo INTERFACE)
 add_library(foo INTERFACE)
 install(TARGETS foo EXPORT foo DESTINATION .)
 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 DESCRIPTION "Test")
-export(EXPORT foo PACKAGE_INFO foo APPENDIX test HOMEPAGE_URL "example.com")
-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 PROJECT foo)
+set(args EXPORT foo PACKAGE_INFO foo APPENDIX test)
+export(${args} VERSION 1.0)
+export(${args} LICENSE "BSD-3-Clause AND CC-BY-SA-4.0")
+export(${args} DESCRIPTION "Test")
+export(${args} HOMEPAGE_URL "example.com")
+export(${args} DEFAULT_TARGETS foo)
+export(${args} DEFAULT_CONFIGURATIONS Release)
+export(${args} PROJECT foo)

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

@@ -16,6 +16,18 @@ Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
 
 
 
 
+CMake Error at BadArgs4\.cmake:[0-9]+ \(export\):
+  export LICENSE requires PACKAGE_INFO\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+
+
+CMake Error at BadArgs4\.cmake:[0-9]+ \(export\):
+  export DEFAULT_LICENSE requires PACKAGE_INFO\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+
+
 CMake Error at BadArgs4\.cmake:[0-9]+ \(export\):
 CMake Error at BadArgs4\.cmake:[0-9]+ \(export\):
   export DESCRIPTION requires PACKAGE_INFO\.
   export DESCRIPTION requires PACKAGE_INFO\.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):

+ 12 - 9
Tests/RunCMake/ExportPackageInfo/BadArgs4.cmake

@@ -1,11 +1,14 @@
 add_library(foo INTERFACE)
 add_library(foo INTERFACE)
 install(TARGETS foo EXPORT foo DESTINATION .)
 install(TARGETS foo EXPORT foo DESTINATION .)
-export(EXPORT foo LOWER_CASE_FILE)
-export(EXPORT foo APPENDIX test)
-export(EXPORT foo VERSION 1.0)
-export(EXPORT foo DESCRIPTION "Test")
-export(EXPORT foo HOMEPAGE_URL "example.com")
-export(EXPORT foo DEFAULT_TARGETS foo)
-export(EXPORT foo DEFAULT_CONFIGURATIONS Release)
-export(EXPORT foo PROJECT foo)
-export(EXPORT foo NO_PROJECT_METADATA)
+set(args EXPORT foo)
+export(${args} LOWER_CASE_FILE)
+export(${args} APPENDIX test)
+export(${args} VERSION 1.0)
+export(${args} LICENSE "BSD-3-Clause AND CC-BY-SA-4.0")
+export(${args} DEFAULT_LICENSE "BSD-3-Clause")
+export(${args} DESCRIPTION "Test")
+export(${args} HOMEPAGE_URL "example.com")
+export(${args} DEFAULT_TARGETS foo)
+export(${args} DEFAULT_CONFIGURATIONS Release)
+export(${args} PROJECT foo)
+export(${args} NO_PROJECT_METADATA)

+ 2 - 0
Tests/RunCMake/ExportPackageInfo/Metadata-check.cmake

@@ -15,5 +15,7 @@ expect_array("${content}" 2 "configurations")
 expect_value("${content}" "release" "configurations" 0)
 expect_value("${content}" "release" "configurations" 0)
 expect_value("${content}" "debug" "configurations" 1)
 expect_value("${content}" "debug" "configurations" 1)
 
 
+expect_value("${content}" "BSD-3-Clause" "default_license")
+expect_value("${content}" "BSD-3-Clause AND CC-BY-SA-4.0" "license")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 expect_value("${content}" "https://www.example.com/package/foo" "website")

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

@@ -8,6 +8,8 @@ export(
   COMPAT_VERSION 1.2.0
   COMPAT_VERSION 1.2.0
   DEFAULT_TARGETS foo
   DEFAULT_TARGETS foo
   DEFAULT_CONFIGURATIONS release debug
   DEFAULT_CONFIGURATIONS release debug
+  LICENSE "BSD-3-Clause AND CC-BY-SA-4.0"
+  DEFAULT_LICENSE "BSD-3-Clause"
   DESCRIPTION "Sample package"
   DESCRIPTION "Sample package"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   )
   )

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

@@ -6,6 +6,7 @@ file(READ "${out_dir}/foo.cps" content)
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.1.0" "compat_version")
 expect_value("${content}" "1.1.0" "compat_version")
+expect_value("${content}" "BSD-3-Clause" "license")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 
 
@@ -13,6 +14,7 @@ file(READ "${out_dir}/test1.cps" content)
 expect_value("${content}" "test1" "name")
 expect_value("${content}" "test1" "name")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.1.0" "compat_version")
 expect_value("${content}" "1.1.0" "compat_version")
+expect_value("${content}" "BSD-3-Clause" "license")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 
 
@@ -20,5 +22,6 @@ file(READ "${out_dir}/test2.cps" content)
 expect_value("${content}" "test2" "name")
 expect_value("${content}" "test2" "name")
 expect_value("${content}" "1.4.7" "version")
 expect_value("${content}" "1.4.7" "version")
 expect_missing("${content}" "compat_version")
 expect_missing("${content}" "compat_version")
+expect_value("${content}" "Apache-2.0" "license")
 expect_value("${content}" "Don't inherit" "description")
 expect_value("${content}" "Don't inherit" "description")
 expect_value("${content}" "https://www.example.com/package/bar" "website")
 expect_value("${content}" "https://www.example.com/package/bar" "website")

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

@@ -1,6 +1,7 @@
 project(foo
 project(foo
   VERSION 1.2.3
   VERSION 1.2.3
   COMPAT_VERSION 1.1.0
   COMPAT_VERSION 1.1.0
+  SPDX_LICENSE "BSD-3-Clause"
   DESCRIPTION "Sample package"
   DESCRIPTION "Sample package"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   )
   )
@@ -27,6 +28,7 @@ export(
   PROJECT foo
   PROJECT foo
   PACKAGE_INFO test2
   PACKAGE_INFO test2
   VERSION 1.4.7
   VERSION 1.4.7
+  LICENSE "Apache-2.0"
   DESCRIPTION "Don't inherit"
   DESCRIPTION "Don't inherit"
   HOMEPAGE_URL "https://www.example.com/package/bar"
   HOMEPAGE_URL "https://www.example.com/package/bar"
   )
   )

+ 2 - 0
Tests/RunCMake/InstallPackageInfo/Appendix-check.cmake

@@ -5,11 +5,13 @@ set(out_dir "${RunCMake_BINARY_DIR}/Appendix-build/CMakeFiles/Export/510c5684a4a
 file(READ "${out_dir}/foo.cps" content)
 file(READ "${out_dir}/foo.cps" content)
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "interface" "components" "mammal" "type")
 expect_value("${content}" "interface" "components" "mammal" "type")
+expect_value("${content}" "LGPL-3.0-or-later" "default_license")
 expect_value("${content}" "1.0" "version")
 expect_value("${content}" "1.0" "version")
 
 
 file(READ "${out_dir}/foo-dog.cps" content)
 file(READ "${out_dir}/foo-dog.cps" content)
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "interface" "components" "canine" "type")
 expect_value("${content}" "interface" "components" "canine" "type")
+expect_value("${content}" "GPL-3.0-or-later" "default_license")
 expect_missing("${content}" "version")
 expect_missing("${content}" "version")
 
 
 expect_array("${content}" 1 "components" "canine" "requires")
 expect_array("${content}" 1 "components" "canine" "requires")

+ 13 - 2
Tests/RunCMake/InstallPackageInfo/Appendix.cmake

@@ -5,5 +5,16 @@ target_link_libraries(canine INTERFACE mammal)
 install(TARGETS mammal EXPORT mammal DESTINATION .)
 install(TARGETS mammal EXPORT mammal DESTINATION .)
 install(TARGETS canine EXPORT canine DESTINATION .)
 install(TARGETS canine EXPORT canine DESTINATION .)
 
 
-install(PACKAGE_INFO foo DESTINATION cps EXPORT mammal VERSION 1.0)
-install(PACKAGE_INFO foo DESTINATION cps EXPORT canine APPENDIX dog)
+install(
+  PACKAGE_INFO foo
+  DESTINATION cps
+  EXPORT mammal
+  VERSION 1.0
+  DEFAULT_LICENSE "LGPL-3.0-or-later")
+
+install(
+  PACKAGE_INFO foo
+  DESTINATION cps
+  EXPORT canine
+  APPENDIX dog
+  DEFAULT_LICENSE "GPL-3.0-or-later")

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

@@ -4,6 +4,12 @@ Call Stack \(most recent call first\):
   CMakeLists\.txt:3 \(include\)
   CMakeLists\.txt:3 \(include\)
 
 
 
 
+CMake Error at BadArgs2.cmake:[0-9]+ \(install\):
+  install APPENDIX and LICENSE are mutually exclusive.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:3 \(include\)
+
+
 CMake Error at BadArgs2.cmake:[0-9]+ \(install\):
 CMake Error at BadArgs2.cmake:[0-9]+ \(install\):
   install APPENDIX and DESCRIPTION are mutually exclusive.
   install APPENDIX and DESCRIPTION are mutually exclusive.
 Call Stack \(most recent call first\):
 Call Stack \(most recent call first\):

+ 8 - 6
Tests/RunCMake/InstallPackageInfo/BadArgs2.cmake

@@ -1,8 +1,10 @@
 add_library(foo INTERFACE)
 add_library(foo INTERFACE)
 install(TARGETS foo EXPORT foo DESTINATION .)
 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 DESCRIPTION "Test")
-install(PACKAGE_INFO test EXPORT foo APPENDIX test HOMEPAGE_URL "example.com")
-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 PROJECT foo)
+set(args PACKAGE_INFO test EXPORT foo APPENDIX test)
+install(${args} VERSION 1.0)
+install(${args} LICENSE "BSD-3-Clause AND CC-BY-SA-4.0")
+install(${args} DESCRIPTION "Test")
+install(${args} HOMEPAGE_URL "example.com")
+install(${args} DEFAULT_TARGETS foo)
+install(${args} DEFAULT_CONFIGURATIONS test)
+install(${args} PROJECT foo)

+ 2 - 0
Tests/RunCMake/InstallPackageInfo/Metadata-check.cmake

@@ -15,5 +15,7 @@ expect_array("${content}" 2 "configurations")
 expect_value("${content}" "release" "configurations" 0)
 expect_value("${content}" "release" "configurations" 0)
 expect_value("${content}" "debug" "configurations" 1)
 expect_value("${content}" "debug" "configurations" 1)
 
 
+expect_value("${content}" "BSD-3-Clause" "default_license")
+expect_value("${content}" "BSD-3-Clause AND CC-BY-SA-4.0" "license")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 expect_value("${content}" "https://www.example.com/package/foo" "website")

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

@@ -9,6 +9,8 @@ install(
   COMPAT_VERSION 1.2.0
   COMPAT_VERSION 1.2.0
   DEFAULT_TARGETS foo
   DEFAULT_TARGETS foo
   DEFAULT_CONFIGURATIONS release debug
   DEFAULT_CONFIGURATIONS release debug
+  LICENSE "BSD-3-Clause AND CC-BY-SA-4.0"
+  DEFAULT_LICENSE "BSD-3-Clause"
   DESCRIPTION "Sample package"
   DESCRIPTION "Sample package"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   )
   )

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

@@ -6,6 +6,7 @@ file(READ "${out_dir}/foo.cps" content)
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "foo" "name")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.1.0" "compat_version")
 expect_value("${content}" "1.1.0" "compat_version")
+expect_value("${content}" "BSD-3-Clause" "license")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 
 
@@ -13,6 +14,7 @@ file(READ "${out_dir}/test1.cps" content)
 expect_value("${content}" "test1" "name")
 expect_value("${content}" "test1" "name")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.2.3" "version")
 expect_value("${content}" "1.1.0" "compat_version")
 expect_value("${content}" "1.1.0" "compat_version")
+expect_value("${content}" "BSD-3-Clause" "license")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "Sample package" "description")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 expect_value("${content}" "https://www.example.com/package/foo" "website")
 
 
@@ -20,5 +22,6 @@ file(READ "${out_dir}/test2.cps" content)
 expect_value("${content}" "test2" "name")
 expect_value("${content}" "test2" "name")
 expect_value("${content}" "1.4.7" "version")
 expect_value("${content}" "1.4.7" "version")
 expect_missing("${content}" "compat_version")
 expect_missing("${content}" "compat_version")
+expect_value("${content}" "Apache-2.0" "license")
 expect_value("${content}" "Don't inherit" "description")
 expect_value("${content}" "Don't inherit" "description")
 expect_value("${content}" "https://www.example.com/package/bar" "website")
 expect_value("${content}" "https://www.example.com/package/bar" "website")

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

@@ -1,6 +1,7 @@
 project(foo
 project(foo
   VERSION 1.2.3
   VERSION 1.2.3
   COMPAT_VERSION 1.1.0
   COMPAT_VERSION 1.1.0
+  SPDX_LICENSE "BSD-3-Clause"
   DESCRIPTION "Sample package"
   DESCRIPTION "Sample package"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   HOMEPAGE_URL "https://www.example.com/package/foo"
   )
   )
@@ -30,6 +31,7 @@ install(
   EXPORT foo
   EXPORT foo
   PROJECT foo
   PROJECT foo
   VERSION 1.4.7
   VERSION 1.4.7
+  LICENSE "Apache-2.0"
   DESCRIPTION "Don't inherit"
   DESCRIPTION "Don't inherit"
   HOMEPAGE_URL "https://www.example.com/package/bar"
   HOMEPAGE_URL "https://www.example.com/package/bar"
   )
   )