• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 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_TOOL_H_
6 #define TOOLS_GN_TOOL_H_
7 
8 #include <string>
9 
10 #include "base/logging.h"
11 #include "gn/label.h"
12 #include "gn/label_ptr.h"
13 #include "gn/scope.h"
14 #include "gn/source_file.h"
15 #include "gn/substitution_list.h"
16 #include "gn/substitution_pattern.h"
17 
18 class ParseNode;
19 class Pool;
20 class Target;
21 class Toolchain;
22 
23 class CTool;
24 class GeneralTool;
25 class RustTool;
26 class BuiltinTool;
27 
28 // To add a new Tool category, create a subclass implementing SetComplete()
29 // Add a new category to ToolCategories
30 // Add a GetAs* function
31 class Tool {
32  public:
33   static const char* kToolNone;
34 
35   virtual ~Tool();
36 
37   // Manual RTTI and required functions ---------------------------------------
38   //
39   // To implement a new tool category to compile binaries in a different way,
40   // inherit this class, implement the following functions, and add the
41   // appropriate ToolTypes and RTTI getters. New tools will also need to
42   // implement a corresponding class inheriting NinjaBinaryTargetWriter that
43   // does the actual rule writing.
44 
45   // Initialize tool from a scope. Child classes should override this function
46   // and call the parent.
47   bool InitTool(Scope* block_scope, Toolchain* toolchain, Err* err);
48 
49   // Validate the char* passed to the creation.
50   virtual bool ValidateName(const char* name) const = 0;
51 
52   // Called when the toolchain is saving this tool, after everything is filled
53   // in.
54   virtual void SetComplete() = 0;
55 
56   // Validate substitutions in this tool.
57   virtual bool ValidateSubstitution(const Substitution* sub_type) const = 0;
58 
59   // Manual RTTI
60   virtual CTool* AsC();
61   virtual const CTool* AsC() const;
62   virtual GeneralTool* AsGeneral();
63   virtual const GeneralTool* AsGeneral() const;
64   virtual RustTool* AsRust();
65   virtual const RustTool* AsRust() const;
66   virtual BuiltinTool* AsBuiltin();
67   virtual const BuiltinTool* AsBuiltin() const;
68 
69   // Basic information ---------------------------------------------------------
70 
defined_from()71   const ParseNode* defined_from() const { return defined_from_; }
set_defined_from(const ParseNode * df)72   void set_defined_from(const ParseNode* df) { defined_from_ = df; }
73 
name()74   const char* name() const { return name_; }
75 
76   // Getters/setters ----------------------------------------------------------
77   //
78   // After the tool has had its attributes set, the caller must call
79   // SetComplete(), at which point no other changes can be made.
80 
81   // Command to run.
command()82   const SubstitutionPattern& command() const { return command_; }
set_command(SubstitutionPattern cmd)83   void set_command(SubstitutionPattern cmd) {
84     DCHECK(!complete_);
85     command_ = std::move(cmd);
86   }
87 
88   // Launcher for the command (e.g. goma)
command_launcher()89   const std::string& command_launcher() const { return command_launcher_; }
set_command_launcher(std::string l)90   void set_command_launcher(std::string l) {
91     DCHECK(!complete_);
92     command_launcher_ = std::move(l);
93   }
94 
95   // Should include a leading "." if nonempty.
default_output_extension()96   const std::string& default_output_extension() const {
97     return default_output_extension_;
98   }
set_default_output_extension(std::string ext)99   void set_default_output_extension(std::string ext) {
100     DCHECK(!complete_);
101     DCHECK(ext.empty() || ext[0] == '.');
102     default_output_extension_ = std::move(ext);
103   }
104 
default_output_dir()105   const SubstitutionPattern& default_output_dir() const {
106     return default_output_dir_;
107   }
set_default_output_dir(SubstitutionPattern dir)108   void set_default_output_dir(SubstitutionPattern dir) {
109     DCHECK(!complete_);
110     default_output_dir_ = std::move(dir);
111   }
112 
113   // Dependency file (if supported).
depfile()114   const SubstitutionPattern& depfile() const { return depfile_; }
set_depfile(SubstitutionPattern df)115   void set_depfile(SubstitutionPattern df) {
116     DCHECK(!complete_);
117     depfile_ = std::move(df);
118   }
119 
description()120   const SubstitutionPattern& description() const { return description_; }
set_description(SubstitutionPattern desc)121   void set_description(SubstitutionPattern desc) {
122     DCHECK(!complete_);
123     description_ = std::move(desc);
124   }
125 
framework_switch()126   const std::string& framework_switch() const { return framework_switch_; }
set_framework_switch(std::string s)127   void set_framework_switch(std::string s) {
128     DCHECK(!complete_);
129     framework_switch_ = std::move(s);
130   }
131 
weak_framework_switch()132   const std::string& weak_framework_switch() const {
133     return weak_framework_switch_;
134   }
set_weak_framework_switch(std::string s)135   void set_weak_framework_switch(std::string s) {
136     DCHECK(!complete_);
137     weak_framework_switch_ = std::move(s);
138   }
139 
framework_dir_switch()140   const std::string& framework_dir_switch() const {
141     return framework_dir_switch_;
142   }
set_framework_dir_switch(std::string s)143   void set_framework_dir_switch(std::string s) {
144     DCHECK(!complete_);
145     framework_dir_switch_ = std::move(s);
146   }
147 
lib_switch()148   const std::string& lib_switch() const { return lib_switch_; }
set_lib_switch(std::string s)149   void set_lib_switch(std::string s) {
150     DCHECK(!complete_);
151     lib_switch_ = std::move(s);
152   }
153 
lib_dir_switch()154   const std::string& lib_dir_switch() const { return lib_dir_switch_; }
set_lib_dir_switch(std::string s)155   void set_lib_dir_switch(std::string s) {
156     DCHECK(!complete_);
157     lib_dir_switch_ = std::move(s);
158   }
159 
swiftmodule_switch()160   const std::string& swiftmodule_switch() const { return swiftmodule_switch_; }
set_swiftmodule_switch(std::string s)161   void set_swiftmodule_switch(std::string s) {
162     DCHECK(!complete_);
163     swiftmodule_switch_ = std::move(s);
164   }
165 
linker_arg()166   const std::string& linker_arg() const { return linker_arg_; }
set_linker_arg(std::string s)167   void set_linker_arg(std::string s) {
168     DCHECK(!complete_);
169     linker_arg_ = std::move(s);
170   }
171 
outputs()172   const SubstitutionList& outputs() const { return outputs_; }
set_outputs(SubstitutionList out)173   void set_outputs(SubstitutionList out) {
174     DCHECK(!complete_);
175     outputs_ = std::move(out);
176   }
177 
partial_outputs()178   const SubstitutionList& partial_outputs() const { return partial_outputs_; }
set_partial_outputs(SubstitutionList partial_out)179   void set_partial_outputs(SubstitutionList partial_out) {
180     DCHECK(!complete_);
181     partial_outputs_ = std::move(partial_out);
182   }
183 
runtime_outputs()184   const SubstitutionList& runtime_outputs() const { return runtime_outputs_; }
set_runtime_outputs(SubstitutionList run_out)185   void set_runtime_outputs(SubstitutionList run_out) {
186     DCHECK(!complete_);
187     runtime_outputs_ = std::move(run_out);
188   }
189 
output_prefix()190   const std::string& output_prefix() const { return output_prefix_; }
set_output_prefix(std::string s)191   void set_output_prefix(std::string s) {
192     DCHECK(!complete_);
193     output_prefix_ = std::move(s);
194   }
195 
restat()196   bool restat() const { return restat_; }
set_restat(bool r)197   void set_restat(bool r) {
198     DCHECK(!complete_);
199     restat_ = r;
200   }
201 
rspfile()202   const SubstitutionPattern& rspfile() const { return rspfile_; }
set_rspfile(SubstitutionPattern rsp)203   void set_rspfile(SubstitutionPattern rsp) {
204     DCHECK(!complete_);
205     rspfile_ = std::move(rsp);
206   }
207 
rspfile_content()208   const SubstitutionPattern& rspfile_content() const {
209     return rspfile_content_;
210   }
set_rspfile_content(SubstitutionPattern content)211   void set_rspfile_content(SubstitutionPattern content) {
212     DCHECK(!complete_);
213     rspfile_content_ = std::move(content);
214   }
215 
pool()216   const LabelPtrPair<Pool>& pool() const { return pool_; }
set_pool(LabelPtrPair<Pool> pool)217   void set_pool(LabelPtrPair<Pool> pool) { pool_ = std::move(pool); }
218 
219   // Other functions ----------------------------------------------------------
220 
221   // Function for the above override to call to complete the tool.
222   void SetToolComplete();
223 
224   // Substitutions required by this tool.
substitution_bits()225   const SubstitutionBits& substitution_bits() const {
226     DCHECK(complete_);
227     return substitution_bits_;
228   }
229 
230   // Create a tool based on given features.
231   static std::unique_ptr<Tool> CreateTool(const std::string& name);
232   static std::unique_ptr<Tool> CreateTool(const ParseNode* function,
233                                           const std::string& name,
234                                           Scope* scope,
235                                           Toolchain* toolchain,
236                                           Err* err);
237 
238   static const char* GetToolTypeForSourceType(SourceFile::Type type);
239 
240   static const char* GetToolTypeForTargetFinalOutput(const Target* target);
241 
242  protected:
243   explicit Tool(const char* t);
244 
245   // Initialization functions -------------------------------------------------
246   //
247   // Initialization methods used by InitTool(). If successful, will set the
248   // field and return true, otherwise will return false. Must be called before
249   // SetComplete().
250   bool IsPatternInOutputList(const SubstitutionList& output_list,
251                              const SubstitutionPattern& pattern) const;
252   bool ValidateSubstitutionList(const std::vector<const Substitution*>& list,
253                                 const Value* origin,
254                                 Err* err) const;
255   bool ValidateOutputs(Err* err) const;
256   bool ReadBool(Scope* scope, const char* var, bool* field, Err* err);
257   bool ReadString(Scope* scope, const char* var, std::string* field, Err* err);
258   bool ReadPattern(Scope* scope,
259                    const char* var,
260                    SubstitutionPattern* field,
261                    Err* err);
262   bool ReadPatternList(Scope* scope,
263                        const char* var,
264                        SubstitutionList* field,
265                        Err* err);
266   bool ReadLabel(Scope* scope,
267                  const char* var,
268                  const Label& current_toolchain,
269                  LabelPtrPair<Pool>* field,
270                  Err* err);
271   bool ReadOutputExtension(Scope* scope, Err* err);
272 
273   const ParseNode* defined_from_ = nullptr;
274   const char* name_ = nullptr;
275 
276   SubstitutionPattern command_;
277   std::string command_launcher_;
278   std::string default_output_extension_;
279   SubstitutionPattern default_output_dir_;
280   SubstitutionPattern depfile_;
281   SubstitutionPattern description_;
282   std::string framework_switch_;
283   std::string weak_framework_switch_;
284   std::string framework_dir_switch_;
285   std::string lib_switch_;
286   std::string lib_dir_switch_;
287   std::string swiftmodule_switch_;
288   std::string linker_arg_;
289   SubstitutionList outputs_;
290   SubstitutionList partial_outputs_;
291   SubstitutionList runtime_outputs_;
292   std::string output_prefix_;
293   bool restat_ = false;
294   SubstitutionPattern rspfile_;
295   SubstitutionPattern rspfile_content_;
296   LabelPtrPair<Pool> pool_;
297 
298   bool complete_ = false;
299 
300   SubstitutionBits substitution_bits_;
301 
302   Tool(const Tool&) = delete;
303   Tool& operator=(const Tool&) = delete;
304 };
305 
306 #endif  // TOOLS_GN_TOOL_H_
307