• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef TOOLS_GN_NINJA_BUILD_WRITER_H_
6 #define TOOLS_GN_NINJA_BUILD_WRITER_H_
7 
8 #include <iosfwd>
9 #include <map>
10 #include <string_view>
11 #include <unordered_map>
12 #include <vector>
13 
14 #include "gn/path_output.h"
15 
16 class Builder;
17 class BuildSettings;
18 class Err;
19 class Settings;
20 class Target;
21 class Toolchain;
22 
23 namespace base {
24 class CommandLine;
25 }  // namespace base
26 
27 // Generates the toplevel "build.ninja" file. This references the individual
28 // toolchain files and lists all input .gn files as dependencies of the
29 // build itself.
30 class NinjaBuildWriter {
31  public:
32   NinjaBuildWriter(const BuildSettings* settings,
33                    const std::unordered_map<const Settings*, const Toolchain*>&
34                        used_toolchains,
35                    const std::vector<const Target*>& all_targets,
36                    const Toolchain* default_toolchain,
37                    const std::vector<const Target*>& default_toolchain_targets,
38                    std::ostream& out,
39                    std::ostream& dep_out);
40   ~NinjaBuildWriter();
41 
42   // The design of this class is that this static factory function takes the
43   // Builder, extracts the relevant information, and passes it to the class
44   // constructor. The class itself doesn't depend on the Builder at all which
45   // makes testing much easier (tests integrating various functions along with
46   // the Builder get very complicated).
47   static bool RunAndWriteFile(const BuildSettings* settings,
48                               const Builder& builder,
49                               Err* err);
50 
51   // Extracts from an existing build.ninja file's contents the commands
52   // necessary to run GN and regenerate build.ninja.
53   //
54   // The regeneration rules live at the top of the build.ninja file and their
55   // specific contents are an internal detail of NinjaBuildWriter. Used by
56   // commands::PrepareForRegeneration.
57   //
58   // On error, returns an empty string.
59   static std::string ExtractRegenerationCommands(std::istream& build_ninja_in);
60 
61   bool Run(Err* err);
62 
63  private:
64   // WriteNinjaRules writes the rules that ninja uses to regenerate its own
65   // build files, used whenever a build input file has changed.
66   //
67   // Ninja file regeneration is accomplished by two separate build statements.
68   // This is necessary to work around ninja's behavior of deleting all output
69   // files of a build edge if the edge uses a depfile and is interrupted before
70   // it can complete. Previously, interrupting regeneration would cause ninja to
71   // delete build.ninja, losing any flags/build settings passed to gen
72   // previously and requiring the user to manually 'gen' again.
73   //
74   // The workaround involves misleading ninja about when the build.ninja file is
75   // actually written. The first build statement runs the actual 'gen
76   // --regeneration' command, writing "build.ninja" (and .d and .stamp) and
77   // lists the "build.ninja.d" depfile to automatically trigger regeneration as
78   // needed, but does not list "build.ninja" as an output. The second
79   // statement's stated output is "build.ninja", but it simply uses the phony
80   // rule to refer to the first statement.
81   void WriteNinjaRules();
82   void WriteAllPools();
83   bool WriteSubninjas(Err* err);
84   bool WritePhonyAndAllRules(Err* err);
85 
86   void WritePhonyRule(const Target* target, std::string_view phony_name);
87 
88   const BuildSettings* build_settings_;
89 
90   const std::unordered_map<const Settings*, const Toolchain*>& used_toolchains_;
91   const std::vector<const Target*>& all_targets_;
92   const Toolchain* default_toolchain_;
93   const std::vector<const Target*>& default_toolchain_targets_;
94 
95   std::ostream& out_;
96   std::ostream& dep_out_;
97   PathOutput path_output_;
98 
99   NinjaBuildWriter(const NinjaBuildWriter&) = delete;
100   NinjaBuildWriter& operator=(const NinjaBuildWriter&) = delete;
101 };
102 
103 extern const char kNinjaRules_Help[];
104 
105 // Exposed for testing.
106 base::CommandLine GetSelfInvocationCommandLine(
107     const BuildSettings* build_settings);
108 
109 #endif  // TOOLS_GN_NINJA_BUILD_WRITER_H_
110