16d528ed9Sopenharmony_ci// Copyright (c) 2013 The Chromium Authors. All rights reserved. 26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 36d528ed9Sopenharmony_ci// found in the LICENSE file. 46d528ed9Sopenharmony_ci 56d528ed9Sopenharmony_ci#ifndef TOOLS_GN_ARGS_H_ 66d528ed9Sopenharmony_ci#define TOOLS_GN_ARGS_H_ 76d528ed9Sopenharmony_ci 86d528ed9Sopenharmony_ci#include <map> 96d528ed9Sopenharmony_ci#include <mutex> 106d528ed9Sopenharmony_ci#include <set> 116d528ed9Sopenharmony_ci#include <string_view> 126d528ed9Sopenharmony_ci#include <unordered_map> 136d528ed9Sopenharmony_ci 146d528ed9Sopenharmony_ci#include "gn/scope.h" 156d528ed9Sopenharmony_ci 166d528ed9Sopenharmony_ciclass Err; 176d528ed9Sopenharmony_ciclass SourceFile; 186d528ed9Sopenharmony_ci 196d528ed9Sopenharmony_ciextern const char kBuildArgs_Help[]; 206d528ed9Sopenharmony_ci 216d528ed9Sopenharmony_ci// Manages build arguments. It stores the global arguments specified on the 226d528ed9Sopenharmony_ci// command line, and sets up the root scope with the proper values. 236d528ed9Sopenharmony_ci// 246d528ed9Sopenharmony_ci// This class tracks accesses so we can report errors about unused variables. 256d528ed9Sopenharmony_ci// The use case is if the user specifies an override on the command line, but 266d528ed9Sopenharmony_ci// no buildfile actually uses that variable. We want to be able to report that 276d528ed9Sopenharmony_ci// the argument was unused. 286d528ed9Sopenharmony_ciclass Args { 296d528ed9Sopenharmony_ci public: 306d528ed9Sopenharmony_ci struct ValueWithOverride { 316d528ed9Sopenharmony_ci ValueWithOverride(); 326d528ed9Sopenharmony_ci ValueWithOverride(const Value& def_val); 336d528ed9Sopenharmony_ci ~ValueWithOverride(); 346d528ed9Sopenharmony_ci 356d528ed9Sopenharmony_ci Value default_value; // Default value given in declare_args. 366d528ed9Sopenharmony_ci 376d528ed9Sopenharmony_ci bool has_override; // True indicates override_value is valid. 386d528ed9Sopenharmony_ci Value override_value; // From .gn or the current build's "gn args". 396d528ed9Sopenharmony_ci }; 406d528ed9Sopenharmony_ci using ValueWithOverrideMap = std::map<std::string_view, ValueWithOverride>; 416d528ed9Sopenharmony_ci 426d528ed9Sopenharmony_ci Args(); 436d528ed9Sopenharmony_ci Args(const Args& other); 446d528ed9Sopenharmony_ci ~Args(); 456d528ed9Sopenharmony_ci 466d528ed9Sopenharmony_ci // Specifies overrides of the build arguments. These are normally specified 476d528ed9Sopenharmony_ci // on the command line. 486d528ed9Sopenharmony_ci void AddArgOverride(const char* name, const Value& value); 496d528ed9Sopenharmony_ci void AddArgOverrides(const Scope::KeyValueMap& overrides); 506d528ed9Sopenharmony_ci 516d528ed9Sopenharmony_ci // Specifies default overrides of the build arguments. These are normally 526d528ed9Sopenharmony_ci // specified in the .gn file. 536d528ed9Sopenharmony_ci void AddDefaultArgOverrides(const Scope::KeyValueMap& overrides); 546d528ed9Sopenharmony_ci 556d528ed9Sopenharmony_ci // Returns the value corresponding to the given argument name, or NULL if no 566d528ed9Sopenharmony_ci // argument is set. 576d528ed9Sopenharmony_ci const Value* GetArgOverride(const char* name) const; 586d528ed9Sopenharmony_ci 596d528ed9Sopenharmony_ci // Sets up the root scope for a toolchain. This applies the default system 606d528ed9Sopenharmony_ci // flags and saves the toolchain overrides so they can be applied to 616d528ed9Sopenharmony_ci // declare_args blocks that appear when loading files in that toolchain. 626d528ed9Sopenharmony_ci void SetupRootScope(Scope* dest, 636d528ed9Sopenharmony_ci const Scope::KeyValueMap& toolchain_overrides) const; 646d528ed9Sopenharmony_ci 656d528ed9Sopenharmony_ci // Sets up the given scope with arguments passed in. 666d528ed9Sopenharmony_ci // 676d528ed9Sopenharmony_ci // If the values specified in the args are not already set, the values in 686d528ed9Sopenharmony_ci // the args list will be used (which are assumed to be the defaults), but 696d528ed9Sopenharmony_ci // they will not override the system defaults or the current overrides. 706d528ed9Sopenharmony_ci // 716d528ed9Sopenharmony_ci // All args specified in the input will be marked as "used". 726d528ed9Sopenharmony_ci // 736d528ed9Sopenharmony_ci // On failure, the err will be set and it will return false. 746d528ed9Sopenharmony_ci bool DeclareArgs(const Scope::KeyValueMap& args, 756d528ed9Sopenharmony_ci Scope* scope_to_set, 766d528ed9Sopenharmony_ci Err* err) const; 776d528ed9Sopenharmony_ci 786d528ed9Sopenharmony_ci // Checks to see if any of the overrides ever used were never declared as 796d528ed9Sopenharmony_ci // arguments. If there are, this returns false and sets the error. 806d528ed9Sopenharmony_ci bool VerifyAllOverridesUsed(Err* err) const; 816d528ed9Sopenharmony_ci 826d528ed9Sopenharmony_ci // Returns information about all arguments, both defaults and overrides. 836d528ed9Sopenharmony_ci // This is used for the help system which is not performance critical. Use a 846d528ed9Sopenharmony_ci // map instead of a hash map so the arguments are sorted alphabetically. 856d528ed9Sopenharmony_ci ValueWithOverrideMap GetAllArguments() const; 866d528ed9Sopenharmony_ci 876d528ed9Sopenharmony_ci // Returns the set of build files that may affect the build arguments, please 886d528ed9Sopenharmony_ci // refer to Scope for how this is determined. 896d528ed9Sopenharmony_ci const SourceFileSet& build_args_dependency_files() const { 906d528ed9Sopenharmony_ci return build_args_dependency_files_; 916d528ed9Sopenharmony_ci } 926d528ed9Sopenharmony_ci 936d528ed9Sopenharmony_ci void set_build_args_dependency_files( 946d528ed9Sopenharmony_ci const SourceFileSet& build_args_dependency_files) { 956d528ed9Sopenharmony_ci build_args_dependency_files_ = build_args_dependency_files; 966d528ed9Sopenharmony_ci } 976d528ed9Sopenharmony_ci 986d528ed9Sopenharmony_ci private: 996d528ed9Sopenharmony_ci using ArgumentsPerToolchain = 1006d528ed9Sopenharmony_ci std::unordered_map<const Settings*, Scope::KeyValueMap>; 1016d528ed9Sopenharmony_ci 1026d528ed9Sopenharmony_ci // Sets the default config based on the current system. 1036d528ed9Sopenharmony_ci void SetSystemVarsLocked(Scope* scope) const; 1046d528ed9Sopenharmony_ci 1056d528ed9Sopenharmony_ci // Sets the given already declared vars on the given scope. 1066d528ed9Sopenharmony_ci void ApplyOverridesLocked(const Scope::KeyValueMap& values, 1076d528ed9Sopenharmony_ci Scope* scope) const; 1086d528ed9Sopenharmony_ci 1096d528ed9Sopenharmony_ci void SaveOverrideRecordLocked(const Scope::KeyValueMap& values) const; 1106d528ed9Sopenharmony_ci 1116d528ed9Sopenharmony_ci // Returns the KeyValueMap used for arguments declared for the specified 1126d528ed9Sopenharmony_ci // toolchain. 1136d528ed9Sopenharmony_ci Scope::KeyValueMap& DeclaredArgumentsForToolchainLocked(Scope* scope) const; 1146d528ed9Sopenharmony_ci 1156d528ed9Sopenharmony_ci // Returns the KeyValueMap used for overrides for the specified 1166d528ed9Sopenharmony_ci // toolchain. 1176d528ed9Sopenharmony_ci Scope::KeyValueMap& OverridesForToolchainLocked(Scope* scope) const; 1186d528ed9Sopenharmony_ci 1196d528ed9Sopenharmony_ci // Since this is called during setup which we assume is single-threaded, 1206d528ed9Sopenharmony_ci // this is not protected by the lock. It should be set only during init. 1216d528ed9Sopenharmony_ci Scope::KeyValueMap overrides_; 1226d528ed9Sopenharmony_ci 1236d528ed9Sopenharmony_ci mutable std::mutex lock_; 1246d528ed9Sopenharmony_ci 1256d528ed9Sopenharmony_ci // Maintains a list of all overrides we've ever seen. This is the main 1266d528ed9Sopenharmony_ci // |overrides_| as well as toolchain overrides. Tracking this allows us to 1276d528ed9Sopenharmony_ci // check for overrides that were specified but never used. 1286d528ed9Sopenharmony_ci mutable Scope::KeyValueMap all_overrides_; 1296d528ed9Sopenharmony_ci 1306d528ed9Sopenharmony_ci // Maps from Settings (which corresponds to a toolchain) to the map of 1316d528ed9Sopenharmony_ci // declared variables. This is used to tracks all variables declared in any 1326d528ed9Sopenharmony_ci // buildfile. This is so we can see if the user set variables on the command 1336d528ed9Sopenharmony_ci // line that are not used anywhere. Each map is toolchain specific as each 1346d528ed9Sopenharmony_ci // toolchain may define variables in different locations. 1356d528ed9Sopenharmony_ci mutable ArgumentsPerToolchain declared_arguments_per_toolchain_; 1366d528ed9Sopenharmony_ci 1376d528ed9Sopenharmony_ci // Overrides for individual toolchains. This is necessary so we 1386d528ed9Sopenharmony_ci // can apply the correct override for the current toolchain, once 1396d528ed9Sopenharmony_ci // we see an argument declaration. 1406d528ed9Sopenharmony_ci mutable ArgumentsPerToolchain toolchain_overrides_; 1416d528ed9Sopenharmony_ci 1426d528ed9Sopenharmony_ci SourceFileSet build_args_dependency_files_; 1436d528ed9Sopenharmony_ci 1446d528ed9Sopenharmony_ci Args& operator=(const Args&) = delete; 1456d528ed9Sopenharmony_ci}; 1466d528ed9Sopenharmony_ci 1476d528ed9Sopenharmony_ci#endif // TOOLS_GN_ARGS_H_ 148