/* 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 #include "cmAlgorithms.h" #include "cmGeneratorExpression.h" #include "cmMakefile.h" #include "cmPolicies.h" #include "cmSystemTools.h" #include "cmTarget.h" #include "cmake.h" class cmExecutionStatus; bool cmTargetSourcesCommand::InitialPass(std::vector const& args, cmExecutionStatus&) { return this->HandleArguments(args, "SOURCES"); } void cmTargetSourcesCommand::HandleInterfaceContent( cmTarget* tgt, const std::vector& 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(cmake::FATAL_ERROR, e.str()); } std::string cmTargetSourcesCommand::Join( const std::vector& content) { return cmJoin(content, ";"); } bool cmTargetSourcesCommand::HandleDirectContent( cmTarget* tgt, const std::vector& content, bool, bool) { tgt->AppendProperty( "SOURCES", this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str()); return true; // Successfully handled. } std::vector cmTargetSourcesCommand::ConvertToAbsoluteContent( cmTarget* tgt, const std::vector& 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 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( cmake::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(cmake::AUTHOR_WARNING, e.str()); } return useAbsoluteContent ? absoluteContent : content; }