diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn
index 204d909..d377ca3 100644
--- a/tools/gn/BUILD.gn
+++ b/tools/gn/BUILD.gn
@@ -207,6 +207,10 @@
     "visual_studio_utils.h",
     "visual_studio_writer.cc",
     "visual_studio_writer.h",
+    "xcode_object.cc",
+    "xcode_object.h",
+    "xcode_writer.cc",
+    "xcode_writer.h",
     "xml_element_writer.cc",
     "xml_element_writer.h",
   ]
diff --git a/tools/gn/DEPS b/tools/gn/DEPS
new file mode 100644
index 0000000..0de07bb
--- /dev/null
+++ b/tools/gn/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+third_party/re2",
+]
diff --git a/tools/gn/bundle_data.h b/tools/gn/bundle_data.h
index d742674..9a2ea07 100644
--- a/tools/gn/bundle_data.h
+++ b/tools/gn/bundle_data.h
@@ -98,6 +98,9 @@
   SourceDir& plugins_dir() { return plugins_dir_; }
   const SourceDir& plugins_dir() const { return plugins_dir_; }
 
+  std::string& product_type() { return product_type_; }
+  const std::string& product_type() const { return product_type_; }
+
   // Recursive collection of all bundle_data that the target depends on.
   const UniqueTargets& bundle_deps() const { return bundle_deps_; }
 
@@ -112,6 +115,12 @@
   SourceDir resources_dir_;
   SourceDir executable_dir_;
   SourceDir plugins_dir_;
+
+  // This is the target type as known to Xcode. This is only used to generate
+  // the Xcode project file when using --ide=xcode.
+  std::string product_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(BundleData);
 };
 
 #endif  // TOOLS_GN_BUNDLE_DATA_H_
diff --git a/tools/gn/command_gen.cc b/tools/gn/command_gen.cc
index fee3f1a..74a5d90 100644
--- a/tools/gn/command_gen.cc
+++ b/tools/gn/command_gen.cc
@@ -20,6 +20,7 @@
 #include "tools/gn/switches.h"
 #include "tools/gn/target.h"
 #include "tools/gn/visual_studio_writer.h"
+#include "tools/gn/xcode_writer.h"
 
 namespace commands {
 
@@ -32,7 +33,11 @@
 const char kSwitchIdeValueVs[] = "vs";
 const char kSwitchIdeValueVs2013[] = "vs2013";
 const char kSwitchIdeValueVs2015[] = "vs2015";
+const char kSwitchIdeValueXcode[] = "xcode";
+const char kSwitchNinjaExtraArgs[] = "ninja-extra-args";
+const char kSwitchRootTarget[] = "root-target";
 const char kSwitchSln[] = "sln";
+const char kSwitchWorkspace[] = "workspace";
 
 // Called on worker thread to write the ninja file.
 void BackgroundDoWrite(const Target* target) {
@@ -188,6 +193,19 @@
                    "ms\n");
     }
     return res;
+  } else if (ide == kSwitchIdeValueXcode) {
+    bool res = XcodeWriter::RunAndWriteFiles(
+        command_line->GetSwitchValueASCII(kSwitchWorkspace),
+        command_line->GetSwitchValueASCII(kSwitchRootTarget),
+        command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs),
+        command_line->GetSwitchValueASCII(kSwitchFilters), build_settings,
+        builder, err);
+    if (res && !command_line->HasSwitch(switches::kQuiet)) {
+      OutputString("Generating Xcode projects took " +
+                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
+                   "ms\n");
+    }
+    return res;
   }
 
   *err = Err(Location(), "Unknown IDE: " + ide);
@@ -225,16 +243,35 @@
     "             (default Visual Studio version: 2015)\n"
     "      \"vs2013\" - Visual Studio 2013 project/solution files.\n"
     "      \"vs2015\" - Visual Studio 2015 project/solution files.\n"
-    "\n"
-    "  --sln=<file_name>\n"
-    "      Override default sln file name (\"all\"). Solution file is written\n"
-    "      to the root build directory. Only for Visual Studio.\n"
+    "      \"xcode\" - Xcode workspace/solution files.\n"
     "\n"
     "  --filters=<path_prefixes>\n"
     "      Semicolon-separated list of label patterns used to limit the set\n"
     "      of generated projects (see \"gn help label_pattern\"). Only\n"
-    "      matching targets will be included to the solution. Only for Visual\n"
-    "      Studio.\n"
+    "      matching targets will be included to the solution. Only used for\n"
+    "      Visual Studio and Xcode.\n"
+    "\n"
+    "Visual Studio Flags\n"
+    "\n"
+    "  --sln=<file_name>\n"
+    "      Override default sln file name (\"all\"). Solution file is written\n"
+    "      to the root build directory.\n"
+    "\n"
+    "Xcode Flags\n"
+    "\n"
+    "  --workspace=<file_name>\n"
+    "      Override defaut workspace file name (\"all\"). The workspace file\n"
+    "      is written to the root build directory.\n"
+    "\n"
+    "  --ninja-extra-args=<string>\n"
+    "      This string is passed without any quoting to the ninja invocation\n"
+    "      command-line. Can be used to configure ninja flags, like \"-j\" if\n"
+    "      using goma for example.\n"
+    "\n"
+    "  --root-target=<target_name>\n"
+    "      Name of the target corresponding to \"All\" target in Xcode. If\n"
+    "      unset, \"All\" invokes ninja without any target thus build all the\n"
+    "      targets.\n"
     "\n"
     "Eclipse IDE Support\n"
     "\n"
diff --git a/tools/gn/commands.cc b/tools/gn/commands.cc
index ed7a009..8682d92 100644
--- a/tools/gn/commands.cc
+++ b/tools/gn/commands.cc
@@ -5,6 +5,7 @@
 #include "tools/gn/commands.h"
 
 #include "base/command_line.h"
+#include "base/strings/string_split.h"
 #include "tools/gn/builder.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/item.h"
@@ -468,6 +469,27 @@
   }
 }
 
+bool FilterPatternsFromString(const BuildSettings* build_settings,
+                              const std::string& label_list_string,
+                              std::vector<LabelPattern>* filters,
+                              Err* err) {
+  std::vector<std::string> tokens = base::SplitString(
+      label_list_string, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+  SourceDir root_dir =
+      SourceDirForCurrentDirectory(build_settings->root_path());
+
+  filters->reserve(tokens.size());
+  for (const std::string& token : tokens) {
+    LabelPattern pattern =
+        LabelPattern::GetPattern(root_dir, Value(nullptr, token), err);
+    if (err->has_error())
+      return false;
+    filters->push_back(pattern);
+  }
+
+  return true;
+}
+
 void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets) {
   if (targets->empty())
     return;
diff --git a/tools/gn/commands.h b/tools/gn/commands.h
index 9d8af5c..fdd10fc 100644
--- a/tools/gn/commands.h
+++ b/tools/gn/commands.h
@@ -140,6 +140,12 @@
                              const std::vector<LabelPattern>& filter,
                              UniqueVector<const Target*>* output);
 
+// Builds a list of pattern from a semicolon-separated list of labels.
+bool FilterPatternsFromString(const BuildSettings* build_settings,
+                              const std::string& label_list_string,
+                              std::vector<LabelPattern>* filters,
+                              Err* err);
+
 // These are the documentation strings for the command-line flags used by
 // FilterAndPrintTargets. Commands that call that function should incorporate
 // these into their help.
diff --git a/tools/gn/create_bundle_target_generator.cc b/tools/gn/create_bundle_target_generator.cc
index 6085419..8374998 100644
--- a/tools/gn/create_bundle_target_generator.cc
+++ b/tools/gn/create_bundle_target_generator.cc
@@ -41,6 +41,14 @@
                     variables::kBundlePlugInsDir,
                     &bundle_data.plugins_dir()))
     return;
