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