@@ -45,12 +45,12 @@ pub fn run(target: Target,
45
45
fs:: create_dir ( & cargo_dir) . ok ( ) ;
46
46
fs:: create_dir ( & xargo_dir) . ok ( ) ;
47
47
48
- let mut cmd = if target. uses_xargo ( ) {
48
+ let mut cargo = if target. uses_xargo ( ) {
49
49
Command :: new ( "xargo" )
50
50
} else {
51
51
Command :: new ( "cargo" )
52
52
} ;
53
- cmd . args ( args) ;
53
+ cargo . args ( args) ;
54
54
55
55
let version = env ! ( "CARGO_PKG_VERSION" ) ;
56
56
let tag = if version. ends_with ( "-dev" ) {
@@ -59,22 +59,60 @@ pub fn run(target: Target,
59
59
Cow :: from ( format ! ( "v{}" , version) )
60
60
} ;
61
61
62
- Command :: new ( "docker" )
63
- . arg ( "run" )
62
+ let mut docker = Command :: new ( "docker" ) ;
63
+
64
+ docker. arg ( "run" )
64
65
. arg ( "--rm" )
65
66
. args ( & [ "--user" , & format ! ( "{}:{}" , id:: user( ) , id:: group( ) ) ] )
66
67
. args ( & [ "-e" , "CARGO_HOME=/cargo" ] )
67
68
. args ( & [ "-e" , "CARGO_TARGET_DIR=/target" ] )
69
+ . args ( & [ "-e" , "HOME=/tmp" ] )
68
70
. args ( & [ "-e" , & format ! ( "USER={}" , id:: username( ) ) ] )
69
71
. args ( & [ "-e" , "XARGO_HOME=/xargo" ] )
70
72
. args ( & [ "-v" , & format ! ( "{}:/xargo" , xargo_dir. display( ) ) ] )
71
73
. args ( & [ "-v" , & format ! ( "{}:/cargo" , cargo_dir. display( ) ) ] )
72
74
. args ( & [ "-v" , & format ! ( "{}:/project:ro" , cargo_root. display( ) ) ] )
73
75
. args ( & [ "-v" ,
74
76
& format ! ( "{}:/rust:ro" , rustc:: sysroot( verbose) ?. display( ) ) ] )
75
- . args ( & [ "-v" , & format ! ( "{}:/target" , target_dir. display( ) ) ] )
76
- . args ( & [ "-w" , "/project" ] )
77
- . args ( & [ "-it" , & format ! ( "japaric/{}:{}" , target. triple( ) , tag) ] )
78
- . args ( & [ "sh" , "-c" , & format ! ( "PATH=$PATH:/rust/bin {:?}" , cmd) ] )
79
- . run_and_get_status ( verbose)
77
+ . args ( & [ "-v" , & format ! ( "{}:/target" , target_dir. display( ) ) ] ) ;
78
+
79
+ // `emcc` caches stuff in `$HOME`. We must preserve that information across
80
+ // runs so we use an OS-level temporary directory for that.
81
+ let must_run_emcc_first = if target. uses_emcc ( ) {
82
+ let temp_dir = env:: temp_dir ( ) ;
83
+ let cache_dir = temp_dir. join ( format ! ( "cross-{}" , target. triple( ) ) ) ;
84
+
85
+ if !cache_dir. exists ( ) {
86
+ fs:: create_dir ( & cache_dir) . chain_err ( || {
87
+ format ! ( "couldn't create a directory in {}" ,
88
+ temp_dir. display( ) )
89
+ } ) ?;
90
+ }
91
+
92
+ docker. args ( & [ "-v" , & format ! ( "{}:{}" , cache_dir. display( ) , "/tmp" ) ] ) ;
93
+
94
+ !cache_dir. join ( ".emscripten" ) . exists ( )
95
+ } else {
96
+ false
97
+ } ;
98
+
99
+ docker. args ( & [ "-w" , "/project" ] )
100
+ . args ( & [ "-it" , & format ! ( "japaric/{}:{}" , target. triple( ) , tag) ] ) ;
101
+
102
+ // `emcc` only creates the `~/.emscripten` file the very first time is
103
+ // called. Make sure that first time is from "outside" `rustc` so that
104
+ // `cross build` doesn't result in a no-op.
105
+ if must_run_emcc_first {
106
+ docker. args ( & [ "sh" ,
107
+ "-c" ,
108
+ & format ! ( "emcc 2>/dev/null; \
109
+ PATH=$PATH:/rust/bin {:?}",
110
+ cargo) ] ) ;
111
+ } else {
112
+ docker. args ( & [ "sh" ,
113
+ "-c" ,
114
+ & format ! ( "PATH=$PATH:/rust/bin {:?}" , cargo) ] ) ;
115
+ }
116
+
117
+ docker. run_and_get_status ( verbose)
80
118
}
0 commit comments