Home | History | Annotate | Download | only in gn
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "tools/gn/test_with_scope.h"
      6 
      7 #include "base/bind.h"
      8 #include "tools/gn/parser.h"
      9 #include "tools/gn/tokenizer.h"
     10 
     11 namespace {
     12 
     13 void SetCommandForTool(const std::string& cmd, Tool* tool) {
     14   Err err;
     15   SubstitutionPattern command;
     16   command.Parse(cmd, NULL, &err);
     17   CHECK(!err.has_error())
     18       << "Couldn't parse \"" << cmd << "\", " << "got " << err.message();
     19   tool->set_command(command);
     20 }
     21 
     22 }  // namespace
     23 
     24 TestWithScope::TestWithScope()
     25     : build_settings_(),
     26       settings_(&build_settings_, std::string()),
     27       toolchain_(&settings_, Label(SourceDir("//toolchain/"), "default")),
     28       scope_(&settings_) {
     29   build_settings_.SetBuildDir(SourceDir("//out/Debug/"));
     30   build_settings_.set_print_callback(
     31       base::Bind(&TestWithScope::AppendPrintOutput, base::Unretained(this)));
     32 
     33   settings_.set_toolchain_label(toolchain_.label());
     34   settings_.set_default_toolchain_label(toolchain_.label());
     35 
     36   SetupToolchain(&toolchain_);
     37 }
     38 
     39 TestWithScope::~TestWithScope() {
     40 }
     41 
     42 // static
     43 void TestWithScope::SetupToolchain(Toolchain* toolchain) {
     44   Err err;
     45 
     46   // CC
     47   scoped_ptr<Tool> cc_tool(new Tool);
     48   SetCommandForTool(
     49       "cc {{source}} {{cflags}} {{cflags_c}} {{defines}} {{include_dirs}} "
     50       "-o {{output}}",
     51       cc_tool.get());
     52   cc_tool->set_outputs(SubstitutionList::MakeForTest(
     53       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
     54   toolchain->SetTool(Toolchain::TYPE_CC, cc_tool.Pass());
     55 
     56   // CXX
     57   scoped_ptr<Tool> cxx_tool(new Tool);
     58   SetCommandForTool(
     59       "c++ {{source}} {{cflags}} {{cflags_cc}} {{defines}} {{include_dirs}} "
     60       "-o {{output}}",
     61       cxx_tool.get());
     62   cxx_tool->set_outputs(SubstitutionList::MakeForTest(
     63       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
     64   toolchain->SetTool(Toolchain::TYPE_CXX, cxx_tool.Pass());
     65 
     66   // OBJC
     67   scoped_ptr<Tool> objc_tool(new Tool);
     68   SetCommandForTool(
     69       "objcc {{source}} {{cflags}} {{cflags_objc}} {{defines}} "
     70       "{{include_dirs}} -o {{output}}",
     71       objc_tool.get());
     72   objc_tool->set_outputs(SubstitutionList::MakeForTest(
     73       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
     74   toolchain->SetTool(Toolchain::TYPE_OBJC, objc_tool.Pass());
     75 
     76   // OBJC
     77   scoped_ptr<Tool> objcxx_tool(new Tool);
     78   SetCommandForTool(
     79       "objcxx {{source}} {{cflags}} {{cflags_objcc}} {{defines}} "
     80       "{{include_dirs}} -o {{output}}",
     81       objcxx_tool.get());
     82   objcxx_tool->set_outputs(SubstitutionList::MakeForTest(
     83       "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o"));
     84   toolchain->SetTool(Toolchain::TYPE_OBJCXX, objcxx_tool.Pass());
     85 
     86   // Don't use RC and ASM tools in unit tests yet. Add here if needed.
     87 
     88   // ALINK
     89   scoped_ptr<Tool> alink_tool(new Tool);
     90   SetCommandForTool("ar {{output}} {{source}}", alink_tool.get());
     91   alink_tool->set_output_prefix("lib");
     92   alink_tool->set_outputs(SubstitutionList::MakeForTest(
     93       "{{target_out_dir}}/{{target_output_name}}.a"));
     94   toolchain->SetTool(Toolchain::TYPE_ALINK, alink_tool.Pass());
     95 
     96   // SOLINK
     97   scoped_ptr<Tool> solink_tool(new Tool);
     98   SetCommandForTool("ld -shared -o {{target_output_name}}.so {{inputs}} "
     99       "{{ldflags}} {{libs}}", solink_tool.get());
    100   solink_tool->set_output_prefix("lib");
    101   solink_tool->set_default_output_extension(".so");
    102   solink_tool->set_outputs(SubstitutionList::MakeForTest(
    103       "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"));
    104   toolchain->SetTool(Toolchain::TYPE_SOLINK, solink_tool.Pass());
    105 
    106   // LINK
    107   scoped_ptr<Tool> link_tool(new Tool);
    108   SetCommandForTool("ld -o {{target_output_name}} {{source}} "
    109       "{{ldflags}} {{libs}}", link_tool.get());
    110   link_tool->set_outputs(SubstitutionList::MakeForTest(
    111       "{{root_out_dir}}/{{target_output_name}}"));
    112   toolchain->SetTool(Toolchain::TYPE_LINK, link_tool.Pass());
    113 
    114   // STAMP
    115   scoped_ptr<Tool> stamp_tool(new Tool);
    116   SetCommandForTool("touch {{output}}", stamp_tool.get());
    117   toolchain->SetTool(Toolchain::TYPE_STAMP, stamp_tool.Pass());
    118 
    119   // COPY
    120   scoped_ptr<Tool> copy_tool(new Tool);
    121   SetCommandForTool("cp {{source}} {{output}}", copy_tool.get());
    122   toolchain->SetTool(Toolchain::TYPE_COPY, copy_tool.Pass());
    123 
    124   toolchain->ToolchainSetupComplete();
    125 }
    126 
    127 void TestWithScope::AppendPrintOutput(const std::string& str) {
    128   print_output_.append(str);
    129 }
    130 
    131 TestParseInput::TestParseInput(const std::string& input)
    132     : input_file_(SourceFile("//test")) {
    133   input_file_.SetContents(input);
    134 
    135   tokens_ = Tokenizer::Tokenize(&input_file_, &parse_err_);
    136   if (!parse_err_.has_error())
    137     parsed_ = Parser::Parse(tokens_, &parse_err_);
    138 }
    139 
    140 TestParseInput::~TestParseInput() {
    141 }
    142