diff options
Diffstat (limited to 'Source/cmTargetPropCommandBase.cxx')
-rw-r--r-- | Source/cmTargetPropCommandBase.cxx | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx new file mode 100644 index 0000000..9a5c1da --- /dev/null +++ b/Source/cmTargetPropCommandBase.cxx @@ -0,0 +1,142 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmTargetPropCommandBase.h" + +#include "cmGlobalGenerator.h" +#include "cmMakefile.h" +#include "cmStateTypes.h" +#include "cmTarget.h" +#include "cmake.h" + +bool cmTargetPropCommandBase::HandleArguments( + std::vector<std::string> const& args, const std::string& prop, + ArgumentFlags flags) +{ + if (args.size() < 2) { + this->SetError("called with incorrect number of arguments"); + return false; + } + + // Lookup the target for which libraries are specified. + if (this->Makefile->IsAlias(args[0])) { + this->SetError("can not be used on an ALIAS target."); + return false; + } + this->Target = + this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget( + args[0]); + if (!this->Target) { + this->Target = this->Makefile->FindTargetToUse(args[0]); + } + if (!this->Target) { + this->HandleMissingTarget(args[0]); + return false; + } + if ((this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) && + (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) && + (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) && + (this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) && + (this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) && + (this->Target->GetType() != cmStateEnums::EXECUTABLE)) { + this->SetError("called with non-compilable target type"); + return false; + } + + bool system = false; + unsigned int argIndex = 1; + + if ((flags & PROCESS_SYSTEM) && args[argIndex] == "SYSTEM") { + if (args.size() < 3) { + this->SetError("called with incorrect number of arguments"); + return false; + } + system = true; + ++argIndex; + } + + bool prepend = false; + if ((flags & PROCESS_BEFORE) && args[argIndex] == "BEFORE") { + if (args.size() < 3) { + this->SetError("called with incorrect number of arguments"); + return false; + } + prepend = true; + ++argIndex; + } + + this->Property = prop; + + while (argIndex < args.size()) { + if (!this->ProcessContentArgs(args, argIndex, prepend, system)) { + return false; + } + } + return true; +} + +bool cmTargetPropCommandBase::ProcessContentArgs( + std::vector<std::string> const& args, unsigned int& argIndex, bool prepend, + bool system) +{ + const std::string scope = args[argIndex]; + + if (scope != "PUBLIC" && scope != "PRIVATE" && scope != "INTERFACE") { + this->SetError("called with invalid arguments"); + return false; + } + + if (this->Target->IsImported()) { + this->HandleImportedTarget(args[0]); + return false; + } + + if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY && + scope != "INTERFACE") { + this->SetError("may only be set INTERFACE properties on INTERFACE " + "targets"); + return false; + } + + ++argIndex; + + std::vector<std::string> content; + + for (unsigned int i = argIndex; i < args.size(); ++i, ++argIndex) { + if (args[i] == "PUBLIC" || args[i] == "PRIVATE" || + args[i] == "INTERFACE") { + return this->PopulateTargetProperies(scope, content, prepend, system); + } + content.push_back(args[i]); + } + return this->PopulateTargetProperies(scope, content, prepend, system); +} + +bool cmTargetPropCommandBase::PopulateTargetProperies( + const std::string& scope, const std::vector<std::string>& content, + bool prepend, bool system) +{ + if (scope == "PRIVATE" || scope == "PUBLIC") { + if (!this->HandleDirectContent(this->Target, content, prepend, system)) { + return false; + } + } + if (scope == "INTERFACE" || scope == "PUBLIC") { + this->HandleInterfaceContent(this->Target, content, prepend, system); + } + return true; +} + +void cmTargetPropCommandBase::HandleInterfaceContent( + cmTarget* tgt, const std::vector<std::string>& content, bool prepend, bool) +{ + if (prepend) { + const std::string propName = std::string("INTERFACE_") + this->Property; + const char* propValue = tgt->GetProperty(propName); + const std::string totalContent = this->Join(content) + + (propValue ? std::string(";") + propValue : std::string()); + tgt->SetProperty(propName, totalContent.c_str()); + } else { + tgt->AppendProperty("INTERFACE_" + this->Property, + this->Join(content).c_str()); + } +} |