cmTargetSourcesCommand.cxx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmTargetSourcesCommand.h"
  4. #include <cstring>
  5. #include <sstream>
  6. #include "cmAlgorithms.h"
  7. #include "cmGeneratorExpression.h"
  8. #include "cmMakefile.h"
  9. #include "cmPolicies.h"
  10. #include "cmSystemTools.h"
  11. #include "cmTarget.h"
  12. #include "cmake.h"
  13. class cmExecutionStatus;
  14. bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args,
  15. cmExecutionStatus&)
  16. {
  17. return this->HandleArguments(args, "SOURCES");
  18. }
  19. void cmTargetSourcesCommand::HandleInterfaceContent(
  20. cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
  21. bool system)
  22. {
  23. cmTargetPropCommandBase::HandleInterfaceContent(
  24. tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system);
  25. }
  26. void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name)
  27. {
  28. std::ostringstream e;
  29. e << "Cannot specify sources for target \"" << name
  30. << "\" "
  31. "which is not built by this project.";
  32. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  33. }
  34. std::string cmTargetSourcesCommand::Join(
  35. const std::vector<std::string>& content)
  36. {
  37. return cmJoin(content, ";");
  38. }
  39. bool cmTargetSourcesCommand::HandleDirectContent(
  40. cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
  41. {
  42. tgt->AppendProperty(
  43. "SOURCES",
  44. this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str());
  45. return true; // Successfully handled.
  46. }
  47. std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent(
  48. cmTarget* tgt, const std::vector<std::string>& content,
  49. bool isInterfaceContent)
  50. {
  51. // Skip conversion in case old behavior has been explictly requested
  52. if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076) ==
  53. cmPolicies::OLD) {
  54. return content;
  55. }
  56. bool changedPath = false;
  57. std::vector<std::string> absoluteContent;
  58. absoluteContent.reserve(content.size());
  59. for (std::string const& src : content) {
  60. std::string absoluteSrc;
  61. if (cmSystemTools::FileIsFullPath(src) ||
  62. cmGeneratorExpression::Find(src) == 0 ||
  63. (!isInterfaceContent &&
  64. strcmp(this->Makefile->GetCurrentSourceDirectory(),
  65. tgt->GetMakefile()->GetCurrentSourceDirectory()) == 0)) {
  66. absoluteSrc = src;
  67. } else {
  68. changedPath = true;
  69. absoluteSrc = this->Makefile->GetCurrentSourceDirectory();
  70. absoluteSrc += "/";
  71. absoluteSrc += src;
  72. }
  73. absoluteContent.push_back(absoluteSrc);
  74. }
  75. if (!changedPath) {
  76. return content;
  77. }
  78. bool issueMessage = true;
  79. bool useAbsoluteContent = false;
  80. std::ostringstream e;
  81. switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076)) {
  82. case cmPolicies::WARN:
  83. e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0076) << "\n";
  84. break;
  85. case cmPolicies::OLD:
  86. issueMessage = false;
  87. break;
  88. case cmPolicies::REQUIRED_ALWAYS:
  89. case cmPolicies::REQUIRED_IF_USED:
  90. this->Makefile->IssueMessage(
  91. cmake::FATAL_ERROR,
  92. cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0076));
  93. break;
  94. case cmPolicies::NEW: {
  95. issueMessage = false;
  96. useAbsoluteContent = true;
  97. break;
  98. }
  99. }
  100. if (issueMessage) {
  101. if (isInterfaceContent) {
  102. e << "An interface source of target \"" << tgt->GetName()
  103. << "\" has a relative path.";
  104. } else {
  105. e << "A private source from a directory other than that of target \""
  106. << tgt->GetName() << "\" has a relative path.";
  107. }
  108. this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
  109. }
  110. return useAbsoluteContent ? absoluteContent : content;
  111. }