• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef TOOLS_GN_XCODE_OBJECT_H_
6 #define TOOLS_GN_XCODE_OBJECT_H_
7 
8 #include <iosfwd>
9 #include <map>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 // Helper classes to generate Xcode project files.
15 //
16 // This code is based on gyp xcodeproj_file.py generator. It does not support
17 // all features of Xcode project but instead just enough to implement a hybrid
18 // mode where Xcode uses external scripts to perform the compilation steps.
19 //
20 // See
21 // https://chromium.googlesource.com/external/gyp/+/master/pylib/gyp/xcodeproj_file.py
22 // for more information on Xcode project file format.
23 
24 // PBXObjectClass -------------------------------------------------------------
25 
26 enum PBXObjectClass {
27   // Those values needs to stay sorted in alphabetic order.
28   PBXAggregateTargetClass,
29   PBXBuildFileClass,
30   PBXContainerItemProxyClass,
31   PBXFileReferenceClass,
32   PBXFrameworksBuildPhaseClass,
33   PBXGroupClass,
34   PBXNativeTargetClass,
35   PBXProjectClass,
36   PBXResourcesBuildPhaseClass,
37   PBXShellScriptBuildPhaseClass,
38   PBXSourcesBuildPhaseClass,
39   PBXTargetDependencyClass,
40   XCBuildConfigurationClass,
41   XCConfigurationListClass,
42 };
43 
44 const char* ToString(PBXObjectClass cls);
45 
46 // Forward-declarations -------------------------------------------------------
47 
48 class PBXAggregateTarget;
49 class PBXBuildFile;
50 class PBXBuildPhase;
51 class PBXContainerItemProxy;
52 class PBXFileReference;
53 class PBXFrameworksBuildPhase;
54 class PBXGroup;
55 class PBXNativeTarget;
56 class PBXObject;
57 class PBXProject;
58 class PBXResourcesBuildPhase;
59 class PBXShellScriptBuildPhase;
60 class PBXSourcesBuildPhase;
61 class PBXTarget;
62 class PBXTargetDependency;
63 class XCBuildConfiguration;
64 class XCConfigurationList;
65 
66 using PBXAttributes = std::map<std::string, std::string>;
67 
68 // PBXObjectVisitor -----------------------------------------------------------
69 
70 class PBXObjectVisitor {
71  public:
72   PBXObjectVisitor();
73   virtual ~PBXObjectVisitor();
74   virtual void Visit(PBXObject* object) = 0;
75 
76  private:
77   PBXObjectVisitor(const PBXObjectVisitor&) = delete;
78   PBXObjectVisitor& operator=(const PBXObjectVisitor&) = delete;
79 };
80 
81 // PBXObjectVisitorConst ------------------------------------------------------
82 
83 class PBXObjectVisitorConst {
84  public:
85   PBXObjectVisitorConst();
86   virtual ~PBXObjectVisitorConst();
87   virtual void Visit(const PBXObject* object) = 0;
88 
89  private:
90   PBXObjectVisitorConst(const PBXObjectVisitorConst&) = delete;
91   PBXObjectVisitorConst& operator=(const PBXObjectVisitorConst&) = delete;
92 };
93 
94 // PBXObject ------------------------------------------------------------------
95 
96 class PBXObject {
97  public:
98   PBXObject();
99   virtual ~PBXObject();
100 
id()101   const std::string id() const { return id_; }
102   void SetId(const std::string& id);
103 
104   std::string Reference() const;
105 
106   virtual PBXObjectClass Class() const = 0;
107   virtual std::string Name() const = 0;
108   virtual std::string Comment() const;
109   virtual void Visit(PBXObjectVisitor& visitor);
110   virtual void Visit(PBXObjectVisitorConst& visitor) const;
111   virtual void Print(std::ostream& out, unsigned indent) const = 0;
112 
113  private:
114   std::string id_;
115 
116   PBXObject(const PBXObject&) = delete;
117   PBXObject& operator=(const PBXObject&) = delete;
118 };
119 
120 // PBXBuildPhase --------------------------------------------------------------
121 
122 class PBXBuildPhase : public PBXObject {
123  public:
124   PBXBuildPhase();
125   ~PBXBuildPhase() override;
126 
127   void AddBuildFile(std::unique_ptr<PBXBuildFile> build_file);
128 
129   // PBXObject implementation.
130   void Visit(PBXObjectVisitor& visitor) override;
131   void Visit(PBXObjectVisitorConst& visitor) const override;
132 
133  protected:
134   std::vector<std::unique_ptr<PBXBuildFile>> files_;
135 
136  private:
137   PBXBuildPhase(const PBXBuildPhase&) = delete;
138   PBXBuildPhase& operator=(const PBXBuildPhase&) = delete;
139 };
140 
141 // PBXTarget ------------------------------------------------------------------
142 
143 class PBXTarget : public PBXObject {
144  public:
145   PBXTarget(const std::string& name,
146             const std::string& shell_script,
147             const std::vector<std::string>& configs,
148             const PBXAttributes& attributes);
149   ~PBXTarget() override;
150 
151   void AddDependency(std::unique_ptr<PBXTargetDependency> dependency);
152 
153   // PBXObject implementation.
154   std::string Name() const override;
155   void Visit(PBXObjectVisitor& visitor) override;
156   void Visit(PBXObjectVisitorConst& visitor) const override;
157 
158  protected:
159   std::unique_ptr<XCConfigurationList> configurations_;
160   std::vector<std::unique_ptr<PBXBuildPhase>> build_phases_;
161   std::vector<std::unique_ptr<PBXTargetDependency>> dependencies_;
162   PBXSourcesBuildPhase* source_build_phase_ = nullptr;
163   PBXResourcesBuildPhase* resource_build_phase_ = nullptr;
164   std::string name_;
165 
166  private:
167   PBXTarget(const PBXTarget&) = delete;
168   PBXTarget& operator=(const PBXTarget&) = delete;
169 };
170 
171 // PBXAggregateTarget ---------------------------------------------------------
172 
173 class PBXAggregateTarget : public PBXTarget {
174  public:
175   PBXAggregateTarget(const std::string& name,
176                      const std::string& shell_script,
177                      const std::vector<std::string>& configs,
178                      const PBXAttributes& attributes);
179   ~PBXAggregateTarget() override;
180 
181   // PBXObject implementation.
182   PBXObjectClass Class() const override;
183   void Print(std::ostream& out, unsigned indent) const override;
184 
185  private:
186   PBXAggregateTarget(const PBXAggregateTarget&) = delete;
187   PBXAggregateTarget& operator=(const PBXAggregateTarget&) = delete;
188 };
189 
190 // PBXBuildFile ---------------------------------------------------------------
191 
192 class PBXBuildFile : public PBXObject {
193  public:
194   PBXBuildFile(const PBXFileReference* file_reference,
195                const PBXBuildPhase* build_phase);
196   ~PBXBuildFile() override;
197 
198   // PBXObject implementation.
199   PBXObjectClass Class() const override;
200   std::string Name() const override;
201   void Print(std::ostream& out, unsigned indent) const override;
202 
203  private:
204   const PBXFileReference* file_reference_ = nullptr;
205   const PBXBuildPhase* build_phase_ = nullptr;
206 
207   PBXBuildFile(const PBXBuildFile&) = delete;
208   PBXBuildFile& operator=(const PBXBuildFile&) = delete;
209 };
210 
211 // PBXContainerItemProxy ------------------------------------------------------
212 class PBXContainerItemProxy : public PBXObject {
213  public:
214   PBXContainerItemProxy(const PBXProject* project, const PBXTarget* target);
215   ~PBXContainerItemProxy() override;
216 
217   // PBXObject implementation.
218   PBXObjectClass Class() const override;
219   std::string Name() const override;
220   void Print(std::ostream& out, unsigned indent) const override;
221 
222  private:
223   const PBXProject* project_ = nullptr;
224   const PBXTarget* target_ = nullptr;
225 
226   PBXContainerItemProxy(const PBXContainerItemProxy&) = delete;
227   PBXContainerItemProxy& operator=(const PBXContainerItemProxy&) = delete;
228 };
229 
230 // PBXFileReference -----------------------------------------------------------
231 
232 class PBXFileReference : public PBXObject {
233  public:
234   PBXFileReference(const std::string& name,
235                    const std::string& path,
236                    const std::string& type);
237   ~PBXFileReference() override;
238 
239   // PBXObject implementation.
240   PBXObjectClass Class() const override;
241   std::string Name() const override;
242   std::string Comment() const override;
243   void Print(std::ostream& out, unsigned indent) const override;
244 
path()245   const std::string& path() const { return path_; }
246 
247  private:
248   std::string name_;
249   std::string path_;
250   std::string type_;
251 
252   PBXFileReference(const PBXFileReference&) = delete;
253   PBXFileReference& operator=(const PBXFileReference&) = delete;
254 };
255 
256 // PBXFrameworksBuildPhase ----------------------------------------------------
257 
258 class PBXFrameworksBuildPhase : public PBXBuildPhase {
259  public:
260   PBXFrameworksBuildPhase();
261   ~PBXFrameworksBuildPhase() override;
262 
263   // PBXObject implementation.
264   PBXObjectClass Class() const override;
265   std::string Name() const override;
266   void Print(std::ostream& out, unsigned indent) const override;
267 
268  private:
269   PBXFrameworksBuildPhase(const PBXFrameworksBuildPhase&) = delete;
270   PBXFrameworksBuildPhase& operator=(const PBXFrameworksBuildPhase&) = delete;
271 };
272 
273 // PBXGroup -------------------------------------------------------------------
274 
275 class PBXGroup : public PBXObject {
276  public:
277   explicit PBXGroup(const std::string& path = std::string(),
278                     const std::string& name = std::string());
279   ~PBXGroup() override;
280 
path()281   const std::string& path() const { return path_; }
name()282   const std::string& name() const { return name_; }
283 
284   PBXFileReference* AddSourceFile(const std::string& navigator_path,
285                                   const std::string& source_path);
286 
287   template <typename T, typename... Args>
CreateChild(Args &&...args)288   T* CreateChild(Args&&... args) {
289     return static_cast<T*>(
290         AddChildImpl(std::make_unique<T>(std::forward<Args>(args)...)));
291   }
292 
293   // PBXObject implementation.
294   PBXObjectClass Class() const override;
295   std::string Name() const override;
296   void Visit(PBXObjectVisitor& visitor) override;
297   void Visit(PBXObjectVisitorConst& visitor) const override;
298   void Print(std::ostream& out, unsigned indent) const override;
299 
300   // Returns whether the current PBXGroup should sort last when sorting
301   // children of a PBXGroup. This should only be used for the "Products"
302   // group which is hidden in Xcode UI when it is the last children of
303   // the main PBXProject group.
304   virtual bool SortLast() const;
305 
306  private:
307   PBXObject* AddChildImpl(std::unique_ptr<PBXObject> child);
308 
309   std::vector<std::unique_ptr<PBXObject>> children_;
310   std::string name_;
311   std::string path_;
312 
313   PBXGroup(const PBXGroup&) = delete;
314   PBXGroup& operator=(const PBXGroup&) = delete;
315 };
316 
317 // PBXMainGroup ---------------------------------------------------------------
318 
319 class PBXMainGroup : public PBXGroup {
320  public:
321   explicit PBXMainGroup(const std::string& source_path);
322   ~PBXMainGroup() override;
323 
324   std::string Name() const override;
325 };
326 
327 // PBXProductsGroup -----------------------------------------------------------
328 
329 class PBXProductsGroup : public PBXGroup {
330  public:
331   explicit PBXProductsGroup();
332   ~PBXProductsGroup() override;
333 
334   bool SortLast() const override;
335 };
336 
337 // PBXNativeTarget ------------------------------------------------------------
338 
339 class PBXNativeTarget : public PBXTarget {
340  public:
341   PBXNativeTarget(const std::string& name,
342                   const std::string& shell_script,
343                   const std::vector<std::string>& configs,
344                   const PBXAttributes& attributes,
345                   const std::string& product_type,
346                   const std::string& product_name,
347                   const PBXFileReference* product_reference);
348   ~PBXNativeTarget() override;
349 
350   void AddResourceFile(const PBXFileReference* file_reference);
351 
352   void AddFileForIndexing(const PBXFileReference* file_reference);
353 
354   // PBXObject implementation.
355   PBXObjectClass Class() const override;
356   void Print(std::ostream& out, unsigned indent) const override;
357 
358  private:
359   const PBXFileReference* product_reference_ = nullptr;
360   std::string product_type_;
361   std::string product_name_;
362 
363   PBXNativeTarget(const PBXNativeTarget&) = delete;
364   PBXNativeTarget& operator=(const PBXNativeTarget&) = delete;
365 };
366 
367 // PBXProject -----------------------------------------------------------------
368 
369 class PBXProject : public PBXObject {
370  public:
371   PBXProject(const std::string& name,
372              std::vector<std::string> configs,
373              const std::string& source_path,
374              const PBXAttributes& attributes);
375   ~PBXProject() override;
376 
377   void AddSourceFileToIndexingTarget(const std::string& navigator_path,
378                                      const std::string& source_path);
379   void AddSourceFile(const std::string& navigator_path,
380                      const std::string& source_path,
381                      PBXNativeTarget* target);
382   void AddAggregateTarget(const std::string& name,
383                           const std::string& output_dir,
384                           const std::string& shell_script);
385   void AddIndexingTarget();
386   PBXNativeTarget* AddNativeTarget(
387       const std::string& name,
388       const std::string& type,
389       const std::string& output_dir,
390       const std::string& output_name,
391       const std::string& output_type,
392       const std::string& shell_script,
393       const PBXAttributes& extra_attributes = PBXAttributes());
394 
395   void SetProjectDirPath(const std::string& project_dir_path);
396   void SetProjectRoot(const std::string& project_root);
397   void AddTarget(std::unique_ptr<PBXTarget> target);
398 
399   // PBXObject implementation.
400   PBXObjectClass Class() const override;
401   std::string Name() const override;
402   std::string Comment() const override;
403   void Visit(PBXObjectVisitor& visitor) override;
404   void Visit(PBXObjectVisitorConst& visitor) const override;
405   void Print(std::ostream& out, unsigned indent) const override;
406 
407  private:
408   PBXAttributes attributes_;
409   std::unique_ptr<XCConfigurationList> configurations_;
410   std::unique_ptr<PBXGroup> main_group_;
411   std::string project_dir_path_;
412   std::string project_root_;
413   std::vector<std::unique_ptr<PBXTarget>> targets_;
414   std::string name_;
415   std::vector<std::string> configs_;
416 
417   PBXGroup* products_ = nullptr;
418   PBXNativeTarget* target_for_indexing_ = nullptr;
419 
420   PBXProject(const PBXProject&) = delete;
421   PBXProject& operator=(const PBXProject&) = delete;
422 };
423 
424 // PBXResourcesBuildPhase -----------------------------------------------------
425 
426 class PBXResourcesBuildPhase : public PBXBuildPhase {
427  public:
428   PBXResourcesBuildPhase();
429   ~PBXResourcesBuildPhase() override;
430 
431   // PBXObject implementation.
432   PBXObjectClass Class() const override;
433   std::string Name() const override;
434   void Print(std::ostream& out, unsigned indent) const override;
435 
436  private:
437   PBXResourcesBuildPhase(const PBXResourcesBuildPhase&) = delete;
438   PBXResourcesBuildPhase& operator=(const PBXResourcesBuildPhase&) = delete;
439 };
440 
441 // PBXShellScriptBuildPhase ---------------------------------------------------
442 
443 class PBXShellScriptBuildPhase : public PBXBuildPhase {
444  public:
445   PBXShellScriptBuildPhase(const std::string& name,
446                            const std::string& shell_script);
447   ~PBXShellScriptBuildPhase() override;
448 
449   // PBXObject implementation.
450   PBXObjectClass Class() const override;
451   std::string Name() const override;
452   void Print(std::ostream& out, unsigned indent) const override;
453 
454  private:
455   std::string name_;
456   std::string shell_script_;
457 
458   PBXShellScriptBuildPhase(const PBXShellScriptBuildPhase&) = delete;
459   PBXShellScriptBuildPhase& operator=(const PBXShellScriptBuildPhase&) = delete;
460 };
461 
462 // PBXSourcesBuildPhase -------------------------------------------------------
463 
464 class PBXSourcesBuildPhase : public PBXBuildPhase {
465  public:
466   PBXSourcesBuildPhase();
467   ~PBXSourcesBuildPhase() override;
468 
469   // PBXObject implementation.
470   PBXObjectClass Class() const override;
471   std::string Name() const override;
472   void Print(std::ostream& out, unsigned indent) const override;
473 
474  private:
475   PBXSourcesBuildPhase(const PBXSourcesBuildPhase&) = delete;
476   PBXSourcesBuildPhase& operator=(const PBXSourcesBuildPhase&) = delete;
477 };
478 
479 // PBXTargetDependency -----------------------------------------------------
480 class PBXTargetDependency : public PBXObject {
481  public:
482   PBXTargetDependency(
483       const PBXTarget* target,
484       std::unique_ptr<PBXContainerItemProxy> container_item_proxy);
485   ~PBXTargetDependency() override;
486 
487   // PBXObject implementation.
488   PBXObjectClass Class() const override;
489   std::string Name() const override;
490   void Visit(PBXObjectVisitor& visitor) override;
491   void Visit(PBXObjectVisitorConst& visitor) const override;
492   void Print(std::ostream& out, unsigned indent) const override;
493 
494  private:
495   const PBXTarget* target_ = nullptr;
496   std::unique_ptr<PBXContainerItemProxy> container_item_proxy_;
497 
498   PBXTargetDependency(const PBXTargetDependency&) = delete;
499   PBXTargetDependency& operator=(const PBXTargetDependency&) = delete;
500 };
501 
502 // XCBuildConfiguration -------------------------------------------------------
503 
504 class XCBuildConfiguration : public PBXObject {
505  public:
506   XCBuildConfiguration(const std::string& name,
507                        const PBXAttributes& attributes);
508   ~XCBuildConfiguration() override;
509 
510   // PBXObject implementation.
511   PBXObjectClass Class() const override;
512   std::string Name() const override;
513   void Print(std::ostream& out, unsigned indent) const override;
514 
515  private:
516   PBXAttributes attributes_;
517   std::string name_;
518 
519   XCBuildConfiguration(const XCBuildConfiguration&) = delete;
520   XCBuildConfiguration& operator=(const XCBuildConfiguration&) = delete;
521 };
522 
523 // XCConfigurationList --------------------------------------------------------
524 
525 class XCConfigurationList : public PBXObject {
526  public:
527   XCConfigurationList(const std::vector<std::string>& configs,
528                       const PBXAttributes& attributes,
529                       const PBXObject* owner_reference);
530   ~XCConfigurationList() override;
531 
532   // PBXObject implementation.
533   PBXObjectClass Class() const override;
534   std::string Name() const override;
535   void Visit(PBXObjectVisitor& visitor) override;
536   void Visit(PBXObjectVisitorConst& visitor) const override;
537   void Print(std::ostream& out, unsigned indent) const override;
538 
539  private:
540   std::vector<std::unique_ptr<XCBuildConfiguration>> configurations_;
541   const PBXObject* owner_reference_ = nullptr;
542 
543   XCConfigurationList(const XCConfigurationList&) = delete;
544   XCConfigurationList& operator=(const XCConfigurationList&) = delete;
545 };
546 
547 #endif  // TOOLS_GN_XCODE_OBJECT_H_
548