blob: 076e9937d282e6530203b5690e94a77f34d4a4d5 [file] [log] [blame]
// 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_