]> git.proxmox.com Git - cargo.git/blob - tests/testsuite/cross_compile.rs
Auto merge of #5790 - dwijnand:dependabot/cargo/crossbeam-0.4, r=alexcrichton
[cargo.git] / tests / testsuite / cross_compile.rs
1 use cargo::util::process;
2 use support::{is_nightly, rustc_host};
3 use support::{basic_manifest, basic_bin_manifest, cross_compile, execs, project};
4 use support::hamcrest::{assert_that, existing_file};
5
6 #[test]
7 fn simple_cross() {
8 if cross_compile::disabled() {
9 return;
10 }
11
12 let p = project()
13 .file(
14 "Cargo.toml",
15 r#"
16 [package]
17 name = "foo"
18 version = "0.0.0"
19 authors = []
20 build = "build.rs"
21 "#,
22 )
23 .file(
24 "build.rs",
25 &format!(
26 r#"
27 fn main() {{
28 assert_eq!(std::env::var("TARGET").unwrap(), "{}");
29 }}
30 "#,
31 cross_compile::alternate()
32 ),
33 )
34 .file(
35 "src/main.rs",
36 &format!(
37 r#"
38 use std::env;
39 fn main() {{
40 assert_eq!(env::consts::ARCH, "{}");
41 }}
42 "#,
43 cross_compile::alternate_arch()
44 ),
45 )
46 .build();
47
48 let target = cross_compile::alternate();
49 assert_that(
50 p.cargo("build").arg("--target").arg(&target).arg("-v"),
51 execs().with_status(0),
52 );
53 assert_that(&p.target_bin(&target, "foo"), existing_file());
54
55 assert_that(
56 process(&p.target_bin(&target, "foo")),
57 execs().with_status(0),
58 );
59 }
60
61 #[test]
62 fn simple_cross_config() {
63 if cross_compile::disabled() {
64 return;
65 }
66
67 let p = project()
68 .file(
69 ".cargo/config",
70 &format!(
71 r#"
72 [build]
73 target = "{}"
74 "#,
75 cross_compile::alternate()
76 ),
77 )
78 .file(
79 "Cargo.toml",
80 r#"
81 [package]
82 name = "foo"
83 version = "0.0.0"
84 authors = []
85 build = "build.rs"
86 "#,
87 )
88 .file(
89 "build.rs",
90 &format!(
91 r#"
92 fn main() {{
93 assert_eq!(std::env::var("TARGET").unwrap(), "{}");
94 }}
95 "#,
96 cross_compile::alternate()
97 ),
98 )
99 .file(
100 "src/main.rs",
101 &format!(
102 r#"
103 use std::env;
104 fn main() {{
105 assert_eq!(env::consts::ARCH, "{}");
106 }}
107 "#,
108 cross_compile::alternate_arch()
109 ),
110 )
111 .build();
112
113 let target = cross_compile::alternate();
114 assert_that(p.cargo("build").arg("-v"), execs().with_status(0));
115 assert_that(&p.target_bin(&target, "foo"), existing_file());
116
117 assert_that(
118 process(&p.target_bin(&target, "foo")),
119 execs().with_status(0),
120 );
121 }
122
123 #[test]
124 fn simple_deps() {
125 if cross_compile::disabled() {
126 return;
127 }
128
129 let p = project()
130 .file(
131 "Cargo.toml",
132 r#"
133 [package]
134 name = "foo"
135 version = "0.0.1"
136 authors = []
137
138 [dependencies.bar]
139 path = "../bar"
140 "#,
141 )
142 .file("src/main.rs", "extern crate bar; fn main() { bar::bar(); }")
143 .build();
144 let _p2 = project().at("bar")
145 .file("Cargo.toml", &basic_manifest("bar", "0.0.1"))
146 .file("src/lib.rs", "pub fn bar() {}")
147 .build();
148
149 let target = cross_compile::alternate();
150 assert_that(
151 p.cargo("build").arg("--target").arg(&target),
152 execs().with_status(0),
153 );
154 assert_that(&p.target_bin(&target, "foo"), existing_file());
155
156 assert_that(
157 process(&p.target_bin(&target, "foo")),
158 execs().with_status(0),
159 );
160 }
161
162 #[test]
163 fn plugin_deps() {
164 if cross_compile::disabled() {
165 return;
166 }
167 if !is_nightly() {
168 return;
169 }
170
171 let foo = project()
172 .file(
173 "Cargo.toml",
174 r#"
175 [package]
176 name = "foo"
177 version = "0.0.1"
178 authors = []
179
180 [dependencies.bar]
181 path = "../bar"
182
183 [dependencies.baz]
184 path = "../baz"
185 "#,
186 )
187 .file(
188 "src/main.rs",
189 r#"
190 #![feature(plugin)]
191 #![plugin(bar)]
192 extern crate baz;
193 fn main() {
194 assert_eq!(bar!(), baz::baz());
195 }
196 "#,
197 )
198 .build();
199 let _bar = project().at("bar")
200 .file(
201 "Cargo.toml",
202 r#"
203 [package]
204 name = "bar"
205 version = "0.0.1"
206 authors = []
207
208 [lib]
209 name = "bar"
210 plugin = true
211 "#,
212 )
213 .file(
214 "src/lib.rs",
215 r#"
216 #![feature(plugin_registrar, rustc_private)]
217
218 extern crate rustc_plugin;
219 extern crate syntax;
220
221 use rustc_plugin::Registry;
222 use syntax::tokenstream::TokenTree;
223 use syntax::codemap::Span;
224 use syntax::ast::*;
225 use syntax::ext::base::{ExtCtxt, MacEager, MacResult};
226 use syntax::ext::build::AstBuilder;
227
228 #[plugin_registrar]
229 pub fn foo(reg: &mut Registry) {
230 reg.register_macro("bar", expand_bar);
231 }
232
233 fn expand_bar(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
234 -> Box<MacResult + 'static> {
235 MacEager::expr(cx.expr_lit(sp, LitKind::Int(1, LitIntType::Unsuffixed)))
236 }
237 "#,
238 )
239 .build();
240 let _baz = project().at("baz")
241 .file("Cargo.toml", &basic_manifest("baz", "0.0.1"))
242 .file("src/lib.rs", "pub fn baz() -> i32 { 1 }")
243 .build();
244
245 let target = cross_compile::alternate();
246 assert_that(
247 foo.cargo("build").arg("--target").arg(&target),
248 execs().with_status(0),
249 );
250 assert_that(&foo.target_bin(&target, "foo"), existing_file());
251
252 assert_that(
253 process(&foo.target_bin(&target, "foo")),
254 execs().with_status(0),
255 );
256 }
257
258 #[test]
259 fn plugin_to_the_max() {
260 if cross_compile::disabled() {
261 return;
262 }
263 if !is_nightly() {
264 return;
265 }
266
267 let foo = project()
268 .file(
269 "Cargo.toml",
270 r#"
271 [package]
272 name = "foo"
273 version = "0.0.1"
274 authors = []
275
276 [dependencies.bar]
277 path = "../bar"
278
279 [dependencies.baz]
280 path = "../baz"
281 "#,
282 )
283 .file(
284 "src/main.rs",
285 r#"
286 #![feature(plugin)]
287 #![plugin(bar)]
288 extern crate baz;
289 fn main() {
290 assert_eq!(bar!(), baz::baz());
291 }
292 "#,
293 )
294 .build();
295 let _bar = project().at("bar")
296 .file(
297 "Cargo.toml",
298 r#"
299 [package]
300 name = "bar"
301 version = "0.0.1"
302 authors = []
303
304 [lib]
305 name = "bar"
306 plugin = true
307
308 [dependencies.baz]
309 path = "../baz"
310 "#,
311 )
312 .file(
313 "src/lib.rs",
314 r#"
315 #![feature(plugin_registrar, rustc_private)]
316
317 extern crate rustc_plugin;
318 extern crate syntax;
319 extern crate baz;
320
321 use rustc_plugin::Registry;
322 use syntax::tokenstream::TokenTree;
323 use syntax::codemap::Span;
324 use syntax::ast::*;
325 use syntax::ext::base::{ExtCtxt, MacEager, MacResult};
326 use syntax::ext::build::AstBuilder;
327 use syntax::ptr::P;
328
329 #[plugin_registrar]
330 pub fn foo(reg: &mut Registry) {
331 reg.register_macro("bar", expand_bar);
332 }
333
334 fn expand_bar(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
335 -> Box<MacResult + 'static> {
336 let bar = Ident::from_str("baz");
337 let path = cx.path(sp, vec![bar.clone(), bar]);
338 MacEager::expr(cx.expr_call(sp, cx.expr_path(path), vec![]))
339 }
340 "#,
341 )
342 .build();
343 let _baz = project().at("baz")
344 .file("Cargo.toml", &basic_manifest("baz", "0.0.1"))
345 .file("src/lib.rs", "pub fn baz() -> i32 { 1 }")
346 .build();
347
348 let target = cross_compile::alternate();
349 assert_that(
350 foo.cargo("build").arg("--target").arg(&target).arg("-v"),
351 execs().with_status(0),
352 );
353 println!("second");
354 assert_that(
355 foo.cargo("build").arg("-v").arg("--target").arg(&target),
356 execs().with_status(0),
357 );
358 assert_that(&foo.target_bin(&target, "foo"), existing_file());
359
360 assert_that(
361 process(&foo.target_bin(&target, "foo")),
362 execs().with_status(0),
363 );
364 }
365
366 #[test]
367 fn linker_and_ar() {
368 if cross_compile::disabled() {
369 return;
370 }
371
372 let target = cross_compile::alternate();
373 let p = project()
374 .file(
375 ".cargo/config",
376 &format!(
377 r#"
378 [target.{}]
379 ar = "my-ar-tool"
380 linker = "my-linker-tool"
381 "#,
382 target
383 ),
384 )
385 .file("Cargo.toml", &basic_bin_manifest("foo"))
386 .file(
387 "src/foo.rs",
388 &format!(
389 r#"
390 use std::env;
391 fn main() {{
392 assert_eq!(env::consts::ARCH, "{}");
393 }}
394 "#,
395 cross_compile::alternate_arch()
396 ),
397 )
398 .build();
399
400 assert_that(
401 p.cargo("build").arg("--target").arg(&target).arg("-v"),
402 execs().with_status(101).with_stderr_contains(&format!(
403 "\
404 [COMPILING] foo v0.5.0 ({url})
405 [RUNNING] `rustc --crate-name foo src[/]foo.rs --crate-type bin \
406 --emit=dep-info,link -C debuginfo=2 \
407 -C metadata=[..] \
408 --out-dir {dir}[/]target[/]{target}[/]debug[/]deps \
409 --target {target} \
410 -C ar=my-ar-tool -C linker=my-linker-tool \
411 -L dependency={dir}[/]target[/]{target}[/]debug[/]deps \
412 -L dependency={dir}[/]target[/]debug[/]deps`
413 ",
414 dir = p.root().display(),
415 url = p.url(),
416 target = target,
417 )),
418 );
419 }
420
421 #[test]
422 fn plugin_with_extra_dylib_dep() {
423 if cross_compile::disabled() {
424 return;
425 }
426 if !is_nightly() {
427 return;
428 }
429
430 let foo = project()
431 .file(
432 "Cargo.toml",
433 r#"
434 [package]
435 name = "foo"
436 version = "0.0.1"
437 authors = []
438
439 [dependencies.bar]
440 path = "../bar"
441 "#,
442 )
443 .file(
444 "src/main.rs",
445 r#"
446 #![feature(plugin)]
447 #![plugin(bar)]
448
449 fn main() {}
450 "#,
451 )
452 .build();
453 let _bar = project().at("bar")
454 .file(
455 "Cargo.toml",
456 r#"
457 [package]
458 name = "bar"
459 version = "0.0.1"
460 authors = []
461
462 [lib]
463 name = "bar"
464 plugin = true
465
466 [dependencies.baz]
467 path = "../baz"
468 "#,
469 )
470 .file(
471 "src/lib.rs",
472 r#"
473 #![feature(plugin_registrar, rustc_private)]
474
475 extern crate rustc_plugin;
476 extern crate baz;
477
478 use rustc_plugin::Registry;
479
480 #[plugin_registrar]
481 pub fn foo(reg: &mut Registry) {
482 println!("{}", baz::baz());
483 }
484 "#,
485 )
486 .build();
487 let _baz = project().at("baz")
488 .file(
489 "Cargo.toml",
490 r#"
491 [package]
492 name = "baz"
493 version = "0.0.1"
494 authors = []
495
496 [lib]
497 name = "baz"
498 crate_type = ["dylib"]
499 "#,
500 )
501 .file("src/lib.rs", "pub fn baz() -> i32 { 1 }")
502 .build();
503
504 let target = cross_compile::alternate();
505 assert_that(
506 foo.cargo("build").arg("--target").arg(&target),
507 execs().with_status(0),
508 );
509 }
510
511 #[test]
512 fn cross_tests() {
513 if cross_compile::disabled() {
514 return;
515 }
516
517 let p = project()
518 .file(
519 "Cargo.toml",
520 r#"
521 [project]
522 name = "foo"
523 authors = []
524 version = "0.0.0"
525
526 [[bin]]
527 name = "bar"
528 "#,
529 )
530 .file(
531 "src/bin/bar.rs",
532 &format!(
533 r#"
534 #[allow(unused_extern_crates)]
535 extern crate foo;
536 use std::env;
537 fn main() {{
538 assert_eq!(env::consts::ARCH, "{}");
539 }}
540 #[test] fn test() {{ main() }}
541 "#,
542 cross_compile::alternate_arch()
543 ),
544 )
545 .file(
546 "src/lib.rs",
547 &format!(
548 r#"
549 use std::env;
550 pub fn foo() {{ assert_eq!(env::consts::ARCH, "{}"); }}
551 #[test] fn test_foo() {{ foo() }}
552 "#,
553 cross_compile::alternate_arch()
554 ),
555 )
556 .build();
557
558 let target = cross_compile::alternate();
559 assert_that(
560 p.cargo("test").arg("--target").arg(&target),
561 execs()
562 .with_status(0)
563 .with_stderr(&format!(
564 "\
565 [COMPILING] foo v0.0.0 ({foo})
566 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
567 [RUNNING] target[/]{triple}[/]debug[/]deps[/]foo-[..][EXE]
568 [RUNNING] target[/]{triple}[/]debug[/]deps[/]bar-[..][EXE]",
569 foo = p.url(),
570 triple = target
571 ))
572 .with_stdout_contains("test test_foo ... ok")
573 .with_stdout_contains("test test ... ok"),
574 );
575 }
576
577 #[test]
578 fn no_cross_doctests() {
579 if cross_compile::disabled() {
580 return;
581 }
582
583 let p = project()
584 .file(
585 "src/lib.rs",
586 r#"
587 //! ```
588 //! extern crate foo;
589 //! assert!(true);
590 //! ```
591 "#,
592 )
593 .build();
594
595 let host_output = format!(
596 "\
597 [COMPILING] foo v0.0.1 ({foo})
598 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
599 [RUNNING] target[/]debug[/]deps[/]foo-[..][EXE]
600 [DOCTEST] foo
601 ",
602 foo = p.url()
603 );
604
605 println!("a");
606 assert_that(
607 p.cargo("test"),
608 execs().with_status(0).with_stderr(&host_output),
609 );
610
611 println!("b");
612 let target = cross_compile::host();
613 assert_that(
614 p.cargo("test").arg("--target").arg(&target),
615 execs().with_status(0).with_stderr(&format!(
616 "\
617 [COMPILING] foo v0.0.1 ({foo})
618 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
619 [RUNNING] target[/]{triple}[/]debug[/]deps[/]foo-[..][EXE]
620 [DOCTEST] foo
621 ",
622 foo = p.url(),
623 triple = target
624 )),
625 );
626
627 println!("c");
628 let target = cross_compile::alternate();
629 assert_that(
630 p.cargo("test").arg("--target").arg(&target),
631 execs().with_status(0).with_stderr(&format!(
632 "\
633 [COMPILING] foo v0.0.1 ({foo})
634 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
635 [RUNNING] target[/]{triple}[/]debug[/]deps[/]foo-[..][EXE]
636 ",
637 foo = p.url(),
638 triple = target
639 )),
640 );
641 }
642
643 #[test]
644 fn simple_cargo_run() {
645 if cross_compile::disabled() {
646 return;
647 }
648
649 let p = project()
650 .file(
651 "src/main.rs",
652 &format!(
653 r#"
654 use std::env;
655 fn main() {{
656 assert_eq!(env::consts::ARCH, "{}");
657 }}
658 "#,
659 cross_compile::alternate_arch()
660 ),
661 )
662 .build();
663
664 let target = cross_compile::alternate();
665 assert_that(
666 p.cargo("run").arg("--target").arg(&target),
667 execs().with_status(0),
668 );
669 }
670
671 #[test]
672 fn cross_with_a_build_script() {
673 if cross_compile::disabled() {
674 return;
675 }
676
677 let target = cross_compile::alternate();
678 let p = project()
679 .file(
680 "Cargo.toml",
681 r#"
682 [package]
683 name = "foo"
684 version = "0.0.0"
685 authors = []
686 build = 'build.rs'
687 "#,
688 )
689 .file(
690 "build.rs",
691 &format!(
692 r#"
693 use std::env;
694 use std::path::PathBuf;
695 fn main() {{
696 assert_eq!(env::var("TARGET").unwrap(), "{0}");
697 let mut path = PathBuf::from(env::var_os("OUT_DIR").unwrap());
698 assert_eq!(path.file_name().unwrap().to_str().unwrap(), "out");
699 path.pop();
700 assert!(path.file_name().unwrap().to_str().unwrap()
701 .starts_with("foo-"));
702 path.pop();
703 assert_eq!(path.file_name().unwrap().to_str().unwrap(), "build");
704 path.pop();
705 assert_eq!(path.file_name().unwrap().to_str().unwrap(), "debug");
706 path.pop();
707 assert_eq!(path.file_name().unwrap().to_str().unwrap(), "{0}");
708 path.pop();
709 assert_eq!(path.file_name().unwrap().to_str().unwrap(), "target");
710 }}
711 "#,
712 target
713 ),
714 )
715 .file("src/main.rs", "fn main() {}")
716 .build();
717
718 assert_that(
719 p.cargo("build").arg("--target").arg(&target).arg("-v"),
720 execs().with_status(0).with_stderr(&format!(
721 "\
722 [COMPILING] foo v0.0.0 (file://[..])
723 [RUNNING] `rustc [..] build.rs [..] --out-dir {dir}[/]target[/]debug[/]build[/]foo-[..]`
724 [RUNNING] `{dir}[/]target[/]debug[/]build[/]foo-[..][/]build-script-build`
725 [RUNNING] `rustc [..] src[/]main.rs [..] --target {target} [..]`
726 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
727 ",
728 target = target,
729 dir = p.root().display()
730 )),
731 );
732 }
733
734 #[test]
735 fn build_script_needed_for_host_and_target() {
736 if cross_compile::disabled() {
737 return;
738 }
739
740 let target = cross_compile::alternate();
741 let host = rustc_host();
742 let p = project()
743 .file(
744 "Cargo.toml",
745 r#"
746 [package]
747 name = "foo"
748 version = "0.0.0"
749 authors = []
750 build = 'build.rs'
751
752 [dependencies.d1]
753 path = "d1"
754 [build-dependencies.d2]
755 path = "d2"
756 "#,
757 )
758 .file(
759 "build.rs",
760 r#"
761 #[allow(unused_extern_crates)]
762 extern crate d2;
763 fn main() { d2::d2(); }
764 "#,
765 )
766 .file(
767 "src/main.rs",
768 "
769 #[allow(unused_extern_crates)]
770 extern crate d1;
771 fn main() { d1::d1(); }
772 ",
773 )
774 .file(
775 "d1/Cargo.toml",
776 r#"
777 [package]
778 name = "d1"
779 version = "0.0.0"
780 authors = []
781 build = 'build.rs'
782 "#,
783 )
784 .file("d1/src/lib.rs", "pub fn d1() {}")
785 .file(
786 "d1/build.rs",
787 r#"
788 use std::env;
789 fn main() {
790 let target = env::var("TARGET").unwrap();
791 println!("cargo:rustc-flags=-L /path/to/{}", target);
792 }
793 "#,
794 )
795 .file(
796 "d2/Cargo.toml",
797 r#"
798 [package]
799 name = "d2"
800 version = "0.0.0"
801 authors = []
802
803 [dependencies.d1]
804 path = "../d1"
805 "#,
806 )
807 .file(
808 "d2/src/lib.rs",
809 "
810 #[allow(unused_extern_crates)]
811 extern crate d1;
812 pub fn d2() { d1::d1(); }
813 ",
814 )
815 .build();
816
817 assert_that(
818 p.cargo("build").arg("--target").arg(&target).arg("-v"),
819 execs()
820 .with_status(0)
821 .with_stderr_contains(&format!(
822 "[COMPILING] d1 v0.0.0 ({url}/d1)",
823 url = p.url()
824 ))
825 .with_stderr_contains(&format!("[RUNNING] `rustc [..] d1[/]build.rs [..] --out-dir {dir}[/]target[/]debug[/]build[/]d1-[..]`",
826 dir = p.root().display()))
827 .with_stderr_contains(&format!(
828 "[RUNNING] `{dir}[/]target[/]debug[/]build[/]d1-[..][/]build-script-build`",
829 dir = p.root().display()
830 ))
831 .with_stderr_contains(
832 "[RUNNING] `rustc [..] d1[/]src[/]lib.rs [..]`",
833 )
834 .with_stderr_contains(&format!(
835 "[COMPILING] d2 v0.0.0 ({url}/d2)",
836 url = p.url()
837 ))
838 .with_stderr_contains(&format!(
839 "\
840 [RUNNING] `rustc [..] d2[/]src[/]lib.rs [..] \
841 -L /path/to/{host}`",
842 host = host
843 ))
844 .with_stderr_contains(&format!(
845 "[COMPILING] foo v0.0.0 ({url})",
846 url = p.url()
847 ))
848 .with_stderr_contains(&format!("\
849 [RUNNING] `rustc [..] build.rs [..] --out-dir {dir}[/]target[/]debug[/]build[/]foo-[..] \
850 -L /path/to/{host}`", dir = p.root().display(), host = host))
851 .with_stderr_contains(&format!(
852 "\
853 [RUNNING] `rustc [..] src[/]main.rs [..] --target {target} [..] \
854 -L /path/to/{target}`",
855 target = target
856 )),
857 );
858 }
859
860 #[test]
861 fn build_deps_for_the_right_arch() {
862 if cross_compile::disabled() {
863 return;
864 }
865
866 let p = project()
867 .file(
868 "Cargo.toml",
869 r#"
870 [package]
871 name = "foo"
872 version = "0.0.0"
873 authors = []
874
875 [dependencies.d2]
876 path = "d2"
877 "#,
878 )
879 .file("src/main.rs", "extern crate d2; fn main() {}")
880 .file("d1/Cargo.toml", &basic_manifest("d1", "0.0.0"))
881 .file("d1/src/lib.rs", "pub fn d1() {}")
882 .file(
883 "d2/Cargo.toml",
884 r#"
885 [package]
886 name = "d2"
887 version = "0.0.0"
888 authors = []
889 build = "build.rs"
890
891 [build-dependencies.d1]
892 path = "../d1"
893 "#,
894 )
895 .file("d2/build.rs", "extern crate d1; fn main() {}")
896 .file("d2/src/lib.rs", "")
897 .build();
898
899 let target = cross_compile::alternate();
900 assert_that(
901 p.cargo("build").arg("--target").arg(&target).arg("-v"),
902 execs().with_status(0),
903 );
904 }
905
906 #[test]
907 fn build_script_only_host() {
908 if cross_compile::disabled() {
909 return;
910 }
911
912 let p = project()
913 .file(
914 "Cargo.toml",
915 r#"
916 [package]
917 name = "foo"
918 version = "0.0.0"
919 authors = []
920 build = "build.rs"
921
922 [build-dependencies.d1]
923 path = "d1"
924 "#,
925 )
926 .file("src/main.rs", "fn main() {}")
927 .file("build.rs", "extern crate d1; fn main() {}")
928 .file(
929 "d1/Cargo.toml",
930 r#"
931 [package]
932 name = "d1"
933 version = "0.0.0"
934 authors = []
935 build = "build.rs"
936 "#,
937 )
938 .file("d1/src/lib.rs", "pub fn d1() {}")
939 .file(
940 "d1/build.rs",
941 r#"
942 use std::env;
943
944 fn main() {
945 assert!(env::var("OUT_DIR").unwrap().replace("\\", "/")
946 .contains("target/debug/build/d1-"),
947 "bad: {:?}", env::var("OUT_DIR"));
948 }
949 "#,
950 )
951 .build();
952
953 let target = cross_compile::alternate();
954 assert_that(
955 p.cargo("build").arg("--target").arg(&target).arg("-v"),
956 execs().with_status(0),
957 );
958 }
959
960 #[test]
961 fn plugin_build_script_right_arch() {
962 if cross_compile::disabled() {
963 return;
964 }
965 let p = project()
966 .file(
967 "Cargo.toml",
968 r#"
969 [package]
970 name = "foo"
971 version = "0.0.1"
972 authors = []
973 build = "build.rs"
974
975 [lib]
976 name = "foo"
977 plugin = true
978 "#,
979 )
980 .file("build.rs", "fn main() {}")
981 .file("src/lib.rs", "")
982 .build();
983
984 assert_that(
985 p.cargo("build")
986 .arg("-v")
987 .arg("--target")
988 .arg(cross_compile::alternate()),
989 execs().with_status(0).with_stderr(
990 "\
991 [COMPILING] foo v0.0.1 ([..])
992 [RUNNING] `rustc [..] build.rs [..]`
993 [RUNNING] `[..][/]build-script-build`
994 [RUNNING] `rustc [..] src[/]lib.rs [..]`
995 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
996 ",
997 ),
998 );
999 }
1000
1001 #[test]
1002 fn build_script_with_platform_specific_dependencies() {
1003 if cross_compile::disabled() {
1004 return;
1005 }
1006
1007 let target = cross_compile::alternate();
1008 let host = rustc_host();
1009 let p = project()
1010 .file(
1011 "Cargo.toml",
1012 r#"
1013 [package]
1014 name = "foo"
1015 version = "0.0.1"
1016 authors = []
1017 build = "build.rs"
1018
1019 [build-dependencies.d1]
1020 path = "d1"
1021 "#,
1022 )
1023 .file(
1024 "build.rs",
1025 "
1026 #[allow(unused_extern_crates)]
1027 extern crate d1;
1028 fn main() {}
1029 ",
1030 )
1031 .file("src/lib.rs", "")
1032 .file(
1033 "d1/Cargo.toml",
1034 &format!(
1035 r#"
1036 [package]
1037 name = "d1"
1038 version = "0.0.0"
1039 authors = []
1040
1041 [target.{}.dependencies]
1042 d2 = {{ path = "../d2" }}
1043 "#,
1044 host
1045 ),
1046 )
1047 .file("d1/src/lib.rs", "#[allow(unused_extern_crates)] extern crate d2;")
1048 .file("d2/Cargo.toml", &basic_manifest("d2", "0.0.0"))
1049 .file("d2/src/lib.rs", "")
1050 .build();
1051
1052 assert_that(
1053 p.cargo("build").arg("-v").arg("--target").arg(&target),
1054 execs().with_status(0).with_stderr(&format!(
1055 "\
1056 [COMPILING] d2 v0.0.0 ([..])
1057 [RUNNING] `rustc [..] d2[/]src[/]lib.rs [..]`
1058 [COMPILING] d1 v0.0.0 ([..])
1059 [RUNNING] `rustc [..] d1[/]src[/]lib.rs [..]`
1060 [COMPILING] foo v0.0.1 ([..])
1061 [RUNNING] `rustc [..] build.rs [..]`
1062 [RUNNING] `{dir}[/]target[/]debug[/]build[/]foo-[..][/]build-script-build`
1063 [RUNNING] `rustc [..] src[/]lib.rs [..] --target {target} [..]`
1064 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1065 ",
1066 dir = p.root().display(),
1067 target = target
1068 )),
1069 );
1070 }
1071
1072 #[test]
1073 fn platform_specific_dependencies_do_not_leak() {
1074 if cross_compile::disabled() {
1075 return;
1076 }
1077
1078 let target = cross_compile::alternate();
1079 let host = rustc_host();
1080 let p = project()
1081 .file(
1082 "Cargo.toml",
1083 r#"
1084 [package]
1085 name = "foo"
1086 version = "0.0.1"
1087 authors = []
1088 build = "build.rs"
1089
1090 [dependencies.d1]
1091 path = "d1"
1092
1093 [build-dependencies.d1]
1094 path = "d1"
1095 "#,
1096 )
1097 .file("build.rs", "extern crate d1; fn main() {}")
1098 .file("src/lib.rs", "")
1099 .file(
1100 "d1/Cargo.toml",
1101 &format!(
1102 r#"
1103 [package]
1104 name = "d1"
1105 version = "0.0.0"
1106 authors = []
1107
1108 [target.{}.dependencies]
1109 d2 = {{ path = "../d2" }}
1110 "#,
1111 host
1112 ),
1113 )
1114 .file("d1/src/lib.rs", "extern crate d2;")
1115 .file("d1/Cargo.toml", &basic_manifest("d1", "0.0.0"))
1116 .file("d2/src/lib.rs", "")
1117 .build();
1118
1119 assert_that(
1120 p.cargo("build").arg("-v").arg("--target").arg(&target),
1121 execs()
1122 .with_status(101)
1123 .with_stderr_contains("[..] can't find crate for `d2`[..]"),
1124 );
1125 }
1126
1127 #[test]
1128 fn platform_specific_variables_reflected_in_build_scripts() {
1129 if cross_compile::disabled() {
1130 return;
1131 }
1132
1133 let target = cross_compile::alternate();
1134 let host = rustc_host();
1135 let p = project()
1136 .file(
1137 "Cargo.toml",
1138 &format!(
1139 r#"
1140 [package]
1141 name = "foo"
1142 version = "0.0.1"
1143 authors = []
1144 build = "build.rs"
1145
1146 [target.{host}.dependencies]
1147 d1 = {{ path = "d1" }}
1148
1149 [target.{target}.dependencies]
1150 d2 = {{ path = "d2" }}
1151 "#,
1152 host = host,
1153 target = target
1154 ),
1155 )
1156 .file(
1157 "build.rs",
1158 &format!(
1159 r#"
1160 use std::env;
1161
1162 fn main() {{
1163 let platform = env::var("TARGET").unwrap();
1164 let (expected, not_expected) = match &platform[..] {{
1165 "{host}" => ("DEP_D1_VAL", "DEP_D2_VAL"),
1166 "{target}" => ("DEP_D2_VAL", "DEP_D1_VAL"),
1167 _ => panic!("unknown platform")
1168 }};
1169
1170 env::var(expected).ok()
1171 .expect(&format!("missing {{}}", expected));
1172 env::var(not_expected).err()
1173 .expect(&format!("found {{}}", not_expected));
1174 }}
1175 "#,
1176 host = host,
1177 target = target
1178 ),
1179 )
1180 .file("src/lib.rs", "")
1181 .file(
1182 "d1/Cargo.toml",
1183 r#"
1184 [package]
1185 name = "d1"
1186 version = "0.0.0"
1187 authors = []
1188 links = "d1"
1189 build = "build.rs"
1190 "#,
1191 )
1192 .file("d1/build.rs", r#"fn main() { println!("cargo:val=1") }"#)
1193 .file("d1/src/lib.rs", "")
1194 .file(
1195 "d2/Cargo.toml",
1196 r#"
1197 [package]
1198 name = "d2"
1199 version = "0.0.0"
1200 authors = []
1201 links = "d2"
1202 build = "build.rs"
1203 "#,
1204 )
1205 .file("d2/build.rs", r#"fn main() { println!("cargo:val=1") }"#)
1206 .file("d2/src/lib.rs", "")
1207 .build();
1208
1209 assert_that(p.cargo("build").arg("-v"), execs().with_status(0));
1210 assert_that(
1211 p.cargo("build").arg("-v").arg("--target").arg(&target),
1212 execs().with_status(0),
1213 );
1214 }
1215
1216 #[test]
1217 fn cross_test_dylib() {
1218 if cross_compile::disabled() {
1219 return;
1220 }
1221
1222 let target = cross_compile::alternate();
1223
1224 let p = project()
1225 .file(
1226 "Cargo.toml",
1227 r#"
1228 [package]
1229 name = "foo"
1230 version = "0.0.1"
1231 authors = []
1232
1233 [lib]
1234 name = "foo"
1235 crate_type = ["dylib"]
1236
1237 [dependencies.bar]
1238 path = "bar"
1239 "#,
1240 )
1241 .file(
1242 "src/lib.rs",
1243 r#"
1244 extern crate bar as the_bar;
1245
1246 pub fn bar() { the_bar::baz(); }
1247
1248 #[test]
1249 fn foo() { bar(); }
1250 "#,
1251 )
1252 .file(
1253 "tests/test.rs",
1254 r#"
1255 extern crate foo as the_foo;
1256
1257 #[test]
1258 fn foo() { the_foo::bar(); }
1259 "#,
1260 )
1261 .file(
1262 "bar/Cargo.toml",
1263 r#"
1264 [package]
1265 name = "bar"
1266 version = "0.0.1"
1267 authors = []
1268
1269 [lib]
1270 name = "bar"
1271 crate_type = ["dylib"]
1272 "#,
1273 )
1274 .file(
1275 "bar/src/lib.rs",
1276 &format!(
1277 r#"
1278 use std::env;
1279 pub fn baz() {{
1280 assert_eq!(env::consts::ARCH, "{}");
1281 }}
1282 "#,
1283 cross_compile::alternate_arch()
1284 ),
1285 )
1286 .build();
1287
1288 assert_that(
1289 p.cargo("test").arg("--target").arg(&target),
1290 execs()
1291 .with_status(0)
1292 .with_stderr(&format!(
1293 "\
1294 [COMPILING] bar v0.0.1 ({dir}/bar)
1295 [COMPILING] foo v0.0.1 ({dir})
1296 [FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
1297 [RUNNING] target[/]{arch}[/]debug[/]deps[/]foo-[..][EXE]
1298 [RUNNING] target[/]{arch}[/]debug[/]deps[/]test-[..][EXE]",
1299 dir = p.url(),
1300 arch = cross_compile::alternate()
1301 ))
1302 .with_stdout_contains_n("test foo ... ok", 2),
1303 );
1304 }