|
@@ -21,8 +21,10 @@
|
|
|
#include "cmExportBuildAndroidMKGenerator.h"
|
|
|
#include "cmExportBuildCMakeConfigGenerator.h"
|
|
|
#include "cmExportBuildFileGenerator.h"
|
|
|
+#include "cmExportBuildPackageInfoGenerator.h"
|
|
|
#include "cmExportSet.h"
|
|
|
#include "cmGeneratedFileStream.h"
|
|
|
+#include "cmGeneratorExpression.h"
|
|
|
#include "cmGlobalGenerator.h"
|
|
|
#include "cmMakefile.h"
|
|
|
#include "cmMessageType.h"
|
|
@@ -68,9 +70,17 @@ bool cmExportCommand(std::vector<std::string> const& args,
|
|
|
ArgumentParser::NonEmpty<std::string> Namespace;
|
|
|
ArgumentParser::NonEmpty<std::string> Filename;
|
|
|
ArgumentParser::NonEmpty<std::string> AndroidMKFile;
|
|
|
+ ArgumentParser::NonEmpty<std::string> PackageName;
|
|
|
+ ArgumentParser::NonEmpty<std::string> Appendix;
|
|
|
+ ArgumentParser::NonEmpty<std::string> Version;
|
|
|
+ ArgumentParser::NonEmpty<std::string> VersionCompat;
|
|
|
+ ArgumentParser::NonEmpty<std::string> VersionSchema;
|
|
|
ArgumentParser::NonEmpty<std::string> CxxModulesDirectory;
|
|
|
+ ArgumentParser::NonEmpty<std::vector<std::string>> DefaultTargets;
|
|
|
+ ArgumentParser::NonEmpty<std::vector<std::string>> DefaultConfigs;
|
|
|
bool Append = false;
|
|
|
bool ExportOld = false;
|
|
|
+ bool LowerCase = false;
|
|
|
|
|
|
std::vector<std::vector<std::string>> PackageDependencyArgs;
|
|
|
bool ExportPackageDependencies = false;
|
|
@@ -92,6 +102,17 @@ bool cmExportCommand(std::vector<std::string> const& args,
|
|
|
parser.Bind("EXPORT_PACKAGE_DEPENDENCIES"_s,
|
|
|
&Arguments::ExportPackageDependencies);
|
|
|
}
|
|
|
+ if (cmExperimental::HasSupportEnabled(
|
|
|
+ status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo)) {
|
|
|
+ parser.Bind("PACKAGE_INFO"_s, &Arguments::PackageName);
|
|
|
+ parser.Bind("LOWER_CASE_FILE"_s, &Arguments::LowerCase);
|
|
|
+ parser.Bind("APPENDIX"_s, &Arguments::Appendix);
|
|
|
+ parser.Bind("VERSION"_s, &Arguments::Version);
|
|
|
+ parser.Bind("COMPAT_VERSION"_s, &Arguments::VersionCompat);
|
|
|
+ parser.Bind("VERSION_SCHEMA"_s, &Arguments::VersionSchema);
|
|
|
+ parser.Bind("DEFAULT_TARGETS"_s, &Arguments::DefaultTargets);
|
|
|
+ parser.Bind("DEFAULT_CONFIGURATIONS"_s, &Arguments::DefaultConfigs);
|
|
|
+ }
|
|
|
} else if (args[0] == "SETUP") {
|
|
|
parser.Bind("SETUP"_s, &Arguments::ExportSetName);
|
|
|
if (cmExperimental::HasSupportEnabled(
|
|
@@ -200,19 +221,98 @@ bool cmExportCommand(std::vector<std::string> const& args,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ if (arguments.PackageName.empty()) {
|
|
|
+ if (arguments.LowerCase) {
|
|
|
+ status.SetError("LOWER_CASE_FILE requires PACKAGE_INFO.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.Appendix.empty()) {
|
|
|
+ status.SetError("APPENDIX requires PACKAGE_INFO.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.Version.empty()) {
|
|
|
+ status.SetError("VERSION requires PACKAGE_INFO.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.DefaultTargets.empty()) {
|
|
|
+ status.SetError("DEFAULT_TARGETS requires PACKAGE_INFO.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.DefaultConfigs.empty()) {
|
|
|
+ status.SetError("DEFAULT_CONFIGURATIONS requires PACKAGE_INFO.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!arguments.Filename.empty()) {
|
|
|
+ status.SetError("PACKAGE_INFO and FILE are mutually exclusive.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.Namespace.empty()) {
|
|
|
+ status.SetError("PACKAGE_INFO and NAMESPACE are mutually exclusive.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.Appendix.empty()) {
|
|
|
+ if (!arguments.Version.empty()) {
|
|
|
+ status.SetError("APPENDIX and VERSION are mutually exclusive.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.DefaultTargets.empty()) {
|
|
|
+ status.SetError("APPENDIX and DEFAULT_TARGETS "
|
|
|
+ "are mutually exclusive.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.DefaultConfigs.empty()) {
|
|
|
+ status.SetError("APPENDIX and DEFAULT_CONFIGURATIONS "
|
|
|
+ "are mutually exclusive.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (arguments.Version.empty()) {
|
|
|
+ if (!arguments.VersionCompat.empty()) {
|
|
|
+ status.SetError("COMPAT_VERSION requires VERSION.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ if (!arguments.VersionSchema.empty()) {
|
|
|
+ status.SetError("VERSION_SCHEMA requires VERSION.");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
std::string fname;
|
|
|
bool android = false;
|
|
|
+ bool cps = false;
|
|
|
if (!arguments.AndroidMKFile.empty()) {
|
|
|
fname = arguments.AndroidMKFile;
|
|
|
android = true;
|
|
|
- }
|
|
|
- if (arguments.Filename.empty() && fname.empty()) {
|
|
|
+ } else if (arguments.Filename.empty()) {
|
|
|
if (args[0] != "EXPORT") {
|
|
|
status.SetError("FILE <filename> option missing.");
|
|
|
return false;
|
|
|
}
|
|
|
- fname = arguments.ExportSetName + ".cmake";
|
|
|
- } else if (fname.empty()) {
|
|
|
+ if (arguments.PackageName.empty()) {
|
|
|
+ fname = arguments.ExportSetName + ".cmake";
|
|
|
+ } else {
|
|
|
+ // Validate the package name.
|
|
|
+ if (!cmGeneratorExpression::IsValidTargetName(arguments.PackageName) ||
|
|
|
+ arguments.PackageName.find(':') != std::string::npos) {
|
|
|
+ status.SetError(
|
|
|
+ cmStrCat(R"(PACKAGE_INFO given invalid package name ")"_s,
|
|
|
+ arguments.PackageName, R"(".)"_s));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string const pkgNameOnDisk =
|
|
|
+ (arguments.LowerCase ? cmSystemTools::LowerCase(arguments.PackageName)
|
|
|
+ : std::string{ arguments.PackageName });
|
|
|
+ if (arguments.Appendix.empty()) {
|
|
|
+ fname = cmStrCat(pkgNameOnDisk, ".cps"_s);
|
|
|
+ } else {
|
|
|
+ fname = cmStrCat(pkgNameOnDisk, '-', arguments.Appendix, ".cps"_s);
|
|
|
+ }
|
|
|
+ cps = true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
// Make sure the file has a .cmake extension.
|
|
|
if (cmSystemTools::GetFilenameLastExtension(arguments.Filename) !=
|
|
|
".cmake") {
|
|
@@ -298,6 +398,11 @@ bool cmExportCommand(std::vector<std::string> const& args,
|
|
|
// and APPEND is not specified, if CMP0103 is OLD ignore previous definition
|
|
|
// else raise an error
|
|
|
if (gg->GetExportedTargetsFile(fname)) {
|
|
|
+ if (cps) {
|
|
|
+ status.SetError(cmStrCat("command already specified for the file "_s,
|
|
|
+ cmSystemTools::GetFilenameName(fname), '.'));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
switch (mf.GetPolicyStatus(cmPolicies::CMP0103)) {
|
|
|
case cmPolicies::WARN:
|
|
|
mf.IssueMessage(
|
|
@@ -316,21 +421,28 @@ bool cmExportCommand(std::vector<std::string> const& args,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Setup export file generation.
|
|
|
+ // Set up export file generation.
|
|
|
std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
|
|
|
if (android) {
|
|
|
auto ebag = cm::make_unique<cmExportBuildAndroidMKGenerator>();
|
|
|
+ ebag->SetNamespace(arguments.Namespace);
|
|
|
ebag->SetAppendMode(arguments.Append);
|
|
|
ebfg = std::move(ebag);
|
|
|
+ } else if (cps) {
|
|
|
+ auto ebpg = cm::make_unique<cmExportBuildPackageInfoGenerator>(
|
|
|
+ arguments.PackageName, arguments.Version, arguments.VersionCompat,
|
|
|
+ arguments.VersionSchema, arguments.DefaultTargets,
|
|
|
+ arguments.DefaultConfigs);
|
|
|
+ ebfg = std::move(ebpg);
|
|
|
} else {
|
|
|
auto ebcg = cm::make_unique<cmExportBuildCMakeConfigGenerator>();
|
|
|
+ ebcg->SetNamespace(arguments.Namespace);
|
|
|
ebcg->SetAppendMode(arguments.Append);
|
|
|
ebcg->SetExportOld(arguments.ExportOld);
|
|
|
ebcg->SetExportPackageDependencies(arguments.ExportPackageDependencies);
|
|
|
ebfg = std::move(ebcg);
|
|
|
}
|
|
|
ebfg->SetExportFile(fname.c_str());
|
|
|
- ebfg->SetNamespace(arguments.Namespace);
|
|
|
ebfg->SetCxxModuleDirectory(arguments.CxxModulesDirectory);
|
|
|
if (exportSet) {
|
|
|
ebfg->SetExportSet(exportSet);
|