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