+
+  const Value* value = scope_->GetValue(variables::kProductType, true);
+  if (value) {
+    if (!value->VerifyTypeIs(Value::STRING, err_))
+      return;
+
+    bundle_data.product_type().assign(value->string_value());
+  }
 }
 
 bool CreateBundleTargetGenerator::GetBundleDir(
@@ -53,6 +61,8 @@
   if (!value->VerifyTypeIs(Value::STRING, err_))
     return false;
   std::string str = value->string_value();
+  if (!str.empty() && str[str.size() - 1] != '/')
+    str.push_back('/');
   if (!EnsureStringIsInOutputDir(GetBuildSettings()->build_dir(), str,
                                  value->origin(), err_))
     return false;
diff --git a/tools/gn/functions_target.cc b/tools/gn/functions_target.cc
index 7ec5a50..cc863ac 100644
--- a/tools/gn/functions_target.cc
+++ b/tools/gn/functions_target.cc
@@ -331,7 +331,8 @@
     "Variables\n"
     "\n"
     "  bundle_root_dir*, bundle_resources_dir*, bundle_executable_dir*,\n"
-    "  bundle_plugins_dir*, deps, data_deps, public_deps, visibility\n"
+    "  bundle_plugins_dir*, deps, data_deps, public_deps, visibility,\n"
+    "  product_type\n"
     "  * = required\n"
     "\n"
     "Example\n"
@@ -378,6 +379,7 @@
     "      }\n"
     "\n"
     "      create_bundle(\"${app_name}.app\") {\n"
+    "        product_type = \"com.apple.product-type.application\"\n"
     "        deps = [\n"
     "          \":${app_name}_bundle_executable\",\n"
     "          \":${app_name}_bundle_info_plist\",\n"
diff --git a/tools/gn/gn.gyp b/tools/gn/gn.gyp
index 79f83a7..86b5d4b 100644
--- a/tools/gn/gn.gyp
+++ b/tools/gn/gn.gyp
@@ -207,6 +207,10 @@
         'visual_studio_utils.h',
         'visual_studio_writer.cc',
         'visual_studio_writer.h',
+        'xcode_object.cc',
+        'xcode_object.h',
+        'xcode_writer.cc',
+        'xcode_writer.h',
         'xml_element_writer.cc',
         'xml_element_writer.h',
       ],
diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc
index eea5bca..a65d940 100644
--- a/tools/gn/variables.cc
+++ b/tools/gn/variables.cc
@@ -1326,6 +1326,19 @@
     "  using \"msvc\"-style precompiled headers. It will be implicitly added\n"
     "  to the sources of the target. See \"gn help precompiled_header\".\n";
 
+const char kProductType[] = "product_type";
+const char kProductType_HelpShort[] =
+    "product_type: [string] Product type for Xcode projects.";
+const char kProductType_Help[] =
+    "product_type: Product type for Xcode projects.\n"
+    "\n"
+    "  Correspond to the type of the product of a create_bundle target. Only\n"
+    "  meaningful to Xcode (used as part of the Xcode project generation).\n"
+    "\n"
+    "  When generating Xcode project files, only create_bundle target with\n"
+    "  a non-empty product_type will have a corresponding target in Xcode\n"
+    "  project.\n";
+
 const char kPublic[] = "public";
 const char kPublic_HelpShort[] =
     "public: [file list] Declare public header files for a target.";
@@ -1698,6 +1711,7 @@
     INSERT_VARIABLE(Outputs)
     INSERT_VARIABLE(PrecompiledHeader)
     INSERT_VARIABLE(PrecompiledSource)
+    INSERT_VARIABLE(ProductType)
     INSERT_VARIABLE(Public)
     INSERT_VARIABLE(PublicConfigs)
     INSERT_VARIABLE(PublicDeps)
diff --git a/tools/gn/variables.h b/tools/gn/variables.h
index 2523c1f..0aaa8e0 100644
--- a/tools/gn/variables.h
+++ b/tools/gn/variables.h
@@ -215,6 +215,10 @@
 extern const char kPrecompiledSource_HelpShort[];
 extern const char kPrecompiledSource_Help[];
 
+extern const char kProductType[];
+extern const char kProductType_HelpShort[];
+extern const char kProductType_Help[];
+
 extern const char kPublic[];
 extern const char kPublic_HelpShort[];
 extern const char kPublic_Help[];
diff --git a/tools/gn/visual_studio_writer.cc b/tools/gn/visual_studio_writer.cc
index 87dfa81..50d6878 100644
--- a/tools/gn/visual_studio_writer.cc
+++ b/tools/gn/visual_studio_writer.cc
@@ -12,7 +12,6 @@
 #include <string>
 
 #include "base/logging.h"
