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_ARGS_H_ 6 #define TOOLS_GN_ARGS_H_ 7 8 #include <map> 9 #include <mutex> 10 #include <set> 11 #include <string_view> 12 #include <unordered_map> 13 14 #include "gn/scope.h" 15 16 class Err; 17 class SourceFile; 18 19 extern const char kBuildArgs_Help[]; 20 21 // Manages build arguments. It stores the global arguments specified on the 22 // command line, and sets up the root scope with the proper values. 23 // 24 // This class tracks accesses so we can report errors about unused variables. 25 // The use case is if the user specifies an override on the command line, but 26 // no buildfile actually uses that variable. We want to be able to report that 27 // the argument was unused. 28 class Args { 29 public: 30 struct ValueWithOverride { 31 ValueWithOverride(); 32 ValueWithOverride(const Value& def_val); 33 ~ValueWithOverride(); 34 35 Value default_value; // Default value given in declare_args. 36 37 bool has_override; // True indicates override_value is valid. 38 Value override_value; // From .gn or the current build's "gn args". 39 }; 40 using ValueWithOverrideMap = std::map<std::string_view, ValueWithOverride>; 41 42 Args(); 43 Args(const Args& other); 44 ~Args(); 45 46 // Specifies overrides of the build arguments. These are normally specified 47 // on the command line. 48 void AddArgOverride(const char* name, const Value& value); 49 void AddArgOverrides(const Scope::KeyValueMap& overrides); 50 51 // Specifies default overrides of the build arguments. These are normally 52 // specified in the .gn file. 53 void AddDefaultArgOverrides(const Scope::KeyValueMap& overrides); 54 55 // Returns the value corresponding to the given argument name, or NULL if no 56 // argument is set. 57 const Value* GetArgOverride(const char* name) const; 58 59 // Sets up the root scope for a toolchain. This applies the default system 60 // flags and saves the toolchain overrides so they can be applied to 61 // declare_args blocks that appear when loading files in that toolchain. 62 void SetupRootScope(Scope* dest, 63 const Scope::KeyValueMap& toolchain_overrides) const; 64 65 // Sets up the given scope with arguments passed in. 66 // 67 // If the values specified in the args are not already set, the values in 68 // the args list will be used (which are assumed to be the defaults), but 69 // they will not override the system defaults or the current overrides. 70 // 71 // All args specified in the input will be marked as "used". 72 // 73 // On failure, the err will be set and it will return false. 74 bool DeclareArgs(const Scope::KeyValueMap& args, 75 Scope* scope_to_set, 76 Err* err) const; 77 78 // Checks to see if any of the overrides ever used were never declared as 79 // arguments. If there are, this returns false and sets the error. 80 bool VerifyAllOverridesUsed(Err* err) const; 81 82 // Returns information about all arguments, both defaults and overrides. 83 // This is used for the help system which is not performance critical. Use a 84 // map instead of a hash map so the arguments are sorted alphabetically. 85 ValueWithOverrideMap GetAllArguments() const; 86 87 // Returns the set of build files that may affect the build arguments, please 88 // refer to Scope for how this is determined. build_args_dependency_files()89 const SourceFileSet& build_args_dependency_files() const { 90 return build_args_dependency_files_; 91 } 92 set_build_args_dependency_files(const SourceFileSet & build_args_dependency_files)93 void set_build_args_dependency_files( 94 const SourceFileSet& build_args_dependency_files) { 95 build_args_dependency_files_ = build_args_dependency_files; 96 } 97 98 private: 99 using ArgumentsPerToolchain = 100 std::unordered_map<const Settings*, Scope::KeyValueMap>; 101 102 // Sets the default config based on the current system. 103 void SetSystemVarsLocked(Scope* scope) const; 104 105 // Sets the given already declared vars on the given scope. 106 void ApplyOverridesLocked(const Scope::KeyValueMap& values, 107 Scope* scope) const; 108 109 void SaveOverrideRecordLocked(const Scope::KeyValueMap& values) const; 110 111 // Returns the KeyValueMap used for arguments declared for the specified 112 // toolchain. 113 Scope::KeyValueMap& DeclaredArgumentsForToolchainLocked(Scope* scope) const; 114 115 // Returns the KeyValueMap used for overrides for the specified 116 // toolchain. 117 Scope::KeyValueMap& OverridesForToolchainLocked(Scope* scope) const; 118 119 // Since this is called during setup which we assume is single-threaded, 120 // this is not protected by the lock. It should be set only during init. 121 Scope::KeyValueMap overrides_; 122 123 mutable std::mutex lock_; 124 125 // Maintains a list of all overrides we've ever seen. This is the main 126 // |overrides_| as well as toolchain overrides. Tracking this allows us to 127 // check for overrides that were specified but never used. 128 mutable Scope::KeyValueMap all_overrides_; 129 130 // Maps from Settings (which corresponds to a toolchain) to the map of 131 // declared variables. This is used to tracks all variables declared in any 132 // buildfile. This is so we can see if the user set variables on the command 133 // line that are not used anywhere. Each map is toolchain specific as each 134 // toolchain may define variables in different locations. 135 mutable ArgumentsPerToolchain declared_arguments_per_toolchain_; 136 137 // Overrides for individual toolchains. This is necessary so we 138 // can apply the correct override for the current toolchain, once 139 // we see an argument declaration. 140 mutable ArgumentsPerToolchain toolchain_overrides_; 141 142 SourceFileSet build_args_dependency_files_; 143 144 Args& operator=(const Args&) = delete; 145 }; 146 147 #endif // TOOLS_GN_ARGS_H_ 148