]> git.proxmox.com Git - rustc.git/blame - src/tools/cargo/tests/testsuite/build.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / src / tools / cargo / tests / testsuite / build.rs
CommitLineData
0a29b90c
FG
1//! Tests for the `cargo build` command.
2
3use cargo::{
4 core::compiler::CompileMode,
5 core::{Shell, Workspace},
6 ops::CompileOptions,
7 Config,
8};
9use cargo_test_support::compare;
10use cargo_test_support::paths::{root, CargoPathExt};
11use cargo_test_support::registry::Package;
12use cargo_test_support::tools;
13use cargo_test_support::{
14 basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, git, is_nightly, main_file,
15 paths, process, project, rustc_host, sleep_ms, symlink_supported, t, Execs, ProjectBuilder,
16};
17use cargo_util::paths::dylib_path_envvar;
18use std::env;
19use std::fs;
20use std::io::Read;
21use std::process::Stdio;
22
23#[cargo_test]
24fn cargo_compile_simple() {
25 let p = project()
26 .file("Cargo.toml", &basic_bin_manifest("foo"))
27 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
28 .build();
29
30 p.cargo("build").run();
31 assert!(p.bin("foo").is_file());
32
33 p.process(&p.bin("foo")).with_stdout("i am foo\n").run();
34}
35
36#[cargo_test]
37fn cargo_fail_with_no_stderr() {
38 let p = project()
39 .file("Cargo.toml", &basic_bin_manifest("foo"))
40 .file("src/foo.rs", &String::from("refusal"))
41 .build();
42 p.cargo("build --message-format=json")
43 .with_status(101)
44 .with_stderr_does_not_contain("--- stderr")
45 .run();
46}
47
48/// Checks that the `CARGO_INCREMENTAL` environment variable results in
49/// `rustc` getting `-C incremental` passed to it.
50#[cargo_test]
51fn cargo_compile_incremental() {
52 let p = project()
53 .file("Cargo.toml", &basic_bin_manifest("foo"))
54 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
55 .build();
56
57 p.cargo("build -v")
58 .env("CARGO_INCREMENTAL", "1")
59 .with_stderr_contains(
60 "[RUNNING] `rustc [..] -C incremental=[..]/target/debug/incremental[..]`\n",
61 )
62 .run();
63
64 p.cargo("test -v")
65 .env("CARGO_INCREMENTAL", "1")
66 .with_stderr_contains(
67 "[RUNNING] `rustc [..] -C incremental=[..]/target/debug/incremental[..]`\n",
68 )
69 .run();
70}
71
72#[cargo_test]
73fn incremental_profile() {
74 let p = project()
75 .file(
76 "Cargo.toml",
77 r#"
78 [package]
79 name = "foo"
80 version = "0.1.0"
81 authors = []
82
83 [profile.dev]
84 incremental = false
85
86 [profile.release]
87 incremental = true
88 "#,
89 )
90 .file("src/main.rs", "fn main() {}")
91 .build();
92
93 p.cargo("build -v")
94 .env_remove("CARGO_INCREMENTAL")
95 .with_stderr_does_not_contain("[..]C incremental=[..]")
96 .run();
97
98 p.cargo("build -v")
99 .env("CARGO_INCREMENTAL", "1")
100 .with_stderr_contains("[..]C incremental=[..]")
101 .run();
102
103 p.cargo("build --release -v")
104 .env_remove("CARGO_INCREMENTAL")
105 .with_stderr_contains("[..]C incremental=[..]")
106 .run();
107
108 p.cargo("build --release -v")
109 .env("CARGO_INCREMENTAL", "0")
110 .with_stderr_does_not_contain("[..]C incremental=[..]")
111 .run();
112}
113
114#[cargo_test]
115fn incremental_config() {
116 let p = project()
117 .file("src/main.rs", "fn main() {}")
118 .file(
119 ".cargo/config",
120 r#"
121 [build]
122 incremental = false
123 "#,
124 )
125 .build();
126
127 p.cargo("build -v")
128 .env_remove("CARGO_INCREMENTAL")
129 .with_stderr_does_not_contain("[..]C incremental=[..]")
130 .run();
131
132 p.cargo("build -v")
133 .env("CARGO_INCREMENTAL", "1")
134 .with_stderr_contains("[..]C incremental=[..]")
135 .run();
136}
137
781aab86
FG
138#[cargo_test]
139fn cargo_compile_with_redundant_default_mode() {
140 let p = project()
141 .file("Cargo.toml", &basic_bin_manifest("foo"))
142 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
143 .build();
144
145 p.cargo("build --debug")
146 .with_stderr(
147 "\
148error: unexpected argument '--debug' found
149
150 tip: `--debug` is the default for `cargo build`; instead `--release` is supported
151
152Usage: cargo[EXE] build [OPTIONS]
153
154For more information, try '--help'.
155",
156 )
157 .with_status(1)
158 .run();
159}
160
ed00b5ec
FG
161#[cargo_test]
162fn cargo_compile_with_unsupported_short_config_flag() {
163 let p = project()
164 .file("Cargo.toml", &basic_bin_manifest("foo"))
165 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
166 .build();
167
168 p.cargo("build -c net.git-fetch-with-cli=true")
169 .with_stderr(
170 "\
171error: unexpected argument '-c' found
172
173 tip: a similar argument exists: '--config'
174
175Usage: cargo[EXE] build [OPTIONS]
176
177For more information, try '--help'.
178",
179 )
180 .with_status(1)
181 .run();
182}
183
0a29b90c
FG
184#[cargo_test]
185fn cargo_compile_with_workspace_excluded() {
186 let p = project().file("src/main.rs", "fn main() {}").build();
187
188 p.cargo("build --workspace --exclude foo")
189 .with_stderr_does_not_contain("[..]virtual[..]")
190 .with_stderr_contains("[..]no packages to compile")
191 .with_status(101)
192 .run();
193}
194
195#[cargo_test]
196fn cargo_compile_manifest_path() {
197 let p = project()
198 .file("Cargo.toml", &basic_bin_manifest("foo"))
199 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
200 .build();
201
202 p.cargo("build --manifest-path foo/Cargo.toml")
203 .cwd(p.root().parent().unwrap())
204 .run();
205 assert!(p.bin("foo").is_file());
206}
207
ed00b5ec
FG
208#[cargo_test]
209fn cargo_compile_with_wrong_manifest_path_flag() {
210 let p = project()
211 .file("Cargo.toml", &basic_bin_manifest("foo"))
212 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
213 .build();
214
215 p.cargo("build --path foo/Cargo.toml")
216 .cwd(p.root().parent().unwrap())
217 .with_stderr(
218 "\
219error: unexpected argument '--path' found
220
221 tip: a similar argument exists: '--manifest-path'
222
223Usage: cargo[EXE] build [OPTIONS]
224
225For more information, try '--help'.
226",
227 )
228 .with_status(1)
229 .run();
230}
231
0a29b90c
FG
232#[cargo_test]
233fn chdir_gated() {
234 let p = project()
235 .file("Cargo.toml", &basic_bin_manifest("foo"))
236 .build();
237 p.cargo("-C foo build")
238 .cwd(p.root().parent().unwrap())
239 .with_stderr(
240 "error: the `-C` flag is unstable, \
241 pass `-Z unstable-options` on the nightly channel to enable it",
242 )
243 .with_status(101)
244 .run();
245 // No masquerade should also fail.
246 p.cargo("-C foo -Z unstable-options build")
247 .cwd(p.root().parent().unwrap())
248 .with_stderr(
249 "error: the `-C` flag is unstable, \
250 pass `-Z unstable-options` on the nightly channel to enable it",
251 )
252 .with_status(101)
253 .run();
254}
255
256#[cargo_test]
257fn cargo_compile_directory_not_cwd() {
258 let p = project()
259 .file("Cargo.toml", &basic_bin_manifest("foo"))
260 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
261 .file(".cargo/config.toml", &"")
262 .build();
263
264 p.cargo("-Zunstable-options -C foo build")
265 .masquerade_as_nightly_cargo(&["chdir"])
266 .cwd(p.root().parent().unwrap())
267 .run();
268 assert!(p.bin("foo").is_file());
269}
270
ed00b5ec
FG
271#[cargo_test]
272fn cargo_compile_with_unsupported_short_unstable_feature_flag() {
273 let p = project()
274 .file("Cargo.toml", &basic_bin_manifest("foo"))
275 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
276 .file(".cargo/config.toml", &"")
277 .build();
278
279 p.cargo("-zunstable-options -C foo build")
280 .masquerade_as_nightly_cargo(&["chdir"])
281 .cwd(p.root().parent().unwrap())
282 .with_stderr(
283 "\
284error: unexpected argument '-z' found
285
286 tip: a similar argument exists: '-Z'
287
288Usage: cargo [..][OPTIONS] [COMMAND]
289 cargo [..][OPTIONS] -Zscript <MANIFEST_RS> [ARGS]...
290
291For more information, try '--help'.
292",
293 )
294 .with_status(1)
295 .run();
296}
297
0a29b90c
FG
298#[cargo_test]
299fn cargo_compile_directory_not_cwd_with_invalid_config() {
300 let p = project()
301 .file("Cargo.toml", &basic_bin_manifest("foo"))
302 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
303 .file(".cargo/config.toml", &"!")
304 .build();
305
306 p.cargo("-Zunstable-options -C foo build")
307 .masquerade_as_nightly_cargo(&["chdir"])
308 .cwd(p.root().parent().unwrap())
309 .with_status(101)
310 .with_stderr_contains(
311 "\
312Caused by:
313 TOML parse error at line 1, column 1
314 |
315 1 | !
316 | ^
317 invalid key
318",
319 )
320 .run();
321}
322
323#[cargo_test]
324fn cargo_compile_with_invalid_manifest() {
325 let p = project().file("Cargo.toml", "").build();
326
327 p.cargo("build")
328 .with_status(101)
329 .with_stderr(
330 "\
331[ERROR] failed to parse manifest at `[..]`
332
333Caused by:
334 virtual manifests must be configured with [workspace]
335",
336 )
337 .run();
338}
339
340#[cargo_test]
341fn cargo_compile_with_invalid_manifest2() {
342 let p = project()
343 .file(
344 "Cargo.toml",
345 "
346 [package]
347 foo = bar
348 ",
349 )
350 .build();
351
352 p.cargo("build")
353 .with_status(101)
354 .with_stderr(
355 "\
356[ERROR] failed to parse manifest at `[..]`
357
0a29b90c
FG
358Caused by:
359 TOML parse error at line 3, column 23
360 |
361 3 | foo = bar
362 | ^
363 invalid string
364 expected `\"`, `'`
365",
366 )
367 .run();
368}
369
370#[cargo_test]
371fn cargo_compile_with_invalid_manifest3() {
372 let p = project().file("src/Cargo.toml", "a = bar").build();
373
374 p.cargo("build --manifest-path src/Cargo.toml")
375 .with_status(101)
376 .with_stderr(
377 "\
378[ERROR] failed to parse manifest at `[..]`
379
0a29b90c
FG
380Caused by:
381 TOML parse error at line 1, column 5
382 |
383 1 | a = bar
384 | ^
385 invalid string
386 expected `\"`, `'`
387",
388 )
389 .run();
390}
391
392#[cargo_test]
393fn cargo_compile_duplicate_build_targets() {
394 let p = project()
395 .file(
396 "Cargo.toml",
397 r#"
398 [package]
399 name = "foo"
400 version = "0.0.1"
401 authors = []
402
403 [lib]
404 name = "main"
405 path = "src/main.rs"
406 crate-type = ["dylib"]
407
408 [dependencies]
409 "#,
410 )
411 .file("src/main.rs", "#![allow(warnings)] fn main() {}")
412 .build();
413
414 p.cargo("build")
415 .with_stderr(
416 "\
417warning: file `[..]main.rs` found to be present in multiple build targets:
418 * `lib` target `main`
419 * `bin` target `foo`
420[COMPILING] foo v0.0.1 ([..])
421[FINISHED] [..]
422",
423 )
424 .run();
425}
426
427#[cargo_test]
428fn cargo_compile_with_invalid_version() {
429 let p = project()
430 .file("Cargo.toml", &basic_manifest("foo", "1.0"))
431 .build();
432
433 p.cargo("build")
434 .with_status(101)
435 .with_stderr(
436 "\
437[ERROR] failed to parse manifest at `[..]`
438
439Caused by:
781aab86
FG
440 TOML parse error at line 4, column 19
441 |
442 4 | version = \"1.0\"
443 | ^^^^^
0a29b90c 444 unexpected end of input while parsing minor version number
0a29b90c
FG
445",
446 )
447 .run();
448}
449
450#[cargo_test]
451fn cargo_compile_with_empty_package_name() {
452 let p = project()
453 .file("Cargo.toml", &basic_manifest("", "0.0.0"))
454 .build();
455
456 p.cargo("build")
457 .with_status(101)
458 .with_stderr(
459 "\
460[ERROR] failed to parse manifest at `[..]`
461
462Caused by:
4b012472
FG
463 TOML parse error at line 3, column 16
464 |
465 3 | name = \"\"
466 | ^^
467 package name cannot be empty
0a29b90c
FG
468",
469 )
470 .run();
471}
472
473#[cargo_test]
474fn cargo_compile_with_invalid_package_name() {
475 let p = project()
476 .file("Cargo.toml", &basic_manifest("foo::bar", "0.0.0"))
477 .build();
478
479 p.cargo("build")
480 .with_status(101)
481 .with_stderr(
482 "\
483[ERROR] failed to parse manifest at `[..]`
484
485Caused by:
4b012472
FG
486 TOML parse error at line 3, column 16
487 |
488 3 | name = \"foo::bar\"
489 | ^^^^^^^^^^
0a29b90c
FG
490 invalid character `:` in package name: `foo::bar`, [..]
491",
492 )
493 .run();
494}
495
496#[cargo_test]
497fn cargo_compile_with_invalid_bin_target_name() {
498 let p = project()
499 .file(
500 "Cargo.toml",
501 r#"
502 [package]
503 name = "foo"
504 authors = []
505 version = "0.0.0"
506
507 [[bin]]
508 name = ""
509 "#,
510 )
511 .build();
512
513 p.cargo("build")
514 .with_status(101)
515 .with_stderr(
516 "\
517[ERROR] failed to parse manifest at `[..]`
518
519Caused by:
520 binary target names cannot be empty
521",
522 )
523 .run();
524}
525
526#[cargo_test]
527fn cargo_compile_with_forbidden_bin_target_name() {
528 let p = project()
529 .file(
530 "Cargo.toml",
531 r#"
532 [package]
533 name = "foo"
534 authors = []
535 version = "0.0.0"
536
537 [[bin]]
538 name = "build"
539 "#,
540 )
541 .build();
542
543 p.cargo("build")
544 .with_status(101)
545 .with_stderr(
546 "\
547[ERROR] failed to parse manifest at `[..]`
548
549Caused by:
ed00b5ec 550 the binary target name `build` is forbidden, it conflicts with cargo's build directory names
0a29b90c
FG
551",
552 )
553 .run();
554}
555
556#[cargo_test]
557fn cargo_compile_with_bin_and_crate_type() {
558 let p = project()
559 .file(
560 "Cargo.toml",
561 r#"
562 [package]
563 name = "foo"
564 authors = []
565 version = "0.0.0"
566
567 [[bin]]
568 name = "the_foo_bin"
569 path = "src/foo.rs"
570 crate-type = ["cdylib", "rlib"]
571 "#,
572 )
573 .file("src/foo.rs", "fn main() {}")
574 .build();
575
576 p.cargo("build")
577 .with_status(101)
578 .with_stderr(
579 "\
580[ERROR] failed to parse manifest at `[..]`
581
582Caused by:
583 the target `the_foo_bin` is a binary and can't have any crate-types set \
584(currently \"cdylib, rlib\")",
585 )
586 .run();
587}
588
589#[cargo_test]
590fn cargo_compile_api_exposes_artifact_paths() {
591 let p = project()
592 .file(
593 "Cargo.toml",
594 r#"
595 [package]
596 name = "foo"
597 authors = []
598 version = "0.0.0"
599
600 [[bin]]
601 name = "the_foo_bin"
602 path = "src/bin.rs"
603
604 [lib]
605 name = "the_foo_lib"
606 path = "src/foo.rs"
607 crate-type = ["cdylib", "rlib"]
608 "#,
609 )
610 .file("src/foo.rs", "pub fn bar() {}")
611 .file("src/bin.rs", "pub fn main() {}")
612 .build();
613
614 let shell = Shell::from_write(Box::new(Vec::new()));
615 let config = Config::new(shell, env::current_dir().unwrap(), paths::home());
616 let ws = Workspace::new(&p.root().join("Cargo.toml"), &config).unwrap();
617 let compile_options = CompileOptions::new(ws.config(), CompileMode::Build).unwrap();
618
619 let result = cargo::ops::compile(&ws, &compile_options).unwrap();
620
621 assert_eq!(1, result.binaries.len());
622 assert!(result.binaries[0].path.exists());
623 assert!(result.binaries[0]
624 .path
625 .to_str()
626 .unwrap()
627 .contains("the_foo_bin"));
628
629 assert_eq!(1, result.cdylibs.len());
630 // The exact library path varies by platform, but should certainly exist at least
631 assert!(result.cdylibs[0].path.exists());
632 assert!(result.cdylibs[0]
633 .path
634 .to_str()
635 .unwrap()
636 .contains("the_foo_lib"));
637}
638
639#[cargo_test]
640fn cargo_compile_with_bin_and_proc() {
641 let p = project()
642 .file(
643 "Cargo.toml",
644 r#"
645 [package]
646 name = "foo"
647 authors = []
648 version = "0.0.0"
649
650 [[bin]]
651 name = "the_foo_bin"
652 path = "src/foo.rs"
653 proc-macro = true
654 "#,
655 )
656 .file("src/foo.rs", "fn main() {}")
657 .build();
658
659 p.cargo("build")
660 .with_status(101)
661 .with_stderr(
662 "\
663[ERROR] failed to parse manifest at `[..]`
664
665Caused by:
666 the target `the_foo_bin` is a binary and can't have `proc-macro` set `true`",
667 )
668 .run();
669}
670
671#[cargo_test]
672fn cargo_compile_with_invalid_lib_target_name() {
673 let p = project()
674 .file(
675 "Cargo.toml",
676 r#"
677 [package]
678 name = "foo"
679 authors = []
680 version = "0.0.0"
681
682 [lib]
683 name = ""
684 "#,
685 )
686 .build();
687
688 p.cargo("build")
689 .with_status(101)
690 .with_stderr(
691 "\
692[ERROR] failed to parse manifest at `[..]`
693
694Caused by:
695 library target names cannot be empty
696",
697 )
698 .run();
699}
700
701#[cargo_test]
702fn cargo_compile_with_invalid_non_numeric_dep_version() {
703 let p = project()
704 .file(
705 "Cargo.toml",
706 r#"
707 [package]
708 name = "foo"
709 version = "0.0.1"
710
711 [dependencies]
712 crossbeam = "y"
713 "#,
714 )
715 .build();
716
717 p.cargo("build")
718 .with_status(101)
719 .with_stderr(
720 "\
721[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`
722
723Caused by:
724 failed to parse the version requirement `y` for dependency `crossbeam`
725
726Caused by:
727 unexpected character 'y' while parsing major version number
728",
729 )
730 .run();
731}
732
733#[cargo_test]
734fn cargo_compile_without_manifest() {
735 let p = project().no_manifest().build();
736
737 p.cargo("build")
738 .with_status(101)
739 .with_stderr("[ERROR] could not find `Cargo.toml` in `[..]` or any parent directory")
740 .run();
741}
742
743#[cargo_test]
744#[cfg(target_os = "linux")]
745fn cargo_compile_with_lowercase_cargo_toml() {
746 let p = project()
747 .no_manifest()
748 .file("cargo.toml", &basic_manifest("foo", "0.1.0"))
749 .file("src/lib.rs", &main_file(r#""i am foo""#, &[]))
750 .build();
751
752 p.cargo("build")
753 .with_status(101)
754 .with_stderr(
755 "[ERROR] could not find `Cargo.toml` in `[..]` or any parent directory, \
756 but found cargo.toml please try to rename it to Cargo.toml",
757 )
758 .run();
759}
760
761#[cargo_test]
762fn cargo_compile_with_invalid_code() {
763 let p = project()
764 .file("Cargo.toml", &basic_bin_manifest("foo"))
765 .file("src/foo.rs", "invalid rust code!")
766 .build();
767
768 p.cargo("build")
769 .with_status(101)
770 .with_stderr_contains(
4b012472 771 "[ERROR] could not compile `foo` (bin \"foo\") due to 1 previous error\n",
0a29b90c
FG
772 )
773 .run();
774 assert!(p.root().join("Cargo.lock").is_file());
775}
776
777#[cargo_test]
778fn cargo_compile_with_invalid_code_in_deps() {
779 let p = project()
780 .file(
781 "Cargo.toml",
782 r#"
783 [package]
784 name = "foo"
785 version = "0.0.1"
786 authors = []
787
788 [dependencies.bar]
789 path = "../bar"
790 [dependencies.baz]
791 path = "../baz"
792 "#,
793 )
794 .file("src/main.rs", "invalid rust code!")
795 .build();
796 let _bar = project()
797 .at("bar")
798 .file("Cargo.toml", &basic_manifest("bar", "0.1.0"))
799 .file("src/lib.rs", "invalid rust code!")
800 .build();
801 let _baz = project()
802 .at("baz")
803 .file("Cargo.toml", &basic_manifest("baz", "0.1.0"))
804 .file("src/lib.rs", "invalid rust code!")
805 .build();
806 p.cargo("build")
807 .with_status(101)
808 .with_stderr_contains("[..]invalid rust code[..]")
809 .with_stderr_contains("[ERROR] could not compile [..]")
810 .run();
811}
812
813#[cargo_test]
814fn cargo_compile_with_warnings_in_the_root_package() {
815 let p = project()
816 .file("Cargo.toml", &basic_bin_manifest("foo"))
817 .file("src/foo.rs", "fn main() {} fn dead() {}")
818 .build();
819
820 p.cargo("build")
821 .with_stderr_contains("[WARNING] [..]dead[..]")
822 .run();
823}
824
825#[cargo_test]
826fn cargo_compile_with_warnings_in_a_dep_package() {
827 let p = project()
828 .file(
829 "Cargo.toml",
830 r#"
831 [package]
832
833 name = "foo"
834 version = "0.5.0"
835 authors = ["wycats@example.com"]
836
837 [dependencies.bar]
838 path = "bar"
839
840 [[bin]]
841
842 name = "foo"
843 "#,
844 )
845 .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
846 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
847 .file(
848 "bar/src/bar.rs",
849 r#"
850 pub fn gimme() -> &'static str {
851 "test passed"
852 }
853
854 fn dead() {}
855 "#,
856 )
857 .build();
858
859 p.cargo("build")
860 .with_stderr_contains("[WARNING] [..]dead[..]")
861 .run();
862
863 assert!(p.bin("foo").is_file());
864
865 p.process(&p.bin("foo")).with_stdout("test passed\n").run();
866}
867
868#[cargo_test]
869fn cargo_compile_with_nested_deps_inferred() {
870 let p = project()
871 .file(
872 "Cargo.toml",
873 r#"
874 [package]
875
876 name = "foo"
877 version = "0.5.0"
878 authors = ["wycats@example.com"]
879
880 [dependencies.bar]
881 path = 'bar'
882
883 [[bin]]
884 name = "foo"
885 "#,
886 )
887 .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
888 .file(
889 "bar/Cargo.toml",
890 r#"
891 [package]
892
893 name = "bar"
894 version = "0.5.0"
895 authors = ["wycats@example.com"]
896
897 [dependencies.baz]
898 path = "../baz"
899 "#,
900 )
901 .file(
902 "bar/src/lib.rs",
903 r#"
904 extern crate baz;
905
906 pub fn gimme() -> String {
907 baz::gimme()
908 }
909 "#,
910 )
911 .file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0"))
912 .file(
913 "baz/src/lib.rs",
914 r#"
915 pub fn gimme() -> String {
916 "test passed".to_string()
917 }
918 "#,
919 )
920 .build();
921
922 p.cargo("build").run();
923
924 assert!(p.bin("foo").is_file());
925 assert!(!p.bin("libbar.rlib").is_file());
926 assert!(!p.bin("libbaz.rlib").is_file());
927
928 p.process(&p.bin("foo")).with_stdout("test passed\n").run();
929}
930
931#[cargo_test]
932fn cargo_compile_with_nested_deps_correct_bin() {
933 let p = project()
934 .file(
935 "Cargo.toml",
936 r#"
937 [package]
938
939 name = "foo"
940 version = "0.5.0"
941 authors = ["wycats@example.com"]
942
943 [dependencies.bar]
944 path = "bar"
945
946 [[bin]]
947 name = "foo"
948 "#,
949 )
950 .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
951 .file(
952 "bar/Cargo.toml",
953 r#"
954 [package]
955
956 name = "bar"
957 version = "0.5.0"
958 authors = ["wycats@example.com"]
959
960 [dependencies.baz]
961 path = "../baz"
962 "#,
963 )
964 .file(
965 "bar/src/lib.rs",
966 r#"
967 extern crate baz;
968
969 pub fn gimme() -> String {
970 baz::gimme()
971 }
972 "#,
973 )
974 .file("baz/Cargo.toml", &basic_manifest("baz", "0.5.0"))
975 .file(
976 "baz/src/lib.rs",
977 r#"
978 pub fn gimme() -> String {
979 "test passed".to_string()
980 }
981 "#,
982 )
983 .build();
984
985 p.cargo("build").run();
986
987 assert!(p.bin("foo").is_file());
988 assert!(!p.bin("libbar.rlib").is_file());
989 assert!(!p.bin("libbaz.rlib").is_file());
990
991 p.process(&p.bin("foo")).with_stdout("test passed\n").run();
992}
993
994#[cargo_test]
995fn cargo_compile_with_nested_deps_shorthand() {
996 let p = project()
997 .file(
998 "Cargo.toml",
999 r#"
1000 [package]
1001
1002 name = "foo"
1003 version = "0.5.0"
1004 authors = ["wycats@example.com"]
1005
1006 [dependencies.bar]
1007 path = "bar"
1008 "#,
1009 )
1010 .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
1011 .file(
1012 "bar/Cargo.toml",
1013 r#"
1014 [package]
1015
1016 name = "bar"
1017 version = "0.5.0"
1018 authors = ["wycats@example.com"]
1019
1020 [dependencies.baz]
1021 path = "../baz"
1022
1023 [lib]
1024
1025 name = "bar"
1026 "#,
1027 )
1028 .file(
1029 "bar/src/bar.rs",
1030 r#"
1031 extern crate baz;
1032
1033 pub fn gimme() -> String {
1034 baz::gimme()
1035 }
1036 "#,
1037 )
1038 .file("baz/Cargo.toml", &basic_lib_manifest("baz"))
1039 .file(
1040 "baz/src/baz.rs",
1041 r#"
1042 pub fn gimme() -> String {
1043 "test passed".to_string()
1044 }
1045 "#,
1046 )
1047 .build();
1048
1049 p.cargo("build").run();
1050
1051 assert!(p.bin("foo").is_file());
1052 assert!(!p.bin("libbar.rlib").is_file());
1053 assert!(!p.bin("libbaz.rlib").is_file());
1054
1055 p.process(&p.bin("foo")).with_stdout("test passed\n").run();
1056}
1057
1058#[cargo_test]
1059fn cargo_compile_with_nested_deps_longhand() {
1060 let p = project()
1061 .file(
1062 "Cargo.toml",
1063 r#"
1064 [package]
1065
1066 name = "foo"
1067 version = "0.5.0"
1068 authors = ["wycats@example.com"]
1069
1070 [dependencies.bar]
1071 path = "bar"
1072 version = "0.5.0"
1073
1074 [[bin]]
1075
1076 name = "foo"
1077 "#,
1078 )
1079 .file("src/foo.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
1080 .file(
1081 "bar/Cargo.toml",
1082 r#"
1083 [package]
1084
1085 name = "bar"
1086 version = "0.5.0"
1087 authors = ["wycats@example.com"]
1088
1089 [dependencies.baz]
1090 path = "../baz"
1091 version = "0.5.0"
1092
1093 [lib]
1094
1095 name = "bar"
1096 "#,
1097 )
1098 .file(
1099 "bar/src/bar.rs",
1100 r#"
1101 extern crate baz;
1102
1103 pub fn gimme() -> String {
1104 baz::gimme()
1105 }
1106 "#,
1107 )
1108 .file("baz/Cargo.toml", &basic_lib_manifest("baz"))
1109 .file(
1110 "baz/src/baz.rs",
1111 r#"
1112 pub fn gimme() -> String {
1113 "test passed".to_string()
1114 }
1115 "#,
1116 )
1117 .build();
1118
1119 p.cargo("build").run();
1120
1121 assert!(p.bin("foo").is_file());
1122 assert!(!p.bin("libbar.rlib").is_file());
1123 assert!(!p.bin("libbaz.rlib").is_file());
1124
1125 p.process(&p.bin("foo")).with_stdout("test passed\n").run();
1126}
1127
1128// Check that Cargo gives a sensible error if a dependency can't be found
1129// because of a name mismatch.
1130#[cargo_test]
1131fn cargo_compile_with_dep_name_mismatch() {
1132 let p = project()
1133 .file(
1134 "Cargo.toml",
1135 r#"
1136 [package]
1137
1138 name = "foo"
1139 version = "0.0.1"
1140 authors = ["wycats@example.com"]
1141
1142 [[bin]]
1143
1144 name = "foo"
1145
1146 [dependencies.notquitebar]
1147
1148 path = "bar"
1149 "#,
1150 )
1151 .file("src/bin/foo.rs", &main_file(r#""i am foo""#, &["bar"]))
1152 .file("bar/Cargo.toml", &basic_bin_manifest("bar"))
1153 .file("bar/src/bar.rs", &main_file(r#""i am bar""#, &[]))
1154 .build();
1155
1156 p.cargo("build")
1157 .with_status(101)
1158 .with_stderr(
1159 "\
1160error: no matching package named `notquitebar` found
1161location searched: [CWD]/bar
1162required by package `foo v0.0.1 ([CWD])`
1163",
1164 )
1165 .run();
1166}
1167
1168// Ensure that renamed deps have a valid name
1169#[cargo_test]
1170fn cargo_compile_with_invalid_dep_rename() {
1171 let p = project()
1172 .file(
1173 "Cargo.toml",
1174 r#"
1175 [package]
1176 name = "buggin"
1177 version = "0.1.0"
1178
1179 [dependencies]
1180 "haha this isn't a valid name 🐛" = { package = "libc", version = "0.1" }
1181 "#,
1182 )
1183 .file("src/main.rs", &main_file(r#""What's good?""#, &[]))
1184 .build();
1185
1186 p.cargo("build")
1187 .with_status(101)
1188 .with_stderr(
1189 "\
1190error: failed to parse manifest at `[..]`
1191
1192Caused by:
4b012472
FG
1193 TOML parse error at line 7, column 17
1194 |
1195 7 | \"haha this isn't a valid name 🐛\" = { package = \"libc\", version = \"0.1\" }
1196 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1197 invalid character ` ` in package name: `haha this isn't a valid name 🐛`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)
0a29b90c
FG
1198",
1199 )
1200 .run();
1201}
1202
1203#[cargo_test]
1204fn cargo_compile_with_filename() {
1205 let p = project()
1206 .file("src/lib.rs", "")
1207 .file(
1208 "src/bin/a.rs",
1209 r#"
1210 extern crate foo;
1211 fn main() { println!("hello a.rs"); }
1212 "#,
1213 )
1214 .file("examples/a.rs", r#"fn main() { println!("example"); }"#)
1215 .build();
1216
1217 p.cargo("build --bin bin.rs")
1218 .with_status(101)
1219 .with_stderr(
1220 "\
1221[ERROR] no bin target named `bin.rs`.
1222Available bin targets:
1223 a
1224
1225",
1226 )
1227 .run();
1228
1229 p.cargo("build --bin a.rs")
1230 .with_status(101)
1231 .with_stderr(
1232 "\
1233[ERROR] no bin target named `a.rs`
1234
1235<tab>Did you mean `a`?",
1236 )
1237 .run();
1238
1239 p.cargo("build --example example.rs")
1240 .with_status(101)
1241 .with_stderr(
1242 "\
1243[ERROR] no example target named `example.rs`.
1244Available example targets:
1245 a
1246
1247",
1248 )
1249 .run();
1250
1251 p.cargo("build --example a.rs")
1252 .with_status(101)
1253 .with_stderr(
1254 "\
1255[ERROR] no example target named `a.rs`
1256
1257<tab>Did you mean `a`?",
1258 )
1259 .run();
1260}
1261
1262#[cargo_test]
1263fn incompatible_dependencies() {
1264 Package::new("bad", "0.1.0").publish();
1265 Package::new("bad", "1.0.0").publish();
1266 Package::new("bad", "1.0.1").publish();
1267 Package::new("bad", "1.0.2").publish();
1268 Package::new("bar", "0.1.0").dep("bad", "0.1.0").publish();
1269 Package::new("baz", "0.1.1").dep("bad", "=1.0.0").publish();
1270 Package::new("baz", "0.1.0").dep("bad", "=1.0.0").publish();
1271 Package::new("qux", "0.1.2").dep("bad", ">=1.0.1").publish();
1272 Package::new("qux", "0.1.1").dep("bad", ">=1.0.1").publish();
1273 Package::new("qux", "0.1.0").dep("bad", ">=1.0.1").publish();
1274
1275 let p = project()
1276 .file(
1277 "Cargo.toml",
1278 r#"
1279 [package]
1280 name = "foo"
1281 version = "0.0.1"
1282
1283 [dependencies]
1284 bar = "0.1.0"
1285 baz = "0.1.0"
1286 qux = "0.1.0"
1287 "#,
1288 )
1289 .file("src/main.rs", "fn main(){}")
1290 .build();
1291
1292 p.cargo("build")
1293 .with_status(101)
1294 .with_stderr_contains(
1295 "\
1296error: failed to select a version for `bad`.
1297 ... required by package `qux v0.1.0`
1298 ... which satisfies dependency `qux = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
1299versions that meet the requirements `>=1.0.1` are: 1.0.2, 1.0.1
1300
1301all possible versions conflict with previously selected packages.
1302
1303 previously selected package `bad v1.0.0`
1304 ... which satisfies dependency `bad = \"=1.0.0\"` of package `baz v0.1.0`
1305 ... which satisfies dependency `baz = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
1306
1307failed to select a version for `bad` which could resolve this conflict",
1308 )
1309 .run();
1310}
1311
1312#[cargo_test]
1313fn incompatible_dependencies_with_multi_semver() {
1314 Package::new("bad", "1.0.0").publish();
1315 Package::new("bad", "1.0.1").publish();
1316 Package::new("bad", "2.0.0").publish();
1317 Package::new("bad", "2.0.1").publish();
1318 Package::new("bar", "0.1.0").dep("bad", "=1.0.0").publish();
1319 Package::new("baz", "0.1.0").dep("bad", ">=2.0.1").publish();
1320
1321 let p = project()
1322 .file(
1323 "Cargo.toml",
1324 r#"
1325 [package]
1326 name = "foo"
1327 version = "0.0.1"
1328
1329 [dependencies]
1330 bar = "0.1.0"
1331 baz = "0.1.0"
1332 bad = ">=1.0.1, <=2.0.0"
1333 "#,
1334 )
1335 .file("src/main.rs", "fn main(){}")
1336 .build();
1337
1338 p.cargo("build")
1339 .with_status(101)
1340 .with_stderr_contains(
1341 "\
1342error: failed to select a version for `bad`.
1343 ... required by package `foo v0.0.1 ([..])`
1344versions that meet the requirements `>=1.0.1, <=2.0.0` are: 2.0.0, 1.0.1
1345
1346all possible versions conflict with previously selected packages.
1347
1348 previously selected package `bad v2.0.1`
1349 ... which satisfies dependency `bad = \">=2.0.1\"` of package `baz v0.1.0`
1350 ... which satisfies dependency `baz = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
1351
1352 previously selected package `bad v1.0.0`
1353 ... which satisfies dependency `bad = \"=1.0.0\"` of package `bar v0.1.0`
1354 ... which satisfies dependency `bar = \"^0.1.0\"` of package `foo v0.0.1 ([..])`
1355
1356failed to select a version for `bad` which could resolve this conflict",
1357 )
1358 .run();
1359}
1360
1361#[cargo_test]
1362fn compile_path_dep_then_change_version() {
1363 let p = project()
1364 .file(
1365 "Cargo.toml",
1366 r#"
1367 [package]
1368 name = "foo"
1369 version = "0.0.1"
1370 authors = []
1371
1372 [dependencies.bar]
1373 path = "bar"
1374 "#,
1375 )
1376 .file("src/lib.rs", "")
1377 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
1378 .file("bar/src/lib.rs", "")
1379 .build();
1380
1381 p.cargo("build").run();
1382
1383 p.change_file("bar/Cargo.toml", &basic_manifest("bar", "0.0.2"));
1384
1385 p.cargo("build").run();
1386}
1387
1388#[cargo_test]
1389fn ignores_carriage_return_in_lockfile() {
1390 let p = project()
1391 .file("src/main.rs", "mod a; fn main() {}")
1392 .file("src/a.rs", "")
1393 .build();
1394
1395 p.cargo("build").run();
1396
1397 let lock = p.read_lockfile();
1398 p.change_file("Cargo.lock", &lock.replace("\n", "\r\n"));
1399 p.cargo("build").run();
1400}
1401
1402#[cargo_test]
1403fn cargo_default_env_metadata_env_var() {
1404 // Ensure that path dep + dylib + env_var get metadata
1405 // (even though path_dep + dylib should not)
1406 let p = project()
1407 .file(
1408 "Cargo.toml",
1409 r#"
1410 [package]
1411 name = "foo"
1412 version = "0.0.1"
1413 authors = []
1414
1415 [dependencies.bar]
1416 path = "bar"
1417 "#,
1418 )
1419 .file("src/lib.rs", "// hi")
1420 .file(
1421 "bar/Cargo.toml",
1422 r#"
1423 [package]
1424 name = "bar"
1425 version = "0.0.1"
1426 authors = []
1427
1428 [lib]
1429 name = "bar"
1430 crate_type = ["dylib"]
1431 "#,
1432 )
1433 .file("bar/src/lib.rs", "// hello")
1434 .build();
1435
1436 // No metadata on libbar since it's a dylib path dependency
1437 p.cargo("build -v")
1438 .with_stderr(&format!(
1439 "\
1440[COMPILING] bar v0.0.1 ([CWD]/bar)
1441[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type dylib \
1442 --emit=[..]link \
fe692bf9 1443 -C prefer-dynamic[..]-C debuginfo=2 [..]\
0a29b90c
FG
1444 -C metadata=[..] \
1445 --out-dir [..] \
1446 -L dependency=[CWD]/target/debug/deps`
1447[COMPILING] foo v0.0.1 ([CWD])
1448[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
fe692bf9 1449 --emit=[..]link[..]-C debuginfo=2 [..]\
0a29b90c
FG
1450 -C metadata=[..] \
1451 -C extra-filename=[..] \
1452 --out-dir [..] \
1453 -L dependency=[CWD]/target/debug/deps \
1454 --extern bar=[CWD]/target/debug/deps/{prefix}bar{suffix}`
1455[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
1456 prefix = env::consts::DLL_PREFIX,
1457 suffix = env::consts::DLL_SUFFIX,
1458 ))
1459 .run();
1460
1461 p.cargo("clean").run();
1462
1463 // If you set the env-var, then we expect metadata on libbar
1464 p.cargo("build -v")
1465 .env("__CARGO_DEFAULT_LIB_METADATA", "stable")
1466 .with_stderr(&format!(
1467 "\
1468[COMPILING] bar v0.0.1 ([CWD]/bar)
1469[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type dylib \
1470 --emit=[..]link \
fe692bf9 1471 -C prefer-dynamic[..]-C debuginfo=2 [..]\
0a29b90c
FG
1472 -C metadata=[..] \
1473 --out-dir [..] \
1474 -L dependency=[CWD]/target/debug/deps`
1475[COMPILING] foo v0.0.1 ([CWD])
1476[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
fe692bf9 1477 --emit=[..]link[..]-C debuginfo=2 [..]\
0a29b90c
FG
1478 -C metadata=[..] \
1479 -C extra-filename=[..] \
1480 --out-dir [..] \
1481 -L dependency=[CWD]/target/debug/deps \
1482 --extern bar=[CWD]/target/debug/deps/{prefix}bar-[..]{suffix}`
1483[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1484",
1485 prefix = env::consts::DLL_PREFIX,
1486 suffix = env::consts::DLL_SUFFIX,
1487 ))
1488 .run();
1489}
1490
1491#[cargo_test]
1492fn crate_env_vars() {
1493 let p = project()
1494 .file(
1495 "Cargo.toml",
1496 r#"
1497 [package]
1498 name = "foo"
1499 version = "0.5.1-alpha.1"
1500 description = "This is foo"
1501 homepage = "https://example.com"
1502 repository = "https://example.com/repo.git"
1503 authors = ["wycats@example.com"]
1504 license = "MIT OR Apache-2.0"
1505 license-file = "license.txt"
1506 rust-version = "1.61.0"
1507 readme = "../../README.md"
1508
1509 [[bin]]
1510 name = "foo-bar"
1511 path = "src/main.rs"
1512 "#,
1513 )
1514 .file(
1515 "src/main.rs",
1516 r#"
1517 extern crate foo;
1518
1519
1520 static VERSION_MAJOR: &'static str = env!("CARGO_PKG_VERSION_MAJOR");
1521 static VERSION_MINOR: &'static str = env!("CARGO_PKG_VERSION_MINOR");
1522 static VERSION_PATCH: &'static str = env!("CARGO_PKG_VERSION_PATCH");
1523 static VERSION_PRE: &'static str = env!("CARGO_PKG_VERSION_PRE");
1524 static VERSION: &'static str = env!("CARGO_PKG_VERSION");
1525 static CARGO_MANIFEST_DIR: &'static str = env!("CARGO_MANIFEST_DIR");
1526 static PKG_NAME: &'static str = env!("CARGO_PKG_NAME");
1527 static HOMEPAGE: &'static str = env!("CARGO_PKG_HOMEPAGE");
1528 static REPOSITORY: &'static str = env!("CARGO_PKG_REPOSITORY");
1529 static LICENSE: &'static str = env!("CARGO_PKG_LICENSE");
1530 static LICENSE_FILE: &'static str = env!("CARGO_PKG_LICENSE_FILE");
1531 static DESCRIPTION: &'static str = env!("CARGO_PKG_DESCRIPTION");
1532 static RUST_VERSION: &'static str = env!("CARGO_PKG_RUST_VERSION");
1533 static README: &'static str = env!("CARGO_PKG_README");
1534 static BIN_NAME: &'static str = env!("CARGO_BIN_NAME");
1535 static CRATE_NAME: &'static str = env!("CARGO_CRATE_NAME");
1536
1537
1538 fn main() {
1539 let s = format!("{}-{}-{} @ {} in {}", VERSION_MAJOR,
1540 VERSION_MINOR, VERSION_PATCH, VERSION_PRE,
1541 CARGO_MANIFEST_DIR);
1542 assert_eq!(s, foo::version());
1543 println!("{}", s);
1544 assert_eq!("foo", PKG_NAME);
1545 assert_eq!("foo-bar", BIN_NAME);
1546 assert_eq!("foo_bar", CRATE_NAME);
1547 assert_eq!("https://example.com", HOMEPAGE);
1548 assert_eq!("https://example.com/repo.git", REPOSITORY);
1549 assert_eq!("MIT OR Apache-2.0", LICENSE);
1550 assert_eq!("license.txt", LICENSE_FILE);
1551 assert_eq!("This is foo", DESCRIPTION);
1552 assert_eq!("1.61.0", RUST_VERSION);
1553 assert_eq!("../../README.md", README);
1554 let s = format!("{}.{}.{}-{}", VERSION_MAJOR,
1555 VERSION_MINOR, VERSION_PATCH, VERSION_PRE);
1556 assert_eq!(s, VERSION);
1557
1558 // Verify CARGO_TARGET_TMPDIR isn't set for bins
1559 assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
4b012472
FG
1560
1561 // Verify CARGO_RUSTC_CURRENT_DIR is set for examples
1562 let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1563 let file_path = workspace_dir.join(file!());
1564 assert!(file_path.exists(), "{}", file_path.display());
0a29b90c
FG
1565 }
1566 "#,
1567 )
1568 .file(
1569 "src/lib.rs",
1570 r#"
1571 use std::env;
1572 use std::path::PathBuf;
1573
1574 pub fn version() -> String {
1575 format!("{}-{}-{} @ {} in {}",
1576 env!("CARGO_PKG_VERSION_MAJOR"),
1577 env!("CARGO_PKG_VERSION_MINOR"),
1578 env!("CARGO_PKG_VERSION_PATCH"),
1579 env!("CARGO_PKG_VERSION_PRE"),
1580 env!("CARGO_MANIFEST_DIR"))
1581 }
1582
1583 pub fn check_no_int_test_env() {
1584 env::var("CARGO_TARGET_DIR").unwrap_err();
1585 }
1586
1587 pub fn check_tmpdir(tmp: Option<&'static str>) {
1588 let tmpdir: PathBuf = tmp.unwrap().into();
1589
1590 let exe: PathBuf = env::current_exe().unwrap().into();
1591 let mut expected: PathBuf = exe.parent().unwrap()
1592 .parent().unwrap()
1593 .parent().unwrap()
1594 .into();
1595 expected.push("tmp");
1596 assert_eq!(tmpdir, expected);
1597
1598 // Check that CARGO_TARGET_TMPDIR isn't set for lib code
1599 assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
1600 env::var("CARGO_TARGET_TMPDIR").unwrap_err();
4b012472
FG
1601
1602 // Verify CARGO_RUSTC_CURRENT_DIR is set for examples
1603 let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1604 let file_path = workspace_dir.join(file!());
1605 assert!(file_path.exists(), "{}", file_path.display());
0a29b90c
FG
1606 }
1607
1608 #[test]
4b012472 1609 fn unit_env_cargo_target_tmpdir() {
0a29b90c
FG
1610 // Check that CARGO_TARGET_TMPDIR isn't set for unit tests
1611 assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
1612 env::var("CARGO_TARGET_TMPDIR").unwrap_err();
1613 }
4b012472
FG
1614
1615 #[test]
1616 fn unit_env_cargo_rustc_current_dir() {
1617 let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1618 let file_path = workspace_dir.join(file!());
1619 assert!(file_path.exists(), "{}", file_path.display());
1620 }
0a29b90c
FG
1621 "#,
1622 )
1623 .file(
1624 "examples/ex-env-vars.rs",
1625 r#"
1626 static PKG_NAME: &'static str = env!("CARGO_PKG_NAME");
1627 static BIN_NAME: &'static str = env!("CARGO_BIN_NAME");
1628 static CRATE_NAME: &'static str = env!("CARGO_CRATE_NAME");
1629
1630 fn main() {
1631 assert_eq!("foo", PKG_NAME);
1632 assert_eq!("ex-env-vars", BIN_NAME);
1633 assert_eq!("ex_env_vars", CRATE_NAME);
1634
1635 // Verify CARGO_TARGET_TMPDIR isn't set for examples
1636 assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
4b012472
FG
1637
1638 // Verify CARGO_RUSTC_CURRENT_DIR is set for examples
1639 let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1640 let file_path = workspace_dir.join(file!());
1641 assert!(file_path.exists(), "{}", file_path.display());
0a29b90c
FG
1642 }
1643 "#,
1644 )
1645 .file(
1646 "tests/env.rs",
1647 r#"
1648 #[test]
4b012472 1649 fn integration_env_cargo_target_tmpdir() {
0a29b90c
FG
1650 foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
1651 }
4b012472
FG
1652
1653 #[test]
1654 fn integration_env_cargo_rustc_current_dir() {
1655 let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1656 let file_path = workspace_dir.join(file!());
1657 assert!(file_path.exists(), "{}", file_path.display());
1658 }
0a29b90c
FG
1659 "#,
1660 );
1661
1662 let p = if is_nightly() {
1663 p.file(
1664 "benches/env.rs",
1665 r#"
1666 #![feature(test)]
1667 extern crate test;
1668 use test::Bencher;
1669
1670 #[bench]
4b012472 1671 fn bench_env_cargo_target_tmpdir(_: &mut Bencher) {
0a29b90c
FG
1672 foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
1673 }
4b012472
FG
1674
1675 #[test]
1676 fn bench_env_cargo_rustc_current_dir() {
1677 let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1678 let file_path = workspace_dir.join(file!());
1679 assert!(file_path.exists(), "{}", file_path.display());
1680 }
0a29b90c
FG
1681 "#,
1682 )
1683 .build()
1684 } else {
1685 p.build()
1686 };
1687
1688 println!("build");
4b012472
FG
1689 p.cargo("build -v")
1690 .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
1691 .run();
0a29b90c
FG
1692
1693 println!("bin");
1694 p.process(&p.bin("foo-bar"))
1695 .with_stdout("0-5-1 @ alpha.1 in [CWD]")
1696 .run();
1697
1698 println!("example");
4b012472
FG
1699 p.cargo("run --example ex-env-vars -v")
1700 .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
1701 .run();
0a29b90c
FG
1702
1703 println!("test");
4b012472
FG
1704 p.cargo("test -v")
1705 .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
1706 .run();
0a29b90c
FG
1707
1708 if is_nightly() {
1709 println!("bench");
4b012472
FG
1710 p.cargo("bench -v")
1711 .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
1712 .run();
1713 }
1714}
1715
1716#[cargo_test]
1717fn cargo_rustc_current_dir_foreign_workspace_dep() {
1718 let foo = project()
1719 .file(
1720 "Cargo.toml",
1721 r#"
1722 [workspace]
1723
1724 [package]
1725 name = "foo"
1726 version = "0.0.1"
1727 authors = []
1728
1729 [dependencies]
1730 baz.path = "../baz"
1731 baz_member.path = "../baz/baz_member"
1732 "#,
1733 )
1734 .file("src/lib.rs", "")
1735 .build();
1736 let _baz = project()
1737 .at("baz")
1738 .file(
1739 "Cargo.toml",
1740 r#"
1741 [workspace]
1742 members = ["baz_member"]
1743
1744 [package]
1745 name = "baz"
1746 version = "0.1.0"
1747 "#,
1748 )
1749 .file("src/lib.rs", "")
1750 .file(
1751 "tests/env.rs",
1752 r#"
1753 use std::path::Path;
1754
1755 #[test]
1756 fn baz_env() {
1757 let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1758 let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
1759 let current_dir = std::env::current_dir().expect("current_dir");
1760 let file_path = workspace_dir.join(file!());
1761 assert!(file_path.exists(), "{}", file_path.display());
1762 let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR");
1763 let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
1764 assert_eq!(workspace_dir, manifest_dir);
1765 }
1766 "#,
1767 )
1768 .file(
1769 "baz_member/Cargo.toml",
1770 r#"
1771 [package]
1772 name = "baz_member"
1773 version = "0.1.0"
1774 authors = []
1775 "#,
1776 )
1777 .file("baz_member/src/lib.rs", "")
1778 .file(
1779 "baz_member/tests/env.rs",
1780 r#"
1781 use std::path::Path;
1782
1783 #[test]
1784 fn baz_member_env() {
1785 let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1786 let file_path = workspace_dir.join(file!());
1787 assert!(file_path.exists(), "{}", file_path.display());
1788 }
1789 "#,
1790 )
1791 .build();
1792
1793 // Verify it works from a different workspace
1794 foo.cargo("test -p baz")
1795 .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
1796 .with_stdout_contains("running 1 test\ntest baz_env ... ok")
1797 .run();
1798 foo.cargo("test -p baz_member")
1799 .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
1800 .with_stdout_contains("running 1 test\ntest baz_member_env ... ok")
1801 .run();
1802}
1803
1804#[cargo_test]
1805fn cargo_rustc_current_dir_non_local_dep() {
1806 Package::new("bar", "0.1.0")
1807 .file(
1808 "tests/bar_env.rs",
1809 r#"
1810 use std::path::Path;
1811
1812 #[test]
1813 fn bar_env() {
1814 let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR"));
1815 let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR"));
1816 let current_dir = std::env::current_dir().expect("current_dir");
1817 let file_path = workspace_dir.join(file!());
1818 assert!(file_path.exists(), "{}", file_path.display());
1819 let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR");
1820 let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR");
1821 assert_eq!(workspace_dir, manifest_dir);
1822 }
1823 "#,
1824 )
1825 .publish();
1826
1827 let p = project()
1828 .file("src/lib.rs", "")
1829 .file(
1830 "Cargo.toml",
1831 r#"
1832 [package]
1833 name = "foo"
1834 version = "0.0.1"
1835
1836 [dependencies]
1837 bar = "0.1.0"
1838 "#,
1839 )
1840 .build();
1841
1842 p.cargo("test -p bar")
1843 .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"])
1844 .with_stdout_contains("running 1 test\ntest bar_env ... ok")
1845 .run();
1846}
1847
1848#[cargo_test]
1849fn cargo_rustc_current_dir_is_not_stable() {
1850 if is_nightly() {
1851 return;
0a29b90c 1852 }
4b012472
FG
1853 let p = project()
1854 .file(
1855 "tests/env.rs",
1856 r#"
1857 use std::path::Path;
1858
1859 #[test]
1860 fn env() {
1861 assert_eq!(option_env!("CARGO_RUSTC_CURRENT_DIR"), None);
1862 }
1863 "#,
1864 )
1865 .build();
1866
1867 p.cargo("test").run();
0a29b90c
FG
1868}
1869
1870#[cargo_test]
1871fn crate_authors_env_vars() {
1872 let p = project()
1873 .file(
1874 "Cargo.toml",
1875 r#"
1876 [package]
1877 name = "foo"
1878 version = "0.5.1-alpha.1"
1879 authors = ["wycats@example.com", "neikos@example.com"]
1880 "#,
1881 )
1882 .file(
1883 "src/main.rs",
1884 r#"
1885 extern crate foo;
1886
1887 static AUTHORS: &'static str = env!("CARGO_PKG_AUTHORS");
1888
1889 fn main() {
1890 let s = "wycats@example.com:neikos@example.com";
1891 assert_eq!(AUTHORS, foo::authors());
1892 println!("{}", AUTHORS);
1893 assert_eq!(s, AUTHORS);
1894 }
1895 "#,
1896 )
1897 .file(
1898 "src/lib.rs",
1899 r#"
1900 pub fn authors() -> String {
1901 format!("{}", env!("CARGO_PKG_AUTHORS"))
1902 }
1903 "#,
1904 )
1905 .build();
1906
1907 println!("build");
1908 p.cargo("build -v").run();
1909
1910 println!("bin");
1911 p.process(&p.bin("foo"))
1912 .with_stdout("wycats@example.com:neikos@example.com")
1913 .run();
1914
1915 println!("test");
1916 p.cargo("test -v").run();
1917}
1918
1919#[cargo_test]
1920fn vv_prints_rustc_env_vars() {
1921 let p = project()
1922 .file(
1923 "Cargo.toml",
1924 r#"
1925 [package]
1926 name = "foo"
1927 version = "0.0.1"
1928 authors = ["escape='\"@example.com"]
1929 "#,
1930 )
1931 .file("src/main.rs", "fn main() {}")
1932 .build();
1933
1934 let mut b = p.cargo("build -vv");
1935
1936 if cfg!(windows) {
1937 b.with_stderr_contains(
1938 "[RUNNING] `[..]set CARGO_PKG_NAME=foo&& [..]rustc [..]`"
1939 ).with_stderr_contains(
1940 r#"[RUNNING] `[..]set CARGO_PKG_AUTHORS="escape='\"@example.com"&& [..]rustc [..]`"#
1941 )
1942 } else {
1943 b.with_stderr_contains("[RUNNING] `[..]CARGO_PKG_NAME=foo [..]rustc [..]`")
1944 .with_stderr_contains(
1945 r#"[RUNNING] `[..]CARGO_PKG_AUTHORS='escape='\''"@example.com' [..]rustc [..]`"#,
1946 )
1947 };
1948
1949 b.run();
1950}
1951
1952// The tester may already have LD_LIBRARY_PATH=::/foo/bar which leads to a false positive error
1953fn setenv_for_removing_empty_component(mut execs: Execs) -> Execs {
1954 let v = dylib_path_envvar();
1955 if let Ok(search_path) = env::var(v) {
1956 let new_search_path =
1957 env::join_paths(env::split_paths(&search_path).filter(|e| !e.as_os_str().is_empty()))
1958 .expect("join_paths");
1959 execs.env(v, new_search_path); // build_command() will override LD_LIBRARY_PATH accordingly
1960 }
1961 execs
1962}
1963
1964// Regression test for #4277
1965#[cargo_test]
1966fn crate_library_path_env_var() {
1967 let p = project()
1968 .file(
1969 "src/main.rs",
1970 &format!(
1971 r#"
1972 fn main() {{
1973 let search_path = env!("{}");
1974 let paths = std::env::split_paths(&search_path).collect::<Vec<_>>();
1975 assert!(!paths.contains(&"".into()));
1976 }}
1977 "#,
1978 dylib_path_envvar()
1979 ),
1980 )
1981 .build();
1982
1983 setenv_for_removing_empty_component(p.cargo("run")).run();
1984}
1985
1986// Regression test for #4277
1987#[cargo_test]
1988fn build_with_fake_libc_not_loading() {
1989 let p = project()
1990 .file("src/main.rs", "fn main() {}")
1991 .file("src/lib.rs", r#" "#)
1992 .file("libc.so.6", r#""#)
1993 .build();
1994
1995 setenv_for_removing_empty_component(p.cargo("build")).run();
1996}
1997
1998// this is testing that src/<pkg-name>.rs still works (for now)
1999#[cargo_test]
2000fn many_crate_types_old_style_lib_location() {
2001 let p = project()
2002 .file(
2003 "Cargo.toml",
2004 r#"
2005 [package]
2006
2007 name = "foo"
2008 version = "0.5.0"
2009 authors = ["wycats@example.com"]
2010
2011 [lib]
2012
2013 name = "foo"
2014 crate_type = ["rlib", "dylib"]
2015 "#,
2016 )
2017 .file("src/foo.rs", "pub fn foo() {}")
2018 .build();
2019 p.cargo("build")
2020 .with_stderr_contains(
2021 "\
2022[WARNING] path `[..]src/foo.rs` was erroneously implicitly accepted for library `foo`,
2023please rename the file to `src/lib.rs` or set lib.path in Cargo.toml",
2024 )
2025 .run();
2026
2027 assert!(p.root().join("target/debug/libfoo.rlib").is_file());
2028 let fname = format!("{}foo{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX);
2029 assert!(p.root().join("target/debug").join(&fname).is_file());
2030}
2031
2032#[cargo_test]
2033fn many_crate_types_correct() {
2034 let p = project()
2035 .file(
2036 "Cargo.toml",
2037 r#"
2038 [package]
2039
2040 name = "foo"
2041 version = "0.5.0"
2042 authors = ["wycats@example.com"]
2043
2044 [lib]
2045
2046 name = "foo"
2047 crate_type = ["rlib", "dylib"]
2048 "#,
2049 )
2050 .file("src/lib.rs", "pub fn foo() {}")
2051 .build();
2052 p.cargo("build").run();
2053
2054 assert!(p.root().join("target/debug/libfoo.rlib").is_file());
2055 let fname = format!("{}foo{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX);
2056 assert!(p.root().join("target/debug").join(&fname).is_file());
2057}
2058
2059#[cargo_test]
2060fn set_both_dylib_and_cdylib_crate_types() {
2061 let p = project()
2062 .file(
2063 "Cargo.toml",
2064 r#"
2065 [package]
2066
2067 name = "foo"
2068 version = "0.5.0"
2069 authors = ["wycats@example.com"]
2070
2071 [lib]
2072
2073 name = "foo"
2074 crate_type = ["cdylib", "dylib"]
2075 "#,
2076 )
2077 .file("src/lib.rs", "pub fn foo() {}")
2078 .build();
2079 p.cargo("build")
2080 .with_status(101)
2081 .with_stderr(
2082 "\
2083error: failed to parse manifest at `[..]`
2084
2085Caused by:
2086 library `foo` cannot set the crate type of both `dylib` and `cdylib`
2087",
2088 )
2089 .run();
2090}
2091
2092#[cargo_test]
2093fn dev_dependencies_conflicting_warning() {
2094 let p = project()
2095 .file(
2096 "Cargo.toml",
2097 r#"
2098 [package]
2099 name = "foo"
2100 version = "0.1.0"
2101 edition = "2018"
2102
2103 [dev-dependencies]
2104 a = {path = "a"}
2105 [dev_dependencies]
2106 a = {path = "a"}
2107 "#,
2108 )
2109 .file("src/lib.rs", "")
2110 .file(
2111 "a/Cargo.toml",
2112 r#"
2113 [package]
2114 name = "a"
2115 version = "0.0.1"
2116 "#,
2117 )
2118 .file("a/src/lib.rs", "")
2119 .build();
2120 p.cargo("build")
2121 .with_stderr_contains(
2122"[WARNING] conflicting between `dev-dependencies` and `dev_dependencies` in the `foo` package.\n
2123 `dev_dependencies` is ignored and not recommended for use in the future"
2124 )
2125 .run();
2126}
2127
2128#[cargo_test]
2129fn build_dependencies_conflicting_warning() {
2130 let p = project()
2131 .file(
2132 "Cargo.toml",
2133 r#"
2134 [package]
2135 name = "foo"
2136 version = "0.1.0"
2137 edition = "2018"
2138
2139 [build-dependencies]
2140 a = {path = "a"}
2141 [build_dependencies]
2142 a = {path = "a"}
2143 "#,
2144 )
2145 .file("src/lib.rs", "")
2146 .file(
2147 "a/Cargo.toml",
2148 r#"
2149 [package]
2150 name = "a"
2151 version = "0.0.1"
2152 "#,
2153 )
2154 .file("a/src/lib.rs", "")
2155 .build();
2156 p.cargo("build")
2157 .with_stderr_contains(
2158"[WARNING] conflicting between `build-dependencies` and `build_dependencies` in the `foo` package.\n
2159 `build_dependencies` is ignored and not recommended for use in the future"
2160 )
2161 .run();
2162}
2163
2164#[cargo_test]
2165fn lib_crate_types_conflicting_warning() {
2166 let p = project()
2167 .file(
2168 "Cargo.toml",
2169 r#"
2170 [package]
2171 name = "foo"
2172 version = "0.5.0"
2173 authors = ["wycats@example.com"]
2174
2175 [lib]
2176 name = "foo"
2177 crate-type = ["rlib", "dylib"]
2178 crate_type = ["staticlib", "dylib"]
2179 "#,
2180 )
2181 .file("src/lib.rs", "pub fn foo() {}")
2182 .build();
2183 p.cargo("build")
2184 .with_stderr_contains(
2185"[WARNING] conflicting between `crate-type` and `crate_type` in the `foo` library target.\n
2186 `crate_type` is ignored and not recommended for use in the future",
2187 )
2188 .run();
2189}
2190
2191#[cargo_test]
2192fn examples_crate_types_conflicting_warning() {
2193 let p = project()
2194 .file(
2195 "Cargo.toml",
2196 r#"
2197 [package]
2198 name = "foo"
2199 version = "0.5.0"
2200 authors = ["wycats@example.com"]
2201
2202 [[example]]
2203 name = "ex"
2204 path = "examples/ex.rs"
2205 crate-type = ["rlib", "dylib"]
2206 crate_type = ["proc_macro"]
2207 [[example]]
2208 name = "goodbye"
2209 path = "examples/ex-goodbye.rs"
2210 crate-type = ["rlib", "dylib"]
2211 crate_type = ["rlib", "staticlib"]
2212 "#,
2213 )
2214 .file("src/lib.rs", "")
2215 .file(
2216 "examples/ex.rs",
2217 r#"
2218 fn main() { println!("ex"); }
2219 "#,
2220 )
2221 .file(
2222 "examples/ex-goodbye.rs",
2223 r#"
2224 fn main() { println!("goodbye"); }
2225 "#,
2226 )
2227 .build();
2228 p.cargo("build")
2229 .with_stderr_contains(
2230 "\
2231[WARNING] conflicting between `crate-type` and `crate_type` in the `ex` example target.\n
2232 `crate_type` is ignored and not recommended for use in the future
2233[WARNING] conflicting between `crate-type` and `crate_type` in the `goodbye` example target.\n
2234 `crate_type` is ignored and not recommended for use in the future",
2235 )
2236 .run();
2237}
2238
2239#[cargo_test]
2240fn self_dependency() {
2241 let p = project()
2242 .file(
2243 "Cargo.toml",
2244 r#"
2245 [package]
2246
2247 name = "test"
2248 version = "0.0.0"
2249 authors = []
2250
2251 [dependencies.test]
2252
2253 path = "."
2254
2255 [lib]
2256 name = "test"
2257 path = "src/test.rs"
2258 "#,
2259 )
2260 .file("src/test.rs", "fn main() {}")
2261 .build();
2262 p.cargo("build")
2263 .with_status(101)
2264 .with_stderr(
2265 "\
2266[ERROR] cyclic package dependency: package `test v0.0.0 ([CWD])` depends on itself. Cycle:
2267package `test v0.0.0 ([CWD])`
2268 ... which satisfies path dependency `test` of package `test v0.0.0 ([..])`",
2269 )
2270 .run();
2271}
2272
2273#[cargo_test]
2274/// Make sure broken and loop symlinks don't break the build
2275///
2276/// This test requires you to be able to make symlinks.
2277/// For windows, this may require you to enable developer mode.
2278fn ignore_broken_symlinks() {
2279 if !symlink_supported() {
2280 return;
2281 }
2282
2283 let p = project()
2284 .file("Cargo.toml", &basic_bin_manifest("foo"))
2285 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
2286 .symlink("Notafile", "bar")
2287 // To hit the symlink directory, we need a build script
2288 // to trigger a full scan of package files.
2289 .file("build.rs", &main_file(r#""build script""#, &[]))
2290 .symlink_dir("a/b", "a/b/c/d/foo")
2291 .build();
2292
2293 p.cargo("build")
2294 .with_stderr_contains(
2295 "[WARNING] File system loop found: [..]/a/b/c/d/foo points to an ancestor [..]/a/b",
2296 )
2297 .run();
2298 assert!(p.bin("foo").is_file());
2299
2300 p.process(&p.bin("foo")).with_stdout("i am foo\n").run();
2301}
2302
2303#[cargo_test]
2304fn missing_lib_and_bin() {
2305 let p = project().build();
2306 p.cargo("build")
2307 .with_status(101)
2308 .with_stderr(
2309 "\
2310[ERROR] failed to parse manifest at `[..]Cargo.toml`
2311
2312Caused by:
2313 no targets specified in the manifest
2314 either src/lib.rs, src/main.rs, a [lib] section, or [[bin]] section must be present\n",
2315 )
2316 .run();
2317}
2318
2319#[cargo_test]
2320fn lto_build() {
2321 let p = project()
2322 .file(
2323 "Cargo.toml",
2324 r#"
2325 [package]
2326
2327 name = "test"
2328 version = "0.0.0"
2329 authors = []
2330
2331 [profile.release]
2332 lto = true
2333 "#,
2334 )
2335 .file("src/main.rs", "fn main() {}")
2336 .build();
2337 p.cargo("build -v --release")
2338 .with_stderr(
2339 "\
2340[COMPILING] test v0.0.0 ([CWD])
2341[RUNNING] `rustc --crate-name test src/main.rs [..]--crate-type bin \
2342 --emit=[..]link \
2343 -C opt-level=3 \
2344 -C lto \
2345 [..]
2346[FINISHED] release [optimized] target(s) in [..]
2347",
2348 )
2349 .run();
2350}
2351
2352#[cargo_test]
2353fn verbose_build() {
2354 let p = project().file("src/lib.rs", "").build();
2355 p.cargo("build -v")
2356 .with_stderr(
2357 "\
2358[COMPILING] foo v0.0.1 ([CWD])
2359[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
fe692bf9 2360 --emit=[..]link[..]-C debuginfo=2 [..]\
0a29b90c
FG
2361 -C metadata=[..] \
2362 --out-dir [..] \
2363 -L dependency=[CWD]/target/debug/deps`
2364[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
2365",
2366 )
2367 .run();
2368}
2369
2370#[cargo_test]
2371fn verbose_release_build() {
2372 let p = project().file("src/lib.rs", "").build();
2373 p.cargo("build -v --release")
2374 .with_stderr(
2375 "\
2376[COMPILING] foo v0.0.1 ([CWD])
2377[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
2378 --emit=[..]link[..]\
2379 -C opt-level=3[..]\
2380 -C metadata=[..] \
2381 --out-dir [..] \
2382 -L dependency=[CWD]/target/release/deps`
2383[FINISHED] release [optimized] target(s) in [..]
2384",
2385 )
2386 .run();
2387}
2388
2389#[cargo_test]
2390fn verbose_release_build_short() {
2391 let p = project().file("src/lib.rs", "").build();
2392 p.cargo("build -v -r")
2393 .with_stderr(
2394 "\
2395[COMPILING] foo v0.0.1 ([CWD])
2396[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
2397 --emit=[..]link[..]\
2398 -C opt-level=3[..]\
2399 -C metadata=[..] \
2400 --out-dir [..] \
2401 -L dependency=[CWD]/target/release/deps`
2402[FINISHED] release [optimized] target(s) in [..]
2403",
2404 )
2405 .run();
2406}
2407
2408#[cargo_test]
2409fn verbose_release_build_deps() {
2410 let p = project()
2411 .file(
2412 "Cargo.toml",
2413 r#"
2414 [package]
2415
2416 name = "test"
2417 version = "0.0.0"
2418 authors = []
2419
2420 [dependencies.foo]
2421 path = "foo"
2422 "#,
2423 )
2424 .file("src/lib.rs", "")
2425 .file(
2426 "foo/Cargo.toml",
2427 r#"
2428 [package]
2429
2430 name = "foo"
2431 version = "0.0.0"
2432 authors = []
2433
2434 [lib]
2435 name = "foo"
2436 crate_type = ["dylib", "rlib"]
2437 "#,
2438 )
2439 .file("foo/src/lib.rs", "")
2440 .build();
2441 p.cargo("build -v --release")
2442 .with_stderr(&format!(
2443 "\
2444[COMPILING] foo v0.0.0 ([CWD]/foo)
2445[RUNNING] `rustc --crate-name foo foo/src/lib.rs [..]\
2446 --crate-type dylib --crate-type rlib \
2447 --emit=[..]link \
2448 -C prefer-dynamic[..]\
2449 -C opt-level=3[..]\
2450 -C metadata=[..] \
2451 --out-dir [..] \
2452 -L dependency=[CWD]/target/release/deps`
2453[COMPILING] test v0.0.0 ([CWD])
2454[RUNNING] `rustc --crate-name test src/lib.rs [..]--crate-type lib \
2455 --emit=[..]link[..]\
2456 -C opt-level=3[..]\
2457 -C metadata=[..] \
2458 --out-dir [..] \
2459 -L dependency=[CWD]/target/release/deps \
2460 --extern foo=[CWD]/target/release/deps/{prefix}foo{suffix} \
2461 --extern foo=[CWD]/target/release/deps/libfoo.rlib`
2462[FINISHED] release [optimized] target(s) in [..]
2463",
2464 prefix = env::consts::DLL_PREFIX,
2465 suffix = env::consts::DLL_SUFFIX
2466 ))
2467 .run();
2468}
2469
2470#[cargo_test]
2471fn explicit_examples() {
2472 let p = project()
2473 .file(
2474 "Cargo.toml",
2475 r#"
2476 [package]
2477 name = "foo"
2478 version = "1.0.0"
2479 authors = []
2480
2481 [lib]
2482 name = "foo"
2483 path = "src/lib.rs"
2484
2485 [[example]]
2486 name = "hello"
2487 path = "examples/ex-hello.rs"
2488
2489 [[example]]
2490 name = "goodbye"
2491 path = "examples/ex-goodbye.rs"
2492 "#,
2493 )
2494 .file(
2495 "src/lib.rs",
2496 r#"
2497 pub fn get_hello() -> &'static str { "Hello" }
2498 pub fn get_goodbye() -> &'static str { "Goodbye" }
2499 pub fn get_world() -> &'static str { "World" }
2500 "#,
2501 )
2502 .file(
2503 "examples/ex-hello.rs",
2504 r#"
2505 extern crate foo;
2506 fn main() { println!("{}, {}!", foo::get_hello(), foo::get_world()); }
2507 "#,
2508 )
2509 .file(
2510 "examples/ex-goodbye.rs",
2511 r#"
2512 extern crate foo;
2513 fn main() { println!("{}, {}!", foo::get_goodbye(), foo::get_world()); }
2514 "#,
2515 )
2516 .build();
2517
2518 p.cargo("build --examples").run();
2519 p.process(&p.bin("examples/hello"))
2520 .with_stdout("Hello, World!\n")
2521 .run();
2522 p.process(&p.bin("examples/goodbye"))
2523 .with_stdout("Goodbye, World!\n")
2524 .run();
2525}
2526
2527#[cargo_test]
2528fn non_existing_test() {
2529 let p = project()
2530 .file(
2531 "Cargo.toml",
2532 r#"
2533 [package]
2534 name = "foo"
2535 version = "1.0.0"
2536
2537 [lib]
2538 name = "foo"
2539 path = "src/lib.rs"
2540
2541 [[test]]
2542 name = "hello"
2543 "#,
2544 )
2545 .file("src/lib.rs", "")
2546 .build();
2547
2548 p.cargo("build --tests -v")
2549 .with_status(101)
2550 .with_stderr(
2551 "\
2552[ERROR] failed to parse manifest at `[..]`
2553
2554Caused by:
2555 can't find `hello` test at `tests/hello.rs` or `tests/hello/main.rs`. \
2556 Please specify test.path if you want to use a non-default path.",
2557 )
2558 .run();
2559}
2560
2561#[cargo_test]
2562fn non_existing_example() {
2563 let p = project()
2564 .file(
2565 "Cargo.toml",
2566 r#"
2567 [package]
2568 name = "foo"
2569 version = "1.0.0"
2570
2571 [lib]
2572 name = "foo"
2573 path = "src/lib.rs"
2574
2575 [[example]]
2576 name = "hello"
2577 "#,
2578 )
2579 .file("src/lib.rs", "")
2580 .build();
2581
2582 p.cargo("build --examples -v")
2583 .with_status(101)
2584 .with_stderr(
2585 "\
2586[ERROR] failed to parse manifest at `[..]`
2587
2588Caused by:
2589 can't find `hello` example at `examples/hello.rs` or `examples/hello/main.rs`. \
2590 Please specify example.path if you want to use a non-default path.",
2591 )
2592 .run();
2593}
2594
2595#[cargo_test]
2596fn non_existing_benchmark() {
2597 let p = project()
2598 .file(
2599 "Cargo.toml",
2600 r#"
2601 [package]
2602 name = "foo"
2603 version = "1.0.0"
2604
2605 [lib]
2606 name = "foo"
2607 path = "src/lib.rs"
2608
2609 [[bench]]
2610 name = "hello"
2611 "#,
2612 )
2613 .file("src/lib.rs", "")
2614 .build();
2615
2616 p.cargo("build --benches -v")
2617 .with_status(101)
2618 .with_stderr(
2619 "\
2620[ERROR] failed to parse manifest at `[..]`
2621
2622Caused by:
2623 can't find `hello` bench at `benches/hello.rs` or `benches/hello/main.rs`. \
2624 Please specify bench.path if you want to use a non-default path.",
2625 )
2626 .run();
2627}
2628
2629#[cargo_test]
2630fn non_existing_binary() {
2631 let p = project()
2632 .file("Cargo.toml", &basic_bin_manifest("foo"))
2633 .file("src/lib.rs", "")
2634 .file("src/bin/ehlo.rs", "")
2635 .build();
2636
2637 p.cargo("build -v")
2638 .with_status(101)
2639 .with_stderr(
2640 "\
2641[ERROR] failed to parse manifest at `[..]`
2642
2643Caused by:
2644 can't find `foo` bin at `src/bin/foo.rs` or `src/bin/foo/main.rs`. \
2645 Please specify bin.path if you want to use a non-default path.",
2646 )
2647 .run();
2648}
2649
2650#[cargo_test]
2651fn commonly_wrong_path_of_test() {
2652 let p = project()
2653 .file(
2654 "Cargo.toml",
2655 r#"
2656 [package]
2657 name = "foo"
2658 version = "1.0.0"
2659
2660 [lib]
2661 name = "foo"
2662 path = "src/lib.rs"
2663
2664 [[test]]
2665 name = "foo"
2666 "#,
2667 )
2668 .file("src/lib.rs", "")
2669 .file("test/foo.rs", "")
2670 .build();
2671
2672 p.cargo("build --tests -v")
2673 .with_status(101)
2674 .with_stderr(
2675 "\
2676[ERROR] failed to parse manifest at `[..]`
2677
2678Caused by:
2679 can't find `foo` test at default paths, but found a file at `test/foo.rs`.
2680 Perhaps rename the file to `tests/foo.rs` for target auto-discovery, \
2681 or specify test.path if you want to use a non-default path.",
2682 )
2683 .run();
2684}
2685
2686#[cargo_test]
2687fn commonly_wrong_path_of_example() {
2688 let p = project()
2689 .file(
2690 "Cargo.toml",
2691 r#"
2692 [package]
2693 name = "foo"
2694 version = "1.0.0"
2695
2696 [lib]
2697 name = "foo"
2698 path = "src/lib.rs"
2699
2700 [[example]]
2701 name = "foo"
2702 "#,
2703 )
2704 .file("src/lib.rs", "")
2705 .file("example/foo.rs", "")
2706 .build();
2707
2708 p.cargo("build --examples -v")
2709 .with_status(101)
2710 .with_stderr(
2711 "\
2712[ERROR] failed to parse manifest at `[..]`
2713
2714Caused by:
2715 can't find `foo` example at default paths, but found a file at `example/foo.rs`.
2716 Perhaps rename the file to `examples/foo.rs` for target auto-discovery, \
2717 or specify example.path if you want to use a non-default path.",
2718 )
2719 .run();
2720}
2721
2722#[cargo_test]
2723fn commonly_wrong_path_of_benchmark() {
2724 let p = project()
2725 .file(
2726 "Cargo.toml",
2727 r#"
2728 [package]
2729 name = "foo"
2730 version = "1.0.0"
2731
2732 [lib]
2733 name = "foo"
2734 path = "src/lib.rs"
2735
2736 [[bench]]
2737 name = "foo"
2738 "#,
2739 )
2740 .file("src/lib.rs", "")
2741 .file("bench/foo.rs", "")
2742 .build();
2743
2744 p.cargo("build --benches -v")
2745 .with_status(101)
2746 .with_stderr(
2747 "\
2748[ERROR] failed to parse manifest at `[..]`
2749
2750Caused by:
2751 can't find `foo` bench at default paths, but found a file at `bench/foo.rs`.
2752 Perhaps rename the file to `benches/foo.rs` for target auto-discovery, \
2753 or specify bench.path if you want to use a non-default path.",
2754 )
2755 .run();
2756}
2757
2758#[cargo_test]
2759fn commonly_wrong_path_binary() {
2760 let p = project()
2761 .file("Cargo.toml", &basic_bin_manifest("foo"))
2762 .file("src/lib.rs", "")
2763 .file("src/bins/foo.rs", "")
2764 .build();
2765
2766 p.cargo("build -v")
2767 .with_status(101)
2768 .with_stderr(
2769 "\
2770[ERROR] failed to parse manifest at `[..]`
2771
2772Caused by:
2773 can't find `foo` bin at default paths, but found a file at `src/bins/foo.rs`.
2774 Perhaps rename the file to `src/bin/foo.rs` for target auto-discovery, \
2775 or specify bin.path if you want to use a non-default path.",
2776 )
2777 .run();
2778}
2779
2780#[cargo_test]
2781fn commonly_wrong_path_subdir_binary() {
2782 let p = project()
2783 .file("Cargo.toml", &basic_bin_manifest("foo"))
2784 .file("src/lib.rs", "")
2785 .file("src/bins/foo/main.rs", "")
2786 .build();
2787
2788 p.cargo("build -v")
2789 .with_status(101)
2790 .with_stderr(
2791 "\
2792[ERROR] failed to parse manifest at `[..]`
2793
2794Caused by:
2795 can't find `foo` bin at default paths, but found a file at `src/bins/foo/main.rs`.
2796 Perhaps rename the file to `src/bin/foo/main.rs` for target auto-discovery, \
2797 or specify bin.path if you want to use a non-default path.",
2798 )
2799 .run();
2800}
2801
2802#[cargo_test]
2803fn found_multiple_target_files() {
2804 let p = project()
2805 .file("Cargo.toml", &basic_bin_manifest("foo"))
2806 .file("src/lib.rs", "")
2807 .file("src/bin/foo.rs", "")
2808 .file("src/bin/foo/main.rs", "")
2809 .build();
2810
2811 p.cargo("build -v")
2812 .with_status(101)
2813 // Don't assert the inferred paths since the order is non-deterministic.
2814 .with_stderr(
2815 "\
2816[ERROR] failed to parse manifest at `[..]`
2817
2818Caused by:
2819 cannot infer path for `foo` bin
2820 Cargo doesn't know which to use because multiple target files found \
2821 at `src/bin/foo[..].rs` and `src/bin/foo[..].rs`.",
2822 )
2823 .run();
2824}
2825
2826#[cargo_test]
2827fn legacy_binary_paths_warnings() {
2828 let p = project()
2829 .file(
2830 "Cargo.toml",
2831 r#"
2832 [package]
2833 name = "foo"
2834 version = "1.0.0"
2835 authors = []
2836
2837 [[bin]]
2838 name = "bar"
2839 "#,
2840 )
2841 .file("src/lib.rs", "")
2842 .file("src/main.rs", "fn main() {}")
2843 .build();
2844
2845 p.cargo("build -v")
2846 .with_stderr_contains(
2847 "\
2848[WARNING] path `[..]src/main.rs` was erroneously implicitly accepted for binary `bar`,
2849please set bin.path in Cargo.toml",
2850 )
2851 .run();
2852
2853 let p = project()
2854 .file(
2855 "Cargo.toml",
2856 r#"
2857 [package]
2858 name = "foo"
2859 version = "1.0.0"
2860 authors = []
2861
2862 [[bin]]
2863 name = "bar"
2864 "#,
2865 )
2866 .file("src/lib.rs", "")
2867 .file("src/bin/main.rs", "fn main() {}")
2868 .build();
2869
2870 p.cargo("build -v")
2871 .with_stderr_contains(
2872 "\
2873[WARNING] path `[..]src/bin/main.rs` was erroneously implicitly accepted for binary `bar`,
2874please set bin.path in Cargo.toml",
2875 )
2876 .run();
2877
2878 let p = project()
2879 .file(
2880 "Cargo.toml",
2881 r#"
2882 [package]
2883 name = "foo"
2884 version = "1.0.0"
2885 authors = []
2886
2887 [[bin]]
2888 name = "bar"
2889 "#,
2890 )
2891 .file("src/bar.rs", "fn main() {}")
2892 .build();
2893
2894 p.cargo("build -v")
2895 .with_stderr_contains(
2896 "\
2897[WARNING] path `[..]src/bar.rs` was erroneously implicitly accepted for binary `bar`,
2898please set bin.path in Cargo.toml",
2899 )
2900 .run();
2901}
2902
2903#[cargo_test]
2904fn implicit_examples() {
2905 let p = project()
2906 .file(
2907 "src/lib.rs",
2908 r#"
2909 pub fn get_hello() -> &'static str { "Hello" }
2910 pub fn get_goodbye() -> &'static str { "Goodbye" }
2911 pub fn get_world() -> &'static str { "World" }
2912 "#,
2913 )
2914 .file(
2915 "examples/hello.rs",
2916 r#"
2917 extern crate foo;
2918 fn main() {
2919 println!("{}, {}!", foo::get_hello(), foo::get_world());
2920 }
2921 "#,
2922 )
2923 .file(
2924 "examples/goodbye.rs",
2925 r#"
2926 extern crate foo;
2927 fn main() {
2928 println!("{}, {}!", foo::get_goodbye(), foo::get_world());
2929 }
2930 "#,
2931 )
2932 .build();
2933
2934 p.cargo("build --examples").run();
2935 p.process(&p.bin("examples/hello"))
2936 .with_stdout("Hello, World!\n")
2937 .run();
2938 p.process(&p.bin("examples/goodbye"))
2939 .with_stdout("Goodbye, World!\n")
2940 .run();
2941}
2942
2943#[cargo_test]
2944fn standard_build_no_ndebug() {
2945 let p = project()
2946 .file("Cargo.toml", &basic_bin_manifest("foo"))
2947 .file(
2948 "src/foo.rs",
2949 r#"
2950 fn main() {
2951 if cfg!(debug_assertions) {
2952 println!("slow")
2953 } else {
2954 println!("fast")
2955 }
2956 }
2957 "#,
2958 )
2959 .build();
2960
2961 p.cargo("build").run();
2962 p.process(&p.bin("foo")).with_stdout("slow\n").run();
2963}
2964
2965#[cargo_test]
2966fn release_build_ndebug() {
2967 let p = project()
2968 .file("Cargo.toml", &basic_bin_manifest("foo"))
2969 .file(
2970 "src/foo.rs",
2971 r#"
2972 fn main() {
2973 if cfg!(debug_assertions) {
2974 println!("slow")
2975 } else {
2976 println!("fast")
2977 }
2978 }
2979 "#,
2980 )
2981 .build();
2982
2983 p.cargo("build --release").run();
2984 p.process(&p.release_bin("foo")).with_stdout("fast\n").run();
2985}
2986
2987#[cargo_test]
2988fn inferred_main_bin() {
2989 let p = project().file("src/main.rs", "fn main() {}").build();
2990
2991 p.cargo("build").run();
2992 p.process(&p.bin("foo")).run();
2993}
2994
2995#[cargo_test]
2996fn deletion_causes_failure() {
2997 let p = project()
2998 .file(
2999 "Cargo.toml",
3000 r#"
3001 [package]
3002 name = "foo"
3003 version = "0.0.1"
3004 authors = []
3005
3006 [dependencies.bar]
3007 path = "bar"
3008 "#,
3009 )
3010 .file("src/main.rs", "extern crate bar; fn main() {}")
3011 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.1"))
3012 .file("bar/src/lib.rs", "")
3013 .build();
3014
3015 p.cargo("build").run();
3016 p.change_file("Cargo.toml", &basic_manifest("foo", "0.0.1"));
3017 p.cargo("build")
3018 .with_status(101)
3019 .with_stderr_contains("[..]can't find crate for `bar`")
3020 .run();
3021}
3022
3023#[cargo_test]
3024fn bad_cargo_toml_in_target_dir() {
3025 let p = project()
3026 .file("src/main.rs", "fn main() {}")
3027 .file("target/Cargo.toml", "bad-toml")
3028 .build();
3029
3030 p.cargo("build").run();
3031 p.process(&p.bin("foo")).run();
3032}
3033
3034#[cargo_test]
3035fn lib_with_standard_name() {
3036 let p = project()
3037 .file("Cargo.toml", &basic_manifest("syntax", "0.0.1"))
3038 .file("src/lib.rs", "pub fn foo() {}")
3039 .file(
3040 "src/main.rs",
3041 "extern crate syntax; fn main() { syntax::foo() }",
3042 )
3043 .build();
3044
3045 p.cargo("build")
3046 .with_stderr(
3047 "\
3048[COMPILING] syntax v0.0.1 ([CWD])
3049[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
3050",
3051 )
3052 .run();
3053}
3054
3055#[cargo_test]
3056fn simple_staticlib() {
3057 let p = project()
3058 .file(
3059 "Cargo.toml",
3060 r#"
3061 [package]
3062 name = "foo"
3063 authors = []
3064 version = "0.0.1"
3065
3066 [lib]
3067 name = "foo"
3068 crate-type = ["staticlib"]
3069 "#,
3070 )
3071 .file("src/lib.rs", "pub fn foo() {}")
3072 .build();
3073
3074 // env var is a test for #1381
3075 p.cargo("build").env("CARGO_LOG", "nekoneko=trace").run();
3076}
3077
3078#[cargo_test]
3079fn staticlib_rlib_and_bin() {
3080 let p = project()
3081 .file(
3082 "Cargo.toml",
3083 r#"
3084 [package]
3085 name = "foo"
3086 authors = []
3087 version = "0.0.1"
3088
3089 [lib]
3090 name = "foo"
3091 crate-type = ["staticlib", "rlib"]
3092 "#,
3093 )
3094 .file("src/lib.rs", "pub fn foo() {}")
3095 .file("src/main.rs", "extern crate foo; fn main() { foo::foo(); }")
3096 .build();
3097
3098 p.cargo("build -v").run();
3099}
3100
3101#[cargo_test]
3102fn opt_out_of_bin() {
3103 let p = project()
3104 .file(
3105 "Cargo.toml",
3106 r#"
3107 bin = []
3108
3109 [package]
3110 name = "foo"
3111 authors = []
3112 version = "0.0.1"
3113 "#,
3114 )
3115 .file("src/lib.rs", "")
3116 .file("src/main.rs", "bad syntax")
3117 .build();
3118 p.cargo("build").run();
3119}
3120
3121#[cargo_test]
3122fn single_lib() {
3123 let p = project()
3124 .file(
3125 "Cargo.toml",
3126 r#"
3127 [package]
3128 name = "foo"
3129 authors = []
3130 version = "0.0.1"
3131
3132 [lib]
3133 name = "foo"
3134 path = "src/bar.rs"
3135 "#,
3136 )
3137 .file("src/bar.rs", "")
3138 .build();
3139 p.cargo("build").run();
3140}
3141
3142#[cargo_test]
3143fn freshness_ignores_excluded() {
3144 let foo = project()
3145 .file(
3146 "Cargo.toml",
3147 r#"
3148 [package]
3149 name = "foo"
3150 version = "0.0.0"
3151 authors = []
3152 build = "build.rs"
3153 exclude = ["src/b*.rs"]
3154 "#,
3155 )
3156 .file("build.rs", "fn main() {}")
3157 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
3158 .build();
3159 foo.root().move_into_the_past();
3160
3161 foo.cargo("build")
3162 .with_stderr(
3163 "\
3164[COMPILING] foo v0.0.0 ([CWD])
3165[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
3166",
3167 )
3168 .run();
3169
3170 // Smoke test to make sure it doesn't compile again
3171 println!("first pass");
4b012472 3172 foo.cargo("build").with_stderr("[FINISHED] [..]").run();
0a29b90c
FG
3173
3174 // Modify an ignored file and make sure we don't rebuild
3175 println!("second pass");
3176 foo.change_file("src/bar.rs", "");
4b012472 3177 foo.cargo("build").with_stderr("[FINISHED] [..]").run();
0a29b90c
FG
3178}
3179
3180#[cargo_test]
3181fn rebuild_preserves_out_dir() {
3182 let foo = project()
3183 .file(
3184 "Cargo.toml",
3185 r#"
3186 [package]
3187 name = "foo"
3188 version = "0.0.0"
3189 authors = []
3190 build = 'build.rs'
3191 "#,
3192 )
3193 .file(
3194 "build.rs",
3195 r#"
3196 use std::env;
3197 use std::fs::File;
3198 use std::path::Path;
3199
3200 fn main() {
3201 let path = Path::new(&env::var("OUT_DIR").unwrap()).join("foo");
3202 if env::var_os("FIRST").is_some() {
3203 File::create(&path).unwrap();
3204 } else {
3205 File::create(&path).unwrap();
3206 }
3207 }
3208 "#,
3209 )
3210 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
3211 .build();
3212 foo.root().move_into_the_past();
3213
3214 foo.cargo("build")
3215 .env("FIRST", "1")
3216 .with_stderr(
3217 "\
3218[COMPILING] foo v0.0.0 ([CWD])
3219[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
3220",
3221 )
3222 .run();
3223
3224 foo.change_file("src/bar.rs", "");
3225 foo.cargo("build")
3226 .with_stderr(
3227 "\
3228[COMPILING] foo v0.0.0 ([CWD])
3229[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
3230",
3231 )
3232 .run();
3233}
3234
3235#[cargo_test]
3236fn dep_no_libs() {
3237 let foo = project()
3238 .file(
3239 "Cargo.toml",
3240 r#"
3241 [package]
3242 name = "foo"
3243 version = "0.0.0"
3244 authors = []
3245
3246 [dependencies.bar]
3247 path = "bar"
3248 "#,
3249 )
3250 .file("src/lib.rs", "pub fn bar() -> i32 { 1 }")
3251 .file("bar/Cargo.toml", &basic_manifest("bar", "0.0.0"))
3252 .file("bar/src/main.rs", "")
3253 .build();
3254 foo.cargo("build").run();
3255}
3256
3257#[cargo_test]
3258fn recompile_space_in_name() {
3259 let foo = project()
3260 .file(
3261 "Cargo.toml",
3262 r#"
3263 [package]
3264 name = "foo"
3265 version = "0.0.0"
3266 authors = []
3267
3268 [lib]
3269 name = "foo"
3270 path = "src/my lib.rs"
3271 "#,
3272 )
3273 .file("src/my lib.rs", "")
3274 .build();
3275 foo.cargo("build").run();
3276 foo.root().move_into_the_past();
4b012472 3277 foo.cargo("build").with_stderr("[FINISHED] [..]").run();
0a29b90c
FG
3278}
3279
3280#[cfg(unix)]
3281#[cargo_test]
3282fn credentials_is_unreadable() {
3283 use cargo_test_support::paths::home;
3284 use std::os::unix::prelude::*;
3285 let p = project()
3286 .file("Cargo.toml", &basic_manifest("foo", "0.1.0"))
3287 .file("src/lib.rs", "")
3288 .build();
3289
3290 let credentials = home().join(".cargo/credentials.toml");
3291 t!(fs::create_dir_all(credentials.parent().unwrap()));
3292 t!(fs::write(
3293 &credentials,
3294 r#"
3295 [registry]
3296 token = "api-token"
3297 "#
3298 ));
3299 let stat = fs::metadata(credentials.as_path()).unwrap();
3300 let mut perms = stat.permissions();
3301 perms.set_mode(0o000);
3302 fs::set_permissions(credentials, perms).unwrap();
3303
3304 p.cargo("build").run();
3305}
3306
3307#[cfg(unix)]
3308#[cargo_test]
3309fn ignore_bad_directories() {
3310 use std::os::unix::prelude::*;
3311 let foo = project()
3312 .file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
3313 .file("src/lib.rs", "")
3314 .build();
3315 let dir = foo.root().join("tmp");
3316 fs::create_dir(&dir).unwrap();
3317 let stat = fs::metadata(&dir).unwrap();
3318 let mut perms = stat.permissions();
3319 perms.set_mode(0o644);
3320 fs::set_permissions(&dir, perms.clone()).unwrap();
3321 foo.cargo("build").run();
3322 perms.set_mode(0o755);
3323 fs::set_permissions(&dir, perms).unwrap();
3324}
3325
3326#[cargo_test]
3327fn bad_cargo_config() {
3328 let foo = project()
3329 .file("Cargo.toml", &basic_manifest("foo", "0.0.0"))
3330 .file("src/lib.rs", "")
3331 .file(".cargo/config", "this is not valid toml")
3332 .build();
3333 foo.cargo("build -v")
3334 .with_status(101)
3335 .with_stderr(
3336 "\
3337[ERROR] could not load Cargo configuration
3338
3339Caused by:
3340 could not parse TOML configuration in `[..]`
3341
0a29b90c
FG
3342Caused by:
3343 TOML parse error at line 1, column 6
3344 |
3345 1 | this is not valid toml
3346 | ^
3347 expected `.`, `=`
3348",
3349 )
3350 .run();
3351}
3352
3353#[cargo_test]
3354fn cargo_platform_specific_dependency() {
3355 let host = rustc_host();
3356 let p = project()
3357 .file(
3358 "Cargo.toml",
3359 &format!(
3360 r#"
3361 [package]
3362 name = "foo"
3363 version = "0.5.0"
3364 authors = ["wycats@example.com"]
3365 build = "build.rs"
3366
3367 [target.{host}.dependencies]
3368 dep = {{ path = "dep" }}
3369 [target.{host}.build-dependencies]
3370 build = {{ path = "build" }}
3371 [target.{host}.dev-dependencies]
3372 dev = {{ path = "dev" }}
3373 "#,
3374 host = host
3375 ),
3376 )
3377 .file("src/main.rs", "extern crate dep; fn main() { dep::dep() }")
3378 .file(
3379 "tests/foo.rs",
3380 "extern crate dev; #[test] fn foo() { dev::dev() }",
3381 )
3382 .file(
3383 "build.rs",
3384 "extern crate build; fn main() { build::build(); }",
3385 )
3386 .file("dep/Cargo.toml", &basic_manifest("dep", "0.5.0"))
3387 .file("dep/src/lib.rs", "pub fn dep() {}")
3388 .file("build/Cargo.toml", &basic_manifest("build", "0.5.0"))
3389 .file("build/src/lib.rs", "pub fn build() {}")
3390 .file("dev/Cargo.toml", &basic_manifest("dev", "0.5.0"))
3391 .file("dev/src/lib.rs", "pub fn dev() {}")
3392 .build();
3393
3394 p.cargo("build").run();
3395
3396 assert!(p.bin("foo").is_file());
3397 p.cargo("test").run();
3398}
3399
3400#[cargo_test]
3401fn cargo_platform_specific_dependency_build_dependencies_conflicting_warning() {
3402 let host = rustc_host();
3403 let p = project()
3404 .file(
3405 "Cargo.toml",
3406 &format!(
3407 r#"
3408 [package]
3409 name = "foo"
3410 version = "0.5.0"
3411 authors = ["wycats@example.com"]
3412 build = "build.rs"
3413
3414 [target.{host}.build-dependencies]
3415 build = {{ path = "build" }}
3416 [target.{host}.build_dependencies]
3417 build = {{ path = "build" }}
3418 "#,
3419 host = host
3420 ),
3421 )
3422 .file("src/main.rs", "fn main() { }")
3423 .file(
3424 "build.rs",
3425 "extern crate build; fn main() { build::build(); }",
3426 )
3427 .file("build/Cargo.toml", &basic_manifest("build", "0.5.0"))
3428 .file("build/src/lib.rs", "pub fn build() {}")
3429 .build();
3430
3431 p.cargo("build")
3432 .with_stderr_contains(
3433 format!("[WARNING] conflicting between `build-dependencies` and `build_dependencies` in the `{}` platform target.\n
3434 `build_dependencies` is ignored and not recommended for use in the future", host)
3435 )
3436 .run();
3437
3438 assert!(p.bin("foo").is_file());
3439}
3440
3441#[cargo_test]
3442fn cargo_platform_specific_dependency_dev_dependencies_conflicting_warning() {
3443 let host = rustc_host();
3444 let p = project()
3445 .file(
3446 "Cargo.toml",
3447 &format!(
3448 r#"
3449 [package]
3450 name = "foo"
3451 version = "0.5.0"
3452 authors = ["wycats@example.com"]
3453
3454 [target.{host}.dev-dependencies]
3455 dev = {{ path = "dev" }}
3456 [target.{host}.dev_dependencies]
3457 dev = {{ path = "dev" }}
3458 "#,
3459 host = host
3460 ),
3461 )
3462 .file("src/main.rs", "fn main() { }")
3463 .file(
3464 "tests/foo.rs",
3465 "extern crate dev; #[test] fn foo() { dev::dev() }",
3466 )
3467 .file("dev/Cargo.toml", &basic_manifest("dev", "0.5.0"))
3468 .file("dev/src/lib.rs", "pub fn dev() {}")
3469 .build();
3470
3471 p.cargo("build")
3472 .with_stderr_contains(
3473 format!("[WARNING] conflicting between `dev-dependencies` and `dev_dependencies` in the `{}` platform target.\n
3474 `dev_dependencies` is ignored and not recommended for use in the future", host)
3475 )
3476 .run();
3477
3478 assert!(p.bin("foo").is_file());
3479 p.cargo("test").run();
3480}
3481
3482#[cargo_test]
3483fn bad_platform_specific_dependency() {
3484 let p = project()
3485 .file(
3486 "Cargo.toml",
3487 r#"
3488 [package]
3489
3490 name = "foo"
3491 version = "0.5.0"
3492 authors = ["wycats@example.com"]
3493
3494 [target.wrong-target.dependencies.bar]
3495 path = "bar"
3496 "#,
3497 )
3498 .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"]))
3499 .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0"))
3500 .file(
3501 "bar/src/lib.rs",
3502 r#"pub fn gimme() -> String { format!("") }"#,
3503 )
3504 .build();
3505
3506 p.cargo("build")
3507 .with_status(101)
3508 .with_stderr_contains("[..]can't find crate for `bar`")
3509 .run();
3510}
3511
3512#[cargo_test]
3513fn cargo_platform_specific_dependency_wrong_platform() {
3514 let p = project()
3515 .file(
3516 "Cargo.toml",
3517 r#"
3518 [package]
3519
3520 name = "foo"
3521 version = "0.5.0"
3522 authors = ["wycats@example.com"]
3523
3524 [target.non-existing-triplet.dependencies.bar]
3525 path = "bar"
3526 "#,
3527 )
3528 .file("src/main.rs", "fn main() {}")
3529 .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0"))
3530 .file(
3531 "bar/src/lib.rs",
3532 "invalid rust file, should not be compiled",
3533 )
3534 .build();
3535
3536 p.cargo("build").run();
3537
3538 assert!(p.bin("foo").is_file());
3539 p.process(&p.bin("foo")).run();
3540
3541 let lockfile = p.read_lockfile();
3542 assert!(lockfile.contains("bar"));
3543}
3544
3545#[cargo_test]
3546fn example_as_lib() {
3547 let p = project()
3548 .file(
3549 "Cargo.toml",
3550 r#"
3551 [package]
3552 name = "foo"
3553 version = "0.0.1"
3554 authors = []
3555
3556 [[example]]
3557 name = "ex"
3558 crate-type = ["lib"]
3559 "#,
3560 )
3561 .file("src/lib.rs", "")
3562 .file("examples/ex.rs", "")
3563 .build();
3564
3565 p.cargo("build --example=ex").run();
3566 assert!(p.example_lib("ex", "lib").is_file());
3567}
3568
3569#[cargo_test]
3570fn example_as_rlib() {
3571 let p = project()
3572 .file(
3573 "Cargo.toml",
3574 r#"
3575 [package]
3576 name = "foo"
3577 version = "0.0.1"
3578 authors = []
3579
3580 [[example]]
3581 name = "ex"
3582 crate-type = ["rlib"]
3583 "#,
3584 )
3585 .file("src/lib.rs", "")
3586 .file("examples/ex.rs", "")
3587 .build();
3588
3589 p.cargo("build --example=ex").run();
3590 assert!(p.example_lib("ex", "rlib").is_file());
3591}
3592
3593#[cargo_test]
3594fn example_as_dylib() {
3595 let p = project()
3596 .file(
3597 "Cargo.toml",
3598 r#"
3599 [package]
3600 name = "foo"
3601 version = "0.0.1"
3602 authors = []
3603
3604 [[example]]
3605 name = "ex"
3606 crate-type = ["dylib"]
3607 "#,
3608 )
3609 .file("src/lib.rs", "")
3610 .file("examples/ex.rs", "")
3611 .build();
3612
3613 p.cargo("build --example=ex").run();
3614 assert!(p.example_lib("ex", "dylib").is_file());
3615}
3616
3617#[cargo_test]
3618fn example_as_proc_macro() {
3619 let p = project()
3620 .file(
3621 "Cargo.toml",
3622 r#"
3623 [package]
3624 name = "foo"
3625 version = "0.0.1"
3626 authors = []
3627
3628 [[example]]
3629 name = "ex"
3630 crate-type = ["proc-macro"]
3631 "#,
3632 )
3633 .file("src/lib.rs", "")
3634 .file(
3635 "examples/ex.rs",
3636 r#"
3637 extern crate proc_macro;
3638 use proc_macro::TokenStream;
3639
3640 #[proc_macro]
3641 pub fn eat(_item: TokenStream) -> TokenStream {
3642 "".parse().unwrap()
3643 }
3644 "#,
3645 )
3646 .build();
3647
3648 p.cargo("build --example=ex").run();
3649 assert!(p.example_lib("ex", "proc-macro").is_file());
3650}
3651
3652#[cargo_test]
3653fn example_bin_same_name() {
3654 let p = project()
3655 .file("src/main.rs", "fn main() {}")
3656 .file("examples/foo.rs", "fn main() {}")
3657 .build();
3658
3659 p.cargo("build --examples").run();
3660
3661 assert!(!p.bin("foo").is_file());
3662 // We expect a file of the form bin/foo-{metadata_hash}
3663 assert!(p.bin("examples/foo").is_file());
3664
3665 p.cargo("build --examples").run();
3666
3667 assert!(!p.bin("foo").is_file());
3668 // We expect a file of the form bin/foo-{metadata_hash}
3669 assert!(p.bin("examples/foo").is_file());
3670}
3671
3672#[cargo_test]
3673fn compile_then_delete() {
3674 let p = project().file("src/main.rs", "fn main() {}").build();
3675
3676 p.cargo("run -v").run();
3677 assert!(p.bin("foo").is_file());
3678 if cfg!(windows) {
3679 // On windows unlinking immediately after running often fails, so sleep
3680 sleep_ms(100);
3681 }
3682 fs::remove_file(&p.bin("foo")).unwrap();
3683 p.cargo("run -v").run();
3684}
3685
3686#[cargo_test]
3687fn transitive_dependencies_not_available() {
3688 let p = project()
3689 .file(
3690 "Cargo.toml",
3691 r#"
3692 [package]
3693 name = "foo"
3694 version = "0.0.1"
3695 authors = []
3696
3697 [dependencies.aaaaa]
3698 path = "a"
3699 "#,
3700 )
3701 .file(
3702 "src/main.rs",
3703 "extern crate bbbbb; extern crate aaaaa; fn main() {}",
3704 )
3705 .file(
3706 "a/Cargo.toml",
3707 r#"
3708 [package]
3709 name = "aaaaa"
3710 version = "0.0.1"
3711 authors = []
3712
3713 [dependencies.bbbbb]
3714 path = "../b"
3715 "#,
3716 )
3717 .file("a/src/lib.rs", "extern crate bbbbb;")
3718 .file("b/Cargo.toml", &basic_manifest("bbbbb", "0.0.1"))
3719 .file("b/src/lib.rs", "")
3720 .build();
3721
3722 p.cargo("build -v")
3723 .with_status(101)
3724 .with_stderr_contains("[..] can't find crate for `bbbbb`[..]")
3725 .run();
3726}
3727
3728#[cargo_test]
3729fn cyclic_deps_rejected() {
3730 let p = project()
3731 .file(
3732 "Cargo.toml",
3733 r#"
3734 [package]
3735 name = "foo"
3736 version = "0.0.1"
3737 authors = []
3738
3739 [dependencies.a]
3740 path = "a"
3741 "#,
3742 )
3743 .file("src/lib.rs", "")
3744 .file(
3745 "a/Cargo.toml",
3746 r#"
3747 [package]
3748 name = "a"
3749 version = "0.0.1"
3750 authors = []
3751
3752 [dependencies.foo]
3753 path = ".."
3754 "#,
3755 )
3756 .file("a/src/lib.rs", "")
3757 .build();
3758
3759 p.cargo("build -v")
3760 .with_status(101)
3761 .with_stderr(
3762"[ERROR] cyclic package dependency: package `a v0.0.1 ([CWD]/a)` depends on itself. Cycle:
3763package `a v0.0.1 ([CWD]/a)`
3764 ... which satisfies path dependency `a` of package `foo v0.0.1 ([CWD])`
3765 ... which satisfies path dependency `foo` of package `a v0.0.1 ([..])`",
3766 ).run();
3767}
3768
3769#[cargo_test]
3770fn predictable_filenames() {
3771 let p = project()
3772 .file(
3773 "Cargo.toml",
3774 r#"
3775 [package]
3776 name = "foo"
3777 version = "0.0.1"
3778 authors = []
3779
3780 [lib]
3781 name = "foo"
3782 crate-type = ["dylib", "rlib"]
3783 "#,
3784 )
3785 .file("src/lib.rs", "")
3786 .build();
3787
3788 p.cargo("build -v").run();
3789 assert!(p.root().join("target/debug/libfoo.rlib").is_file());
3790 let dylib_name = format!("{}foo{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX);
3791 assert!(p.root().join("target/debug").join(dylib_name).is_file());
3792}
3793
3794#[cargo_test]
3795fn dashes_to_underscores() {
3796 let p = project()
3797 .file("Cargo.toml", &basic_manifest("foo-bar", "0.0.1"))
3798 .file("src/lib.rs", "")
3799 .file("src/main.rs", "extern crate foo_bar; fn main() {}")
3800 .build();
3801
3802 p.cargo("build -v").run();
3803 assert!(p.bin("foo-bar").is_file());
3804}
3805
3806#[cargo_test]
3807fn dashes_in_crate_name_bad() {
3808 let p = project()
3809 .file(
3810 "Cargo.toml",
3811 r#"
3812 [package]
3813 name = "foo"
3814 version = "0.0.1"
3815 authors = []
3816
3817 [lib]
3818 name = "foo-bar"
3819 "#,
3820 )
3821 .file("src/lib.rs", "")
3822 .file("src/main.rs", "extern crate foo_bar; fn main() {}")
3823 .build();
3824
3825 p.cargo("build -v")
3826 .with_status(101)
3827 .with_stderr(
3828 "\
3829[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
3830
3831Caused by:
3832 library target names cannot contain hyphens: foo-bar
3833",
3834 )
3835 .run();
3836}
3837
3838#[cargo_test]
3839fn rustc_env_var() {
3840 let p = project().file("src/lib.rs", "").build();
3841
3842 p.cargo("build -v")
3843 .env("RUSTC", "rustc-that-does-not-exist")
3844 .with_status(101)
3845 .with_stderr(
3846 "\
3847[ERROR] could not execute process `rustc-that-does-not-exist -vV` ([..])
3848
3849Caused by:
3850[..]
3851",
3852 )
3853 .run();
3854 assert!(!p.bin("a").is_file());
3855}
3856
3857#[cargo_test]
3858fn filtering() {
3859 let p = project()
3860 .file("src/lib.rs", "")
3861 .file("src/bin/a.rs", "fn main() {}")
3862 .file("src/bin/b.rs", "fn main() {}")
3863 .file("examples/a.rs", "fn main() {}")
3864 .file("examples/b.rs", "fn main() {}")
3865 .build();
3866
3867 p.cargo("build --lib").run();
3868 assert!(!p.bin("a").is_file());
3869
3870 p.cargo("build --bin=a --example=a").run();
3871 assert!(p.bin("a").is_file());
3872 assert!(!p.bin("b").is_file());
3873 assert!(p.bin("examples/a").is_file());
3874 assert!(!p.bin("examples/b").is_file());
3875}
3876
3877#[cargo_test]
3878fn filtering_implicit_bins() {
3879 let p = project()
3880 .file("src/lib.rs", "")
3881 .file("src/bin/a.rs", "fn main() {}")
3882 .file("src/bin/b.rs", "fn main() {}")
3883 .file("examples/a.rs", "fn main() {}")
3884 .file("examples/b.rs", "fn main() {}")
3885 .build();
3886
3887 p.cargo("build --bins").run();
3888 assert!(p.bin("a").is_file());
3889 assert!(p.bin("b").is_file());
3890 assert!(!p.bin("examples/a").is_file());
3891 assert!(!p.bin("examples/b").is_file());
3892}
3893
3894#[cargo_test]
3895fn filtering_implicit_examples() {
3896 let p = project()
3897 .file("src/lib.rs", "")
3898 .file("src/bin/a.rs", "fn main() {}")
3899 .file("src/bin/b.rs", "fn main() {}")
3900 .file("examples/a.rs", "fn main() {}")
3901 .file("examples/b.rs", "fn main() {}")
3902 .build();
3903
3904 p.cargo("build --examples").run();
3905 assert!(!p.bin("a").is_file());
3906 assert!(!p.bin("b").is_file());
3907 assert!(p.bin("examples/a").is_file());
3908 assert!(p.bin("examples/b").is_file());
3909}
3910
3911#[cargo_test]
3912fn ignore_dotfile() {
3913 let p = project()
3914 .file("src/bin/.a.rs", "")
3915 .file("src/bin/a.rs", "fn main() {}")
3916 .build();
3917
3918 p.cargo("build").run();
3919}
3920
3921#[cargo_test]
3922fn ignore_dotdirs() {
3923 let p = project()
3924 .file("src/bin/a.rs", "fn main() {}")
3925 .file(".git/Cargo.toml", "")
3926 .file(".pc/dummy-fix.patch/Cargo.toml", "")
3927 .build();
3928
3929 p.cargo("build").run();
3930}
3931
3932#[cargo_test]
3933fn dotdir_root() {
3934 let p = ProjectBuilder::new(root().join(".foo"))
3935 .file("src/bin/a.rs", "fn main() {}")
3936 .build();
3937 p.cargo("build").run();
3938}
3939
3940#[cargo_test]
3941fn custom_target_dir_env() {
3942 let p = project().file("src/main.rs", "fn main() {}").build();
3943
3944 let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
3945
3946 p.cargo("build").env("CARGO_TARGET_DIR", "foo/target").run();
3947 assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
3948 assert!(!p.root().join("target/debug").join(&exe_name).is_file());
3949
3950 p.cargo("build").run();
3951 assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
3952 assert!(p.root().join("target/debug").join(&exe_name).is_file());
3953
3954 p.cargo("build")
3955 .env("CARGO_BUILD_TARGET_DIR", "foo2/target")
3956 .run();
3957 assert!(p.root().join("foo2/target/debug").join(&exe_name).is_file());
3958
3959 p.change_file(
3960 ".cargo/config",
3961 r#"
3962 [build]
3963 target-dir = "foo/target"
3964 "#,
3965 );
3966 p.cargo("build").env("CARGO_TARGET_DIR", "bar/target").run();
3967 assert!(p.root().join("bar/target/debug").join(&exe_name).is_file());
3968 assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
3969 assert!(p.root().join("target/debug").join(&exe_name).is_file());
3970}
3971
3972#[cargo_test]
3973fn custom_target_dir_line_parameter() {
3974 let p = project().file("src/main.rs", "fn main() {}").build();
3975
3976 let exe_name = format!("foo{}", env::consts::EXE_SUFFIX);
3977
3978 p.cargo("build --target-dir foo/target").run();
3979 assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
3980 assert!(!p.root().join("target/debug").join(&exe_name).is_file());
3981
3982 p.cargo("build").run();
3983 assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
3984 assert!(p.root().join("target/debug").join(&exe_name).is_file());
3985
3986 p.change_file(
3987 ".cargo/config",
3988 r#"
3989 [build]
3990 target-dir = "foo/target"
3991 "#,
3992 );
3993 p.cargo("build --target-dir bar/target").run();
3994 assert!(p.root().join("bar/target/debug").join(&exe_name).is_file());
3995 assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
3996 assert!(p.root().join("target/debug").join(&exe_name).is_file());
3997
3998 p.cargo("build --target-dir foobar/target")
3999 .env("CARGO_TARGET_DIR", "bar/target")
4000 .run();
4001 assert!(p
4002 .root()
4003 .join("foobar/target/debug")
4004 .join(&exe_name)
4005 .is_file());
4006 assert!(p.root().join("bar/target/debug").join(&exe_name).is_file());
4007 assert!(p.root().join("foo/target/debug").join(&exe_name).is_file());
4008 assert!(p.root().join("target/debug").join(&exe_name).is_file());
4009}
4010
4011#[cargo_test]
4012fn build_multiple_packages() {
4013 let p = project()
4014 .file(
4015 "Cargo.toml",
4016 r#"
4017 [package]
4018 name = "foo"
4019 version = "0.0.1"
4020 authors = []
4021
4022 [dependencies.d1]
4023 path = "d1"
4024 [dependencies.d2]
4025 path = "d2"
4026
4027 [[bin]]
4028 name = "foo"
4029 "#,
4030 )
4031 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
4032 .file("d1/Cargo.toml", &basic_bin_manifest("d1"))
4033 .file("d1/src/lib.rs", "")
4034 .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
4035 .file(
4036 "d2/Cargo.toml",
4037 r#"
4038 [package]
4039 name = "d2"
4040 version = "0.0.1"
4041 authors = []
4042
4043 [[bin]]
4044 name = "d2"
4045 doctest = false
4046 "#,
4047 )
4048 .file("d2/src/main.rs", "fn main() { println!(\"d2\"); }")
4049 .build();
4050
4051 p.cargo("build -p d1 -p d2 -p foo").run();
4052
4053 assert!(p.bin("foo").is_file());
4054 p.process(&p.bin("foo")).with_stdout("i am foo\n").run();
4055
4056 let d1_path = &p
4057 .build_dir()
4058 .join("debug")
4059 .join(format!("d1{}", env::consts::EXE_SUFFIX));
4060 let d2_path = &p
4061 .build_dir()
4062 .join("debug")
4063 .join(format!("d2{}", env::consts::EXE_SUFFIX));
4064
4065 assert!(d1_path.is_file());
4066 p.process(d1_path).with_stdout("d1").run();
4067
4068 assert!(d2_path.is_file());
4069 p.process(d2_path).with_stdout("d2").run();
4070}
4071
4072#[cargo_test]
4073fn invalid_spec() {
4074 let p = project()
4075 .file(
4076 "Cargo.toml",
4077 r#"
4078 [package]
4079 name = "foo"
4080 version = "0.0.1"
4081 authors = []
4082
4083 [dependencies.d1]
4084 path = "d1"
4085
4086 [[bin]]
4087 name = "foo"
4088 "#,
4089 )
4090 .file("src/bin/foo.rs", &main_file(r#""i am foo""#, &[]))
4091 .file("d1/Cargo.toml", &basic_bin_manifest("d1"))
4092 .file("d1/src/lib.rs", "")
4093 .file("d1/src/main.rs", "fn main() { println!(\"d1\"); }")
4094 .build();
4095
4096 p.cargo("build -p notAValidDep")
4097 .with_status(101)
4098 .with_stderr("[ERROR] package ID specification `notAValidDep` did not match any packages")
4099 .run();
4100
4101 p.cargo("build -p d1 -p notAValidDep")
4102 .with_status(101)
4103 .with_stderr("[ERROR] package ID specification `notAValidDep` did not match any packages")
4104 .run();
4105}
4106
4107#[cargo_test]
4108fn manifest_with_bom_is_ok() {
4109 let p = project()
4110 .file(
4111 "Cargo.toml",
4112 "\u{FEFF}
4113 [package]
4114 name = \"foo\"
4115 version = \"0.0.1\"
4116 authors = []
4117 ",
4118 )
4119 .file("src/lib.rs", "")
4120 .build();
4121 p.cargo("build -v").run();
4122}
4123
4124#[cargo_test]
4125fn panic_abort_compiles_with_panic_abort() {
4126 let p = project()
4127 .file(
4128 "Cargo.toml",
4129 r#"
4130 [package]
4131 name = "foo"
4132 version = "0.0.1"
4133 authors = []
4134
4135 [profile.dev]
4136 panic = 'abort'
4137 "#,
4138 )
4139 .file("src/lib.rs", "")
4140 .build();
4141 p.cargo("build -v")
4142 .with_stderr_contains("[..] -C panic=abort [..]")
4143 .run();
4144}
4145
4146#[cargo_test]
4147fn compiler_json_error_format() {
4148 let p = project()
4149 .file(
4150 "Cargo.toml",
4151 r#"
4152 [package]
4153
4154 name = "foo"
4155 version = "0.5.0"
4156 authors = ["wycats@example.com"]
4157
4158 [dependencies.bar]
4159 path = "bar"
4160 "#,
4161 )
4162 .file(
4163 "build.rs",
4164 "fn main() { println!(\"cargo:rustc-cfg=xyz\") }",
4165 )
4166 .file("src/main.rs", "fn main() { let unused = 92; }")
4167 .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0"))
4168 .file("bar/src/lib.rs", r#"fn dead() {}"#)
4169 .build();
4170
4171 let output = |fresh| {
4172 r#"
4173 {
4174 "reason":"compiler-artifact",
4175 "package_id":"foo 0.5.0 ([..])",
4176 "manifest_path": "[..]",
4177 "target":{
4178 "kind":["custom-build"],
4179 "crate_types":["bin"],
4180 "doc": false,
4181 "doctest": false,
4182 "edition": "2015",
4183 "name":"build-script-build",
4184 "src_path":"[..]build.rs",
4185 "test": false
4186 },
4187 "profile": {
4188 "debug_assertions": true,
49aad941 4189 "debuginfo": 0,
0a29b90c
FG
4190 "opt_level": "0",
4191 "overflow_checks": true,
4192 "test": false
4193 },
4194 "executable": null,
4195 "features": [],
4196 "filenames": "{...}",
4197 "fresh": $FRESH
4198 }
4199
4200 {
4201 "reason":"compiler-message",
4202 "package_id":"bar 0.5.0 ([..])",
4203 "manifest_path": "[..]",
4204 "target":{
4205 "kind":["lib"],
4206 "crate_types":["lib"],
4207 "doc": true,
4208 "doctest": true,
4209 "edition": "2015",
4210 "name":"bar",
4211 "src_path":"[..]lib.rs",
4212 "test": true
4213 },
4214 "message":"{...}"
4215 }
4216
4217 {
4218 "reason":"compiler-artifact",
4219 "profile": {
4220 "debug_assertions": true,
4221 "debuginfo": 2,
4222 "opt_level": "0",
4223 "overflow_checks": true,
4224 "test": false
4225 },
4226 "executable": null,
4227 "features": [],
4228 "package_id":"bar 0.5.0 ([..])",
4229 "manifest_path": "[..]",
4230 "target":{
4231 "kind":["lib"],
4232 "crate_types":["lib"],
4233 "doc": true,
4234 "doctest": true,
4235 "edition": "2015",
4236 "name":"bar",
4237 "src_path":"[..]lib.rs",
4238 "test": true
4239 },
4240 "filenames":[
4241 "[..].rlib",
4242 "[..].rmeta"
4243 ],
4244 "fresh": $FRESH
4245 }
4246
4247 {
4248 "reason":"build-script-executed",
4249 "package_id":"foo 0.5.0 ([..])",
4250 "linked_libs":[],
4251 "linked_paths":[],
4252 "env":[],
4253 "cfgs":["xyz"],
4254 "out_dir": "[..]target/debug/build/foo-[..]/out"
4255 }
4256
4257 {
4258 "reason":"compiler-message",
4259 "package_id":"foo 0.5.0 ([..])",
4260 "manifest_path": "[..]",
4261 "target":{
4262 "kind":["bin"],
4263 "crate_types":["bin"],
4264 "doc": true,
4265 "doctest": false,
4266 "edition": "2015",
4267 "name":"foo",
4268 "src_path":"[..]main.rs",
4269 "test": true
4270 },
4271 "message":"{...}"
4272 }
4273
4274 {
4275 "reason":"compiler-artifact",
4276 "package_id":"foo 0.5.0 ([..])",
4277 "manifest_path": "[..]",
4278 "target":{
4279 "kind":["bin"],
4280 "crate_types":["bin"],
4281 "doc": true,
4282 "doctest": false,
4283 "edition": "2015",
4284 "name":"foo",
4285 "src_path":"[..]main.rs",
4286 "test": true
4287 },
4288 "profile": {
4289 "debug_assertions": true,
4290 "debuginfo": 2,
4291 "opt_level": "0",
4292 "overflow_checks": true,
4293 "test": false
4294 },
4295 "executable": "[..]/foo/target/debug/foo[EXE]",
4296 "features": [],
4297 "filenames": "{...}",
4298 "fresh": $FRESH
4299 }
4300
4301 {"reason": "build-finished", "success": true}
4302 "#
4303 .replace("$FRESH", fresh)
4304 };
4305
4306 // Use `jobs=1` to ensure that the order of messages is consistent.
4307 p.cargo("build -v --message-format=json --jobs=1")
4308 .with_json_contains_unordered(&output("false"))
4309 .run();
4310
4311 // With fresh build, we should repeat the artifacts,
4312 // and replay the cached compiler warnings.
4313 p.cargo("build -v --message-format=json --jobs=1")
4314 .with_json_contains_unordered(&output("true"))
4315 .run();
4316}
4317
4318#[cargo_test]
4319fn wrong_message_format_option() {
4320 let p = project()
4321 .file("Cargo.toml", &basic_bin_manifest("foo"))
4322 .file("src/main.rs", "fn main() {}")
4323 .build();
4324
4325 p.cargo("build --message-format XML")
4326 .with_status(101)
4327 .with_stderr_contains(
4328 "\
4329error: invalid message format specifier: `xml`
4330",
4331 )
4332 .run();
4333}
4334
4335#[cargo_test]
4336fn message_format_json_forward_stderr() {
4337 let p = project()
4338 .file("Cargo.toml", &basic_bin_manifest("foo"))
4339 .file("src/main.rs", "fn main() { let unused = 0; }")
4340 .build();
4341
4342 p.cargo("rustc --release --bin foo --message-format JSON")
4343 .with_json_contains_unordered(
4344 r#"
4345 {
4346 "reason":"compiler-message",
4347 "package_id":"foo 0.5.0 ([..])",
4348 "manifest_path": "[..]",
4349 "target":{
4350 "kind":["bin"],
4351 "crate_types":["bin"],
4352 "doc": true,
4353 "doctest": false,
4354 "edition": "2015",
4355 "name":"foo",
4356 "src_path":"[..]",
4357 "test": true
4358 },
4359 "message":"{...}"
4360 }
4361
4362 {
4363 "reason":"compiler-artifact",
4364 "package_id":"foo 0.5.0 ([..])",
4365 "manifest_path": "[..]",
4366 "target":{
4367 "kind":["bin"],
4368 "crate_types":["bin"],
4369 "doc": true,
4370 "doctest": false,
4371 "edition": "2015",
4372 "name":"foo",
4373 "src_path":"[..]",
4374 "test": true
4375 },
4376 "profile":{
4377 "debug_assertions":false,
fe692bf9 4378 "debuginfo":0,
0a29b90c
FG
4379 "opt_level":"3",
4380 "overflow_checks": false,
4381 "test":false
4382 },
4383 "executable": "{...}",
4384 "features":[],
4385 "filenames": "{...}",
4386 "fresh": false
4387 }
4388
4389 {"reason": "build-finished", "success": true}
4390 "#,
4391 )
4392 .run();
4393}
4394
4395#[cargo_test]
4396fn no_warn_about_package_metadata() {
4397 let p = project()
4398 .file(
4399 "Cargo.toml",
4400 r#"
4401 [package]
4402 name = "foo"
4403 version = "0.0.1"
4404 authors = []
4405
4406 [package.metadata]
4407 foo = "bar"
4408 a = true
4409 b = 3
4410
4411 [package.metadata.another]
4412 bar = 3
4413 "#,
4414 )
4415 .file("src/lib.rs", "")
4416 .build();
4417 p.cargo("build")
4418 .with_stderr(
4419 "[..] foo v0.0.1 ([..])\n\
4420 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
4421 )
4422 .run();
4423}
4424
4425#[cargo_test]
4426fn no_warn_about_workspace_metadata() {
4427 let p = project()
4428 .file(
4429 "Cargo.toml",
4430 r#"
4431 [workspace]
4432 members = ["foo"]
4433
4434 [workspace.metadata]
4435 something = "something_else"
4436 x = 1
4437 y = 2
4438
4439 [workspace.metadata.another]
4440 bar = 12
4441 "#,
4442 )
4443 .file(
4444 "foo/Cargo.toml",
4445 r#"
4446 [package]
4447 name = "foo"
4448 version = "0.0.1"
4449 "#,
4450 )
4451 .file("foo/src/lib.rs", "")
4452 .build();
4453
4454 p.cargo("build")
4455 .with_stderr(
4456 "[..] foo v0.0.1 ([..])\n\
4457 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
4458 )
4459 .run();
4460}
4461
4462#[cargo_test]
4463fn cargo_build_empty_target() {
4464 let p = project()
4465 .file("Cargo.toml", &basic_bin_manifest("foo"))
4466 .file("src/main.rs", "fn main() {}")
4467 .build();
4468
4469 p.cargo("build --target")
4470 .arg("")
4471 .with_status(101)
4472 .with_stderr_contains("[..] target was empty")
4473 .run();
4474}
4475
ed00b5ec
FG
4476#[cargo_test]
4477fn cargo_build_with_unsupported_short_target_flag() {
4478 let p = project()
4479 .file("Cargo.toml", &basic_bin_manifest("foo"))
4480 .file("src/main.rs", "fn main() {}")
4481 .build();
4482
4483 p.cargo("build -t")
4484 .arg("")
4485 .with_stderr(
4486 "\
4487error: unexpected argument '-t' found
4488
4489 tip: a similar argument exists: '--target'
4490
4491Usage: cargo[EXE] build [OPTIONS]
4492
4493For more information, try '--help'.
4494",
4495 )
4496 .with_status(1)
4497 .run();
4498}
4499
0a29b90c
FG
4500#[cargo_test]
4501fn build_all_workspace() {
4502 let p = project()
4503 .file(
4504 "Cargo.toml",
4505 r#"
4506 [package]
4507 name = "foo"
4508 version = "0.1.0"
4509
4510 [dependencies]
4511 bar = { path = "bar" }
4512
4513 [workspace]
4514 "#,
4515 )
4516 .file("src/main.rs", "fn main() {}")
4517 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4518 .file("bar/src/lib.rs", "pub fn bar() {}")
4519 .build();
4520
4521 p.cargo("build --workspace")
4522 .with_stderr(
4523 "\
4524[COMPILING] bar v0.1.0 ([..])
4525[COMPILING] foo v0.1.0 ([..])
4526[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4527",
4528 )
4529 .run();
4530}
4531
4532#[cargo_test]
4533fn build_all_exclude() {
4534 let p = project()
4535 .file(
4536 "Cargo.toml",
4537 r#"
4538 [package]
4539 name = "foo"
4540 version = "0.1.0"
4541
4542 [workspace]
4543 members = ["bar", "baz"]
4544 "#,
4545 )
4546 .file("src/main.rs", "fn main() {}")
4547 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4548 .file("bar/src/lib.rs", "pub fn bar() {}")
4549 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4550 .file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
4551 .build();
4552
4553 p.cargo("build --workspace --exclude baz")
4554 .with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
4555 .with_stderr_unordered(
4556 "\
4557[COMPILING] foo v0.1.0 ([..])
4558[COMPILING] bar v0.1.0 ([..])
4559[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4560",
4561 )
4562 .run();
4563}
4564
ed00b5ec
FG
4565#[cargo_test]
4566fn cargo_build_with_unsupported_short_exclude_flag() {
4567 let p = project()
4568 .file(
4569 "Cargo.toml",
4570 r#"
4571 [package]
4572 name = "foo"
4573 version = "0.1.0"
4574
4575 [workspace]
4576 members = ["bar", "baz"]
4577 "#,
4578 )
4579 .file("src/main.rs", "fn main() {}")
4580 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4581 .file("bar/src/lib.rs", "pub fn bar() {}")
4582 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4583 .file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
4584 .build();
4585
4586 p.cargo("build --workspace -x baz")
4587 .with_stderr(
4588 "\
4589error: unexpected argument '-x' found
4590
4591 tip: a similar argument exists: '--exclude'
4592
4593Usage: cargo[EXE] build [OPTIONS]
4594
4595For more information, try '--help'.
4596",
4597 )
4598 .with_status(1)
4599 .run();
4600}
4601
0a29b90c
FG
4602#[cargo_test]
4603fn build_all_exclude_not_found() {
4604 let p = project()
4605 .file(
4606 "Cargo.toml",
4607 r#"
4608 [package]
4609 name = "foo"
4610 version = "0.1.0"
4611
4612 [workspace]
4613 members = ["bar"]
4614 "#,
4615 )
4616 .file("src/main.rs", "fn main() {}")
4617 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4618 .file("bar/src/lib.rs", "pub fn bar() {}")
4619 .build();
4620
4621 p.cargo("build --workspace --exclude baz")
4622 .with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
4623 .with_stderr_unordered(
4624 "\
4625[WARNING] excluded package(s) `baz` not found in workspace [..]
4626[COMPILING] foo v0.1.0 ([..])
4627[COMPILING] bar v0.1.0 ([..])
4628[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4629",
4630 )
4631 .run();
4632}
4633
4634#[cargo_test]
4635fn build_all_exclude_glob() {
4636 let p = project()
4637 .file(
4638 "Cargo.toml",
4639 r#"
4640 [package]
4641 name = "foo"
4642 version = "0.1.0"
4643
4644 [workspace]
4645 members = ["bar", "baz"]
4646 "#,
4647 )
4648 .file("src/main.rs", "fn main() {}")
4649 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4650 .file("bar/src/lib.rs", "pub fn bar() {}")
4651 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4652 .file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
4653 .build();
4654
4655 p.cargo("build --workspace --exclude '*z'")
4656 .with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
4657 .with_stderr_unordered(
4658 "\
4659[COMPILING] foo v0.1.0 ([..])
4660[COMPILING] bar v0.1.0 ([..])
4661[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4662",
4663 )
4664 .run();
4665}
4666
4667#[cargo_test]
4668fn build_all_exclude_glob_not_found() {
4669 let p = project()
4670 .file(
4671 "Cargo.toml",
4672 r#"
4673 [package]
4674 name = "foo"
4675 version = "0.1.0"
4676
4677 [workspace]
4678 members = ["bar"]
4679 "#,
4680 )
4681 .file("src/main.rs", "fn main() {}")
4682 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4683 .file("bar/src/lib.rs", "pub fn bar() {}")
4684 .build();
4685
4686 p.cargo("build --workspace --exclude '*z'")
4687 .with_stderr_does_not_contain("[COMPILING] baz v0.1.0 [..]")
4688 .with_stderr(
4689 "\
4690[WARNING] excluded package pattern(s) `*z` not found in workspace [..]
4691[COMPILING] [..] v0.1.0 ([..])
4692[COMPILING] [..] v0.1.0 ([..])
4693[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4694",
4695 )
4696 .run();
4697}
4698
4699#[cargo_test]
4700fn build_all_exclude_broken_glob() {
4701 let p = project().file("src/main.rs", "fn main() {}").build();
4702
4703 p.cargo("build --workspace --exclude '[*z'")
4704 .with_status(101)
4705 .with_stderr_contains("[ERROR] cannot build glob pattern from `[*z`")
4706 .run();
4707}
4708
4709#[cargo_test]
4710fn build_all_workspace_implicit_examples() {
4711 let p = project()
4712 .file(
4713 "Cargo.toml",
4714 r#"
4715 [package]
4716 name = "foo"
4717 version = "0.1.0"
4718
4719 [dependencies]
4720 bar = { path = "bar" }
4721
4722 [workspace]
4723 "#,
4724 )
4725 .file("src/lib.rs", "")
4726 .file("src/bin/a.rs", "fn main() {}")
4727 .file("src/bin/b.rs", "fn main() {}")
4728 .file("examples/c.rs", "fn main() {}")
4729 .file("examples/d.rs", "fn main() {}")
4730 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4731 .file("bar/src/lib.rs", "")
4732 .file("bar/src/bin/e.rs", "fn main() {}")
4733 .file("bar/src/bin/f.rs", "fn main() {}")
4734 .file("bar/examples/g.rs", "fn main() {}")
4735 .file("bar/examples/h.rs", "fn main() {}")
4736 .build();
4737
4738 p.cargo("build --workspace --examples")
4739 .with_stderr(
4740 "[..] Compiling bar v0.1.0 ([..])\n\
4741 [..] Compiling foo v0.1.0 ([..])\n\
4742 [..] Finished dev [unoptimized + debuginfo] target(s) in [..]\n",
4743 )
4744 .run();
4745 assert!(!p.bin("a").is_file());
4746 assert!(!p.bin("b").is_file());
4747 assert!(p.bin("examples/c").is_file());
4748 assert!(p.bin("examples/d").is_file());
4749 assert!(!p.bin("e").is_file());
4750 assert!(!p.bin("f").is_file());
4751 assert!(p.bin("examples/g").is_file());
4752 assert!(p.bin("examples/h").is_file());
4753}
4754
4755#[cargo_test]
4756fn build_all_virtual_manifest() {
4757 let p = project()
4758 .file(
4759 "Cargo.toml",
4760 r#"
4761 [workspace]
4762 members = ["bar", "baz"]
4763 "#,
4764 )
4765 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4766 .file("bar/src/lib.rs", "pub fn bar() {}")
4767 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4768 .file("baz/src/lib.rs", "pub fn baz() {}")
4769 .build();
4770
4771 // The order in which bar and baz are built is not guaranteed
4772 p.cargo("build --workspace")
4773 .with_stderr_unordered(
4774 "\
4775[COMPILING] baz v0.1.0 ([..])
4776[COMPILING] bar v0.1.0 ([..])
4777[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4778",
4779 )
4780 .run();
4781}
4782
4783#[cargo_test]
4784fn build_virtual_manifest_all_implied() {
4785 let p = project()
4786 .file(
4787 "Cargo.toml",
4788 r#"
4789 [workspace]
4790 members = ["bar", "baz"]
4791 "#,
4792 )
4793 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4794 .file("bar/src/lib.rs", "pub fn bar() {}")
4795 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4796 .file("baz/src/lib.rs", "pub fn baz() {}")
4797 .build();
4798
4799 // The order in which `bar` and `baz` are built is not guaranteed.
4800 p.cargo("build")
4801 .with_stderr_unordered(
4802 "\
4803[COMPILING] baz v0.1.0 ([..])
4804[COMPILING] bar v0.1.0 ([..])
4805[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4806",
4807 )
4808 .run();
4809}
4810
4811#[cargo_test]
4812fn build_virtual_manifest_one_project() {
4813 let p = project()
4814 .file(
4815 "Cargo.toml",
4816 r#"
4817 [workspace]
4818 members = ["bar", "baz"]
4819 "#,
4820 )
4821 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4822 .file("bar/src/lib.rs", "pub fn bar() {}")
4823 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4824 .file("baz/src/lib.rs", "pub fn baz() { break_the_build(); }")
4825 .build();
4826
4827 p.cargo("build -p bar")
4828 .with_stderr_does_not_contain("[..]baz[..]")
4829 .with_stderr(
4830 "\
4831[COMPILING] bar v0.1.0 ([..])
4832[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4833",
4834 )
4835 .run();
4836}
4837
4838#[cargo_test]
4839fn build_virtual_manifest_glob() {
4840 let p = project()
4841 .file(
4842 "Cargo.toml",
4843 r#"
4844 [workspace]
4845 members = ["bar", "baz"]
4846 "#,
4847 )
4848 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4849 .file("bar/src/lib.rs", "pub fn bar() { break_the_build(); }")
4850 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4851 .file("baz/src/lib.rs", "pub fn baz() {}")
4852 .build();
4853
4854 p.cargo("build -p '*z'")
4855 .with_stderr_does_not_contain("[..]bar[..]")
4856 .with_stderr(
4857 "\
4858[COMPILING] baz v0.1.0 ([..])
4859[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4860",
4861 )
4862 .run();
4863}
4864
4865#[cargo_test]
4866fn build_virtual_manifest_glob_not_found() {
4867 let p = project()
4868 .file(
4869 "Cargo.toml",
4870 r#"
4871 [workspace]
4872 members = ["bar"]
4873 "#,
4874 )
4875 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4876 .file("bar/src/lib.rs", "pub fn bar() {}")
4877 .build();
4878
4879 p.cargo("build -p bar -p '*z'")
4880 .with_status(101)
4881 .with_stderr("[ERROR] package pattern(s) `*z` not found in workspace [..]")
4882 .run();
4883}
4884
4885#[cargo_test]
4886fn build_virtual_manifest_broken_glob() {
4887 let p = project()
4888 .file(
4889 "Cargo.toml",
4890 r#"
4891 [workspace]
4892 members = ["bar"]
4893 "#,
4894 )
4895 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4896 .file("bar/src/lib.rs", "pub fn bar() {}")
4897 .build();
4898
4899 p.cargo("build -p '[*z'")
4900 .with_status(101)
4901 .with_stderr_contains("[ERROR] cannot build glob pattern from `[*z`")
4902 .run();
4903}
4904
4905#[cargo_test]
4906fn build_all_virtual_manifest_implicit_examples() {
4907 let p = project()
4908 .file(
4909 "Cargo.toml",
4910 r#"
4911 [workspace]
4912 members = ["bar", "baz"]
4913 "#,
4914 )
4915 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
4916 .file("bar/src/lib.rs", "")
4917 .file("bar/src/bin/a.rs", "fn main() {}")
4918 .file("bar/src/bin/b.rs", "fn main() {}")
4919 .file("bar/examples/c.rs", "fn main() {}")
4920 .file("bar/examples/d.rs", "fn main() {}")
4921 .file("baz/Cargo.toml", &basic_manifest("baz", "0.1.0"))
4922 .file("baz/src/lib.rs", "")
4923 .file("baz/src/bin/e.rs", "fn main() {}")
4924 .file("baz/src/bin/f.rs", "fn main() {}")
4925 .file("baz/examples/g.rs", "fn main() {}")
4926 .file("baz/examples/h.rs", "fn main() {}")
4927 .build();
4928
4929 // The order in which bar and baz are built is not guaranteed
4930 p.cargo("build --workspace --examples")
4931 .with_stderr_unordered(
4932 "\
4933[COMPILING] baz v0.1.0 ([..])
4934[COMPILING] bar v0.1.0 ([..])
4935[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
4936",
4937 )
4938 .run();
4939 assert!(!p.bin("a").is_file());
4940 assert!(!p.bin("b").is_file());
4941 assert!(p.bin("examples/c").is_file());
4942 assert!(p.bin("examples/d").is_file());
4943 assert!(!p.bin("e").is_file());
4944 assert!(!p.bin("f").is_file());
4945 assert!(p.bin("examples/g").is_file());
4946 assert!(p.bin("examples/h").is_file());
4947}
4948
4949#[cargo_test]
4950fn build_all_member_dependency_same_name() {
4951 let p = project()
4952 .file(
4953 "Cargo.toml",
4954 r#"
4955 [workspace]
4956 members = ["a"]
4957 "#,
4958 )
4959 .file(
4960 "a/Cargo.toml",
4961 r#"
4962 [package]
4963 name = "a"
4964 version = "0.1.0"
4965
4966 [dependencies]
4967 a = "0.1.0"
4968 "#,
4969 )
4970 .file("a/src/lib.rs", "pub fn a() {}")
4971 .build();
4972
4973 Package::new("a", "0.1.0").publish();
4974
4975 p.cargo("build --workspace")
4976 .with_stderr(
4977 "[UPDATING] `[..]` index\n\
4978 [DOWNLOADING] crates ...\n\
4979 [DOWNLOADED] a v0.1.0 ([..])\n\
4980 [COMPILING] a v0.1.0\n\
4981 [COMPILING] a v0.1.0 ([..])\n\
4982 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]\n",
4983 )
4984 .run();
4985}
4986
4987#[cargo_test]
4988fn run_proper_binary() {
4989 let p = project()
4990 .file(
4991 "Cargo.toml",
4992 r#"
4993 [package]
4994 name = "foo"
4995 authors = []
4996 version = "0.0.0"
4997 [[bin]]
4998 name = "main"
4999 [[bin]]
5000 name = "other"
5001 "#,
5002 )
5003 .file("src/lib.rs", "")
5004 .file(
5005 "src/bin/main.rs",
5006 r#"fn main() { panic!("This should never be run."); }"#,
5007 )
5008 .file("src/bin/other.rs", "fn main() {}")
5009 .build();
5010
5011 p.cargo("run --bin other").run();
5012}
5013
5014#[cargo_test]
5015fn run_proper_binary_main_rs() {
5016 let p = project()
5017 .file("Cargo.toml", &basic_bin_manifest("foo"))
5018 .file("src/lib.rs", "")
5019 .file("src/bin/main.rs", "fn main() {}")
5020 .build();
5021
5022 p.cargo("run --bin foo").run();
5023}
5024
5025#[cargo_test]
5026fn run_proper_alias_binary_from_src() {
5027 let p = project()
5028 .file(
5029 "Cargo.toml",
5030 r#"
5031 [package]
5032 name = "foo"
5033 authors = []
5034 version = "0.0.0"
5035 [[bin]]
5036 name = "foo"
5037 [[bin]]
5038 name = "bar"
5039 "#,
5040 )
5041 .file("src/foo.rs", r#"fn main() { println!("foo"); }"#)
5042 .file("src/bar.rs", r#"fn main() { println!("bar"); }"#)
5043 .build();
5044
5045 p.cargo("build --workspace").run();
5046 p.process(&p.bin("foo")).with_stdout("foo\n").run();
5047 p.process(&p.bin("bar")).with_stdout("bar\n").run();
5048}
5049
5050#[cargo_test]
5051fn run_proper_alias_binary_main_rs() {
5052 let p = project()
5053 .file(
5054 "Cargo.toml",
5055 r#"
5056 [package]
5057 name = "foo"
5058 authors = []
5059 version = "0.0.0"
5060 [[bin]]
5061 name = "foo"
5062 [[bin]]
5063 name = "bar"
5064 "#,
5065 )
5066 .file("src/main.rs", r#"fn main() { println!("main"); }"#)
5067 .build();
5068
5069 p.cargo("build --workspace").run();
5070 p.process(&p.bin("foo")).with_stdout("main\n").run();
5071 p.process(&p.bin("bar")).with_stdout("main\n").run();
5072}
5073
5074#[cargo_test]
5075fn run_proper_binary_main_rs_as_foo() {
5076 let p = project()
5077 .file("Cargo.toml", &basic_bin_manifest("foo"))
5078 .file(
5079 "src/foo.rs",
5080 r#" fn main() { panic!("This should never be run."); }"#,
5081 )
5082 .file("src/main.rs", "fn main() {}")
5083 .build();
5084
5085 p.cargo("run --bin foo").run();
5086}
5087
5088#[cargo_test]
5089fn rustc_wrapper() {
5090 let p = project().file("src/lib.rs", "").build();
5091 let wrapper = tools::echo_wrapper();
5092 let running = format!(
5093 "[RUNNING] `{} rustc --crate-name foo [..]",
5094 wrapper.display()
5095 );
5096 p.cargo("build -v")
5097 .env("RUSTC_WRAPPER", &wrapper)
5098 .with_stderr_contains(&running)
5099 .run();
5100 p.build_dir().rm_rf();
5101 p.cargo("build -v")
5102 .env("RUSTC_WORKSPACE_WRAPPER", &wrapper)
5103 .with_stderr_contains(&running)
5104 .run();
5105}
5106
5107#[cargo_test]
5108fn rustc_wrapper_relative() {
5109 Package::new("bar", "1.0.0").publish();
5110 let p = project()
5111 .file(
5112 "Cargo.toml",
5113 r#"
5114 [package]
5115 name = "foo"
5116 version = "0.1.0"
5117
5118 [dependencies]
5119 bar = "1.0"
5120 "#,
5121 )
5122 .file("src/lib.rs", "")
5123 .build();
5124 let wrapper = tools::echo_wrapper();
5125 let exe_name = wrapper.file_name().unwrap().to_str().unwrap();
5126 let relative_path = format!("./{}", exe_name);
5127 fs::hard_link(&wrapper, p.root().join(exe_name)).unwrap();
5128 let running = format!("[RUNNING] `[ROOT]/foo/./{} rustc[..]", exe_name);
5129 p.cargo("build -v")
5130 .env("RUSTC_WRAPPER", &relative_path)
5131 .with_stderr_contains(&running)
5132 .run();
5133 p.build_dir().rm_rf();
5134 p.cargo("build -v")
5135 .env("RUSTC_WORKSPACE_WRAPPER", &relative_path)
5136 .with_stderr_contains(&running)
5137 .run();
5138 p.build_dir().rm_rf();
5139 p.change_file(
5140 ".cargo/config.toml",
5141 &format!(
5142 r#"
5143 build.rustc-wrapper = "./{}"
5144 "#,
5145 exe_name
5146 ),
5147 );
5148 p.cargo("build -v").with_stderr_contains(&running).run();
5149}
5150
5151#[cargo_test]
5152fn rustc_wrapper_from_path() {
5153 let p = project().file("src/lib.rs", "").build();
5154 p.cargo("build -v")
5155 .env("RUSTC_WRAPPER", "wannabe_sccache")
5156 .with_status(101)
5157 .with_stderr_contains("[..]`wannabe_sccache rustc [..]")
5158 .run();
5159 p.build_dir().rm_rf();
5160 p.cargo("build -v")
5161 .env("RUSTC_WORKSPACE_WRAPPER", "wannabe_sccache")
5162 .with_status(101)
5163 .with_stderr_contains("[..]`wannabe_sccache rustc [..]")
5164 .run();
5165}
5166
5167#[cargo_test]
5168fn cdylib_not_lifted() {
5169 let p = project()
5170 .file(
5171 "Cargo.toml",
5172 r#"
5173 [package]
5174 name = "foo"
5175 authors = []
5176 version = "0.1.0"
5177
5178 [lib]
5179 crate-type = ["cdylib"]
5180 "#,
5181 )
5182 .file("src/lib.rs", "")
5183 .build();
5184
5185 p.cargo("build").run();
5186
5187 let files = if cfg!(windows) {
5188 if cfg!(target_env = "msvc") {
5189 vec!["foo.dll.lib", "foo.dll.exp", "foo.dll"]
5190 } else {
5191 vec!["libfoo.dll.a", "foo.dll"]
5192 }
5193 } else if cfg!(target_os = "macos") {
5194 vec!["libfoo.dylib"]
5195 } else {
5196 vec!["libfoo.so"]
5197 };
5198
5199 for file in files {
5200 println!("checking: {}", file);
5201 assert!(p.root().join("target/debug/deps").join(&file).is_file());
5202 }
5203}
5204
5205#[cargo_test]
5206fn cdylib_final_outputs() {
5207 let p = project()
5208 .file(
5209 "Cargo.toml",
5210 r#"
5211 [package]
5212 name = "foo-bar"
5213 authors = []
5214 version = "0.1.0"
5215
5216 [lib]
5217 crate-type = ["cdylib"]
5218 "#,
5219 )
5220 .file("src/lib.rs", "")
5221 .build();
5222
5223 p.cargo("build").run();
5224
5225 let files = if cfg!(windows) {
5226 if cfg!(target_env = "msvc") {
5227 vec!["foo_bar.dll.lib", "foo_bar.dll"]
5228 } else {
5229 vec!["foo_bar.dll", "libfoo_bar.dll.a"]
5230 }
5231 } else if cfg!(target_os = "macos") {
5232 vec!["libfoo_bar.dylib"]
5233 } else {
5234 vec!["libfoo_bar.so"]
5235 };
5236
5237 for file in files {
5238 println!("checking: {}", file);
5239 assert!(p.root().join("target/debug").join(&file).is_file());
5240 }
5241}
5242
5243#[cargo_test]
5244// NOTE: Windows MSVC and wasm32-unknown-emscripten do not use metadata. Skip them.
5245// See <https://github.com/rust-lang/cargo/issues/9325#issuecomment-1030662699>
5246#[cfg(not(all(target_os = "windows", target_env = "msvc")))]
5247fn no_dep_info_collision_when_cdylib_and_bin_coexist() {
5248 let p = project()
5249 .file(
5250 "Cargo.toml",
5251 r#"
5252 [package]
5253 name = "foo"
5254 version = "1.0.0"
5255
5256 [lib]
5257 crate-type = ["cdylib"]
5258 "#,
5259 )
5260 .file("src/main.rs", "fn main() {}")
5261 .file("src/lib.rs", "")
5262 .build();
5263
5264 p.cargo("build -v")
5265 .with_stderr_unordered(
5266 "\
5267[COMPILING] foo v1.0.0 ([CWD])
5268[RUNNING] `rustc [..] --crate-type bin [..] -C metadata=[..]`
5269[RUNNING] `rustc [..] --crate-type cdylib [..] -C metadata=[..]`
5270[FINISHED] [..]
5271",
5272 )
5273 .run();
5274
5275 let deps_dir = p.target_debug_dir().join("deps");
5276 assert!(deps_dir.join("foo.d").exists());
5277 let dep_info_count = deps_dir
5278 .read_dir()
5279 .unwrap()
5280 .filter(|e| {
5281 let filename = e.as_ref().unwrap().file_name();
5282 let filename = filename.to_str().unwrap();
5283 filename.starts_with("foo") && filename.ends_with(".d")
5284 })
5285 .count();
5286 // cdylib -> foo.d
5287 // bin -> foo-<meta>.d
5288 assert_eq!(dep_info_count, 2);
5289}
5290
5291#[cargo_test]
5292fn deterministic_cfg_flags() {
5293 // This bug is non-deterministic.
5294
5295 let p = project()
5296 .file(
5297 "Cargo.toml",
5298 r#"
5299 [package]
5300 name = "foo"
5301 version = "0.1.0"
5302 authors = []
5303 build = "build.rs"
5304
5305 [features]
5306 default = ["f_a", "f_b", "f_c", "f_d"]
5307 f_a = []
5308 f_b = []
5309 f_c = []
5310 f_d = []
5311 "#,
5312 )
5313 .file(
5314 "build.rs",
5315 r#"
5316 fn main() {
5317 println!("cargo:rustc-cfg=cfg_a");
5318 println!("cargo:rustc-cfg=cfg_b");
5319 println!("cargo:rustc-cfg=cfg_c");
5320 println!("cargo:rustc-cfg=cfg_d");
5321 println!("cargo:rustc-cfg=cfg_e");
5322 }
5323 "#,
5324 )
5325 .file("src/main.rs", "fn main() {}")
5326 .build();
5327
5328 p.cargo("build -v")
5329 .with_stderr(
5330 "\
5331[COMPILING] foo v0.1.0 [..]
5332[RUNNING] [..]
5333[RUNNING] [..]
5334[RUNNING] `rustc --crate-name foo [..] \
5335--cfg[..]default[..]--cfg[..]f_a[..]--cfg[..]f_b[..]\
5336--cfg[..]f_c[..]--cfg[..]f_d[..] \
5337--cfg cfg_a --cfg cfg_b --cfg cfg_c --cfg cfg_d --cfg cfg_e`
5338[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
5339 )
5340 .run();
5341}
5342
5343#[cargo_test]
5344fn explicit_bins_without_paths() {
5345 let p = project()
5346 .file(
5347 "Cargo.toml",
5348 r#"
5349 [package]
5350 name = "foo"
5351 version = "0.1.0"
5352 authors = []
5353
5354 [[bin]]
5355 name = "foo"
5356
5357 [[bin]]
5358 name = "bar"
5359 "#,
5360 )
5361 .file("src/lib.rs", "")
5362 .file("src/main.rs", "fn main() {}")
5363 .file("src/bin/bar.rs", "fn main() {}")
5364 .build();
5365
5366 p.cargo("build").run();
5367}
5368
5369#[cargo_test]
5370fn no_bin_in_src_with_lib() {
5371 let p = project()
5372 .file("Cargo.toml", &basic_bin_manifest("foo"))
5373 .file("src/lib.rs", "")
5374 .file("src/foo.rs", "fn main() {}")
5375 .build();
5376
5377 p.cargo("build")
5378 .with_status(101)
5379 .with_stderr_contains(
5380 "\
5381[ERROR] failed to parse manifest at `[..]`
5382
5383Caused by:
5384 can't find `foo` bin at `src/bin/foo.rs` or `src/bin/foo/main.rs`. [..]",
5385 )
5386 .run();
5387}
5388
5389#[cargo_test]
5390fn inferred_bins() {
5391 let p = project()
5392 .file("src/main.rs", "fn main() {}")
5393 .file("src/bin/bar.rs", "fn main() {}")
5394 .file("src/bin/baz/main.rs", "fn main() {}")
5395 .build();
5396
5397 p.cargo("build").run();
5398 assert!(p.bin("foo").is_file());
5399 assert!(p.bin("bar").is_file());
5400 assert!(p.bin("baz").is_file());
5401}
5402
5403#[cargo_test]
5404fn inferred_bins_duplicate_name() {
5405 // this should fail, because we have two binaries with the same name
5406 let p = project()
5407 .file("src/main.rs", "fn main() {}")
5408 .file("src/bin/bar.rs", "fn main() {}")
5409 .file("src/bin/bar/main.rs", "fn main() {}")
5410 .build();
5411
5412 p.cargo("build").with_status(101).with_stderr_contains(
5413 "[..]found duplicate binary name bar, but all binary targets must have a unique name[..]",
5414 )
5415 .run();
5416}
5417
5418#[cargo_test]
5419fn inferred_bin_path() {
5420 let p = project()
5421 .file(
5422 "Cargo.toml",
5423 r#"
5424 [package]
5425 name = "foo"
5426 version = "0.1.0"
5427 authors = []
5428
5429 [[bin]]
5430 name = "bar"
5431 # Note, no `path` key!
5432 "#,
5433 )
5434 .file("src/bin/bar/main.rs", "fn main() {}")
5435 .build();
5436
5437 p.cargo("build").run();
5438 assert!(p.bin("bar").is_file());
5439}
5440
5441#[cargo_test]
5442fn inferred_examples() {
5443 let p = project()
5444 .file("src/lib.rs", "fn main() {}")
5445 .file("examples/bar.rs", "fn main() {}")
5446 .file("examples/baz/main.rs", "fn main() {}")
5447 .build();
5448
5449 p.cargo("build --examples").run();
5450 assert!(p.bin("examples/bar").is_file());
5451 assert!(p.bin("examples/baz").is_file());
5452}
5453
5454#[cargo_test]
5455fn inferred_tests() {
5456 let p = project()
5457 .file("src/lib.rs", "fn main() {}")
5458 .file("tests/bar.rs", "fn main() {}")
5459 .file("tests/baz/main.rs", "fn main() {}")
5460 .build();
5461
5462 p.cargo("test --test=bar --test=baz").run();
5463}
5464
5465#[cargo_test]
5466fn inferred_benchmarks() {
5467 let p = project()
5468 .file("src/lib.rs", "fn main() {}")
5469 .file("benches/bar.rs", "fn main() {}")
5470 .file("benches/baz/main.rs", "fn main() {}")
5471 .build();
5472
5473 p.cargo("bench --bench=bar --bench=baz").run();
5474}
5475
5476#[cargo_test]
5477fn no_infer_dirs() {
5478 let p = project()
5479 .file("src/lib.rs", "fn main() {}")
5480 .file("examples/dir.rs/dummy", "")
5481 .file("benches/dir.rs/dummy", "")
5482 .file("tests/dir.rs/dummy", "")
5483 .build();
5484
5485 p.cargo("build --examples --benches --tests").run(); // should not fail with "is a directory"
5486}
5487
5488#[cargo_test]
5489fn target_edition() {
5490 let p = project()
5491 .file(
5492 "Cargo.toml",
5493 r#"
5494 [package]
5495 name = "foo"
5496 version = "0.0.1"
5497
5498 [lib]
5499 edition = "2018"
5500 "#,
5501 )
5502 .file("src/lib.rs", "")
5503 .build();
5504
5505 p.cargo("build -v")
5506 .with_stderr_contains(
5507 "\
5508[COMPILING] foo v0.0.1 ([..])
5509[RUNNING] `rustc [..]--edition=2018 [..]
5510",
5511 )
5512 .run();
5513}
5514
5515#[cargo_test]
5516fn target_edition_override() {
5517 let p = project()
5518 .file(
5519 "Cargo.toml",
5520 r#"
5521 [package]
5522 name = "foo"
5523 version = "0.0.1"
5524 authors = []
5525 edition = "2018"
5526
5527 [lib]
5528 edition = "2015"
5529 "#,
5530 )
5531 .file(
5532 "src/lib.rs",
5533 "
5534 pub fn async() {}
5535 pub fn try() {}
5536 pub fn await() {}
5537 ",
5538 )
5539 .build();
5540
5541 p.cargo("build -v").run();
5542}
5543
5544#[cargo_test]
5545fn same_metadata_different_directory() {
5546 // A top-level crate built in two different workspaces should have the
5547 // same metadata hash.
5548 let p = project()
5549 .at("foo1")
5550 .file("Cargo.toml", &basic_bin_manifest("foo"))
5551 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
5552 .build();
5553 let output = t!(String::from_utf8(
5554 t!(p.cargo("build -v").exec_with_output()).stderr,
5555 ));
5556 let metadata = output
5557 .split_whitespace()
5558 .find(|arg| arg.starts_with("metadata="))
5559 .unwrap();
5560
5561 let p = project()
5562 .at("foo2")
5563 .file("Cargo.toml", &basic_bin_manifest("foo"))
5564 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
5565 .build();
5566
5567 p.cargo("build -v")
5568 .with_stderr_contains(format!("[..]{}[..]", metadata))
5569 .run();
5570}
5571
5572#[cargo_test]
5573fn building_a_dependent_crate_without_bin_should_fail() {
5574 Package::new("testless", "0.1.0")
5575 .file(
5576 "Cargo.toml",
5577 r#"
5578 [package]
5579 name = "testless"
5580 version = "0.1.0"
5581
5582 [[bin]]
5583 name = "a_bin"
5584 "#,
5585 )
5586 .file("src/lib.rs", "")
5587 .publish();
5588
5589 let p = project()
5590 .file(
5591 "Cargo.toml",
5592 r#"
5593 [package]
5594 name = "foo"
5595 version = "0.1.0"
5596
5597 [dependencies]
5598 testless = "0.1.0"
5599 "#,
5600 )
5601 .file("src/lib.rs", "")
5602 .build();
5603
5604 p.cargo("build")
5605 .with_status(101)
5606 .with_stderr_contains(
5607 "[..]can't find `a_bin` bin at `src/bin/a_bin.rs` or `src/bin/a_bin/main.rs`[..]",
5608 )
5609 .run();
5610}
5611
5612#[cargo_test]
5613#[cfg(any(target_os = "macos", target_os = "ios"))]
5614fn uplift_dsym_of_bin_on_mac() {
5615 let p = project()
5616 .file("src/main.rs", "fn main() { panic!(); }")
5617 .file("src/bin/b.rs", "fn main() { panic!(); }")
5618 .file("examples/c.rs", "fn main() { panic!(); }")
5619 .file("tests/d.rs", "fn main() { panic!(); }")
5620 .build();
5621
5622 p.cargo("build --bins --examples --tests")
5623 .enable_mac_dsym()
5624 .run();
5625 assert!(p.target_debug_dir().join("foo.dSYM").is_dir());
5626 assert!(p.target_debug_dir().join("b.dSYM").is_dir());
5627 assert!(p.target_debug_dir().join("b.dSYM").is_symlink());
5628 assert!(p.target_debug_dir().join("examples/c.dSYM").is_dir());
5629 assert!(!p.target_debug_dir().join("c.dSYM").exists());
5630 assert!(!p.target_debug_dir().join("d.dSYM").exists());
5631}
5632
5633#[cargo_test]
5634#[cfg(any(target_os = "macos", target_os = "ios"))]
5635fn uplift_dsym_of_bin_on_mac_when_broken_link_exists() {
5636 let p = project()
5637 .file("src/main.rs", "fn main() { panic!(); }")
5638 .build();
5639 let dsym = p.target_debug_dir().join("foo.dSYM");
5640
5641 p.cargo("build").enable_mac_dsym().run();
5642 assert!(dsym.is_dir());
5643
5644 // Simulate the situation where the underlying dSYM bundle goes missing
5645 // but the uplifted symlink to it remains. This would previously cause
5646 // builds to permanently fail until the bad symlink was manually removed.
5647 dsym.rm_rf();
5648 p.symlink(
5649 p.target_debug_dir()
5650 .join("deps")
5651 .join("foo-baaaaaadbaaaaaad.dSYM"),
5652 &dsym,
5653 );
5654 assert!(dsym.is_symlink());
5655 assert!(!dsym.exists());
5656
5657 p.cargo("build").enable_mac_dsym().run();
5658 assert!(dsym.is_dir());
5659}
5660
5661#[cargo_test]
5662#[cfg(all(target_os = "windows", target_env = "msvc"))]
5663fn uplift_pdb_of_bin_on_windows() {
5664 let p = project()
5665 .file("src/main.rs", "fn main() { panic!(); }")
5666 .file("src/bin/b.rs", "fn main() { panic!(); }")
5667 .file("src/bin/foo-bar.rs", "fn main() { panic!(); }")
5668 .file("examples/c.rs", "fn main() { panic!(); }")
5669 .file("tests/d.rs", "fn main() { panic!(); }")
5670 .build();
5671
5672 p.cargo("build --bins --examples --tests").run();
5673 assert!(p.target_debug_dir().join("foo.pdb").is_file());
5674 assert!(p.target_debug_dir().join("b.pdb").is_file());
5675 assert!(p.target_debug_dir().join("examples/c.pdb").exists());
5676 assert!(p.target_debug_dir().join("foo-bar.exe").is_file());
5677 assert!(p.target_debug_dir().join("foo_bar.pdb").is_file());
5678 assert!(!p.target_debug_dir().join("c.pdb").exists());
5679 assert!(!p.target_debug_dir().join("d.pdb").exists());
5680}
5681
5682#[cargo_test]
5683#[cfg(target_os = "linux")]
5684fn uplift_dwp_of_bin_on_linux() {
5685 let p = project()
5686 .file("src/main.rs", "fn main() { panic!(); }")
5687 .file("src/bin/b.rs", "fn main() { panic!(); }")
5688 .file("src/bin/foo-bar.rs", "fn main() { panic!(); }")
5689 .file("examples/c.rs", "fn main() { panic!(); }")
5690 .file("tests/d.rs", "fn main() { panic!(); }")
5691 .build();
5692
5693 p.cargo("build --bins --examples --tests")
5694 .enable_split_debuginfo_packed()
5695 .run();
5696 assert!(p.target_debug_dir().join("foo.dwp").is_file());
5697 assert!(p.target_debug_dir().join("b.dwp").is_file());
5698 assert!(p.target_debug_dir().join("examples/c.dwp").exists());
5699 assert!(p.target_debug_dir().join("foo-bar").is_file());
5700 assert!(p.target_debug_dir().join("foo-bar.dwp").is_file());
5701 assert!(!p.target_debug_dir().join("c.dwp").exists());
5702 assert!(!p.target_debug_dir().join("d.dwp").exists());
5703}
5704
5705// Ensure that `cargo build` chooses the correct profile for building
5706// targets based on filters (assuming `--profile` is not specified).
5707#[cargo_test]
5708fn build_filter_infer_profile() {
5709 let p = project()
5710 .file("src/lib.rs", "")
5711 .file("src/main.rs", "fn main() {}")
5712 .file("tests/t1.rs", "")
5713 .file("benches/b1.rs", "")
5714 .file("examples/ex1.rs", "fn main() {}")
5715 .build();
5716
5717 p.cargo("build -v")
5718 .with_stderr_contains(
5719 "[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
5720 --emit=[..]link[..]",
5721 )
5722 .with_stderr_contains(
5723 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
5724 --emit=[..]link[..]",
5725 )
5726 .run();
5727
5728 p.root().join("target").rm_rf();
5729 p.cargo("build -v --test=t1")
5730 .with_stderr_contains(
5731 "[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
5732 --emit=[..]link[..]-C debuginfo=2 [..]",
5733 )
5734 .with_stderr_contains(
5735 "[RUNNING] `rustc --crate-name t1 tests/t1.rs [..]--emit=[..]link[..]\
5736 -C debuginfo=2 [..]",
5737 )
5738 .with_stderr_contains(
5739 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
5740 --emit=[..]link[..]-C debuginfo=2 [..]",
5741 )
5742 .run();
5743
5744 p.root().join("target").rm_rf();
5745 // Bench uses test profile without `--release`.
5746 p.cargo("build -v --bench=b1")
5747 .with_stderr_contains(
5748 "[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
5749 --emit=[..]link[..]-C debuginfo=2 [..]",
5750 )
5751 .with_stderr_contains(
5752 "[RUNNING] `rustc --crate-name b1 benches/b1.rs [..]--emit=[..]link[..]\
5753 -C debuginfo=2 [..]",
5754 )
5755 .with_stderr_does_not_contain("opt-level")
5756 .with_stderr_contains(
5757 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
5758 --emit=[..]link[..]-C debuginfo=2 [..]",
5759 )
5760 .run();
5761}
5762
5763#[cargo_test]
5764fn targets_selected_default() {
5765 let p = project().file("src/main.rs", "fn main() {}").build();
5766 p.cargo("build -v")
5767 // Binaries.
5768 .with_stderr_contains(
5769 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
5770 --emit=[..]link[..]",
5771 )
5772 // Benchmarks.
5773 .with_stderr_does_not_contain(
5774 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link \
5775 -C opt-level=3 --test [..]",
5776 )
5777 // Unit tests.
5778 .with_stderr_does_not_contain(
5779 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link[..]\
5780 -C debuginfo=2 --test [..]",
5781 )
5782 .run();
5783}
5784
5785#[cargo_test]
5786fn targets_selected_all() {
5787 let p = project().file("src/main.rs", "fn main() {}").build();
5788 p.cargo("build -v --all-targets")
5789 // Binaries.
5790 .with_stderr_contains(
5791 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
5792 --emit=[..]link[..]",
5793 )
5794 // Unit tests.
5795 .with_stderr_contains(
5796 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link[..]\
fe692bf9 5797 -C debuginfo=2 [..]--test [..]",
0a29b90c
FG
5798 )
5799 .run();
5800}
5801
5802#[cargo_test]
5803fn all_targets_no_lib() {
5804 let p = project().file("src/main.rs", "fn main() {}").build();
5805 p.cargo("build -v --all-targets")
5806 // Binaries.
5807 .with_stderr_contains(
5808 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--crate-type bin \
5809 --emit=[..]link[..]",
5810 )
5811 // Unit tests.
5812 .with_stderr_contains(
5813 "[RUNNING] `rustc --crate-name foo src/main.rs [..]--emit=[..]link[..]\
fe692bf9 5814 -C debuginfo=2 [..]--test [..]",
0a29b90c
FG
5815 )
5816 .run();
5817}
5818
5819#[cargo_test]
5820fn no_linkable_target() {
5821 // Issue 3169: this is currently not an error as per discussion in PR #4797.
5822 let p = project()
5823 .file(
5824 "Cargo.toml",
5825 r#"
5826 [package]
5827 name = "foo"
5828 version = "0.1.0"
5829 authors = []
5830 [dependencies]
5831 the_lib = { path = "the_lib" }
5832 "#,
5833 )
5834 .file("src/main.rs", "fn main() {}")
5835 .file(
5836 "the_lib/Cargo.toml",
5837 r#"
5838 [package]
5839 name = "the_lib"
5840 version = "0.1.0"
5841 [lib]
5842 name = "the_lib"
5843 crate-type = ["staticlib"]
5844 "#,
5845 )
5846 .file("the_lib/src/lib.rs", "pub fn foo() {}")
5847 .build();
5848 p.cargo("build")
5849 .with_stderr_contains(
5850 "[WARNING] The package `the_lib` provides no linkable [..] \
5851 while compiling `foo`. [..] in `the_lib`'s Cargo.toml. [..]",
5852 )
5853 .run();
5854}
5855
5856#[cargo_test]
5857fn avoid_dev_deps() {
5858 Package::new("foo", "1.0.0").publish();
5859 let p = project()
5860 .file(
5861 "Cargo.toml",
5862 r#"
5863 [package]
5864 name = "bar"
5865 version = "0.1.0"
5866 authors = []
5867
5868 [dev-dependencies]
5869 baz = "1.0.0"
5870 "#,
5871 )
5872 .file("src/main.rs", "fn main() {}")
5873 .build();
5874
5875 p.cargo("build")
5876 .with_status(101)
5877 .with_stderr(
5878 "\
5879[UPDATING] [..]
5880[ERROR] no matching package named `baz` found
5881location searched: registry `crates-io`
5882required by package `bar v0.1.0 ([..]/foo)`
5883",
5884 )
5885 .run();
5886 p.cargo("build -Zavoid-dev-deps")
5887 .masquerade_as_nightly_cargo(&["avoid-dev-deps"])
5888 .run();
5889}
5890
5891#[cargo_test]
5892fn default_cargo_config_jobs() {
5893 let p = project()
5894 .file("src/lib.rs", "")
5895 .file(
5896 ".cargo/config",
5897 r#"
5898 [build]
5899 jobs = 1
5900 "#,
5901 )
5902 .build();
5903 p.cargo("build -v").run();
5904}
5905
5906#[cargo_test]
5907fn good_cargo_config_jobs() {
5908 let p = project()
5909 .file("src/lib.rs", "")
5910 .file(
5911 ".cargo/config",
5912 r#"
5913 [build]
5914 jobs = 4
5915 "#,
5916 )
5917 .build();
5918 p.cargo("build -v").run();
5919}
5920
5921#[cargo_test]
5922fn good_jobs() {
5923 let p = project()
5924 .file("Cargo.toml", &basic_bin_manifest("foo"))
5925 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
5926 .build();
5927
5928 p.cargo("build --jobs 1").run();
5929
5930 p.cargo("build --jobs -1").run();
fe692bf9
FG
5931
5932 p.cargo("build --jobs default").run();
0a29b90c
FG
5933}
5934
5935#[cargo_test]
5936fn invalid_cargo_config_jobs() {
5937 let p = project()
5938 .file("src/lib.rs", "")
5939 .file(
5940 ".cargo/config",
5941 r#"
5942 [build]
5943 jobs = 0
5944 "#,
5945 )
5946 .build();
5947 p.cargo("build -v")
5948 .with_status(101)
5949 .with_stderr_contains("error: jobs may not be 0")
5950 .run();
5951}
5952
5953#[cargo_test]
5954fn invalid_jobs() {
5955 let p = project()
5956 .file("Cargo.toml", &basic_bin_manifest("foo"))
5957 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
5958 .build();
5959
5960 p.cargo("build --jobs 0")
5961 .with_status(101)
5962 .with_stderr_contains("error: jobs may not be 0")
5963 .run();
5964
5965 p.cargo("build --jobs over9000")
fe692bf9
FG
5966 .with_status(101)
5967 .with_stderr("error: could not parse `over9000`. Number of parallel jobs should be `default` or a number.")
0a29b90c
FG
5968 .run();
5969}
5970
5971#[cargo_test]
5972fn target_filters_workspace() {
5973 let ws = project()
5974 .at("ws")
5975 .file(
5976 "Cargo.toml",
5977 r#"
5978 [workspace]
5979 members = ["a", "b"]
5980 "#,
5981 )
5982 .file("a/Cargo.toml", &basic_lib_manifest("a"))
5983 .file("a/src/lib.rs", "")
5984 .file("a/examples/ex1.rs", "fn main() {}")
5985 .file("b/Cargo.toml", &basic_bin_manifest("b"))
5986 .file("b/src/lib.rs", "")
5987 .file("b/src/main.rs", "fn main() {}")
5988 .build();
5989
5990 ws.cargo("build -v --example ex")
5991 .with_status(101)
5992 .with_stderr(
5993 "\
5994[ERROR] no example target named `ex`
5995
5996<tab>Did you mean `ex1`?",
5997 )
5998 .run();
5999
6000 ws.cargo("build -v --example 'ex??'")
6001 .with_status(101)
6002 .with_stderr(
6003 "\
6004[ERROR] no example target matches pattern `ex??`
6005
6006<tab>Did you mean `ex1`?",
6007 )
6008 .run();
6009
6010 ws.cargo("build -v --lib")
6011 .with_stderr_contains("[RUNNING] `rustc [..]a/src/lib.rs[..]")
6012 .with_stderr_contains("[RUNNING] `rustc [..]b/src/lib.rs[..]")
6013 .run();
6014
6015 ws.cargo("build -v --example ex1")
6016 .with_stderr_contains("[RUNNING] `rustc [..]a/examples/ex1.rs[..]")
6017 .run();
6018}
6019
6020#[cargo_test]
6021fn target_filters_workspace_not_found() {
6022 let ws = project()
6023 .at("ws")
6024 .file(
6025 "Cargo.toml",
6026 r#"
6027 [workspace]
6028 members = ["a", "b"]
6029 "#,
6030 )
6031 .file("a/Cargo.toml", &basic_bin_manifest("a"))
6032 .file("a/src/main.rs", "fn main() {}")
6033 .file("b/Cargo.toml", &basic_bin_manifest("b"))
6034 .file("b/src/main.rs", "fn main() {}")
6035 .build();
6036
6037 ws.cargo("build -v --lib")
6038 .with_status(101)
6039 .with_stderr("[ERROR] no library targets found in packages: a, b")
6040 .run();
6041}
6042
6043#[cfg(unix)]
6044#[cargo_test]
6045fn signal_display() {
6046 // Cause the compiler to crash with a signal.
6047 let foo = project()
6048 .file(
6049 "Cargo.toml",
6050 r#"
6051 [package]
6052 name = "foo"
6053 version = "0.1.0"
6054 [dependencies]
6055 pm = { path = "pm" }
6056 "#,
6057 )
6058 .file(
6059 "src/lib.rs",
6060 r#"
6061 #[macro_use]
6062 extern crate pm;
6063
6064 #[derive(Foo)]
6065 pub struct S;
6066 "#,
6067 )
6068 .file(
6069 "pm/Cargo.toml",
6070 r#"
6071 [package]
6072 name = "pm"
6073 version = "0.1.0"
6074 [lib]
6075 proc-macro = true
6076 "#,
6077 )
6078 .file(
6079 "pm/src/lib.rs",
6080 r#"
6081 extern crate proc_macro;
6082 use proc_macro::TokenStream;
6083
6084 #[proc_macro_derive(Foo)]
6085 pub fn derive(_input: TokenStream) -> TokenStream {
6086 std::process::abort()
6087 }
6088 "#,
6089 )
6090 .build();
6091
6092 foo.cargo("build")
6093 .with_stderr(
6094 "\
6095[COMPILING] pm [..]
6096[COMPILING] foo [..]
6097[ERROR] could not compile `foo` [..]
6098
6099Caused by:
6100 process didn't exit successfully: `rustc [..]` (signal: 6, SIGABRT: process abort signal)
6101",
6102 )
6103 .with_status(101)
6104 .run();
6105}
6106
6107#[cargo_test]
6108fn tricky_pipelining() {
6109 let foo = project()
6110 .file(
6111 "Cargo.toml",
6112 r#"
6113 [package]
6114 name = "foo"
6115 version = "0.1.0"
6116 [dependencies]
6117 bar = { path = "bar" }
6118 "#,
6119 )
6120 .file("src/lib.rs", "extern crate bar;")
6121 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
6122 .file("bar/src/lib.rs", "")
6123 .build();
6124
6125 foo.cargo("build -p bar").run();
6126 foo.cargo("build -p foo").run();
6127}
6128
6129#[cargo_test]
6130fn pipelining_works() {
6131 let foo = project()
6132 .file(
6133 "Cargo.toml",
6134 r#"
6135 [package]
6136 name = "foo"
6137 version = "0.1.0"
6138 [dependencies]
6139 bar = { path = "bar" }
6140 "#,
6141 )
6142 .file("src/lib.rs", "extern crate bar;")
6143 .file("bar/Cargo.toml", &basic_lib_manifest("bar"))
6144 .file("bar/src/lib.rs", "")
6145 .build();
6146
6147 foo.cargo("build")
6148 .with_stdout("")
6149 .with_stderr(
6150 "\
6151[COMPILING] [..]
6152[COMPILING] [..]
6153[FINISHED] [..]
6154",
6155 )
6156 .run();
6157}
6158
6159#[cargo_test]
6160fn pipelining_big_graph() {
6161 // Create a crate graph of the form {a,b}{0..29}, where {a,b}(n) depend on {a,b}(n+1)
6162 // Then have `foo`, a binary crate, depend on the whole thing.
6163 let mut project = project()
6164 .file(
6165 "Cargo.toml",
6166 r#"
6167 [package]
6168 name = "foo"
6169 version = "0.1.0"
6170 [dependencies]
6171 a1 = { path = "a1" }
6172 b1 = { path = "b1" }
6173 "#,
6174 )
6175 .file("src/main.rs", "fn main(){}");
6176
6177 for n in 0..30 {
6178 for x in &["a", "b"] {
6179 project = project
6180 .file(
6181 &format!("{x}{n}/Cargo.toml", x = x, n = n),
6182 &format!(
6183 r#"
6184 [package]
6185 name = "{x}{n}"
6186 version = "0.1.0"
6187 [dependencies]
6188 a{np1} = {{ path = "../a{np1}" }}
6189 b{np1} = {{ path = "../b{np1}" }}
6190 "#,
6191 x = x,
6192 n = n,
6193 np1 = n + 1
6194 ),
6195 )
6196 .file(&format!("{x}{n}/src/lib.rs", x = x, n = n), "");
6197 }
6198 }
6199
6200 let foo = project
6201 .file("a30/Cargo.toml", &basic_lib_manifest("a30"))
6202 .file(
6203 "a30/src/lib.rs",
6204 r#"compile_error!("don't actually build me");"#,
6205 )
6206 .file("b30/Cargo.toml", &basic_lib_manifest("b30"))
6207 .file("b30/src/lib.rs", "")
6208 .build();
6209 foo.cargo("build -p foo")
6210 .with_status(101)
6211 .with_stderr_contains("[ERROR] could not compile `a30`[..]")
6212 .run();
6213}
6214
6215#[cargo_test]
6216fn forward_rustc_output() {
6217 let foo = project()
6218 .file(
6219 "Cargo.toml",
6220 r#"
6221 [package]
6222 name = "foo"
6223 version = "0.1.0"
6224 edition = '2018'
6225 [dependencies]
6226 bar = { path = "bar" }
6227 "#,
6228 )
6229 .file("src/lib.rs", "bar::foo!();")
6230 .file(
6231 "bar/Cargo.toml",
6232 r#"
6233 [package]
6234 name = "bar"
6235 version = "0.1.0"
6236 [lib]
6237 proc-macro = true
6238 "#,
6239 )
6240 .file(
6241 "bar/src/lib.rs",
6242 r#"
6243 extern crate proc_macro;
6244 use proc_macro::*;
6245
6246 #[proc_macro]
6247 pub fn foo(input: TokenStream) -> TokenStream {
6248 println!("a");
6249 println!("b");
6250 println!("{{}}");
6251 eprintln!("c");
6252 eprintln!("d");
6253 eprintln!("{{a"); // "malformed json"
6254 input
6255 }
6256 "#,
6257 )
6258 .build();
6259
6260 foo.cargo("build")
6261 .with_stdout("a\nb\n{}")
6262 .with_stderr(
6263 "\
6264[COMPILING] [..]
6265[COMPILING] [..]
6266c
6267d
6268{a
6269[FINISHED] [..]
6270",
6271 )
6272 .run();
6273}
6274
6275#[cargo_test]
6276fn build_lib_only() {
6277 let p = project()
6278 .file("src/main.rs", "fn main() {}")
6279 .file("src/lib.rs", r#" "#)
6280 .build();
6281
6282 p.cargo("build --lib -v")
6283 .with_stderr(
6284 "\
6285[COMPILING] foo v0.0.1 ([CWD])
6286[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib \
fe692bf9 6287 --emit=[..]link[..]-C debuginfo=2 [..]\
0a29b90c
FG
6288 -C metadata=[..] \
6289 --out-dir [..] \
6290 -L dependency=[CWD]/target/debug/deps`
6291[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]",
6292 )
6293 .run();
6294}
6295
6296#[cargo_test]
6297fn build_with_no_lib() {
6298 let p = project()
6299 .file("Cargo.toml", &basic_bin_manifest("foo"))
6300 .file("src/main.rs", "fn main() {}")
6301 .build();
6302
6303 p.cargo("build --lib")
6304 .with_status(101)
6305 .with_stderr("[ERROR] no library targets found in package `foo`")
6306 .run();
6307}
6308
6309#[cargo_test]
6310fn build_with_relative_cargo_home_path() {
6311 let p = project()
6312 .file(
6313 "Cargo.toml",
6314 r#"
6315 [package]
6316
6317 name = "foo"
6318 version = "0.0.1"
6319 authors = ["wycats@example.com"]
6320
6321 [dependencies]
6322
6323 "test-dependency" = { path = "src/test_dependency" }
6324 "#,
6325 )
6326 .file("src/main.rs", "fn main() {}")
6327 .file("src/test_dependency/src/lib.rs", r#" "#)
6328 .file(
6329 "src/test_dependency/Cargo.toml",
6330 &basic_manifest("test-dependency", "0.0.1"),
6331 )
6332 .build();
6333
6334 p.cargo("build").env("CARGO_HOME", "./cargo_home/").run();
6335}
6336
6337#[cargo_test]
6338fn user_specific_cfgs_are_filtered_out() {
6339 let p = project()
6340 .file("Cargo.toml", &basic_bin_manifest("foo"))
6341 .file("src/main.rs", r#"fn main() {}"#)
6342 .file(
6343 "build.rs",
6344 r#"
6345 fn main() {
6346 assert!(std::env::var_os("CARGO_CFG_PROC_MACRO").is_none());
6347 assert!(std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_none());
6348 }
6349 "#,
6350 )
6351 .build();
6352
6353 p.cargo("rustc -- --cfg debug_assertions --cfg proc_macro")
6354 .run();
6355 p.process(&p.bin("foo")).run();
6356}
6357
6358#[cargo_test]
6359fn close_output() {
6360 // What happens when stdout or stderr is closed during a build.
6361
6362 // Server to know when rustc has spawned.
6363 let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
6364 let addr = listener.local_addr().unwrap();
6365
6366 let p = project()
6367 .file(
6368 "Cargo.toml",
6369 r#"
6370 [package]
6371 name = "foo"
6372 version = "0.1.0"
6373 edition = "2018"
6374
6375 [lib]
6376 proc-macro = true
6377
6378 [[bin]]
6379 name = "foobar"
6380 "#,
6381 )
6382 .file(
6383 "src/lib.rs",
6384 &r#"
6385 use proc_macro::TokenStream;
6386 use std::io::Read;
6387
6388 #[proc_macro]
6389 pub fn repro(_input: TokenStream) -> TokenStream {
6390 println!("hello stdout!");
6391 eprintln!("hello stderr!");
6392 // Tell the test we have started.
6393 let mut socket = std::net::TcpStream::connect("__ADDR__").unwrap();
6394 // Wait for the test to tell us to start printing.
6395 let mut buf = [0];
6396 drop(socket.read_exact(&mut buf));
6397 let use_stderr = std::env::var("__CARGO_REPRO_STDERR").is_ok();
6398 // Emit at least 1MB of data.
6399 // Linux pipes can buffer up to 64KB.
6400 // This test seems to be sensitive to having other threads
6401 // calling fork. My hypothesis is that the stdout/stderr
6402 // file descriptors are duplicated into the child process,
6403 // and during the short window between fork and exec, the
6404 // file descriptor is kept alive long enough for the
6405 // build to finish. It's a half-baked theory, but this
6406 // seems to prevent the spurious errors in CI.
6407 // An alternative solution is to run this test in
6408 // a single-threaded environment.
6409 for i in 0..100000 {
6410 if use_stderr {
6411 eprintln!("0123456789{}", i);
6412 } else {
6413 println!("0123456789{}", i);
6414 }
6415 }
6416 TokenStream::new()
6417 }
6418 "#
6419 .replace("__ADDR__", &addr.to_string()),
6420 )
6421 .file(
6422 "src/bin/foobar.rs",
6423 r#"
6424 foo::repro!();
6425
6426 fn main() {}
6427 "#,
6428 )
6429 .build();
6430
6431 // The `stderr` flag here indicates if this should forcefully close stderr or stdout.
6432 let spawn = |stderr: bool| {
6433 let mut cmd = p.cargo("build").build_command();
6434 cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
6435 if stderr {
6436 cmd.env("__CARGO_REPRO_STDERR", "1");
6437 }
6438 let mut child = cmd.spawn().unwrap();
6439 // Wait for proc macro to start.
6440 let pm_conn = listener.accept().unwrap().0;
6441 // Close stderr or stdout.
6442 if stderr {
6443 drop(child.stderr.take());
6444 } else {
6445 drop(child.stdout.take());
6446 }
6447 // Tell the proc-macro to continue;
6448 drop(pm_conn);
6449 // Read the output from the other channel.
6450 let out: &mut dyn Read = if stderr {
6451 child.stdout.as_mut().unwrap()
6452 } else {
6453 child.stderr.as_mut().unwrap()
6454 };
6455 let mut result = String::new();
6456 out.read_to_string(&mut result).unwrap();
6457 let status = child.wait().unwrap();
6458 assert!(!status.success());
6459 result
6460 };
6461
6462 let stderr = spawn(false);
6463 compare::match_unordered(
6464 "\
6465[COMPILING] foo [..]
6466hello stderr!
6467[ERROR] [..]
6468[WARNING] build failed, waiting for other jobs to finish...
6469",
6470 &stderr,
6471 None,
6472 )
6473 .unwrap();
6474
6475 // Try again with stderr.
6476 p.build_dir().rm_rf();
6477 let stdout = spawn(true);
6478 assert_eq!(stdout, "hello stdout!\n");
6479}
6480
6481#[cargo_test]
6482fn close_output_during_drain() {
6483 // Test to close the output during the build phase (drain_the_queue).
6484 // There was a bug where it would hang.
6485
6486 // Server to know when rustc has spawned.
6487 let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
6488 let addr = listener.local_addr().unwrap();
6489
6490 // Create a wrapper so the test can know when compiling has started.
6491 let rustc_wrapper = {
6492 let p = project()
6493 .at("compiler")
6494 .file("Cargo.toml", &basic_manifest("compiler", "1.0.0"))
6495 .file(
6496 "src/main.rs",
6497 &r#"
6498 use std::process::Command;
6499 use std::env;
6500 use std::io::Read;
6501
6502 fn main() {
6503 // Only wait on the first dependency.
6504 if matches!(env::var("CARGO_PKG_NAME").as_deref(), Ok("dep")) {
6505 let mut socket = std::net::TcpStream::connect("__ADDR__").unwrap();
6506 // Wait for the test to tell us to start printing.
6507 let mut buf = [0];
6508 drop(socket.read_exact(&mut buf));
6509 }
6510 let mut cmd = Command::new("rustc");
6511 for arg in env::args_os().skip(1) {
6512 cmd.arg(arg);
6513 }
6514 std::process::exit(cmd.status().unwrap().code().unwrap());
6515 }
6516 "#
6517 .replace("__ADDR__", &addr.to_string()),
6518 )
6519 .build();
6520 p.cargo("build").run();
6521 p.bin("compiler")
6522 };
6523
6524 Package::new("dep", "1.0.0").publish();
6525 let p = project()
6526 .file(
6527 "Cargo.toml",
6528 r#"
6529 [package]
6530 name = "foo"
6531 version = "0.1.0"
6532
6533 [dependencies]
6534 dep = "1.0"
6535 "#,
6536 )
6537 .file("src/lib.rs", "")
6538 .build();
6539
6540 // Spawn cargo, wait for the first rustc to start, and then close stderr.
6541 let mut cmd = process(&cargo_exe())
6542 .arg("check")
6543 .cwd(p.root())
6544 .env("RUSTC", rustc_wrapper)
6545 .build_command();
6546 cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
6547 let mut child = cmd.spawn().expect("cargo should spawn");
6548 // Wait for the rustc wrapper to start.
6549 let rustc_conn = listener.accept().unwrap().0;
6550 // Close stderr to force an error.
6551 drop(child.stderr.take());
6552 // Tell the wrapper to continue.
6553 drop(rustc_conn);
6554 match child.wait() {
6555 Ok(status) => assert!(!status.success()),
6556 Err(e) => panic!("child wait failed: {}", e),
6557 }
6558}
6559
6560use cargo_test_support::registry::Dependency;
6561
6562#[cargo_test]
6563fn reduced_reproduction_8249() {
6564 // https://github.com/rust-lang/cargo/issues/8249
6565 Package::new("a-src", "0.1.0").links("a").publish();
6566 Package::new("a-src", "0.2.0").links("a").publish();
6567
6568 Package::new("b", "0.1.0")
6569 .add_dep(Dependency::new("a-src", "0.1").optional(true))
6570 .publish();
6571 Package::new("b", "0.2.0")
6572 .add_dep(Dependency::new("a-src", "0.2").optional(true))
6573 .publish();
6574
6575 Package::new("c", "1.0.0")
6576 .add_dep(&Dependency::new("b", "0.1.0"))
6577 .publish();
6578
6579 let p = project()
6580 .file(
6581 "Cargo.toml",
6582 r#"
6583 [package]
6584 name = "foo"
6585 version = "0.1.0"
6586
6587 [dependencies]
6588 b = { version = "*", features = ["a-src"] }
6589 a-src = "*"
6590 "#,
6591 )
6592 .file("src/lib.rs", "")
6593 .build();
6594
6595 p.cargo("generate-lockfile").run();
6596 cargo_util::paths::append(&p.root().join("Cargo.toml"), b"c = \"*\"").unwrap();
6597 p.cargo("check").run();
6598 p.cargo("check").run();
6599}
6600
6601#[cargo_test]
6602fn target_directory_backup_exclusion() {
6603 let p = project()
6604 .file("Cargo.toml", &basic_bin_manifest("foo"))
6605 .file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
6606 .build();
6607
6608 // Newly created target/ should have CACHEDIR.TAG inside...
6609 p.cargo("build").run();
6610 let cachedir_tag = p.build_dir().join("CACHEDIR.TAG");
6611 assert!(cachedir_tag.is_file());
6612 assert!(fs::read_to_string(&cachedir_tag)
6613 .unwrap()
6614 .starts_with("Signature: 8a477f597d28d172789f06886806bc55"));
6615 // ...but if target/ already exists CACHEDIR.TAG should not be created in it.
6616 fs::remove_file(&cachedir_tag).unwrap();
6617 p.cargo("build").run();
6618 assert!(!&cachedir_tag.is_file());
6619}
6620
6621#[cargo_test]
6622fn simple_terminal_width() {
6623 let p = project()
6624 .file(
6625 "src/lib.rs",
6626 r#"
6627 pub fn foo() {
6628 let _: () = 42;
6629 }
6630 "#,
6631 )
6632 .build();
6633
6634 p.cargo("build -v")
6635 .env("__CARGO_TEST_TTY_WIDTH_DO_NOT_USE_THIS", "20")
6636 .with_status(101)
6637 .with_stderr_contains("[RUNNING] `rustc [..]--diagnostic-width=20[..]")
6638 .run();
6639
6640 p.cargo("doc -v")
6641 .env("__CARGO_TEST_TTY_WIDTH_DO_NOT_USE_THIS", "20")
6642 .with_stderr_contains("[RUNNING] `rustdoc [..]--diagnostic-width=20[..]")
6643 .run();
6644}
6645
6646#[cargo_test]
6647fn build_script_o0_default() {
6648 let p = project()
6649 .file("src/lib.rs", "")
6650 .file("build.rs", "fn main() {}")
6651 .build();
6652
6653 p.cargo("build -v --release")
6654 .with_stderr_does_not_contain("[..]build_script_build[..]opt-level[..]")
6655 .run();
6656}
6657
6658#[cargo_test]
6659fn build_script_o0_default_even_with_release() {
6660 let p = project()
6661 .file(
6662 "Cargo.toml",
6663 r#"
6664 [package]
6665 name = "foo"
6666 version = "0.1.0"
6667
6668 [profile.release]
6669 opt-level = 1
6670 "#,
6671 )
6672 .file("src/lib.rs", "")
6673 .file("build.rs", "fn main() {}")
6674 .build();
6675
6676 p.cargo("build -v --release")
6677 .with_stderr_does_not_contain("[..]build_script_build[..]opt-level[..]")
6678 .run();
6679}
6680
6681#[cargo_test]
6682fn primary_package_env_var() {
6683 // Test that CARGO_PRIMARY_PACKAGE is enabled only for "foo" and not for any dependency.
6684
6685 let is_primary_package = r#"
6686 pub fn is_primary_package() -> bool {{
6687 option_env!("CARGO_PRIMARY_PACKAGE").is_some()
6688 }}
6689 "#;
6690
6691 Package::new("qux", "0.1.0")
6692 .file("src/lib.rs", is_primary_package)
6693 .publish();
6694
6695 let baz = git::new("baz", |project| {
6696 project
6697 .file("Cargo.toml", &basic_manifest("baz", "0.1.0"))
6698 .file("src/lib.rs", is_primary_package)
6699 });
6700
6701 let foo = project()
6702 .file(
6703 "Cargo.toml",
6704 &format!(
6705 r#"
6706 [package]
6707 name = "foo"
6708 version = "0.1.0"
6709
6710 [dependencies]
6711 bar = {{ path = "bar" }}
6712 baz = {{ git = '{}' }}
6713 qux = "0.1"
6714 "#,
6715 baz.url()
6716 ),
6717 )
6718 .file(
6719 "src/lib.rs",
6720 &format!(
6721 r#"
6722 extern crate bar;
6723 extern crate baz;
6724 extern crate qux;
6725
6726 {}
6727
6728 #[test]
6729 fn verify_primary_package() {{
6730 assert!(!bar::is_primary_package());
6731 assert!(!baz::is_primary_package());
6732 assert!(!qux::is_primary_package());
6733 assert!(is_primary_package());
6734 }}
6735 "#,
6736 is_primary_package
6737 ),
6738 )
6739 .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.0"))
6740 .file("bar/src/lib.rs", is_primary_package)
6741 .build();
6742
6743 foo.cargo("test").run();
6744}
6745
6746#[cargo_test]
6747fn renamed_uplifted_artifact_remains_unmodified_after_rebuild() {
6748 let p = project()
6749 .file(
6750 "Cargo.toml",
6751 r#"
6752 [package]
6753 name = "foo"
6754 authors = []
6755 version = "0.0.0"
6756 "#,
6757 )
6758 .file("src/main.rs", "fn main() {}")
6759 .build();
6760
6761 p.cargo("build").run();
6762
6763 let bin = p.bin("foo");
6764 let renamed_bin = p.bin("foo-renamed");
6765
6766 fs::rename(&bin, &renamed_bin).unwrap();
6767
6768 p.change_file("src/main.rs", "fn main() { eprintln!(\"hello, world\"); }");
6769 p.cargo("build").run();
6770
6771 let not_the_same = !same_file::is_same_file(bin, renamed_bin).unwrap();
6772 assert!(not_the_same, "renamed uplifted artifact must be unmodified");
6773}