-#include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "tools/gn/builder.h"
@@ -237,18 +236,10 @@
   if (dir_filters.empty()) {
     targets = builder->GetAllResolvedTargets();
   } else {
-    std::vector<std::string> tokens = base::SplitString(
-        dir_filters, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-    SourceDir root_dir =
-        SourceDirForCurrentDirectory(build_settings->root_path());
-
     std::vector<LabelPattern> filters;
-    for (const std::string& token : tokens) {
-      LabelPattern pattern =
-          LabelPattern::GetPattern(root_dir, Value(nullptr, token), err);
-      if (err->has_error())
-        return false;
-      filters.push_back(pattern);
+    if (!commands::FilterPatternsFromString(build_settings, dir_filters,
+                                            &filters, err)) {
+      return false;
     }
 
     commands::FilterTargetsByPatterns(builder->GetAllResolvedTargets(), filters,
diff --git a/tools/gn/xcode_object.cc b/tools/gn/xcode_object.cc
new file mode 100644
index 0000000..bc89944
--- /dev/null
+++ b/tools/gn/xcode_object.cc
@@ -0,0 +1,858 @@
+// 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.
+
+#include "tools/gn/xcode_object.h"
+
+#include <iomanip>
+#include <sstream>
+#include <utility>
+
+#include "base/files/file_path.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/string_util.h"
+
+// Helper methods -------------------------------------------------------------
+
+namespace {
+struct IndentRules {
+  bool one_line;
+  unsigned level;
+};
+
+std::vector<std::unique_ptr<PBXObject>> EmptyPBXObjectVector() {
+  return std::vector<std::unique_ptr<PBXObject>>();
+}
+
+bool CharNeedEscaping(char c) {
+  if (base::IsAsciiAlpha(c) || base::IsAsciiDigit(c))
+    return false;
+  if (c == '$' || c == '.' || c == '/' || c == '_')
+    return false;
+  return true;
+}
+
+bool StringNeedEscaping(const std::string& string) {
+  if (string.empty())
+    return true;
+  if (string.find("___") != std::string::npos)
+    return true;
+
+  for (char c : string) {
+    if (CharNeedEscaping(c))
+      return true;
+  }
+  return false;
+}
+
+std::string EncodeString(const std::string& string) {
+  if (!StringNeedEscaping(string))
+    return string;
+
+  std::stringstream buffer;
+  buffer << '"';
+  for (char c : string) {
+    if (c <= 31) {
+      switch (c) {
+        case '\a':
+          buffer << "\\a";
+          break;
+        case '\b':
+          buffer << "\\b";
+          break;
+        case '\t':
+          buffer << "\\t";
+          break;
+        case '\n':
+        case '\r':
+          buffer << "\\n";
+          break;
+        case '\v':
+          buffer << "\\v";
+          break;
+        case '\f':
+          buffer << "\\f";
+          break;
+        default:
+          buffer << std::hex << std::setw(4) << std::left << "\\U"
+                 << static_cast<unsigned>(c);
+          break;
+      }
+    } else {
+      if (c == '"' || c == '\\')
+        buffer << '\\';
+      buffer << c;
+    }
+  }
+  buffer << '"';
+  return buffer.str();
+}
+
+const char* GetSourceType(const base::FilePath::StringType& ext) {
+  std::map<base::FilePath::StringType, const char*> extension_map = {
+      {FILE_PATH_LITERAL(".a"), "archive.ar"},
+      {FILE_PATH_LITERAL(".app"), "wrapper.application"},
+      {FILE_PATH_LITERAL(".bdic"), "file"},
+      {FILE_PATH_LITERAL(".bundle"), "wrapper.cfbundle"},
+      {FILE_PATH_LITERAL(".c"), "sourcecode.c.c"},
+      {FILE_PATH_LITERAL(".cc"), "sourcecode.cpp.cpp"},
+      {FILE_PATH_LITERAL(".cpp"), "sourcecode.cpp.cpp"},
+      {FILE_PATH_LITERAL(".css"), "text.css"},
+      {FILE_PATH_LITERAL(".cxx"), "sourcecode.cpp.cpp"},
+      {FILE_PATH_LITERAL(".dart"), "sourcecode"},
+      {FILE_PATH_LITERAL(".dylib"), "compiled.mach-o.dylib"},
+      {FILE_PATH_LITERAL(".framework"), "wrapper.framework"},
+      {FILE_PATH_LITERAL(".h"), "sourcecode.c.h"},
+      {FILE_PATH_LITERAL(".hxx"), "sourcecode.cpp.h"},
+      {FILE_PATH_LITERAL(".icns"), "image.icns"},
+      {FILE_PATH_LITERAL(".java"), "sourcecode.java"},
+      {FILE_PATH_LITERAL(".js"), "sourcecode.javascript"},
+      {FILE_PATH_LITERAL(".kext"), "wrapper.kext"},
+      {FILE_PATH_LITERAL(".m"), "sourcecode.c.objc"},
+      {FILE_PATH_LITERAL(".mm"), "sourcecode.cpp.objcpp"},
+      {FILE_PATH_LITERAL(".nib"), "wrapper.nib"},
+      {FILE_PATH_LITERAL(".o"), "compiled.mach-o.objfile"},
+      {FILE_PATH_LITERAL(".pdf"), "image.pdf"},
+      {FILE_PATH_LITERAL(".pl"), "text.script.perl"},
+      {FILE_PATH_LITERAL(".plist"), "text.plist.xml"},
+      {FILE_PATH_LITERAL(".pm"), "text.script.perl"},
+      {FILE_PATH_LITERAL(".png"), "image.png"},
+      {FILE_PATH_LITERAL(".py"), "text.script.python"},
+      {FILE_PATH_LITERAL(".r"), "sourcecode.rez"},
+      {FILE_PATH_LITERAL(".rez"), "sourcecode.rez"},
+      {FILE_PATH_LITERAL(".s"), "sourcecode.asm"},
+      {FILE_PATH_LITERAL(".storyboard"), "file.storyboard"},
+      {FILE_PATH_LITERAL(".strings"), "text.plist.strings"},
+      {FILE_PATH_LITERAL(".swift"), "sourcecode.swift"},
+      {FILE_PATH_LITERAL(".ttf"), "file"},
+      {FILE_PATH_LITERAL(".xcassets"), "folder.assetcatalog"},
+      {FILE_PATH_LITERAL(".xcconfig"), "text.xcconfig"},
+      {FILE_PATH_LITERAL(".xcdatamodel"), "wrapper.xcdatamodel"},
+      {FILE_PATH_LITERAL(".xcdatamodeld"), "wrapper.xcdatamodeld"},
+      {FILE_PATH_LITERAL(".xib"), "file.xib"},
+      {FILE_PATH_LITERAL(".y"), "sourcecode.yacc"},
+  };
+
+  const auto& iter = extension_map.find(ext);
+  if (iter != extension_map.end()) {
+    return iter->second;
+  }
+
+  return "text";
+}
+
+bool HasExplicitFileType(const base::FilePath::StringType& ext) {
+  return ext == FILE_PATH_LITERAL(".dart");
+}
+
+bool IsSourceFileForIndexing(const base::FilePath::StringType& ext) {
+  return ext == FILE_PATH_LITERAL(".c") || ext == FILE_PATH_LITERAL(".cc") ||
+         ext == FILE_PATH_LITERAL(".cpp") || ext == FILE_PATH_LITERAL(".cxx") ||
+         ext == FILE_PATH_LITERAL(".m") || ext == FILE_PATH_LITERAL(".mm");
+}
+
+void PrintValue(std::ostream& out, IndentRules rules, unsigned value) {
+  out << value;
+}
+
+void PrintValue(std::ostream& out, IndentRules rules, const char* value) {
+  out << EncodeString(value);
+}
+
+void PrintValue(std::ostream& out,
+                IndentRules rules,
+                const std::string& value) {
+  out << EncodeString(value);
+}
+
+void PrintValue(std::ostream& out, IndentRules rules, const PBXObject* value) {
+  out << value->Reference();
+}
+
+template <typename ObjectClass>
+void PrintValue(std::ostream& out,
+                IndentRules rules,
+                const std::unique_ptr<ObjectClass>& value) {
+  PrintValue(out, rules, value.get());
+}
+
+template <typename ValueType>
+void PrintValue(std::ostream& out,
+                IndentRules rules,
+                const std::vector<ValueType>& values) {
+  IndentRules sub_rule{rules.one_line, rules.level + 1};
+  out << "(" << (rules.one_line ? " " : "\n");
+  for (const auto& value : values) {
+    if (!sub_rule.one_line)
+      out << std::string(sub_rule.level, '\t');
+
+    PrintValue(out, sub_rule, value);
+    out << "," << (rules.one_line ? " " : "\n");
+  }
+
+  if (!rules.one_line && rules.level)
+    out << std::string(rules.level, '\t');
+  out << ")";
+}
+
+template <typename ValueType>
+void PrintValue(std::ostream& out,
+                IndentRules rules,
+                const std::map<std::string, ValueType>& values) {
+  IndentRules sub_rule{rules.one_line, rules.level + 1};
+  out << "{" << (rules.one_line ? " " : "\n");
+  for (const auto& pair : values) {
+    if (!sub_rule.one_line)
+      out << std::string(sub_rule.level, '\t');
+
+    out << pair.first << " = ";
+    PrintValue(out, sub_rule, pair.second);
+    out << ";" << (rules.one_line ? " " : "\n");
+  }
+
+  if (!rules.one_line && rules.level)
+    out << std::string(rules.level, '\t');
+  out << "}";
+}
+
+template <typename ValueType>
+void PrintProperty(std::ostream& out,
+                   IndentRules rules,
+                   const char* name,
+                   ValueType&& value) {
+  if (!rules.one_line && rules.level)
+    out << std::string(rules.level, '\t');
+
+  out << name << " = ";
+  PrintValue(out, rules, std::forward<ValueType>(value));
+  out << ";" << (rules.one_line ? " " : "\n");
+}
+}  // namespace
+
+// PBXObjectClass -------------------------------------------------------------
+
+const char* ToString(PBXObjectClass cls) {
+  switch (cls) {
+    case PBXAggregateTargetClass:
+      return "PBXAggregateTarget";
+    case PBXBuildFileClass:
+      return "PBXBuildFile";
+    case PBXFileReferenceClass:
+      return "PBXFileReference";
+    case PBXFrameworksBuildPhaseClass:
+      return "PBXFrameworksBuildPhase";
+    case PBXGroupClass:
+      return "PBXGroup";
+    case PBXNativeTargetClass:
+      return "PBXNativeTarget";
+    case PBXProjectClass:
+      return "PBXProject";
+    case PBXShellScriptBuildPhaseClass:
+      return "PBXShellScriptBuildPhase";
+    case PBXSourcesBuildPhaseClass:
+      return "PBXSourcesBuildPhase";
+    case XCBuildConfigurationClass:
+      return "XCBuildConfiguration";
+    case XCConfigurationListClass:
+      return "XCConfigurationList";
+  }
+  NOTREACHED();
+  return nullptr;
+}
+
+// PBXObjectVisitor -----------------------------------------------------------
+
+PBXObjectVisitor::PBXObjectVisitor() {}
+
+PBXObjectVisitor::~PBXObjectVisitor() {}
+
+// PBXObject ------------------------------------------------------------------
+
+PBXObject::PBXObject() {}
+
+PBXObject::~PBXObject() {}
+
+void PBXObject::SetId(const std::string& id) {
+  DCHECK(id_.empty());
+  DCHECK(!id.empty());
+  id_.assign(id);
+}
+
+std::string PBXObject::Reference() const {
+  std::string comment = Comment();
+  if (comment.empty())
+    return id_;
+
+  return id_ + " /* " + comment + " */";
+}
+
+std::string PBXObject::Comment() const {
+  return Name();
+}
+
+void PBXObject::Visit(PBXObjectVisitor& visitor) {
+  visitor.Visit(this);
+}
+
+// PBXBuildPhase --------------------------------------------------------------
+
+PBXBuildPhase::PBXBuildPhase() {}
+
+PBXBuildPhase::~PBXBuildPhase() {}
+
+// PBXTarget ------------------------------------------------------------------
+
+PBXTarget::PBXTarget(const std::string& name,
+                     const std::string& shell_script,
+                     const std::string& config_name,
+                     const PBXAttributes& attributes)
+    : configurations_(new XCConfigurationList(config_name, attributes, this)),
+      name_(name) {
+  if (!shell_script.empty()) {
+    build_phases_.push_back(
+        base::WrapUnique(new PBXShellScriptBuildPhase(name, shell_script)));
+  }
+}
+
+PBXTarget::~PBXTarget() {}
+
+std::string PBXTarget::Name() const {
+  return name_;
+}
+
+void PBXTarget::Visit(PBXObjectVisitor& visitor) {
+  PBXObject::Visit(visitor);
+  configurations_->Visit(visitor);
+  for (const auto& build_phase : build_phases_) {
+    build_phase->Visit(visitor);
+  }
+}
+
+// PBXAggregateTarget ---------------------------------------------------------
+
+PBXAggregateTarget::PBXAggregateTarget(const std::string& name,
+                                       const std::string& shell_script,
+                                       const std::string& config_name,
+                                       const PBXAttributes& attributes)
+    : PBXTarget(name, shell_script, config_name, attributes) {}
+
+PBXAggregateTarget::~PBXAggregateTarget() {}
+
+PBXObjectClass PBXAggregateTarget::Class() const {
+  return PBXAggregateTargetClass;
+}
+
+void PBXAggregateTarget::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "buildConfigurationList", configurations_);
+  PrintProperty(out, rules, "buildPhases", build_phases_);
+  PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector());
+  PrintProperty(out, rules, "name", name_);
+  PrintProperty(out, rules, "productName", name_);
+  out << indent_str << "};\n";
+}
+
+// PBXBuildFile ---------------------------------------------------------------
+
+PBXBuildFile::PBXBuildFile(const PBXFileReference* file_reference,
+                           const PBXSourcesBuildPhase* build_phase)
+    : file_reference_(file_reference), build_phase_(build_phase) {
+  DCHECK(file_reference_);
+  DCHECK(build_phase_);
+}
+
+PBXBuildFile::~PBXBuildFile() {}
+
+PBXObjectClass PBXBuildFile::Class() const {
+  return PBXBuildFileClass;
+}
+
+std::string PBXBuildFile::Name() const {
+  return file_reference_->Name() + " in " + build_phase_->Name();
+}
+
+void PBXBuildFile::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {true, 0};
+  out << indent_str << Reference() << " = {";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "fileRef", file_reference_);
+  out << "};\n";
+}
+
+// PBXFileReference -----------------------------------------------------------
+
+PBXFileReference::PBXFileReference(const std::string& name,
+                                   const std::string& path,
+                                   const std::string& type)
+    : name_(name), path_(path), type_(type) {}
+
+PBXFileReference::~PBXFileReference() {}
+
+PBXObjectClass PBXFileReference::Class() const {
+  return PBXFileReferenceClass;
+}
+
+std::string PBXFileReference::Name() const {
+  return path_;
+}
+
+void PBXFileReference::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {true, 0};
+  out << indent_str << Reference() << " = {";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+
+  if (!type_.empty()) {
+    PrintProperty(out, rules, "explicitFileType", type_);
+    PrintProperty(out, rules, "includeInIndex", 0u);
+  } else {
+    const base::FilePath::StringType ext =
+        base::FilePath::FromUTF8Unsafe(path_).Extension();
+
+    if (HasExplicitFileType(ext))
+      PrintProperty(out, rules, "explicitFileType", GetSourceType(ext));
+    else
+      PrintProperty(out, rules, "lastKnownFileType", GetSourceType(ext));
+  }
+
+  if (name_ != path_ && !name_.empty())
+    PrintProperty(out, rules, "name", name_);
+
+  PrintProperty(out, rules, "path", path_);
+  PrintProperty(out, rules, "sourceTree",
+                type_.empty() ? "<group>" : "BUILT_PRODUCTS_DIR");
+  out << "};\n";
+}
+
+// PBXFrameworksBuildPhase ----------------------------------------------------
+
+PBXFrameworksBuildPhase::PBXFrameworksBuildPhase() {}
+
+PBXFrameworksBuildPhase::~PBXFrameworksBuildPhase() {}
+
+PBXObjectClass PBXFrameworksBuildPhase::Class() const {
+  return PBXFrameworksBuildPhaseClass;
+}
+
+std::string PBXFrameworksBuildPhase::Name() const {
+  return "Frameworks";
+}
+
+void PBXFrameworksBuildPhase::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "buildActionMask", 0x7fffffffu);
+  PrintProperty(out, rules, "files", EmptyPBXObjectVector());
+  PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u);
+  out << indent_str << "};\n";
+}
+
+// PBXGroup -------------------------------------------------------------------
+
+PBXGroup::PBXGroup(const std::string& path, const std::string& name)
+    : name_(name), path_(path) {}
+
+PBXGroup::~PBXGroup() {}
+
+PBXObject* PBXGroup::AddChild(std::unique_ptr<PBXObject> child) {
+  DCHECK(child);
+  children_.push_back(std::move(child));
+  return children_.back().get();
+}
+
+PBXFileReference* PBXGroup::AddSourceFile(const std::string& source_path) {
+  DCHECK(!source_path.empty());
+  std::string::size_type sep = source_path.find("/");
+  if (sep == std::string::npos) {
+    children_.push_back(base::WrapUnique(
+        new PBXFileReference(std::string(), source_path, std::string())));
+    return static_cast<PBXFileReference*>(children_.back().get());
+  }
+
+  PBXGroup* group = nullptr;
+  base::StringPiece component(source_path.data(), sep);
+  for (const auto& child : children_) {
+    if (child->Class() != PBXGroupClass)
+      continue;
+
+    PBXGroup* child_as_group = static_cast<PBXGroup*>(child.get());
+    if (child_as_group->path_ == component) {
+      group = child_as_group;
+      break;
+    }
+  }
+
+  if (!group) {
+    children_.push_back(base::WrapUnique(new PBXGroup(component.as_string())));
+    group = static_cast<PBXGroup*>(children_.back().get());
+  }
+
+  DCHECK(group);
+  DCHECK(group->path_ == component);
+  return group->AddSourceFile(source_path.substr(sep + 1));
+}
+
+PBXObjectClass PBXGroup::Class() const {
+  return PBXGroupClass;
+}
+
+std::string PBXGroup::Name() const {
+  if (!name_.empty())
+    return name_;
+  if (!path_.empty())
+    return path_;
+  return std::string();
+}
+
+void PBXGroup::Visit(PBXObjectVisitor& visitor) {
+  PBXObject::Visit(visitor);
+  for (const auto& child : children_) {
+    child->Visit(visitor);
+  }
+}
+
+void PBXGroup::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "children", children_);
+  if (!name_.empty())
+    PrintProperty(out, rules, "name", name_);
+  if (!path_.empty())
+    PrintProperty(out, rules, "path", path_);
+  PrintProperty(out, rules, "sourceTree", "<group>");
+  out << indent_str << "};\n";
+}
+
+// PBXNativeTarget ------------------------------------------------------------
+
+PBXNativeTarget::PBXNativeTarget(const std::string& name,
+                                 const std::string& shell_script,
+                                 const std::string& config_name,
+                                 const PBXAttributes& attributes,
+                                 const std::string& product_type,
+                                 const PBXFileReference* product_reference)
+    : PBXTarget(name, shell_script, config_name, attributes),
+      product_reference_(product_reference),
+      product_type_(product_type) {
+  DCHECK(product_reference_);
+  build_phases_.push_back(base::WrapUnique(new PBXSourcesBuildPhase));
+  source_build_phase_ =
+      static_cast<PBXSourcesBuildPhase*>(build_phases_.back().get());
+
+  build_phases_.push_back(base::WrapUnique(new PBXFrameworksBuildPhase));
+}
+
+PBXNativeTarget::~PBXNativeTarget() {}
+
+void PBXNativeTarget::AddFileForIndexing(
+    const PBXFileReference* file_reference) {
+  DCHECK(file_reference);
+  source_build_phase_->AddBuildFile(
+      base::WrapUnique(new PBXBuildFile(file_reference, source_build_phase_)));
+}
+
+PBXObjectClass PBXNativeTarget::Class() const {
+  return PBXNativeTargetClass;
+}
+
+void PBXNativeTarget::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "buildConfigurationList", configurations_);
+  PrintProperty(out, rules, "buildPhases", build_phases_);
+  PrintProperty(out, rules, "buildRules", EmptyPBXObjectVector());
+  PrintProperty(out, rules, "dependencies", EmptyPBXObjectVector());
+  PrintProperty(out, rules, "name", name_);
+  PrintProperty(out, rules, "productName", name_);
+  PrintProperty(out, rules, "productReference", product_reference_);
+  PrintProperty(out, rules, "productType", product_type_);
+  out << indent_str << "};\n";
+}
+
+// PBXProject -----------------------------------------------------------------
+
+PBXProject::PBXProject(const std::string& name,
+                       const std::string& config_name,
+                       const std::string& source_path,
+                       const PBXAttributes& attributes)
+    : name_(name), config_name_(config_name), target_for_indexing_(nullptr) {
+  attributes_["BuildIndependentTargetsInParallel"] = "YES";
+
+  main_group_.reset(new PBXGroup);
+  sources_ = static_cast<PBXGroup*>(main_group_->AddChild(
+      base::WrapUnique(new PBXGroup(source_path, "Source"))));
+  products_ = static_cast<PBXGroup*>(main_group_->AddChild(
+      base::WrapUnique(new PBXGroup(std::string(), "Product"))));
+  main_group_->AddChild(base::WrapUnique(new PBXGroup(std::string(), "Build")));
+
+  configurations_.reset(new XCConfigurationList(config_name, attributes, this));
+}
+
+PBXProject::~PBXProject() {}
+
+void PBXProject::AddSourceFile(const std::string& source_path) {
+  PBXFileReference* file_reference = sources_->AddSourceFile(source_path);
+  const base::FilePath::StringType ext =
+      base::FilePath::FromUTF8Unsafe(source_path).Extension();
+  if (!IsSourceFileForIndexing(ext))
+    return;
+
+  if (!target_for_indexing_) {
+    PBXAttributes attributes;
+    attributes["EXECUTABLE_PREFIX"] = "";
+    attributes["HEADER_SEARCH_PATHS"] = sources_->path();
+    attributes["PRODUCT_NAME"] = name_;
+
+    PBXFileReference* product_reference = static_cast<PBXFileReference*>(
+        products_->AddChild(base::WrapUnique(new PBXFileReference(
+            std::string(), name_, "compiled.mach-o.executable"))));
+
+    const char product_type[] = "com.apple.product-type.tool";
+    targets_.push_back(base::WrapUnique(
+        new PBXNativeTarget(name_, std::string(), config_name_, attributes,
+                            product_type, product_reference)));
+    target_for_indexing_ = static_cast<PBXNativeTarget*>(targets_.back().get());
+  }
+
+  DCHECK(target_for_indexing_);
+  target_for_indexing_->AddFileForIndexing(file_reference);
+}
+
+void PBXProject::AddAggregateTarget(const std::string& name,
+                                    const std::string& shell_script) {
+  PBXAttributes attributes;
+  attributes["CODE_SIGNING_REQUIRED"] = "NO";
+  attributes["CONFIGURATION_BUILD_DIR"] = ".";
+  attributes["PRODUCT_NAME"] = name;
+
+  targets_.push_back(base::WrapUnique(
+      new PBXAggregateTarget(name, shell_script, config_name_, attributes)));
+}
+
+void PBXProject::AddNativeTarget(const std::string& name,
+                                 const std::string& type,
+                                 const std::string& output_name,
+                                 const std::string& output_type,
+                                 const std::string& shell_script) {
+  const base::FilePath::StringType ext =
+      base::FilePath::FromUTF8Unsafe(output_name).Extension();
+
+  PBXFileReference* product = static_cast<PBXFileReference*>(
+      products_->AddChild(base::WrapUnique(new PBXFileReference(
+          name, output_name, type.empty() ? GetSourceType(ext) : type))));
+
+  PBXAttributes attributes;
+  attributes["CODE_SIGNING_REQUIRED"] = "NO";
+  attributes["CONFIGURATION_BUILD_DIR"] = ".";
+  attributes["PRODUCT_NAME"] = name;
+
+  targets_.push_back(base::WrapUnique(new PBXNativeTarget(
+      name, shell_script, config_name_, attributes, output_type, product)));
+}
+
+void PBXProject::SetProjectDirPath(const std::string& project_dir_path) {
+  DCHECK(!project_dir_path.empty());
+  project_dir_path_.assign(project_dir_path);
+}
+
+void PBXProject::SetProjectRoot(const std::string& project_root) {
+  DCHECK(!project_root.empty());
+  project_root_.assign(project_root);
+}
+
+void PBXProject::AddTarget(std::unique_ptr<PBXTarget> target) {
+  DCHECK(target);
+  targets_.push_back(std::move(target));
+}
+
+PBXObjectClass PBXProject::Class() const {
+  return PBXProjectClass;
+}
+
+std::string PBXProject::Name() const {
+  return name_;
+}
+
+std::string PBXProject::Comment() const {
+  return "Project object";
+}
+
+void PBXProject::Visit(PBXObjectVisitor& visitor) {
+  PBXObject::Visit(visitor);
+  configurations_->Visit(visitor);
+  main_group_->Visit(visitor);
+  for (const auto& target : targets_) {
+    target->Visit(visitor);
+  }
+}
+
+void PBXProject::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "attributes", attributes_);
+  PrintProperty(out, rules, "buildConfigurationList", configurations_);
+  PrintProperty(out, rules, "compatibilityVersion", "Xcode 3.2");
+  PrintProperty(out, rules, "developmentRegion", "English");
+  PrintProperty(out, rules, "hasScannedForEncodings", 1u);
+  PrintProperty(out, rules, "knownRegions", std::vector<std::string>({"en"}));
+  PrintProperty(out, rules, "mainGroup", main_group_);
+  PrintProperty(out, rules, "projectDirPath", project_dir_path_);
+  PrintProperty(out, rules, "projectRoot", project_root_);
+  PrintProperty(out, rules, "targets", targets_);
+  out << indent_str << "};\n";
+}
+
+// PBXShellScriptBuildPhase ---------------------------------------------------
+
+PBXShellScriptBuildPhase::PBXShellScriptBuildPhase(
+    const std::string& name,
+    const std::string& shell_script)
+    : name_("Action \"Compile and copy " + name + " via ninja\""),
+      shell_script_(shell_script) {}
+
+PBXShellScriptBuildPhase::~PBXShellScriptBuildPhase() {}
+
+PBXObjectClass PBXShellScriptBuildPhase::Class() const {
+  return PBXShellScriptBuildPhaseClass;
+}
+
+std::string PBXShellScriptBuildPhase::Name() const {
+  return name_;
+}
+
+void PBXShellScriptBuildPhase::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "buildActionMask", 0x7fffffffu);
+  PrintProperty(out, rules, "files", EmptyPBXObjectVector());
+  PrintProperty(out, rules, "inputPaths", EmptyPBXObjectVector());
+  PrintProperty(out, rules, "name", name_);
+  PrintProperty(out, rules, "outputPaths", EmptyPBXObjectVector());
+  PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u);
+  PrintProperty(out, rules, "shellPath", "/bin/sh");
+  PrintProperty(out, rules, "shellScript", shell_script_);
+  PrintProperty(out, rules, "showEnvVarsInLog", 0u);
+  out << indent_str << "};\n";
+}
+
+// PBXSourcesBuildPhase -------------------------------------------------------
+
+PBXSourcesBuildPhase::PBXSourcesBuildPhase() {}
+
+PBXSourcesBuildPhase::~PBXSourcesBuildPhase() {}
+
+void PBXSourcesBuildPhase::AddBuildFile(
+    std::unique_ptr<PBXBuildFile> build_file) {
+  files_.push_back(std::move(build_file));
+}
+
+PBXObjectClass PBXSourcesBuildPhase::Class() const {
+  return PBXSourcesBuildPhaseClass;
+}
+
+std::string PBXSourcesBuildPhase::Name() const {
+  return "Sources";
+}
+
+void PBXSourcesBuildPhase::Visit(PBXObjectVisitor& visitor) {
+  PBXBuildPhase::Visit(visitor);
+  for (const auto& file : files_) {
+    file->Visit(visitor);
+  }
+}
+
+void PBXSourcesBuildPhase::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "buildActionMask", 0x7fffffffu);
+  PrintProperty(out, rules, "files", files_);
+  PrintProperty(out, rules, "runOnlyForDeploymentPostprocessing", 0u);
+  out << indent_str << "};\n";
+}
+
+// XCBuildConfiguration -------------------------------------------------------
+
+XCBuildConfiguration::XCBuildConfiguration(const std::string& name,
+                                           const PBXAttributes& attributes)
+    : attributes_(attributes), name_(name) {}
+
+XCBuildConfiguration::~XCBuildConfiguration() {}
+
+PBXObjectClass XCBuildConfiguration::Class() const {
+  return XCBuildConfigurationClass;
+}
+
+std::string XCBuildConfiguration::Name() const {
+  return name_;
+}
+
+void XCBuildConfiguration::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "buildSettings", attributes_);
+  PrintProperty(out, rules, "name", name_);
+  out << indent_str << "};\n";
+}
+
+// XCConfigurationList --------------------------------------------------------
+
+XCConfigurationList::XCConfigurationList(const std::string& name,
+                                         const PBXAttributes& attributes,
+                                         const PBXObject* owner_reference)
+    : owner_reference_(owner_reference) {
+  DCHECK(owner_reference_);
+  configurations_.push_back(
+      base::WrapUnique(new XCBuildConfiguration(name, attributes)));
+}
+
+XCConfigurationList::~XCConfigurationList() {}
+
+PBXObjectClass XCConfigurationList::Class() const {
+  return XCConfigurationListClass;
+}
+
+std::string XCConfigurationList::Name() const {
+  std::stringstream buffer;
+  buffer << "Build configuration list for "
+         << ToString(owner_reference_->Class()) << " \""
+         << owner_reference_->Name() << "\"";
+  return buffer.str();
+}
+
+void XCConfigurationList::Visit(PBXObjectVisitor& visitor) {
+  PBXObject::Visit(visitor);
+  for (const auto& configuration : configurations_) {
+    configuration->Visit(visitor);
+  }
+}
+
+void XCConfigurationList::Print(std::ostream& out, unsigned indent) const {
+  const std::string indent_str(indent, '\t');
+  const IndentRules rules = {false, indent + 1};
+  out << indent_str << Reference() << " = {\n";
+  PrintProperty(out, rules, "isa", ToString(Class()));
+  PrintProperty(out, rules, "buildConfigurations", configurations_);
+  PrintProperty(out, rules, "defaultConfigurationIsVisible", 1u);
+  PrintProperty(out, rules, "defaultConfigurationName",
+                configurations_[0]->Name());
+  out << indent_str << "};\n";
+}
diff --git a/tools/gn/xcode_object.h b/tools/gn/xcode_object.h
new file mode 100644
index 0000000..25f2415
--- /dev/null
+++ b/tools/gn/xcode_object.h
@@ -0,0 +1,392 @@
+// 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>
+
+#include "base/macros.h"
+
+// 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,
+  PBXFileReferenceClass,
+  PBXFrameworksBuildPhaseClass,
+  PBXGroupClass,
+  PBXNativeTargetClass,
+  PBXProjectClass,
+  PBXShellScriptBuildPhaseClass,
+  PBXSourcesBuildPhaseClass,
+  XCBuildConfigurationClass,
+  XCConfigurationListClass,
+};
+
+const char* ToString(PBXObjectClass cls);
+
+// Forward-declarations -------------------------------------------------------
+
+class PBXAggregateTarget;
+class PBXBuildFile;
+class PBXFileReference;
+class PBXBuildPhase;
+class PBXFrameworksBuildPhase;
+class PBXGroup;
+class PBXNativeTarget;
+class PBXObject;
+class PBXProject;
+class PBXShellScriptBuildPhase;
+class PBXSourcesBuildPhase;
+class PBXTarget;
+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:
+  DISALLOW_COPY_AND_ASSIGN(PBXObjectVisitor);
+};
+
+// 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 Print(std::ostream& out, unsigned indent) const = 0;
+
+ private:
+  std::string id_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXObject);
+};
+
+// PBXBuildPhase --------------------------------------------------------------
+
+class PBXBuildPhase : public PBXObject {
+ public:
+  PBXBuildPhase();
+  ~PBXBuildPhase() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PBXBuildPhase);
+};
+
+// PBXTarget ------------------------------------------------------------------
+
+class PBXTarget : public PBXObject {
+ public:
+  PBXTarget(const std::string& name,
+            const std::string& shell_script,
+            const std::string& config_name,
+            const PBXAttributes& attributes);
+  ~PBXTarget() override;
+
+  // PXBObject implementation.
+  std::string Name() const override;
+  void Visit(PBXObjectVisitor& visitor) override;
+
+ protected:
+  std::unique_ptr<XCConfigurationList> configurations_;
+  std::vector<std::unique_ptr<PBXBuildPhase>> build_phases_;
+  PBXSourcesBuildPhase* source_build_phase_;
+  std::string name_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PBXTarget);
+};
+
+// PBXAggregateTarget ---------------------------------------------------------
+
+class PBXAggregateTarget : public PBXTarget {
+ public:
+  PBXAggregateTarget(const std::string& name,
+                     const std::string& shell_script,
+                     const std::string& config_name,
+                     const PBXAttributes& attributes);
+  ~PBXAggregateTarget() override;
+
+  // PXBObject implementation.
+  PBXObjectClass Class() const override;
+  void Print(std::ostream& out, unsigned indent) const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PBXAggregateTarget);
+};
+
+// PBXBuildFile ---------------------------------------------------------------
+
+class PBXBuildFile : public PBXObject {
+ public:
+  PBXBuildFile(const PBXFileReference* file_reference,
+               const PBXSourcesBuildPhase* build_phase);
+  ~PBXBuildFile() override;
+
+  // PXBObject implementation.
+  PBXObjectClass Class() const override;
+  std::string Name() const override;
+  void Print(std::ostream& out, unsigned indent) const override;
+
+ private:
+  const PBXFileReference* file_reference_;
+  const PBXSourcesBuildPhase* build_phase_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXBuildFile);
+};
+
+// 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;
+  void Print(std::ostream& out, unsigned indent) const override;
+
+ private:
+  std::string name_;
+  std::string path_;
+  std::string type_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXFileReference);
+};
+
+// 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:
+  DISALLOW_COPY_AND_ASSIGN(PBXFrameworksBuildPhase);
+};
+
+// 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_; }
+
+  PBXObject* AddChild(std::unique_ptr<PBXObject> child);
+  PBXFileReference* AddSourceFile(const std::string& source_path);
+
+  // PBXObject implementation.
+  PBXObjectClass Class() const override;
+  std::string Name() const override;
+  void Visit(PBXObjectVisitor& visitor) override;
+  void Print(std::ostream& out, unsigned indent) const override;
+
+ private:
+  std::vector<std::unique_ptr<PBXObject>> children_;
+  std::string name_;
+  std::string path_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXGroup);
+};
+
+// PBXNativeTarget ------------------------------------------------------------
+
+class PBXNativeTarget : public PBXTarget {
+ public:
+  PBXNativeTarget(const std::string& name,
+                  const std::string& shell_script,
+                  const std::string& config_name,
+                  const PBXAttributes& attributes,
+                  const std::string& product_type,
+                  const PBXFileReference* product_reference);
+  ~PBXNativeTarget() override;
+
+  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_;
+  std::string product_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXNativeTarget);
+};
+
+// PBXProject -----------------------------------------------------------------
+
+class PBXProject : public PBXObject {
+ public:
+  PBXProject(const std::string& name,
+             const std::string& config_name,
+             const std::string& source_path,
+             const PBXAttributes& attributes);
+  ~PBXProject() override;
+
+  void AddSourceFile(const std::string& source_path);
+  void AddAggregateTarget(const std::string& name,
+                          const std::string& shell_script);
+  void AddNativeTarget(const std::string& name,
+                       const std::string& type,
+                       const std::string& output_name,
+                       const std::string& output_type,
+                       const std::string& shell_script);
+
+  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 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::string config_name_;
+
+  PBXGroup* sources_;
+  PBXGroup* products_;
+  PBXNativeTarget* target_for_indexing_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXProject);
+};
+
+// 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_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXShellScriptBuildPhase);
+};
+
+// PBXSourcesBuildPhase -------------------------------------------------------
+
+class PBXSourcesBuildPhase : public PBXBuildPhase {
+ public:
+  PBXSourcesBuildPhase();
+  ~PBXSourcesBuildPhase() override;
+
+  void AddBuildFile(std::unique_ptr<PBXBuildFile> build_file);
+
+  // PBXObject implementation.
+  PBXObjectClass Class() const override;
+  std::string Name() const override;
+  void Visit(PBXObjectVisitor& visitor) override;
+  void Print(std::ostream& out, unsigned indent) const override;
+
+ private:
+  std::vector<std::unique_ptr<PBXBuildFile>> files_;
+
+  DISALLOW_COPY_AND_ASSIGN(PBXSourcesBuildPhase);
+};
+
+// 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_;
+
+  DISALLOW_COPY_AND_ASSIGN(XCBuildConfiguration);
+};
+
+// XCConfigurationList --------------------------------------------------------
+
+class XCConfigurationList : public PBXObject {
+ public:
+  XCConfigurationList(const std::string& name,
+                      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 Print(std::ostream& out, unsigned indent) const override;
+
+ private:
+  std::vector<std::unique_ptr<XCBuildConfiguration>> configurations_;
+  const PBXObject* owner_reference_;
+
+  DISALLOW_COPY_AND_ASSIGN(XCConfigurationList);
+};
+
+#endif  // TOOLS_GN_XCODE_OBJECT_H_
diff --git a/tools/gn/xcode_writer.cc b/tools/gn/xcode_writer.cc
new file mode 100644
index 0000000..4168f7f
--- /dev/null
+++ b/tools/gn/xcode_writer.cc
@@ -0,0 +1,432 @@
+// 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.
+
+#include "tools/gn/xcode_writer.h"
+
+#include <iomanip>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "base/environment.h"
+#include "base/logging.h"
+#include "base/sha1.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "tools/gn/args.h"
+#include "tools/gn/build_settings.h"
+#include "tools/gn/builder.h"
+#include "tools/gn/commands.h"
+#include "tools/gn/deps_iterator.h"
+#include "tools/gn/filesystem_utils.h"
+#include "tools/gn/settings.h"
+#include "tools/gn/source_file.h"
+#include "tools/gn/target.h"
+#include "tools/gn/value.h"
+#include "tools/gn/variables.h"
+#include "tools/gn/xcode_object.h"
+
+namespace {
+
+XcodeWriter::TargetOsType GetTargetOs(const Args& args) {
+  const Value* target_os_value = args.GetArgOverride(variables::kTargetOs);
+  if (target_os_value) {
+    if (target_os_value->type() == Value::STRING) {
+      if (target_os_value->string_value() == "ios")
+        return XcodeWriter::WRITER_TARGET_OS_IOS;
+    }
+  }
+  return XcodeWriter::WRITER_TARGET_OS_MACOS;
+}
+
+std::string GetArchs(const Args& args) {
+  const Value* target_cpu_value = args.GetArgOverride(variables::kTargetCpu);
+  if (target_cpu_value) {
+    if (target_cpu_value->type() == Value::STRING) {
+      if (target_cpu_value->string_value() == "x86")
+        return "i386";
+      if (target_cpu_value->string_value() == "x64")
+        return "x86_64";
+      if (target_cpu_value->string_value() == "arm")
+        return "armv7";
+      if (target_cpu_value->string_value() == "armv7")
+        return "armv7";
+      if (target_cpu_value->string_value() == "arm64")
+        return "armv64";
+    }
+  }
+  return "x86_64";
+}
+
+std::string GetBuildScript(const std::string& target_name,
+                           const std::string& build_path,
+                           const std::string& ninja_extra_args) {
+  std::stringstream script;
+  script << "echo note: \"Compile and copy " << target_name << " via ninja\"\n"
+         << "exec ";
+  if (!build_path.empty())
+    script << "env PATH=\"" << build_path << "\" ";
+  script << "ninja -C .";
+  if (!ninja_extra_args.empty())
+    script << " " << ninja_extra_args;
+  if (!target_name.empty())
+    script << " " << target_name;
+  script << "\nexit 1\n";
+  return script.str();
+}
+
+class CollectPBXObjectsPerClassHelper : public PBXObjectVisitor {
+ public:
+  CollectPBXObjectsPerClassHelper() {}
+
+  void Visit(PBXObject* object) override {
+    DCHECK(object);
+    objects_per_class_[object->Class()].push_back(object);
+  }
+
+  const std::map<PBXObjectClass, std::vector<const PBXObject*>>&
+  objects_per_class() const {
+    return objects_per_class_;
+  }
+
+ private:
+  std::map<PBXObjectClass, std::vector<const PBXObject*>> objects_per_class_;
+
+  DISALLOW_COPY_AND_ASSIGN(CollectPBXObjectsPerClassHelper);
+};
+
+std::map<PBXObjectClass, std::vector<const PBXObject*>>
+CollectPBXObjectsPerClass(PBXProject* project) {
+  CollectPBXObjectsPerClassHelper visitor;
+  project->Visit(visitor);
+  return visitor.objects_per_class();
+}
+
+class RecursivelyAssignIdsHelper : public PBXObjectVisitor {
+ public:
+  RecursivelyAssignIdsHelper(const std::string& seed)
+      : seed_(seed), counter_(0) {}
+
+  void Visit(PBXObject* object) override {
+    std::stringstream buffer;
+    buffer << seed_ << " " << object->Name() << " " << counter_;
+    std::string hash = base::SHA1HashString(buffer.str());
+    DCHECK_EQ(hash.size() % 4, 0u);
+
+    uint32_t id[3] = {0, 0, 0};
+    const uint32_t* ptr = reinterpret_cast<const uint32_t*>(hash.data());
+    for (size_t i = 0; i < hash.size() / 4; i++)
+      id[i % 3] ^= ptr[i];
+
+    object->SetId(base::HexEncode(id, sizeof(id)));
+    ++counter_;
+  }
+
+ private:
+  std::string seed_;
+  int64_t counter_;
+
+  DISALLOW_COPY_AND_ASSIGN(RecursivelyAssignIdsHelper);
+};
+
+void RecursivelyAssignIds(PBXProject* project) {
+  RecursivelyAssignIdsHelper visitor(project->Name());
+  project->Visit(visitor);
+}
+
+}  // namespace
+
+// static
+bool XcodeWriter::RunAndWriteFiles(const std::string& workspace_name,
+                                   const std::string& root_target_name,
+                                   const std::string& ninja_extra_args,
+                                   const std::string& dir_filters_string,
+                                   const BuildSettings* build_settings,
+                                   Builder* builder,
+                                   Err* err) {
+  const XcodeWriter::TargetOsType target_os =
+      GetTargetOs(build_settings->build_args());
+
+  PBXAttributes attributes;
+  switch (target_os) {
+    case XcodeWriter::WRITER_TARGET_OS_IOS:
+      attributes["SDKROOT"] = "iphoneos";
+      attributes["TARGETED_DEVICE_FAMILY"] = "1,2";
+      break;
+    case XcodeWriter::WRITER_TARGET_OS_MACOS:
+      attributes["ARCHS"] = GetArchs(build_settings->build_args());
+      attributes["SDKROOT"] = "macosx10.11";
+      break;
+  }
+
+  const std::string source_path =
+      base::FilePath::FromUTF8Unsafe(
+          RebasePath("//", build_settings->build_dir()))
+          .StripTrailingSeparators()
+          .AsUTF8Unsafe();
+
+  std::string config_name = build_settings->build_dir()
+                                .Resolve(base::FilePath())
+                                .StripTrailingSeparators()
+                                .BaseName()
+                                .AsUTF8Unsafe();
+  DCHECK(!config_name.empty());
+
+  std::string::size_type separator = config_name.find('-');
+  if (separator != std::string::npos)
+    config_name = config_name.substr(0, separator);
+
+  std::vector<const Target*> targets;
+  std::vector<const Target*> all_targets = builder->GetAllResolvedTargets();
+  if (!XcodeWriter::FilterTargets(build_settings, all_targets,
+                                  dir_filters_string, &targets, err)) {
+    return false;
+  }
+
+  XcodeWriter workspace(workspace_name);
+  workspace.CreateProductsProject(targets, attributes, source_path, config_name,
+                                  root_target_name, ninja_extra_args,
+                                  target_os);
+
+  workspace.CreateSourcesProject(all_targets, build_settings->build_dir(),
+                                 attributes, source_path, config_name,
+                                 target_os);
+
+  return workspace.WriteFiles(build_settings, err);
+}
+
+XcodeWriter::XcodeWriter(const std::string& name) : name_(name) {
+  if (name_.empty())
+    name_.assign("all");
+}
+
+XcodeWriter::~XcodeWriter() {}
+
+// static
+bool XcodeWriter::FilterTargets(const BuildSettings* build_settings,
+                                const std::vector<const Target*>& all_targets,
+                                const std::string& dir_filters_string,
+                                std::vector<const Target*>* targets,
+                                Err* err) {
+  // Filter targets according to the semicolon-delimited list of label patterns,
+  // if defined, first.
+  targets->reserve(all_targets.size());
+  if (dir_filters_string.empty()) {
+    *targets = all_targets;
+  } else {
+    std::vector<LabelPattern> filters;
+    if (!commands::FilterPatternsFromString(build_settings, dir_filters_string,
+                                            &filters, err)) {
+      return false;
+    }
+
+    commands::FilterTargetsByPatterns(all_targets, filters, targets);
+  }
+
+  // Filter out all target of type EXECUTABLE that are direct dependency of
+  // a BUNDLE_DATA target (under the assumption that they will be part of a
+  // CREATE_BUNDLE target generating an application bundle). Sort the list
+  // of targets per pointer to use binary search for the removal.
+  std::sort(targets->begin(), targets->end());
+
+  for (const Target* target : all_targets) {
+    if (!target->settings()->is_default())
+      continue;
+
+    if (target->output_type() != Target::BUNDLE_DATA)
+      continue;
+
+    for (const auto& pair : target->GetDeps(Target::DEPS_LINKED)) {
+      if (pair.ptr->output_type() != Target::EXECUTABLE)
+        continue;
+
+      auto iter = std::lower_bound(targets->begin(), targets->end(), pair.ptr);
+      if (iter != targets->end() && *iter == pair.ptr)
+        targets->erase(iter);
+    }
+  }
+
+  // Sort the list of targets per-label to get a consistent ordering of them
+  // in the generated Xcode project (and thus stability of the file generated).
+  std::sort(targets->begin(), targets->end(),
+            [](const Target* a, const Target* b) {
+              return a->label().name() < b->label().name();
+            });
+
+  return true;
+}
+
+void XcodeWriter::CreateProductsProject(
+    const std::vector<const Target*>& targets,
+    const PBXAttributes& attributes,
+    const std::string& source_path,
+    const std::string& config_name,
+    const std::string& root_target,
+    const std::string& ninja_extra_args,
+    TargetOsType target_os) {
+  std::unique_ptr<PBXProject> main_project(
+      new PBXProject("products", config_name, source_path, attributes));
+
+  std::string build_path;
+  std::unique_ptr<base::Environment> env(base::Environment::Create());
+  env->GetVar("PATH", &build_path);
+
+  main_project->AddAggregateTarget(
+      "All", GetBuildScript(root_target, build_path, ninja_extra_args));
+
+  for (const Target* target : targets) {
+    switch (target->output_type()) {
+      case Target::EXECUTABLE:
+        if (target_os == XcodeWriter::WRITER_TARGET_OS_IOS)
+          continue;
+
+        main_project->AddNativeTarget(
+            target->label().name(), "compiled.mach-o.executable",
+            target->output_name().empty() ? target->label().name()
+                                          : target->output_name(),
+            "com.apple.product-type.tool",
+            GetBuildScript(target->label().name(), build_path,
+                           ninja_extra_args));
+        break;
+
+      case Target::CREATE_BUNDLE:
+        if (target->bundle_data().product_type().empty())
+          continue;
+
+        main_project->AddNativeTarget(
+            target->label().name(), std::string(),
+            target->bundle_data()
+                .GetBundleRootDirOutput(target->settings())
+                .Resolve(base::FilePath())
+                .AsUTF8Unsafe(),
+            target->bundle_data().product_type(),
+            GetBuildScript(target->label().name(), build_path,
+                           ninja_extra_args));
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  projects_.push_back(std::move(main_project));
+}
+
+void XcodeWriter::CreateSourcesProject(
+    const std::vector<const Target*>& targets,
+    const SourceDir& root_build_dir,
+    const PBXAttributes& attributes,
+    const std::string& source_path,
+    const std::string& config_name,
+    TargetOsType target_os) {
+  std::vector<SourceFile> sources;
+  for (const Target* target : targets) {
+    if (!target->settings()->is_default())
+      continue;
+
+    for (const SourceFile& source : target->sources()) {
+      if (source.is_system_absolute())
+        continue;
+
+      if (IsStringInOutputDir(root_build_dir, source.value()))
+        continue;
+
+      sources.push_back(source);
+    }
+  }
+
+  std::unique_ptr<PBXProject> sources_for_indexing(
+      new PBXProject("sources", config_name, source_path, attributes));
+
+  // Sort sources to ensure determinisn of the project file generation and
+  // remove duplicate reference to the source files (can happen due to the
+  // bundle_data targets).
+  std::sort(sources.begin(), sources.end());
+  sources.erase(std::unique(sources.begin(), sources.end()), sources.end());
+
+  for (const SourceFile& source : sources) {
+    base::FilePath source_path = source.Resolve(base::FilePath());
+    sources_for_indexing->AddSourceFile(source_path.AsUTF8Unsafe());
+  }
+
+  projects_.push_back(std::move(sources_for_indexing));
+}
+
+bool XcodeWriter::WriteFiles(const BuildSettings* build_settings, Err* err) {
+  for (const auto& project : projects_) {
+    if (!WriteProjectFile(build_settings, project.get(), err))
+      return false;
+  }
+
+  SourceFile xcworkspacedata_file =
+      build_settings->build_dir().ResolveRelativeFile(
+          Value(nullptr, name_ + ".xcworkspace/contents.xcworkspacedata"), err);
+  if (xcworkspacedata_file.is_null())
+    return false;
+
+  std::stringstream xcworkspacedata_string_out;
+  WriteWorkspaceContent(xcworkspacedata_string_out);
+
+  return WriteFileIfChanged(build_settings->GetFullPath(xcworkspacedata_file),
+                            xcworkspacedata_string_out.str(), err);
+}
+
+bool XcodeWriter::WriteProjectFile(const BuildSettings* build_settings,
+                                   PBXProject* project,
+                                   Err* err) {
+  SourceFile pbxproj_file = build_settings->build_dir().ResolveRelativeFile(
+      Value(nullptr, project->Name() + ".xcodeproj/project.pbxproj"), err);
+  if (pbxproj_file.is_null())
+    return false;
+
+  std::stringstream pbxproj_string_out;
+  WriteProjectContent(pbxproj_string_out, project);
+
+  if (!WriteFileIfChanged(build_settings->GetFullPath(pbxproj_file),
+                          pbxproj_string_out.str(), err))
+    return false;
+
+  return true;
+}
+
+void XcodeWriter::WriteWorkspaceContent(std::ostream& out) {
+  out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+      << "<Workspace version = \"1.0\">\n";
+  for (const auto& project : projects_) {
+    out << "  <FileRef location = \"group:" << project->Name()
+        << ".xcodeproj\"></FileRef>\n";
+  }
+  out << "</Workspace>\n";
+}
+
+void XcodeWriter::WriteProjectContent(std::ostream& out, PBXProject* project) {
+  RecursivelyAssignIds(project);
+
+  out << "// !$*UTF8*$!\n"
+      << "{\n"
+      << "\tarchiveVersion = 1;\n"
+      << "\tclasses = {\n"
+      << "\t};\n"
+      << "\tobjectVersion = 46;\n"
+      << "\tobjects = {\n";
+
+  for (auto& pair : CollectPBXObjectsPerClass(project)) {
+    out << "\n"
+        << "/* Begin " << ToString(pair.first) << " section */\n";
+    std::sort(pair.second.begin(), pair.second.end(),
+              [](const PBXObject* a, const PBXObject* b) {
+                return a->id() < b->id();
+              });
+    for (const auto& object : pair.second) {
+      object->Print(out, 2);
+    }
+    out << "/* End " << ToString(pair.first) << " section */\n";
+  }
+
+  out << "\t};\n"
+      << "\trootObject = " << project->Reference() << ";\n"
+      << "}\n";
+}
diff --git a/tools/gn/xcode_writer.h b/tools/gn/xcode_writer.h
new file mode 100644
index 0000000..dd162c6
--- /dev/null
+++ b/tools/gn/xcode_writer.h
@@ -0,0 +1,97 @@
+// 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_WRITER_H_
+#define TOOLS_GN_XCODE_WRITER_H_
+
+#include <iosfwd>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+
+class Builder;
+class BuildSettings;
+class Err;
+class SourceDir;
+class Target;
+
+using PBXAttributes = std::map<std::string, std::string>;
+class PBXProject;
+
+class XcodeWriter {
+ public:
+  enum TargetOsType {
+    WRITER_TARGET_OS_IOS,
+    WRITER_TARGET_OS_MACOS,
+  };
+
+  // Writes Xcode workspace and project files.
+  //
+  // |workspace_name| is the optional name of the workspace file name ("all"
+  // is used if not specified). |root_target_name| is the name of the main
+  // target corresponding to building "All" (for example "gn_all" in Chromium).
+  // |ninja_extra_args| are additional arguments to pass to ninja invocation
+  // (can be used to increase limit of concurrent processes when using goma).
+  // |dir_filters_string| is optional semicolon-separated list of label patterns
+  // used to limit the set of generated projects. Only matching targets will be
+  // included to the workspace. On failure will populate |err| and return false.
+  static bool RunAndWriteFiles(const std::string& workspace_name,
+                               const std::string& root_target_name,
+                               const std::string& ninja_extra_args,
+                               const std::string& dir_filters_string,
+                               const BuildSettings* build_settings,
+                               Builder* builder,
+                               Err* err);
+
+ private:
+  XcodeWriter(const std::string& name);
+  ~XcodeWriter();
+
+  // Filters the list of targets to only return the targets with artifacts
+  // usable from Xcode (mostly application bundles). On failure populate |err|
+  // and return false.
+  static bool FilterTargets(const BuildSettings* build_settings,
+                            const std::vector<const Target*>& all_targets,
+                            const std::string& dir_filters_string,
+                            std::vector<const Target*>* targets,
+                            Err* err);
+
+  // Generate the "products.xcodeproj" project that reference all products
+  // (i.e. targets that have a build artefact usable from Xcode, mostly
+  // application bundles).
+  void CreateProductsProject(const std::vector<const Target*>& targets,
+                             const PBXAttributes& attributes,
+                             const std::string& source_path,
+                             const std::string& config_name,
+                             const std::string& root_target,
+                             const std::string& ninja_extra_args,
+                             TargetOsType target_os);
+
+  // Generates the "sources.xcodeproj" project that reference all source
+  // files to allow Xcode to index them.
+  void CreateSourcesProject(const std::vector<const Target*>& targets,
+                            const SourceDir& root_build_dir,
+                            const PBXAttributes& attributes,
+                            const std::string& source_path,
+                            const std::string& config_name,
+                            TargetOsType target_os);
+
+  bool WriteFiles(const BuildSettings* build_settings, Err* err);
+  bool WriteProjectFile(const BuildSettings* build_settings,
+                        PBXProject* project,
+                        Err* err);
+
+  void WriteWorkspaceContent(std::ostream& out);
+  void WriteProjectContent(std::ostream& out, PBXProject* project);
+
+  std::string name_;
+  std::vector<std::unique_ptr<PBXProject>> projects_;
+
+  DISALLOW_COPY_AND_ASSIGN(XcodeWriter);
+};
+
+#endif  // TOOLS_GN_XCODE_WRITER_H_
