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