|  | // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "tools/gn/config_values_generator.h" | 
|  |  | 
|  | #include "base/strings/string_util.h" | 
|  | #include "tools/gn/config_values.h" | 
|  | #include "tools/gn/scope.h" | 
|  | #include "tools/gn/settings.h" | 
|  | #include "tools/gn/value.h" | 
|  | #include "tools/gn/value_extractors.h" | 
|  | #include "tools/gn/variables.h" | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | void GetStringList( | 
|  | Scope* scope, | 
|  | const char* var_name, | 
|  | ConfigValues* config_values, | 
|  | std::vector<std::string>& (ConfigValues::* accessor)(), | 
|  | Err* err) { | 
|  | const Value* value = scope->GetValue(var_name, true); | 
|  | if (!value) | 
|  | return;  // No value, empty input and succeed. | 
|  |  | 
|  | ExtractListOfStringValues(*value, &(config_values->*accessor)(), err); | 
|  | } | 
|  |  | 
|  | void GetDirList( | 
|  | Scope* scope, | 
|  | const char* var_name, | 
|  | ConfigValues* config_values, | 
|  | const SourceDir input_dir, | 
|  | std::vector<SourceDir>& (ConfigValues::* accessor)(), | 
|  | Err* err) { | 
|  | const Value* value = scope->GetValue(var_name, true); | 
|  | if (!value) | 
|  | return;  // No value, empty input and succeed. | 
|  |  | 
|  | std::vector<SourceDir> result; | 
|  | ExtractListOfRelativeDirs(scope->settings()->build_settings(), | 
|  | *value, input_dir, &result, err); | 
|  | (config_values->*accessor)().swap(result); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | ConfigValuesGenerator::ConfigValuesGenerator( | 
|  | ConfigValues* dest_values, | 
|  | Scope* scope, | 
|  | const SourceDir& input_dir, | 
|  | Err* err) | 
|  | : config_values_(dest_values), | 
|  | scope_(scope), | 
|  | input_dir_(input_dir), | 
|  | err_(err) { | 
|  | } | 
|  |  | 
|  | ConfigValuesGenerator::~ConfigValuesGenerator() = default; | 
|  |  | 
|  | void ConfigValuesGenerator::Run() { | 
|  | #define FILL_STRING_CONFIG_VALUE(name) \ | 
|  | GetStringList(scope_, #name, config_values_, &ConfigValues::name, err_); | 
|  | #define FILL_DIR_CONFIG_VALUE(name) \ | 
|  | GetDirList(scope_, #name, config_values_, input_dir_, \ | 
|  | &ConfigValues::name, err_); | 
|  |  | 
|  | FILL_STRING_CONFIG_VALUE(arflags) | 
|  | FILL_STRING_CONFIG_VALUE(asmflags) | 
|  | FILL_STRING_CONFIG_VALUE(cflags) | 
|  | FILL_STRING_CONFIG_VALUE(cflags_c) | 
|  | FILL_STRING_CONFIG_VALUE(cflags_cc) | 
|  | FILL_STRING_CONFIG_VALUE(cflags_objc) | 
|  | FILL_STRING_CONFIG_VALUE(cflags_objcc) | 
|  | FILL_STRING_CONFIG_VALUE(defines) | 
|  | FILL_DIR_CONFIG_VALUE(   include_dirs) | 
|  | FILL_STRING_CONFIG_VALUE(ldflags) | 
|  | FILL_DIR_CONFIG_VALUE(   lib_dirs) | 
|  |  | 
|  | #undef FILL_STRING_CONFIG_VALUE | 
|  | #undef FILL_DIR_CONFIG_VALUE | 
|  |  | 
|  | // Inputs | 
|  | const Value* inputs_value = scope_->GetValue(variables::kInputs, true); | 
|  | if (inputs_value) { | 
|  | ExtractListOfRelativeFiles(scope_->settings()->build_settings(), | 
|  | *inputs_value, input_dir_, | 
|  | &config_values_->inputs(), err_); | 
|  | } | 
|  |  | 
|  | // Libs | 
|  | const Value* libs_value = scope_->GetValue("libs", true); | 
|  | if (libs_value) { | 
|  | ExtractListOfLibs(scope_->settings()->build_settings(), *libs_value, | 
|  | input_dir_, &config_values_->libs(), err_); | 
|  | } | 
|  |  | 
|  | // Precompiled headers. | 
|  | const Value* precompiled_header_value = | 
|  | scope_->GetValue(variables::kPrecompiledHeader, true); | 
|  | if (precompiled_header_value) { | 
|  | if (!precompiled_header_value->VerifyTypeIs(Value::STRING, err_)) | 
|  | return; | 
|  |  | 
|  | // Check for common errors. This is a string and not a file. | 
|  | const std::string& pch_string = precompiled_header_value->string_value(); | 
|  | if (base::StartsWith(pch_string, "//", base::CompareCase::SENSITIVE)) { | 
|  | *err_ = Err(*precompiled_header_value, | 
|  | "This precompiled_header value is wrong.", | 
|  | "You need to specify a string that the compiler will match against\n" | 
|  | "the #include lines rather than a GN-style file name.\n"); | 
|  | return; | 
|  | } | 
|  | config_values_->set_precompiled_header(pch_string); | 
|  | } | 
|  |  | 
|  | const Value* precompiled_source_value = | 
|  | scope_->GetValue(variables::kPrecompiledSource, true); | 
|  | if (precompiled_source_value) { | 
|  | config_values_->set_precompiled_source( | 
|  | input_dir_.ResolveRelativeFile( | 
|  | *precompiled_source_value, err_, | 
|  | scope_->settings()->build_settings()->root_path_utf8())); | 
|  | if (err_->has_error()) | 
|  | return; | 
|  | } | 
|  | } |