@@ -98,6 +98,139 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
9898 }
9999}
100100
101+ fn find_files ( files : & [ & str ] , path : & [ PathBuf ] ) -> Vec < PathBuf > {
102+ let mut found = Vec :: new ( ) ;
103+
104+ for file in files {
105+ let file_path =
106+ path. iter ( )
107+ . map ( |dir| dir. join ( file) )
108+ . find ( |p| p. exists ( ) ) ;
109+
110+ if let Some ( file_path) = file_path {
111+ found. push ( file_path) ;
112+ } else {
113+ panic ! ( "Could not find '{}' in {:?}" , file, path) ;
114+ }
115+ }
116+
117+ found
118+ }
119+
120+ fn make_win_dist ( rust_root : & Path , plat_root : & Path , target_triple : & str , build : & Build ) {
121+ //Ask gcc where it keeps its stuff
122+ let mut cmd = Command :: new ( build. cc ( target_triple) ) ;
123+ cmd. arg ( "-print-search-dirs" ) ;
124+ build. run_quiet ( & mut cmd) ;
125+ let gcc_out =
126+ String :: from_utf8 (
127+ cmd
128+ . output ( )
129+ . expect ( "failed to execute gcc" )
130+ . stdout ) . expect ( "gcc.exe output was not utf8" ) ;
131+
132+ let mut bin_path: Vec < _ > =
133+ env:: split_paths ( & env:: var_os ( "PATH" ) . unwrap_or_default ( ) )
134+ . collect ( ) ;
135+ let mut lib_path = Vec :: new ( ) ;
136+
137+ for line in gcc_out. lines ( ) {
138+ let idx = line. find ( ':' ) . unwrap ( ) ;
139+ let key = & line[ ..idx] ;
140+ let trim_chars: & [ _ ] = & [ ' ' , '=' ] ;
141+ let value =
142+ line[ ( idx + 1 ) ..]
143+ . trim_left_matches ( trim_chars)
144+ . split ( ';' )
145+ . map ( |s| PathBuf :: from ( s) ) ;
146+
147+ if key == "programs" {
148+ bin_path. extend ( value) ;
149+ } else if key == "libraries" {
150+ lib_path. extend ( value) ;
151+ }
152+ }
153+
154+ let target_tools = vec ! [ "gcc.exe" , "ld.exe" , "ar.exe" , "dlltool.exe" , "libwinpthread-1.dll" ] ;
155+ let mut rustc_dlls = vec ! [ "libstdc++-6.dll" , "libwinpthread-1.dll" ] ;
156+ if target_triple. starts_with ( "i686-" ) {
157+ rustc_dlls. push ( "libgcc_s_dw2-1.dll" ) ;
158+ } else {
159+ rustc_dlls. push ( "libgcc_s_seh-1.dll" ) ;
160+ }
161+
162+ let target_libs = vec ! [ //MinGW libs
163+ "libgcc.a" ,
164+ "libgcc_eh.a" ,
165+ "libgcc_s.a" ,
166+ "libm.a" ,
167+ "libmingw32.a" ,
168+ "libmingwex.a" ,
169+ "libstdc++.a" ,
170+ "libiconv.a" ,
171+ "libmoldname.a" ,
172+ "libpthread.a" ,
173+ //Windows import libs
174+ "libadvapi32.a" ,
175+ "libbcrypt.a" ,
176+ "libcomctl32.a" ,
177+ "libcomdlg32.a" ,
178+ "libcrypt32.a" ,
179+ "libgdi32.a" ,
180+ "libimagehlp.a" ,
181+ "libiphlpapi.a" ,
182+ "libkernel32.a" ,
183+ "libmsvcrt.a" ,
184+ "libodbc32.a" ,
185+ "libole32.a" ,
186+ "liboleaut32.a" ,
187+ "libopengl32.a" ,
188+ "libpsapi.a" ,
189+ "librpcrt4.a" ,
190+ "libsetupapi.a" ,
191+ "libshell32.a" ,
192+ "libuser32.a" ,
193+ "libuserenv.a" ,
194+ "libuuid.a" ,
195+ "libwinhttp.a" ,
196+ "libwinmm.a" ,
197+ "libwinspool.a" ,
198+ "libws2_32.a" ,
199+ "libwsock32.a" ,
200+ ] ;
201+
202+ //Find mingw artifacts we want to bundle
203+ let target_tools = find_files ( & target_tools, & bin_path) ;
204+ let rustc_dlls = find_files ( & rustc_dlls, & bin_path) ;
205+ let target_libs = find_files ( & target_libs, & lib_path) ;
206+
207+ fn copy_to_folder ( src : & Path , dest_folder : & Path ) {
208+ let file_name = src. file_name ( ) . unwrap ( ) . to_os_string ( ) ;
209+ let dest = dest_folder. join ( file_name) ;
210+ copy ( src, & dest) ;
211+ }
212+
213+ //Copy runtime dlls next to rustc.exe
214+ let dist_bin_dir = rust_root. join ( "bin/" ) ;
215+ for src in rustc_dlls {
216+ copy_to_folder ( & src, & dist_bin_dir) ;
217+ }
218+
219+ //Copy platform tools to platform-specific bin directory
220+ let target_bin_dir = plat_root. join ( "lib" ) . join ( "rustlib" ) . join ( target_triple) . join ( "bin" ) ;
221+ fs:: create_dir_all ( & target_bin_dir) . expect ( "creating target_bin_dir failed" ) ;
222+ for src in target_tools {
223+ copy_to_folder ( & src, & target_bin_dir) ;
224+ }
225+
226+ //Copy platform libs to platform-specific lib directory
227+ let target_lib_dir = plat_root. join ( "lib" ) . join ( "rustlib" ) . join ( target_triple) . join ( "lib" ) ;
228+ fs:: create_dir_all ( & target_lib_dir) . expect ( "creating target_lib_dir failed" ) ;
229+ for src in target_libs {
230+ copy_to_folder ( & src, & target_lib_dir) ;
231+ }
232+ }
233+
101234/// Build the `rust-mingw` installer component.
102235///
103236/// This contains all the bits and pieces to run the MinGW Windows targets
@@ -111,18 +244,11 @@ pub fn mingw(build: &Build, host: &str) {
111244 let _ = fs:: remove_dir_all ( & image) ;
112245 t ! ( fs:: create_dir_all( & image) ) ;
113246
114- // The first argument to the script is a "temporary directory" which is just
247+ // The first argument is a "temporary directory" which is just
115248 // thrown away (this contains the runtime DLLs included in the rustc package
116249 // above) and the second argument is where to place all the MinGW components
117250 // (which is what we want).
118- //
119- // FIXME: this script should be rewritten into Rust
120- let mut cmd = Command :: new ( build. python ( ) ) ;
121- cmd. arg ( build. src . join ( "src/etc/make-win-dist.py" ) )
122- . arg ( tmpdir ( build) )
123- . arg ( & image)
124- . arg ( host) ;
125- build. run ( & mut cmd) ;
251+ make_win_dist ( & tmpdir ( build) , & image, host, & build) ;
126252
127253 let mut cmd = Command :: new ( SH_CMD ) ;
128254 cmd. arg ( sanitize_sh ( & build. src . join ( "src/rust-installer/gen-installer.sh" ) ) )
@@ -174,15 +300,8 @@ pub fn rustc(build: &Build, stage: u32, host: &str) {
174300 // anything requiring us to distribute a license, but it's likely the
175301 // install will *also* include the rust-mingw package, which also needs
176302 // licenses, so to be safe we just include it here in all MinGW packages.
177- //
178- // FIXME: this script should be rewritten into Rust
179303 if host. contains ( "pc-windows-gnu" ) {
180- let mut cmd = Command :: new ( build. python ( ) ) ;
181- cmd. arg ( build. src . join ( "src/etc/make-win-dist.py" ) )
182- . arg ( & image)
183- . arg ( tmpdir ( build) )
184- . arg ( host) ;
185- build. run ( & mut cmd) ;
304+ make_win_dist ( & image, & tmpdir ( build) , host, build) ;
186305
187306 let dst = image. join ( "share/doc" ) ;
188307 t ! ( fs:: create_dir_all( & dst) ) ;
0 commit comments