Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Source / cmGlobalXCodeGenerator.h
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 <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <vector>
13
14 #include <cm/optional>
15 #include <cm/string_view>
16
17 #include "cmGlobalGenerator.h"
18 #include "cmTransformDepfile.h"
19 #include "cmValue.h"
20 #include "cmXCodeObject.h"
21
22 class cmCustomCommand;
23 class cmCustomCommandGenerator;
24 class cmGeneratorTarget;
25 class cmGlobalGeneratorFactory;
26 class cmLocalGenerator;
27 class cmMakefile;
28 class cmSourceFile;
29 class cmSourceGroup;
30 class cmake;
31 struct cmDocumentationEntry;
32
33 /** \class cmGlobalXCodeGenerator
34  * \brief Write a Unix makefiles.
35  *
36  * cmGlobalXCodeGenerator manages Xcode build process for a tree
37  */
38 class cmGlobalXCodeGenerator : public cmGlobalGenerator
39 {
40 public:
41   cmGlobalXCodeGenerator(cmake* cm, std::string const& version_string,
42                          unsigned int version_number);
43   static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
44
45   cmGlobalXCodeGenerator(const cmGlobalXCodeGenerator&) = delete;
46   const cmGlobalXCodeGenerator& operator=(const cmGlobalXCodeGenerator&) =
47     delete;
48
49   //! Get the name for the generator.
50   std::string GetName() const override
51   {
52     return cmGlobalXCodeGenerator::GetActualName();
53   }
54   static std::string GetActualName() { return "Xcode"; }
55
56   /** Get the documentation entry for this generator.  */
57   static void GetDocumentation(cmDocumentationEntry& entry);
58
59   //! Create a local generator appropriate to this Global Generator
60   std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
61     cmMakefile* mf) override;
62
63   /**
64    * Try to determine system information such as shared library
65    * extension, pthreads, byte order etc.
66    */
67   void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
68                       bool optional) override;
69
70   /**
71    * Open a generated IDE project given the following information.
72    */
73   bool Open(const std::string& bindir, const std::string& projectName,
74             bool dryRun) override;
75
76   /**
77    * Try running cmake and building a file. This is used for dynalically
78    * loaded commands, not as part of the usual build process.
79    */
80   std::vector<GeneratedMakeCommand> GenerateBuildCommand(
81     const std::string& makeProgram, const std::string& projectName,
82     const std::string& projectDir, std::vector<std::string> const& targetNames,
83     const std::string& config, int jobs, bool verbose,
84     const cmBuildOptions& buildOptions = cmBuildOptions(),
85     std::vector<std::string> const& makeOptions =
86       std::vector<std::string>()) override;
87
88   /** Append the subdirectory for the given configuration.  */
89   void AppendDirectoryForConfig(const std::string& prefix,
90                                 const std::string& config,
91                                 const std::string& suffix,
92                                 std::string& dir) override;
93
94   bool FindMakeProgram(cmMakefile*) override;
95
96   //! What is the configurations directory variable called?
97   const char* GetCMakeCFGIntDir() const override;
98   //! expand CFGIntDir
99   std::string ExpandCFGIntDir(const std::string& str,
100                               const std::string& config) const override;
101
102   void SetCurrentLocalGenerator(cmLocalGenerator*);
103
104   /** Return true if the generated build tree may contain multiple builds.
105       i.e. "Can I build Debug and Release in the same tree?" */
106   bool IsMultiConfig() const override;
107
108   bool IsXcode() const override { return true; }
109
110   bool HasKnownObjectFileLocation(cmTarget const&,
111                                   std::string* reason) const override;
112
113   bool IsIPOSupported() const override { return true; }
114
115   bool UseEffectivePlatformName(cmMakefile* mf) const override;
116
117   bool ShouldStripResourcePath(cmMakefile*) const override;
118
119   /**
120    * Used to determine if this generator supports DEPFILE option.
121    */
122   bool SupportsCustomCommandDepfile() const override { return true; }
123   virtual cm::optional<cmDepfileFormat> DepfileFormat() const override
124   {
125     return this->XcodeBuildSystem == BuildSystem::One
126       ? cmDepfileFormat::MakeDepfile
127       : cmDepfileFormat::GccDepfile;
128   }
129
130   bool SetSystemName(std::string const& s, cmMakefile* mf) override;
131   bool SetGeneratorToolset(std::string const& ts, bool build,
132                            cmMakefile* mf) override;
133   void AppendFlag(std::string& flags, std::string const& flag) const;
134
135   enum class BuildSystem
136   {
137     One = 1,
138     Twelve = 12,
139   };
140
141 protected:
142   void AddExtraIDETargets() override;
143   void Generate() override;
144
145 private:
146   enum EmbedActionFlags
147   {
148     NoActionOnCopyByDefault = 0,
149     CodeSignOnCopyByDefault = 1,
150     RemoveHeadersOnCopyByDefault = 2,
151   };
152
153   bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
154   bool ProcessGeneratorToolsetField(std::string const& key,
155                                     std::string const& value, cmMakefile* mf);
156
157   cmXCodeObject* CreateOrGetPBXGroup(cmGeneratorTarget* gtgt,
158                                      cmSourceGroup* sg);
159   cmXCodeObject* CreatePBXGroup(cmXCodeObject* parent,
160                                 const std::string& name);
161   bool CreateGroups(std::vector<cmLocalGenerator*>& generators);
162   std::string XCodeEscapePath(const std::string& p);
163   std::string RelativeToSource(const std::string& p);
164   std::string RelativeToBinary(const std::string& p);
165   std::string ConvertToRelativeForMake(std::string const& p);
166   void CreateCustomCommands(
167     cmXCodeObject* buildPhases, cmXCodeObject* sourceBuildPhase,
168     cmXCodeObject* headerBuildPhase, cmXCodeObject* resourceBuildPhase,
169     std::vector<cmXCodeObject*> const& contentBuildPhases,
170     cmXCodeObject* frameworkBuildPhase, cmGeneratorTarget* gtgt);
171
172   std::string ComputeInfoPListLocation(cmGeneratorTarget* target);
173
174   void AddCommandsToBuildPhase(cmXCodeObject* buildphase,
175                                cmGeneratorTarget* target,
176                                std::vector<cmCustomCommand> const& commands,
177                                const char* commandFileName);
178
179   void CreateCustomRulesMakefile(const char* makefileBasename,
180                                  cmGeneratorTarget* target,
181                                  std::vector<cmCustomCommand> const& commands,
182                                  const std::string& configName);
183
184   cmXCodeObject* FindXCodeTarget(const cmGeneratorTarget*);
185   std::string GetObjectId(cmXCodeObject::PBXType ptype, cm::string_view key);
186   std::string GetOrCreateId(const std::string& name, const std::string& id);
187
188   // create cmXCodeObject from these functions so that memory can be managed
189   // correctly.  All objects created are stored in this->XCodeObjects.
190   cmXCodeObject* CreateObject(cmXCodeObject::PBXType ptype,
191                               cm::string_view key = {});
192   cmXCodeObject* CreateObject(cmXCodeObject::Type type);
193   cmXCodeObject* CreateString(const std::string& s);
194   cmXCodeObject* CreateObjectReference(cmXCodeObject*);
195   cmXCodeObject* CreateFlatClone(cmXCodeObject*);
196   cmXCodeObject* CreateXCodeTarget(cmGeneratorTarget* gtgt,
197                                    cmXCodeObject* buildPhases);
198   void ForceLinkerLanguages() override;
199   void ForceLinkerLanguage(cmGeneratorTarget* gtgt);
200   const char* GetTargetLinkFlagsVar(const cmGeneratorTarget* target) const;
201   const char* GetTargetFileType(cmGeneratorTarget* target);
202   const char* GetTargetProductType(cmGeneratorTarget* target);
203   std::string AddConfigurations(cmXCodeObject* target,
204                                 cmGeneratorTarget* gtgt);
205   void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr,
206                                cmXCodeObject* value);
207   void AppendBuildSettingAttribute(cmXCodeObject* settings,
208                                    const char* attribute, cmXCodeObject* attr,
209                                    cmXCodeObject* value);
210   void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr,
211                                    cmXCodeObject* value,
212                                    const std::string& configName);
213   void InheritBuildSettingAttribute(cmXCodeObject* target,
214                                     const char* attribute);
215   cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget* gtgt);
216   void AddDependAndLinkInformation(cmXCodeObject* target);
217   void AddEmbeddedObjects(cmXCodeObject* target,
218                           const std::string& copyFilesBuildPhaseName,
219                           const std::string& embedPropertyName,
220                           const std::string& dstSubfolderSpec,
221                           int actionsOnByDefault);
222   void AddEmbeddedFrameworks(cmXCodeObject* target);
223   void AddEmbeddedPlugIns(cmXCodeObject* target);
224   void AddEmbeddedAppExtensions(cmXCodeObject* target);
225   void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target,
226                                            cmXCodeObject* buildSettings,
227                                            const std::string& configName);
228   void CreateGlobalXCConfigSettings(cmLocalGenerator* root,
229                                     cmXCodeObject* config,
230                                     const std::string& configName);
231   void CreateTargetXCConfigSettings(cmGeneratorTarget* target,
232                                     cmXCodeObject* config,
233                                     const std::string& configName);
234   void CreateBuildSettings(cmGeneratorTarget* gtgt,
235                            cmXCodeObject* buildSettings,
236                            const std::string& buildType);
237   std::string ExtractFlag(const char* flag, std::string& flags);
238   std::string ExtractFlagRegex(const char* exp, int matchIndex,
239                                std::string& flags);
240   void FilterConfigurationAttribute(std::string const& configName,
241                                     std::string& attribute);
242   void SortXCodeObjects();
243   // delete all objects in the this->XCodeObjects vector.
244   void ClearXCodeObjects();
245   bool CreateXCodeObjects(cmLocalGenerator* root,
246                           std::vector<cmLocalGenerator*>& generators);
247   void OutputXCodeProject(cmLocalGenerator* root,
248                           std::vector<cmLocalGenerator*>& generators);
249   // Write shared scheme files for all the native targets
250   //  return true if any were written
251   bool OutputXCodeSharedSchemes(const std::string& xcProjDir,
252                                 cmLocalGenerator* root);
253   void OutputXCodeWorkspaceSettings(const std::string& xcProjDir,
254                                     bool hasGeneratedSchemes);
255   void WriteXCodePBXProj(std::ostream& fout, cmLocalGenerator* root,
256                          std::vector<cmLocalGenerator*>& generators);
257   cmXCodeObject* CreateXCodeFileReferenceFromPath(const std::string& fullpath,
258                                                   cmGeneratorTarget* target,
259                                                   const std::string& lang,
260                                                   cmSourceFile* sf);
261   cmXCodeObject* CreateXCodeBuildFileFromPath(const std::string& fullpath,
262                                               cmGeneratorTarget* target,
263                                               const std::string& lang,
264                                               cmSourceFile* sf);
265   cmXCodeObject* CreateXCodeFileReference(cmSourceFile* sf,
266                                           cmGeneratorTarget* target);
267   cmXCodeObject* CreateXCodeSourceFile(cmLocalGenerator* gen, cmSourceFile* sf,
268                                        cmGeneratorTarget* gtgt);
269   void AddXCodeProjBuildRule(cmGeneratorTarget* target,
270                              std::vector<cmSourceFile*>& sources) const;
271   bool CreateXCodeTargets(cmLocalGenerator* gen, std::vector<cmXCodeObject*>&);
272   bool CreateXCodeTarget(cmGeneratorTarget* gtgt,
273                          std::vector<cmXCodeObject*>&);
274   bool IsHeaderFile(cmSourceFile*);
275   void AddDependTarget(cmXCodeObject* target, cmXCodeObject* dependTarget);
276   void CreateXCodeDependHackMakefile(std::vector<cmXCodeObject*>& targets);
277   bool SpecialTargetEmitted(std::string const& tname);
278   void SetGenerationRoot(cmLocalGenerator* root);
279   void AddExtraTargets(cmLocalGenerator* root,
280                        std::vector<cmLocalGenerator*>& gens);
281   cmXCodeObject* CreateLegacyRunScriptBuildPhase(
282     const char* name, const char* name2, cmGeneratorTarget* target,
283     const std::vector<cmCustomCommand>&);
284   void CreateRunScriptBuildPhases(cmXCodeObject* buildPhases,
285                                   cmGeneratorTarget const* gt);
286   void CreateRunScriptBuildPhases(cmXCodeObject* buildPhases,
287                                   cmSourceFile const* sf,
288                                   cmGeneratorTarget const* gt,
289                                   std::set<cmSourceFile const*>& visited);
290   cmXCodeObject* CreateRunScriptBuildPhase(cmSourceFile const* sf,
291                                            cmGeneratorTarget const* gt,
292                                            cmCustomCommand const& cc);
293   cmXCodeObject* CreateRunScriptBuildPhase(
294     std::string const& name, cmGeneratorTarget const* gt,
295     std::vector<cmCustomCommand> const& commands);
296   std::string ConstructScript(cmCustomCommandGenerator const& ccg);
297   void CreateReRunCMakeFile(cmLocalGenerator* root,
298                             std::vector<cmLocalGenerator*> const& gens);
299
300   std::string LookupFlags(const std::string& varNamePrefix,
301                           const std::string& varNameLang,
302                           const std::string& varNameSuffix,
303                           const std::string& default_flags);
304
305   class Factory;
306   class BuildObjectListOrString;
307   friend class BuildObjectListOrString;
308
309   void AppendDefines(BuildObjectListOrString& defs, const char* defines_list,
310                      bool dflag = false);
311   void AppendDefines(BuildObjectListOrString& defs,
312                      std::vector<std::string> const& defines,
313                      bool dflag = false);
314
315   void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
316
317 protected:
318   const char* GetInstallTargetName() const override { return "install"; }
319   const char* GetPackageTargetName() const override { return "package"; }
320
321   unsigned int XcodeVersion;
322   std::string VersionString;
323   std::set<std::string> XCodeObjectIDs;
324   std::vector<std::unique_ptr<cmXCodeObject>> XCodeObjects;
325   cmXCodeObject* RootObject;
326
327   BuildSystem XcodeBuildSystem = BuildSystem::One;
328
329 private:
330   std::string const& GetXcodeBuildCommand();
331   std::string FindXcodeBuildCommand();
332   std::string XcodeBuildCommand;
333   bool XcodeBuildCommandInitialized;
334
335   void PrintCompilerAdvice(std::ostream&, std::string const&,
336                            cmValue) const override
337   {
338   }
339
340   std::string GetLibraryOrFrameworkPath(const std::string& path) const;
341
342   std::string GetSymrootDir() const;
343   std::string GetTargetTempDir(cmGeneratorTarget const* gt,
344                                std::string const& configName) const;
345
346   static std::string GetDeploymentPlatform(const cmMakefile* mf);
347
348   void ComputeArchitectures(cmMakefile* mf);
349   void ComputeObjectDirArch(cmMakefile* mf);
350
351   void addObject(std::unique_ptr<cmXCodeObject> obj);
352   std::string PostBuildMakeTarget(std::string const& tName,
353                                   std::string const& configName);
354   cmXCodeObject* MainGroupChildren;
355   cmXCodeObject* FrameworkGroup;
356   cmMakefile* CurrentMakefile;
357   cmLocalGenerator* CurrentLocalGenerator;
358   cmLocalGenerator* CurrentRootGenerator = nullptr;
359   std::vector<std::string> CurrentConfigurationTypes;
360   std::string CurrentReRunCMakeMakefile;
361   std::string CurrentXCodeHackMakefile;
362   std::string CurrentProject;
363   std::set<std::string> TargetDoneSet;
364   std::map<std::string, cmXCodeObject*> GroupMap;
365   std::map<std::string, cmXCodeObject*> GroupNameMap;
366   std::map<std::string, cmXCodeObject*> TargetGroup;
367   std::map<std::string, cmXCodeObject*> FileRefs;
368   std::map<std::string, cmXCodeObject*> ExternalLibRefs;
369   std::map<std::string, cmXCodeObject*> EmbeddedLibRefs;
370   std::map<cmGeneratorTarget const*, cmXCodeObject*> XCodeObjectMap;
371   std::map<cmXCodeObject*, cmXCodeObject*> FileRefToBuildFileMap;
372   std::map<cmXCodeObject*, cmXCodeObject*> FileRefToEmbedBuildFileMap;
373   std::vector<std::string> Architectures;
374   std::string ObjectDirArchDefault;
375   std::string ObjectDirArch;
376   std::string SystemName;
377   std::string GeneratorToolset;
378   std::vector<std::string> EnabledLangs;
379   std::map<cmGeneratorTarget const*, std::set<cmSourceFile const*>>
380     CommandsVisited;
381   std::map<cmSourceFile const*, std::set<cmGeneratorTarget const*>>
382     CustomCommandRoots;
383 };