blob: 20551f19475d278c5e68e60a08dba209b772c4e1 [file] [log] [blame]
// 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());
// 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() {
}