diff --git a/build/gen.py b/build/gen.py
index 75210d7..eeb7cb5 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -491,6 +491,7 @@
         'tools/gn/ninja_binary_target_writer.cc',
         'tools/gn/ninja_build_writer.cc',
         'tools/gn/ninja_bundle_data_target_writer.cc',
+        'tools/gn/ninja_c_binary_target_writer.cc',
         'tools/gn/ninja_copy_target_writer.cc',
         'tools/gn/ninja_create_bundle_target_writer.cc',
         'tools/gn/ninja_generated_file_target_writer.cc',
@@ -591,6 +592,7 @@
         'tools/gn/metadata_walk_unittest.cc',
         'tools/gn/ninja_action_target_writer_unittest.cc',
         'tools/gn/ninja_binary_target_writer_unittest.cc',
+        'tools/gn/ninja_c_binary_target_writer_unittest.cc',
         'tools/gn/ninja_build_writer_unittest.cc',
         'tools/gn/ninja_bundle_data_target_writer_unittest.cc',
         'tools/gn/ninja_copy_target_writer_unittest.cc',
diff --git a/tools/gn/ninja_binary_target_writer.cc b/tools/gn/ninja_binary_target_writer.cc
index 9f0e949..4cda834 100644
--- a/tools/gn/ninja_binary_target_writer.cc
+++ b/tools/gn/ninja_binary_target_writer.cc
@@ -18,7 +18,7 @@
 #include "tools/gn/err.h"
 #include "tools/gn/escape.h"
 #include "tools/gn/filesystem_utils.h"
-#include "tools/gn/general_tool.h"
+#include "tools/gn/ninja_c_binary_target_writer.h"
 #include "tools/gn/ninja_target_command_util.h"
 #include "tools/gn/ninja_utils.h"
 #include "tools/gn/scheduler.h"
@@ -28,865 +28,25 @@
 #include "tools/gn/substitution_writer.h"
 #include "tools/gn/target.h"
 
-// Represents a set of tool types. Must be first since it is also shared by
-// some helper functions in the anonymous namespace below.
-class NinjaBinaryTargetWriter::SourceFileTypeSet {
- public:
-  SourceFileTypeSet() {
-    memset(flags_, 0, sizeof(bool) * static_cast<int>(SOURCE_NUMTYPES));
-  }
-
-  void Set(SourceFileType type) { flags_[static_cast<int>(type)] = true; }
-  bool Get(SourceFileType type) const { return flags_[static_cast<int>(type)]; }
-
- private:
-  bool flags_[static_cast<int>(SOURCE_NUMTYPES)];
-};
-
-namespace {
-
-// Returns the proper escape options for writing compiler and linker flags.
-EscapeOptions GetFlagOptions() {
-  EscapeOptions opts;
-  opts.mode = ESCAPE_NINJA_COMMAND;
-  return opts;
+bool NinjaBinaryTargetWriter::SourceFileTypeSet::CSourceUsed() {
+  return Get(SOURCE_CPP) || Get(SOURCE_H) || Get(SOURCE_C) || Get(SOURCE_M) ||
+         Get(SOURCE_MM) || Get(SOURCE_RC) || Get(SOURCE_S);
 }
 
-// Returns the language-specific lang recognized by gcc’s -x flag for
-// precompiled header files.
-const char* GetPCHLangForToolType(const char* name) {
-  if (name == CTool::kCToolCc)
-    return "c-header";
-  if (name == CTool::kCToolCxx)
-    return "c++-header";
-  if (name == CTool::kCToolObjC)
-    return "objective-c-header";
-  if (name == CTool::kCToolObjCxx)
-    return "objective-c++-header";
-  NOTREACHED() << "Not a valid PCH tool type: " << name;
-  return "";
-}
-
-// Appends the object files generated by the given source set to the given
-// output vector.
-void AddSourceSetObjectFiles(const Target* source_set,
-                             UniqueVector<OutputFile>* obj_files) {
-  std::vector<OutputFile> tool_outputs;  // Prevent allocation in loop.
-  NinjaBinaryTargetWriter::SourceFileTypeSet used_types;
-
-  // Compute object files for all sources. Only link the first output from
-  // the tool if there are more than one.
-  for (const auto& source : source_set->sources()) {
-    const char* tool_name = Tool::kToolNone;
-    if (source_set->GetOutputFilesForSource(source, &tool_name, &tool_outputs))
-      obj_files->push_back(tool_outputs[0]);
-
-    used_types.Set(GetSourceFileType(source));
-  }
-
-  // Add MSVC precompiled header object files. GCC .gch files are not object
-  // files so they are omitted.
-  if (source_set->config_values().has_precompiled_headers()) {
-    if (used_types.Get(SOURCE_C)) {
-      const CTool* tool = source_set->toolchain()->GetToolAsC(CTool::kCToolCc);
-      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
-        GetPCHOutputFiles(source_set, CTool::kCToolCc, &tool_outputs);
-        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
-      }
-    }
-    if (used_types.Get(SOURCE_CPP)) {
-      const CTool* tool = source_set->toolchain()->GetToolAsC(CTool::kCToolCxx);
-      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
-        GetPCHOutputFiles(source_set, CTool::kCToolCxx, &tool_outputs);
-        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
-      }
-    }
-    if (used_types.Get(SOURCE_M)) {
-      const CTool* tool =
-          source_set->toolchain()->GetToolAsC(CTool::kCToolObjC);
-      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
-        GetPCHOutputFiles(source_set, CTool::kCToolObjC, &tool_outputs);
-        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
-      }
-    }
-    if (used_types.Get(SOURCE_MM)) {
-      const CTool* tool =
-          source_set->toolchain()->GetToolAsC(CTool::kCToolObjCxx);
-      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
-        GetPCHOutputFiles(source_set, CTool::kCToolObjCxx, &tool_outputs);
-        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
-      }
-    }
-  }
-}
-
-}  // namespace
-
 NinjaBinaryTargetWriter::NinjaBinaryTargetWriter(const Target* target,
                                                  std::ostream& out)
     : NinjaTargetWriter(target, out),
