| // 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) | |
| FILL_STRING_CONFIG_VALUE(rustflags) | |
| FILL_STRING_CONFIG_VALUE(rustenv) | |
| #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; | |
| } | |
| } |