| // 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/test_with_scope.h" |
| |
| #include "base/bind.h" |
| #include "tools/gn/parser.h" |
| #include "tools/gn/tokenizer.h" |
| |
| TestWithScope::TestWithScope() |
| : build_settings_(), |
| settings_(&build_settings_, std::string()), |
| toolchain_(&settings_, Label(SourceDir("//toolchain/"), "default")), |
| scope_(&settings_), |
| scope_progammatic_provider_(&scope_, true) { |
| build_settings_.SetBuildDir(SourceDir("//out/Debug/")); |
| build_settings_.set_print_callback( |
| base::Bind(&TestWithScope::AppendPrintOutput, base::Unretained(this))); |
| |
| settings_.set_toolchain_label(toolchain_.label()); |
| settings_.set_default_toolchain_label(toolchain_.label()); |
| |
| SetupToolchain(&toolchain_); |
| } |
| |
| TestWithScope::~TestWithScope() { |
| } |
| |
| Label TestWithScope::ParseLabel(const std::string& str) const { |
| Err err; |
| Label result = Label::Resolve(SourceDir("//"), toolchain_.label(), |
| Value(nullptr, str), &err); |
| CHECK(!err.has_error()); |
| return result; |
| } |
| |
| // static |
| void TestWithScope::SetupToolchain(Toolchain* toolchain) { |
| Err err; |
| |
| // CC |
| scoped_ptr<Tool> cc_tool(new Tool); |
| SetCommandForTool( |
| "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} " |
| "-o {{output}}", |
| cc_tool.get()); |
| cc_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o")); |
| toolchain->SetTool(Toolchain::TYPE_CC, cc_tool.Pass()); |
| |
| // CXX |
| scoped_ptr<Tool> cxx_tool(new Tool); |
| SetCommandForTool( |
| "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} " |
| "-o {{output}}", |
| cxx_tool.get()); |
| cxx_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o")); |
| toolchain->SetTool(Toolchain::TYPE_CXX, cxx_tool.Pass()); |
| |
| // OBJC |
| scoped_ptr<Tool> objc_tool(new Tool); |
| SetCommandForTool( |
| "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} " |
| "{{include_dirs}} -o {{output}}", |
| objc_tool.get()); |
| objc_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o")); |
| toolchain->SetTool(Toolchain::TYPE_OBJC, objc_tool.Pass()); |
| |
| // OBJC |
| scoped_ptr<Tool> objcxx_tool(new Tool); |
| SetCommandForTool( |
| "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} " |
| "{{include_dirs}} -o {{output}}", |
| objcxx_tool.get()); |
| objcxx_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o")); |
| toolchain->SetTool(Toolchain::TYPE_OBJCXX, objcxx_tool.Pass()); |
| |
| // Don't use RC and ASM tools in unit tests yet. Add here if needed. |
| |
| // ALINK |
| scoped_ptr<Tool> alink_tool(new Tool); |
| SetCommandForTool("ar {{output}} {{source}}", alink_tool.get()); |
| alink_tool->set_output_prefix("lib"); |
| alink_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{target_out_dir}}/{{target_output_name}}.a")); |
| toolchain->SetTool(Toolchain::TYPE_ALINK, alink_tool.Pass()); |
| |
| // SOLINK |
| scoped_ptr<Tool> solink_tool(new Tool); |
| SetCommandForTool("ld -shared -o {{target_output_name}}.so {{inputs}} " |
| "{{ldflags}} {{libs}}", solink_tool.get()); |
| solink_tool->set_output_prefix("lib"); |
| solink_tool->set_default_output_extension(".so"); |
| solink_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{root_out_dir}}/{{target_output_name}}{{output_extension}}")); |
| toolchain->SetTool(Toolchain::TYPE_SOLINK, solink_tool.Pass()); |
| |
| // SOLINK_MODULE |
| scoped_ptr<Tool> solink_module_tool(new Tool); |
| SetCommandForTool("ld -bundle -o {{target_output_name}}.so {{inputs}} " |
| "{{ldflags}} {{libs}}", solink_module_tool.get()); |
| solink_module_tool->set_output_prefix("lib"); |
| solink_module_tool->set_default_output_extension(".so"); |
| solink_module_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{root_out_dir}}/{{target_output_name}}{{output_extension}}")); |
| toolchain->SetTool(Toolchain::TYPE_SOLINK_MODULE, solink_module_tool.Pass()); |
| |
| // LINK |
| scoped_ptr<Tool> link_tool(new Tool); |
| SetCommandForTool("ld -o {{target_output_name}} {{source}} " |
| "{{ldflags}} {{libs}}", link_tool.get()); |
| link_tool->set_outputs(SubstitutionList::MakeForTest( |
| "{{root_out_dir}}/{{target_output_name}}")); |
| toolchain->SetTool(Toolchain::TYPE_LINK, link_tool.Pass()); |
| |
| // STAMP |
| scoped_ptr<Tool> stamp_tool(new Tool); |
| SetCommandForTool("touch {{output}}", stamp_tool.get()); |
| toolchain->SetTool(Toolchain::TYPE_STAMP, stamp_tool.Pass()); |
| |
| // COPY |
| scoped_ptr<Tool> copy_tool(new Tool); |
| SetCommandForTool("cp {{source}} {{output}}", copy_tool.get()); |
| toolchain->SetTool(Toolchain::TYPE_COPY, copy_tool.Pass()); |
| |
| toolchain->ToolchainSetupComplete(); |
| } |
| |
| // static |
| void TestWithScope::SetCommandForTool(const std::string& cmd, Tool* tool) { |
| Err err; |
| SubstitutionPattern command; |
| command.Parse(cmd, nullptr, &err); |
| CHECK(!err.has_error()) |
| << "Couldn't parse \"" << cmd << "\", " << "got " << err.message(); |
| tool->set_command(command); |
| } |
| |
| void TestWithScope::AppendPrintOutput(const std::string& str) { |
| print_output_.append(str); |
| } |
| |
| TestParseInput::TestParseInput(const std::string& input) |
| : input_file_(SourceFile("//test")) { |
| input_file_.SetContents(input); |
| |
| tokens_ = Tokenizer::Tokenize(&input_file_, &parse_err_); |
| if (!parse_err_.has_error()) |
| parsed_ = Parser::Parse(tokens_, &parse_err_); |
| } |
| |
| TestParseInput::~TestParseInput() { |
| } |
| |
| TestTarget::TestTarget(TestWithScope& setup, |
| const std::string& label_string, |
| Target::OutputType type) |
| : Target(setup.settings(), setup.ParseLabel(label_string)) { |
| visibility().SetPublic(); |
| set_output_type(type); |
| SetToolchain(setup.toolchain()); |
| } |
| |
| TestTarget::~TestTarget() { |
| } |