1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file.
4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/ninja_toolchain_writer.h"
6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include <fstream>
8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/file_util.h"
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/strings/stringize_macros.h"
11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/build_settings.h"
12d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/settings.h"
13d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/target.h"
14d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/toolchain.h"
15d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
16d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochNinjaToolchainWriter::NinjaToolchainWriter(
17d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const Settings* settings,
18d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const std::vector<const Target*>& targets,
19d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    std::ostream& out)
20d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    : settings_(settings),
21d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      targets_(targets),
22d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      out_(out),
23d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      path_output_(settings_->build_settings()->build_dir(),
24d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                   ESCAPE_NINJA, true),
25d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      helper_(settings->build_settings()) {
26d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
27d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
28d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochNinjaToolchainWriter::~NinjaToolchainWriter() {
29d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
30d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
31d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NinjaToolchainWriter::Run() {
32d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  WriteRules();
33d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  WriteSubninjas();
34d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
35d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
36d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static
37d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochbool NinjaToolchainWriter::RunAndWriteFile(
38d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const Settings* settings,
39d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const std::vector<const Target*>& targets) {
40d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  NinjaHelper helper(settings->build_settings());
41d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  base::FilePath ninja_file(settings->build_settings()->GetFullPath(
42d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      helper.GetNinjaFileForToolchain(settings).GetSourceFile(
43d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          settings->build_settings())));
44d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  file_util::CreateDirectory(ninja_file.DirName());
45d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
46d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::ofstream file;
47d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  file.open(FilePathToUTF8(ninja_file).c_str(),
48d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch            std::ios_base::out | std::ios_base::binary);
49d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (file.fail())
50d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return false;
51d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
52d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  NinjaToolchainWriter gen(settings, targets, file);
53d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  gen.Run();
54d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return true;
55d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
56d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
57d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NinjaToolchainWriter::WriteRules() {
58d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  const Toolchain* tc = settings_->toolchain();
59d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  std::string indent("  ");
60d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
61d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  for (int i = Toolchain::TYPE_NONE + 1; i < Toolchain::TYPE_NUMTYPES; i++) {
62d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(i);
63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    const Toolchain::Tool& tool = tc->GetTool(tool_type);
64d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (tool.empty())
65d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      continue;
66d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
67d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    out_ << "rule " << Toolchain::ToolTypeToName(tool_type) << std::endl;
68d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
69d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    #define WRITE_ARG(name) \
70d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      if (!tool.name.empty()) \
71d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch        out_ << indent << "  " STRINGIZE(name) " = " << tool.name << std::endl;
72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(command);
73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(depfile);
74d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(deps);
75d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(description);
76d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(pool);
77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(restat);
78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(rspfile);
79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    WRITE_ARG(rspfile_content);
80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    #undef WRITE_ARG
81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  out_ << std::endl;
83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochvoid NinjaToolchainWriter::WriteSubninjas() {
86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  for (size_t i = 0; i < targets_.size(); i++) {
87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (targets_[i]->output_type() != Target::NONE) {
88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      out_ << "subninja ";
89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      path_output_.WriteFile(out_, helper_.GetNinjaFileForTarget(targets_[i]));
90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      out_ << std::endl;
91d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    }
92d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
93d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  out_ << std::endl;
94d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
95