1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#include "cmProjectInfoArguments.h"
#include <utility>
#include <cm/string_view>
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmValue.h"
template void cmProjectInfoArguments::Bind<void>(cmArgumentParser<void>&,
cmProjectInfoArguments*);
#define ENFORCE_REQUIRES(req, value, arg) \
do { \
if (ArgWasSpecified(value)) { \
status.SetError(arg " requires " req "."); \
return false; \
} \
} while (false)
#define ENFORCE_EXCLUSIVE(arg1, value, arg2) \
do { \
if (ArgWasSpecified(value)) { \
status.SetError(arg1 " and " arg2 " are mutually exclusive."); \
return false; \
} \
} while (false)
cmProjectInfoArguments::cmProjectInfoArguments() = default;
bool cmProjectInfoArguments::Check(cmExecutionStatus& status) const
{
// Check for incompatible options.
if (this->NoProjectDefaults) {
ENFORCE_EXCLUSIVE("PROJECT", this->ProjectName, "NO_PROJECT_METADATA");
}
// Validate the package name.
if (!this->PackageName.empty()) {
if (!cmGeneratorExpression::IsValidTargetName(this->PackageName) ||
this->PackageName.find(':') != std::string::npos) {
status.SetError(cmStrCat(this->CommandName(),
" given invalid package name \""_s,
this->PackageName, "\"."_s));
return false;
}
}
return true;
}
#undef ENFORCE_REQUIRES
#undef ENFORCE_EXCLUSIVE
bool cmProjectInfoArguments::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();
auto mapProjectValue = [&](std::string& arg, cm::string_view suffix) {
cmValue const& projectValue =
mf.GetDefinition(cmStrCat(this->ProjectName, '_', suffix));
if (projectValue) {
arg = *projectValue;
return true;
}
return false;
};
if (this->Version.empty()) {
if (mapProjectValue(this->Version, "VERSION"_s)) {
mapProjectValue(this->VersionCompat, "COMPAT_VERSION"_s);
}
}
if (this->License.empty()) {
mapProjectValue(this->License, "SPDX_LICENSE"_s);
}
if (this->Description.empty()) {
mapProjectValue(this->Description, "DESCRIPTION"_s);
}
if (this->Website.empty()) {
mapProjectValue(this->Website, "HOMEPAGE_URL"_s);
}
return true;
}
bool cmProjectInfoArguments::SetEffectiveProject(cmExecutionStatus& status)
{
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 unknown 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;
}
|