1 // Copyright 2016 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 "gn/functions.h"
6 #include "gn/rust_tool.h"
7 #include "gn/scheduler.h"
8 #include "gn/test_with_scheduler.h"
9 #include "gn/test_with_scope.h"
10 #include "util/test/test.h"
11
12 using FunctionToolchain = TestWithScheduler;
13
TEST_F(FunctionToolchain,RuntimeOutputs)14 TEST_F(FunctionToolchain, RuntimeOutputs) {
15 TestWithScope setup;
16
17 // These runtime outputs are a subset of the outputs so are OK.
18 {
19 TestParseInput input(
20 R"(toolchain("good") {
21 tool("link") {
22 outputs = [ "foo" ]
23 runtime_outputs = [ "foo" ]
24 }
25 })");
26 ASSERT_FALSE(input.has_error());
27
28 Err err;
29 input.parsed()->Execute(setup.scope(), &err);
30 ASSERT_FALSE(err.has_error()) << err.message();
31
32 // It should have generated a toolchain.
33 ASSERT_EQ(1u, setup.items().size());
34 const Toolchain* toolchain = setup.items()[0]->AsToolchain();
35 ASSERT_TRUE(toolchain);
36
37 // The toolchain should have a link tool with the two outputs.
38 const Tool* link = toolchain->GetTool(CTool::kCToolLink);
39 ASSERT_TRUE(link);
40 ASSERT_EQ(1u, link->outputs().list().size());
41 EXPECT_EQ("foo", link->outputs().list()[0].AsString());
42 ASSERT_EQ(1u, link->runtime_outputs().list().size());
43 EXPECT_EQ("foo", link->runtime_outputs().list()[0].AsString());
44 }
45
46 // This one is not a subset so should throw an error.
47 {
48 TestParseInput input(
49 R"(toolchain("bad") {
50 tool("link") {
51 outputs = [ "foo" ]
52 runtime_outputs = [ "bar" ]
53 }
54 })");
55 ASSERT_FALSE(input.has_error());
56
57 Err err;
58 input.parsed()->Execute(setup.scope(), &err);
59 ASSERT_TRUE(err.has_error()) << err.message();
60 }
61 }
62
TEST_F(FunctionToolchain,Rust)63 TEST_F(FunctionToolchain, Rust) {
64 TestWithScope setup;
65
66 // These runtime outputs are a subset of the outputs so are OK.
67 {
68 TestParseInput input(
69 R"(toolchain("rust") {
70 tool("rust_bin") {
71 command = "{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin {{rustflags}} -o {{output}} {{externs}} {{source}}"
72 description = "RUST {{output}}"
73 }
74 })");
75 ASSERT_FALSE(input.has_error());
76
77 Err err;
78 input.parsed()->Execute(setup.scope(), &err);
79 ASSERT_FALSE(err.has_error()) << err.message();
80
81 // It should have generated a toolchain.
82 ASSERT_EQ(1u, setup.items().size());
83 const Toolchain* toolchain = setup.items()[0]->AsToolchain();
84 ASSERT_TRUE(toolchain);
85
86 const Tool* rust = toolchain->GetTool(RustTool::kRsToolBin);
87 ASSERT_TRUE(rust);
88 ASSERT_EQ(rust->command().AsString(),
89 "{{rustenv}} rustc --crate-name {{crate_name}} --crate-type bin "
90 "{{rustflags}} -o {{output}} {{externs}} {{source}}");
91 ASSERT_EQ(rust->description().AsString(), "RUST {{output}}");
92 }
93 }
94
TEST_F(FunctionToolchain,CommandLauncher)95 TEST_F(FunctionToolchain, CommandLauncher) {
96 TestWithScope setup;
97
98 TestParseInput input(
99 R"(toolchain("good") {
100 tool("cxx") {
101 command_launcher = "/usr/goma/gomacc"
102 }
103 })");
104 ASSERT_FALSE(input.has_error());
105
106 Err err;
107 input.parsed()->Execute(setup.scope(), &err);
108 ASSERT_FALSE(err.has_error()) << err.message();
109
110 // It should have generated a toolchain.
111 ASSERT_EQ(1u, setup.items().size());
112 const Toolchain* toolchain = setup.items()[0]->AsToolchain();
113 ASSERT_TRUE(toolchain);
114
115 // The toolchain should have a link tool with the two outputs.
116 const Tool* link = toolchain->GetTool(CTool::kCToolCxx);
117 ASSERT_TRUE(link);
118 EXPECT_EQ("/usr/goma/gomacc", link->command_launcher());
119 }
120