cmTargetSourcesCommand.cxx 3.6 KB

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