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