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