• 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_TARGET_WRITER_H_
6 #define TOOLS_GN_NINJA_TARGET_WRITER_H_
7 
8 #include <iosfwd>
9 
10 #include "gn/path_output.h"
11 #include "gn/resolved_target_data.h"
12 #include "gn/substitution_type.h"
13 
14 class OutputFile;
15 class Settings;
16 class Target;
17 struct SubstitutionBits;
18 
19 // Generates one target's ".ninja" file. The toplevel "build.ninja" file is
20 // generated by the NinjaBuildWriter.
21 class NinjaTargetWriter {
22  public:
23   NinjaTargetWriter(const Target* target, std::ostream& out);
24   virtual ~NinjaTargetWriter();
25 
26   // Returns a ResolvedTargetData that can be used to retrieve information
27   // from targets. The instance can be set through SetResolvedTargetData()
28   // or may be created on demand otherwise (which is useful to keep unit-tests
29   // simple).
30   const ResolvedTargetData& resolved() const;
31 
32   // Sets the ResolvedTargetData instance to return for future resolved()
33   // calls. Does not transfer ownership, and allows several NinjaTargetWriter
34   // instances to share the same cached information.
35   void SetResolvedTargetData(ResolvedTargetData* resolved);
36 
37   // Set the vector that will receive the Ninja output file paths generated
38   // by this writer. A nullptr value means no output files needs to be
39   // collected.
40   void SetNinjaOutputs(std::vector<OutputFile>* ninja_outputs);
41 
42   // Returns the build line to be written to the toolchain build file.
43   //
44   // Some targets have their rules written to separate files, and some can have
45   // their rules coalesced in the main build file. For the coalesced case, this
46   // function will return the rules as a string. For the separate file case,
47   // the separate ninja file will be written and the return string will be the
48   // subninja command to load that file.
49   //
50   // If |ninja_outputs| is not nullptr, it will be set with the list of
51   // Ninja output paths generated by the corresponding writer.
52   static std::string RunAndWriteFile(
53       const Target* target,
54       ResolvedTargetData* resolved = nullptr,
55       std::vector<OutputFile>* ninja_outputs = nullptr);
56 
57   virtual void Run() = 0;
58 
59  protected:
60   // Returns a writable pointer to resolved(). Only used internally.
61   ResolvedTargetData* GetResolvedTargetData();
62 
63   // Writes out the substitution values that are shared between the different
64   // types of tools (target gen dir, target label, etc.). Only the substitutions
65   // identified by the given bits will be written.
66   void WriteSharedVars(const SubstitutionBits& bits);
67 
68   // Writes out the substitution values that are shared between C compiler tools
69   // and action tools. Only the substitutions identified by the given bits will
70   // be written.
71   // If respect_source_used is set, the generated substitution values will
72   // respect the types of source code used; otherwise they will respect the bits
73   // passed in.
74   void WriteCCompilerVars(const SubstitutionBits& bits,
75                           bool indent,
76                           bool respect_source_used);
77 
78   // Writes out the substitution values that are shared between Rust tools
79   // and action tools. Only the substitutions identified by the given bits will
80   // be written, unless 'always_write' is specified.
81   void WriteRustCompilerVars(const SubstitutionBits& bits,
82                              bool indent,
83                              bool always_write);
84 
85   // Writes to the output stream a stamp rule for input dependencies, and
86   // returns the file to be appended to source rules that encodes the
87   // order-only dependencies for the current target.
88   // If num_stamp_uses is small, this might return all input dependencies
89   // directly, without writing a stamp file.
90   // If there are no implicit dependencies and no additional target dependencies
91   // are passed in, this returns an empty vector.
92   std::vector<OutputFile> WriteInputDepsStampAndGetDep(
93       const std::vector<const Target*>& additional_hard_deps,
94       size_t num_stamp_uses) const;
95 
96   // Writes to the output file a final stamp rule for the target that stamps
97   // the given list of files. This function assumes the stamp is for the target
98   // as a whole so the stamp file is set as the target's dependency output.
99   void WriteStampForTarget(const std::vector<OutputFile>& deps,
100                            const std::vector<OutputFile>& order_only_deps);
101 
102   const Settings* settings_;  // Non-owning.
103   const Target* target_;      // Non-owning.
104   std::ostream& out_;
105   PathOutput path_output_;
106 
107   // Write a Ninja output file to out_, and also add it to |*ninja_outputs_|
108   // if needed.
109   void WriteOutput(const OutputFile& output) const;
110   void WriteOutput(OutputFile&& output) const;
111 
112   // Same as WriteOutput() for a list of Ninja output file paths.
113   void WriteOutputs(const std::vector<OutputFile>& outputs) const;
114   void WriteOutputs(std::vector<OutputFile>&& outputs) const;
115 
116   // The list of all Ninja output file paths generated by this writer for
117   // this target. Used to implement the --ide=ninja_outputs `gn gen` flag.
118   // Needs to be mutable because WriteOutput() and WriteOutputs() need to
119   // be const.
120   mutable std::vector<OutputFile>* ninja_outputs_ = nullptr;
121 
122   // The ResolvedTargetData instance can be set through SetResolvedTargetData()
123   // or it will be created lazily when resolved() is called, hence the need
124   // for 'mutable' here.
125   mutable ResolvedTargetData* resolved_ptr_ = nullptr;
126   mutable std::unique_ptr<ResolvedTargetData> resolved_owned_;
127 
128  private:
129   void WriteCopyRules();
130   void WriteEscapedSubstitution(const Substitution* type);
131 
132   NinjaTargetWriter(const NinjaTargetWriter&) = delete;
133   NinjaTargetWriter& operator=(const NinjaTargetWriter&) = delete;
134 };
135 
136 #endif  // TOOLS_GN_NINJA_TARGET_WRITER_H_
137