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