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