summaryrefslogtreecommitdiffstats
path: root/Source/cmTargetSourcesCommand.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmTargetSourcesCommand.cxx')
-rw-r--r--Source/cmTargetSourcesCommand.cxx124
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;
+}