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