• 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 "base/macros.h"
12 #include "gn/label.h"
13 #include "gn/label_ptr.h"
14 #include "gn/scope.h"
15 #include "gn/source_file.h"
16 #include "gn/substitution_list.h"
17 #include "gn/substitution_pattern.h"
18 
19 class ParseNode;
20 class Pool;
21 class Target;
22 class Toolchain;
23 
24 class CTool;
25 class GeneralTool;
26 class RustTool;
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 
67   // Basic information ---------------------------------------------------------
68 
defined_from()69   const ParseNode* defined_from() const { return defined_from_; }
set_defined_from(const ParseNode * df)70   void set_defined_from(const ParseNode* df) { defined_from_ = df; }
71 
name()72   const char* name() const { return name_; }
73 
74   // Getters/setters ----------------------------------------------------------
75   //
76   // After the tool has had its attributes set, the caller must call
77   // SetComplete(), at which point no other changes can be made.
78 
79   // Command to run.
command()80   const SubstitutionPattern& command() const { return command_; }
set_command(SubstitutionPattern cmd)81   void set_command(SubstitutionPattern cmd) {
82     DCHECK(!complete_);
83     command_ = std::move(cmd);
84   }
85 
86   // Launcher for the command (e.g. goma)
command_launcher()87   const std::string& command_launcher() const {
88     return command_launcher_;
89   }
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 
framework_dir_switch()132   const std::string& framework_dir_switch() const {
133     return framework_dir_switch_;
134   }
set_framework_dir_switch(std::string s)135   void set_framework_dir_switch(std::string s) {
136     DCHECK(!complete_);
137     framework_dir_switch_ = std::move(s);
138   }
139 
lib_switch()140   const std::string& lib_switch() const { return lib_switch_; }
set_lib_switch(std::string s)141   void set_lib_switch(std::string s) {
142     DCHECK(!complete_);
143     lib_switch_ = std::move(s);
144   }
145 
lib_dir_switch()146   const std::string& lib_dir_switch() const { return lib_dir_switch_; }
set_lib_dir_switch(std::string s)147   void set_lib_dir_switch(std::string s) {
148     DCHECK(!complete_);
149     lib_dir_switch_ = std::move(s);
150   }
151 
linker_arg()152   const std::string& linker_arg() const { return linker_arg_; }
set_linker_arg(std::string s)153   void set_linker_arg(std::string s) {
154     DCHECK(!complete_);
155     linker_arg_ = std::move(s);
156   }
157 
outputs()158   const SubstitutionList& outputs() const { return outputs_; }
set_outputs(SubstitutionList out)159   void set_outputs(SubstitutionList out) {
160     DCHECK(!complete_);
161     outputs_ = std::move(out);
162   }
163 
runtime_outputs()164   const SubstitutionList& runtime_outputs() const { return runtime_outputs_; }
set_runtime_outputs(SubstitutionList run_out)165   void set_runtime_outputs(SubstitutionList run_out) {
166     DCHECK(!complete_);
167     runtime_outputs_ = std::move(run_out);
168   }
169 
output_prefix()170   const std::string& output_prefix() const { return output_prefix_; }
set_output_prefix(std::string s)171   void set_output_prefix(std::string s) {
172     DCHECK(!complete_);
173     output_prefix_ = std::move(s);
174   }
175 
restat()176   bool restat() const { return restat_; }
set_restat(bool r)177   void set_restat(bool r) {
178     DCHECK(!complete_);
179     restat_ = r;
180   }
181 
rspfile()182   const SubstitutionPattern& rspfile() const { return rspfile_; }
set_rspfile(SubstitutionPattern rsp)183   void set_rspfile(SubstitutionPattern rsp) {
184     DCHECK(!complete_);
185     rspfile_ = std::move(rsp);
186   }
187 
rspfile_content()188   const SubstitutionPattern& rspfile_content() const {
189     return rspfile_content_;
190   }
set_rspfile_content(SubstitutionPattern content)191   void set_rspfile_content(SubstitutionPattern content) {
192     DCHECK(!complete_);
193     rspfile_content_ = std::move(content);
194   }
195 
pool()196   const LabelPtrPair<Pool>& pool() const { return pool_; }
set_pool(LabelPtrPair<Pool> pool)197   void set_pool(LabelPtrPair<Pool> pool) { pool_ = std::move(pool); }
198 
199   // Other functions ----------------------------------------------------------
200 
201   // Function for the above override to call to complete the tool.
202   void SetToolComplete();
203 
204   // Substitutions required by this tool.
substitution_bits()205   const SubstitutionBits& substitution_bits() const {
206     DCHECK(complete_);
207     return substitution_bits_;
208   }
209 
210   // Create a tool based on given features.
211   static std::unique_ptr<Tool> CreateTool(const std::string& name);
212   static std::unique_ptr<Tool> CreateTool(const ParseNode* function,
213                                           const std::string& name,
214                                           Scope* scope,
215                                           Toolchain* toolchain,
216                                           Err* err);
217 
218   static const char* GetToolTypeForSourceType(SourceFile::Type type);
219   static const char* GetToolTypeForTargetFinalOutput(const Target* target);
220 
221  protected:
222   explicit Tool(const char* t);
223 
224   // Initialization functions -------------------------------------------------
225   //
226   // Initialization methods used by InitTool(). If successful, will set the
227   // field and return true, otherwise will return false. Must be called before
228   // SetComplete().
229   bool IsPatternInOutputList(const SubstitutionList& output_list,
230                              const SubstitutionPattern& pattern) const;
231   bool ValidateSubstitutionList(const std::vector<const Substitution*>& list,
232                                 const Value* origin,
233                                 Err* err) const;
234   bool ValidateOutputs(Err* err) const;
235   bool ReadBool(Scope* scope, const char* var, bool* field, Err* err);
236   bool ReadString(Scope* scope, const char* var, std::string* field, Err* err);
237   bool ReadPattern(Scope* scope,
238                    const char* var,
239                    SubstitutionPattern* field,
240                    Err* err);
241   bool ReadPatternList(Scope* scope,
242                        const char* var,
243                        SubstitutionList* field,
244                        Err* err);
245   bool ReadLabel(Scope* scope,
246                  const char* var,
247                  const Label& current_toolchain,
248                  LabelPtrPair<Pool>* field,
249                  Err* err);
250   bool ReadOutputExtension(Scope* scope, Err* err);
251 
252   const ParseNode* defined_from_ = nullptr;
253   const char* name_ = nullptr;
254 
255   SubstitutionPattern command_;
256   std::string command_launcher_;
257   std::string default_output_extension_;
258   SubstitutionPattern default_output_dir_;
259   SubstitutionPattern depfile_;
260   SubstitutionPattern description_;
261   std::string framework_switch_;
262   std::string framework_dir_switch_;
263   std::string lib_switch_;
264   std::string lib_dir_switch_;
265   std::string linker_arg_;
266   SubstitutionList outputs_;
267   SubstitutionList runtime_outputs_;
268   std::string output_prefix_;
269   bool restat_ = false;
270   SubstitutionPattern rspfile_;
271   SubstitutionPattern rspfile_content_;
272   LabelPtrPair<Pool> pool_;
273 
274   bool complete_ = false;
275 
276   SubstitutionBits substitution_bits_;
277 
278   DISALLOW_COPY_AND_ASSIGN(Tool);
279 };
280 
281 #endif  // TOOLS_GN_TOOL_H_
282