| // Copyright 2016 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef TOOLS_GN_XCODE_OBJECT_H_ | |
| #define TOOLS_GN_XCODE_OBJECT_H_ | |
| #include <iosfwd> | |
| #include <map> | |
| #include <memory> | |
| #include <string> | |
| #include <vector> | |
| // Helper classes to generate Xcode project files. | |
| // | |
| // This code is based on gyp xcodeproj_file.py generator. It does not support | |
| // all features of Xcode project but instead just enough to implement a hybrid | |
| // mode where Xcode uses external scripts to perform the compilation steps. | |
| // | |
| // See | |
| // https://chromium.googlesource.com/external/gyp/+/master/pylib/gyp/xcodeproj_file.py | |
| // for more information on Xcode project file format. | |
| // PBXObjectClass ------------------------------------------------------------- | |
| enum PBXObjectClass { | |
| // Those values needs to stay sorted in alphabetic order. | |
| PBXAggregateTargetClass, | |
| PBXBuildFileClass, | |
| PBXContainerItemProxyClass, | |
| PBXFileReferenceClass, | |
| PBXFrameworksBuildPhaseClass, | |
| PBXGroupClass, | |
| PBXNativeTargetClass, | |
| PBXProjectClass, | |
| PBXResourcesBuildPhaseClass, | |
| PBXShellScriptBuildPhaseClass, | |
| PBXSourcesBuildPhaseClass, | |
| PBXTargetDependencyClass, | |
| XCBuildConfigurationClass, | |
| XCConfigurationListClass, | |
| }; | |
| const char* ToString(PBXObjectClass cls); | |
| // Forward-declarations ------------------------------------------------------- | |
| class PBXAggregateTarget; | |
| class PBXBuildFile; | |
| class PBXBuildPhase; | |
| class PBXContainerItemProxy; | |
| class PBXFileReference; | |
| class PBXFrameworksBuildPhase; | |
| class PBXGroup; | |
| class PBXNativeTarget; | |
| class PBXObject; | |
| class PBXProject; | |
| class PBXResourcesBuildPhase; | |
| class PBXShellScriptBuildPhase; | |
| class PBXSourcesBuildPhase; | |
| class PBXTarget; | |
| class PBXTargetDependency; | |
| class XCBuildConfiguration; | |
| class XCConfigurationList; | |
| using PBXAttributes = std::map<std::string, std::string>; | |
| // PBXObjectVisitor ----------------------------------------------------------- | |
| class PBXObjectVisitor { | |
| public: | |
| PBXObjectVisitor(); | |
| virtual ~PBXObjectVisitor(); | |
| virtual void Visit(PBXObject* object) = 0; | |
| private: | |
| PBXObjectVisitor(const PBXObjectVisitor&) = delete; | |
| PBXObjectVisitor& operator=(const PBXObjectVisitor&) = delete; | |
| }; | |
| // PBXObjectVisitorConst ------------------------------------------------------ | |
| class PBXObjectVisitorConst { | |
| public: | |
| PBXObjectVisitorConst(); | |
| virtual ~PBXObjectVisitorConst(); | |
| virtual void Visit(const PBXObject* object) = 0; | |
| private: | |
| PBXObjectVisitorConst(const PBXObjectVisitorConst&) = delete; | |
| PBXObjectVisitorConst& operator=(const PBXObjectVisitorConst&) = delete; | |
| }; | |
| // PBXObject ------------------------------------------------------------------ | |
| class PBXObject { | |
| public: | |
| PBXObject(); | |
| virtual ~PBXObject(); | |
| const std::string id() const { return id_; } | |
| void SetId(const std::string& id); | |
| std::string Reference() const; | |
| virtual PBXObjectClass Class() const = 0; | |
| virtual std::string Name() const = 0; | |
| virtual std::string Comment() const; | |
| virtual void Visit(PBXObjectVisitor& visitor); | |
| virtual void Visit(PBXObjectVisitorConst& visitor) const; | |
| virtual void Print(std::ostream& out, unsigned indent) const = 0; | |
| private: | |
| std::string id_; | |
| PBXObject(const PBXObject&) = delete; | |
| PBXObject& operator=(const PBXObject&) = delete; | |
| }; | |
| // PBXBuildPhase -------------------------------------------------------------- | |
| class PBXBuildPhase : public PBXObject { | |
| public: | |
| PBXBuildPhase(); | |
| ~PBXBuildPhase() override; | |
| void AddBuildFile(std::unique_ptr<PBXBuildFile> build_file); | |
| // PBXObject implementation. | |
| void Visit(PBXObjectVisitor& visitor) override; | |
| void Visit(PBXObjectVisitorConst& visitor) const override; | |
| protected: | |
| std::vector<std::unique_ptr<PBXBuildFile>> files_; | |
| private: | |
| PBXBuildPhase(const PBXBuildPhase&) = delete; | |
| PBXBuildPhase& operator=(const PBXBuildPhase&) = delete; | |
| }; | |
| // PBXTarget ------------------------------------------------------------------ | |
| class PBXTarget : public PBXObject { | |
| public: | |
| PBXTarget(const std::string& name, | |
| const std::string& shell_script, | |
| const std::vector<std::string>& configs, | |
| const PBXAttributes& attributes); | |
| ~PBXTarget() override; | |
| void AddDependency(std::unique_ptr<PBXTargetDependency> dependency); | |
| // PBXObject implementation. | |
| std::string Name() const override; | |
| void Visit(PBXObjectVisitor& visitor) override; | |
| void Visit(PBXObjectVisitorConst& visitor) const override; | |
| protected: | |
| std::unique_ptr<XCConfigurationList> configurations_; | |
| std::vector<std::unique_ptr<PBXBuildPhase>> build_phases_; | |
| std::vector<std::unique_ptr<PBXTargetDependency>> dependencies_; | |
| PBXSourcesBuildPhase* source_build_phase_ = nullptr; | |
| PBXResourcesBuildPhase* resource_build_phase_ = nullptr; | |
| std::string name_; | |
| private: | |
| PBXTarget(const PBXTarget&) = delete; | |
| PBXTarget& operator=(const PBXTarget&) = delete; | |
| }; | |
| // PBXAggregateTarget --------------------------------------------------------- | |
| class PBXAggregateTarget : public PBXTarget { | |
| public: | |
| PBXAggregateTarget(const std::string& name, | |
| const std::string& shell_script, | |
| const std::vector<std::string>& configs, | |
| const PBXAttributes& attributes); | |
| ~PBXAggregateTarget() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| PBXAggregateTarget(const PBXAggregateTarget&) = delete; | |
| PBXAggregateTarget& operator=(const PBXAggregateTarget&) = delete; | |
| }; | |
| // PBXBuildFile --------------------------------------------------------------- | |
| class PBXBuildFile : public PBXObject { | |
| public: | |
| PBXBuildFile(const PBXFileReference* file_reference, | |
| const PBXBuildPhase* build_phase); | |
| ~PBXBuildFile() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| const PBXFileReference* file_reference_ = nullptr; | |
| const PBXBuildPhase* build_phase_ = nullptr; | |
| PBXBuildFile(const PBXBuildFile&) = delete; | |
| PBXBuildFile& operator=(const PBXBuildFile&) = delete; | |
| }; | |
| // PBXContainerItemProxy ------------------------------------------------------ | |
| class PBXContainerItemProxy : public PBXObject { | |
| public: | |
| PBXContainerItemProxy(const PBXProject* project, const PBXTarget* target); | |
| ~PBXContainerItemProxy() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| const PBXProject* project_ = nullptr; | |
| const PBXTarget* target_ = nullptr; | |
| PBXContainerItemProxy(const PBXContainerItemProxy&) = delete; | |
| PBXContainerItemProxy& operator=(const PBXContainerItemProxy&) = delete; | |
| }; | |
| // PBXFileReference ----------------------------------------------------------- | |
| class PBXFileReference : public PBXObject { | |
| public: | |
| PBXFileReference(const std::string& name, | |
| const std::string& path, | |
| const std::string& type); | |
| ~PBXFileReference() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| std::string Comment() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| const std::string& path() const { return path_; } | |
| private: | |
| std::string name_; | |
| std::string path_; | |
| std::string type_; | |
| PBXFileReference(const PBXFileReference&) = delete; | |
| PBXFileReference& operator=(const PBXFileReference&) = delete; | |
| }; | |
| // PBXFrameworksBuildPhase ---------------------------------------------------- | |
| class PBXFrameworksBuildPhase : public PBXBuildPhase { | |
| public: | |
| PBXFrameworksBuildPhase(); | |
| ~PBXFrameworksBuildPhase() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| PBXFrameworksBuildPhase(const PBXFrameworksBuildPhase&) = delete; | |
| PBXFrameworksBuildPhase& operator=(const PBXFrameworksBuildPhase&) = delete; | |
| }; | |
| // PBXGroup ------------------------------------------------------------------- | |
| class PBXGroup : public PBXObject { | |
| public: | |
| explicit PBXGroup(const std::string& path = std::string(), | |
| const std::string& name = std::string()); | |
| ~PBXGroup() override; | |
| const std::string& path() const { return path_; } | |
| const std::string& name() const { return name_; } | |
| PBXFileReference* AddSourceFile(const std::string& navigator_path, | |
| const std::string& source_path); | |
| template <typename T, typename... Args> | |
| T* CreateChild(Args&&... args) { | |
| return static_cast<T*>( | |
| AddChildImpl(std::make_unique<T>(std::forward<Args>(args)...))); | |
| } | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Visit(PBXObjectVisitor& visitor) override; | |
| void Visit(PBXObjectVisitorConst& visitor) const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| // Returns whether the current PBXGroup should sort last when sorting | |
| // children of a PBXGroup. This should only be used for the "Products" | |
| // group which is hidden in Xcode UI when it is the last children of | |
| // the main PBXProject group. | |
| virtual bool SortLast() const; | |
| private: | |
| PBXObject* AddChildImpl(std::unique_ptr<PBXObject> child); | |
| std::vector<std::unique_ptr<PBXObject>> children_; | |
| std::string name_; | |
| std::string path_; | |
| PBXGroup(const PBXGroup&) = delete; | |
| PBXGroup& operator=(const PBXGroup&) = delete; | |
| }; | |
| // PBXMainGroup --------------------------------------------------------------- | |
| class PBXMainGroup : public PBXGroup { | |
| public: | |
| explicit PBXMainGroup(const std::string& source_path); | |
| ~PBXMainGroup() override; | |
| std::string Name() const override; | |
| }; | |
| // PBXProductsGroup ----------------------------------------------------------- | |
| class PBXProductsGroup : public PBXGroup { | |
| public: | |
| explicit PBXProductsGroup(); | |
| ~PBXProductsGroup() override; | |
| bool SortLast() const override; | |
| }; | |
| // PBXNativeTarget ------------------------------------------------------------ | |
| class PBXNativeTarget : public PBXTarget { | |
| public: | |
| PBXNativeTarget(const std::string& name, | |
| const std::string& shell_script, | |
| const std::vector<std::string>& configs, | |
| const PBXAttributes& attributes, | |
| const std::string& product_type, | |
| const std::string& product_name, | |
| const PBXFileReference* product_reference); | |
| ~PBXNativeTarget() override; | |
| void AddResourceFile(const PBXFileReference* file_reference); | |
| void AddFileForIndexing(const PBXFileReference* file_reference); | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| const PBXFileReference* product_reference_ = nullptr; | |
| std::string product_type_; | |
| std::string product_name_; | |
| PBXNativeTarget(const PBXNativeTarget&) = delete; | |
| PBXNativeTarget& operator=(const PBXNativeTarget&) = delete; | |
| }; | |
| // PBXProject ----------------------------------------------------------------- | |
| class PBXProject : public PBXObject { | |
| public: | |
| PBXProject(const std::string& name, | |
| std::vector<std::string> configs, | |
| const std::string& source_path, | |
| const PBXAttributes& attributes); | |
| ~PBXProject() override; | |
| void AddSourceFileToIndexingTarget(const std::string& navigator_path, | |
| const std::string& source_path); | |
| void AddSourceFile(const std::string& navigator_path, | |
| const std::string& source_path, | |
| PBXNativeTarget* target); | |
| void AddAggregateTarget(const std::string& name, | |
| const std::string& output_dir, | |
| const std::string& shell_script); | |
| void AddIndexingTarget(); | |
| PBXNativeTarget* AddNativeTarget( | |
| const std::string& name, | |
| const std::string& type, | |
| const std::string& output_dir, | |
| const std::string& output_name, | |
| const std::string& output_type, | |
| const std::string& shell_script, | |
| const PBXAttributes& extra_attributes = PBXAttributes()); | |
| void SetProjectDirPath(const std::string& project_dir_path); | |
| void SetProjectRoot(const std::string& project_root); | |
| void AddTarget(std::unique_ptr<PBXTarget> target); | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| std::string Comment() const override; | |
| void Visit(PBXObjectVisitor& visitor) override; | |
| void Visit(PBXObjectVisitorConst& visitor) const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| PBXAttributes attributes_; | |
| std::unique_ptr<XCConfigurationList> configurations_; | |
| std::unique_ptr<PBXGroup> main_group_; | |
| std::string project_dir_path_; | |
| std::string project_root_; | |
| std::vector<std::unique_ptr<PBXTarget>> targets_; | |
| std::string name_; | |
| std::vector<std::string> configs_; | |
| PBXGroup* products_ = nullptr; | |
| PBXNativeTarget* target_for_indexing_ = nullptr; | |
| PBXProject(const PBXProject&) = delete; | |
| PBXProject& operator=(const PBXProject&) = delete; | |
| }; | |
| // PBXResourcesBuildPhase ----------------------------------------------------- | |
| class PBXResourcesBuildPhase : public PBXBuildPhase { | |
| public: | |
| PBXResourcesBuildPhase(); | |
| ~PBXResourcesBuildPhase() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| PBXResourcesBuildPhase(const PBXResourcesBuildPhase&) = delete; | |
| PBXResourcesBuildPhase& operator=(const PBXResourcesBuildPhase&) = delete; | |
| }; | |
| // PBXShellScriptBuildPhase --------------------------------------------------- | |
| class PBXShellScriptBuildPhase : public PBXBuildPhase { | |
| public: | |
| PBXShellScriptBuildPhase(const std::string& name, | |
| const std::string& shell_script); | |
| ~PBXShellScriptBuildPhase() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| std::string name_; | |
| std::string shell_script_; | |
| PBXShellScriptBuildPhase(const PBXShellScriptBuildPhase&) = delete; | |
| PBXShellScriptBuildPhase& operator=(const PBXShellScriptBuildPhase&) = delete; | |
| }; | |
| // PBXSourcesBuildPhase ------------------------------------------------------- | |
| class PBXSourcesBuildPhase : public PBXBuildPhase { | |
| public: | |
| PBXSourcesBuildPhase(); | |
| ~PBXSourcesBuildPhase() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| PBXSourcesBuildPhase(const PBXSourcesBuildPhase&) = delete; | |
| PBXSourcesBuildPhase& operator=(const PBXSourcesBuildPhase&) = delete; | |
| }; | |
| // PBXTargetDependency ----------------------------------------------------- | |
| class PBXTargetDependency : public PBXObject { | |
| public: | |
| PBXTargetDependency( | |
| const PBXTarget* target, | |
| std::unique_ptr<PBXContainerItemProxy> container_item_proxy); | |
| ~PBXTargetDependency() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Visit(PBXObjectVisitor& visitor) override; | |
| void Visit(PBXObjectVisitorConst& visitor) const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| const PBXTarget* target_ = nullptr; | |
| std::unique_ptr<PBXContainerItemProxy> container_item_proxy_; | |
| PBXTargetDependency(const PBXTargetDependency&) = delete; | |
| PBXTargetDependency& operator=(const PBXTargetDependency&) = delete; | |
| }; | |
| // XCBuildConfiguration ------------------------------------------------------- | |
| class XCBuildConfiguration : public PBXObject { | |
| public: | |
| XCBuildConfiguration(const std::string& name, | |
| const PBXAttributes& attributes); | |
| ~XCBuildConfiguration() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| PBXAttributes attributes_; | |
| std::string name_; | |
| XCBuildConfiguration(const XCBuildConfiguration&) = delete; | |
| XCBuildConfiguration& operator=(const XCBuildConfiguration&) = delete; | |
| }; | |
| // XCConfigurationList -------------------------------------------------------- | |
| class XCConfigurationList : public PBXObject { | |
| public: | |
| XCConfigurationList(const std::vector<std::string>& configs, | |
| const PBXAttributes& attributes, | |
| const PBXObject* owner_reference); | |
| ~XCConfigurationList() override; | |
| // PBXObject implementation. | |
| PBXObjectClass Class() const override; | |
| std::string Name() const override; | |
| void Visit(PBXObjectVisitor& visitor) override; | |
| void Visit(PBXObjectVisitorConst& visitor) const override; | |
| void Print(std::ostream& out, unsigned indent) const override; | |
| private: | |
| std::vector<std::unique_ptr<XCBuildConfiguration>> configurations_; | |
| const PBXObject* owner_reference_ = nullptr; | |
| XCConfigurationList(const XCConfigurationList&) = delete; | |
| XCConfigurationList& operator=(const XCConfigurationList&) = delete; | |
| }; | |
| #endif // TOOLS_GN_XCODE_OBJECT_H_ |