| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmDefinePropertyCommand.h"
- #include <algorithm>
- #include <iterator>
- #include <cmext/string_view>
- #include "cmArgumentParser.h"
- #include "cmExecutionStatus.h"
- #include "cmMakefile.h"
- #include "cmProperty.h"
- #include "cmRange.h"
- #include "cmState.h"
- #include "cmStringAlgorithms.h"
- bool cmDefinePropertyCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
- {
- if (args.empty()) {
- status.SetError("called with incorrect number of arguments");
- return false;
- }
- // Get the scope in which to define the property.
- cmProperty::ScopeType scope;
- std::string const& scope_arg = args[0];
- if (scope_arg == "GLOBAL") {
- scope = cmProperty::GLOBAL;
- } else if (scope_arg == "DIRECTORY") {
- scope = cmProperty::DIRECTORY;
- } else if (scope_arg == "TARGET") {
- scope = cmProperty::TARGET;
- } else if (scope_arg == "SOURCE") {
- scope = cmProperty::SOURCE_FILE;
- } else if (scope_arg == "TEST") {
- scope = cmProperty::TEST;
- } else if (scope_arg == "VARIABLE") {
- scope = cmProperty::VARIABLE;
- } else if (scope_arg == "CACHED_VARIABLE") {
- scope = cmProperty::CACHED_VARIABLE;
- } else {
- status.SetError(cmStrCat("given invalid scope ", scope_arg,
- ". Valid scopes are GLOBAL, DIRECTORY, TARGET, "
- "SOURCE, TEST, VARIABLE, CACHED_VARIABLE."));
- return false;
- }
- // Parse remaining arguments.
- bool inherited = false;
- std::string PropertyName;
- std::vector<std::string> BriefDocs;
- std::vector<std::string> FullDocs;
- std::string initializeFromVariable;
- cmArgumentParser<void> parser;
- parser.Bind("PROPERTY"_s, PropertyName);
- parser.Bind("BRIEF_DOCS"_s, BriefDocs);
- parser.Bind("FULL_DOCS"_s, FullDocs);
- parser.Bind("INHERITED"_s, inherited);
- parser.Bind("INITIALIZE_FROM_VARIABLE"_s, initializeFromVariable);
- std::vector<std::string> invalidArgs;
- parser.Parse(cmMakeRange(args).advance(1), &invalidArgs);
- if (!invalidArgs.empty()) {
- status.SetError(
- cmStrCat("given invalid argument \"", invalidArgs.front(), "\"."));
- return false;
- }
- // Make sure a property name was found.
- if (PropertyName.empty()) {
- status.SetError("not given a PROPERTY <name> argument.");
- return false;
- }
- if (!initializeFromVariable.empty()) {
- // Make sure property scope is TARGET.
- if (scope != cmProperty::TARGET) {
- status.SetError(
- "Scope must be TARGET if INITIALIZE_FROM_VARIABLE is specified");
- return false;
- }
- // Make sure the variable has the property name as a suffix.
- if (!cmHasSuffix(initializeFromVariable, PropertyName)) {
- status.SetError(cmStrCat("Variable name \"", initializeFromVariable,
- "\" does not end with property name \"",
- PropertyName, "\""));
- return false;
- }
- if (initializeFromVariable == PropertyName) {
- status.SetError(cmStrCat(
- "Variable name must have a non-empty prefix before property name \"",
- PropertyName, "\""));
- return false;
- }
- // Make sure the variable is not reserved.
- static constexpr const char* reservedPrefixes[] = {
- "CMAKE_",
- "_CMAKE_",
- };
- if (std::any_of(std::begin(reservedPrefixes), std::end(reservedPrefixes),
- [&initializeFromVariable](const char* prefix) {
- return cmHasPrefix(initializeFromVariable, prefix);
- })) {
- status.SetError(cmStrCat("variable name \"", initializeFromVariable,
- "\" is reserved"));
- return false;
- }
- }
- // Actually define the property.
- status.GetMakefile().GetState()->DefineProperty(
- PropertyName, scope, cmJoin(BriefDocs, ""), cmJoin(FullDocs, ""),
- inherited, initializeFromVariable);
- return true;
- }
|