blob: c21769a572ce833f7113096b1e003a2c1cc81376 [file] [log] [blame]
// Copyright (c) 2013 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 <iosfwd>
#include <map>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "gn/path_output.h"
class Builder;
class BuildSettings;
class Err;
class Settings;
class Target;
class Toolchain;
namespace base {
class CommandLine;
} // namespace base
// Generates the toplevel "" file. This references the individual
// toolchain files and lists all input .gn files as dependencies of the
// build itself.
class NinjaBuildWriter {
NinjaBuildWriter(const BuildSettings* settings,
const std::unordered_map<const Settings*, const Toolchain*>&
const std::vector<const Target*>& all_targets,
const Toolchain* default_toolchain,
const std::vector<const Target*>& default_toolchain_targets,
std::ostream& out,
std::ostream& dep_out);
// The design of this class is that this static factory function takes the
// Builder, extracts the relevant information, and passes it to the class
// constructor. The class itself doesn't depend on the Builder at all which
// makes testing much easier (tests integrating various functions along with
// the Builder get very complicated).
static bool RunAndWriteFile(const BuildSettings* settings,
const Builder& builder,
Err* err);
// Extracts from an existing file's contents the commands
// necessary to run GN and regenerate
// The regeneration rules live at the top of the file and their
// specific contents are an internal detail of NinjaBuildWriter. Used by
// commands::PrepareForRegeneration.
// On error, returns an empty string.
static std::string ExtractRegenerationCommands(std::istream& build_ninja_in);
bool Run(Err* err);
// WriteNinjaRules writes the rules that ninja uses to regenerate its own
// build files, used whenever a build input file has changed.
// Ninja file regeneration is accomplished by two separate build statements.
// This is necessary to work around ninja's behavior of deleting all output
// files of a build edge if the edge uses a depfile and is interrupted before
// it can complete. Previously, interrupting regeneration would cause ninja to
// delete, losing any flags/build settings passed to gen
// previously and requiring the user to manually 'gen' again.
// The workaround involves misleading ninja about when the file is
// actually written. The first build statement runs the actual 'gen
// --regeneration' command, writing "" (and .d and .stamp) and
// lists the "" depfile to automatically trigger regeneration as
// needed, but does not list "" as an output. The second
// statement's stated output is "", but it simply uses the phony
// rule to refer to the first statement.
void WriteNinjaRules();
void WriteAllPools();
bool WriteSubninjas(Err* err);
bool WritePhonyAndAllRules(Err* err);
void WritePhonyRule(const Target* target, std::string_view phony_name);
const BuildSettings* build_settings_;
const std::unordered_map<const Settings*, const Toolchain*>& used_toolchains_;
const std::vector<const Target*>& all_targets_;
const Toolchain* default_toolchain_;
const std::vector<const Target*>& default_toolchain_targets_;
std::ostream& out_;
std::ostream& dep_out_;
PathOutput path_output_;
NinjaBuildWriter(const NinjaBuildWriter&) = delete;
NinjaBuildWriter& operator=(const NinjaBuildWriter&) = delete;
extern const char kNinjaRules_Help[];
// Exposed for testing.
base::CommandLine GetSelfInvocationCommandLine(
const BuildSettings* build_settings);