1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #pragma once
4 
5 #include "cmConfigure.h" // IWYU pragma: keep
6 
7 #include <iosfwd>
8 #include <memory>
9 #include <set>
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 #include "cmAlgorithms.h"
15 #include "cmListFileCache.h"
16 #include "cmPolicies.h"
17 #include "cmStateTypes.h"
18 #include "cmStringAlgorithms.h"
19 #include "cmTargetLinkLibraryType.h"
20 #include "cmValue.h"
21 
22 class cmCustomCommand;
23 class cmGlobalGenerator;
24 class cmInstallTargetGenerator;
25 class cmMakefile;
26 class cmMessenger;
27 class cmPropertyMap;
28 class cmSourceFile;
29 class cmTargetInternals;
30 
31 /** \class cmTarget
32  * \brief Represent a library or executable target loaded from a makefile.
33  *
34  * cmTarget represents a target loaded from a makefile.
35  */
36 class cmTarget
37 {
38 public:
39   enum Visibility
40   {
41     VisibilityNormal,
42     VisibilityImported,
43     VisibilityImportedGlobally
44   };
45 
46   enum class PerConfig
47   {
48     Yes,
49     No
50   };
51 
52   cmTarget(std::string const& name, cmStateEnums::TargetType type,
53            Visibility vis, cmMakefile* mf, PerConfig perConfig);
54 
55   cmTarget(cmTarget const&) = delete;
56   cmTarget(cmTarget&&) noexcept;
57   ~cmTarget();
58 
59   cmTarget& operator=(cmTarget const&) = delete;
60   cmTarget& operator=(cmTarget&&) noexcept;
61 
62   //! Return the type of target.
63   cmStateEnums::TargetType GetType() const;
64 
65   //! Get the cmMakefile that owns this target.
66   cmMakefile* GetMakefile() const;
67 
68   //! Return the global generator.
69   cmGlobalGenerator* GetGlobalGenerator() const;
70 
71   //! Set/Get the name of the target
72   const std::string& GetName() const;
73 
74   //! Get the policy map
75   cmPolicies::PolicyMap const& GetPolicyMap() const;
76 
77   //! Get policy status
78   cmPolicies::PolicyStatus GetPolicyStatus(cmPolicies::PolicyID policy) const;
79 
80 #define DECLARE_TARGET_POLICY(POLICY)                                         \
81   cmPolicies::PolicyStatus GetPolicyStatus##POLICY() const                    \
82   {                                                                           \
83     return this->GetPolicyStatus(cmPolicies::POLICY);                         \
84   }
85 
86   CM_FOR_EACH_TARGET_POLICY(DECLARE_TARGET_POLICY)
87 
88 #undef DECLARE_TARGET_POLICY
89 
90   //! Get the list of the PRE_BUILD custom commands for this target
91   std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
92   void AddPreBuildCommand(cmCustomCommand const& cmd);
93   void AddPreBuildCommand(cmCustomCommand&& cmd);
94 
95   //! Get the list of the PRE_LINK custom commands for this target
96   std::vector<cmCustomCommand> const& GetPreLinkCommands() const;
97   void AddPreLinkCommand(cmCustomCommand const& cmd);
98   void AddPreLinkCommand(cmCustomCommand&& cmd);
99 
100   //! Get the list of the POST_BUILD custom commands for this target
101   std::vector<cmCustomCommand> const& GetPostBuildCommands() const;
102   void AddPostBuildCommand(cmCustomCommand const& cmd);
103   void AddPostBuildCommand(cmCustomCommand&& cmd);
104 
105   //! Add sources to the target.
106   void AddSources(std::vector<std::string> const& srcs);
107   void AddTracedSources(std::vector<std::string> const& srcs);
108   std::string GetSourceCMP0049(const std::string& src);
109   cmSourceFile* AddSource(const std::string& src, bool before = false);
110 
111   //! how we identify a library, by name and type
112   using LibraryID = std::pair<std::string, cmTargetLinkLibraryType>;
113   using LinkLibraryVectorType = std::vector<LibraryID>;
114   LinkLibraryVectorType const& GetOriginalLinkLibraries() const;
115 
116   //! Clear the dependency information recorded for this target, if any.
117   void ClearDependencyInformation(cmMakefile& mf) const;
118 
119   void AddLinkLibrary(cmMakefile& mf, std::string const& lib,
120                       cmTargetLinkLibraryType llt);
121 
122   enum TLLSignature
123   {
124     KeywordTLLSignature,
125     PlainTLLSignature
126   };
127   bool PushTLLCommandTrace(TLLSignature signature,
128                            cmListFileContext const& lfc);
129   void GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const;
130 
131   /**
132    * Set the path where this target should be installed. This is relative to
133    * INSTALL_PREFIX
134    */
135   std::string const& GetInstallPath() const;
136   void SetInstallPath(std::string const& name);
137 
138   /**
139    * Set the path where this target (if it has a runtime part) should be
140    * installed. This is relative to INSTALL_PREFIX
141    */
142   std::string const& GetRuntimeInstallPath() const;
143   void SetRuntimeInstallPath(std::string const& name);
144 
145   /**
146    * Get/Set whether there is an install rule for this target.
147    */
148   bool GetHaveInstallRule() const;
149   void SetHaveInstallRule(bool hir);
150 
151   void AddInstallGenerator(cmInstallTargetGenerator* g);
152   std::vector<cmInstallTargetGenerator*> const& GetInstallGenerators() const;
153 
154   /**
155    * Get/Set whether this target was auto-created by a generator.
156    */
157   bool GetIsGeneratorProvided() const;
158   void SetIsGeneratorProvided(bool igp);
159 
160   /**
161    * Add a utility on which this project depends. A utility is an executable
162    * name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE
163    * commands. It is not a full path nor does it have an extension.
164    */
165   void AddUtility(std::string const& name, bool cross,
166                   cmMakefile* mf = nullptr);
167   void AddUtility(BT<std::pair<std::string, bool>> util);
168   //! Get the utilities used by this target
169   std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
170 
171   //! Set/Get a property of this target file
172   void SetProperty(const std::string& prop, const char* value);
173   void SetProperty(const std::string& prop, cmValue value);
SetProperty(const std::string & prop,const std::string & value)174   void SetProperty(const std::string& prop, const std::string& value)
175   {
176     this->SetProperty(prop, cmValue(value));
177   }
178   void AppendProperty(const std::string& prop, const std::string& value,
179                       bool asString = false);
180   //! Might return a nullptr if the property is not set or invalid
181   cmValue GetProperty(const std::string& prop) const;
182   //! Always returns a valid pointer
183   std::string const& GetSafeProperty(std::string const& prop) const;
184   bool GetPropertyAsBool(const std::string& prop) const;
185   void CheckProperty(const std::string& prop, cmMakefile* context) const;
186   cmValue GetComputedProperty(const std::string& prop, cmMessenger* messenger,
187                               cmListFileBacktrace const& context) const;
188   //! Get all properties
189   cmPropertyMap const& GetProperties() const;
190 
191   //! Return whether or not the target is for a DLL platform.
192   bool IsDLLPlatform() const;
193 
194   //! Return whether or not we are targeting AIX.
195   bool IsAIX() const;
196 
197   bool IsImported() const;
198   bool IsImportedGloballyVisible() const;
199   bool IsPerConfig() const;
200   bool CanCompileSources() const;
201 
202   bool GetMappedConfig(std::string const& desired_config, cmValue& loc,
203                        cmValue& imp, std::string& suffix) const;
204 
205   //! Return whether this target is an executable with symbol exports enabled.
206   bool IsExecutableWithExports() const;
207 
208   //! Return whether this target is a shared library Framework on Apple.
209   bool IsFrameworkOnApple() const;
210 
211   //! Return whether this target is an executable Bundle on Apple.
212   bool IsAppBundleOnApple() const;
213 
214   //! Return whether this target is a GUI executable on Android.
215   bool IsAndroidGuiExecutable() const;
216 
217   //! Get a backtrace from the creation of the target.
218   cmListFileBacktrace const& GetBacktrace() const;
219 
220   void InsertInclude(BT<std::string> const& entry, bool before = false);
221   void InsertCompileOption(BT<std::string> const& entry, bool before = false);
222   void InsertCompileDefinition(BT<std::string> const& entry);
223   void InsertLinkOption(BT<std::string> const& entry, bool before = false);
224   void InsertLinkDirectory(BT<std::string> const& entry, bool before = false);
225   void InsertPrecompileHeader(BT<std::string> const& entry);
226 
227   void AppendBuildInterfaceIncludes();
228 
229   std::string GetDebugGeneratorExpressions(const std::string& value,
230                                            cmTargetLinkLibraryType llt) const;
231 
232   void AddSystemIncludeDirectories(std::set<std::string> const& incs);
233   std::set<std::string> const& GetSystemIncludeDirectories() const;
234 
235   void AddInstallIncludeDirectories(cmStringRange const& incs);
236   cmStringRange GetInstallIncludeDirectoriesEntries() const;
237 
238   BTs<std::string> const* GetLanguageStandardProperty(
239     const std::string& propertyName) const;
240 
241   void SetLanguageStandardProperty(std::string const& lang,
242                                    std::string const& value,
243                                    const std::string& feature);
244 
245   cmBTStringRange GetIncludeDirectoriesEntries() const;
246 
247   cmBTStringRange GetCompileOptionsEntries() const;
248 
249   cmBTStringRange GetCompileFeaturesEntries() const;
250 
251   cmBTStringRange GetCompileDefinitionsEntries() const;
252 
253   cmBTStringRange GetPrecompileHeadersEntries() const;
254 
255   cmBTStringRange GetSourceEntries() const;
256 
257   cmBTStringRange GetLinkOptionsEntries() const;
258 
259   cmBTStringRange GetLinkDirectoriesEntries() const;
260 
261   cmBTStringRange GetLinkImplementationEntries() const;
262 
263   std::string ImportedGetFullPath(const std::string& config,
264                                   cmStateEnums::ArtifactType artifact) const;
265 
266   struct StrictTargetComparison
267   {
268     bool operator()(cmTarget const* t1, cmTarget const* t2) const;
269   };
270 
271 private:
272   template <typename ValueType>
273   void StoreProperty(const std::string& prop, ValueType value);
274 
275   // Internal representation details.
276   friend class cmGeneratorTarget;
277 
278   const char* GetSuffixVariableInternal(
279     cmStateEnums::ArtifactType artifact) const;
280   const char* GetPrefixVariableInternal(
281     cmStateEnums::ArtifactType artifact) const;
282 
283   std::unique_ptr<cmTargetInternals> impl;
284 };
285