• 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_COMMANDS_H_
6 #define TOOLS_GN_COMMANDS_H_
7 
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <string_view>
12 #include <vector>
13 
14 #include "base/values.h"
15 #include "gn/target.h"
16 #include "gn/unique_vector.h"
17 
18 class BuildSettings;
19 class Config;
20 class LabelPattern;
21 class Setup;
22 class SourceFile;
23 class Target;
24 class Toolchain;
25 
26 namespace base {
27 class CommandLine;
28 }  // namespace base
29 
30 // Each "Run" command returns the value we should return from main().
31 
32 namespace commands {
33 
34 using CommandRunner = int (*)(const std::vector<std::string>&);
35 
36 extern const char kAnalyze[];
37 extern const char kAnalyze_HelpShort[];
38 extern const char kAnalyze_Help[];
39 int RunAnalyze(const std::vector<std::string>& args);
40 
41 extern const char kArgs[];
42 extern const char kArgs_HelpShort[];
43 extern const char kArgs_Help[];
44 int RunArgs(const std::vector<std::string>& args);
45 
46 extern const char kCheck[];
47 extern const char kCheck_HelpShort[];
48 extern const char kCheck_Help[];
49 int RunCheck(const std::vector<std::string>& args);
50 
51 extern const char kClean[];
52 extern const char kClean_HelpShort[];
53 extern const char kClean_Help[];
54 int RunClean(const std::vector<std::string>& args);
55 
56 extern const char kDesc[];
57 extern const char kDesc_HelpShort[];
58 extern const char kDesc_Help[];
59 int RunDesc(const std::vector<std::string>& args);
60 
61 extern const char kGen[];
62 extern const char kGen_HelpShort[];
63 extern const char kGen_Help[];
64 int RunGen(const std::vector<std::string>& args);
65 
66 extern const char kFormat[];
67 extern const char kFormat_HelpShort[];
68 extern const char kFormat_Help[];
69 int RunFormat(const std::vector<std::string>& args);
70 
71 extern const char kHelp[];
72 extern const char kHelp_HelpShort[];
73 extern const char kHelp_Help[];
74 int RunHelp(const std::vector<std::string>& args);
75 
76 extern const char kMeta[];
77 extern const char kMeta_HelpShort[];
78 extern const char kMeta_Help[];
79 int RunMeta(const std::vector<std::string>& args);
80 
81 extern const char kLs[];
82 extern const char kLs_HelpShort[];
83 extern const char kLs_Help[];
84 int RunLs(const std::vector<std::string>& args);
85 
86 extern const char kOutputs[];
87 extern const char kOutputs_HelpShort[];
88 extern const char kOutputs_Help[];
89 int RunOutputs(const std::vector<std::string>& args);
90 
91 extern const char kPath[];
92 extern const char kPath_HelpShort[];
93 extern const char kPath_Help[];
94 int RunPath(const std::vector<std::string>& args);
95 
96 extern const char kRefs[];
97 extern const char kRefs_HelpShort[];
98 extern const char kRefs_Help[];
99 int RunRefs(const std::vector<std::string>& args);
100 
101 extern const char kCleanStale[];
102 extern const char kCleanStale_HelpShort[];
103 extern const char kCleanStale_Help[];
104 int RunCleanStale(const std::vector<std::string>& args);
105 
106 // -----------------------------------------------------------------------------
107 
108 struct CommandInfo {
109   CommandInfo();
110   CommandInfo(const char* in_help_short,
111               const char* in_help,
112               CommandRunner in_runner);
113 
114   const char* help_short;
115   const char* help;
116   CommandRunner runner;
117 };
118 
119 using CommandInfoMap = std::map<std::string_view, CommandInfo>;
120 
121 const CommandInfoMap& GetCommands();
122 
123 // Command switches as flags and enums -----------------------------------------
124 
125 // A class that models a set of command-line flags and values that
126 // can affect the output of various GN commands. For example --tree
127 // can be used with `gn desc <out_dir> <label> deps --tree`.
128 //
129 // Each flag or value is checked by an accessor method which returns
130 // a boolean or an enum.
131 //
132 // Use CommandSwitches::Get() to get a reference to the current
133 // global set of switches for the process.
134 //
135 // Use CommandSwitches::Set() to update its value. This may be
136 // useful when implementing a REPL in GN, where each evaluation
137 // might need a different set of command switches.
138 class CommandSwitches {
139  public:
140   // Default constructor.
141   CommandSwitches() = default;
142 
143   // For --quiet, used by `refs`.
has_quiet()144   bool has_quiet() const { return has_quiet_; }
145 
146   // For --force, used by `check`.
has_force()147   bool has_force() const { return has_force_; }
148 
149   // For --all, used by `desc` and `refs`.
has_all()150   bool has_all() const { return has_all_; }
151 
152   // For --blame used by `desc`.
has_blame()153   bool has_blame() const { return has_blame_; }
154 
155   // For --tree used by `desc` and `refs`.
has_tree()156   bool has_tree() const { return has_tree_; }
157 
158   // For --format=json used by `desc`.
has_format_json()159   bool has_format_json() const { return has_format_json_; }
160 
161   // For --default-toolchain used by `desc`, `refs`.
has_default_toolchain()162   bool has_default_toolchain() const { return has_default_toolchain_; }
163 
164   // For --check-generated
has_check_generated()165   bool has_check_generated() const { return has_check_generated_; }
166 
167   // For --check-system
has_check_system()168   bool has_check_system() const { return has_check_system_; }
169 
170   // For --public
has_public()171   bool has_public() const { return has_public_; }
172 
173   // For --with-data
has_with_data()174   bool has_with_data() const { return has_with_data_; }
175 
176   // For --as=(buildtype|label|output).
177   enum TargetPrintMode {
178     TARGET_PRINT_BUILDFILE,
179     TARGET_PRINT_LABEL,
180     TARGET_PRINT_OUTPUT,
181   };
target_print_mode()182   TargetPrintMode target_print_mode() const { return target_print_mode_; }
183 
184   // For --type=TARGET_TYPE
target_type()185   Target::OutputType target_type() const { return target_type_; }
186 
187   enum TestonlyMode {
188     TESTONLY_NONE,   // no --testonly used.
189     TESTONLY_FALSE,  // --testonly=false
190     TESTONLY_TRUE,   // --testonly=true
191   };
testonly_mode()192   TestonlyMode testonly_mode() const { return testonly_mode_; }
193 
194   // For --rebase, --walk and --data in `gn meta`
meta_rebase_dir()195   std::string meta_rebase_dir() const { return meta_rebase_dir_; }
meta_data_keys()196   std::string meta_data_keys() const { return meta_data_keys_; }
meta_walk_keys()197   std::string meta_walk_keys() const { return meta_walk_keys_; }
198 
199   // Initialize the global set from a given command line.
200   // Must be called early from main(). On success return true,
201   // on failure return false after printing an error message.
202   static bool Init(const base::CommandLine& cmdline);
203 
204   // Retrieve a reference to the current global set of command switches.
205   static const CommandSwitches& Get();
206 
207   // Change the current global set of command switches, and return
208   // the previous value.
209   static CommandSwitches Set(CommandSwitches new_switches);
210 
211  private:
is_initialized()212   bool is_initialized() const { return initialized_; }
213 
214   bool InitFrom(const base::CommandLine&);
215 
216   static CommandSwitches s_global_switches_;
217 
218   bool initialized_ = false;
219   bool has_quiet_ = false;
220   bool has_force_ = false;
221   bool has_all_ = false;
222   bool has_blame_ = false;
223   bool has_tree_ = false;
224   bool has_format_json_ = false;
225   bool has_default_toolchain_ = false;
226   bool has_check_generated_ = false;
227   bool has_check_system_ = false;
228   bool has_public_ = false;
229   bool has_with_data_ = false;
230 
231   TargetPrintMode target_print_mode_ = TARGET_PRINT_LABEL;
232   Target::OutputType target_type_ = Target::UNKNOWN;
233   TestonlyMode testonly_mode_ = TESTONLY_NONE;
234 
235   std::string meta_rebase_dir_;
236   std::string meta_data_keys_;
237   std::string meta_walk_keys_;
238 };
239 
240 // Helper functions for some commands ------------------------------------------
241 
242 // Given a setup that has already been run and some command-line input,
243 // resolves that input as a target label and returns the corresponding target.
244 // On failure, returns null and prints the error to the standard output.
245 const Target* ResolveTargetFromCommandLineString(
246     Setup* setup,
247     const std::string& label_string);
248 
249 // Resolves a vector of command line inputs and figures out the full set of
250 // things they resolve to.
251 //
252 // On success, returns true and populates the vectors. On failure, prints the
253 // error and returns false.
254 //
255 // Patterns with wildcards will only match targets. The file_matches aren't
256 // validated that they are real files or referenced by any targets. They're just
257 // the set of things that didn't match anything else.
258 bool ResolveFromCommandLineInput(
259     Setup* setup,
260     const std::vector<std::string>& input,
261     bool default_toolchain_only,
262     UniqueVector<const Target*>* target_matches,
263     UniqueVector<const Config*>* config_matches,
264     UniqueVector<const Toolchain*>* toolchain_matches,
265     UniqueVector<SourceFile>* file_matches);
266 
267 // Runs the header checker. All targets in the build should be given in
268 // all_targets, and the specific targets to check should be in to_check.
269 //
270 // force_check, if true, will override targets opting out of header checking
271 // with "check_includes = false" and will check them anyway.
272 //
273 // Generated files are normally not checked since they do not exist
274 // unless a build has been run, but passing true for |check_generated|
275 // will attempt to check them anyway, assuming they exist.
276 //
277 // On success, returns true. If the check fails, the error(s) will be printed
278 // to stdout and false will be returned.
279 bool CheckPublicHeaders(const BuildSettings* build_settings,
280                         const std::vector<const Target*>& all_targets,
281                         const std::vector<const Target*>& to_check,
282                         bool force_check,
283                         bool check_generated,
284                         bool check_system);
285 
286 // Filters the given list of targets by the given pattern list.
287 void FilterTargetsByPatterns(const std::vector<const Target*>& input,
288                              const std::vector<LabelPattern>& filter,
289                              std::vector<const Target*>* output);
290 void FilterTargetsByPatterns(const std::vector<const Target*>& input,
291                              const std::vector<LabelPattern>& filter,
292                              UniqueVector<const Target*>* output);
293 
294 // Removes targets from the input that match the given pattern list.
295 void FilterOutTargetsByPatterns(const std::vector<const Target*>& input,
296                                 const std::vector<LabelPattern>& filter,
297                                 std::vector<const Target*>* output);
298 
299 // Builds a list of pattern from a semicolon-separated list of labels.
300 bool FilterPatternsFromString(const BuildSettings* build_settings,
301                               const std::string& label_list_string,
302                               std::vector<LabelPattern>* filters,
303                               Err* err);
304 
305 // These are the documentation strings for the command-line flags used by
306 // FilterAndPrintTargets. Commands that call that function should incorporate
307 // these into their help.
308 #define TARGET_PRINTING_MODE_COMMAND_LINE_HELP                                \
309   "  --as=(buildfile|label|output)\n"                                         \
310   "      How to print targets.\n"                                             \
311   "\n"                                                                        \
312   "      buildfile\n"                                                         \
313   "          Prints the build files where the given target was declared as\n" \
314   "          file names.\n"                                                   \
315   "      label  (default)\n"                                                  \
316   "          Prints the label of the target.\n"                               \
317   "      output\n"                                                            \
318   "          Prints the first output file for the target relative to the\n"   \
319   "          root build directory.\n"
320 #define TARGET_TYPE_FILTER_COMMAND_LINE_HELP                                 \
321   "  --type=(action|copy|executable|group|loadable_module|shared_library|\n" \
322   "          source_set|static_library)\n"                                   \
323   "      Restrict outputs to targets matching the given type. If\n"          \
324   "      unspecified, no filtering will be performed.\n"
325 #define TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP                           \
326   "  --testonly=(true|false)\n"                                            \
327   "      Restrict outputs to targets with the testonly flag set\n"         \
328   "      accordingly. When unspecified, the target's testonly flags are\n" \
329   "      ignored.\n"
330 
331 // Applies any testonly and type filters specified on the command line,
332 // and prints the targets as specified by the --as command line flag.
333 //
334 // If indent is true, the results will be indented two spaces.
335 //
336 // The vector will be modified so that only the printed targets will remain.
337 void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets);
338 void FilterAndPrintTargets(std::vector<const Target*>* targets,
339                            base::ListValue* out);
340 
341 void FilterAndPrintTargetSet(bool indent, const TargetSet& targets);
342 void FilterAndPrintTargetSet(const TargetSet& targets, base::ListValue* out);
343 
344 // Computes which targets reference the given file and also stores how the
345 // target references the file.
346 enum class HowTargetContainsFile {
347   kSources,
348   kPublic,
349   kInputs,
350   kData,
351   kScript,
352   kOutput,
353 };
354 using TargetContainingFile = std::pair<const Target*, HowTargetContainsFile>;
355 void GetTargetsContainingFile(Setup* setup,
356                               const std::vector<const Target*>& all_targets,
357                               const SourceFile& file,
358                               bool default_toolchain_only,
359                               std::vector<TargetContainingFile>* matches);
360 
361 // Extra help from command_check.cc
362 extern const char kNoGnCheck_Help[];
363 
364 }  // namespace commands
365 
366 #endif  // TOOLS_GN_COMMANDS_H_
367