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 // Modifies the existing build.ninja to only contain the commands necessary to 243 // run GN and regenerate and build.ninja.d such that build.ninja will be 244 // treated as dirty and regenerated. 245 // 246 // This is used by commands like gen and clean before they modify or delete 247 // other ninja files, and ensures that ninja can still call GN if the commands 248 // are interrupted before completion. 249 // 250 // On error, returns false. 251 bool PrepareForRegeneration(const BuildSettings* settings); 252 253 // Given a setup that has already been run and some command-line input, 254 // resolves that input as a target label and returns the corresponding target. 255 // On failure, returns null and prints the error to the standard output. 256 const Target* ResolveTargetFromCommandLineString( 257 Setup* setup, 258 const std::string& label_string); 259 260 // Resolves a vector of command line inputs and figures out the full set of 261 // things they resolve to. 262 // 263 // On success, returns true and populates the vectors. On failure, prints the 264 // error and returns false. 265 // 266 // Patterns with wildcards will only match targets. The file_matches aren't 267 // validated that they are real files or referenced by any targets. They're just 268 // the set of things that didn't match anything else. 269 bool ResolveFromCommandLineInput( 270 Setup* setup, 271 const std::vector<std::string>& input, 272 bool default_toolchain_only, 273 UniqueVector<const Target*>* target_matches, 274 UniqueVector<const Config*>* config_matches, 275 UniqueVector<const Toolchain*>* toolchain_matches, 276 UniqueVector<SourceFile>* file_matches); 277 278 // Runs the header checker. All targets in the build should be given in 279 // all_targets, and the specific targets to check should be in to_check. 280 // 281 // force_check, if true, will override targets opting out of header checking 282 // with "check_includes = false" and will check them anyway. 283 // 284 // Generated files are normally not checked since they do not exist 285 // unless a build has been run, but passing true for |check_generated| 286 // will attempt to check them anyway, assuming they exist. 287 // 288 // On success, returns true. If the check fails, the error(s) will be printed 289 // to stdout and false will be returned. 290 bool CheckPublicHeaders(const BuildSettings* build_settings, 291 const std::vector<const Target*>& all_targets, 292 const std::vector<const Target*>& to_check, 293 bool force_check, 294 bool check_generated, 295 bool check_system); 296 297 // Filters the given list of targets by the given pattern list. 298 void FilterTargetsByPatterns(const std::vector<const Target*>& input, 299 const std::vector<LabelPattern>& filter, 300 std::vector<const Target*>* output); 301 void FilterTargetsByPatterns(const std::vector<const Target*>& input, 302 const std::vector<LabelPattern>& filter, 303 UniqueVector<const Target*>* output); 304 305 // Removes targets from the input that match the given pattern list. 306 void FilterOutTargetsByPatterns(const std::vector<const Target*>& input, 307 const std::vector<LabelPattern>& filter, 308 std::vector<const Target*>* output); 309 310 // Builds a list of pattern from a semicolon-separated list of labels. 311 bool FilterPatternsFromString(const BuildSettings* build_settings, 312 const std::string& label_list_string, 313 std::vector<LabelPattern>* filters, 314 Err* err); 315 316 // These are the documentation strings for the command-line flags used by 317 // FilterAndPrintTargets. Commands that call that function should incorporate 318 // these into their help. 319 #define TARGET_PRINTING_MODE_COMMAND_LINE_HELP \ 320 " --as=(buildfile|label|output)\n" \ 321 " How to print targets.\n" \ 322 "\n" \ 323 " buildfile\n" \ 324 " Prints the build files where the given target was declared as\n" \ 325 " file names.\n" \ 326 " label (default)\n" \ 327 " Prints the label of the target.\n" \ 328 " output\n" \ 329 " Prints the first output file for the target relative to the\n" \ 330 " root build directory.\n" 331 #define TARGET_TYPE_FILTER_COMMAND_LINE_HELP \ 332 " --type=(action|copy|executable|group|loadable_module|shared_library|\n" \ 333 " source_set|static_library)\n" \ 334 " Restrict outputs to targets matching the given type. If\n" \ 335 " unspecified, no filtering will be performed.\n" 336 #define TARGET_TESTONLY_FILTER_COMMAND_LINE_HELP \ 337 " --testonly=(true|false)\n" \ 338 " Restrict outputs to targets with the testonly flag set\n" \ 339 " accordingly. When unspecified, the target's testonly flags are\n" \ 340 " ignored.\n" 341 342 // Applies any testonly and type filters specified on the command line, 343 // and prints the targets as specified by the --as command line flag. 344 // 345 // If indent is true, the results will be indented two spaces. 346 // 347 // The vector will be modified so that only the printed targets will remain. 348 void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets); 349 void FilterAndPrintTargets(std::vector<const Target*>* targets, 350 base::ListValue* out); 351 352 void FilterAndPrintTargetSet(bool indent, const TargetSet& targets); 353 void FilterAndPrintTargetSet(const TargetSet& targets, base::ListValue* out); 354 355 // Computes which targets reference the given file and also stores how the 356 // target references the file. 357 enum class HowTargetContainsFile { 358 kSources, 359 kPublic, 360 kInputs, 361 kData, 362 kScript, 363 kOutput, 364 }; 365 using TargetContainingFile = std::pair<const Target*, HowTargetContainsFile>; 366 void GetTargetsContainingFile(Setup* setup, 367 const std::vector<const Target*>& all_targets, 368 const SourceFile& file, 369 bool default_toolchain_only, 370 std::vector<TargetContainingFile>* matches); 371 372 // Extra help from command_check.cc 373 extern const char kNoGnCheck_Help[]; 374 375 } // namespace commands 376 377 #endif // TOOLS_GN_COMMANDS_H_ 378