cmTargetIncludeDirectoriesCommand.cxx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 "cmTargetIncludeDirectoriesCommand.h"
  4. #include <set>
  5. #include "cmGeneratorExpression.h"
  6. #include "cmListFileCache.h"
  7. #include "cmMakefile.h"
  8. #include "cmMessageType.h"
  9. #include "cmStringAlgorithms.h"
  10. #include "cmSystemTools.h"
  11. #include "cmTarget.h"
  12. #include "cmTargetPropCommandBase.h"
  13. namespace {
  14. class TargetIncludeDirectoriesImpl : public cmTargetPropCommandBase
  15. {
  16. public:
  17. using cmTargetPropCommandBase::cmTargetPropCommandBase;
  18. private:
  19. void HandleMissingTarget(const std::string& name) override
  20. {
  21. this->Makefile->IssueMessage(
  22. MessageType::FATAL_ERROR,
  23. cmStrCat("Cannot specify include directories for target \"", name,
  24. "\" which is not built by this project."));
  25. }
  26. bool HandleDirectContent(cmTarget* tgt,
  27. const std::vector<std::string>& content,
  28. bool prepend, bool system) override;
  29. void HandleInterfaceContent(cmTarget* tgt,
  30. const std::vector<std::string>& content,
  31. bool prepend, bool system) override;
  32. std::string Join(const std::vector<std::string>& content) override;
  33. };
  34. std::string TargetIncludeDirectoriesImpl::Join(
  35. const std::vector<std::string>& content)
  36. {
  37. std::string dirs;
  38. std::string sep;
  39. std::string prefix = this->Makefile->GetCurrentSourceDirectory() + "/";
  40. for (std::string const& it : content) {
  41. if (cmSystemTools::FileIsFullPath(it) ||
  42. cmGeneratorExpression::Find(it) == 0) {
  43. dirs += cmStrCat(sep, it);
  44. } else {
  45. dirs += cmStrCat(sep, prefix, it);
  46. }
  47. sep = ";";
  48. }
  49. return dirs;
  50. }
  51. bool TargetIncludeDirectoriesImpl::HandleDirectContent(
  52. cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
  53. bool system)
  54. {
  55. cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
  56. tgt->InsertInclude(BT<std::string>(this->Join(content), lfbt), prepend);
  57. if (system) {
  58. std::string prefix = this->Makefile->GetCurrentSourceDirectory() + "/";
  59. std::set<std::string> sdirs;
  60. for (std::string const& it : content) {
  61. if (cmSystemTools::FileIsFullPath(it) ||
  62. cmGeneratorExpression::Find(it) == 0) {
  63. sdirs.insert(it);
  64. } else {
  65. sdirs.insert(prefix + it);
  66. }
  67. }
  68. tgt->AddSystemIncludeDirectories(sdirs);
  69. }
  70. return true; // Successfully handled.
  71. }
  72. void TargetIncludeDirectoriesImpl::HandleInterfaceContent(
  73. cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
  74. bool system)
  75. {
  76. this->cmTargetPropCommandBase::HandleInterfaceContent(tgt, content, prepend,
  77. system);
  78. if (system) {
  79. std::string joined = this->Join(content);
  80. tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined);
  81. }
  82. }
  83. } // namespace
  84. bool cmTargetIncludeDirectoriesCommand(std::vector<std::string> const& args,
  85. cmExecutionStatus& status)
  86. {
  87. return TargetIncludeDirectoriesImpl(status).HandleArguments(
  88. args, "INCLUDE_DIRECTORIES",
  89. TargetIncludeDirectoriesImpl::ArgumentFlags(
  90. TargetIncludeDirectoriesImpl::PROCESS_BEFORE |
  91. TargetIncludeDirectoriesImpl::PROCESS_AFTER |
  92. TargetIncludeDirectoriesImpl::PROCESS_SYSTEM));
  93. }