1 // Copyright 2014 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.
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "tools/gn/ninja_target_writer.h"
9 #include "tools/gn/target.h"
10 #include "tools/gn/test_with_scope.h"
14 class TestingNinjaTargetWriter
: public NinjaTargetWriter
{
16 TestingNinjaTargetWriter(const Target
* target
,
17 const Toolchain
* toolchain
,
19 : NinjaTargetWriter(target
, out
) {
22 void Run() override
{}
24 // Make this public so the test can call it.
25 OutputFile
WriteInputDepsStampAndGetDep(
26 const std::vector
<const Target
*>& extra_hard_deps
) {
27 return NinjaTargetWriter::WriteInputDepsStampAndGetDep(extra_hard_deps
);
33 TEST(NinjaTargetWriter
, WriteInputDepsStampAndGetDep
) {
37 // Make a base target that's a hard dep (action).
38 Target
base_target(setup
.settings(), Label(SourceDir("//foo/"), "base"));
39 base_target
.set_output_type(Target::ACTION
);
40 base_target
.visibility().SetPublic();
41 base_target
.SetToolchain(setup
.toolchain());
42 base_target
.action_values().set_script(SourceFile("//foo/script.py"));
44 // Dependent target that also includes a source prerequisite (should get
45 // included) and a source (should not be included).
46 Target
target(setup
.settings(), Label(SourceDir("//foo/"), "target"));
47 target
.set_output_type(Target::EXECUTABLE
);
48 target
.visibility().SetPublic();
49 target
.SetToolchain(setup
.toolchain());
50 target
.inputs().push_back(SourceFile("//foo/input.txt"));
51 target
.sources().push_back(SourceFile("//foo/source.txt"));
52 target
.public_deps().push_back(LabelTargetPair(&base_target
));
54 // Dependent action to test that action sources will be treated the same as
56 Target
action(setup
.settings(), Label(SourceDir("//foo/"), "action"));
57 action
.set_output_type(Target::ACTION
);
58 action
.visibility().SetPublic();
59 action
.SetToolchain(setup
.toolchain());
60 action
.action_values().set_script(SourceFile("//foo/script.py"));
61 action
.sources().push_back(SourceFile("//foo/action_source.txt"));
62 action
.public_deps().push_back(LabelTargetPair(&target
));
64 ASSERT_TRUE(base_target
.OnResolved(&err
));
65 ASSERT_TRUE(target
.OnResolved(&err
));
66 ASSERT_TRUE(action
.OnResolved(&err
));
68 // Input deps for the base (should be only the script itself).
70 std::ostringstream stream
;
71 TestingNinjaTargetWriter
writer(&base_target
, setup
.toolchain(), stream
);
73 writer
.WriteInputDepsStampAndGetDep(std::vector
<const Target
*>());
75 EXPECT_EQ("obj/foo/base.inputdeps.stamp", dep
.value());
76 EXPECT_EQ("build obj/foo/base.inputdeps.stamp: stamp "
77 "../../foo/script.py\n",
81 // Input deps for the target (should depend on the base).
83 std::ostringstream stream
;
84 TestingNinjaTargetWriter
writer(&target
, setup
.toolchain(), stream
);
86 writer
.WriteInputDepsStampAndGetDep(std::vector
<const Target
*>());
88 EXPECT_EQ("obj/foo/target.inputdeps.stamp", dep
.value());
89 EXPECT_EQ("build obj/foo/target.inputdeps.stamp: stamp "
90 "../../foo/input.txt obj/foo/base.stamp\n",
94 // Input deps for action which should depend on the base since its a hard dep
95 // that is a (indirect) dependency, as well as the the action source.
97 std::ostringstream stream
;
98 TestingNinjaTargetWriter
writer(&action
, setup
.toolchain(), stream
);
100 writer
.WriteInputDepsStampAndGetDep(std::vector
<const Target
*>());
102 EXPECT_EQ("obj/foo/action.inputdeps.stamp", dep
.value());
103 EXPECT_EQ("build obj/foo/action.inputdeps.stamp: stamp ../../foo/script.py "
104 "../../foo/action_source.txt obj/foo/base.stamp\n",
109 // Tests WriteInputDepsStampAndGetDep when toolchain deps are present.
110 TEST(NinjaTargetWriter
, WriteInputDepsStampAndGetDepWithToolchainDeps
) {
114 // Toolchain dependency. Here we make a target in the same toolchain for
115 // simplicity, but in real life (using the Builder) this would be rejected
116 // because it would be a circular dependency (the target depends on its
117 // toolchain, and the toolchain depends on this target).
118 Target
toolchain_dep_target(setup
.settings(),
119 Label(SourceDir("//foo/"), "setup"));
120 toolchain_dep_target
.set_output_type(Target::ACTION
);
121 toolchain_dep_target
.SetToolchain(setup
.toolchain());
122 ASSERT_TRUE(toolchain_dep_target
.OnResolved(&err
));
123 setup
.toolchain()->deps().push_back(LabelTargetPair(&toolchain_dep_target
));
125 // Make a binary target
126 Target
target(setup
.settings(), Label(SourceDir("//foo/"), "target"));
127 target
.set_output_type(Target::EXECUTABLE
);
128 target
.SetToolchain(setup
.toolchain());
129 ASSERT_TRUE(target
.OnResolved(&err
));
131 std::ostringstream stream
;
132 TestingNinjaTargetWriter
writer(&target
, setup
.toolchain(), stream
);
134 writer
.WriteInputDepsStampAndGetDep(std::vector
<const Target
*>());
136 EXPECT_EQ("obj/foo/target.inputdeps.stamp", dep
.value());
137 EXPECT_EQ("build obj/foo/target.inputdeps.stamp: stamp "
138 "obj/foo/setup.stamp\n",