1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu// Use of this source code is governed by a BSD-style license that can be
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// found in the LICENSE file.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "tools/gn/ninja_writer.h"
6221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "tools/gn/builder.h"
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "tools/gn/loader.h"
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "tools/gn/location.h"
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "tools/gn/ninja_build_writer.h"
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "tools/gn/ninja_toolchain_writer.h"
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "tools/gn/settings.h"
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectNinjaWriter::NinjaWriter(const BuildSettings* build_settings,
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                         Builder* builder)
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    : build_settings_(build_settings),
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      builder_(builder) {
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectNinjaWriter::~NinjaWriter() {
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// static
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectbool NinjaWriter::RunAndWriteFiles(const BuildSettings* build_settings,
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                   Builder* builder) {
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  NinjaWriter writer(build_settings, builder);
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<const Settings*> all_settings;
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<const Target*> default_targets;
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (!writer.WriteToolchains(&all_settings, &default_targets))
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return false;
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return writer.WriteRootBuildfiles(all_settings, default_targets);
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// static
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectbool NinjaWriter::RunAndWriteToolchainFiles(
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const BuildSettings* build_settings,
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    Builder* builder,
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    std::vector<const Settings*>* all_settings) {
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  NinjaWriter writer(build_settings, builder);
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<const Target*> default_targets;
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return writer.WriteToolchains(all_settings, &default_targets);
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectbool NinjaWriter::WriteToolchains(std::vector<const Settings*>* all_settings,
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                  std::vector<const Target*>* default_targets) {
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Categorize all targets by toolchain.
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  typedef std::map<Label, std::vector<const Target*> > CategorizedMap;
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  CategorizedMap categorized;
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<const BuilderRecord*> all_records = builder_->GetAllRecords();
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  for (size_t i = 0; i < all_records.size(); i++) {
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (all_records[i]->type() == BuilderRecord::ITEM_TARGET &&
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        all_records[i]->should_generate()) {
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      categorized[all_records[i]->label().GetToolchainLabel()].push_back(
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          all_records[i]->item()->AsTarget());
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      }
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (categorized.empty()) {
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    Err(Location(), "No targets.",
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        "I could not find any targets to write, so I'm doing nothing.")
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        .PrintToStdout();
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return false;
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  Label default_label = builder_->loader()->GetDefaultToolchain();
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Write out the toolchain buildfiles, and also accumulate the set of
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // all settings and find the list of targets in the default toolchain.
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  for (CategorizedMap::const_iterator i = categorized.begin();
71221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom       i != categorized.end(); ++i) {
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const Settings* settings =
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        builder_->loader()->GetToolchainSettings(i->first);
74221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const Toolchain* toolchain = builder_->GetToolchain(i->first);
75221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
76221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    all_settings->push_back(settings);
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!NinjaToolchainWriter::RunAndWriteFile(settings, toolchain,
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                               i->second)) {
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      Err(Location(),
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          "Couldn't open toolchain buildfile(s) for writing").PrintToStdout();
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return false;
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  *default_targets = categorized[default_label];
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  return true;
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectbool NinjaWriter::WriteRootBuildfiles(
90221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const std::vector<const Settings*>& all_settings,
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const std::vector<const Target*>& default_targets) {
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // All Settings objects should have the same default toolchain, and there
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // should always be at least one settings object in the build.
94221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  CHECK(!all_settings.empty());
95221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  const Toolchain* default_toolchain =
96221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      builder_->GetToolchain(all_settings[0]->default_toolchain_label());
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Write the root buildfile.
99221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!NinjaBuildWriter::RunAndWriteFile(build_settings_, all_settings,
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                         default_toolchain, default_targets)) {
101221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    Err(Location(),
102221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        "Couldn't open toolchain buildfile(s) for writing").PrintToStdout();
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return false;
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return true;
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom