1 // Copyright 2019 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/ninja_rust_binary_target_writer.h"
6
7 #include "gn/config.h"
8 #include "gn/pool.h"
9 #include "gn/rust_values.h"
10 #include "gn/scheduler.h"
11 #include "gn/target.h"
12 #include "gn/test_with_scheduler.h"
13 #include "gn/test_with_scope.h"
14 #include "util/build_config.h"
15 #include "util/test/test.h"
16
17 using NinjaRustBinaryTargetWriterTest = TestWithScheduler;
18
TEST_F(NinjaRustBinaryTargetWriterTest,RustSourceSet)19 TEST_F(NinjaRustBinaryTargetWriterTest, RustSourceSet) {
20 Err err;
21 TestWithScope setup;
22
23 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
24 target.set_output_type(Target::SOURCE_SET);
25 target.visibility().SetPublic();
26 target.sources().push_back(SourceFile("//foo/input1.rs"));
27 target.sources().push_back(SourceFile("//foo/main.rs"));
28 target.source_types_used().Set(SourceFile::SOURCE_RS);
29 target.SetToolchain(setup.toolchain());
30 ASSERT_FALSE(target.OnResolved(&err));
31 }
32
TEST_F(NinjaRustBinaryTargetWriterTest,RustExecutable)33 TEST_F(NinjaRustBinaryTargetWriterTest, RustExecutable) {
34 Err err;
35 TestWithScope setup;
36
37 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
38 target.set_output_type(Target::EXECUTABLE);
39 target.visibility().SetPublic();
40 SourceFile main("//foo/main.rs");
41 target.sources().push_back(SourceFile("//foo/input3.rs"));
42 target.sources().push_back(main);
43 target.source_types_used().Set(SourceFile::SOURCE_RS);
44 target.rust_values().set_crate_root(main);
45 target.rust_values().crate_name() = "foo_bar";
46 target.config_values().ldflags().push_back("-fsanitize=address");
47 target.SetToolchain(setup.toolchain());
48 ASSERT_TRUE(target.OnResolved(&err));
49
50 {
51 std::ostringstream out;
52 NinjaRustBinaryTargetWriter writer(&target, out);
53 writer.Run();
54
55 const char expected[] =
56 "crate_name = foo_bar\n"
57 "crate_type = bin\n"
58 "output_extension = \n"
59 "output_dir = \n"
60 "rustflags =\n"
61 "rustenv =\n"
62 "root_out_dir = .\n"
63 "target_gen_dir = gen/foo\n"
64 "target_out_dir = obj/foo\n"
65 "target_output_name = bar\n"
66 "\n"
67 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/input3.rs "
68 "../../foo/main.rs\n"
69 " source_file_part = main.rs\n"
70 " source_name_part = main\n"
71 " externs =\n"
72 " rustdeps =\n"
73 " ldflags = -fsanitize=address\n"
74 " sources = ../../foo/input3.rs ../../foo/main.rs\n";
75 std::string out_str = out.str();
76 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
77 }
78 }
79
80 // Accessible dependencies appear as --extern switches for rustc, so that the
81 // target crate can make use of them whether transitive or not. Transitive
82 // dependencies can be accessible if they are in the public_deps of a direct
83 // dependency, or part of a chain of public_deps from a direct dependency. Any
84 // dependencies used by other crate dependencies also must appear, but are
85 // pointed to by -Ldependency as they are not available for use from the target
86 // crate. In the future they may move to `--extern priv:` when explicit private
87 // dependencies are stabilized.
TEST_F(NinjaRustBinaryTargetWriterTest,RlibDeps)88 TEST_F(NinjaRustBinaryTargetWriterTest, RlibDeps) {
89 Err err;
90 TestWithScope setup;
91
92 Target private_rlib(setup.settings(),
93 Label(SourceDir("//baz/"), "privatelib"));
94 private_rlib.set_output_type(Target::RUST_LIBRARY);
95 private_rlib.visibility().SetPublic();
96 SourceFile bazlib("//baz/lib.rs");
97 private_rlib.sources().push_back(SourceFile("//baz/privatelib.rs"));
98 private_rlib.sources().push_back(bazlib);
99 private_rlib.source_types_used().Set(SourceFile::SOURCE_RS);
100 private_rlib.rust_values().set_crate_root(bazlib);
101 private_rlib.rust_values().crate_name() = "privatecrate";
102 private_rlib.SetToolchain(setup.toolchain());
103 ASSERT_TRUE(private_rlib.OnResolved(&err));
104
105 {
106 std::ostringstream out;
107 NinjaRustBinaryTargetWriter writer(&private_rlib, out);
108 writer.Run();
109
110 const char expected[] =
111 "crate_name = privatecrate\n"
112 "crate_type = rlib\n"
113 "output_extension = .rlib\n"
114 "output_dir = \n"
115 "rustflags =\n"
116 "rustenv =\n"
117 "root_out_dir = .\n"
118 "target_gen_dir = gen/baz\n"
119 "target_out_dir = obj/baz\n"
120 "target_output_name = libprivatelib\n"
121 "\n"
122 "build obj/baz/libprivatelib.rlib: rust_rlib ../../baz/lib.rs | "
123 "../../baz/privatelib.rs ../../baz/lib.rs\n"
124 " source_file_part = lib.rs\n"
125 " source_name_part = lib\n"
126 " externs =\n"
127 " rustdeps =\n"
128 " ldflags =\n"
129 " sources = ../../baz/privatelib.rs ../../baz/lib.rs\n";
130 std::string out_str = out.str();
131 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
132 }
133
134 Target far_public_rlib(setup.settings(),
135 Label(SourceDir("//far/"), "farlib"));
136 far_public_rlib.set_output_type(Target::RUST_LIBRARY);
137 far_public_rlib.visibility().SetPublic();
138 SourceFile farlib("//far/lib.rs");
139 far_public_rlib.sources().push_back(SourceFile("//far/farlib.rs"));
140 far_public_rlib.sources().push_back(farlib);
141 far_public_rlib.source_types_used().Set(SourceFile::SOURCE_RS);
142 far_public_rlib.rust_values().set_crate_root(farlib);
143 far_public_rlib.rust_values().crate_name() = "farcrate";
144 far_public_rlib.SetToolchain(setup.toolchain());
145 ASSERT_TRUE(far_public_rlib.OnResolved(&err));
146
147 {
148 std::ostringstream out;
149 NinjaRustBinaryTargetWriter writer(&far_public_rlib, out);
150 writer.Run();
151
152 const char expected[] =
153 "crate_name = farcrate\n"
154 "crate_type = rlib\n"
155 "output_extension = .rlib\n"
156 "output_dir = \n"
157 "rustflags =\n"
158 "rustenv =\n"
159 "root_out_dir = .\n"
160 "target_gen_dir = gen/far\n"
161 "target_out_dir = obj/far\n"
162 "target_output_name = libfarlib\n"
163 "\n"
164 "build obj/far/libfarlib.rlib: rust_rlib ../../far/lib.rs | "
165 "../../far/farlib.rs ../../far/lib.rs\n"
166 " source_file_part = lib.rs\n"
167 " source_name_part = lib\n"
168 " externs =\n"
169 " rustdeps =\n"
170 " ldflags =\n"
171 " sources = ../../far/farlib.rs ../../far/lib.rs\n";
172 std::string out_str = out.str();
173 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
174 }
175
176 Target public_rlib(setup.settings(), Label(SourceDir("//bar/"), "publiclib"));
177 public_rlib.set_output_type(Target::RUST_LIBRARY);
178 public_rlib.visibility().SetPublic();
179 SourceFile barlib("//bar/lib.rs");
180 public_rlib.sources().push_back(SourceFile("//bar/publiclib.rs"));
181 public_rlib.sources().push_back(barlib);
182 public_rlib.source_types_used().Set(SourceFile::SOURCE_RS);
183 public_rlib.rust_values().set_crate_root(barlib);
184 public_rlib.rust_values().crate_name() = "publiccrate";
185 public_rlib.public_deps().push_back(LabelTargetPair(&far_public_rlib));
186 public_rlib.SetToolchain(setup.toolchain());
187 ASSERT_TRUE(public_rlib.OnResolved(&err));
188
189 {
190 std::ostringstream out;
191 NinjaRustBinaryTargetWriter writer(&public_rlib, out);
192 writer.Run();
193
194 const char expected[] =
195 "crate_name = publiccrate\n"
196 "crate_type = rlib\n"
197 "output_extension = .rlib\n"
198 "output_dir = \n"
199 "rustflags =\n"
200 "rustenv =\n"
201 "root_out_dir = .\n"
202 "target_gen_dir = gen/bar\n"
203 "target_out_dir = obj/bar\n"
204 "target_output_name = libpubliclib\n"
205 "\n"
206 "build obj/bar/libpubliclib.rlib: rust_rlib ../../bar/lib.rs | "
207 "../../bar/publiclib.rs ../../bar/lib.rs obj/far/libfarlib.rlib\n"
208 " source_file_part = lib.rs\n"
209 " source_name_part = lib\n"
210 " externs = --extern farcrate=obj/far/libfarlib.rlib\n"
211 " rustdeps = -Ldependency=obj/far\n"
212 " ldflags =\n"
213 " sources = ../../bar/publiclib.rs ../../bar/lib.rs\n";
214 std::string out_str = out.str();
215 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
216 }
217
218 Target rlib(setup.settings(), Label(SourceDir("//foo/"), "direct"));
219 rlib.set_output_type(Target::RUST_LIBRARY);
220 rlib.visibility().SetPublic();
221 SourceFile lib("//foo/main.rs");
222 rlib.sources().push_back(SourceFile("//foo/direct.rs"));
223 rlib.sources().push_back(lib);
224 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
225 rlib.rust_values().set_crate_root(lib);
226 rlib.rust_values().crate_name() = "direct";
227 rlib.SetToolchain(setup.toolchain());
228 rlib.public_deps().push_back(LabelTargetPair(&public_rlib));
229 rlib.private_deps().push_back(LabelTargetPair(&private_rlib));
230 ASSERT_TRUE(rlib.OnResolved(&err));
231
232 Target target(setup.settings(), Label(SourceDir("//main/"), "main"));
233 target.set_output_type(Target::EXECUTABLE);
234 target.visibility().SetPublic();
235 SourceFile main("//main/main.rs");
236 target.sources().push_back(SourceFile("//main/source.rs"));
237 target.sources().push_back(main);
238 target.source_types_used().Set(SourceFile::SOURCE_RS);
239 target.rust_values().set_crate_root(main);
240 target.rust_values().crate_name() = "main_crate";
241 target.private_deps().push_back(LabelTargetPair(&rlib));
242 target.SetToolchain(setup.toolchain());
243 ASSERT_TRUE(target.OnResolved(&err));
244
245 {
246 std::ostringstream out;
247 NinjaRustBinaryTargetWriter writer(&target, out);
248 writer.Run();
249
250 const char expected[] =
251 "crate_name = main_crate\n"
252 "crate_type = bin\n"
253 "output_extension = \n"
254 "output_dir = \n"
255 "rustflags =\n"
256 "rustenv =\n"
257 "root_out_dir = .\n"
258 "target_gen_dir = gen/main\n"
259 "target_out_dir = obj/main\n"
260 "target_output_name = main\n"
261 "\n"
262 "build ./main_crate: rust_bin ../../main/main.rs | "
263 "../../main/source.rs ../../main/main.rs obj/foo/libdirect.rlib "
264 "obj/bar/libpubliclib.rlib obj/far/libfarlib.rlib "
265 "obj/baz/libprivatelib.rlib\n"
266 " source_file_part = main.rs\n"
267 " source_name_part = main\n"
268 " externs = --extern direct=obj/foo/libdirect.rlib "
269 "--extern publiccrate=obj/bar/libpubliclib.rlib "
270 "--extern farcrate=obj/far/libfarlib.rlib\n"
271 " rustdeps = -Ldependency=obj/foo -Ldependency=obj/bar "
272 "-Ldependency=obj/far -Ldependency=obj/baz\n"
273 " ldflags =\n"
274 " sources = ../../main/source.rs ../../main/main.rs\n";
275 std::string out_str = out.str();
276 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
277 }
278 }
279
TEST_F(NinjaRustBinaryTargetWriterTest,DylibDeps)280 TEST_F(NinjaRustBinaryTargetWriterTest, DylibDeps) {
281 Err err;
282 TestWithScope setup;
283
284 Target private_inside_dylib(setup.settings(),
285 Label(SourceDir("//faz/"), "private_inside"));
286 private_inside_dylib.set_output_type(Target::RUST_LIBRARY);
287 private_inside_dylib.visibility().SetPublic();
288 SourceFile fazlib("//faz/lib.rs");
289 private_inside_dylib.sources().push_back(
290 SourceFile("//faz/private_inside.rs"));
291 private_inside_dylib.sources().push_back(fazlib);
292 private_inside_dylib.source_types_used().Set(SourceFile::SOURCE_RS);
293 private_inside_dylib.rust_values().set_crate_root(fazlib);
294 private_inside_dylib.rust_values().crate_name() = "private_inside";
295 private_inside_dylib.SetToolchain(setup.toolchain());
296 ASSERT_TRUE(private_inside_dylib.OnResolved(&err));
297
298 {
299 std::ostringstream out;
300 NinjaRustBinaryTargetWriter writer(&private_inside_dylib, out);
301 writer.Run();
302
303 const char expected[] =
304 "crate_name = private_inside\n"
305 "crate_type = rlib\n"
306 "output_extension = .rlib\n"
307 "output_dir = \n"
308 "rustflags =\n"
309 "rustenv =\n"
310 "root_out_dir = .\n"
311 "target_gen_dir = gen/faz\n"
312 "target_out_dir = obj/faz\n"
313 "target_output_name = libprivate_inside\n"
314 "\n"
315 "build obj/faz/libprivate_inside.rlib: rust_rlib ../../faz/lib.rs | "
316 "../../faz/private_inside.rs ../../faz/lib.rs\n"
317 " source_file_part = lib.rs\n"
318 " source_name_part = lib\n"
319 " externs =\n"
320 " rustdeps =\n"
321 " ldflags =\n"
322 " sources = ../../faz/private_inside.rs ../../faz/lib.rs\n";
323 std::string out_str = out.str();
324 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
325 }
326
327 Target inside_dylib(setup.settings(), Label(SourceDir("//baz/"), "inside"));
328 inside_dylib.set_output_type(Target::RUST_LIBRARY);
329 inside_dylib.visibility().SetPublic();
330 SourceFile bazlib("//baz/lib.rs");
331 inside_dylib.sources().push_back(SourceFile("//baz/inside.rs"));
332 inside_dylib.sources().push_back(bazlib);
333 inside_dylib.source_types_used().Set(SourceFile::SOURCE_RS);
334 inside_dylib.rust_values().set_crate_root(bazlib);
335 inside_dylib.rust_values().crate_name() = "inside";
336 inside_dylib.SetToolchain(setup.toolchain());
337 ASSERT_TRUE(inside_dylib.OnResolved(&err));
338
339 {
340 std::ostringstream out;
341 NinjaRustBinaryTargetWriter writer(&inside_dylib, out);
342 writer.Run();
343
344 const char expected[] =
345 "crate_name = inside\n"
346 "crate_type = rlib\n"
347 "output_extension = .rlib\n"
348 "output_dir = \n"
349 "rustflags =\n"
350 "rustenv =\n"
351 "root_out_dir = .\n"
352 "target_gen_dir = gen/baz\n"
353 "target_out_dir = obj/baz\n"
354 "target_output_name = libinside\n"
355 "\n"
356 "build obj/baz/libinside.rlib: rust_rlib ../../baz/lib.rs | "
357 "../../baz/inside.rs ../../baz/lib.rs\n"
358 " source_file_part = lib.rs\n"
359 " source_name_part = lib\n"
360 " externs =\n"
361 " rustdeps =\n"
362 " ldflags =\n"
363 " sources = ../../baz/inside.rs ../../baz/lib.rs\n";
364 std::string out_str = out.str();
365 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
366 }
367
368 Target dylib(setup.settings(), Label(SourceDir("//bar/"), "mylib"));
369 dylib.set_output_type(Target::SHARED_LIBRARY);
370 dylib.visibility().SetPublic();
371 SourceFile barlib("//bar/lib.rs");
372 dylib.sources().push_back(SourceFile("//bar/mylib.rs"));
373 dylib.sources().push_back(barlib);
374 dylib.source_types_used().Set(SourceFile::SOURCE_RS);
375 dylib.rust_values().set_crate_type(RustValues::CRATE_DYLIB);
376 dylib.rust_values().set_crate_root(barlib);
377 dylib.rust_values().crate_name() = "mylib";
378 dylib.public_deps().push_back(LabelTargetPair(&inside_dylib));
379 dylib.private_deps().push_back(LabelTargetPair(&private_inside_dylib));
380 dylib.SetToolchain(setup.toolchain());
381 ASSERT_TRUE(dylib.OnResolved(&err));
382
383 {
384 std::ostringstream out;
385 NinjaRustBinaryTargetWriter writer(&dylib, out);
386 writer.Run();
387
388 const char expected[] =
389 "crate_name = mylib\n"
390 "crate_type = dylib\n"
391 "output_extension = .so\n"
392 "output_dir = \n"
393 "rustflags =\n"
394 "rustenv =\n"
395 "root_out_dir = .\n"
396 "target_gen_dir = gen/bar\n"
397 "target_out_dir = obj/bar\n"
398 "target_output_name = libmylib\n"
399 "\n"
400 "build obj/bar/libmylib.so: rust_dylib ../../bar/lib.rs | "
401 "../../bar/mylib.rs ../../bar/lib.rs "
402 "obj/baz/libinside.rlib obj/faz/libprivate_inside.rlib\n"
403 " source_file_part = lib.rs\n"
404 " source_name_part = lib\n"
405 " externs = --extern inside=obj/baz/libinside.rlib "
406 "--extern private_inside=obj/faz/libprivate_inside.rlib\n"
407 " rustdeps = -Ldependency=obj/baz -Ldependency=obj/faz\n"
408 " ldflags =\n"
409 " sources = ../../bar/mylib.rs ../../bar/lib.rs\n";
410 std::string out_str = out.str();
411 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
412 }
413
414 Target private_dylib(setup.settings(),
415 Label(SourceDir("//private_dylib/"), "private_dylib"));
416 private_dylib.set_output_type(Target::SHARED_LIBRARY);
417 private_dylib.visibility().SetPublic();
418 SourceFile private_dyliblib("//private_dylib/lib.rs");
419 private_dylib.sources().push_back(SourceFile("//private_dylib/mylib.rs"));
420 private_dylib.sources().push_back(private_dyliblib);
421 private_dylib.source_types_used().Set(SourceFile::SOURCE_RS);
422 private_dylib.rust_values().set_crate_type(RustValues::CRATE_DYLIB);
423 private_dylib.rust_values().set_crate_root(private_dyliblib);
424 private_dylib.rust_values().crate_name() = "private_dylib";
425 private_dylib.SetToolchain(setup.toolchain());
426 ASSERT_TRUE(private_dylib.OnResolved(&err));
427
428 Target another_dylib(setup.settings(), Label(SourceDir("//foo/"), "direct"));
429 another_dylib.set_output_type(Target::SHARED_LIBRARY);
430 another_dylib.visibility().SetPublic();
431 SourceFile lib("//foo/main.rs");
432 another_dylib.sources().push_back(SourceFile("//foo/direct.rs"));
433 another_dylib.sources().push_back(lib);
434 another_dylib.source_types_used().Set(SourceFile::SOURCE_RS);
435 another_dylib.rust_values().set_crate_type(RustValues::CRATE_DYLIB);
436 another_dylib.rust_values().set_crate_root(lib);
437 another_dylib.rust_values().crate_name() = "direct";
438 another_dylib.SetToolchain(setup.toolchain());
439 another_dylib.public_deps().push_back(LabelTargetPair(&dylib));
440 another_dylib.private_deps().push_back(LabelTargetPair(&private_dylib));
441 ASSERT_TRUE(another_dylib.OnResolved(&err));
442
443 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
444 target.set_output_type(Target::EXECUTABLE);
445 target.visibility().SetPublic();
446 SourceFile main("//foo/main.rs");
447 target.sources().push_back(SourceFile("//foo/source.rs"));
448 target.sources().push_back(main);
449 target.source_types_used().Set(SourceFile::SOURCE_RS);
450 target.rust_values().set_crate_root(main);
451 target.rust_values().crate_name() = "foo_bar";
452 target.private_deps().push_back(LabelTargetPair(&another_dylib));
453 target.SetToolchain(setup.toolchain());
454 ASSERT_TRUE(target.OnResolved(&err));
455
456 {
457 std::ostringstream out;
458 NinjaRustBinaryTargetWriter writer(&target, out);
459 writer.Run();
460
461 const char expected[] =
462 "crate_name = foo_bar\n"
463 "crate_type = bin\n"
464 "output_extension = \n"
465 "output_dir = \n"
466 "rustflags =\n"
467 "rustenv =\n"
468 "root_out_dir = .\n"
469 "target_gen_dir = gen/foo\n"
470 "target_out_dir = obj/foo\n"
471 "target_output_name = bar\n"
472 "\n"
473 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
474 "../../foo/main.rs obj/foo/libdirect.so obj/bar/libmylib.so "
475 "obj/baz/libinside.rlib\n"
476 " source_file_part = main.rs\n"
477 " source_name_part = main\n"
478 " externs = --extern direct=obj/foo/libdirect.so "
479 "--extern mylib=obj/bar/libmylib.so "
480 "--extern inside=obj/baz/libinside.rlib\n"
481 " rustdeps = -Ldependency=obj/foo -Ldependency=obj/bar "
482 "-Ldependency=obj/baz -Ldependency=obj/faz "
483 "-Ldependency=obj/private_dylib\n"
484 " ldflags =\n"
485 " sources = ../../foo/source.rs ../../foo/main.rs\n";
486 std::string out_str = out.str();
487 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
488 }
489 }
490
TEST_F(NinjaRustBinaryTargetWriterTest,RlibDepsAcrossGroups)491 TEST_F(NinjaRustBinaryTargetWriterTest, RlibDepsAcrossGroups) {
492 Err err;
493 TestWithScope setup;
494
495 Target procmacro(setup.settings(), Label(SourceDir("//bar/"), "mymacro"));
496 procmacro.set_output_type(Target::RUST_PROC_MACRO);
497 procmacro.visibility().SetPublic();
498 SourceFile barproc("//bar/lib.rs");
499 procmacro.sources().push_back(SourceFile("//bar/mylib.rs"));
500 procmacro.sources().push_back(barproc);
501 procmacro.source_types_used().Set(SourceFile::SOURCE_RS);
502 procmacro.rust_values().set_crate_root(barproc);
503 procmacro.rust_values().crate_name() = "mymacro";
504 procmacro.rust_values().set_crate_type(RustValues::CRATE_PROC_MACRO);
505 procmacro.SetToolchain(setup.toolchain());
506 ASSERT_TRUE(procmacro.OnResolved(&err));
507
508 {
509 std::ostringstream out;
510 NinjaRustBinaryTargetWriter writer(&procmacro, out);
511 writer.Run();
512
513 const char expected[] =
514 "crate_name = mymacro\n"
515 "crate_type = proc-macro\n"
516 "output_extension = .so\n"
517 "output_dir = \n"
518 "rustflags =\n"
519 "rustenv =\n"
520 "root_out_dir = .\n"
521 "target_gen_dir = gen/bar\n"
522 "target_out_dir = obj/bar\n"
523 "target_output_name = libmymacro\n"
524 "\n"
525 "build obj/bar/libmymacro.so: rust_macro ../../bar/lib.rs | "
526 "../../bar/mylib.rs ../../bar/lib.rs\n"
527 " source_file_part = lib.rs\n"
528 " source_name_part = lib\n"
529 " externs =\n"
530 " rustdeps =\n"
531 " ldflags =\n"
532 " sources = ../../bar/mylib.rs ../../bar/lib.rs\n";
533 std::string out_str = out.str();
534 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
535 }
536
537 // A group produces an order-only dependency in ninja:
538 // https://ninja-build.org/manual.html#ref_dependencies.
539 //
540 // If a crate D inside the group is visible to a crate C depending on the
541 // group, the crate C needs to be rebuilt when D is changed. The group
542 // dependency does not guarantee that it would, so we test that C has an
543 // indirect dependency on D through this group.
544 Target group(setup.settings(), Label(SourceDir("//baz/"), "group"));
545 group.set_output_type(Target::GROUP);
546 group.visibility().SetPublic();
547 group.public_deps().push_back(LabelTargetPair(&procmacro));
548 group.SetToolchain(setup.toolchain());
549 ASSERT_TRUE(group.OnResolved(&err));
550
551 Target rlib(setup.settings(), Label(SourceDir("//bar/"), "mylib"));
552 rlib.set_output_type(Target::RUST_LIBRARY);
553 rlib.visibility().SetPublic();
554 SourceFile barlib("//bar/lib.rs");
555 rlib.sources().push_back(SourceFile("//bar/mylib.rs"));
556 rlib.sources().push_back(barlib);
557 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
558 rlib.rust_values().set_crate_root(barlib);
559 rlib.rust_values().crate_name() = "mylib";
560 rlib.SetToolchain(setup.toolchain());
561 rlib.public_deps().push_back(LabelTargetPair(&group));
562 ASSERT_TRUE(rlib.OnResolved(&err));
563
564 {
565 std::ostringstream out;
566 NinjaRustBinaryTargetWriter writer(&rlib, out);
567 writer.Run();
568
569 // libmymacro.so is inside the obj/baz/group, so would be built before
570 // libmylib.rlib. However it must also cause libmylib.rlib to be recompiled
571 // when changed, so we expect an implicit dependency (appearing after `|` on
572 // the build line) from libmylib.rlib to libmymacro.so.
573 const char expected[] =
574 "crate_name = mylib\n"
575 "crate_type = rlib\n"
576 "output_extension = .rlib\n"
577 "output_dir = \n"
578 "rustflags =\n"
579 "rustenv =\n"
580 "root_out_dir = .\n"
581 "target_gen_dir = gen/bar\n"
582 "target_out_dir = obj/bar\n"
583 "target_output_name = libmylib\n"
584 "\n"
585 "build obj/bar/libmylib.rlib: rust_rlib ../../bar/lib.rs | "
586 "../../bar/mylib.rs ../../bar/lib.rs obj/bar/libmymacro.so || "
587 "obj/baz/group.stamp\n"
588 " source_file_part = lib.rs\n"
589 " source_name_part = lib\n"
590 " externs = --extern mymacro=obj/bar/libmymacro.so\n"
591 " rustdeps = -Ldependency=obj/bar\n"
592 " ldflags =\n"
593 " sources = ../../bar/mylib.rs ../../bar/lib.rs\n";
594 std::string out_str = out.str();
595 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
596 }
597
598 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
599 target.set_output_type(Target::EXECUTABLE);
600 target.visibility().SetPublic();
601 SourceFile main("//foo/main.rs");
602 target.sources().push_back(SourceFile("//foo/source.rs"));
603 target.sources().push_back(main);
604 target.source_types_used().Set(SourceFile::SOURCE_RS);
605 target.rust_values().set_crate_root(main);
606 target.rust_values().crate_name() = "foo_bar";
607 target.private_deps().push_back(LabelTargetPair(&rlib));
608 target.SetToolchain(setup.toolchain());
609 ASSERT_TRUE(target.OnResolved(&err));
610
611 {
612 std::ostringstream out;
613 NinjaRustBinaryTargetWriter writer(&target, out);
614 writer.Run();
615
616 const char expected[] =
617 "crate_name = foo_bar\n"
618 "crate_type = bin\n"
619 "output_extension = \n"
620 "output_dir = \n"
621 "rustflags =\n"
622 "rustenv =\n"
623 "root_out_dir = .\n"
624 "target_gen_dir = gen/foo\n"
625 "target_out_dir = obj/foo\n"
626 "target_output_name = bar\n"
627 "\n"
628 "build ./foo_bar: rust_bin ../../foo/main.rs | "
629 "../../foo/source.rs ../../foo/main.rs "
630 "obj/bar/libmylib.rlib obj/bar/libmymacro.so\n"
631 " source_file_part = main.rs\n"
632 " source_name_part = main\n"
633 " externs = --extern mylib=obj/bar/libmylib.rlib "
634 "--extern mymacro=obj/bar/libmymacro.so\n"
635 " rustdeps = -Ldependency=obj/bar\n"
636 " ldflags =\n"
637 " sources = ../../foo/source.rs ../../foo/main.rs\n";
638 std::string out_str = out.str();
639 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
640 }
641 }
642
TEST_F(NinjaRustBinaryTargetWriterTest,RenamedDeps)643 TEST_F(NinjaRustBinaryTargetWriterTest, RenamedDeps) {
644 Err err;
645 TestWithScope setup;
646
647 Target transitive(setup.settings(), Label(SourceDir("//faz/"), "transitive"));
648 transitive.set_output_type(Target::RUST_LIBRARY);
649 transitive.visibility().SetPublic();
650 SourceFile transitive_lib("//faz/transitive/lib.rs");
651 transitive.sources().push_back(SourceFile("//faz/transitive/transitive.rs"));
652 transitive.sources().push_back(transitive_lib);
653 transitive.source_types_used().Set(SourceFile::SOURCE_RS);
654 transitive.rust_values().set_crate_root(transitive_lib);
655 transitive.rust_values().crate_name() = "transitive";
656 transitive.SetToolchain(setup.toolchain());
657 ASSERT_TRUE(transitive.OnResolved(&err));
658
659 Target rlib(setup.settings(), Label(SourceDir("//baz/"), "mylib"));
660 rlib.set_output_type(Target::RUST_LIBRARY);
661 rlib.visibility().SetPublic();
662 SourceFile barlib("//baz/bar/lib.rs");
663 rlib.sources().push_back(SourceFile("//baz/bar/mylib.rs"));
664 rlib.sources().push_back(barlib);
665 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
666 rlib.rust_values().set_crate_root(barlib);
667 rlib.rust_values().crate_name() = "mylib";
668 rlib.SetToolchain(setup.toolchain());
669 rlib.public_deps().push_back(LabelTargetPair(&transitive));
670 ASSERT_TRUE(rlib.OnResolved(&err));
671
672 Target direct(setup.settings(), Label(SourceDir("//bar/"), "direct"));
673 direct.set_output_type(Target::RUST_LIBRARY);
674 direct.visibility().SetPublic();
675 SourceFile direct_lib("//bar/direct/lib.rs");
676 direct.sources().push_back(SourceFile("//bar/direct/direct.rs"));
677 direct.sources().push_back(direct_lib);
678 direct.source_types_used().Set(SourceFile::SOURCE_RS);
679 direct.rust_values().set_crate_root(direct_lib);
680 direct.rust_values().crate_name() = "direct";
681 direct.SetToolchain(setup.toolchain());
682 ASSERT_TRUE(direct.OnResolved(&err));
683
684 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
685 target.set_output_type(Target::EXECUTABLE);
686 target.visibility().SetPublic();
687 SourceFile main("//foo/main.rs");
688 target.sources().push_back(SourceFile("//foo/source.rs"));
689 target.sources().push_back(main);
690 target.source_types_used().Set(SourceFile::SOURCE_RS);
691 target.rust_values().set_crate_root(main);
692 target.rust_values().crate_name() = "foo_bar";
693 // A direct dependency is renamed.
694 target.rust_values().aliased_deps()[direct.label()] = "direct_renamed";
695 // A transitive public dependency, through `rlib`, is renamed.
696 target.rust_values().aliased_deps()[transitive.label()] =
697 "transitive_renamed";
698 target.private_deps().push_back(LabelTargetPair(&direct));
699 target.private_deps().push_back(LabelTargetPair(&rlib));
700 target.SetToolchain(setup.toolchain());
701 ASSERT_TRUE(target.OnResolved(&err));
702
703 {
704 std::ostringstream out;
705 NinjaRustBinaryTargetWriter writer(&target, out);
706 writer.Run();
707
708 const char expected[] =
709 "crate_name = foo_bar\n"
710 "crate_type = bin\n"
711 "output_extension = \n"
712 "output_dir = \n"
713 "rustflags =\n"
714 "rustenv =\n"
715 "root_out_dir = .\n"
716 "target_gen_dir = gen/foo\n"
717 "target_out_dir = obj/foo\n"
718 "target_output_name = bar\n"
719 "\n"
720 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
721 "../../foo/main.rs obj/bar/libdirect.rlib obj/baz/libmylib.rlib "
722 "obj/faz/libtransitive.rlib\n"
723 " source_file_part = main.rs\n"
724 " source_name_part = main\n"
725 " externs = --extern direct_renamed=obj/bar/libdirect.rlib "
726 "--extern mylib=obj/baz/libmylib.rlib "
727 "--extern transitive_renamed=obj/faz/libtransitive.rlib\n"
728 " rustdeps = -Ldependency=obj/bar -Ldependency=obj/baz "
729 "-Ldependency=obj/faz\n"
730 " ldflags =\n"
731 " sources = ../../foo/source.rs ../../foo/main.rs\n";
732 std::string out_str = out.str();
733 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
734 }
735 }
736
TEST_F(NinjaRustBinaryTargetWriterTest,NonRustDeps)737 TEST_F(NinjaRustBinaryTargetWriterTest, NonRustDeps) {
738 Err err;
739 TestWithScope setup;
740
741 Target staticlib(setup.settings(), Label(SourceDir("//foo/"), "static"));
742 staticlib.set_output_type(Target::STATIC_LIBRARY);
743 staticlib.visibility().SetPublic();
744 staticlib.sources().push_back(SourceFile("//foo/static.cpp"));
745 staticlib.source_types_used().Set(SourceFile::SOURCE_CPP);
746 staticlib.SetToolchain(setup.toolchain());
747 ASSERT_TRUE(staticlib.OnResolved(&err));
748
749 Target rlib(setup.settings(), Label(SourceDir("//bar/"), "mylib"));
750 rlib.set_output_type(Target::RUST_LIBRARY);
751 rlib.visibility().SetPublic();
752 SourceFile barlib("//bar/lib.rs");
753 rlib.sources().push_back(SourceFile("//bar/mylib.rs"));
754 rlib.sources().push_back(barlib);
755 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
756 rlib.rust_values().set_crate_root(barlib);
757 rlib.rust_values().crate_name() = "mylib";
758 rlib.SetToolchain(setup.toolchain());
759 ASSERT_TRUE(rlib.OnResolved(&err));
760
761 Target sharedlib(setup.settings(), Label(SourceDir("//foo/"), "shared"));
762 sharedlib.set_output_type(Target::SHARED_LIBRARY);
763 sharedlib.visibility().SetPublic();
764 sharedlib.sources().push_back(SourceFile("//foo/static.cpp"));
765 sharedlib.source_types_used().Set(SourceFile::SOURCE_CPP);
766 sharedlib.SetToolchain(setup.toolchain());
767 ASSERT_TRUE(sharedlib.OnResolved(&err));
768
769 Target csourceset(setup.settings(), Label(SourceDir("//baz/"), "sourceset"));
770 csourceset.set_output_type(Target::SOURCE_SET);
771 csourceset.visibility().SetPublic();
772 csourceset.sources().push_back(SourceFile("//baz/csourceset.cpp"));
773 csourceset.source_types_used().Set(SourceFile::SOURCE_CPP);
774 csourceset.SetToolchain(setup.toolchain());
775 ASSERT_TRUE(csourceset.OnResolved(&err));
776
777 Toolchain toolchain_with_toc(
778 setup.settings(), Label(SourceDir("//toolchain_with_toc/"), "with_toc"));
779 TestWithScope::SetupToolchain(&toolchain_with_toc, true);
780 Target sharedlib_with_toc(setup.settings(),
781 Label(SourceDir("//foo/"), "shared_with_toc"));
782 sharedlib_with_toc.set_output_type(Target::SHARED_LIBRARY);
783 sharedlib_with_toc.visibility().SetPublic();
784 sharedlib_with_toc.sources().push_back(SourceFile("//foo/static.cpp"));
785 sharedlib_with_toc.source_types_used().Set(SourceFile::SOURCE_CPP);
786 sharedlib_with_toc.SetToolchain(&toolchain_with_toc);
787 ASSERT_TRUE(sharedlib_with_toc.OnResolved(&err));
788
789 Target nonrust(setup.settings(), Label(SourceDir("//foo/"), "bar"));
790 nonrust.set_output_type(Target::EXECUTABLE);
791 nonrust.visibility().SetPublic();
792 SourceFile main("//foo/main.rs");
793 nonrust.sources().push_back(SourceFile("//foo/source.rs"));
794 nonrust.sources().push_back(main);
795 nonrust.source_types_used().Set(SourceFile::SOURCE_RS);
796 nonrust.rust_values().set_crate_root(main);
797 nonrust.rust_values().crate_name() = "foo_bar";
798 nonrust.private_deps().push_back(LabelTargetPair(&rlib));
799 nonrust.private_deps().push_back(LabelTargetPair(&staticlib));
800 nonrust.private_deps().push_back(LabelTargetPair(&sharedlib));
801 nonrust.private_deps().push_back(LabelTargetPair(&csourceset));
802 nonrust.private_deps().push_back(LabelTargetPair(&sharedlib_with_toc));
803 nonrust.SetToolchain(setup.toolchain());
804 ASSERT_TRUE(nonrust.OnResolved(&err));
805
806 {
807 std::ostringstream out;
808 NinjaRustBinaryTargetWriter writer(&nonrust, out);
809 writer.Run();
810
811 const char expected[] =
812 "crate_name = foo_bar\n"
813 "crate_type = bin\n"
814 "output_extension = \n"
815 "output_dir = \n"
816 "rustflags =\n"
817 "rustenv =\n"
818 "root_out_dir = .\n"
819 "target_gen_dir = gen/foo\n"
820 "target_out_dir = obj/foo\n"
821 "target_output_name = bar\n"
822 "\n"
823 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
824 "../../foo/main.rs obj/baz/sourceset.csourceset.o "
825 "obj/bar/libmylib.rlib "
826 "obj/foo/libstatic.a ./libshared.so ./libshared_with_toc.so.TOC "
827 "|| obj/baz/sourceset.stamp\n"
828 " source_file_part = main.rs\n"
829 " source_name_part = main\n"
830 " externs = --extern mylib=obj/bar/libmylib.rlib\n"
831 " rustdeps = -Ldependency=obj/bar "
832 "-Lnative=obj/baz -Lnative=obj/foo -Lnative=. "
833 "-Clink-arg=-Bdynamic -Clink-arg=obj/baz/sourceset.csourceset.o "
834 "-Clink-arg=obj/foo/libstatic.a -Clink-arg=./libshared.so "
835 "-Clink-arg=./libshared_with_toc.so\n"
836 " ldflags =\n"
837 " sources = ../../foo/source.rs ../../foo/main.rs\n";
838 std::string out_str = out.str();
839 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
840 }
841
842 Target nonrust_only(setup.settings(), Label(SourceDir("//foo/"), "bar"));
843 nonrust_only.set_output_type(Target::EXECUTABLE);
844 nonrust_only.visibility().SetPublic();
845 nonrust_only.sources().push_back(SourceFile("//foo/source.rs"));
846 nonrust_only.sources().push_back(main);
847 nonrust_only.source_types_used().Set(SourceFile::SOURCE_RS);
848 nonrust_only.rust_values().set_crate_root(main);
849 nonrust_only.rust_values().crate_name() = "foo_bar";
850 nonrust_only.private_deps().push_back(LabelTargetPair(&staticlib));
851 nonrust_only.SetToolchain(setup.toolchain());
852 ASSERT_TRUE(nonrust_only.OnResolved(&err));
853
854 {
855 std::ostringstream out;
856 NinjaRustBinaryTargetWriter writer(&nonrust_only, out);
857 writer.Run();
858
859 const char expected[] =
860 "crate_name = foo_bar\n"
861 "crate_type = bin\n"
862 "output_extension = \n"
863 "output_dir = \n"
864 "rustflags =\n"
865 "rustenv =\n"
866 "root_out_dir = .\n"
867 "target_gen_dir = gen/foo\n"
868 "target_out_dir = obj/foo\n"
869 "target_output_name = bar\n"
870 "\n"
871 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
872 "../../foo/main.rs obj/foo/libstatic.a\n"
873 " source_file_part = main.rs\n"
874 " source_name_part = main\n"
875 " externs =\n"
876 " rustdeps = -Lnative=obj/foo -Clink-arg=-Bdynamic "
877 "-Clink-arg=obj/foo/libstatic.a\n"
878 " ldflags =\n"
879 " sources = ../../foo/source.rs ../../foo/main.rs\n";
880 std::string out_str = out.str();
881 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
882 }
883
884 Target rstaticlib(setup.settings(), Label(SourceDir("//baz/"), "baz"));
885 rstaticlib.set_output_type(Target::STATIC_LIBRARY);
886 rstaticlib.visibility().SetPublic();
887 SourceFile bazlib("//baz/lib.rs");
888 rstaticlib.sources().push_back(bazlib);
889 rstaticlib.source_types_used().Set(SourceFile::SOURCE_RS);
890 rstaticlib.rust_values().set_crate_root(bazlib);
891 rstaticlib.rust_values().crate_name() = "baz";
892 rstaticlib.private_deps().push_back(LabelTargetPair(&staticlib));
893 rstaticlib.SetToolchain(setup.toolchain());
894 ASSERT_TRUE(rstaticlib.OnResolved(&err));
895
896 {
897 std::ostringstream out;
898 NinjaRustBinaryTargetWriter writer(&rstaticlib, out);
899 writer.Run();
900
901 const char expected[] =
902 "crate_name = baz\n"
903 "crate_type = staticlib\n"
904 "output_extension = .a\n"
905 "output_dir = \n"
906 "rustflags =\n"
907 "rustenv =\n"
908 "root_out_dir = .\n"
909 "target_gen_dir = gen/baz\n"
910 "target_out_dir = obj/baz\n"
911 "target_output_name = libbaz\n"
912 "\n"
913 "build obj/baz/libbaz.a: rust_staticlib ../../baz/lib.rs | "
914 "../../baz/lib.rs "
915 "obj/foo/libstatic.a\n"
916 " source_file_part = lib.rs\n"
917 " source_name_part = lib\n"
918 " externs =\n"
919 " rustdeps = -Lnative=obj/foo -Clink-arg=-Balternative-dynamic "
920 "-Clink-arg=obj/foo/libstatic.a\n"
921 " ldflags =\n"
922 " sources = ../../baz/lib.rs\n";
923 std::string out_str = out.str();
924 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
925 }
926 }
927
TEST_F(NinjaRustBinaryTargetWriterTest,RlibInLibrary)928 TEST_F(NinjaRustBinaryTargetWriterTest, RlibInLibrary) {
929 Err err;
930 TestWithScope setup;
931
932 Target priv_sset_in_staticlib(
933 setup.settings(),
934 Label(SourceDir("//priv_sset_in_staticlib/"), "priv_sset_in_staticlib"));
935 priv_sset_in_staticlib.set_output_type(Target::SOURCE_SET);
936 priv_sset_in_staticlib.visibility().SetPublic();
937 priv_sset_in_staticlib.sources().push_back(
938 SourceFile("//priv_sset_in_staticlib/lib.cc"));
939 priv_sset_in_staticlib.source_types_used().Set(SourceFile::SOURCE_CPP);
940 priv_sset_in_staticlib.SetToolchain(setup.toolchain());
941 ASSERT_TRUE(priv_sset_in_staticlib.OnResolved(&err));
942
943 Target pub_sset_in_staticlib(
944 setup.settings(),
945 Label(SourceDir("//pub_sset_in_staticlib/"), "pub_sset_in_staticlib"));
946 pub_sset_in_staticlib.set_output_type(Target::SOURCE_SET);
947 pub_sset_in_staticlib.visibility().SetPublic();
948 pub_sset_in_staticlib.sources().push_back(
949 SourceFile("//pub_sset_in_staticlib/lib.cc"));
950 pub_sset_in_staticlib.source_types_used().Set(SourceFile::SOURCE_CPP);
951 pub_sset_in_staticlib.SetToolchain(setup.toolchain());
952 ASSERT_TRUE(pub_sset_in_staticlib.OnResolved(&err));
953
954 Target priv_sset_in_dylib(
955 setup.settings(),
956 Label(SourceDir("//priv_sset_in_dylib/"), "priv_sset_in_dylib"));
957 priv_sset_in_dylib.set_output_type(Target::SOURCE_SET);
958 priv_sset_in_dylib.visibility().SetPublic();
959 priv_sset_in_dylib.sources().push_back(
960 SourceFile("//priv_sset_in_dylib/lib.cc"));
961 priv_sset_in_dylib.source_types_used().Set(SourceFile::SOURCE_CPP);
962 priv_sset_in_dylib.SetToolchain(setup.toolchain());
963 ASSERT_TRUE(priv_sset_in_dylib.OnResolved(&err));
964
965 Target pub_sset_in_dylib(
966 setup.settings(),
967 Label(SourceDir("//pub_sset_in_dylib"), "pub_sset_in_dylib"));
968 pub_sset_in_dylib.set_output_type(Target::SOURCE_SET);
969 pub_sset_in_dylib.visibility().SetPublic();
970 pub_sset_in_dylib.sources().push_back(
971 SourceFile("//pub_sset_in_dylib/lib.cc"));
972 pub_sset_in_dylib.source_types_used().Set(SourceFile::SOURCE_CPP);
973 pub_sset_in_dylib.SetToolchain(setup.toolchain());
974 ASSERT_TRUE(pub_sset_in_dylib.OnResolved(&err));
975
976 Target priv_in_staticlib(
977 setup.settings(),
978 Label(SourceDir("//priv_in_staticlib/"), "priv_in_staticlib"));
979 priv_in_staticlib.set_output_type(Target::RUST_LIBRARY);
980 priv_in_staticlib.visibility().SetPublic();
981 SourceFile priv_in_staticlib_root("//priv_in_staticlib/lib.rs");
982 priv_in_staticlib.sources().push_back(priv_in_staticlib_root);
983 priv_in_staticlib.source_types_used().Set(SourceFile::SOURCE_RS);
984 priv_in_staticlib.rust_values().set_crate_root(priv_in_staticlib_root);
985 priv_in_staticlib.rust_values().crate_name() = "priv_in_staticlib";
986 priv_in_staticlib.SetToolchain(setup.toolchain());
987 priv_in_staticlib.private_deps().push_back(
988 LabelTargetPair(&priv_sset_in_staticlib));
989 ASSERT_TRUE(priv_in_staticlib.OnResolved(&err));
990
991 Target pub_in_staticlib(
992 setup.settings(),
993 Label(SourceDir("//pub_in_staticlib/"), "pub_in_staticlib"));
994 pub_in_staticlib.set_output_type(Target::RUST_LIBRARY);
995 pub_in_staticlib.visibility().SetPublic();
996 SourceFile pub_in_staticlib_root("//pub_in_staticlib/lib.rs");
997 pub_in_staticlib.sources().push_back(pub_in_staticlib_root);
998 pub_in_staticlib.source_types_used().Set(SourceFile::SOURCE_RS);
999 pub_in_staticlib.rust_values().set_crate_root(pub_in_staticlib_root);
1000 pub_in_staticlib.rust_values().crate_name() = "pub_in_staticlib";
1001 pub_in_staticlib.SetToolchain(setup.toolchain());
1002 pub_in_staticlib.private_deps().push_back(
1003 LabelTargetPair(&pub_sset_in_staticlib));
1004 ASSERT_TRUE(pub_in_staticlib.OnResolved(&err));
1005
1006 Target priv_in_dylib(setup.settings(),
1007 Label(SourceDir("//priv_in_dylib/"), "priv_in_dylib"));
1008 priv_in_dylib.set_output_type(Target::RUST_LIBRARY);
1009 priv_in_dylib.visibility().SetPublic();
1010 SourceFile priv_in_dylib_root("//priv_in_dylib/lib.rs");
1011 priv_in_dylib.sources().push_back(priv_in_dylib_root);
1012 priv_in_dylib.source_types_used().Set(SourceFile::SOURCE_RS);
1013 priv_in_dylib.rust_values().set_crate_root(priv_in_dylib_root);
1014 priv_in_dylib.rust_values().crate_name() = "priv_in_dylib";
1015 priv_in_dylib.SetToolchain(setup.toolchain());
1016 priv_in_dylib.private_deps().push_back(LabelTargetPair(&priv_sset_in_dylib));
1017 ASSERT_TRUE(priv_in_dylib.OnResolved(&err));
1018
1019 Target pub_in_dylib(setup.settings(),
1020 Label(SourceDir("//pub_in_dylib/"), "pub_in_dylib"));
1021 pub_in_dylib.set_output_type(Target::RUST_LIBRARY);
1022 pub_in_dylib.visibility().SetPublic();
1023 SourceFile pub_in_dylib_root("//pub_in_dylib/lib.rs");
1024 pub_in_dylib.sources().push_back(pub_in_dylib_root);
1025 pub_in_dylib.source_types_used().Set(SourceFile::SOURCE_RS);
1026 pub_in_dylib.rust_values().set_crate_root(pub_in_dylib_root);
1027 pub_in_dylib.rust_values().crate_name() = "pub_in_dylib";
1028 pub_in_dylib.SetToolchain(setup.toolchain());
1029 pub_in_dylib.private_deps().push_back(LabelTargetPair(&pub_sset_in_dylib));
1030 ASSERT_TRUE(pub_in_dylib.OnResolved(&err));
1031
1032 Target staticlib(setup.settings(),
1033 Label(SourceDir("//staticlib/"), "staticlib"));
1034 staticlib.set_output_type(Target::STATIC_LIBRARY);
1035 staticlib.visibility().SetPublic();
1036 staticlib.sources().push_back(SourceFile("//staticlib/lib.cc"));
1037 staticlib.source_types_used().Set(SourceFile::SOURCE_CPP);
1038 staticlib.public_deps().push_back(LabelTargetPair(&pub_in_staticlib));
1039 staticlib.private_deps().push_back(LabelTargetPair(&priv_in_staticlib));
1040 staticlib.SetToolchain(setup.toolchain());
1041 ASSERT_TRUE(staticlib.OnResolved(&err));
1042
1043 Target dylib(setup.settings(), Label(SourceDir("//dylib/"), "dylib"));
1044 dylib.set_output_type(Target::SHARED_LIBRARY);
1045 dylib.visibility().SetPublic();
1046 SourceFile dylib_root("//dylib/lib.rs");
1047 dylib.sources().push_back(dylib_root);
1048 dylib.source_types_used().Set(SourceFile::SOURCE_RS);
1049 dylib.rust_values().set_crate_root(dylib_root);
1050 dylib.rust_values().crate_name() = "dylib";
1051 dylib.public_deps().push_back(LabelTargetPair(&pub_in_dylib));
1052 dylib.private_deps().push_back(LabelTargetPair(&priv_in_dylib));
1053 dylib.SetToolchain(setup.toolchain());
1054 ASSERT_TRUE(dylib.OnResolved(&err));
1055
1056 Target target(setup.settings(), Label(SourceDir("//exe/"), "exe"));
1057 target.set_output_type(Target::EXECUTABLE);
1058 target.visibility().SetPublic();
1059 SourceFile main("//exe/main.rs");
1060 target.sources().push_back(main);
1061 target.source_types_used().Set(SourceFile::SOURCE_RS);
1062 target.rust_values().set_crate_root(main);
1063 target.rust_values().crate_name() = "exe";
1064 target.private_deps().push_back(LabelTargetPair(&staticlib));
1065 target.private_deps().push_back(LabelTargetPair(&dylib));
1066 target.SetToolchain(setup.toolchain());
1067 ASSERT_TRUE(target.OnResolved(&err));
1068
1069 std::ostringstream out;
1070 NinjaRustBinaryTargetWriter writer(&target, out);
1071 writer.Run();
1072
1073 const char expected[] =
1074 "crate_name = exe\n"
1075 "crate_type = bin\n"
1076 "output_extension = \n"
1077 "output_dir = \n"
1078 "rustflags =\n"
1079 "rustenv =\n"
1080 "root_out_dir = .\n"
1081 "target_gen_dir = gen/exe\n"
1082 "target_out_dir = obj/exe\n"
1083 "target_output_name = exe\n"
1084 "\n"
1085 "build ./exe: rust_bin ../../exe/main.rs | "
1086 "../../exe/main.rs "
1087 "obj/pub_sset_in_staticlib/pub_sset_in_staticlib.lib.o "
1088 "obj/priv_sset_in_staticlib/priv_sset_in_staticlib.lib.o "
1089 "obj/staticlib/libstaticlib.a "
1090 "obj/dylib/libdylib.so "
1091 "obj/pub_in_staticlib/libpub_in_staticlib.rlib "
1092 "obj/priv_in_staticlib/libpriv_in_staticlib.rlib "
1093 "obj/pub_in_dylib/libpub_in_dylib.rlib || "
1094 "obj/pub_sset_in_staticlib/pub_sset_in_staticlib.stamp "
1095 "obj/priv_sset_in_staticlib/priv_sset_in_staticlib.stamp\n"
1096 " source_file_part = main.rs\n"
1097 " source_name_part = main\n"
1098 " externs = "
1099 "--extern pub_in_staticlib=obj/pub_in_staticlib/libpub_in_staticlib.rlib "
1100 "--extern dylib=obj/dylib/libdylib.so "
1101 "--extern pub_in_dylib=obj/pub_in_dylib/libpub_in_dylib.rlib\n"
1102 " rustdeps = -Ldependency=obj/pub_in_staticlib "
1103 "-Ldependency=obj/priv_in_staticlib -Ldependency=obj/dylib "
1104 "-Ldependency=obj/pub_in_dylib -Ldependency=obj/priv_in_dylib "
1105 "-Lnative=obj/pub_sset_in_staticlib "
1106 "-Lnative=obj/priv_sset_in_staticlib "
1107 "-Lnative=obj/staticlib -Clink-arg=-Bdynamic "
1108 "-Clink-arg=obj/pub_sset_in_staticlib/pub_sset_in_staticlib.lib.o "
1109 "-Clink-arg=obj/priv_sset_in_staticlib/priv_sset_in_staticlib.lib.o "
1110 "-Clink-arg=obj/staticlib/libstaticlib.a\n"
1111 " ldflags =\n"
1112 " sources = ../../exe/main.rs\n";
1113
1114 std::string out_str = out.str();
1115 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1116 }
1117
TEST_F(NinjaRustBinaryTargetWriterTest,RustOutputExtensionAndDir)1118 TEST_F(NinjaRustBinaryTargetWriterTest, RustOutputExtensionAndDir) {
1119 Err err;
1120 TestWithScope setup;
1121
1122 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1123 target.set_output_type(Target::EXECUTABLE);
1124 target.visibility().SetPublic();
1125 SourceFile main("//foo/main.rs");
1126 target.sources().push_back(SourceFile("//foo/input3.rs"));
1127 target.sources().push_back(main);
1128 target.source_types_used().Set(SourceFile::SOURCE_RS);
1129 target.set_output_extension(std::string("exe"));
1130 target.set_output_dir(SourceDir("//out/Debug/foo/"));
1131 target.rust_values().set_crate_root(main);
1132 target.rust_values().crate_name() = "foo_bar";
1133 target.SetToolchain(setup.toolchain());
1134 ASSERT_TRUE(target.OnResolved(&err));
1135
1136 {
1137 std::ostringstream out;
1138 NinjaRustBinaryTargetWriter writer(&target, out);
1139 writer.Run();
1140
1141 const char expected[] =
1142 "crate_name = foo_bar\n"
1143 "crate_type = bin\n"
1144 "output_extension = .exe\n"
1145 "output_dir = foo\n"
1146 "rustflags =\n"
1147 "rustenv =\n"
1148 "root_out_dir = .\n"
1149 "target_gen_dir = gen/foo\n"
1150 "target_out_dir = obj/foo\n"
1151 "target_output_name = bar\n"
1152 "\n"
1153 "build ./foo_bar.exe: rust_bin ../../foo/main.rs | ../../foo/input3.rs "
1154 "../../foo/main.rs\n"
1155 " source_file_part = main.rs\n"
1156 " source_name_part = main\n"
1157 " externs =\n"
1158 " rustdeps =\n"
1159 " ldflags =\n"
1160 " sources = ../../foo/input3.rs ../../foo/main.rs\n";
1161 std::string out_str = out.str();
1162 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1163 }
1164 }
1165
TEST_F(NinjaRustBinaryTargetWriterTest,LibsAndLibDirs)1166 TEST_F(NinjaRustBinaryTargetWriterTest, LibsAndLibDirs) {
1167 Err err;
1168 TestWithScope setup;
1169
1170 Target rlib(setup.settings(), Label(SourceDir("//bar/"), "rlib"));
1171 rlib.set_output_type(Target::RUST_LIBRARY);
1172 rlib.visibility().SetPublic();
1173 SourceFile barlib("//bar/lib.rs");
1174 rlib.sources().push_back(SourceFile("//bar/rlib.rs"));
1175 rlib.sources().push_back(barlib);
1176 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
1177 rlib.rust_values().set_crate_root(barlib);
1178 rlib.rust_values().crate_name() = "rlibcrate";
1179 rlib.config_values().libs().push_back(LibFile("rliblib"));
1180 rlib.config_values().lib_dirs().push_back(SourceDir("//rliblibdir/"));
1181 rlib.config_values().framework_dirs().push_back(SourceDir("//rlibfwdir/"));
1182 rlib.SetToolchain(setup.toolchain());
1183 ASSERT_TRUE(rlib.OnResolved(&err));
1184
1185 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1186 target.set_output_type(Target::EXECUTABLE);
1187 target.visibility().SetPublic();
1188 SourceFile main("//foo/main.rs");
1189 target.sources().push_back(SourceFile("//foo/input.rs"));
1190 target.sources().push_back(main);
1191 target.source_types_used().Set(SourceFile::SOURCE_RS);
1192 target.set_output_dir(SourceDir("//out/Debug/foo/"));
1193 target.config_values().libs().push_back(LibFile(SourceFile("//dir1/ar.a")));
1194 target.config_values().libs().push_back(LibFile("binlib"));
1195 target.config_values().lib_dirs().push_back(SourceDir("//binlibdir/"));
1196 target.config_values().framework_dirs().push_back(SourceDir("//binfwdir/"));
1197 target.public_deps().push_back(LabelTargetPair(&rlib));
1198 target.rust_values().set_crate_root(main);
1199 target.rust_values().crate_name() = "foo_bar";
1200 target.SetToolchain(setup.toolchain());
1201 ASSERT_TRUE(target.OnResolved(&err));
1202
1203 {
1204 std::ostringstream out;
1205 NinjaRustBinaryTargetWriter writer(&target, out);
1206 writer.Run();
1207
1208 const char expected[] =
1209 "crate_name = foo_bar\n"
1210 "crate_type = bin\n"
1211 "output_extension = \n"
1212 "output_dir = foo\n"
1213 "rustflags =\n"
1214 "rustenv =\n"
1215 "root_out_dir = .\n"
1216 "target_gen_dir = gen/foo\n"
1217 "target_out_dir = obj/foo\n"
1218 "target_output_name = bar\n"
1219 "\n"
1220 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/input.rs "
1221 "../../foo/main.rs obj/bar/librlib.rlib\n"
1222 " source_file_part = main.rs\n"
1223 " source_name_part = main\n"
1224 " externs = --extern rlibcrate=obj/bar/librlib.rlib\n"
1225 " rustdeps = -Ldependency=obj/bar -Lnative=../../binlibdir "
1226 "-Lnative=../../rliblibdir -Lframework=../../binfwdir "
1227 "-Lframework=../../rlibfwdir -Clink-arg=../../dir1/ar.a -lbinlib "
1228 "-lrliblib\n"
1229 " ldflags =\n"
1230 " sources = ../../foo/input.rs ../../foo/main.rs\n";
1231 std::string out_str = out.str();
1232 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1233 }
1234 }
1235
TEST_F(NinjaRustBinaryTargetWriterTest,RlibWithLibDeps)1236 TEST_F(NinjaRustBinaryTargetWriterTest, RlibWithLibDeps) {
1237 Err err;
1238 TestWithScope setup;
1239
1240 Target public_rlib(setup.settings(), Label(SourceDir("//bar/"), "publiclib"));
1241 public_rlib.set_output_type(Target::RUST_LIBRARY);
1242 public_rlib.visibility().SetPublic();
1243 SourceFile barlib("//bar/lib.rs");
1244 public_rlib.sources().push_back(SourceFile("//bar/publiclib.rs"));
1245 public_rlib.sources().push_back(barlib);
1246 public_rlib.source_types_used().Set(SourceFile::SOURCE_RS);
1247 public_rlib.rust_values().set_crate_root(barlib);
1248 public_rlib.rust_values().crate_name() = "publiccrate";
1249 public_rlib.SetToolchain(setup.toolchain());
1250 ASSERT_TRUE(public_rlib.OnResolved(&err));
1251
1252 Target staticlib(setup.settings(), Label(SourceDir("//clib/"), "static"));
1253 staticlib.set_output_type(Target::STATIC_LIBRARY);
1254 staticlib.visibility().SetPublic();
1255 staticlib.sources().push_back(SourceFile("//foo/clib.cpp"));
1256 staticlib.source_types_used().Set(SourceFile::SOURCE_CPP);
1257 staticlib.SetToolchain(setup.toolchain());
1258 ASSERT_TRUE(staticlib.OnResolved(&err));
1259
1260 Target rlib(setup.settings(), Label(SourceDir("//foo/"), "rlibcrate"));
1261 rlib.set_output_type(Target::RUST_LIBRARY);
1262 rlib.visibility().SetPublic();
1263 SourceFile lib("//foo/input.rs");
1264 rlib.sources().push_back(lib);
1265 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
1266 rlib.rust_values().set_crate_root(lib);
1267 rlib.rust_values().crate_name() = "rlibcrate";
1268 rlib.SetToolchain(setup.toolchain());
1269 rlib.public_deps().push_back(LabelTargetPair(&public_rlib));
1270
1271 // This adds dependencies on static libraries, which are not consumed by an
1272 // rlib since it does not get linked. None of these should appear in
1273 // `rustdeps` for a `rust_rlib`, though they would for a `rust_bin` (as tested
1274 // for above).
1275 //
1276 // 1. A dependency on an archive file directly as happens with a `libs` rule,
1277 // requesting a system library. The path to that library must be specified
1278 // separately with `-L` in ldflags, the library does not appear in the
1279 // rustc compilation of an rlib.
1280 rlib.config_values().libs().push_back(LibFile(SourceFile("//dir1/ar.a")));
1281 // 2. A dependency on a library name as happens with a `libs` rule. Libraries
1282 // need only be named when linking, they do not need to appear in an rlib
1283 // compilation.
1284 rlib.config_values().libs().push_back(LibFile("quux"));
1285 // 3. A dependency on a library path which will be used for linking, which is
1286 // separate from the dependency paths for finding Rust crates. But it may
1287 // be needed to resolve the path to a native library in a #[link]
1288 // directive.
1289 rlib.config_values().lib_dirs().push_back(SourceDir("//baz/"));
1290 // 4. A framework search directory will be used for linking frameworks, which
1291 // is also separate from finding Rust crates. Again a #[link] directive can
1292 // point to a framework, so these paths need to be present during
1293 // compilation
1294 rlib.config_values().framework_dirs().push_back(SourceDir("//fwdir/"));
1295 // 5. A dependency on a C library through a `deps` rule, which points to a
1296 // `static_library` target. GN guarantees that Rust can refer to that
1297 // library through #[link] without having to specify the path in ldflags
1298 // as well.
1299 rlib.private_deps().push_back(LabelTargetPair(&staticlib));
1300
1301 ASSERT_TRUE(rlib.OnResolved(&err));
1302
1303 {
1304 std::ostringstream out;
1305 NinjaRustBinaryTargetWriter writer(&rlib, out);
1306 writer.Run();
1307
1308 const char expected[] =
1309 "crate_name = rlibcrate\n"
1310 "crate_type = rlib\n"
1311 "output_extension = .rlib\n"
1312 "output_dir = \n"
1313 "rustflags =\n"
1314 "rustenv =\n"
1315 "root_out_dir = .\n"
1316 "target_gen_dir = gen/foo\n"
1317 "target_out_dir = obj/foo\n"
1318 "target_output_name = librlibcrate\n"
1319 "\n"
1320 "build obj/foo/librlibcrate.rlib: rust_rlib ../../foo/input.rs | "
1321 "../../foo/input.rs obj/bar/libpubliclib.rlib obj/clib/libstatic.a\n"
1322 " source_file_part = input.rs\n"
1323 " source_name_part = input\n"
1324 " externs = --extern publiccrate=obj/bar/libpubliclib.rlib\n"
1325 " rustdeps = -Ldependency=obj/bar -Lnative=obj/clib "
1326 "-Clink-arg=-Bdynamic -Clink-arg=obj/clib/libstatic.a "
1327 "-Lnative=../../baz -Lframework=../../fwdir -Clink-arg=../../dir1/ar.a "
1328 "-lquux\n"
1329 " ldflags =\n"
1330 " sources = ../../foo/input.rs\n";
1331 std::string out_str = out.str();
1332 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1333 }
1334 }
1335
1336 // Test that neither public nor private rust dependencies of a proc-macro are
1337 // transitively acquired as accessible dependencies by users of the macro. But
1338 // the macro itself is listed as an accessible dependency (via --extern).
TEST_F(NinjaRustBinaryTargetWriterTest,RustProcMacro)1339 TEST_F(NinjaRustBinaryTargetWriterTest, RustProcMacro) {
1340 Err err;
1341 TestWithScope setup;
1342
1343 Target procmacropublicdep(
1344 setup.settings(), Label(SourceDir("//baz/public/"), "mymacropublicdep"));
1345 procmacropublicdep.set_output_type(Target::RUST_LIBRARY);
1346 procmacropublicdep.visibility().SetPublic();
1347 SourceFile publicbazlib("//baz/public/lib.rs");
1348 procmacropublicdep.sources().push_back(SourceFile("//baz/public/mylib.rs"));
1349 procmacropublicdep.sources().push_back(publicbazlib);
1350 procmacropublicdep.source_types_used().Set(SourceFile::SOURCE_RS);
1351 procmacropublicdep.rust_values().set_crate_root(publicbazlib);
1352 procmacropublicdep.rust_values().crate_name() = "publicdep";
1353 procmacropublicdep.SetToolchain(setup.toolchain());
1354 ASSERT_TRUE(procmacropublicdep.OnResolved(&err));
1355
1356 Target procmacroprivatedep(
1357 setup.settings(),
1358 Label(SourceDir("//baz/private/"), "mymacroprivatedep"));
1359 procmacroprivatedep.set_output_type(Target::RUST_LIBRARY);
1360 procmacroprivatedep.visibility().SetPublic();
1361 SourceFile privatebazlib("//baz/private/lib.rs");
1362 procmacroprivatedep.sources().push_back(SourceFile("//baz/private/mylib.rs"));
1363 procmacroprivatedep.sources().push_back(privatebazlib);
1364 procmacroprivatedep.source_types_used().Set(SourceFile::SOURCE_RS);
1365 procmacroprivatedep.rust_values().set_crate_root(privatebazlib);
1366 procmacroprivatedep.rust_values().crate_name() = "privatedep";
1367 procmacroprivatedep.SetToolchain(setup.toolchain());
1368 ASSERT_TRUE(procmacroprivatedep.OnResolved(&err));
1369
1370 Target procmacro(setup.settings(), Label(SourceDir("//bar/"), "mymacro"));
1371 procmacro.set_output_type(Target::RUST_PROC_MACRO);
1372 procmacro.visibility().SetPublic();
1373 SourceFile barlib("//bar/lib.rs");
1374 procmacro.sources().push_back(SourceFile("//bar/mylib.rs"));
1375 procmacro.sources().push_back(barlib);
1376 procmacro.source_types_used().Set(SourceFile::SOURCE_RS);
1377 procmacro.rust_values().set_crate_root(barlib);
1378 procmacro.rust_values().crate_name() = "mymacro";
1379 procmacro.rust_values().set_crate_type(RustValues::CRATE_PROC_MACRO);
1380 // Add a dependency to the procmacro so we can be sure its output
1381 // directory is not propagated downstream beyond the proc macro.
1382 procmacro.public_deps().push_back(LabelTargetPair(&procmacropublicdep));
1383 procmacro.private_deps().push_back(LabelTargetPair(&procmacroprivatedep));
1384 procmacro.SetToolchain(setup.toolchain());
1385 ASSERT_TRUE(procmacro.OnResolved(&err));
1386
1387 {
1388 std::ostringstream out;
1389 NinjaRustBinaryTargetWriter writer(&procmacro, out);
1390 writer.Run();
1391
1392 const char expected[] =
1393 "crate_name = mymacro\n"
1394 "crate_type = proc-macro\n"
1395 "output_extension = .so\n"
1396 "output_dir = \n"
1397 "rustflags =\n"
1398 "rustenv =\n"
1399 "root_out_dir = .\n"
1400 "target_gen_dir = gen/bar\n"
1401 "target_out_dir = obj/bar\n"
1402 "target_output_name = libmymacro\n"
1403 "\n"
1404 "build obj/bar/libmymacro.so: rust_macro ../../bar/lib.rs | "
1405 "../../bar/mylib.rs ../../bar/lib.rs "
1406 "obj/baz/public/libmymacropublicdep.rlib "
1407 "obj/baz/private/libmymacroprivatedep.rlib\n"
1408 " source_file_part = lib.rs\n"
1409 " source_name_part = lib\n"
1410 " externs = "
1411 "--extern publicdep=obj/baz/public/libmymacropublicdep.rlib "
1412 "--extern privatedep=obj/baz/private/libmymacroprivatedep.rlib\n"
1413 " rustdeps = -Ldependency=obj/baz/public "
1414 "-Ldependency=obj/baz/private\n"
1415 " ldflags =\n"
1416 " sources = ../../bar/mylib.rs ../../bar/lib.rs\n";
1417 std::string out_str = out.str();
1418 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1419 }
1420
1421 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1422 target.set_output_type(Target::EXECUTABLE);
1423 target.visibility().SetPublic();
1424 SourceFile main("//foo/main.rs");
1425 target.sources().push_back(SourceFile("//foo/source.rs"));
1426 target.sources().push_back(main);
1427 target.source_types_used().Set(SourceFile::SOURCE_RS);
1428 target.rust_values().set_crate_root(main);
1429 target.rust_values().crate_name() = "foo_bar";
1430 target.private_deps().push_back(LabelTargetPair(&procmacro));
1431 target.SetToolchain(setup.toolchain());
1432 ASSERT_TRUE(target.OnResolved(&err));
1433
1434 {
1435 std::ostringstream out;
1436 NinjaRustBinaryTargetWriter writer(&target, out);
1437 writer.Run();
1438
1439 const char expected[] =
1440 "crate_name = foo_bar\n"
1441 "crate_type = bin\n"
1442 "output_extension = \n"
1443 "output_dir = \n"
1444 "rustflags =\n"
1445 "rustenv =\n"
1446 "root_out_dir = .\n"
1447 "target_gen_dir = gen/foo\n"
1448 "target_out_dir = obj/foo\n"
1449 "target_output_name = bar\n"
1450 "\n"
1451 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
1452 "../../foo/main.rs obj/bar/libmymacro.so\n"
1453 " source_file_part = main.rs\n"
1454 " source_name_part = main\n"
1455 " externs = --extern mymacro=obj/bar/libmymacro.so\n"
1456 " rustdeps = -Ldependency=obj/bar\n"
1457 " ldflags =\n"
1458 " sources = ../../foo/source.rs ../../foo/main.rs\n";
1459 std::string out_str = out.str();
1460 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1461 }
1462 }
1463
TEST_F(NinjaRustBinaryTargetWriterTest,GroupDeps)1464 TEST_F(NinjaRustBinaryTargetWriterTest, GroupDeps) {
1465 Err err;
1466 TestWithScope setup;
1467
1468 Target rlib(setup.settings(), Label(SourceDir("//bar/"), "mylib"));
1469 rlib.set_output_type(Target::RUST_LIBRARY);
1470 rlib.visibility().SetPublic();
1471 SourceFile barlib("//bar/lib.rs");
1472 rlib.sources().push_back(SourceFile("//bar/mylib.rs"));
1473 rlib.sources().push_back(barlib);
1474 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
1475 rlib.rust_values().set_crate_root(barlib);
1476 rlib.rust_values().crate_name() = "mylib";
1477 rlib.SetToolchain(setup.toolchain());
1478 ASSERT_TRUE(rlib.OnResolved(&err));
1479
1480 {
1481 std::ostringstream out;
1482 NinjaRustBinaryTargetWriter writer(&rlib, out);
1483 writer.Run();
1484
1485 const char expected[] =
1486 "crate_name = mylib\n"
1487 "crate_type = rlib\n"
1488 "output_extension = .rlib\n"
1489 "output_dir = \n"
1490 "rustflags =\n"
1491 "rustenv =\n"
1492 "root_out_dir = .\n"
1493 "target_gen_dir = gen/bar\n"
1494 "target_out_dir = obj/bar\n"
1495 "target_output_name = libmylib\n"
1496 "\n"
1497 "build obj/bar/libmylib.rlib: rust_rlib ../../bar/lib.rs | "
1498 "../../bar/mylib.rs ../../bar/lib.rs\n"
1499 " source_file_part = lib.rs\n"
1500 " source_name_part = lib\n"
1501 " externs =\n"
1502 " rustdeps =\n"
1503 " ldflags =\n"
1504 " sources = ../../bar/mylib.rs ../../bar/lib.rs\n";
1505 std::string out_str = out.str();
1506 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1507 }
1508
1509 Target group(setup.settings(), Label(SourceDir("//baz/"), "group"));
1510 group.set_output_type(Target::GROUP);
1511 group.visibility().SetPublic();
1512 group.public_deps().push_back(LabelTargetPair(&rlib));
1513 group.SetToolchain(setup.toolchain());
1514 ASSERT_TRUE(group.OnResolved(&err));
1515
1516 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1517 target.set_output_type(Target::EXECUTABLE);
1518 target.visibility().SetPublic();
1519 SourceFile main("//foo/main.rs");
1520 target.sources().push_back(SourceFile("//foo/source.rs"));
1521 target.sources().push_back(main);
1522 target.source_types_used().Set(SourceFile::SOURCE_RS);
1523 target.rust_values().set_crate_root(main);
1524 target.rust_values().crate_name() = "foo_bar";
1525 target.private_deps().push_back(LabelTargetPair(&group));
1526 target.SetToolchain(setup.toolchain());
1527 ASSERT_TRUE(target.OnResolved(&err));
1528
1529 {
1530 std::ostringstream out;
1531 NinjaRustBinaryTargetWriter writer(&target, out);
1532 writer.Run();
1533
1534 const char expected[] =
1535 "crate_name = foo_bar\n"
1536 "crate_type = bin\n"
1537 "output_extension = \n"
1538 "output_dir = \n"
1539 "rustflags =\n"
1540 "rustenv =\n"
1541 "root_out_dir = .\n"
1542 "target_gen_dir = gen/foo\n"
1543 "target_out_dir = obj/foo\n"
1544 "target_output_name = bar\n"
1545 "\n"
1546 "build ./foo_bar: rust_bin ../../foo/main.rs | "
1547 "../../foo/source.rs ../../foo/main.rs obj/bar/libmylib.rlib || "
1548 "obj/baz/group.stamp\n"
1549 " source_file_part = main.rs\n"
1550 " source_name_part = main\n"
1551 " externs = --extern mylib=obj/bar/libmylib.rlib\n"
1552 " rustdeps = -Ldependency=obj/bar\n"
1553 " ldflags =\n"
1554 " sources = ../../foo/source.rs ../../foo/main.rs\n";
1555 std::string out_str = out.str();
1556 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1557 }
1558 }
1559
TEST_F(NinjaRustBinaryTargetWriterTest,Externs)1560 TEST_F(NinjaRustBinaryTargetWriterTest, Externs) {
1561 Err err;
1562 TestWithScope setup;
1563
1564 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1565 target.set_output_type(Target::EXECUTABLE);
1566 target.visibility().SetPublic();
1567 SourceFile main("//foo/main.rs");
1568 target.sources().push_back(SourceFile("//foo/source.rs"));
1569 target.sources().push_back(main);
1570 target.source_types_used().Set(SourceFile::SOURCE_RS);
1571 target.rust_values().set_crate_root(main);
1572 target.rust_values().crate_name() = "foo_bar";
1573
1574 const char* lib = "lib1";
1575 target.config_values().externs().push_back(
1576 std::pair(lib, LibFile(SourceFile("//foo/lib1.rlib"))));
1577 lib = "lib2";
1578 target.config_values().externs().push_back(
1579 std::pair(lib, LibFile("lib2.rlib")));
1580
1581 target.SetToolchain(setup.toolchain());
1582 ASSERT_TRUE(target.OnResolved(&err));
1583
1584 {
1585 std::ostringstream out;
1586 NinjaRustBinaryTargetWriter writer(&target, out);
1587 writer.Run();
1588
1589 const char expected[] =
1590 "crate_name = foo_bar\n"
1591 "crate_type = bin\n"
1592 "output_extension = \n"
1593 "output_dir = \n"
1594 "rustflags =\n"
1595 "rustenv =\n"
1596 "root_out_dir = .\n"
1597 "target_gen_dir = gen/foo\n"
1598 "target_out_dir = obj/foo\n"
1599 "target_output_name = bar\n"
1600 "\n"
1601 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
1602 "../../foo/main.rs ../../foo/lib1.rlib\n"
1603 " source_file_part = main.rs\n"
1604 " source_name_part = main\n"
1605 " externs = --extern lib1=../../foo/lib1.rlib --extern "
1606 "lib2=lib2.rlib\n"
1607 " rustdeps =\n"
1608 " ldflags =\n"
1609 " sources = ../../foo/source.rs ../../foo/main.rs\n";
1610 std::string out_str = out.str();
1611 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1612 }
1613 }
1614
TEST_F(NinjaRustBinaryTargetWriterTest,Inputs)1615 TEST_F(NinjaRustBinaryTargetWriterTest, Inputs) {
1616 Err err;
1617 TestWithScope setup;
1618
1619 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1620 target.set_output_type(Target::EXECUTABLE);
1621 target.visibility().SetPublic();
1622 SourceFile main("//foo/main.rs");
1623 target.sources().push_back(SourceFile("//foo/source.rs"));
1624 target.sources().push_back(main);
1625 target.source_types_used().Set(SourceFile::SOURCE_RS);
1626 target.rust_values().set_crate_root(main);
1627 target.rust_values().crate_name() = "foo_bar";
1628 target.config_values().inputs().push_back(SourceFile("//foo/config.json"));
1629 target.config_values().inputs().push_back(SourceFile("//foo/template.h"));
1630 target.SetToolchain(setup.toolchain());
1631 ASSERT_TRUE(target.OnResolved(&err));
1632
1633 {
1634 std::ostringstream out;
1635 NinjaRustBinaryTargetWriter writer(&target, out);
1636 writer.Run();
1637
1638 const char expected[] =
1639 "build obj/foo/bar.inputs.stamp: stamp ../../foo/config.json "
1640 "../../foo/template.h\n"
1641 "crate_name = foo_bar\n"
1642 "crate_type = bin\n"
1643 "output_extension = \n"
1644 "output_dir = \n"
1645 "rustflags =\n"
1646 "rustenv =\n"
1647 "root_out_dir = .\n"
1648 "target_gen_dir = gen/foo\n"
1649 "target_out_dir = obj/foo\n"
1650 "target_output_name = bar\n"
1651 "\n"
1652 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
1653 "../../foo/main.rs ../../foo/config.json ../../foo/template.h "
1654 "|| obj/foo/bar.inputs.stamp\n"
1655 " source_file_part = main.rs\n"
1656 " source_name_part = main\n"
1657 " externs =\n"
1658 " rustdeps =\n"
1659 " ldflags =\n"
1660 " sources = ../../foo/source.rs ../../foo/main.rs "
1661 "../../foo/config.json ../../foo/template.h\n";
1662 std::string out_str = out.str();
1663 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1664 }
1665 }
1666
TEST_F(NinjaRustBinaryTargetWriterTest,CdylibDeps)1667 TEST_F(NinjaRustBinaryTargetWriterTest, CdylibDeps) {
1668 Err err;
1669 TestWithScope setup;
1670 Target cdylib(setup.settings(), Label(SourceDir("//bar/"), "mylib"));
1671 cdylib.set_output_type(Target::SHARED_LIBRARY);
1672 cdylib.visibility().SetPublic();
1673 SourceFile barlib("//bar/lib.rs");
1674 cdylib.sources().push_back(barlib);
1675 cdylib.source_types_used().Set(SourceFile::SOURCE_RS);
1676 cdylib.rust_values().set_crate_type(RustValues::CRATE_CDYLIB);
1677 cdylib.rust_values().set_crate_root(barlib);
1678 cdylib.rust_values().crate_name() = "mylib";
1679 cdylib.SetToolchain(setup.toolchain());
1680 ASSERT_TRUE(cdylib.OnResolved(&err));
1681 {
1682 std::ostringstream out;
1683 NinjaRustBinaryTargetWriter writer(&cdylib, out);
1684 writer.Run();
1685 const char expected[] =
1686 "crate_name = mylib\n"
1687 "crate_type = cdylib\n"
1688 "output_extension = .so\n"
1689 "output_dir = \n"
1690 "rustflags =\n"
1691 "rustenv =\n"
1692 "root_out_dir = .\n"
1693 "target_gen_dir = gen/bar\n"
1694 "target_out_dir = obj/bar\n"
1695 "target_output_name = libmylib\n"
1696 "\n"
1697 "build obj/bar/libmylib.so: rust_cdylib ../../bar/lib.rs | "
1698 "../../bar/lib.rs\n"
1699 " source_file_part = lib.rs\n"
1700 " source_name_part = lib\n"
1701 " externs =\n"
1702 " rustdeps =\n"
1703 " ldflags =\n"
1704 " sources = ../../bar/lib.rs\n";
1705 std::string out_str = out.str();
1706 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1707 }
1708
1709 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1710 target.set_output_type(Target::EXECUTABLE);
1711 target.visibility().SetPublic();
1712 SourceFile main("//foo/main.rs");
1713 target.sources().push_back(SourceFile("//foo/source.rs"));
1714 target.sources().push_back(main);
1715 target.source_types_used().Set(SourceFile::SOURCE_RS);
1716 target.rust_values().set_crate_root(main);
1717 target.rust_values().crate_name() = "foo_bar";
1718 target.private_deps().push_back(LabelTargetPair(&cdylib));
1719 target.SetToolchain(setup.toolchain());
1720 ASSERT_TRUE(target.OnResolved(&err));
1721 {
1722 std::ostringstream out;
1723 NinjaRustBinaryTargetWriter writer(&target, out);
1724 writer.Run();
1725
1726 const char expected[] =
1727 "crate_name = foo_bar\n"
1728 "crate_type = bin\n"
1729 "output_extension = \n"
1730 "output_dir = \n"
1731 "rustflags =\n"
1732 "rustenv =\n"
1733 "root_out_dir = .\n"
1734 "target_gen_dir = gen/foo\n"
1735 "target_out_dir = obj/foo\n"
1736 "target_output_name = bar\n"
1737 "\n"
1738 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/source.rs "
1739 "../../foo/main.rs obj/bar/libmylib.so\n"
1740 " source_file_part = main.rs\n"
1741 " source_name_part = main\n"
1742 " externs =\n"
1743 " rustdeps = -Lnative=obj/bar -Clink-arg=-Bdynamic "
1744 "-Clink-arg=obj/bar/libmylib.so\n"
1745 " ldflags =\n"
1746 " sources = ../../foo/source.rs ../../foo/main.rs\n";
1747 std::string out_str = out.str();
1748 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1749 }
1750 }
1751
TEST_F(NinjaRustBinaryTargetWriterTest,TransitivePublicNonRustDeps)1752 TEST_F(NinjaRustBinaryTargetWriterTest, TransitivePublicNonRustDeps) {
1753 Err err;
1754 TestWithScope setup;
1755
1756 // This test verifies that the Rust binary "target" links against this lib.
1757 Target implicitlib(setup.settings(), Label(SourceDir("//foo/"), "implicit"));
1758 implicitlib.set_output_type(Target::SHARED_LIBRARY);
1759 implicitlib.visibility().SetPublic();
1760 implicitlib.sources().push_back(SourceFile("//foo/implicit.cpp"));
1761 implicitlib.source_types_used().Set(SourceFile::SOURCE_CPP);
1762 implicitlib.SetToolchain(setup.toolchain());
1763 ASSERT_TRUE(implicitlib.OnResolved(&err));
1764
1765 Target sharedlib(setup.settings(), Label(SourceDir("//foo/"), "shared"));
1766 sharedlib.set_output_type(Target::SHARED_LIBRARY);
1767 sharedlib.visibility().SetPublic();
1768 sharedlib.sources().push_back(SourceFile("//foo/shared.cpp"));
1769 sharedlib.source_types_used().Set(SourceFile::SOURCE_CPP);
1770 sharedlib.SetToolchain(setup.toolchain());
1771 sharedlib.public_deps().push_back(LabelTargetPair(&implicitlib));
1772 ASSERT_TRUE(sharedlib.OnResolved(&err));
1773
1774 Target rlib(setup.settings(), Label(SourceDir("//bar/"), "mylib"));
1775 rlib.set_output_type(Target::RUST_LIBRARY);
1776 rlib.visibility().SetPublic();
1777 SourceFile barlib("//bar/lib.rs");
1778 rlib.sources().push_back(SourceFile("//bar/mylib.rs"));
1779 rlib.sources().push_back(barlib);
1780 rlib.source_types_used().Set(SourceFile::SOURCE_RS);
1781 rlib.rust_values().set_crate_root(barlib);
1782 rlib.rust_values().crate_name() = "mylib";
1783 rlib.SetToolchain(setup.toolchain());
1784 rlib.private_deps().push_back(LabelTargetPair(&sharedlib));
1785 ASSERT_TRUE(rlib.OnResolved(&err));
1786
1787 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1788 target.set_output_type(Target::EXECUTABLE);
1789 target.visibility().SetPublic();
1790 SourceFile main("//foo/main.rs");
1791 target.sources().push_back(main);
1792 target.source_types_used().Set(SourceFile::SOURCE_RS);
1793 target.rust_values().set_crate_root(main);
1794 target.rust_values().crate_name() = "foo_bar";
1795 target.private_deps().push_back(LabelTargetPair(&rlib));
1796 target.SetToolchain(setup.toolchain());
1797 ASSERT_TRUE(target.OnResolved(&err));
1798
1799 {
1800 std::ostringstream out;
1801 NinjaRustBinaryTargetWriter writer(&target, out);
1802 writer.Run();
1803
1804 const char expected[] =
1805 "crate_name = foo_bar\n"
1806 "crate_type = bin\n"
1807 "output_extension = \n"
1808 "output_dir = \n"
1809 "rustflags =\n"
1810 "rustenv =\n"
1811 "root_out_dir = .\n"
1812 "target_gen_dir = gen/foo\n"
1813 "target_out_dir = obj/foo\n"
1814 "target_output_name = bar\n"
1815 "\n"
1816 "build ./foo_bar: rust_bin ../../foo/main.rs | ../../foo/main.rs "
1817 "obj/bar/libmylib.rlib ./libshared.so ./libimplicit.so\n"
1818 " source_file_part = main.rs\n"
1819 " source_name_part = main\n"
1820 " externs = --extern mylib=obj/bar/libmylib.rlib\n"
1821 " rustdeps = -Ldependency=obj/bar -Lnative=. -Clink-arg=-Bdynamic "
1822 "-Clink-arg=./libshared.so -Clink-arg=./libimplicit.so\n"
1823 " ldflags =\n"
1824 " sources = ../../foo/main.rs\n";
1825 std::string out_str = out.str();
1826 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1827 }
1828 }
1829
TEST_F(NinjaRustBinaryTargetWriterTest,TransitiveRustDepsThroughSourceSet)1830 TEST_F(NinjaRustBinaryTargetWriterTest, TransitiveRustDepsThroughSourceSet) {
1831 Err err;
1832 TestWithScope setup;
1833
1834 Target rlib_pub(setup.settings(),
1835 Label(SourceDir("//public/"), "behind_sourceset_public"));
1836 rlib_pub.set_output_type(Target::RUST_LIBRARY);
1837 rlib_pub.visibility().SetPublic();
1838 SourceFile rlib_pub_root("//public/lib.rs");
1839 rlib_pub.sources().push_back(
1840 SourceFile("//public/behind_sourceset_public.rs"));
1841 rlib_pub.sources().push_back(rlib_pub_root);
1842 rlib_pub.source_types_used().Set(SourceFile::SOURCE_RS);
1843 rlib_pub.rust_values().set_crate_root(rlib_pub_root);
1844 rlib_pub.rust_values().crate_name() = "behind_sourceset_public";
1845 rlib_pub.SetToolchain(setup.toolchain());
1846 ASSERT_TRUE(rlib_pub.OnResolved(&err));
1847
1848 Target rlib_priv(setup.settings(),
1849 Label(SourceDir("//private/"), "behind_sourceset_private"));
1850 rlib_priv.set_output_type(Target::RUST_LIBRARY);
1851 rlib_priv.visibility().SetPublic();
1852 SourceFile rlib_priv_root("//private/lib.rs");
1853 rlib_priv.sources().push_back(
1854 SourceFile("//private/behind_sourceset_private.rs"));
1855 rlib_priv.sources().push_back(rlib_priv_root);
1856 rlib_priv.source_types_used().Set(SourceFile::SOURCE_RS);
1857 rlib_priv.rust_values().set_crate_root(rlib_priv_root);
1858 rlib_priv.rust_values().crate_name() = "behind_sourceset_private";
1859 rlib_priv.SetToolchain(setup.toolchain());
1860 ASSERT_TRUE(rlib_priv.OnResolved(&err));
1861
1862 Target sset(setup.settings(), Label(SourceDir("//sset/"), "bar"));
1863 sset.set_output_type(Target::SOURCE_SET);
1864 sset.visibility().SetPublic();
1865 sset.sources().push_back(SourceFile("//sset/input1.cc"));
1866 sset.source_types_used().Set(SourceFile::SOURCE_CPP);
1867 sset.SetToolchain(setup.toolchain());
1868 sset.public_deps().push_back(LabelTargetPair(&rlib_pub));
1869 sset.private_deps().push_back(LabelTargetPair(&rlib_priv));
1870 ASSERT_TRUE(sset.OnResolved(&err));
1871
1872 Target target(setup.settings(), Label(SourceDir("//linked/"), "exe"));
1873 target.set_output_type(Target::EXECUTABLE);
1874 target.visibility().SetPublic();
1875 SourceFile main("//linked/exe.rs");
1876 target.sources().push_back(main);
1877 target.source_types_used().Set(SourceFile::SOURCE_RS);
1878 target.rust_values().set_crate_root(main);
1879 target.rust_values().crate_name() = "exe";
1880 target.private_deps().push_back(LabelTargetPair(&sset));
1881 target.SetToolchain(setup.toolchain());
1882 ASSERT_TRUE(target.OnResolved(&err));
1883
1884 {
1885 std::ostringstream out;
1886 NinjaRustBinaryTargetWriter writer(&target, out);
1887 writer.Run();
1888
1889 const char expected[] =
1890 "crate_name = exe\n"
1891 "crate_type = bin\n"
1892 "output_extension = \n"
1893 "output_dir = \n"
1894 "rustflags =\n"
1895 "rustenv =\n"
1896 "root_out_dir = .\n"
1897 "target_gen_dir = gen/linked\n"
1898 "target_out_dir = obj/linked\n"
1899 "target_output_name = exe\n"
1900 "\n"
1901 "build ./exe: rust_bin ../../linked/exe.rs | ../../linked/exe.rs "
1902 "obj/sset/bar.input1.o obj/public/libbehind_sourceset_public.rlib "
1903 "obj/private/libbehind_sourceset_private.rlib || obj/sset/bar.stamp\n"
1904 " source_file_part = exe.rs\n"
1905 " source_name_part = exe\n"
1906 " externs = --extern "
1907 "behind_sourceset_public=obj/public/libbehind_sourceset_public.rlib\n"
1908 " rustdeps = -Ldependency=obj/public -Ldependency=obj/private "
1909 "-Lnative=obj/sset -Clink-arg=-Bdynamic "
1910 "-Clink-arg=obj/sset/bar.input1.o\n"
1911 " ldflags =\n"
1912 " sources = ../../linked/exe.rs\n";
1913 std::string out_str = out.str();
1914 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1915 }
1916 }
1917
TEST_F(NinjaRustBinaryTargetWriterTest,Pool)1918 TEST_F(NinjaRustBinaryTargetWriterTest, Pool) {
1919 Err err;
1920 TestWithScope setup;
1921
1922 Pool pool(setup.settings(),
1923 Label(SourceDir("//foo/"), "pool", setup.toolchain()->label().dir(),
1924 setup.toolchain()->label().name()));
1925 pool.set_depth(42);
1926
1927 Target target(setup.settings(), Label(SourceDir("//foo/"), "bar"));
1928 SourceFile main("//foo/source.rs");
1929 target.sources().push_back(main);
1930 target.source_types_used().Set(SourceFile::SOURCE_RS);
1931 target.rust_values().set_crate_root(main);
1932 target.rust_values().crate_name() = "bar";
1933 target.set_output_type(Target::EXECUTABLE);
1934 target.set_pool(LabelPtrPair<Pool>(&pool));
1935 target.visibility().SetPublic();
1936 target.SetToolchain(setup.toolchain());
1937 ASSERT_TRUE(target.OnResolved(&err));
1938
1939 std::ostringstream out;
1940 NinjaBinaryTargetWriter writer(&target, out);
1941 writer.Run();
1942
1943 const char expected[] =
1944 "crate_name = bar\n"
1945 "crate_type = bin\n"
1946 "output_extension = \n"
1947 "output_dir = \n"
1948 "rustflags =\n"
1949 "rustenv =\n"
1950 "root_out_dir = .\n"
1951 "target_gen_dir = gen/foo\n"
1952 "target_out_dir = obj/foo\n"
1953 "target_output_name = bar\n"
1954 "\n"
1955 "build ./bar: rust_bin ../../foo/source.rs | ../../foo/source.rs\n"
1956 " source_file_part = source.rs\n"
1957 " source_name_part = source\n"
1958 " externs =\n"
1959 " rustdeps =\n"
1960 " ldflags =\n"
1961 " sources = ../../foo/source.rs\n"
1962 " pool = foo_pool\n";
1963 std::string out_str = out.str();
1964 EXPECT_EQ(expected, out_str) << expected << "\n" << out_str;
1965 }
1966