-      tool_(target->toolchain()->GetToolForTargetFinalOutputAsC(target)),
       rule_prefix_(GetNinjaRulePrefixForToolchain(settings_)) {}
 
 NinjaBinaryTargetWriter::~NinjaBinaryTargetWriter() = default;
 
 void NinjaBinaryTargetWriter::Run() {
-  // Figure out what source types are needed.
   SourceFileTypeSet used_types;
   for (const auto& source : target_->sources())
     used_types.Set(GetSourceFileType(source));
 
-  WriteCompilerVars(used_types);
-
-  OutputFile input_dep = WriteInputsStampAndGetDep();
-
-  // The input dependencies will be an order-only dependency. This will cause
-  // Ninja to make sure the inputs are up to date before compiling this source,
-  // but changes in the inputs deps won't cause the file to be recompiled.
-  //
-  // This is important to prevent changes in unrelated actions that are
-  // upstream of this target from causing everything to be recompiled.
-  //
-  // Why can we get away with this rather than using implicit deps ("|", which
-  // will force rebuilds when the inputs change)? For source code, the
-  // computed dependencies of all headers will be computed by the compiler,
-  // which will cause source rebuilds if any "real" upstream dependencies
-  // change.
-  //
-  // If a .cc file is generated by an input dependency, Ninja will see the
-  // input to the build rule doesn't exist, and that it is an output from a
-  // previous step, and build the previous step first. This is a "real"
-  // dependency and doesn't need | or || to express.
-  //
-  // The only case where this rule matters is for the first build where no .d
-  // files exist, and Ninja doesn't know what that source file depends on. In
-  // this case it's sufficient to ensure that the upstream dependencies are
-  // built first. This is exactly what Ninja's order-only dependencies
-  // expresses.
-  //
-  // The order only deps are referenced by each source file compile,
-  // but also by PCH compiles.  The latter are annoying to count, so omit
-  // them here.  This means that binary targets with a single source file
-  // that also use PCH files won't have a stamp file even though having
-  // one would make output ninja file size a bit lower. That's ok, binary
-  // targets with a single source are rare.
-  size_t num_stamp_uses = target_->sources().size();
-  std::vector<OutputFile> order_only_deps = WriteInputDepsStampAndGetDep(
-      std::vector<const Target*>(), num_stamp_uses);
-
-  // For GCC builds, the .gch files are not object files, but still need to be
-  // added as explicit dependencies below. The .gch output files are placed in
-  // |pch_other_files|. This is to prevent linking against them.
-  std::vector<OutputFile> pch_obj_files;
-  std::vector<OutputFile> pch_other_files;
-  WritePCHCommands(used_types, input_dep, order_only_deps, &pch_obj_files,
-                   &pch_other_files);
-  std::vector<OutputFile>* pch_files =
-      !pch_obj_files.empty() ? &pch_obj_files : &pch_other_files;
-
-  // Treat all pch output files as explicit dependencies of all
-  // compiles that support them. Some notes:
-  //
-  //  - On Windows, the .pch file is the input to the compile, not the
-  //    precompiled header's corresponding object file that we're using here.
-  //    But Ninja's depslog doesn't support multiple outputs from the
-  //    precompiled header compile step (it outputs both the .pch file and a
-  //    corresponding .obj file). So we consistently list the .obj file and the
-  //    .pch file we really need comes along with it.
-  //
-  //  - GCC .gch files are not object files, therefore they are not added to the
-  //    object file list.
-  std::vector<OutputFile> obj_files;
-  std::vector<SourceFile> other_files;
-  WriteSources(*pch_files, input_dep, order_only_deps, &obj_files,
-               &other_files);
-
-  // Link all MSVC pch object files. The vector will be empty on GCC toolchains.
-  obj_files.insert(obj_files.end(), pch_obj_files.begin(), pch_obj_files.end());
-  if (!CheckForDuplicateObjectFiles(obj_files))
-    return;
-
-  if (target_->output_type() == Target::SOURCE_SET) {
-    WriteSourceSetStamp(obj_files);
-#ifndef NDEBUG
-    // Verify that the function that separately computes a source set's object
-    // files match the object files just computed.
-    UniqueVector<OutputFile> computed_obj;
-    AddSourceSetObjectFiles(target_, &computed_obj);
-    DCHECK_EQ(obj_files.size(), computed_obj.size());
-    for (const auto& obj : obj_files)
-      DCHECK_NE(static_cast<size_t>(-1), computed_obj.IndexOf(obj));
-#endif
-  } else {
-    WriteLinkerStuff(obj_files, other_files, input_dep);
+  if (used_types.CSourceUsed()) {
+    NinjaCBinaryTargetWriter writer(target_, out_);
+    writer.Run();
   }
 }
-
-void NinjaBinaryTargetWriter::WriteCompilerVars(
-    const SourceFileTypeSet& used_types) {
-  const SubstitutionBits& subst = target_->toolchain()->substitution_bits();
-
-  // Defines.
-  if (subst.used[SUBSTITUTION_DEFINES]) {
-    out_ << kSubstitutionNinjaNames[SUBSTITUTION_DEFINES] << " =";
-    RecursiveTargetConfigToStream<std::string>(target_, &ConfigValues::defines,
-                                               DefineWriter(), out_);
-    out_ << std::endl;
-  }
-
-  // Include directories.
-  if (subst.used[SUBSTITUTION_INCLUDE_DIRS]) {
-    out_ << kSubstitutionNinjaNames[SUBSTITUTION_INCLUDE_DIRS] << " =";
-    PathOutput include_path_output(
-        path_output_.current_dir(),
-        settings_->build_settings()->root_path_utf8(), ESCAPE_NINJA_COMMAND);
-    RecursiveTargetConfigToStream<SourceDir>(
-        target_, &ConfigValues::include_dirs,
-        IncludeWriter(include_path_output), out_);
-    out_ << std::endl;
-  }
-
-  bool has_precompiled_headers =
-      target_->config_values().has_precompiled_headers();
-
-  EscapeOptions opts = GetFlagOptions();
-  if (used_types.Get(SOURCE_S) || used_types.Get(SOURCE_ASM)) {
-    WriteOneFlag(target_, SUBSTITUTION_ASMFLAGS, false, Tool::kToolNone,
-                 &ConfigValues::asmflags, opts, path_output_, out_);
-  }
-  if (used_types.Get(SOURCE_C) || used_types.Get(SOURCE_CPP) ||
-      used_types.Get(SOURCE_M) || used_types.Get(SOURCE_MM)) {
-    WriteOneFlag(target_, SUBSTITUTION_CFLAGS, false, Tool::kToolNone,
-                 &ConfigValues::cflags, opts, path_output_, out_);
-  }
-  if (used_types.Get(SOURCE_C)) {
-    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_C, has_precompiled_headers,
-                 CTool::kCToolCc, &ConfigValues::cflags_c, opts, path_output_,
-                 out_);
-  }
-  if (used_types.Get(SOURCE_CPP)) {
-    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_CC, has_precompiled_headers,
-                 CTool::kCToolCxx, &ConfigValues::cflags_cc, opts, path_output_,
-                 out_);
-  }
-  if (used_types.Get(SOURCE_M)) {
-    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_OBJC, has_precompiled_headers,
-                 CTool::kCToolObjC, &ConfigValues::cflags_objc, opts,
-                 path_output_, out_);
-  }
-  if (used_types.Get(SOURCE_MM)) {
-    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_OBJCC, has_precompiled_headers,
-                 CTool::kCToolObjCxx, &ConfigValues::cflags_objcc, opts,
-                 path_output_, out_);
-  }
-
-  WriteSharedVars(subst);
-}
-
-OutputFile NinjaBinaryTargetWriter::WriteInputsStampAndGetDep() const {
-  CHECK(target_->toolchain()) << "Toolchain not set on target "
-                              << target_->label().GetUserVisibleName(true);
-
-  std::vector<const SourceFile*> inputs;
-  for (ConfigValuesIterator iter(target_); !iter.done(); iter.Next()) {
-    for (const auto& input : iter.cur().inputs()) {
-      inputs.push_back(&input);
-    }
-  }
-
-  if (inputs.size() == 0)
-    return OutputFile();  // No inputs
-
-  // If we only have one input, return it directly instead of writing a stamp
-  // file for it.
-  if (inputs.size() == 1)
-    return OutputFile(settings_->build_settings(), *inputs[0]);
-
-  // Make a stamp file.
-  OutputFile input_stamp_file =
-      GetBuildDirForTargetAsOutputFile(target_, BuildDirType::OBJ);
-  input_stamp_file.value().append(target_->label().name());
-  input_stamp_file.value().append(".inputs.stamp");
-
-  out_ << "build ";
-  path_output_.WriteFile(out_, input_stamp_file);
-  out_ << ": " << GetNinjaRulePrefixForToolchain(settings_)
-       << GeneralTool::kGeneralToolStamp;
-
-  // File inputs.
-  for (const auto* input : inputs) {
-    out_ << " ";
-    path_output_.WriteFile(out_, *input);
-  }
-
-  out_ << "\n";
-  return input_stamp_file;
-}
-
-void NinjaBinaryTargetWriter::WritePCHCommands(
-    const SourceFileTypeSet& used_types,
-    const OutputFile& input_dep,
-    const std::vector<OutputFile>& order_only_deps,
-    std::vector<OutputFile>* object_files,
-    std::vector<OutputFile>* other_files) {
-  if (!target_->config_values().has_precompiled_headers())
-    return;
-
-  const CTool* tool_c = target_->toolchain()->GetToolAsC(CTool::kCToolCc);
-  if (tool_c && tool_c->precompiled_header_type() != CTool::PCH_NONE &&
-      used_types.Get(SOURCE_C)) {
-    WritePCHCommand(SUBSTITUTION_CFLAGS_C, CTool::kCToolCc,
-                    tool_c->precompiled_header_type(), input_dep,
-                    order_only_deps, object_files, other_files);
-  }
-  const CTool* tool_cxx = target_->toolchain()->GetToolAsC(CTool::kCToolCxx);
-  if (tool_cxx && tool_cxx->precompiled_header_type() != CTool::PCH_NONE &&
-      used_types.Get(SOURCE_CPP)) {
-    WritePCHCommand(SUBSTITUTION_CFLAGS_CC, CTool::kCToolCxx,
-                    tool_cxx->precompiled_header_type(), input_dep,
-                    order_only_deps, object_files, other_files);
-  }
-
-  const CTool* tool_objc = target_->toolchain()->GetToolAsC(CTool::kCToolObjC);
-  if (tool_objc && tool_objc->precompiled_header_type() == CTool::PCH_GCC &&
-      used_types.Get(SOURCE_M)) {
-    WritePCHCommand(SUBSTITUTION_CFLAGS_OBJC, CTool::kCToolObjC,
-                    tool_objc->precompiled_header_type(), input_dep,
-                    order_only_deps, object_files, other_files);
-  }
-
-  const CTool* tool_objcxx =
-      target_->toolchain()->GetToolAsC(CTool::kCToolObjCxx);
-  if (tool_objcxx && tool_objcxx->precompiled_header_type() == CTool::PCH_GCC &&
-      used_types.Get(SOURCE_MM)) {
-    WritePCHCommand(SUBSTITUTION_CFLAGS_OBJCC, CTool::kCToolObjCxx,
-                    tool_objcxx->precompiled_header_type(), input_dep,
-                    order_only_deps, object_files, other_files);
-  }
-}
-
-void NinjaBinaryTargetWriter::WritePCHCommand(
-    SubstitutionType flag_type,
-    const char* tool_name,
-    CTool::PrecompiledHeaderType header_type,
-    const OutputFile& input_dep,
-    const std::vector<OutputFile>& order_only_deps,
-    std::vector<OutputFile>* object_files,
-    std::vector<OutputFile>* other_files) {
-  switch (header_type) {
-    case CTool::PCH_MSVC:
-      WriteWindowsPCHCommand(flag_type, tool_name, input_dep, order_only_deps,
-                             object_files);
-      break;
-    case CTool::PCH_GCC:
-      WriteGCCPCHCommand(flag_type, tool_name, input_dep, order_only_deps,
-                         other_files);
-      break;
-    case CTool::PCH_NONE:
-      NOTREACHED() << "Cannot write a PCH command with no PCH header type";
-      break;
-  }
-}
-
-void NinjaBinaryTargetWriter::WriteGCCPCHCommand(
-    SubstitutionType flag_type,
-    const char* tool_name,
-    const OutputFile& input_dep,
-    const std::vector<OutputFile>& order_only_deps,
-    std::vector<OutputFile>* gch_files) {
-  // Compute the pch output file (it will be language-specific).
-  std::vector<OutputFile> outputs;
-  GetPCHOutputFiles(target_, tool_name, &outputs);
-  if (outputs.empty())
-    return;
-
-  gch_files->insert(gch_files->end(), outputs.begin(), outputs.end());
-
-  std::vector<OutputFile> extra_deps;
-  if (!input_dep.value().empty())
-    extra_deps.push_back(input_dep);
-
-  // Build line to compile the file.
-  WriteCompilerBuildLine(target_->config_values().precompiled_source(),
-                         extra_deps, order_only_deps, tool_name, outputs);
-
-  // This build line needs a custom language-specific flags value. Rule-specific
-  // variables are just indented underneath the rule line.
-  out_ << "  " << kSubstitutionNinjaNames[flag_type] << " =";
-
-  // Each substitution flag is overwritten in the target rule to replace the
-  // implicitly generated -include flag with the -x <header lang> flag required
-  // for .gch targets.
-  EscapeOptions opts = GetFlagOptions();
-  if (tool_name == CTool::kCToolCc) {
-    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_c, opts,
-                                         out_);
-  } else if (tool_name == CTool::kCToolCxx) {
-    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_cc,
-                                         opts, out_);
-  } else if (tool_name == CTool::kCToolObjC) {
-    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_objc,
-                                         opts, out_);
-  } else if (tool_name == CTool::kCToolObjCxx) {
-    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_objcc,
-                                         opts, out_);
-  }
-
-  // Append the command to specify the language of the .gch file.
-  out_ << " -x " << GetPCHLangForToolType(tool_name);
-
-  // Write two blank lines to help separate the PCH build lines from the
-  // regular source build lines.
-  out_ << std::endl << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteWindowsPCHCommand(
-    SubstitutionType flag_type,
-    const char* tool_name,
-    const OutputFile& input_dep,
-    const std::vector<OutputFile>& order_only_deps,
-    std::vector<OutputFile>* object_files) {
-  // Compute the pch output file (it will be language-specific).
-  std::vector<OutputFile> outputs;
-  GetPCHOutputFiles(target_, tool_name, &outputs);
-  if (outputs.empty())
-    return;
-
-  object_files->insert(object_files->end(), outputs.begin(), outputs.end());
-
-  std::vector<OutputFile> extra_deps;
-  if (!input_dep.value().empty())
-    extra_deps.push_back(input_dep);
-
-  // Build line to compile the file.
-  WriteCompilerBuildLine(target_->config_values().precompiled_source(),
-                         extra_deps, order_only_deps, tool_name, outputs);
-
-  // This build line needs a custom language-specific flags value. Rule-specific
-  // variables are just indented underneath the rule line.
-  out_ << "  " << kSubstitutionNinjaNames[flag_type] << " =";
-
-  // Append the command to generate the .pch file.
-  // This adds the value to the existing flag instead of overwriting it.
-  out_ << " ${" << kSubstitutionNinjaNames[flag_type] << "}";
-  out_ << " /Yc" << target_->config_values().precompiled_header();
-
-  // Write two blank lines to help separate the PCH build lines from the
-  // regular source build lines.
-  out_ << std::endl << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteSources(
-    const std::vector<OutputFile>& pch_deps,
-    const OutputFile& input_dep,
-    const std::vector<OutputFile>& order_only_deps,
-    std::vector<OutputFile>* object_files,
-    std::vector<SourceFile>* other_files) {
-  object_files->reserve(object_files->size() + target_->sources().size());
-
-  std::vector<OutputFile> tool_outputs;  // Prevent reallocation in loop.
-  std::vector<OutputFile> deps;
-  for (const auto& source : target_->sources()) {
-    // Clear the vector but maintain the max capacity to prevent reallocations.
-    deps.resize(0);
-    const char* tool_name = Tool::kToolNone;
-    if (!target_->GetOutputFilesForSource(source, &tool_name, &tool_outputs)) {
-      if (GetSourceFileType(source) == SOURCE_DEF)
-        other_files->push_back(source);
-      continue;  // No output for this source.
-    }
-
-    if (!input_dep.value().empty())
-      deps.push_back(input_dep);
-
-    if (tool_name != Tool::kToolNone) {
-      // Only include PCH deps that correspond to the tool type, for instance,
-      // do not specify target_name.precompile.cc.obj (a CXX PCH file) as a dep
-      // for the output of a C tool type.
-      //
-      // This makes the assumption that pch_deps only contains pch output files
-      // with the naming scheme specified in GetWindowsPCHObjectExtension or
-      // GetGCCPCHOutputExtension.
-      const CTool* tool = target_->toolchain()->GetToolAsC(tool_name);
-      if (tool->precompiled_header_type() != CTool::PCH_NONE) {
-        for (const auto& dep : pch_deps) {
-          const std::string& output_value = dep.value();
-          size_t extension_offset = FindExtensionOffset(output_value);
-          if (extension_offset == std::string::npos)
-            continue;
-          std::string output_extension;
-          if (tool->precompiled_header_type() == CTool::PCH_MSVC) {
-            output_extension = GetWindowsPCHObjectExtension(
-                tool_name, output_value.substr(extension_offset - 1));
-          } else if (tool->precompiled_header_type() == CTool::PCH_GCC) {
-            output_extension = GetGCCPCHOutputExtension(tool_name);
-          }
-          if (output_value.compare(
-                  output_value.size() - output_extension.size(),
-                  output_extension.size(), output_extension) == 0) {
-            deps.push_back(dep);
-          }
-        }
-      }
-      WriteCompilerBuildLine(source, deps, order_only_deps, tool_name,
-                             tool_outputs);
-    }
-
-    // It's theoretically possible for a compiler to produce more than one
-    // output, but we'll only link to the first output.
-    object_files->push_back(tool_outputs[0]);
-  }
-  out_ << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteCompilerBuildLine(
-    const SourceFile& source,
-    const std::vector<OutputFile>& extra_deps,
-    const std::vector<OutputFile>& order_only_deps,
-    const char* tool_name,
-    const std::vector<OutputFile>& outputs) {
-  out_ << "build";
-  path_output_.WriteFiles(out_, outputs);
-
-  out_ << ": " << rule_prefix_ << tool_name;
-  out_ << " ";
-  path_output_.WriteFile(out_, source);
-
-  if (!extra_deps.empty()) {
-    out_ << " |";
-    path_output_.WriteFiles(out_, extra_deps);
-  }
-
-  if (!order_only_deps.empty()) {
-    out_ << " ||";
-    path_output_.WriteFiles(out_, order_only_deps);
-  }
-  out_ << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteLinkerStuff(
-    const std::vector<OutputFile>& object_files,
-    const std::vector<SourceFile>& other_files,
-    const OutputFile& input_dep) {
-  std::vector<OutputFile> output_files;
-  SubstitutionWriter::ApplyListToLinkerAsOutputFile(
-      target_, tool_, tool_->outputs(), &output_files);
-
-  out_ << "build";
-  path_output_.WriteFiles(out_, output_files);
-
-  out_ << ": " << rule_prefix_
-       << Tool::GetToolTypeForTargetFinalOutput(target_);
-
-  UniqueVector<OutputFile> extra_object_files;
-  UniqueVector<const Target*> linkable_deps;
-  UniqueVector<const Target*> non_linkable_deps;
-  GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps);
-
-  // Object files.
-  path_output_.WriteFiles(out_, object_files);
-  path_output_.WriteFiles(out_, extra_object_files);
-
-  // Dependencies.
-  std::vector<OutputFile> implicit_deps;
-  std::vector<OutputFile> solibs;
-  for (const Target* cur : linkable_deps) {
-    // All linkable deps should have a link output file.
-    DCHECK(!cur->link_output_file().value().empty())
-        << "No link output file for "
-        << target_->label().GetUserVisibleName(false);
-
-    if (cur->dependency_output_file().value() !=
-        cur->link_output_file().value()) {
-      // This is a shared library with separate link and deps files. Save for
-      // later.
-      implicit_deps.push_back(cur->dependency_output_file());
-      solibs.push_back(cur->link_output_file());
-    } else {
-      // Normal case, just link to this target.
-      out_ << " ";
-      path_output_.WriteFile(out_, cur->link_output_file());
-    }
-  }
-
-  const SourceFile* optional_def_file = nullptr;
-  if (!other_files.empty()) {
-    for (const SourceFile& src_file : other_files) {
-      if (GetSourceFileType(src_file) == SOURCE_DEF) {
-        optional_def_file = &src_file;
-        implicit_deps.push_back(
-            OutputFile(settings_->build_settings(), src_file));
-        break;  // Only one def file is allowed.
-      }
-    }
-  }
-
-  // Libraries specified by paths.
-  const OrderedSet<LibFile>& libs = target_->all_libs();
-  for (size_t i = 0; i < libs.size(); i++) {
-    if (libs[i].is_source_file()) {
-      implicit_deps.push_back(
-          OutputFile(settings_->build_settings(), libs[i].source_file()));
-    }
-  }
-
-  // The input dependency is only needed if there are no object files, as the
-  // dependency is normally provided transitively by the source files.
-  if (!input_dep.value().empty() && object_files.empty())
-    implicit_deps.push_back(input_dep);
-
-  // Append implicit dependencies collected above.
-  if (!implicit_deps.empty()) {
-    out_ << " |";
-    path_output_.WriteFiles(out_, implicit_deps);
-  }
-
-  // Append data dependencies as order-only dependencies.
-  //
-  // This will include data dependencies and input dependencies (like when
-  // this target depends on an action). Having the data dependencies in this
-  // list ensures that the data is available at runtime when the user builds
-  // this target.
-  //
-  // The action dependencies are not strictly necessary in this case. They
-  // should also have been collected via the input deps stamp that each source
-  // file has for an order-only dependency, and since this target depends on
-  // the sources, there is already an implicit order-only dependency. However,
-  // it's extra work to separate these out and there's no disadvantage to
-  // listing them again.
-  WriteOrderOnlyDependencies(non_linkable_deps);
-
-  // End of the link "build" line.
-  out_ << std::endl;
-
-  // The remaining things go in the inner scope of the link line.
-  if (target_->output_type() == Target::EXECUTABLE ||
-      target_->output_type() == Target::SHARED_LIBRARY ||
-      target_->output_type() == Target::LOADABLE_MODULE) {
-    WriteLinkerFlags(optional_def_file);
-    WriteLibs();
-  } else if (target_->output_type() == Target::STATIC_LIBRARY) {
-    out_ << "  arflags =";
-    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::arflags,
-                                         GetFlagOptions(), out_);
-    out_ << std::endl;
-  }
-  WriteOutputSubstitutions();
-  WriteSolibs(solibs);
-}
-
-void NinjaBinaryTargetWriter::WriteLinkerFlags(
-    const SourceFile* optional_def_file) {
-  out_ << "  ldflags =";
-
-  // First the ldflags from the target and its config.
-  RecursiveTargetConfigStringsToStream(target_, &ConfigValues::ldflags,
-                                       GetFlagOptions(), out_);
-
-  // Followed by library search paths that have been recursively pushed
-  // through the dependency tree.
-  const OrderedSet<SourceDir> all_lib_dirs = target_->all_lib_dirs();
-  if (!all_lib_dirs.empty()) {
-    // Since we're passing these on the command line to the linker and not
-    // to Ninja, we need to do shell escaping.
-    PathOutput lib_path_output(path_output_.current_dir(),
-                               settings_->build_settings()->root_path_utf8(),
-                               ESCAPE_NINJA_COMMAND);
-    for (size_t i = 0; i < all_lib_dirs.size(); i++) {
-      out_ << " " << tool_->lib_dir_switch();
-      lib_path_output.WriteDir(out_, all_lib_dirs[i],
-                               PathOutput::DIR_NO_LAST_SLASH);
-    }
-  }
-
-  if (optional_def_file) {
-    out_ << " /DEF:";
-    path_output_.WriteFile(out_, *optional_def_file);
-  }
-
-  out_ << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteLibs() {
-  out_ << "  libs =";
-
-  // Libraries that have been recursively pushed through the dependency tree.
-  EscapeOptions lib_escape_opts;
-  lib_escape_opts.mode = ESCAPE_NINJA_COMMAND;
-  const OrderedSet<LibFile> all_libs = target_->all_libs();
-  const std::string framework_ending(".framework");
-  for (size_t i = 0; i < all_libs.size(); i++) {
-    const LibFile& lib_file = all_libs[i];
-    const std::string& lib_value = lib_file.value();
-    if (lib_file.is_source_file()) {
-      out_ << " ";
-      path_output_.WriteFile(out_, lib_file.source_file());
-    } else if (base::EndsWith(lib_value, framework_ending,
-                              base::CompareCase::INSENSITIVE_ASCII)) {
-      // Special-case libraries ending in ".framework" to support Mac: Add the
-      // -framework switch and don't add the extension to the output.
-      out_ << " -framework ";
-      EscapeStringToStream(
-          out_, lib_value.substr(0, lib_value.size() - framework_ending.size()),
-          lib_escape_opts);
-    } else {
-      out_ << " " << tool_->lib_switch();
-      EscapeStringToStream(out_, lib_value, lib_escape_opts);
-    }
-  }
-  out_ << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteOutputSubstitutions() {
-  out_ << "  output_extension = "
-       << SubstitutionWriter::GetLinkerSubstitution(
-              target_, tool_, SUBSTITUTION_OUTPUT_EXTENSION);
-  out_ << std::endl;
-  out_ << "  output_dir = "
-       << SubstitutionWriter::GetLinkerSubstitution(target_, tool_,
-                                                    SUBSTITUTION_OUTPUT_DIR);
-  out_ << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteSolibs(
-    const std::vector<OutputFile>& solibs) {
-  if (solibs.empty())
-    return;
-
-  out_ << "  solibs =";
-  path_output_.WriteFiles(out_, solibs);
-  out_ << std::endl;
-}
-
-void NinjaBinaryTargetWriter::WriteSourceSetStamp(
-    const std::vector<OutputFile>& object_files) {
-  // The stamp rule for source sets is generally not used, since targets that
-  // depend on this will reference the object files directly. However, writing
-  // this rule allows the user to type the name of the target and get a build
-  // which can be convenient for development.
-  UniqueVector<OutputFile> extra_object_files;
-  UniqueVector<const Target*> linkable_deps;
-  UniqueVector<const Target*> non_linkable_deps;
-  GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps);
-
-  // The classifier should never put extra object files in a source set:
-  // any source sets that we depend on should appear in our non-linkable
-  // deps instead.
-  DCHECK(extra_object_files.empty());
-
-  std::vector<OutputFile> order_only_deps;
-  for (auto* dep : non_linkable_deps)
-    order_only_deps.push_back(dep->dependency_output_file());
-
-  WriteStampForTarget(object_files, order_only_deps);
-}
-
-void NinjaBinaryTargetWriter::GetDeps(
-    UniqueVector<OutputFile>* extra_object_files,
-    UniqueVector<const Target*>* linkable_deps,
-    UniqueVector<const Target*>* non_linkable_deps) const {
-  // Normal public/private deps.
-  for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) {
-    ClassifyDependency(pair.ptr, extra_object_files, linkable_deps,
-                       non_linkable_deps);
-  }
-
-  // Inherited libraries.
-  for (auto* inherited_target : target_->inherited_libraries().GetOrdered()) {
-    ClassifyDependency(inherited_target, extra_object_files, linkable_deps,
-                       non_linkable_deps);
-  }
-
-  // Data deps.
-  for (const auto& data_dep_pair : target_->data_deps())
-    non_linkable_deps->push_back(data_dep_pair.ptr);
-}
-
-void NinjaBinaryTargetWriter::ClassifyDependency(
-    const Target* dep,
-    UniqueVector<OutputFile>* extra_object_files,
-    UniqueVector<const Target*>* linkable_deps,
-    UniqueVector<const Target*>* non_linkable_deps) const {
-  // Only the following types of outputs have libraries linked into them:
-  //  EXECUTABLE
-  //  SHARED_LIBRARY
-  //  _complete_ STATIC_LIBRARY
-  //
-  // Child deps of intermediate static libraries get pushed up the
-  // dependency tree until one of these is reached, and source sets
-  // don't link at all.
-  bool can_link_libs = target_->IsFinal();
-
-  if (dep->output_type() == Target::SOURCE_SET ||
-      // If a complete static library depends on an incomplete static library,
-      // manually link in the object files of the dependent library as if it
-      // were a source set. This avoids problems with braindead tools such as
-      // ar which don't properly link dependent static libraries.
-      (target_->complete_static_lib() &&
-       dep->output_type() == Target::STATIC_LIBRARY &&
-       !dep->complete_static_lib())) {
-    // Source sets have their object files linked into final targets
-    // (shared libraries, executables, loadable modules, and complete static
-    // libraries). Intermediate static libraries and other source sets
-    // just forward the dependency, otherwise the files in the source
-    // set can easily get linked more than once which will cause
-    // multiple definition errors.
-    if (can_link_libs)
-      AddSourceSetObjectFiles(dep, extra_object_files);
-
-    // Add the source set itself as a non-linkable dependency on the current
-    // target. This will make sure that anything the source set's stamp file
-    // depends on (like data deps) are also built before the current target
-    // can be complete. Otherwise, these will be skipped since this target
-    // will depend only on the source set's object files.
-    non_linkable_deps->push_back(dep);
-  } else if (target_->complete_static_lib() && dep->IsFinal()) {
-    non_linkable_deps->push_back(dep);
-  } else if (can_link_libs && dep->IsLinkable()) {
-    linkable_deps->push_back(dep);
-  } else {
-    non_linkable_deps->push_back(dep);
-  }
-}
-
-void NinjaBinaryTargetWriter::WriteOrderOnlyDependencies(
-    const UniqueVector<const Target*>& non_linkable_deps) {
-  if (!non_linkable_deps.empty()) {
-    out_ << " ||";
-
-    // Non-linkable targets.
-    for (auto* non_linkable_dep : non_linkable_deps) {
-      out_ << " ";
-      path_output_.WriteFile(out_, non_linkable_dep->dependency_output_file());
-    }
-  }
-}
-
-bool NinjaBinaryTargetWriter::CheckForDuplicateObjectFiles(
-    const std::vector<OutputFile>& files) const {
-  std::unordered_set<std::string> set;
-  for (const auto& file : files) {
-    if (!set.insert(file.value()).second) {
-      Err err(
-          target_->defined_from(), "Duplicate object file",
-          "The target " + target_->label().GetUserVisibleName(false) +
-              "\ngenerates two object files with the same name:\n  " +
-              file.value() +
-              "\n"
-              "\n"
-              "It could be you accidentally have a file listed twice in the\n"
-              "sources. Or, depending on how your toolchain maps sources to\n"
-              "object files, two source files with the same name in different\n"
-              "directories could map to the same object file.\n"
-              "\n"
-              "In the latter case, either rename one of the files or move one "
-              "of\n"
-              "the sources to a separate source_set to avoid them both being "
-              "in\n"
-              "the same target.");
-      g_scheduler->FailWithError(err);
-      return false;
-    }
-  }
-  return true;
-}
diff --git a/tools/gn/ninja_binary_target_writer.h b/tools/gn/ninja_binary_target_writer.h
index 8a31219..d450ce2 100644
--- a/tools/gn/ninja_binary_target_writer.h
+++ b/tools/gn/ninja_binary_target_writer.h
@@ -19,119 +19,32 @@
 // library, or a static library).
 class NinjaBinaryTargetWriter : public NinjaTargetWriter {
  public:
-  class SourceFileTypeSet;
+  // Represents a set of tool types.
+  class SourceFileTypeSet {
+   public:
+    SourceFileTypeSet() {
+      memset(flags_, 0, sizeof(bool) * static_cast<int>(SOURCE_NUMTYPES));
+    }
+
+    void Set(SourceFileType type) { flags_[static_cast<int>(type)] = true; }
+    bool Get(SourceFileType type) const {
+      return flags_[static_cast<int>(type)];
+    }
+
+    bool CSourceUsed();
+
+   private:
+    bool flags_[static_cast<int>(SOURCE_NUMTYPES)];
+  };
 
   NinjaBinaryTargetWriter(const Target* target, std::ostream& out);
   ~NinjaBinaryTargetWriter() override;
 
   void Run() override;
 
- private:
+ protected:
   typedef std::set<OutputFile> OutputFileSet;
 
-  // Writes all flags for the compiler: includes, defines, cflags, etc.
-  void WriteCompilerVars(const SourceFileTypeSet& used_types);
-
-  // Writes to the output stream a stamp rule for inputs, and
-  // returns the file to be appended to source rules that encodes the
-  // implicit dependencies for the current target. The returned OutputFile
-  // will be empty if there are no inputs.
-  OutputFile WriteInputsStampAndGetDep() const;
-
-  // Writes build lines required for precompiled headers. Any generated
-  // object files will be appended to the |object_files|. Any generated
-  // non-object files (for instance, .gch files from a GCC toolchain, are
-  // appended to |other_files|).
-  //
-  // input_dep is the stamp file collecting the dependencies required before
-  // compiling this target. It will be empty if there are no input deps.
-  void WritePCHCommands(const SourceFileTypeSet& used_types,
-                        const OutputFile& input_dep,
-                        const std::vector<OutputFile>& order_only_deps,
-                        std::vector<OutputFile>* object_files,
-                        std::vector<OutputFile>* other_files);
-
-  // Writes a .pch compile build line for a language type.
-  void WritePCHCommand(SubstitutionType flag_type,
-                       const char* tool_name,
-                       CTool::PrecompiledHeaderType header_type,
-                       const OutputFile& input_dep,
-                       const std::vector<OutputFile>& order_only_deps,
-                       std::vector<OutputFile>* object_files,
-                       std::vector<OutputFile>* other_files);
-
-  void WriteGCCPCHCommand(SubstitutionType flag_type,
-                          const char* tool_name,
-                          const OutputFile& input_dep,
-                          const std::vector<OutputFile>& order_only_deps,
-                          std::vector<OutputFile>* gch_files);
-
-  void WriteWindowsPCHCommand(SubstitutionType flag_type,
-                              const char* tool_name,
-                              const OutputFile& input_dep,
-                              const std::vector<OutputFile>& order_only_deps,
-                              std::vector<OutputFile>* object_files);
-
-  // pch_deps are additional dependencies to run before the rule. They are
-  // expected to abide by the naming conventions specified by GetPCHOutputFiles.
-  //
-  // order_only_dep are the dependencies that must be run before doing any
-  // compiles.
-  //
-  // The files produced by the compiler will be added to two output vectors.
-  void WriteSources(const std::vector<OutputFile>& pch_deps,
-                    const OutputFile& input_dep,
-                    const std::vector<OutputFile>& order_only_deps,
-                    std::vector<OutputFile>* object_files,
-                    std::vector<SourceFile>* other_files);
-
-  // Writes a build line.
-  void WriteCompilerBuildLine(const SourceFile& source,
-                              const std::vector<OutputFile>& extra_deps,
-                              const std::vector<OutputFile>& order_only_deps,
-                              const char* tool_name,
-                              const std::vector<OutputFile>& outputs);
-
-  void WriteLinkerStuff(const std::vector<OutputFile>& object_files,
-                        const std::vector<SourceFile>& other_files,
-                        const OutputFile& input_dep);
-  void WriteLinkerFlags(const SourceFile* optional_def_file);
-  void WriteLibs();
-  void WriteOutputSubstitutions();
-  void WriteSolibs(const std::vector<OutputFile>& solibs);
-
-  // Writes the stamp line for a source set. These are not linked.
-  void WriteSourceSetStamp(const std::vector<OutputFile>& object_files);
-
-  // Gets all target dependencies and classifies them, as well as accumulates
-  // object files from source sets we need to link.
-  void GetDeps(UniqueVector<OutputFile>* extra_object_files,
-               UniqueVector<const Target*>* linkable_deps,
-               UniqueVector<const Target*>* non_linkable_deps) const;
-
-  // Classifies the dependency as linkable or nonlinkable with the current
-  // target, adding it to the appropriate vector. If the dependency is a source
-  // set we should link in, the source set's object files will be appended to
-  // |extra_object_files|.
-  void ClassifyDependency(const Target* dep,
-                          UniqueVector<OutputFile>* extra_object_files,
-                          UniqueVector<const Target*>* linkable_deps,
-                          UniqueVector<const Target*>* non_linkable_deps) const;
-
-  // Writes the implicit dependencies for the link or stamp line. This is
-  // the "||" and everything following it on the ninja line.
-  //
-  // The order-only dependencies are the non-linkable deps passed in as an
-  // argument, plus the data file depdencies in the target.
-  void WriteOrderOnlyDependencies(
-      const UniqueVector<const Target*>& non_linkable_deps);
-
-  // Checks for duplicates in the given list of output files. If any duplicates
-  // are found, throws an error and return false.
-  bool CheckForDuplicateObjectFiles(const std::vector<OutputFile>& files) const;
-
-  const CTool* tool_;
-
   // Cached version of the prefix used for rule types for this toolchain.
   std::string rule_prefix_;
 
diff --git a/tools/gn/ninja_binary_target_writer_unittest.cc b/tools/gn/ninja_binary_target_writer_unittest.cc
index f066536..092f637 100644
--- a/tools/gn/ninja_binary_target_writer_unittest.cc
+++ b/tools/gn/ninja_binary_target_writer_unittest.cc
@@ -4,22 +4,13 @@
 
 #include "tools/gn/ninja_binary_target_writer.h"
 
-#include <memory>
-#include <sstream>
-#include <utility>
-
-#include "tools/gn/config.h"
-#include "tools/gn/ninja_target_command_util.h"
-#include "tools/gn/scheduler.h"
-#include "tools/gn/target.h"
 #include "tools/gn/test_with_scheduler.h"
 #include "tools/gn/test_with_scope.h"
-#include "util/build_config.h"
 #include "util/test/test.h"
 
 using NinjaBinaryTargetWriterTest = TestWithScheduler;
 
-TEST_F(NinjaBinaryTargetWriterTest, SourceSet) {
+TEST_F(NinjaBinaryTargetWriterTest, CSources) {
   Err err;
   TestWithScope setup;
 
@@ -35,156 +26,6 @@
   target.SetToolchain(setup.toolchain());
   ASSERT_TRUE(target.OnResolved(&err));
 
-  // Source set itself.
-  {
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_cc =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = bar\n"
-        "\n"
-        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc\n"
-        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc\n"
-        "\n"
-        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
-        "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n";
-    std::string out_str = out.str();
-    EXPECT_EQ(expected, out_str);
-  }
-
-  // A shared library that depends on the source set.
-  Target shlib_target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
-  shlib_target.set_output_type(Target::SHARED_LIBRARY);
-  shlib_target.public_deps().push_back(LabelTargetPair(&target));
-  shlib_target.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(shlib_target.OnResolved(&err));
-
-  {
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&shlib_target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = libshlib\n"
-        "\n"
-        "\n"
-        // Ordering of the obj files here should come out in the order
-        // specified, with the target's first, followed by the source set's, in
-        // order.
-        "build ./libshlib.so: solink obj/foo/bar.input1.o "
-        "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj "
-        "|| obj/foo/bar.stamp\n"
-        "  ldflags =\n"
-        "  libs =\n"
-        "  output_extension = .so\n"
-        "  output_dir = \n";
-    std::string out_str = out.str();
-    EXPECT_EQ(expected, out_str);
-  }
-
-  // A static library that depends on the source set (should not link it).
-  Target stlib_target(setup.settings(), Label(SourceDir("//foo/"), "stlib"));
-  stlib_target.set_output_type(Target::STATIC_LIBRARY);
-  stlib_target.public_deps().push_back(LabelTargetPair(&target));
-  stlib_target.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(stlib_target.OnResolved(&err));
-
-  {
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&stlib_target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = libstlib\n"
-        "\n"
-        "\n"
-        // There are no sources so there are no params to alink. (In practice
-        // this will probably fail in the archive tool.)
-        "build obj/foo/libstlib.a: alink || obj/foo/bar.stamp\n"
-        "  arflags =\n"
-        "  output_extension = \n"
-        "  output_dir = \n";
-    std::string out_str = out.str();
-    EXPECT_EQ(expected, out_str);
-  }
-
-  // Make the static library 'complete', which means it should be linked.
-  stlib_target.set_complete_static_lib(true);
-  {
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&stlib_target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = libstlib\n"
-        "\n"
-        "\n"
-        // Ordering of the obj files here should come out in the order
-        // specified, with the target's first, followed by the source set's, in
-        // order.
-        "build obj/foo/libstlib.a: alink obj/foo/bar.input1.o "
-        "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj "
-        "|| obj/foo/bar.stamp\n"
-        "  arflags =\n"
-        "  output_extension = \n"
-        "  output_dir = \n";
-    std::string out_str = out.str();
-    EXPECT_EQ(expected, out_str);
-  }
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, EscapeDefines) {
-  TestWithScope setup;
-  Err err;
-
-  TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY);
-  target.config_values().defines().push_back("BOOL_DEF");
-  target.config_values().defines().push_back("INT_DEF=123");
-  target.config_values().defines().push_back("STR_DEF=\"ABCD-1\"");
-  ASSERT_TRUE(target.OnResolved(&err));
-
-  std::ostringstream out;
-  NinjaBinaryTargetWriter writer(&target, out);
-  writer.Run();
-
-  const char expectedSubstr[] =
-#if defined(OS_WIN)
-      "defines = -DBOOL_DEF -DINT_DEF=123 \"-DSTR_DEF=\\\"ABCD-1\\\"\"";
-#else
-      "defines = -DBOOL_DEF -DINT_DEF=123 -DSTR_DEF=\\\"ABCD-1\\\"";
-#endif
-  std::string out_str = out.str();
-  EXPECT_TRUE(out_str.find(out_str) != std::string::npos);
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, StaticLibrary) {
-  TestWithScope setup;
-  Err err;
-
-  TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY);
-  target.sources().push_back(SourceFile("//foo/input1.cc"));
-  target.config_values().arflags().push_back("--asdf");
-  ASSERT_TRUE(target.OnResolved(&err));
-
   std::ostringstream out;
   NinjaBinaryTargetWriter writer(&target, out);
   writer.Run();
@@ -196,964 +37,13 @@
       "cflags_cc =\n"
       "root_out_dir = .\n"
       "target_out_dir = obj/foo\n"
-      "target_output_name = libbar\n"
+      "target_output_name = bar\n"
       "\n"
-      "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n"
+      "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc\n"
+      "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc\n"
       "\n"
-      "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o\n"
-      "  arflags = --asdf\n"
-      "  output_extension = \n"
-      "  output_dir = \n";
+      "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
+      "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n";
   std::string out_str = out.str();
   EXPECT_EQ(expected, out_str);
 }
-
-TEST_F(NinjaBinaryTargetWriterTest, CompleteStaticLibrary) {
-  TestWithScope setup;
-  Err err;
-
-  TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY);
-  target.sources().push_back(SourceFile("//foo/input1.cc"));
-  target.config_values().arflags().push_back("--asdf");
-  target.set_complete_static_lib(true);
-
-  TestTarget baz(setup, "//foo:baz", Target::STATIC_LIBRARY);
-  baz.sources().push_back(SourceFile("//foo/input2.cc"));
-
-  target.public_deps().push_back(LabelTargetPair(&baz));
-
-  ASSERT_TRUE(target.OnResolved(&err));
-  ASSERT_TRUE(baz.OnResolved(&err));
-
-  // A complete static library that depends on an incomplete static library
-  // should link in the dependent object files as if the dependent target
-  // were a source set.
-  {
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_cc =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = libbar\n"
-        "\n"
-        "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n"
-        "\n"
-        "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o "
-        "obj/foo/libbaz.input2.o || obj/foo/libbaz.a\n"
-        "  arflags = --asdf\n"
-        "  output_extension = \n"
-        "  output_dir = \n";
-    std::string out_str = out.str();
-    EXPECT_EQ(expected, out_str);
-  }
-
-  // Make the dependent static library complete.
-  baz.set_complete_static_lib(true);
-
-  // Dependent complete static libraries should not be linked directly.
-  {
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_cc =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = libbar\n"
-        "\n"
-        "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n"
-        "\n"
-        "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o "
-        "|| obj/foo/libbaz.a\n"
-        "  arflags = --asdf\n"
-        "  output_extension = \n"
-        "  output_dir = \n";
-    std::string out_str = out.str();
-    EXPECT_EQ(expected, out_str);
-  }
-}
-
-// This tests that output extension and output dir overrides apply, and input
-// dependencies are applied.
-TEST_F(NinjaBinaryTargetWriterTest, OutputExtensionAndInputDeps) {
-  Err err;
-  TestWithScope setup;
-
-  // An action for our library to depend on.
-  Target action(setup.settings(), Label(SourceDir("//foo/"), "action"));
-  action.set_output_type(Target::ACTION_FOREACH);
-  action.visibility().SetPublic();
-  action.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(action.OnResolved(&err));
-
-  // A shared library w/ the output_extension set to a custom value.
-  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
-  target.set_output_type(Target::SHARED_LIBRARY);
-  target.set_output_extension(std::string("so.6"));
-  target.set_output_dir(SourceDir("//out/Debug/foo/"));
-  target.sources().push_back(SourceFile("//foo/input1.cc"));
-  target.sources().push_back(SourceFile("//foo/input2.cc"));
-  target.public_deps().push_back(LabelTargetPair(&action));
-  target.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(target.OnResolved(&err));
-
-  std::ostringstream out;
-  NinjaBinaryTargetWriter writer(&target, out);
-  writer.Run();
-
-  const char expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = libshlib\n"
-      "\n"
-      "build obj/foo/libshlib.input1.o: cxx ../../foo/input1.cc"
-      " || obj/foo/action.stamp\n"
-      "build obj/foo/libshlib.input2.o: cxx ../../foo/input2.cc"
-      " || obj/foo/action.stamp\n"
-      "\n"
-      "build ./libshlib.so.6: solink obj/foo/libshlib.input1.o "
-      // The order-only dependency here is stricly unnecessary since the
-      // sources list this as an order-only dep. See discussion in the code
-      // that writes this.
-      "obj/foo/libshlib.input2.o || obj/foo/action.stamp\n"
-      "  ldflags =\n"
-      "  libs =\n"
-      "  output_extension = .so.6\n"
-      "  output_dir = foo\n";
-
-  std::string out_str = out.str();
-  EXPECT_EQ(expected, out_str);
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, NoHardDepsToNoPublicHeaderTarget) {
-  Err err;
-  TestWithScope setup;
-
-  SourceFile generated_file("//out/Debug/generated.cc");
-
-  // An action does code generation.
-  Target action(setup.settings(), Label(SourceDir("//foo/"), "generate"));
-  action.set_output_type(Target::ACTION);
-  action.visibility().SetPublic();
-  action.SetToolchain(setup.toolchain());
-  action.set_output_dir(SourceDir("//out/Debug/foo/"));
-  action.action_values().outputs() =
-      SubstitutionList::MakeForTest("//out/Debug/generated.cc");
-  ASSERT_TRUE(action.OnResolved(&err));
-
-  // A source set compiling geneated code, this target does not publicize any
-  // headers.
-  Target gen_obj(setup.settings(), Label(SourceDir("//foo/"), "gen_obj"));
-  gen_obj.set_output_type(Target::SOURCE_SET);
-  gen_obj.set_output_dir(SourceDir("//out/Debug/foo/"));
-  gen_obj.sources().push_back(generated_file);
-  gen_obj.visibility().SetPublic();
-  gen_obj.private_deps().push_back(LabelTargetPair(&action));
-  gen_obj.set_all_headers_public(false);
-  gen_obj.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(gen_obj.OnResolved(&err));
-
-  std::ostringstream obj_out;
-  NinjaBinaryTargetWriter obj_writer(&gen_obj, obj_out);
-  obj_writer.Run();
-
-  const char obj_expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = gen_obj\n"
-      "\n"
-      "build obj/out/Debug/gen_obj.generated.o: cxx generated.cc"
-      " || obj/foo/generate.stamp\n"
-      "\n"
-      "build obj/foo/gen_obj.stamp: stamp obj/out/Debug/gen_obj.generated.o"
-      // The order-only dependency here is strictly unnecessary since the
-      // sources list this as an order-only dep.
-      " || obj/foo/generate.stamp\n";
-
-  std::string obj_str = obj_out.str();
-  EXPECT_EQ(obj_expected, obj_str);
-
-  // A shared library depends on gen_obj, having corresponding header for
-  // generated obj.
-  Target gen_lib(setup.settings(), Label(SourceDir("//foo/"), "gen_lib"));
-  gen_lib.set_output_type(Target::SHARED_LIBRARY);
-  gen_lib.set_output_dir(SourceDir("//out/Debug/foo/"));
-  gen_lib.sources().push_back(SourceFile("//foor/generated.h"));
-  gen_lib.visibility().SetPublic();
-  gen_lib.private_deps().push_back(LabelTargetPair(&gen_obj));
-  gen_lib.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(gen_lib.OnResolved(&err));
-
-  std::ostringstream lib_out;
-  NinjaBinaryTargetWriter lib_writer(&gen_lib, lib_out);
-  lib_writer.Run();
-
-  const char lib_expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = libgen_lib\n"
-      "\n"
-      "\n"
-      "build ./libgen_lib.so: solink obj/out/Debug/gen_obj.generated.o"
-      // The order-only dependency here is strictly unnecessary since
-      // obj/out/Debug/gen_obj.generated.o has dependency to
-      // obj/foo/gen_obj.stamp
-      " || obj/foo/gen_obj.stamp\n"
-      "  ldflags =\n"
-      "  libs =\n"
-      "  output_extension = .so\n"
-      "  output_dir = foo\n";
-
-  std::string lib_str = lib_out.str();
-  EXPECT_EQ(lib_expected, lib_str);
-
-  // An executable depends on gen_lib.
-  Target executable(setup.settings(),
-                    Label(SourceDir("//foo/"), "final_target"));
-  executable.set_output_type(Target::EXECUTABLE);
-  executable.set_output_dir(SourceDir("//out/Debug/foo/"));
-  executable.sources().push_back(SourceFile("//foo/main.cc"));
-  executable.private_deps().push_back(LabelTargetPair(&gen_lib));
-  executable.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(executable.OnResolved(&err)) << err.message();
-
-  std::ostringstream final_out;
-  NinjaBinaryTargetWriter final_writer(&executable, final_out);
-  final_writer.Run();
-
-  // There is no order only dependency to action target.
-  const char final_expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = final_target\n"
-      "\n"
-      "build obj/foo/final_target.main.o: cxx ../../foo/main.cc\n"
-      "\n"
-      "build ./final_target: link obj/foo/final_target.main.o"
-      " ./libgen_lib.so\n"
-      "  ldflags =\n"
-      "  libs =\n"
-      "  output_extension = \n"
-      "  output_dir = foo\n";
-
-  std::string final_str = final_out.str();
-  EXPECT_EQ(final_expected, final_str);
-}
-
-// Tests libs are applied.
-TEST_F(NinjaBinaryTargetWriterTest, LibsAndLibDirs) {
-  Err err;
-  TestWithScope setup;
-
-  // A shared library w/ libs and lib_dirs.
-  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
-  target.set_output_type(Target::SHARED_LIBRARY);
-  target.config_values().libs().push_back(LibFile(SourceFile("//foo/lib1.a")));
-  target.config_values().libs().push_back(LibFile("foo"));
-  target.config_values().lib_dirs().push_back(SourceDir("//foo/bar/"));
-  target.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(target.OnResolved(&err));
-
-  std::ostringstream out;
-  NinjaBinaryTargetWriter writer(&target, out);
-  writer.Run();
-
-  const char expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = libshlib\n"
-      "\n"
-      "\n"
-      "build ./libshlib.so: solink | ../../foo/lib1.a\n"
-      "  ldflags = -L../../foo/bar\n"
-      "  libs = ../../foo/lib1.a -lfoo\n"
-      "  output_extension = .so\n"
-      "  output_dir = \n";
-
-  std::string out_str = out.str();
-  EXPECT_EQ(expected, out_str);
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, EmptyOutputExtension) {
-  Err err;
-  TestWithScope setup;
-
-  // This test is the same as OutputExtensionAndInputDeps, except that we call
-  // set_output_extension("") and ensure that we get an empty one and override
-  // the output prefix so that the name matches the target exactly.
-  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
-  target.set_output_type(Target::SHARED_LIBRARY);
-  target.set_output_prefix_override(true);
-  target.set_output_extension(std::string());
-  target.sources().push_back(SourceFile("//foo/input1.cc"));
-  target.sources().push_back(SourceFile("//foo/input2.cc"));
-
-  target.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(target.OnResolved(&err));
-
-  std::ostringstream out;
-  NinjaBinaryTargetWriter writer(&target, out);
-  writer.Run();
-
-  const char expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = shlib\n"
-      "\n"
-      "build obj/foo/shlib.input1.o: cxx ../../foo/input1.cc\n"
-      "build obj/foo/shlib.input2.o: cxx ../../foo/input2.cc\n"
-      "\n"
-      "build ./shlib: solink obj/foo/shlib.input1.o "
-      "obj/foo/shlib.input2.o\n"
-      "  ldflags =\n"
-      "  libs =\n"
-      "  output_extension = \n"
-      "  output_dir = \n";
-
-  std::string out_str = out.str();
-  EXPECT_EQ(expected, out_str);
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, SourceSetDataDeps) {
-  Err err;
-  TestWithScope setup;
-
-  // This target is a data (runtime) dependency of the intermediate target.
-  Target data(setup.settings(), Label(SourceDir("//foo/"), "data_target"));
-  data.set_output_type(Target::EXECUTABLE);
-  data.visibility().SetPublic();
-  data.SetToolchain(setup.toolchain());
-  ASSERT_TRUE(data.OnResolved(&err));
-
-  // Intermediate source set target.
-  Target inter(setup.settings(), Label(SourceDir("//foo/"), "inter"));
-  inter.set_output_type(Target::SOURCE_SET);
-  inter.visibility().SetPublic();
-  inter.data_deps().push_back(LabelTargetPair(&data));
-  inter.SetToolchain(setup.toolchain());
-  inter.sources().push_back(SourceFile("//foo/inter.cc"));
-  ASSERT_TRUE(inter.OnResolved(&err)) << err.message();
-
-  // Write out the intermediate target.
-  std::ostringstream inter_out;
-  NinjaBinaryTargetWriter inter_writer(&inter, inter_out);
-  inter_writer.Run();
-
-  // The intermediate source set will be a stamp file that depends on the
-  // object files, and will have an order-only dependency on its data dep and
-  // data file.
-  const char inter_expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = inter\n"
-      "\n"
-      "build obj/foo/inter.inter.o: cxx ../../foo/inter.cc\n"
-      "\n"
-      "build obj/foo/inter.stamp: stamp obj/foo/inter.inter.o || "
-      "./data_target\n";
-  EXPECT_EQ(inter_expected, inter_out.str());
-
-  // Final target.
-  Target exe(setup.settings(), Label(SourceDir("//foo/"), "exe"));
-  exe.set_output_type(Target::EXECUTABLE);
-  exe.public_deps().push_back(LabelTargetPair(&inter));
-  exe.SetToolchain(setup.toolchain());
-  exe.sources().push_back(SourceFile("//foo/final.cc"));
-  ASSERT_TRUE(exe.OnResolved(&err));
-
-  std::ostringstream final_out;
-  NinjaBinaryTargetWriter final_writer(&exe, final_out);
-  final_writer.Run();
-
-  // The final output depends on both object files (one from the final target,
-  // one from the source set) and has an order-only dependency on the source
-  // set's stamp file and the final target's data file. The source set stamp
-  // dependency will create an implicit order-only dependency on the data
-  // target.
-  const char final_expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = exe\n"
-      "\n"
-      "build obj/foo/exe.final.o: cxx ../../foo/final.cc\n"
-      "\n"
-      "build ./exe: link obj/foo/exe.final.o obj/foo/inter.inter.o || "
-      "obj/foo/inter.stamp\n"
-      "  ldflags =\n"
-      "  libs =\n"
-      "  output_extension = \n"
-      "  output_dir = \n";
-  EXPECT_EQ(final_expected, final_out.str());
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, SharedLibraryModuleDefinitionFile) {
-  Err err;
-  TestWithScope setup;
-
-  Target shared_lib(setup.settings(), Label(SourceDir("//foo/"), "bar"));
-  shared_lib.set_output_type(Target::SHARED_LIBRARY);
-  shared_lib.SetToolchain(setup.toolchain());
-  shared_lib.sources().push_back(SourceFile("//foo/sources.cc"));
-  shared_lib.sources().push_back(SourceFile("//foo/bar.def"));
-  ASSERT_TRUE(shared_lib.OnResolved(&err));
-
-  std::ostringstream out;
-  NinjaBinaryTargetWriter writer(&shared_lib, out);
-  writer.Run();
-
-  const char expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = libbar\n"
-      "\n"
-      "build obj/foo/libbar.sources.o: cxx ../../foo/sources.cc\n"
-      "\n"
-      "build ./libbar.so: solink obj/foo/libbar.sources.o | ../../foo/bar.def\n"
-      "  ldflags = /DEF:../../foo/bar.def\n"
-      "  libs =\n"
-      "  output_extension = .so\n"
-      "  output_dir = \n";
-  EXPECT_EQ(expected, out.str());
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, LoadableModule) {
-  Err err;
-  TestWithScope setup;
-
-  Target loadable_module(setup.settings(), Label(SourceDir("//foo/"), "bar"));
-  loadable_module.set_output_type(Target::LOADABLE_MODULE);
-  loadable_module.visibility().SetPublic();
-  loadable_module.SetToolchain(setup.toolchain());
-  loadable_module.sources().push_back(SourceFile("//foo/sources.cc"));
-  ASSERT_TRUE(loadable_module.OnResolved(&err)) << err.message();
-
-  std::ostringstream out;
-  NinjaBinaryTargetWriter writer(&loadable_module, out);
-  writer.Run();
-
-  const char loadable_expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = libbar\n"
-      "\n"
-      "build obj/foo/libbar.sources.o: cxx ../../foo/sources.cc\n"
-      "\n"
-      "build ./libbar.so: solink_module obj/foo/libbar.sources.o\n"
-      "  ldflags =\n"
-      "  libs =\n"
-      "  output_extension = .so\n"
-      "  output_dir = \n";
-  EXPECT_EQ(loadable_expected, out.str());
-
-  // Final target.
-  Target exe(setup.settings(), Label(SourceDir("//foo/"), "exe"));
-  exe.set_output_type(Target::EXECUTABLE);
-  exe.public_deps().push_back(LabelTargetPair(&loadable_module));
-  exe.SetToolchain(setup.toolchain());
-  exe.sources().push_back(SourceFile("//foo/final.cc"));
-  ASSERT_TRUE(exe.OnResolved(&err)) << err.message();
-
-  std::ostringstream final_out;
-  NinjaBinaryTargetWriter final_writer(&exe, final_out);
-  final_writer.Run();
-
-  // The final output depends on the loadable module so should have an
-  // order-only dependency on the loadable modules's output file.
-  const char final_expected[] =
-      "defines =\n"
-      "include_dirs =\n"
-      "cflags =\n"
-      "cflags_cc =\n"
-      "root_out_dir = .\n"
-      "target_out_dir = obj/foo\n"
-      "target_output_name = exe\n"
-      "\n"
-      "build obj/foo/exe.final.o: cxx ../../foo/final.cc\n"
-      "\n"
-      "build ./exe: link obj/foo/exe.final.o || ./libbar.so\n"
-      "  ldflags =\n"
-      "  libs =\n"
-      "  output_extension = \n"
-      "  output_dir = \n";
-  EXPECT_EQ(final_expected, final_out.str());
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, WinPrecompiledHeaders) {
-  Err err;
-
-  // This setup's toolchain does not have precompiled headers defined.
-  TestWithScope setup;
-
-  // A precompiled header toolchain.
-  Settings pch_settings(setup.build_settings(), "withpch/");
-  Toolchain pch_toolchain(&pch_settings,
-                          Label(SourceDir("//toolchain/"), "withpch"));
-  pch_settings.set_toolchain_label(pch_toolchain.label());
-  pch_settings.set_default_toolchain_label(setup.toolchain()->label());
-
-  // Declare a C++ compiler that supports PCH.
-  std::unique_ptr<Tool> cxx = Tool::CreateTool(CTool::kCToolCxx);
-  CTool* cxx_tool = cxx->AsC();
-  TestWithScope::SetCommandForTool(
-      "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
-      "-o {{output}}",
-      cxx_tool);
-  cxx_tool->set_outputs(SubstitutionList::MakeForTest(
-      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
-  cxx_tool->set_precompiled_header_type(CTool::PCH_MSVC);
-  pch_toolchain.SetTool(std::move(cxx));
-
-  // Add a C compiler as well.
-  std::unique_ptr<Tool> cc = Tool::CreateTool(CTool::kCToolCc);
-  CTool* cc_tool = cc->AsC();
-  TestWithScope::SetCommandForTool(
-      "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
-      "-o {{output}}",
-      cc_tool);
-  cc_tool->set_outputs(SubstitutionList::MakeForTest(
-      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
-  cc_tool->set_precompiled_header_type(CTool::PCH_MSVC);
-  pch_toolchain.SetTool(std::move(cc));
-  pch_toolchain.ToolchainSetupComplete();
-
-  // This target doesn't specify precompiled headers.
-  {
-    Target no_pch_target(&pch_settings,
-                         Label(SourceDir("//foo/"), "no_pch_target"));
-    no_pch_target.set_output_type(Target::SOURCE_SET);
-    no_pch_target.visibility().SetPublic();
-    no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
-    no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
-    no_pch_target.config_values().cflags_c().push_back("-std=c99");
-    no_pch_target.SetToolchain(&pch_toolchain);
-    ASSERT_TRUE(no_pch_target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&no_pch_target, out);
-    writer.Run();
-
-    const char no_pch_expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_c = -std=c99\n"
-        "cflags_cc =\n"
-        "target_output_name = no_pch_target\n"
-        "\n"
-        "build withpch/obj/foo/no_pch_target.input1.o: "
-        "withpch_cxx ../../foo/input1.cc\n"
-        "build withpch/obj/foo/no_pch_target.input2.o: "
-        "withpch_cc ../../foo/input2.c\n"
-        "\n"
-        "build withpch/obj/foo/no_pch_target.stamp: "
-        "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
-        "withpch/obj/foo/no_pch_target.input2.o\n";
-    EXPECT_EQ(no_pch_expected, out.str());
-  }
-
-  // This target specifies PCH.
-  {
-    Target pch_target(&pch_settings, Label(SourceDir("//foo/"), "pch_target"));
-    pch_target.config_values().set_precompiled_header("build/precompile.h");
-    pch_target.config_values().set_precompiled_source(
-        SourceFile("//build/precompile.cc"));
-    pch_target.set_output_type(Target::SOURCE_SET);
-    pch_target.visibility().SetPublic();
-    pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
-    pch_target.sources().push_back(SourceFile("//foo/input2.c"));
-    pch_target.SetToolchain(&pch_toolchain);
-    ASSERT_TRUE(pch_target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&pch_target, out);
-    writer.Run();
-
-    const char pch_win_expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        // It should output language-specific pch files.
-        "cflags_c = /Fpwithpch/obj/foo/pch_target_c.pch "
-        "/Yubuild/precompile.h\n"
-        "cflags_cc = /Fpwithpch/obj/foo/pch_target_cc.pch "
-        "/Yubuild/precompile.h\n"
-        "target_output_name = pch_target\n"
-        "\n"
-        // Compile the precompiled source files with /Yc.
-        "build withpch/obj/build/pch_target.precompile.c.o: "
-        "withpch_cc ../../build/precompile.cc\n"
-        "  cflags_c = ${cflags_c} /Ycbuild/precompile.h\n"
-        "\n"
-        "build withpch/obj/build/pch_target.precompile.cc.o: "
-        "withpch_cxx ../../build/precompile.cc\n"
-        "  cflags_cc = ${cflags_cc} /Ycbuild/precompile.h\n"
-        "\n"
-        "build withpch/obj/foo/pch_target.input1.o: "
-        "withpch_cxx ../../foo/input1.cc | "
-        // Explicit dependency on the PCH build step.
-        "withpch/obj/build/pch_target.precompile.cc.o\n"
-        "build withpch/obj/foo/pch_target.input2.o: "
-        "withpch_cc ../../foo/input2.c | "
-        // Explicit dependency on the PCH build step.
-        "withpch/obj/build/pch_target.precompile.c.o\n"
-        "\n"
-        "build withpch/obj/foo/pch_target.stamp: withpch_stamp "
-        "withpch/obj/foo/pch_target.input1.o "
-        "withpch/obj/foo/pch_target.input2.o "
-        // The precompiled object files were added to the outputs.
-        "withpch/obj/build/pch_target.precompile.c.o "
-        "withpch/obj/build/pch_target.precompile.cc.o\n";
-    EXPECT_EQ(pch_win_expected, out.str()) << pch_win_expected << "--BREAK--" << out.str();
-  }
-}
-
-TEST_F(NinjaBinaryTargetWriterTest, GCCPrecompiledHeaders) {
-  Err err;
-
-  // This setup's toolchain does not have precompiled headers defined.
-  TestWithScope setup;
-
-  // A precompiled header toolchain.
-  Settings pch_settings(setup.build_settings(), "withpch/");
-  Toolchain pch_toolchain(&pch_settings,
-                          Label(SourceDir("//toolchain/"), "withpch"));
-  pch_settings.set_toolchain_label(pch_toolchain.label());
-  pch_settings.set_default_toolchain_label(setup.toolchain()->label());
-
-  // Declare a C++ compiler that supports PCH.
-  std::unique_ptr<Tool> cxx = Tool::CreateTool(CTool::kCToolCxx);
-  CTool* cxx_tool = cxx->AsC();
-  TestWithScope::SetCommandForTool(
-      "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
-      "-o {{output}}",
-      cxx_tool);
-  cxx_tool->set_outputs(SubstitutionList::MakeForTest(
-      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
-  cxx_tool->set_precompiled_header_type(CTool::PCH_GCC);
-  pch_toolchain.SetTool(std::move(cxx));
-  pch_toolchain.ToolchainSetupComplete();
-
-  // Add a C compiler as well.
-  std::unique_ptr<Tool> cc = Tool::CreateTool(CTool::kCToolCc);
-  CTool* cc_tool = cc->AsC();
-  TestWithScope::SetCommandForTool(
-      "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
-      "-o {{output}}",
-      cc_tool);
-  cc_tool->set_outputs(SubstitutionList::MakeForTest(
-      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
-  cc_tool->set_precompiled_header_type(CTool::PCH_GCC);
-  pch_toolchain.SetTool(std::move(cc));
-  pch_toolchain.ToolchainSetupComplete();
-
-  // This target doesn't specify precompiled headers.
-  {
-    Target no_pch_target(&pch_settings,
-                         Label(SourceDir("//foo/"), "no_pch_target"));
-    no_pch_target.set_output_type(Target::SOURCE_SET);
-    no_pch_target.visibility().SetPublic();
-    no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
-    no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
-    no_pch_target.config_values().cflags_c().push_back("-std=c99");
-    no_pch_target.SetToolchain(&pch_toolchain);
-    ASSERT_TRUE(no_pch_target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&no_pch_target, out);
-    writer.Run();
-
-    const char no_pch_expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_c = -std=c99\n"
-        "cflags_cc =\n"
-        "target_output_name = no_pch_target\n"
-        "\n"
-        "build withpch/obj/foo/no_pch_target.input1.o: "
-        "withpch_cxx ../../foo/input1.cc\n"
-        "build withpch/obj/foo/no_pch_target.input2.o: "
-        "withpch_cc ../../foo/input2.c\n"
-        "\n"
-        "build withpch/obj/foo/no_pch_target.stamp: "
-        "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
-        "withpch/obj/foo/no_pch_target.input2.o\n";
-    EXPECT_EQ(no_pch_expected, out.str());
-  }
-
-  // This target specifies PCH.
-  {
-    Target pch_target(&pch_settings, Label(SourceDir("//foo/"), "pch_target"));
-    pch_target.config_values().set_precompiled_source(
-        SourceFile("//build/precompile.h"));
-    pch_target.config_values().cflags_c().push_back("-std=c99");
-    pch_target.set_output_type(Target::SOURCE_SET);
-    pch_target.visibility().SetPublic();
-    pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
-    pch_target.sources().push_back(SourceFile("//foo/input2.c"));
-    pch_target.SetToolchain(&pch_toolchain);
-    ASSERT_TRUE(pch_target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&pch_target, out);
-    writer.Run();
-
-    const char pch_gcc_expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_c = -std=c99 "
-        "-include withpch/obj/build/pch_target.precompile.h-c\n"
-        "cflags_cc = -include withpch/obj/build/pch_target.precompile.h-cc\n"
-        "target_output_name = pch_target\n"
-        "\n"
-        // Compile the precompiled sources with -x <lang>.
-        "build withpch/obj/build/pch_target.precompile.h-c.gch: "
-        "withpch_cc ../../build/precompile.h\n"
-        "  cflags_c = -std=c99 -x c-header\n"
-        "\n"
-        "build withpch/obj/build/pch_target.precompile.h-cc.gch: "
-        "withpch_cxx ../../build/precompile.h\n"
-        "  cflags_cc = -x c++-header\n"
-        "\n"
-        "build withpch/obj/foo/pch_target.input1.o: "
-        "withpch_cxx ../../foo/input1.cc | "
-        // Explicit dependency on the PCH build step.
-        "withpch/obj/build/pch_target.precompile.h-cc.gch\n"
-        "build withpch/obj/foo/pch_target.input2.o: "
-        "withpch_cc ../../foo/input2.c | "
-        // Explicit dependency on the PCH build step.
-        "withpch/obj/build/pch_target.precompile.h-c.gch\n"
-        "\n"
-        "build withpch/obj/foo/pch_target.stamp: "
-        "withpch_stamp withpch/obj/foo/pch_target.input1.o "
-        "withpch/obj/foo/pch_target.input2.o\n";
-    EXPECT_EQ(pch_gcc_expected, out.str());
-  }
-}
-
-// Should throw an error with the scheduler if a duplicate object file exists.
-// This is dependent on the toolchain's object file mapping.
-TEST_F(NinjaBinaryTargetWriterTest, DupeObjFileError) {
-  TestWithScope setup;
-  TestTarget target(setup, "//foo:bar", Target::EXECUTABLE);
-  target.sources().push_back(SourceFile("//a.cc"));
-  target.sources().push_back(SourceFile("//a.cc"));
-
-  EXPECT_FALSE(scheduler().is_failed());
-
-  scheduler().SuppressOutputForTesting(true);
-
-  std::ostringstream out;
-  NinjaBinaryTargetWriter writer(&target, out);
-  writer.Run();
-
-  scheduler().SuppressOutputForTesting(false);
-
-  // Should have issued an error.
-  EXPECT_TRUE(scheduler().is_failed());
-}
-
-// This tests that output extension and output dir overrides apply, and input
-// dependencies are applied.
-TEST_F(NinjaBinaryTargetWriterTest, InputFiles) {
-  Err err;
-  TestWithScope setup;
-
-  // This target has one input.
-  {
-    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
-    target.set_output_type(Target::SOURCE_SET);
-    target.visibility().SetPublic();
-    target.sources().push_back(SourceFile("//foo/input1.cc"));
-    target.sources().push_back(SourceFile("//foo/input2.cc"));
-    target.config_values().inputs().push_back(SourceFile("//foo/input.data"));
-    target.SetToolchain(setup.toolchain());
-    ASSERT_TRUE(target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_cc =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = bar\n"
-        "\n"
-        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc"
-        " | ../../foo/input.data\n"
-        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc"
-        " | ../../foo/input.data\n"
-        "\n"
-        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
-        "obj/foo/bar.input2.o\n";
-
-    EXPECT_EQ(expected, out.str());
-  }
-
-  // This target has one input but no source files.
-  {
-    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
-    target.set_output_type(Target::SHARED_LIBRARY);
-    target.visibility().SetPublic();
-    target.config_values().inputs().push_back(SourceFile("//foo/input.data"));
-    target.SetToolchain(setup.toolchain());
-    ASSERT_TRUE(target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = libbar\n"
-        "\n"
-        "\n"
-        "build ./libbar.so: solink | ../../foo/input.data\n"
-        "  ldflags =\n"
-        "  libs =\n"
-        "  output_extension = .so\n"
-        "  output_dir = \n";
-
-    EXPECT_EQ(expected, out.str());
-  }
-
-  // This target has multiple inputs.
-  {
-    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
-    target.set_output_type(Target::SOURCE_SET);
-    target.visibility().SetPublic();
-    target.sources().push_back(SourceFile("//foo/input1.cc"));
-    target.sources().push_back(SourceFile("//foo/input2.cc"));
-    target.config_values().inputs().push_back(SourceFile("//foo/input1.data"));
-    target.config_values().inputs().push_back(SourceFile("//foo/input2.data"));
-    target.SetToolchain(setup.toolchain());
-    ASSERT_TRUE(target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_cc =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = bar\n"
-        "\n"
-        "build obj/foo/bar.inputs.stamp: stamp"
-        " ../../foo/input1.data ../../foo/input2.data\n"
-        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc"
-        " | obj/foo/bar.inputs.stamp\n"
-        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc"
-        " | obj/foo/bar.inputs.stamp\n"
-        "\n"
-        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
-        "obj/foo/bar.input2.o\n";
-
-    EXPECT_EQ(expected, out.str());
-  }
-
-  // This target has one input itself, one from an immediate config, and one
-  // from a config tacked on to said config.
-  {
-    Config far_config(setup.settings(), Label(SourceDir("//foo/"), "qux"));
-    far_config.own_values().inputs().push_back(SourceFile("//foo/input3.data"));
-    ASSERT_TRUE(far_config.OnResolved(&err));
-
-    Config config(setup.settings(), Label(SourceDir("//foo/"), "baz"));
-    config.own_values().inputs().push_back(SourceFile("//foo/input2.data"));
-    config.configs().push_back(LabelConfigPair(&far_config));
-    ASSERT_TRUE(config.OnResolved(&err));
-
-    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
-    target.set_output_type(Target::SOURCE_SET);
-    target.visibility().SetPublic();
-    target.sources().push_back(SourceFile("//foo/input1.cc"));
-    target.sources().push_back(SourceFile("//foo/input2.cc"));
-    target.config_values().inputs().push_back(SourceFile("//foo/input1.data"));
-    target.configs().push_back(LabelConfigPair(&config));
-    target.SetToolchain(setup.toolchain());
-    ASSERT_TRUE(target.OnResolved(&err));
-
-    std::ostringstream out;
-    NinjaBinaryTargetWriter writer(&target, out);
-    writer.Run();
-
-    const char expected[] =
-        "defines =\n"
-        "include_dirs =\n"
-        "cflags =\n"
-        "cflags_cc =\n"
-        "root_out_dir = .\n"
-        "target_out_dir = obj/foo\n"
-        "target_output_name = bar\n"
-        "\n"
-        "build obj/foo/bar.inputs.stamp: stamp"
-        " ../../foo/input1.data ../../foo/input2.data ../../foo/input3.data\n"
-        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc"
-        " | obj/foo/bar.inputs.stamp\n"
-        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc"
-        " | obj/foo/bar.inputs.stamp\n"
-        "\n"
-        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
-        "obj/foo/bar.input2.o\n";
-
-    EXPECT_EQ(expected, out.str());
-  }
-}
diff --git a/tools/gn/ninja_c_binary_target_writer.cc b/tools/gn/ninja_c_binary_target_writer.cc
new file mode 100644
index 0000000..b96e724
--- /dev/null
+++ b/tools/gn/ninja_c_binary_target_writer.cc
@@ -0,0 +1,875 @@
+// Copyright 2019 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/ninja_c_binary_target_writer.h"
+
+#include <stddef.h>
+#include <string.h>
+
+#include <cstring>
+#include <set>
+#include <sstream>
+#include <unordered_set>
+
+#include "base/strings/string_util.h"
+#include "tools/gn/config_values_extractors.h"
+#include "tools/gn/deps_iterator.h"
+#include "tools/gn/err.h"
+#include "tools/gn/escape.h"
+#include "tools/gn/general_tool.h"
+#include "tools/gn/filesystem_utils.h"
+#include "tools/gn/ninja_target_command_util.h"
+#include "tools/gn/ninja_utils.h"
+#include "tools/gn/scheduler.h"
+#include "tools/gn/settings.h"
+#include "tools/gn/source_file_type.h"
+#include "tools/gn/string_utils.h"
+#include "tools/gn/substitution_writer.h"
+#include "tools/gn/target.h"
+
+namespace {
+
+// Returns the proper escape options for writing compiler and linker flags.
+EscapeOptions GetFlagOptions() {
+  EscapeOptions opts;
+  opts.mode = ESCAPE_NINJA_COMMAND;
+  return opts;
+}
+
+// Returns the language-specific lang recognized by gcc’s -x flag for
+// precompiled header files.
+const char* GetPCHLangForToolType(const char* name) {
+  if (name == CTool::kCToolCc)
+      return "c-header";
+  if (name == CTool::kCToolCxx)
+      return "c++-header";
+  if (name == CTool::kCToolObjC)
+      return "objective-c-header";
+  if (name == CTool::kCToolObjCxx)
+      return "objective-c++-header";
+      NOTREACHED() << "Not a valid PCH tool type: " << name;
+      return "";
+}
+
+// Appends the object files generated by the given source set to the given
+// output vector.
+void AddSourceSetObjectFiles(const Target* source_set,
+                             UniqueVector<OutputFile>* obj_files) {
+  std::vector<OutputFile> tool_outputs;  // Prevent allocation in loop.
+  NinjaBinaryTargetWriter::SourceFileTypeSet used_types;
+
+  // Compute object files for all sources. Only link the first output from
+  // the tool if there are more than one.
+  for (const auto& source : source_set->sources()) {
+    const char* tool_name = Tool::kToolNone;
+    if (source_set->GetOutputFilesForSource(source, &tool_name, &tool_outputs))
+      obj_files->push_back(tool_outputs[0]);
+
+    used_types.Set(GetSourceFileType(source));
+  }
+
+  // Add MSVC precompiled header object files. GCC .gch files are not object
+  // files so they are omitted.
+  if (source_set->config_values().has_precompiled_headers()) {
+    if (used_types.Get(SOURCE_C)) {
+      const CTool* tool = source_set->toolchain()->GetToolAsC(CTool::kCToolCc);
+      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
+        GetPCHOutputFiles(source_set, CTool::kCToolCc, &tool_outputs);
+        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
+      }
+    }
+    if (used_types.Get(SOURCE_CPP)) {
+      const CTool* tool = source_set->toolchain()->GetToolAsC(CTool::kCToolCxx);
+      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
+        GetPCHOutputFiles(source_set, CTool::kCToolCxx, &tool_outputs);
+        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
+      }
+    }
+    if (used_types.Get(SOURCE_M)) {
+      const CTool* tool = source_set->toolchain()->GetToolAsC(CTool::kCToolObjC);
+      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
+        GetPCHOutputFiles(source_set, CTool::kCToolObjC, &tool_outputs);
+        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
+      }
+    }
+    if (used_types.Get(SOURCE_MM)) {
+      const CTool* tool =
+          source_set->toolchain()->GetToolAsC(CTool::kCToolObjCxx);
+      if (tool && tool->precompiled_header_type() == CTool::PCH_MSVC) {
+        GetPCHOutputFiles(source_set, CTool::kCToolObjCxx, &tool_outputs);
+        obj_files->Append(tool_outputs.begin(), tool_outputs.end());
+      }
+    }
+  }
+}
+
+}  // namespace
+
+NinjaCBinaryTargetWriter::NinjaCBinaryTargetWriter(const Target* target,
+                                                   std::ostream& out)
+    : NinjaBinaryTargetWriter(target, out),
+      tool_(target->toolchain()->GetToolForTargetFinalOutputAsC(target)) {}
+
+NinjaCBinaryTargetWriter::~NinjaCBinaryTargetWriter() = default;
+
+void NinjaCBinaryTargetWriter::Run() {
+  // Figure out what source types are needed.
+  SourceFileTypeSet used_types;
+  for (const auto& source : target_->sources())
+    used_types.Set(GetSourceFileType(source));
+
+  WriteCompilerVars(used_types);
+
+  OutputFile input_dep = WriteInputsStampAndGetDep();
+
+  // The input dependencies will be an order-only dependency. This will cause
+  // Ninja to make sure the inputs are up to date before compiling this source,
+  // but changes in the inputs deps won't cause the file to be recompiled.
+  //
+  // This is important to prevent changes in unrelated actions that are
+  // upstream of this target from causing everything to be recompiled.
+  //
+  // Why can we get away with this rather than using implicit deps ("|", which
+  // will force rebuilds when the inputs change)? For source code, the
+  // computed dependencies of all headers will be computed by the compiler,
+  // which will cause source rebuilds if any "real" upstream dependencies
+  // change.
+  //
+  // If a .cc file is generated by an input dependency, Ninja will see the
+  // input to the build rule doesn't exist, and that it is an output from a
+  // previous step, and build the previous step first. This is a "real"
+  // dependency and doesn't need | or || to express.
+  //
+  // The only case where this rule matters is for the first build where no .d
+  // files exist, and Ninja doesn't know what that source file depends on. In
+  // this case it's sufficient to ensure that the upstream dependencies are
+  // built first. This is exactly what Ninja's order-only dependencies
+  // expresses.
+  //
+  // The order only deps are referenced by each source file compile,
+  // but also by PCH compiles.  The latter are annoying to count, so omit
+  // them here.  This means that binary targets with a single source file
+  // that also use PCH files won't have a stamp file even though having
+  // one would make output ninja file size a bit lower. That's ok, binary
+  // targets with a single source are rare.
+  size_t num_stamp_uses = target_->sources().size();
+  std::vector<OutputFile> order_only_deps = WriteInputDepsStampAndGetDep(
+      std::vector<const Target*>(), num_stamp_uses);
+
+  // For GCC builds, the .gch files are not object files, but still need to be
+  // added as explicit dependencies below. The .gch output files are placed in
+  // |pch_other_files|. This is to prevent linking against them.
+  std::vector<OutputFile> pch_obj_files;
+  std::vector<OutputFile> pch_other_files;
+  WritePCHCommands(used_types, input_dep, order_only_deps, &pch_obj_files,
+                   &pch_other_files);
+  std::vector<OutputFile>* pch_files =
+      !pch_obj_files.empty() ? &pch_obj_files : &pch_other_files;
+
+  // Treat all pch output files as explicit dependencies of all
+  // compiles that support them. Some notes:
+  //
+  //  - On Windows, the .pch file is the input to the compile, not the
+  //    precompiled header's corresponding object file that we're using here.
+  //    But Ninja's depslog doesn't support multiple outputs from the
+  //    precompiled header compile step (it outputs both the .pch file and a
+  //    corresponding .obj file). So we consistently list the .obj file and the
+  //    .pch file we really need comes along with it.
+  //
+  //  - GCC .gch files are not object files, therefore they are not added to the
+  //    object file list.
+  std::vector<OutputFile> obj_files;
+  std::vector<SourceFile> other_files;
+  WriteSources(*pch_files, input_dep, order_only_deps, &obj_files,
+               &other_files);
+
+  // Link all MSVC pch object files. The vector will be empty on GCC toolchains.
+  obj_files.insert(obj_files.end(), pch_obj_files.begin(), pch_obj_files.end());
+  if (!CheckForDuplicateObjectFiles(obj_files))
+    return;
+
+  if (target_->output_type() == Target::SOURCE_SET) {
+    WriteSourceSetStamp(obj_files);
+#ifndef NDEBUG
+    // Verify that the function that separately computes a source set's object
+    // files match the object files just computed.
+    UniqueVector<OutputFile> computed_obj;
+    AddSourceSetObjectFiles(target_, &computed_obj);
+    DCHECK_EQ(obj_files.size(), computed_obj.size());
+    for (const auto& obj : obj_files)
+      DCHECK_NE(static_cast<size_t>(-1), computed_obj.IndexOf(obj));
+#endif
+  } else {
+    WriteLinkerStuff(obj_files, other_files, input_dep);
+  }
+}
+
+void NinjaCBinaryTargetWriter::WriteCompilerVars(
+    const SourceFileTypeSet& used_types) {
+  const SubstitutionBits& subst = target_->toolchain()->substitution_bits();
+
+  // Defines.
+  if (subst.used[SUBSTITUTION_DEFINES]) {
+    out_ << kSubstitutionNinjaNames[SUBSTITUTION_DEFINES] << " =";
+    RecursiveTargetConfigToStream<std::string>(target_, &ConfigValues::defines,
+                                               DefineWriter(), out_);
+    out_ << std::endl;
+  }
+
+  // Include directories.
+  if (subst.used[SUBSTITUTION_INCLUDE_DIRS]) {
+    out_ << kSubstitutionNinjaNames[SUBSTITUTION_INCLUDE_DIRS] << " =";
+    PathOutput include_path_output(
+        path_output_.current_dir(),
+        settings_->build_settings()->root_path_utf8(), ESCAPE_NINJA_COMMAND);
+    RecursiveTargetConfigToStream<SourceDir>(
+        target_, &ConfigValues::include_dirs,
+        IncludeWriter(include_path_output), out_);
+    out_ << std::endl;
+  }
+
+  bool has_precompiled_headers =
+      target_->config_values().has_precompiled_headers();
+
+  EscapeOptions opts = GetFlagOptions();
+  if (used_types.Get(SOURCE_S) || used_types.Get(SOURCE_ASM)) {
+    WriteOneFlag(target_, SUBSTITUTION_ASMFLAGS, false, Tool::kToolNone,
+                 &ConfigValues::asmflags, opts, path_output_, out_);
+  }
+  if (used_types.Get(SOURCE_C) || used_types.Get(SOURCE_CPP) ||
+      used_types.Get(SOURCE_M) || used_types.Get(SOURCE_MM)) {
+    WriteOneFlag(target_, SUBSTITUTION_CFLAGS, false, Tool::kToolNone,
+                 &ConfigValues::cflags, opts, path_output_, out_);
+  }
+  if (used_types.Get(SOURCE_C)) {
+    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_C, has_precompiled_headers,
+                 CTool::kCToolCc, &ConfigValues::cflags_c, opts, path_output_,
+                 out_);
+  }
+  if (used_types.Get(SOURCE_CPP)) {
+    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_CC, has_precompiled_headers,
+                 CTool::kCToolCxx, &ConfigValues::cflags_cc, opts, path_output_,
+                 out_);
+  }
+  if (used_types.Get(SOURCE_M)) {
+    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_OBJC, has_precompiled_headers,
+                 CTool::kCToolObjC, &ConfigValues::cflags_objc, opts,
+                 path_output_, out_);
+  }
+  if (used_types.Get(SOURCE_MM)) {
+    WriteOneFlag(target_, SUBSTITUTION_CFLAGS_OBJCC, has_precompiled_headers,
+                 CTool::kCToolObjCxx, &ConfigValues::cflags_objcc, opts,
+                 path_output_, out_);
+  }
+
+  WriteSharedVars(subst);
+}
+
+OutputFile NinjaCBinaryTargetWriter::WriteInputsStampAndGetDep() const {
+  CHECK(target_->toolchain()) << "Toolchain not set on target "
+                              << target_->label().GetUserVisibleName(true);
+
+  std::vector<const SourceFile*> inputs;
+  for (ConfigValuesIterator iter(target_); !iter.done(); iter.Next()) {
+    for (const auto& input : iter.cur().inputs()) {
+      inputs.push_back(&input);
+    }
+  }
+
+  if (inputs.size() == 0)
+    return OutputFile();  // No inputs
+
+  // If we only have one input, return it directly instead of writing a stamp
+  // file for it.
+  if (inputs.size() == 1)
+    return OutputFile(settings_->build_settings(), *inputs[0]);
+
+  // Make a stamp file.
+  OutputFile input_stamp_file =
+      GetBuildDirForTargetAsOutputFile(target_, BuildDirType::OBJ);
+  input_stamp_file.value().append(target_->label().name());
+  input_stamp_file.value().append(".inputs.stamp");
+
+  out_ << "build ";
+  path_output_.WriteFile(out_, input_stamp_file);
+  out_ << ": " << GetNinjaRulePrefixForToolchain(settings_)
+       << GeneralTool::kGeneralToolStamp;
+
+  // File inputs.
+  for (const auto* input : inputs) {
+    out_ << " ";
+    path_output_.WriteFile(out_, *input);
+  }
+
+  out_ << "\n";
+  return input_stamp_file;
+}
+
+void NinjaCBinaryTargetWriter::WritePCHCommands(
+    const SourceFileTypeSet& used_types,
+    const OutputFile& input_dep,
+    const std::vector<OutputFile>& order_only_deps,
+    std::vector<OutputFile>* object_files,
+    std::vector<OutputFile>* other_files) {
+  if (!target_->config_values().has_precompiled_headers())
+    return;
+
+  const CTool* tool_c = target_->toolchain()->GetToolAsC(CTool::kCToolCc);
+  if (tool_c && tool_c->precompiled_header_type() != CTool::PCH_NONE &&
+      used_types.Get(SOURCE_C)) {
+    WritePCHCommand(SUBSTITUTION_CFLAGS_C, CTool::kCToolCc,
+                    tool_c->precompiled_header_type(), input_dep,
+                    order_only_deps, object_files, other_files);
+  }
+  const CTool* tool_cxx = target_->toolchain()->GetToolAsC(CTool::kCToolCxx);
+  if (tool_cxx && tool_cxx->precompiled_header_type() != CTool::PCH_NONE &&
+      used_types.Get(SOURCE_CPP)) {
+    WritePCHCommand(SUBSTITUTION_CFLAGS_CC, CTool::kCToolCxx,
+                    tool_cxx->precompiled_header_type(), input_dep,
+                    order_only_deps, object_files, other_files);
+  }
+
+  const CTool* tool_objc = target_->toolchain()->GetToolAsC(CTool::kCToolObjC);
+  if (tool_objc && tool_objc->precompiled_header_type() == CTool::PCH_GCC &&
+      used_types.Get(SOURCE_M)) {
+    WritePCHCommand(SUBSTITUTION_CFLAGS_OBJC, CTool::kCToolObjC,
+                    tool_objc->precompiled_header_type(), input_dep,
+                    order_only_deps, object_files, other_files);
+  }
+
+  const CTool* tool_objcxx =
+      target_->toolchain()->GetToolAsC(CTool::kCToolObjCxx);
+  if (tool_objcxx && tool_objcxx->precompiled_header_type() == CTool::PCH_GCC &&
+      used_types.Get(SOURCE_MM)) {
+    WritePCHCommand(SUBSTITUTION_CFLAGS_OBJCC, CTool::kCToolObjCxx,
+                    tool_objcxx->precompiled_header_type(), input_dep,
+                    order_only_deps, object_files, other_files);
+  }
+}
+
+void NinjaCBinaryTargetWriter::WritePCHCommand(
+    SubstitutionType flag_type,
+    const char* tool_name,
+    CTool::PrecompiledHeaderType header_type,
+    const OutputFile& input_dep,
+    const std::vector<OutputFile>& order_only_deps,
+    std::vector<OutputFile>* object_files,
+    std::vector<OutputFile>* other_files) {
+  switch (header_type) {
+    case CTool::PCH_MSVC:
+      WriteWindowsPCHCommand(flag_type, tool_name, input_dep, order_only_deps,
+                             object_files);
+      break;
+    case CTool::PCH_GCC:
+      WriteGCCPCHCommand(flag_type, tool_name, input_dep, order_only_deps,
+                         other_files);
+      break;
+    case CTool::PCH_NONE:
+      NOTREACHED() << "Cannot write a PCH command with no PCH header type";
+      break;
+  }
+}
+
+void NinjaCBinaryTargetWriter::WriteGCCPCHCommand(
+    SubstitutionType flag_type,
+    const char* tool_name,
+    const OutputFile& input_dep,
+    const std::vector<OutputFile>& order_only_deps,
+    std::vector<OutputFile>* gch_files) {
+  // Compute the pch output file (it will be language-specific).
+  std::vector<OutputFile> outputs;
+  GetPCHOutputFiles(target_, tool_name, &outputs);
+  if (outputs.empty())
+    return;
+
+  gch_files->insert(gch_files->end(), outputs.begin(), outputs.end());
+
+  std::vector<OutputFile> extra_deps;
+  if (!input_dep.value().empty())
+    extra_deps.push_back(input_dep);
+
+  // Build line to compile the file.
+  WriteCompilerBuildLine(target_->config_values().precompiled_source(),
+                         extra_deps, order_only_deps, tool_name, outputs);
+
+  // This build line needs a custom language-specific flags value. Rule-specific
+  // variables are just indented underneath the rule line.
+  out_ << "  " << kSubstitutionNinjaNames[flag_type] << " =";
+
+  // Each substitution flag is overwritten in the target rule to replace the
+  // implicitly generated -include flag with the -x <header lang> flag required
+  // for .gch targets.
+  EscapeOptions opts = GetFlagOptions();
+  if (tool_name == CTool::kCToolCc) {
+    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_c, opts,
+                                         out_);
+  } else if (tool_name == CTool::kCToolCxx) {
+    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_cc,
+                                         opts, out_);
+  } else if (tool_name == CTool::kCToolObjC) {
+    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_objc,
+                                         opts, out_);
+  } else if (tool_name == CTool::kCToolObjCxx) {
+    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::cflags_objcc,
+                                         opts, out_);
+  }
+
+  // Append the command to specify the language of the .gch file.
+  out_ << " -x " << GetPCHLangForToolType(tool_name);
+
+  // Write two blank lines to help separate the PCH build lines from the
+  // regular source build lines.
+  out_ << std::endl << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteWindowsPCHCommand(
+    SubstitutionType flag_type,
+    const char* tool_name,
+    const OutputFile& input_dep,
+    const std::vector<OutputFile>& order_only_deps,
+    std::vector<OutputFile>* object_files) {
+  // Compute the pch output file (it will be language-specific).
+  std::vector<OutputFile> outputs;
+  GetPCHOutputFiles(target_, tool_name, &outputs);
+  if (outputs.empty())
+    return;
+
+  object_files->insert(object_files->end(), outputs.begin(), outputs.end());
+
+  std::vector<OutputFile> extra_deps;
+  if (!input_dep.value().empty())
+    extra_deps.push_back(input_dep);
+
+  // Build line to compile the file.
+  WriteCompilerBuildLine(target_->config_values().precompiled_source(),
+                         extra_deps, order_only_deps, tool_name, outputs);
+
+  // This build line needs a custom language-specific flags value. Rule-specific
+  // variables are just indented underneath the rule line.
+  out_ << "  " << kSubstitutionNinjaNames[flag_type] << " =";
+
+  // Append the command to generate the .pch file.
+  // This adds the value to the existing flag instead of overwriting it.
+  out_ << " ${" << kSubstitutionNinjaNames[flag_type] << "}";
+  out_ << " /Yc" << target_->config_values().precompiled_header();
+
+  // Write two blank lines to help separate the PCH build lines from the
+  // regular source build lines.
+  out_ << std::endl << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteSources(
+    const std::vector<OutputFile>& pch_deps,
+    const OutputFile& input_dep,
+    const std::vector<OutputFile>& order_only_deps,
+    std::vector<OutputFile>* object_files,
+    std::vector<SourceFile>* other_files) {
+  object_files->reserve(object_files->size() + target_->sources().size());
+
+  std::vector<OutputFile> tool_outputs;  // Prevent reallocation in loop.
+  std::vector<OutputFile> deps;
+  for (const auto& source : target_->sources()) {
+    // Clear the vector but maintain the max capacity to prevent reallocations.
+    deps.resize(0);
+    const char* tool_name = Tool::kToolNone;
+    if (!target_->GetOutputFilesForSource(source, &tool_name, &tool_outputs)) {
+      if (GetSourceFileType(source) == SOURCE_DEF)
+        other_files->push_back(source);
+      continue;  // No output for this source.
+    }
+
+    if (!input_dep.value().empty())
+      deps.push_back(input_dep);
+
+    if (tool_name != Tool::kToolNone) {
+      // Only include PCH deps that correspond to the tool type, for instance,
+      // do not specify target_name.precompile.cc.obj (a CXX PCH file) as a dep
+      // for the output of a C tool type.
+      //
+      // This makes the assumption that pch_deps only contains pch output files
+      // with the naming scheme specified in GetWindowsPCHObjectExtension or
+      // GetGCCPCHOutputExtension.
+      const CTool* tool = target_->toolchain()->GetToolAsC(tool_name);
+      if (tool->precompiled_header_type() != CTool::PCH_NONE) {
+        for (const auto& dep : pch_deps) {
+          const std::string& output_value = dep.value();
+          size_t extension_offset = FindExtensionOffset(output_value);
+          if (extension_offset == std::string::npos)
+            continue;
+          std::string output_extension;
+          if (tool->precompiled_header_type() == CTool::PCH_MSVC) {
+            output_extension = GetWindowsPCHObjectExtension(
+                tool_name, output_value.substr(extension_offset - 1));
+          } else if (tool->precompiled_header_type() == CTool::PCH_GCC) {
+            output_extension = GetGCCPCHOutputExtension(tool_name);
+          }
+          if (output_value.compare(
+                  output_value.size() - output_extension.size(),
+                  output_extension.size(), output_extension) == 0) {
+            deps.push_back(dep);
+          }
+        }
+      }
+      WriteCompilerBuildLine(source, deps, order_only_deps, tool_name,
+                             tool_outputs);
+    }
+
+    // It's theoretically possible for a compiler to produce more than one
+    // output, but we'll only link to the first output.
+    object_files->push_back(tool_outputs[0]);
+  }
+  out_ << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteCompilerBuildLine(
+    const SourceFile& source,
+    const std::vector<OutputFile>& extra_deps,
+    const std::vector<OutputFile>& order_only_deps,
+    const char* tool_name,
+    const std::vector<OutputFile>& outputs) {
+  out_ << "build";
+  path_output_.WriteFiles(out_, outputs);
+
+  out_ << ": " << rule_prefix_ << tool_name;
+  out_ << " ";
+  path_output_.WriteFile(out_, source);
+
+  if (!extra_deps.empty()) {
+    out_ << " |";
+    path_output_.WriteFiles(out_, extra_deps);
+  }
+
+  if (!order_only_deps.empty()) {
+    out_ << " ||";
+    path_output_.WriteFiles(out_, order_only_deps);
+  }
+  out_ << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteLinkerStuff(
+    const std::vector<OutputFile>& object_files,
+    const std::vector<SourceFile>& other_files,
+    const OutputFile& input_dep) {
+  std::vector<OutputFile> output_files;
+  SubstitutionWriter::ApplyListToLinkerAsOutputFile(
+      target_, tool_, tool_->outputs(), &output_files);
+
+  out_ << "build";
+  path_output_.WriteFiles(out_, output_files);
+
+  out_ << ": " << rule_prefix_
+       << Tool::GetToolTypeForTargetFinalOutput(target_);
+
+  UniqueVector<OutputFile> extra_object_files;
+  UniqueVector<const Target*> linkable_deps;
+  UniqueVector<const Target*> non_linkable_deps;
+  GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps);
+
+  // Object files.
+  path_output_.WriteFiles(out_, object_files);
+  path_output_.WriteFiles(out_, extra_object_files);
+
+  // Dependencies.
+  std::vector<OutputFile> implicit_deps;
+  std::vector<OutputFile> solibs;
+  for (const Target* cur : linkable_deps) {
+    // All linkable deps should have a link output file.
+    DCHECK(!cur->link_output_file().value().empty())
+        << "No link output file for "
+        << target_->label().GetUserVisibleName(false);
+
+    if (cur->dependency_output_file().value() !=
+        cur->link_output_file().value()) {
+      // This is a shared library with separate link and deps files. Save for
+      // later.
+      implicit_deps.push_back(cur->dependency_output_file());
+      solibs.push_back(cur->link_output_file());
+    } else {
+      // Normal case, just link to this target.
+      out_ << " ";
+      path_output_.WriteFile(out_, cur->link_output_file());
+    }
+  }
+
+  const SourceFile* optional_def_file = nullptr;
+  if (!other_files.empty()) {
+    for (const SourceFile& src_file : other_files) {
+      if (GetSourceFileType(src_file) == SOURCE_DEF) {
+        optional_def_file = &src_file;
+        implicit_deps.push_back(
+            OutputFile(settings_->build_settings(), src_file));
+        break;  // Only one def file is allowed.
+      }
+    }
+  }
+
+  // Libraries specified by paths.
+  const OrderedSet<LibFile>& libs = target_->all_libs();
+  for (size_t i = 0; i < libs.size(); i++) {
+    if (libs[i].is_source_file()) {
+      implicit_deps.push_back(
+          OutputFile(settings_->build_settings(), libs[i].source_file()));
+    }
+  }
+
+  // The input dependency is only needed if there are no object files, as the
+  // dependency is normally provided transitively by the source files.
+  if (!input_dep.value().empty() && object_files.empty())
+    implicit_deps.push_back(input_dep);
+
+  // Append implicit dependencies collected above.
+  if (!implicit_deps.empty()) {
+    out_ << " |";
+    path_output_.WriteFiles(out_, implicit_deps);
+  }
+
+  // Append data dependencies as order-only dependencies.
+  //
+  // This will include data dependencies and input dependencies (like when
+  // this target depends on an action). Having the data dependencies in this
+  // list ensures that the data is available at runtime when the user builds
+  // this target.
+  //
+  // The action dependencies are not strictly necessary in this case. They
+  // should also have been collected via the input deps stamp that each source
+  // file has for an order-only dependency, and since this target depends on
+  // the sources, there is already an implicit order-only dependency. However,
+  // it's extra work to separate these out and there's no disadvantage to
+  // listing them again.
+  WriteOrderOnlyDependencies(non_linkable_deps);
+
+  // End of the link "build" line.
+  out_ << std::endl;
+
+  // The remaining things go in the inner scope of the link line.
+  if (target_->output_type() == Target::EXECUTABLE ||
+      target_->output_type() == Target::SHARED_LIBRARY ||
+      target_->output_type() == Target::LOADABLE_MODULE) {
+    WriteLinkerFlags(optional_def_file);
+    WriteLibs();
+  } else if (target_->output_type() == Target::STATIC_LIBRARY) {
+    out_ << "  arflags =";
+    RecursiveTargetConfigStringsToStream(target_, &ConfigValues::arflags,
+                                         GetFlagOptions(), out_);
+    out_ << std::endl;
+  }
+  WriteOutputSubstitutions();
+  WriteSolibs(solibs);
+}
+
+void NinjaCBinaryTargetWriter::WriteLinkerFlags(
+    const SourceFile* optional_def_file) {
+  out_ << "  ldflags =";
+
+  // First the ldflags from the target and its config.
+  RecursiveTargetConfigStringsToStream(target_, &ConfigValues::ldflags,
+                                       GetFlagOptions(), out_);
+
+  // Followed by library search paths that have been recursively pushed
+  // through the dependency tree.
+  const OrderedSet<SourceDir> all_lib_dirs = target_->all_lib_dirs();
+  if (!all_lib_dirs.empty()) {
+    // Since we're passing these on the command line to the linker and not
+    // to Ninja, we need to do shell escaping.
+    PathOutput lib_path_output(path_output_.current_dir(),
+                               settings_->build_settings()->root_path_utf8(),
+                               ESCAPE_NINJA_COMMAND);
+    for (size_t i = 0; i < all_lib_dirs.size(); i++) {
+      out_ << " " << tool_->lib_dir_switch();
+      lib_path_output.WriteDir(out_, all_lib_dirs[i],
+                               PathOutput::DIR_NO_LAST_SLASH);
+    }
+  }
+
+  if (optional_def_file) {
+    out_ << " /DEF:";
+    path_output_.WriteFile(out_, *optional_def_file);
+  }
+
+  out_ << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteLibs() {
+  out_ << "  libs =";
+
+  // Libraries that have been recursively pushed through the dependency tree.
+  EscapeOptions lib_escape_opts;
+  lib_escape_opts.mode = ESCAPE_NINJA_COMMAND;
+  const OrderedSet<LibFile> all_libs = target_->all_libs();
+  const std::string framework_ending(".framework");
+  for (size_t i = 0; i < all_libs.size(); i++) {
+    const LibFile& lib_file = all_libs[i];
+    const std::string& lib_value = lib_file.value();
+    if (lib_file.is_source_file()) {
+      out_ << " ";
+      path_output_.WriteFile(out_, lib_file.source_file());
+    } else if (base::EndsWith(lib_value, framework_ending,
+                              base::CompareCase::INSENSITIVE_ASCII)) {
+      // Special-case libraries ending in ".framework" to support Mac: Add the
+      // -framework switch and don't add the extension to the output.
+      out_ << " -framework ";
+      EscapeStringToStream(
+          out_, lib_value.substr(0, lib_value.size() - framework_ending.size()),
+          lib_escape_opts);
+    } else {
+      out_ << " " << tool_->lib_switch();
+      EscapeStringToStream(out_, lib_value, lib_escape_opts);
+    }
+  }
+  out_ << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteOutputSubstitutions() {
+  out_ << "  output_extension = "
+       << SubstitutionWriter::GetLinkerSubstitution(
+              target_, tool_, SUBSTITUTION_OUTPUT_EXTENSION);
+  out_ << std::endl;
+  out_ << "  output_dir = "
+       << SubstitutionWriter::GetLinkerSubstitution(target_, tool_,
+                                                    SUBSTITUTION_OUTPUT_DIR);
+  out_ << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteSolibs(
+    const std::vector<OutputFile>& solibs) {
+  if (solibs.empty())
+    return;
+
+  out_ << "  solibs =";
+  path_output_.WriteFiles(out_, solibs);
+  out_ << std::endl;
+}
+
+void NinjaCBinaryTargetWriter::WriteSourceSetStamp(
+    const std::vector<OutputFile>& object_files) {
+  // The stamp rule for source sets is generally not used, since targets that
+  // depend on this will reference the object files directly. However, writing
+  // this rule allows the user to type the name of the target and get a build
+  // which can be convenient for development.
+  UniqueVector<OutputFile> extra_object_files;
+  UniqueVector<const Target*> linkable_deps;
+  UniqueVector<const Target*> non_linkable_deps;
+  GetDeps(&extra_object_files, &linkable_deps, &non_linkable_deps);
+
+  // The classifier should never put extra object files in a source set:
+  // any source sets that we depend on should appear in our non-linkable
+  // deps instead.
+  DCHECK(extra_object_files.empty());
+
+  std::vector<OutputFile> order_only_deps;
+  for (auto* dep : non_linkable_deps)
+    order_only_deps.push_back(dep->dependency_output_file());
+
+  WriteStampForTarget(object_files, order_only_deps);
+}
+
+void NinjaCBinaryTargetWriter::GetDeps(
+    UniqueVector<OutputFile>* extra_object_files,
+    UniqueVector<const Target*>* linkable_deps,
+    UniqueVector<const Target*>* non_linkable_deps) const {
+  // Normal public/private deps.
+  for (const auto& pair : target_->GetDeps(Target::DEPS_LINKED)) {
+    ClassifyDependency(pair.ptr, extra_object_files, linkable_deps,
+                       non_linkable_deps);
+  }
+
+  // Inherited libraries.
+  for (auto* inherited_target : target_->inherited_libraries().GetOrdered()) {
+    ClassifyDependency(inherited_target, extra_object_files, linkable_deps,
+                       non_linkable_deps);
+  }
+
+  // Data deps.
+  for (const auto& data_dep_pair : target_->data_deps())
+    non_linkable_deps->push_back(data_dep_pair.ptr);
+}
+
+void NinjaCBinaryTargetWriter::ClassifyDependency(
+    const Target* dep,
+    UniqueVector<OutputFile>* extra_object_files,
+    UniqueVector<const Target*>* linkable_deps,
+    UniqueVector<const Target*>* non_linkable_deps) const {
+  // Only the following types of outputs have libraries linked into them:
+  //  EXECUTABLE
+  //  SHARED_LIBRARY
+  //  _complete_ STATIC_LIBRARY
+  //
+  // Child deps of intermediate static libraries get pushed up the
+  // dependency tree until one of these is reached, and source sets
+  // don't link at all.
+  bool can_link_libs = target_->IsFinal();
+
+  if (dep->output_type() == Target::SOURCE_SET ||
+      // If a complete static library depends on an incomplete static library,
+      // manually link in the object files of the dependent library as if it
+      // were a source set. This avoids problems with braindead tools such as
+      // ar which don't properly link dependent static libraries.
+      (target_->complete_static_lib() &&
+       dep->output_type() == Target::STATIC_LIBRARY &&
+       !dep->complete_static_lib())) {
+    // Source sets have their object files linked into final targets
+    // (shared libraries, executables, loadable modules, and complete static
+    // libraries). Intermediate static libraries and other source sets
+    // just forward the dependency, otherwise the files in the source
+    // set can easily get linked more than once which will cause
+    // multiple definition errors.
+    if (can_link_libs)
+      AddSourceSetObjectFiles(dep, extra_object_files);
+
+    // Add the source set itself as a non-linkable dependency on the current
+    // target. This will make sure that anything the source set's stamp file
+    // depends on (like data deps) are also built before the current target
+    // can be complete. Otherwise, these will be skipped since this target
+    // will depend only on the source set's object files.
+    non_linkable_deps->push_back(dep);
+  } else if (target_->complete_static_lib() && dep->IsFinal()) {
+    non_linkable_deps->push_back(dep);
+  } else if (can_link_libs && dep->IsLinkable()) {
+    linkable_deps->push_back(dep);
+  } else {
+    non_linkable_deps->push_back(dep);
+  }
+}
+
+void NinjaCBinaryTargetWriter::WriteOrderOnlyDependencies(
+    const UniqueVector<const Target*>& non_linkable_deps) {
+  if (!non_linkable_deps.empty()) {
+    out_ << " ||";
+
+    // Non-linkable targets.
+    for (auto* non_linkable_dep : non_linkable_deps) {
+      out_ << " ";
+      path_output_.WriteFile(out_, non_linkable_dep->dependency_output_file());
+    }
+  }
+}
+
+bool NinjaCBinaryTargetWriter::CheckForDuplicateObjectFiles(
+    const std::vector<OutputFile>& files) const {
+  std::unordered_set<std::string> set;
+  for (const auto& file : files) {
+    if (!set.insert(file.value()).second) {
+      Err err(
+          target_->defined_from(), "Duplicate object file",
+          "The target " + target_->label().GetUserVisibleName(false) +
+              "\ngenerates two object files with the same name:\n  " +
+              file.value() +
+              "\n"
+              "\n"
+              "It could be you accidentally have a file listed twice in the\n"
+              "sources. Or, depending on how your toolchain maps sources to\n"
+              "object files, two source files with the same name in different\n"
+              "directories could map to the same object file.\n"
+              "\n"
+              "In the latter case, either rename one of the files or move one "
+              "of\n"
+              "the sources to a separate source_set to avoid them both being "
+              "in\n"
+              "the same target.");
+      g_scheduler->FailWithError(err);
+      return false;
+    }
+  }
+  return true;
+}
diff --git a/tools/gn/ninja_c_binary_target_writer.h b/tools/gn/ninja_c_binary_target_writer.h
new file mode 100644
index 0000000..4fb89d9
--- /dev/null
+++ b/tools/gn/ninja_c_binary_target_writer.h
@@ -0,0 +1,134 @@
+// Copyright 2019 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_NINJA_C_BINARY_TARGET_WRITER_H_
+#define TOOLS_GN_NINJA_C_BINARY_TARGET_WRITER_H_
+
+#include "base/macros.h"
+#include "tools/gn/config_values.h"
+#include "tools/gn/ninja_binary_target_writer.h"
+#include "tools/gn/toolchain.h"
+#include "tools/gn/unique_vector.h"
+
+struct EscapeOptions;
+
+// Writes a .ninja file for a binary target type (an executable, a shared
+// library, or a static library).
+class NinjaCBinaryTargetWriter : public NinjaBinaryTargetWriter {
+ public:
+  NinjaCBinaryTargetWriter(const Target* target, std::ostream& out);
+  ~NinjaCBinaryTargetWriter() override;
+
+  void Run() override;
+
+ private:
+  typedef std::set<OutputFile> OutputFileSet;
+
+  // Writes all flags for the compiler: includes, defines, cflags, etc.
+  void WriteCompilerVars(const SourceFileTypeSet& used_types);
+
+  // Writes to the output stream a stamp rule for inputs, and
+  // returns the file to be appended to source rules that encodes the
+  // implicit dependencies for the current target. The returned OutputFile
+  // will be empty if there are no inputs.
+  OutputFile WriteInputsStampAndGetDep() const;
+
+  // Writes build lines required for precompiled headers. Any generated
+  // object files will be appended to the |object_files|. Any generated
+  // non-object files (for instance, .gch files from a GCC toolchain, are
+  // appended to |other_files|).
+  //
+  // input_dep is the stamp file collecting the dependencies required before
+  // compiling this target. It will be empty if there are no input deps.
+  void WritePCHCommands(const SourceFileTypeSet& used_types,
+                        const OutputFile& input_dep,
+                        const std::vector<OutputFile>& order_only_deps,
+                        std::vector<OutputFile>* object_files,
+                        std::vector<OutputFile>* other_files);
+
+  // Writes a .pch compile build line for a language type.
+  void WritePCHCommand(SubstitutionType flag_type,
+                       const char* tool_name,
+                       CTool::PrecompiledHeaderType header_type,
+                       const OutputFile& input_dep,
+                       const std::vector<OutputFile>& order_only_deps,
+                       std::vector<OutputFile>* object_files,
+                       std::vector<OutputFile>* other_files);
+
+  void WriteGCCPCHCommand(SubstitutionType flag_type,
+                          const char* tool_name,
+                          const OutputFile& input_dep,
+                          const std::vector<OutputFile>& order_only_deps,
+                          std::vector<OutputFile>* gch_files);
+
+  void WriteWindowsPCHCommand(SubstitutionType flag_type,
+                              const char* tool_name,
+                              const OutputFile& input_dep,
+                              const std::vector<OutputFile>& order_only_deps,
+                              std::vector<OutputFile>* object_files);
+
+  // pch_deps are additional dependencies to run before the rule. They are
+  // expected to abide by the naming conventions specified by GetPCHOutputFiles.
+  //
+  // order_only_dep are the dependencies that must be run before doing any
+  // compiles.
+  //
+  // The files produced by the compiler will be added to two output vectors.
+  void WriteSources(const std::vector<OutputFile>& pch_deps,
+                    const OutputFile& input_dep,
+                    const std::vector<OutputFile>& order_only_deps,
+                    std::vector<OutputFile>* object_files,
+                    std::vector<SourceFile>* other_files);
+
+  // Writes a build line.
+  void WriteCompilerBuildLine(const SourceFile& source,
+                              const std::vector<OutputFile>& extra_deps,
+                              const std::vector<OutputFile>& order_only_deps,
+                              const char* tool_name,
+                              const std::vector<OutputFile>& outputs);
+
+  void WriteLinkerStuff(const std::vector<OutputFile>& object_files,
+                        const std::vector<SourceFile>& other_files,
+                        const OutputFile& input_dep);
+  void WriteLinkerFlags(const SourceFile* optional_def_file);
+  void WriteLibs();
+  void WriteOutputSubstitutions();
+  void WriteSolibs(const std::vector<OutputFile>& solibs);
+
+  // Writes the stamp line for a source set. These are not linked.
+  void WriteSourceSetStamp(const std::vector<OutputFile>& object_files);
+
+  // Gets all target dependencies and classifies them, as well as accumulates
+  // object files from source sets we need to link.
+  void GetDeps(UniqueVector<OutputFile>* extra_object_files,
+               UniqueVector<const Target*>* linkable_deps,
+               UniqueVector<const Target*>* non_linkable_deps) const;
+
+  // Classifies the dependency as linkable or nonlinkable with the current
+  // target, adding it to the appropriate vector. If the dependency is a source
+  // set we should link in, the source set's object files will be appended to
+  // |extra_object_files|.
+  void ClassifyDependency(const Target* dep,
+                          UniqueVector<OutputFile>* extra_object_files,
+                          UniqueVector<const Target*>* linkable_deps,
+                          UniqueVector<const Target*>* non_linkable_deps) const;
+
+  // Writes the implicit dependencies for the link or stamp line. This is
+  // the "||" and everything following it on the ninja line.
+  //
+  // The order-only dependencies are the non-linkable deps passed in as an
+  // argument, plus the data file depdencies in the target.
+  void WriteOrderOnlyDependencies(
+      const UniqueVector<const Target*>& non_linkable_deps);
+
+  // Checks for duplicates in the given list of output files. If any duplicates
+  // are found, throws an error and return false.
+  bool CheckForDuplicateObjectFiles(const std::vector<OutputFile>& files) const;
+
+  const CTool* tool_;
+
+  DISALLOW_COPY_AND_ASSIGN(NinjaCBinaryTargetWriter);
+};
+
+#endif  // TOOLS_GN_NINJA_C_BINARY_TARGET_WRITER_H_
diff --git a/tools/gn/ninja_c_binary_target_writer_unittest.cc b/tools/gn/ninja_c_binary_target_writer_unittest.cc
new file mode 100644
index 0000000..829114a
--- /dev/null
+++ b/tools/gn/ninja_c_binary_target_writer_unittest.cc
@@ -0,0 +1,1159 @@
+// Copyright 2019 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/ninja_c_binary_target_writer.h"
+
+#include <memory>
+#include <sstream>
+#include <utility>
+
+#include "tools/gn/config.h"
+#include "tools/gn/ninja_target_command_util.h"
+#include "tools/gn/scheduler.h"
+#include "tools/gn/target.h"
+#include "tools/gn/test_with_scheduler.h"
+#include "tools/gn/test_with_scope.h"
+#include "util/build_config.h"
+#include "util/test/test.h"
+
+using NinjaCBinaryTargetWriterTest = TestWithScheduler;
+
+TEST_F(NinjaCBinaryTargetWriterTest, SourceSet) {
+  Err err;
+  TestWithScope setup;
+
+  Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+  target.set_output_type(Target::SOURCE_SET);
+  target.visibility().SetPublic();
+  target.sources().push_back(SourceFile("//foo/input1.cc"));
+  target.sources().push_back(SourceFile("//foo/input2.cc"));
+  // Also test object files, which should be just passed through to the
+  // dependents to link.
+  target.sources().push_back(SourceFile("//foo/input3.o"));
+  target.sources().push_back(SourceFile("//foo/input4.obj"));
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  // Source set itself.
+  {
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_cc =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = bar\n"
+        "\n"
+        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc\n"
+        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc\n"
+        "\n"
+        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
+        "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj\n";
+    std::string out_str = out.str();
+    EXPECT_EQ(expected, out_str);
+  }
+
+  // A shared library that depends on the source set.
+  Target shlib_target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
+  shlib_target.set_output_type(Target::SHARED_LIBRARY);
+  shlib_target.public_deps().push_back(LabelTargetPair(&target));
+  shlib_target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(shlib_target.OnResolved(&err));
+
+  {
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&shlib_target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = libshlib\n"
+        "\n"
+        "\n"
+        // Ordering of the obj files here should come out in the order
+        // specified, with the target's first, followed by the source set's, in
+        // order.
+        "build ./libshlib.so: solink obj/foo/bar.input1.o "
+        "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj "
+        "|| obj/foo/bar.stamp\n"
+        "  ldflags =\n"
+        "  libs =\n"
+        "  output_extension = .so\n"
+        "  output_dir = \n";
+    std::string out_str = out.str();
+    EXPECT_EQ(expected, out_str);
+  }
+
+  // A static library that depends on the source set (should not link it).
+  Target stlib_target(setup.settings(), Label(SourceDir("//foo/"), "stlib"));
+  stlib_target.set_output_type(Target::STATIC_LIBRARY);
+  stlib_target.public_deps().push_back(LabelTargetPair(&target));
+  stlib_target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(stlib_target.OnResolved(&err));
+
+  {
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&stlib_target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = libstlib\n"
+        "\n"
+        "\n"
+        // There are no sources so there are no params to alink. (In practice
+        // this will probably fail in the archive tool.)
+        "build obj/foo/libstlib.a: alink || obj/foo/bar.stamp\n"
+        "  arflags =\n"
+        "  output_extension = \n"
+        "  output_dir = \n";
+    std::string out_str = out.str();
+    EXPECT_EQ(expected, out_str);
+  }
+
+  // Make the static library 'complete', which means it should be linked.
+  stlib_target.set_complete_static_lib(true);
+  {
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&stlib_target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = libstlib\n"
+        "\n"
+        "\n"
+        // Ordering of the obj files here should come out in the order
+        // specified, with the target's first, followed by the source set's, in
+        // order.
+        "build obj/foo/libstlib.a: alink obj/foo/bar.input1.o "
+        "obj/foo/bar.input2.o ../../foo/input3.o ../../foo/input4.obj "
+        "|| obj/foo/bar.stamp\n"
+        "  arflags =\n"
+        "  output_extension = \n"
+        "  output_dir = \n";
+    std::string out_str = out.str();
+    EXPECT_EQ(expected, out_str);
+  }
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, EscapeDefines) {
+  TestWithScope setup;
+  Err err;
+
+  TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY);
+  target.config_values().defines().push_back("BOOL_DEF");
+  target.config_values().defines().push_back("INT_DEF=123");
+  target.config_values().defines().push_back("STR_DEF=\"ABCD-1\"");
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expectedSubstr[] =
+#if defined(OS_WIN)
+      "defines = -DBOOL_DEF -DINT_DEF=123 \"-DSTR_DEF=\\\"ABCD-1\\\"\"";
+#else
+      "defines = -DBOOL_DEF -DINT_DEF=123 -DSTR_DEF=\\\"ABCD-1\\\"";
+#endif
+  std::string out_str = out.str();
+  EXPECT_TRUE(out_str.find(out_str) != std::string::npos);
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, StaticLibrary) {
+  TestWithScope setup;
+  Err err;
+
+  TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY);
+  target.sources().push_back(SourceFile("//foo/input1.cc"));
+  target.config_values().arflags().push_back("--asdf");
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = libbar\n"
+      "\n"
+      "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n"
+      "\n"
+      "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o\n"
+      "  arflags = --asdf\n"
+      "  output_extension = \n"
+      "  output_dir = \n";
+  std::string out_str = out.str();
+  EXPECT_EQ(expected, out_str);
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, CompleteStaticLibrary) {
+  TestWithScope setup;
+  Err err;
+
+  TestTarget target(setup, "//foo:bar", Target::STATIC_LIBRARY);
+  target.sources().push_back(SourceFile("//foo/input1.cc"));
+  target.config_values().arflags().push_back("--asdf");
+  target.set_complete_static_lib(true);
+
+  TestTarget baz(setup, "//foo:baz", Target::STATIC_LIBRARY);
+  baz.sources().push_back(SourceFile("//foo/input2.cc"));
+
+  target.public_deps().push_back(LabelTargetPair(&baz));
+
+  ASSERT_TRUE(target.OnResolved(&err));
+  ASSERT_TRUE(baz.OnResolved(&err));
+
+  // A complete static library that depends on an incomplete static library
+  // should link in the dependent object files as if the dependent target
+  // were a source set.
+  {
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_cc =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = libbar\n"
+        "\n"
+        "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n"
+        "\n"
+        "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o "
+        "obj/foo/libbaz.input2.o || obj/foo/libbaz.a\n"
+        "  arflags = --asdf\n"
+        "  output_extension = \n"
+        "  output_dir = \n";
+    std::string out_str = out.str();
+    EXPECT_EQ(expected, out_str);
+  }
+
+  // Make the dependent static library complete.
+  baz.set_complete_static_lib(true);
+
+  // Dependent complete static libraries should not be linked directly.
+  {
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_cc =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = libbar\n"
+        "\n"
+        "build obj/foo/libbar.input1.o: cxx ../../foo/input1.cc\n"
+        "\n"
+        "build obj/foo/libbar.a: alink obj/foo/libbar.input1.o "
+        "|| obj/foo/libbaz.a\n"
+        "  arflags = --asdf\n"
+        "  output_extension = \n"
+        "  output_dir = \n";
+    std::string out_str = out.str();
+    EXPECT_EQ(expected, out_str);
+  }
+}
+
+// This tests that output extension and output dir overrides apply, and input
+// dependencies are applied.
+TEST_F(NinjaCBinaryTargetWriterTest, OutputExtensionAndInputDeps) {
+  Err err;
+  TestWithScope setup;
+
+  // An action for our library to depend on.
+  Target action(setup.settings(), Label(SourceDir("//foo/"), "action"));
+  action.set_output_type(Target::ACTION_FOREACH);
+  action.visibility().SetPublic();
+  action.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(action.OnResolved(&err));
+
+  // A shared library w/ the output_extension set to a custom value.
+  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
+  target.set_output_type(Target::SHARED_LIBRARY);
+  target.set_output_extension(std::string("so.6"));
+  target.set_output_dir(SourceDir("//out/Debug/foo/"));
+  target.sources().push_back(SourceFile("//foo/input1.cc"));
+  target.sources().push_back(SourceFile("//foo/input2.cc"));
+  target.public_deps().push_back(LabelTargetPair(&action));
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = libshlib\n"
+      "\n"
+      "build obj/foo/libshlib.input1.o: cxx ../../foo/input1.cc"
+      " || obj/foo/action.stamp\n"
+      "build obj/foo/libshlib.input2.o: cxx ../../foo/input2.cc"
+      " || obj/foo/action.stamp\n"
+      "\n"
+      "build ./libshlib.so.6: solink obj/foo/libshlib.input1.o "
+      // The order-only dependency here is stricly unnecessary since the
+      // sources list this as an order-only dep. See discussion in the code
+      // that writes this.
+      "obj/foo/libshlib.input2.o || obj/foo/action.stamp\n"
+      "  ldflags =\n"
+      "  libs =\n"
+      "  output_extension = .so.6\n"
+      "  output_dir = foo\n";
+
+  std::string out_str = out.str();
+  EXPECT_EQ(expected, out_str);
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, NoHardDepsToNoPublicHeaderTarget) {
+  Err err;
+  TestWithScope setup;
+
+  SourceFile generated_file("//out/Debug/generated.cc");
+
+  // An action does code generation.
+  Target action(setup.settings(), Label(SourceDir("//foo/"), "generate"));
+  action.set_output_type(Target::ACTION);
+  action.visibility().SetPublic();
+  action.SetToolchain(setup.toolchain());
+  action.set_output_dir(SourceDir("//out/Debug/foo/"));
+  action.action_values().outputs() =
+      SubstitutionList::MakeForTest("//out/Debug/generated.cc");
+  ASSERT_TRUE(action.OnResolved(&err));
+
+  // A source set compiling geneated code, this target does not publicize any
+  // headers.
+  Target gen_obj(setup.settings(), Label(SourceDir("//foo/"), "gen_obj"));
+  gen_obj.set_output_type(Target::SOURCE_SET);
+  gen_obj.set_output_dir(SourceDir("//out/Debug/foo/"));
+  gen_obj.sources().push_back(generated_file);
+  gen_obj.visibility().SetPublic();
+  gen_obj.private_deps().push_back(LabelTargetPair(&action));
+  gen_obj.set_all_headers_public(false);
+  gen_obj.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(gen_obj.OnResolved(&err));
+
+  std::ostringstream obj_out;
+  NinjaCBinaryTargetWriter obj_writer(&gen_obj, obj_out);
+  obj_writer.Run();
+
+  const char obj_expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = gen_obj\n"
+      "\n"
+      "build obj/out/Debug/gen_obj.generated.o: cxx generated.cc"
+      " || obj/foo/generate.stamp\n"
+      "\n"
+      "build obj/foo/gen_obj.stamp: stamp obj/out/Debug/gen_obj.generated.o"
+      // The order-only dependency here is strictly unnecessary since the
+      // sources list this as an order-only dep.
+      " || obj/foo/generate.stamp\n";
+
+  std::string obj_str = obj_out.str();
+  EXPECT_EQ(obj_expected, obj_str);
+
+  // A shared library depends on gen_obj, having corresponding header for
+  // generated obj.
+  Target gen_lib(setup.settings(), Label(SourceDir("//foo/"), "gen_lib"));
+  gen_lib.set_output_type(Target::SHARED_LIBRARY);
+  gen_lib.set_output_dir(SourceDir("//out/Debug/foo/"));
+  gen_lib.sources().push_back(SourceFile("//foor/generated.h"));
+  gen_lib.visibility().SetPublic();
+  gen_lib.private_deps().push_back(LabelTargetPair(&gen_obj));
+  gen_lib.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(gen_lib.OnResolved(&err));
+
+  std::ostringstream lib_out;
+  NinjaCBinaryTargetWriter lib_writer(&gen_lib, lib_out);
+  lib_writer.Run();
+
+  const char lib_expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = libgen_lib\n"
+      "\n"
+      "\n"
+      "build ./libgen_lib.so: solink obj/out/Debug/gen_obj.generated.o"
+      // The order-only dependency here is strictly unnecessary since
+      // obj/out/Debug/gen_obj.generated.o has dependency to
+      // obj/foo/gen_obj.stamp
+      " || obj/foo/gen_obj.stamp\n"
+      "  ldflags =\n"
+      "  libs =\n"
+      "  output_extension = .so\n"
+      "  output_dir = foo\n";
+
+  std::string lib_str = lib_out.str();
+  EXPECT_EQ(lib_expected, lib_str);
+
+  // An executable depends on gen_lib.
+  Target executable(setup.settings(),
+                    Label(SourceDir("//foo/"), "final_target"));
+  executable.set_output_type(Target::EXECUTABLE);
+  executable.set_output_dir(SourceDir("//out/Debug/foo/"));
+  executable.sources().push_back(SourceFile("//foo/main.cc"));
+  executable.private_deps().push_back(LabelTargetPair(&gen_lib));
+  executable.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(executable.OnResolved(&err)) << err.message();
+
+  std::ostringstream final_out;
+  NinjaCBinaryTargetWriter final_writer(&executable, final_out);
+  final_writer.Run();
+
+  // There is no order only dependency to action target.
+  const char final_expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = final_target\n"
+      "\n"
+      "build obj/foo/final_target.main.o: cxx ../../foo/main.cc\n"
+      "\n"
+      "build ./final_target: link obj/foo/final_target.main.o"
+      " ./libgen_lib.so\n"
+      "  ldflags =\n"
+      "  libs =\n"
+      "  output_extension = \n"
+      "  output_dir = foo\n";
+
+  std::string final_str = final_out.str();
+  EXPECT_EQ(final_expected, final_str);
+}
+
+// Tests libs are applied.
+TEST_F(NinjaCBinaryTargetWriterTest, LibsAndLibDirs) {
+  Err err;
+  TestWithScope setup;
+
+  // A shared library w/ libs and lib_dirs.
+  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
+  target.set_output_type(Target::SHARED_LIBRARY);
+  target.config_values().libs().push_back(LibFile(SourceFile("//foo/lib1.a")));
+  target.config_values().libs().push_back(LibFile("foo"));
+  target.config_values().lib_dirs().push_back(SourceDir("//foo/bar/"));
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = libshlib\n"
+      "\n"
+      "\n"
+      "build ./libshlib.so: solink | ../../foo/lib1.a\n"
+      "  ldflags = -L../../foo/bar\n"
+      "  libs = ../../foo/lib1.a -lfoo\n"
+      "  output_extension = .so\n"
+      "  output_dir = \n";
+
+  std::string out_str = out.str();
+  EXPECT_EQ(expected, out_str);
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, EmptyOutputExtension) {
+  Err err;
+  TestWithScope setup;
+
+  // This test is the same as OutputExtensionAndInputDeps, except that we call
+  // set_output_extension("") and ensure that we get an empty one and override
+  // the output prefix so that the name matches the target exactly.
+  Target target(setup.settings(), Label(SourceDir("//foo/"), "shlib"));
+  target.set_output_type(Target::SHARED_LIBRARY);
+  target.set_output_prefix_override(true);
+  target.set_output_extension(std::string());
+  target.sources().push_back(SourceFile("//foo/input1.cc"));
+  target.sources().push_back(SourceFile("//foo/input2.cc"));
+
+  target.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(target.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&target, out);
+  writer.Run();
+
+  const char expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = shlib\n"
+      "\n"
+      "build obj/foo/shlib.input1.o: cxx ../../foo/input1.cc\n"
+      "build obj/foo/shlib.input2.o: cxx ../../foo/input2.cc\n"
+      "\n"
+      "build ./shlib: solink obj/foo/shlib.input1.o "
+      "obj/foo/shlib.input2.o\n"
+      "  ldflags =\n"
+      "  libs =\n"
+      "  output_extension = \n"
+      "  output_dir = \n";
+
+  std::string out_str = out.str();
+  EXPECT_EQ(expected, out_str);
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, SourceSetDataDeps) {
+  Err err;
+  TestWithScope setup;
+
+  // This target is a data (runtime) dependency of the intermediate target.
+  Target data(setup.settings(), Label(SourceDir("//foo/"), "data_target"));
+  data.set_output_type(Target::EXECUTABLE);
+  data.visibility().SetPublic();
+  data.SetToolchain(setup.toolchain());
+  ASSERT_TRUE(data.OnResolved(&err));
+
+  // Intermediate source set target.
+  Target inter(setup.settings(), Label(SourceDir("//foo/"), "inter"));
+  inter.set_output_type(Target::SOURCE_SET);
+  inter.visibility().SetPublic();
+  inter.data_deps().push_back(LabelTargetPair(&data));
+  inter.SetToolchain(setup.toolchain());
+  inter.sources().push_back(SourceFile("//foo/inter.cc"));
+  ASSERT_TRUE(inter.OnResolved(&err)) << err.message();
+
+  // Write out the intermediate target.
+  std::ostringstream inter_out;
+  NinjaCBinaryTargetWriter inter_writer(&inter, inter_out);
+  inter_writer.Run();
+
+  // The intermediate source set will be a stamp file that depends on the
+  // object files, and will have an order-only dependency on its data dep and
+  // data file.
+  const char inter_expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = inter\n"
+      "\n"
+      "build obj/foo/inter.inter.o: cxx ../../foo/inter.cc\n"
+      "\n"
+      "build obj/foo/inter.stamp: stamp obj/foo/inter.inter.o || "
+      "./data_target\n";
+  EXPECT_EQ(inter_expected, inter_out.str());
+
+  // Final target.
+  Target exe(setup.settings(), Label(SourceDir("//foo/"), "exe"));
+  exe.set_output_type(Target::EXECUTABLE);
+  exe.public_deps().push_back(LabelTargetPair(&inter));
+  exe.SetToolchain(setup.toolchain());
+  exe.sources().push_back(SourceFile("//foo/final.cc"));
+  ASSERT_TRUE(exe.OnResolved(&err));
+
+  std::ostringstream final_out;
+  NinjaCBinaryTargetWriter final_writer(&exe, final_out);
+  final_writer.Run();
+
+  // The final output depends on both object files (one from the final target,
+  // one from the source set) and has an order-only dependency on the source
+  // set's stamp file and the final target's data file. The source set stamp
+  // dependency will create an implicit order-only dependency on the data
+  // target.
+  const char final_expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = exe\n"
+      "\n"
+      "build obj/foo/exe.final.o: cxx ../../foo/final.cc\n"
+      "\n"
+      "build ./exe: link obj/foo/exe.final.o obj/foo/inter.inter.o || "
+      "obj/foo/inter.stamp\n"
+      "  ldflags =\n"
+      "  libs =\n"
+      "  output_extension = \n"
+      "  output_dir = \n";
+  EXPECT_EQ(final_expected, final_out.str());
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, SharedLibraryModuleDefinitionFile) {
+  Err err;
+  TestWithScope setup;
+
+  Target shared_lib(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+  shared_lib.set_output_type(Target::SHARED_LIBRARY);
+  shared_lib.SetToolchain(setup.toolchain());
+  shared_lib.sources().push_back(SourceFile("//foo/sources.cc"));
+  shared_lib.sources().push_back(SourceFile("//foo/bar.def"));
+  ASSERT_TRUE(shared_lib.OnResolved(&err));
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&shared_lib, out);
+  writer.Run();
+
+  const char expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = libbar\n"
+      "\n"
+      "build obj/foo/libbar.sources.o: cxx ../../foo/sources.cc\n"
+      "\n"
+      "build ./libbar.so: solink obj/foo/libbar.sources.o | ../../foo/bar.def\n"
+      "  ldflags = /DEF:../../foo/bar.def\n"
+      "  libs =\n"
+      "  output_extension = .so\n"
+      "  output_dir = \n";
+  EXPECT_EQ(expected, out.str());
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, LoadableModule) {
+  Err err;
+  TestWithScope setup;
+
+  Target loadable_module(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+  loadable_module.set_output_type(Target::LOADABLE_MODULE);
+  loadable_module.visibility().SetPublic();
+  loadable_module.SetToolchain(setup.toolchain());
+  loadable_module.sources().push_back(SourceFile("//foo/sources.cc"));
+  ASSERT_TRUE(loadable_module.OnResolved(&err)) << err.message();
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&loadable_module, out);
+  writer.Run();
+
+  const char loadable_expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = libbar\n"
+      "\n"
+      "build obj/foo/libbar.sources.o: cxx ../../foo/sources.cc\n"
+      "\n"
+      "build ./libbar.so: solink_module obj/foo/libbar.sources.o\n"
+      "  ldflags =\n"
+      "  libs =\n"
+      "  output_extension = .so\n"
+      "  output_dir = \n";
+  EXPECT_EQ(loadable_expected, out.str());
+
+  // Final target.
+  Target exe(setup.settings(), Label(SourceDir("//foo/"), "exe"));
+  exe.set_output_type(Target::EXECUTABLE);
+  exe.public_deps().push_back(LabelTargetPair(&loadable_module));
+  exe.SetToolchain(setup.toolchain());
+  exe.sources().push_back(SourceFile("//foo/final.cc"));
+  ASSERT_TRUE(exe.OnResolved(&err)) << err.message();
+
+  std::ostringstream final_out;
+  NinjaCBinaryTargetWriter final_writer(&exe, final_out);
+  final_writer.Run();
+
+  // The final output depends on the loadable module so should have an
+  // order-only dependency on the loadable modules's output file.
+  const char final_expected[] =
+      "defines =\n"
+      "include_dirs =\n"
+      "cflags =\n"
+      "cflags_cc =\n"
+      "root_out_dir = .\n"
+      "target_out_dir = obj/foo\n"
+      "target_output_name = exe\n"
+      "\n"
+      "build obj/foo/exe.final.o: cxx ../../foo/final.cc\n"
+      "\n"
+      "build ./exe: link obj/foo/exe.final.o || ./libbar.so\n"
+      "  ldflags =\n"
+      "  libs =\n"
+      "  output_extension = \n"
+      "  output_dir = \n";
+  EXPECT_EQ(final_expected, final_out.str());
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, WinPrecompiledHeaders) {
+  Err err;
+
+  // This setup's toolchain does not have precompiled headers defined.
+  TestWithScope setup;
+
+  // A precompiled header toolchain.
+  Settings pch_settings(setup.build_settings(), "withpch/");
+  Toolchain pch_toolchain(&pch_settings,
+                          Label(SourceDir("//toolchain/"), "withpch"));
+  pch_settings.set_toolchain_label(pch_toolchain.label());
+  pch_settings.set_default_toolchain_label(setup.toolchain()->label());
+
+  // Declare a C++ compiler that supports PCH.
+  std::unique_ptr<Tool> cxx = std::make_unique<CTool>(CTool::kCToolCxx);
+  CTool* cxx_tool = cxx->AsC();
+  TestWithScope::SetCommandForTool(
+      "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
+      "-o {{output}}",
+      cxx_tool);
+  cxx_tool->set_outputs(SubstitutionList::MakeForTest(
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
+  cxx_tool->set_precompiled_header_type(CTool::PCH_MSVC);
+  pch_toolchain.SetTool(std::move(cxx));
+
+  // Add a C compiler as well.
+  std::unique_ptr<Tool> cc = std::make_unique<CTool>(CTool::kCToolCc);
+  CTool* cc_tool = cc->AsC();
+  TestWithScope::SetCommandForTool(
+      "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
+      "-o {{output}}",
+      cc_tool);
+  cc_tool->set_outputs(SubstitutionList::MakeForTest(
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
+  cc_tool->set_precompiled_header_type(CTool::PCH_MSVC);
+  pch_toolchain.SetTool(std::move(cc));
+  pch_toolchain.ToolchainSetupComplete();
+
+  // This target doesn't specify precompiled headers.
+  {
+    Target no_pch_target(&pch_settings,
+                         Label(SourceDir("//foo/"), "no_pch_target"));
+    no_pch_target.set_output_type(Target::SOURCE_SET);
+    no_pch_target.visibility().SetPublic();
+    no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
+    no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
+    no_pch_target.config_values().cflags_c().push_back("-std=c99");
+    no_pch_target.SetToolchain(&pch_toolchain);
+    ASSERT_TRUE(no_pch_target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&no_pch_target, out);
+    writer.Run();
+
+    const char no_pch_expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_c = -std=c99\n"
+        "cflags_cc =\n"
+        "target_output_name = no_pch_target\n"
+        "\n"
+        "build withpch/obj/foo/no_pch_target.input1.o: "
+        "withpch_cxx ../../foo/input1.cc\n"
+        "build withpch/obj/foo/no_pch_target.input2.o: "
+        "withpch_cc ../../foo/input2.c\n"
+        "\n"
+        "build withpch/obj/foo/no_pch_target.stamp: "
+        "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
+        "withpch/obj/foo/no_pch_target.input2.o\n";
+    EXPECT_EQ(no_pch_expected, out.str());
+  }
+
+  // This target specifies PCH.
+  {
+    Target pch_target(&pch_settings, Label(SourceDir("//foo/"), "pch_target"));
+    pch_target.config_values().set_precompiled_header("build/precompile.h");
+    pch_target.config_values().set_precompiled_source(
+        SourceFile("//build/precompile.cc"));
+    pch_target.set_output_type(Target::SOURCE_SET);
+    pch_target.visibility().SetPublic();
+    pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
+    pch_target.sources().push_back(SourceFile("//foo/input2.c"));
+    pch_target.SetToolchain(&pch_toolchain);
+    ASSERT_TRUE(pch_target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&pch_target, out);
+    writer.Run();
+
+    const char pch_win_expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        // It should output language-specific pch files.
+        "cflags_c = /Fpwithpch/obj/foo/pch_target_c.pch "
+        "/Yubuild/precompile.h\n"
+        "cflags_cc = /Fpwithpch/obj/foo/pch_target_cc.pch "
+        "/Yubuild/precompile.h\n"
+        "target_output_name = pch_target\n"
+        "\n"
+        // Compile the precompiled source files with /Yc.
+        "build withpch/obj/build/pch_target.precompile.c.o: "
+        "withpch_cc ../../build/precompile.cc\n"
+        "  cflags_c = ${cflags_c} /Ycbuild/precompile.h\n"
+        "\n"
+        "build withpch/obj/build/pch_target.precompile.cc.o: "
+        "withpch_cxx ../../build/precompile.cc\n"
+        "  cflags_cc = ${cflags_cc} /Ycbuild/precompile.h\n"
+        "\n"
+        "build withpch/obj/foo/pch_target.input1.o: "
+        "withpch_cxx ../../foo/input1.cc | "
+        // Explicit dependency on the PCH build step.
+        "withpch/obj/build/pch_target.precompile.cc.o\n"
+        "build withpch/obj/foo/pch_target.input2.o: "
+        "withpch_cc ../../foo/input2.c | "
+        // Explicit dependency on the PCH build step.
+        "withpch/obj/build/pch_target.precompile.c.o\n"
+        "\n"
+        "build withpch/obj/foo/pch_target.stamp: withpch_stamp "
+        "withpch/obj/foo/pch_target.input1.o "
+        "withpch/obj/foo/pch_target.input2.o "
+        // The precompiled object files were added to the outputs.
+        "withpch/obj/build/pch_target.precompile.c.o "
+        "withpch/obj/build/pch_target.precompile.cc.o\n";
+    EXPECT_EQ(pch_win_expected, out.str());
+  }
+}
+
+TEST_F(NinjaCBinaryTargetWriterTest, GCCPrecompiledHeaders) {
+  Err err;
+
+  // This setup's toolchain does not have precompiled headers defined.
+  TestWithScope setup;
+
+  // A precompiled header toolchain.
+  Settings pch_settings(setup.build_settings(), "withpch/");
+  Toolchain pch_toolchain(&pch_settings,
+                          Label(SourceDir("//toolchain/"), "withpch"));
+  pch_settings.set_toolchain_label(pch_toolchain.label());
+  pch_settings.set_default_toolchain_label(setup.toolchain()->label());
+
+  // Declare a C++ compiler that supports PCH.
+  std::unique_ptr<Tool> cxx = std::make_unique<CTool>(CTool::kCToolCxx);
+  CTool* cxx_tool = cxx->AsC();
+  TestWithScope::SetCommandForTool(
+      "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
+      "-o {{output}}",
+      cxx_tool);
+  cxx_tool->set_outputs(SubstitutionList::MakeForTest(
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
+  cxx_tool->set_precompiled_header_type(CTool::PCH_GCC);
+  pch_toolchain.SetTool(std::move(cxx));
+  pch_toolchain.ToolchainSetupComplete();
+
+  // Add a C compiler as well.
+  std::unique_ptr<Tool> cc = std::make_unique<CTool>(CTool::kCToolCc);
+  CTool* cc_tool = cc->AsC();
+  TestWithScope::SetCommandForTool(
+      "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
+      "-o {{output}}",
+      cc_tool);
+  cc_tool->set_outputs(SubstitutionList::MakeForTest(
+      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
+  cc_tool->set_precompiled_header_type(CTool::PCH_GCC);
+  pch_toolchain.SetTool(std::move(cc));
+  pch_toolchain.ToolchainSetupComplete();
+
+  // This target doesn't specify precompiled headers.
+  {
+    Target no_pch_target(&pch_settings,
+                         Label(SourceDir("//foo/"), "no_pch_target"));
+    no_pch_target.set_output_type(Target::SOURCE_SET);
+    no_pch_target.visibility().SetPublic();
+    no_pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
+    no_pch_target.sources().push_back(SourceFile("//foo/input2.c"));
+    no_pch_target.config_values().cflags_c().push_back("-std=c99");
+    no_pch_target.SetToolchain(&pch_toolchain);
+    ASSERT_TRUE(no_pch_target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&no_pch_target, out);
+    writer.Run();
+
+    const char no_pch_expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_c = -std=c99\n"
+        "cflags_cc =\n"
+        "target_output_name = no_pch_target\n"
+        "\n"
+        "build withpch/obj/foo/no_pch_target.input1.o: "
+        "withpch_cxx ../../foo/input1.cc\n"
+        "build withpch/obj/foo/no_pch_target.input2.o: "
+        "withpch_cc ../../foo/input2.c\n"
+        "\n"
+        "build withpch/obj/foo/no_pch_target.stamp: "
+        "withpch_stamp withpch/obj/foo/no_pch_target.input1.o "
+        "withpch/obj/foo/no_pch_target.input2.o\n";
+    EXPECT_EQ(no_pch_expected, out.str());
+  }
+
+  // This target specifies PCH.
+  {
+    Target pch_target(&pch_settings, Label(SourceDir("//foo/"), "pch_target"));
+    pch_target.config_values().set_precompiled_source(
+        SourceFile("//build/precompile.h"));
+    pch_target.config_values().cflags_c().push_back("-std=c99");
+    pch_target.set_output_type(Target::SOURCE_SET);
+    pch_target.visibility().SetPublic();
+    pch_target.sources().push_back(SourceFile("//foo/input1.cc"));
+    pch_target.sources().push_back(SourceFile("//foo/input2.c"));
+    pch_target.SetToolchain(&pch_toolchain);
+    ASSERT_TRUE(pch_target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&pch_target, out);
+    writer.Run();
+
+    const char pch_gcc_expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_c = -std=c99 "
+        "-include withpch/obj/build/pch_target.precompile.h-c\n"
+        "cflags_cc = -include withpch/obj/build/pch_target.precompile.h-cc\n"
+        "target_output_name = pch_target\n"
+        "\n"
+        // Compile the precompiled sources with -x <lang>.
+        "build withpch/obj/build/pch_target.precompile.h-c.gch: "
+        "withpch_cc ../../build/precompile.h\n"
+        "  cflags_c = -std=c99 -x c-header\n"
+        "\n"
+        "build withpch/obj/build/pch_target.precompile.h-cc.gch: "
+        "withpch_cxx ../../build/precompile.h\n"
+        "  cflags_cc = -x c++-header\n"
+        "\n"
+        "build withpch/obj/foo/pch_target.input1.o: "
+        "withpch_cxx ../../foo/input1.cc | "
+        // Explicit dependency on the PCH build step.
+        "withpch/obj/build/pch_target.precompile.h-cc.gch\n"
+        "build withpch/obj/foo/pch_target.input2.o: "
+        "withpch_cc ../../foo/input2.c | "
+        // Explicit dependency on the PCH build step.
+        "withpch/obj/build/pch_target.precompile.h-c.gch\n"
+        "\n"
+        "build withpch/obj/foo/pch_target.stamp: "
+        "withpch_stamp withpch/obj/foo/pch_target.input1.o "
+        "withpch/obj/foo/pch_target.input2.o\n";
+    EXPECT_EQ(pch_gcc_expected, out.str());
+  }
+}
+
+// Should throw an error with the scheduler if a duplicate object file exists.
+// This is dependent on the toolchain's object file mapping.
+TEST_F(NinjaCBinaryTargetWriterTest, DupeObjFileError) {
+  TestWithScope setup;
+  TestTarget target(setup, "//foo:bar", Target::EXECUTABLE);
+  target.sources().push_back(SourceFile("//a.cc"));
+  target.sources().push_back(SourceFile("//a.cc"));
+
+  EXPECT_FALSE(scheduler().is_failed());
+
+  scheduler().SuppressOutputForTesting(true);
+
+  std::ostringstream out;
+  NinjaCBinaryTargetWriter writer(&target, out);
+  writer.Run();
+
+  scheduler().SuppressOutputForTesting(false);
+
+  // Should have issued an error.
+  EXPECT_TRUE(scheduler().is_failed());
+}
+
+// This tests that output extension and output dir overrides apply, and input
+// dependencies are applied.
+TEST_F(NinjaCBinaryTargetWriterTest, InputFiles) {
+  Err err;
+  TestWithScope setup;
+
+  // This target has one input.
+  {
+    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+    target.set_output_type(Target::SOURCE_SET);
+    target.visibility().SetPublic();
+    target.sources().push_back(SourceFile("//foo/input1.cc"));
+    target.sources().push_back(SourceFile("//foo/input2.cc"));
+    target.config_values().inputs().push_back(SourceFile("//foo/input.data"));
+    target.SetToolchain(setup.toolchain());
+    ASSERT_TRUE(target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_cc =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = bar\n"
+        "\n"
+        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc"
+        " | ../../foo/input.data\n"
+        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc"
+        " | ../../foo/input.data\n"
+        "\n"
+        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
+        "obj/foo/bar.input2.o\n";
+
+    EXPECT_EQ(expected, out.str());
+  }
+
+  // This target has one input but no source files.
+  {
+    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+    target.set_output_type(Target::SHARED_LIBRARY);
+    target.visibility().SetPublic();
+    target.config_values().inputs().push_back(SourceFile("//foo/input.data"));
+    target.SetToolchain(setup.toolchain());
+    ASSERT_TRUE(target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = libbar\n"
+        "\n"
+        "\n"
+        "build ./libbar.so: solink | ../../foo/input.data\n"
+        "  ldflags =\n"
+        "  libs =\n"
+        "  output_extension = .so\n"
+        "  output_dir = \n";
+
+    EXPECT_EQ(expected, out.str());
+  }
+
+  // This target has multiple inputs.
+  {
+    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+    target.set_output_type(Target::SOURCE_SET);
+    target.visibility().SetPublic();
+    target.sources().push_back(SourceFile("//foo/input1.cc"));
+    target.sources().push_back(SourceFile("//foo/input2.cc"));
+    target.config_values().inputs().push_back(SourceFile("//foo/input1.data"));
+    target.config_values().inputs().push_back(SourceFile("//foo/input2.data"));
+    target.SetToolchain(setup.toolchain());
+    ASSERT_TRUE(target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_cc =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = bar\n"
+        "\n"
+        "build obj/foo/bar.inputs.stamp: stamp"
+        " ../../foo/input1.data ../../foo/input2.data\n"
+        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc"
+        " | obj/foo/bar.inputs.stamp\n"
+        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc"
+        " | obj/foo/bar.inputs.stamp\n"
+        "\n"
+        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
+        "obj/foo/bar.input2.o\n";
+
+    EXPECT_EQ(expected, out.str());
+  }
+
+  // This target has one input itself, one from an immediate config, and one
+  // from a config tacked on to said config.
+  {
+    Config far_config(setup.settings(), Label(SourceDir("//foo/"), "qux"));
+    far_config.own_values().inputs().push_back(SourceFile("//foo/input3.data"));
+    ASSERT_TRUE(far_config.OnResolved(&err));
+
+    Config config(setup.settings(), Label(SourceDir("//foo/"), "baz"));
+    config.own_values().inputs().push_back(SourceFile("//foo/input2.data"));
+    config.configs().push_back(LabelConfigPair(&far_config));
+    ASSERT_TRUE(config.OnResolved(&err));
+
+    Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
+    target.set_output_type(Target::SOURCE_SET);
+    target.visibility().SetPublic();
+    target.sources().push_back(SourceFile("//foo/input1.cc"));
+    target.sources().push_back(SourceFile("//foo/input2.cc"));
+    target.config_values().inputs().push_back(SourceFile("//foo/input1.data"));
+    target.configs().push_back(LabelConfigPair(&config));
+    target.SetToolchain(setup.toolchain());
+    ASSERT_TRUE(target.OnResolved(&err));
+
+    std::ostringstream out;
+    NinjaCBinaryTargetWriter writer(&target, out);
+    writer.Run();
+
+    const char expected[] =
+        "defines =\n"
+        "include_dirs =\n"
+        "cflags =\n"
+        "cflags_cc =\n"
+        "root_out_dir = .\n"
+        "target_out_dir = obj/foo\n"
+        "target_output_name = bar\n"
+        "\n"
+        "build obj/foo/bar.inputs.stamp: stamp"
+        " ../../foo/input1.data ../../foo/input2.data ../../foo/input3.data\n"
+        "build obj/foo/bar.input1.o: cxx ../../foo/input1.cc"
+        " | obj/foo/bar.inputs.stamp\n"
+        "build obj/foo/bar.input2.o: cxx ../../foo/input2.cc"
+        " | obj/foo/bar.inputs.stamp\n"
+        "\n"
+        "build obj/foo/bar.stamp: stamp obj/foo/bar.input1.o "
+        "obj/foo/bar.input2.o\n";
+
+    EXPECT_EQ(expected, out.str());
+  }
+}
