OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 <algorithm> |
| 6 |
| 7 #include "testing/gtest/include/gtest/gtest.h" |
| 8 #include "tools/gn/runtime_deps.h" |
| 9 #include "tools/gn/target.h" |
| 10 #include "tools/gn/test_with_scope.h" |
| 11 |
| 12 namespace { |
| 13 |
| 14 void InitTargetWithType(TestWithScope& setup, |
| 15 Target* target, |
| 16 Target::OutputType type) { |
| 17 target->set_output_type(type); |
| 18 target->visibility().SetPublic(); |
| 19 target->SetToolchain(setup.toolchain()); |
| 20 } |
| 21 |
| 22 // Convenience function to make the correct kind of pair. |
| 23 std::pair<OutputFile, const Target*> MakePair(const char* str, |
| 24 const Target* t) { |
| 25 return std::pair<OutputFile, const Target*>(OutputFile(str), t); |
| 26 } |
| 27 |
| 28 std::string GetVectorDescription( |
| 29 const std::vector<std::pair<OutputFile, const Target*>>& v) { |
| 30 std::string result; |
| 31 for (size_t i = 0; i < v.size(); i++) { |
| 32 if (i != 0) |
| 33 result.append(", "); |
| 34 result.append("\"" + v[i].first.value() + "\""); |
| 35 } |
| 36 return result; |
| 37 } |
| 38 |
| 39 } // namespace |
| 40 |
| 41 // Tests an exe depending on different types of libraries. |
| 42 TEST(RuntimeDeps, Libs) { |
| 43 TestWithScope setup; |
| 44 Err err; |
| 45 |
| 46 // Dependency hierarchy: main(exe) -> stat |
| 47 // -> shared |
| 48 // -> set |
| 49 |
| 50 Target stat(setup.settings(), Label(SourceDir("//"), "stat")); |
| 51 InitTargetWithType(setup, &stat, Target::STATIC_LIBRARY); |
| 52 stat.data().push_back(SourceFile("//stat.dat")); |
| 53 ASSERT_TRUE(stat.OnResolved(&err)); |
| 54 |
| 55 Target shared(setup.settings(), Label(SourceDir("//"), "shared")); |
| 56 InitTargetWithType(setup, &shared, Target::SHARED_LIBRARY); |
| 57 shared.data().push_back(SourceFile("//shared.dat")); |
| 58 ASSERT_TRUE(shared.OnResolved(&err)); |
| 59 |
| 60 Target set(setup.settings(), Label(SourceDir("//"), "set")); |
| 61 InitTargetWithType(setup, &set, Target::SOURCE_SET); |
| 62 set.data().push_back(SourceFile("//set.dat")); |
| 63 ASSERT_TRUE(set.OnResolved(&err)); |
| 64 |
| 65 Target main(setup.settings(), Label(SourceDir("//"), "main")); |
| 66 InitTargetWithType(setup, &main, Target::EXECUTABLE); |
| 67 main.private_deps().push_back(LabelTargetPair(&stat)); |
| 68 main.private_deps().push_back(LabelTargetPair(&shared)); |
| 69 main.private_deps().push_back(LabelTargetPair(&set)); |
| 70 main.data().push_back(SourceFile("//main.dat")); |
| 71 ASSERT_TRUE(main.OnResolved(&err)); |
| 72 |
| 73 std::vector<std::pair<OutputFile, const Target*>> result = |
| 74 ComputeRuntimeDeps(&main); |
| 75 |
| 76 // The result should have deps of main, all 4 dat files, and libshared.so |
| 77 ASSERT_EQ(6u, result.size()) << GetVectorDescription(result); |
| 78 |
| 79 // The first one should always be the main exe. |
| 80 EXPECT_TRUE(MakePair("./main", &main) == result[0]); |
| 81 |
| 82 // The rest of the ordering is undefined. First the data files. |
| 83 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 84 MakePair("../../stat.dat", &stat)) != |
| 85 result.end()) << GetVectorDescription(result); |
| 86 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 87 MakePair("../../shared.dat", &shared)) != |
| 88 result.end()) << GetVectorDescription(result); |
| 89 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 90 MakePair("../../set.dat", &set)) != |
| 91 result.end()) << GetVectorDescription(result); |
| 92 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 93 MakePair("../../main.dat", &main)) != |
| 94 result.end()) << GetVectorDescription(result); |
| 95 |
| 96 // Check the static library |
| 97 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 98 MakePair("./libshared.so", &shared)) != |
| 99 result.end()) << GetVectorDescription(result); |
| 100 } |
| 101 |
| 102 // Tests that executables that aren't listed as data deps aren't included in |
| 103 // the output, but executables that are data deps are included. |
| 104 TEST(RuntimeDeps, ExeDataDep) { |
| 105 TestWithScope setup; |
| 106 Err err; |
| 107 |
| 108 // Dependency hierarchy: main(exe) -> datadep(exe) -> final_in(source set) |
| 109 // -> dep(exe) -> final_out(source set) |
| 110 // The final_in/out targets each have data files. final_in's should be |
| 111 // included, final_out's should not be. |
| 112 |
| 113 Target final_in(setup.settings(), Label(SourceDir("//"), "final_in")); |
| 114 InitTargetWithType(setup, &final_in, Target::SOURCE_SET); |
| 115 final_in.data().push_back(SourceFile("//final_in.dat")); |
| 116 ASSERT_TRUE(final_in.OnResolved(&err)); |
| 117 |
| 118 Target datadep(setup.settings(), Label(SourceDir("//"), "datadep")); |
| 119 InitTargetWithType(setup, &datadep, Target::EXECUTABLE); |
| 120 datadep.private_deps().push_back(LabelTargetPair(&final_in)); |
| 121 ASSERT_TRUE(datadep.OnResolved(&err)); |
| 122 |
| 123 Target final_out(setup.settings(), Label(SourceDir("//"), "final_out")); |
| 124 InitTargetWithType(setup, &final_out, Target::SOURCE_SET); |
| 125 final_out.data().push_back(SourceFile("//final_out.dat")); |
| 126 ASSERT_TRUE(final_out.OnResolved(&err)); |
| 127 |
| 128 Target dep(setup.settings(), Label(SourceDir("//"), "dep")); |
| 129 InitTargetWithType(setup, &dep, Target::EXECUTABLE); |
| 130 dep.private_deps().push_back(LabelTargetPair(&final_out)); |
| 131 ASSERT_TRUE(dep.OnResolved(&err)); |
| 132 |
| 133 Target main(setup.settings(), Label(SourceDir("//"), "main")); |
| 134 InitTargetWithType(setup, &main, Target::EXECUTABLE); |
| 135 main.private_deps().push_back(LabelTargetPair(&dep)); |
| 136 main.data_deps().push_back(LabelTargetPair(&datadep)); |
| 137 ASSERT_TRUE(main.OnResolved(&err)); |
| 138 |
| 139 std::vector<std::pair<OutputFile, const Target*>> result = |
| 140 ComputeRuntimeDeps(&main); |
| 141 |
| 142 // The result should have deps of main, datadep, final_in.dat |
| 143 ASSERT_EQ(3u, result.size()) << GetVectorDescription(result); |
| 144 |
| 145 // The first one should always be the main exe. |
| 146 EXPECT_TRUE(MakePair("./main", &main) == result[0]); |
| 147 |
| 148 // The rest of the ordering is undefined. |
| 149 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 150 MakePair("./datadep", &datadep)) != |
| 151 result.end()) << GetVectorDescription(result); |
| 152 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 153 MakePair("../../final_in.dat", &final_in)) != |
| 154 result.end()) << GetVectorDescription(result); |
| 155 } |
| 156 |
| 157 // Tests that action and copy outputs are considered if they're data deps, but |
| 158 // not if they're regular deps. Action and copy "data" files are always |
| 159 // included. |
| 160 TEST(RuntimeDeps, ActionOutputs) { |
| 161 TestWithScope setup; |
| 162 Err err; |
| 163 |
| 164 // Dependency hierarchy: main(exe) -> datadep (action) |
| 165 // -> datadep_copy (copy) |
| 166 // -> dep (action) |
| 167 // -> dep_copy (copy) |
| 168 |
| 169 Target datadep(setup.settings(), Label(SourceDir("//"), "datadep")); |
| 170 InitTargetWithType(setup, &datadep, Target::ACTION); |
| 171 datadep.data().push_back(SourceFile("//datadep.data")); |
| 172 datadep.action_values().outputs() = |
| 173 SubstitutionList::MakeForTest("//datadep.output"); |
| 174 ASSERT_TRUE(datadep.OnResolved(&err)); |
| 175 |
| 176 Target datadep_copy(setup.settings(), Label(SourceDir("//"), "datadep_copy")); |
| 177 InitTargetWithType(setup, &datadep_copy, Target::COPY_FILES); |
| 178 datadep_copy.sources().push_back(SourceFile("//input")); |
| 179 datadep_copy.data().push_back(SourceFile("//datadep_copy.data")); |
| 180 datadep_copy.action_values().outputs() = |
| 181 SubstitutionList::MakeForTest("//datadep_copy.output"); |
| 182 ASSERT_TRUE(datadep_copy.OnResolved(&err)); |
| 183 |
| 184 Target dep(setup.settings(), Label(SourceDir("//"), "dep")); |
| 185 InitTargetWithType(setup, &dep, Target::ACTION); |
| 186 dep.data().push_back(SourceFile("//dep.data")); |
| 187 dep.action_values().outputs() = |
| 188 SubstitutionList::MakeForTest("//dep.output"); |
| 189 ASSERT_TRUE(dep.OnResolved(&err)); |
| 190 |
| 191 Target dep_copy(setup.settings(), Label(SourceDir("//"), "dep_copy")); |
| 192 InitTargetWithType(setup, &dep_copy, Target::COPY_FILES); |
| 193 dep_copy.sources().push_back(SourceFile("//input")); |
| 194 dep_copy.data().push_back(SourceFile("//dep_copy.data")); |
| 195 dep_copy.action_values().outputs() = |
| 196 SubstitutionList::MakeForTest("//dep_copy.output"); |
| 197 ASSERT_TRUE(dep_copy.OnResolved(&err)); |
| 198 |
| 199 Target main(setup.settings(), Label(SourceDir("//"), "main")); |
| 200 InitTargetWithType(setup, &main, Target::EXECUTABLE); |
| 201 main.private_deps().push_back(LabelTargetPair(&dep)); |
| 202 main.private_deps().push_back(LabelTargetPair(&dep_copy)); |
| 203 main.data_deps().push_back(LabelTargetPair(&datadep)); |
| 204 main.data_deps().push_back(LabelTargetPair(&datadep_copy)); |
| 205 ASSERT_TRUE(main.OnResolved(&err)); |
| 206 |
| 207 std::vector<std::pair<OutputFile, const Target*>> result = |
| 208 ComputeRuntimeDeps(&main); |
| 209 |
| 210 // The result should have deps of main, both datadeps files, but only |
| 211 // the data file from dep. |
| 212 ASSERT_EQ(7u, result.size()) << GetVectorDescription(result); |
| 213 |
| 214 // The first one should always be the main exe. |
| 215 EXPECT_TRUE(MakePair("./main", &main) == result[0]); |
| 216 |
| 217 // The rest of the ordering is undefined. |
| 218 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 219 MakePair("../../datadep.data", &datadep)) != |
| 220 result.end()) << GetVectorDescription(result); |
| 221 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 222 MakePair("../../datadep_copy.data", &datadep_copy)) != |
| 223 result.end()) << GetVectorDescription(result); |
| 224 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 225 MakePair("../../datadep.output", &datadep)) != |
| 226 result.end()) << GetVectorDescription(result); |
| 227 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 228 MakePair("../../datadep_copy.output", &datadep_copy)) != |
| 229 result.end()) << GetVectorDescription(result); |
| 230 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 231 MakePair("../../dep.data", &dep)) != |
| 232 result.end()) << GetVectorDescription(result); |
| 233 EXPECT_TRUE(std::find(result.begin(), result.end(), |
| 234 MakePair("../../dep_copy.data", &dep_copy)) != |
| 235 result.end()) << GetVectorDescription(result); |
| 236 |
| 237 // Explicitly asking for the runtime deps of an action target only includes |
| 238 // the data and not all outputs. |
| 239 result = ComputeRuntimeDeps(&dep); |
| 240 ASSERT_EQ(1u, result.size()); |
| 241 EXPECT_TRUE(MakePair("../../dep.data", &dep) == result[0]); |
| 242 } |
OLD | NEW |