diff options
Diffstat (limited to 'Source/cmTargetSourcesCommand.cxx')
-rw-r--r-- | Source/cmTargetSourcesCommand.cxx | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx new file mode 100644 index 0000000..11e288f --- /dev/null +++ b/Source/cmTargetSourcesCommand.cxx @@ -0,0 +1,124 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmTargetSourcesCommand.h" + +#include <sstream> + +#include "cmAlgorithms.h" +#include "cmGeneratorExpression.h" +#include "cmMakefile.h" +#include "cmMessageType.h" +#include "cmPolicies.h" +#include "cmSystemTools.h" +#include "cmTarget.h" + +class cmExecutionStatus; + +bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args, + cmExecutionStatus&) +{ + return this->HandleArguments(args, "SOURCES"); +} + +void cmTargetSourcesCommand::HandleInterfaceContent( + cmTarget* tgt, const std::vector<std::string>& content, bool prepend, + bool system) +{ + cmTargetPropCommandBase::HandleInterfaceContent( + tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system); +} + +void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name) +{ + std::ostringstream e; + e << "Cannot specify sources for target \"" << name + << "\" " + "which is not built by this project."; + this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str()); +} + +std::string cmTargetSourcesCommand::Join( + const std::vector<std::string>& content) +{ + return cmJoin(content, ";"); +} + +bool cmTargetSourcesCommand::HandleDirectContent( + cmTarget* tgt, const std::vector<std::string>& content, bool, bool) +{ + tgt->AppendProperty( + "SOURCES", + this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str()); + return true; // Successfully handled. +} + +std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent( + cmTarget* tgt, const std::vector<std::string>& content, + bool isInterfaceContent) +{ + // Skip conversion in case old behavior has been explicitly requested + if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076) == + cmPolicies::OLD) { + return content; + } + + bool changedPath = false; + std::vector<std::string> absoluteContent; + absoluteContent.reserve(content.size()); + for (std::string const& src : content) { + std::string absoluteSrc; + if (cmSystemTools::FileIsFullPath(src) || + cmGeneratorExpression::Find(src) == 0 || + (!isInterfaceContent && + (this->Makefile->GetCurrentSourceDirectory() == + tgt->GetMakefile()->GetCurrentSourceDirectory()))) { + absoluteSrc = src; + } else { + changedPath = true; + absoluteSrc = this->Makefile->GetCurrentSourceDirectory(); + absoluteSrc += "/"; + absoluteSrc += src; + } + absoluteContent.push_back(absoluteSrc); + } + + if (!changedPath) { + return content; + } + + bool issueMessage = true; + bool useAbsoluteContent = false; + std::ostringstream e; + switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076)) { + case cmPolicies::WARN: + e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0076) << "\n"; + break; + case cmPolicies::OLD: + issueMessage = false; + break; + case cmPolicies::REQUIRED_ALWAYS: + case cmPolicies::REQUIRED_IF_USED: + this->Makefile->IssueMessage( + MessageType::FATAL_ERROR, + cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0076)); + break; + case cmPolicies::NEW: { + issueMessage = false; + useAbsoluteContent = true; + break; + } + } + + if (issueMessage) { + if (isInterfaceContent) { + e << "An interface source of target \"" << tgt->GetName() + << "\" has a relative path."; + } else { + e << "A private source from a directory other than that of target \"" + << tgt->GetName() << "\" has a relative path."; + } + this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str()); + } + + return useAbsoluteContent ? absoluteContent : content; +} |