about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWesley Wiser <wwiser@gmail.com>2017-05-06 14:29:37 -0400
committerWesley Wiser <wwiser@gmail.com>2017-05-14 21:24:29 -0400
commit173f6930bab90e62c1bd5dcc3b03d1bb8a1291a7 (patch)
treeacabd4f395126d43b6f90fc4c63cf93269e5f837
parente40beb3af162e676e40704854dd6547ee8d4cf60 (diff)
downloadrust-173f6930bab90e62c1bd5dcc3b03d1bb8a1291a7.tar.gz
rust-173f6930bab90e62c1bd5dcc3b03d1bb8a1291a7.zip
Rewrite make-win-dist.py in Rust
Fixes #41568
-rw-r--r--src/bootstrap/dist.rs153
-rw-r--r--src/etc/make-win-dist.py126
2 files changed, 136 insertions, 143 deletions
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 1b69f7413b5..0c1317c37c1 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -98,6 +98,139 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
     }
 }
 
+fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
+    let mut found = Vec::new();
+
+    for file in files {
+        let file_path =
+            path.iter()
+                .map(|dir| dir.join(file))
+                .find(|p| p.exists());
+
+        if let Some(file_path) = file_path {
+            found.push(file_path);
+        } else {
+            panic!("Could not find '{}' in {:?}", file, path);
+        }
+    }
+
+    found
+}
+
+fn make_win_dist(rust_root: &Path, plat_root: &Path, target_triple: &str, build: &Build) {
+    //Ask gcc where it keeps its stuff
+    let mut cmd = Command::new(build.cc(target_triple));
+    cmd.arg("-print-search-dirs");
+    build.run_quiet(&mut cmd);
+    let gcc_out =
+        String::from_utf8(
+                cmd
+                .output()
+                .expect("failed to execute gcc")
+                .stdout).expect("gcc.exe output was not utf8");
+
+    let mut bin_path: Vec<_> =
+        env::split_paths(&env::var_os("PATH").unwrap_or_default())
+        .collect();
+    let mut lib_path = Vec::new();
+
+    for line in gcc_out.lines() {
+        let idx = line.find(':').unwrap();
+        let key = &line[..idx];
+        let trim_chars: &[_] = &[' ', '='];
+        let value =
+            line[(idx + 1)..]
+                .trim_left_matches(trim_chars)
+                .split(';')
+                .map(|s| PathBuf::from(s));
+
+        if key == "programs" {
+            bin_path.extend(value);
+        } else if key == "libraries" {
+            lib_path.extend(value);
+        }
+    }
+
+    let target_tools = vec!["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe", "libwinpthread-1.dll"];
+    let mut rustc_dlls = vec!["libstdc++-6.dll", "libwinpthread-1.dll"];
+    if target_triple.starts_with("i686-") {
+        rustc_dlls.push("libgcc_s_dw2-1.dll");
+    } else {
+        rustc_dlls.push("libgcc_s_seh-1.dll");
+    }
+
+    let target_libs = vec![ //MinGW libs
+        "libgcc.a",
+        "libgcc_eh.a",
+        "libgcc_s.a",
+        "libm.a",
+        "libmingw32.a",
+        "libmingwex.a",
+        "libstdc++.a",
+        "libiconv.a",
+        "libmoldname.a",
+        "libpthread.a",
+        //Windows import libs
+        "libadvapi32.a",
+        "libbcrypt.a",
+        "libcomctl32.a",
+        "libcomdlg32.a",
+        "libcrypt32.a",
+        "libgdi32.a",
+        "libimagehlp.a",
+        "libiphlpapi.a",
+        "libkernel32.a",
+        "libmsvcrt.a",
+        "libodbc32.a",
+        "libole32.a",
+        "liboleaut32.a",
+        "libopengl32.a",
+        "libpsapi.a",
+        "librpcrt4.a",
+        "libsetupapi.a",
+        "libshell32.a",
+        "libuser32.a",
+        "libuserenv.a",
+        "libuuid.a",
+        "libwinhttp.a",
+        "libwinmm.a",
+        "libwinspool.a",
+        "libws2_32.a",
+        "libwsock32.a",
+    ];
+
+    //Find mingw artifacts we want to bundle
+    let target_tools = find_files(&target_tools, &bin_path);
+    let rustc_dlls = find_files(&rustc_dlls, &bin_path);
+    let target_libs = find_files(&target_libs, &lib_path);
+
+    fn copy_to_folder(src: &Path, dest_folder: &Path) {
+        let file_name = src.file_name().unwrap().to_os_string();
+        let dest = dest_folder.join(file_name);
+        copy(src, &dest);
+    }
+
+    //Copy runtime dlls next to rustc.exe
+    let dist_bin_dir = rust_root.join("bin/");
+    for src in rustc_dlls {
+        copy_to_folder(&src, &dist_bin_dir);
+    }
+
+    //Copy platform tools to platform-specific bin directory
+    let target_bin_dir = plat_root.join("lib").join("rustlib").join(target_triple).join("bin");
+    fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed");
+    for src in target_tools {
+        copy_to_folder(&src, &target_bin_dir);
+    }
+
+    //Copy platform libs to platform-specific lib directory
+    let target_lib_dir = plat_root.join("lib").join("rustlib").join(target_triple).join("lib");
+    fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
+    for src in target_libs {
+        copy_to_folder(&src, &target_lib_dir);
+    }
+}
+
 /// Build the `rust-mingw` installer component.
 ///
 /// This contains all the bits and pieces to run the MinGW Windows targets
@@ -111,18 +244,11 @@ pub fn mingw(build: &Build, host: &str) {
     let _ = fs::remove_dir_all(&image);
     t!(fs::create_dir_all(&image));
 
-    // The first argument to the script is a "temporary directory" which is just
+    // The first argument is a "temporary directory" which is just
     // thrown away (this contains the runtime DLLs included in the rustc package
     // above) and the second argument is where to place all the MinGW components
     // (which is what we want).
-    //
-    // FIXME: this script should be rewritten into Rust
-    let mut cmd = Command::new(build.python());
-    cmd.arg(build.src.join("src/etc/make-win-dist.py"))
-       .arg(tmpdir(build))
-       .arg(&image)
-       .arg(host);
-    build.run(&mut cmd);
+    make_win_dist(&tmpdir(build), &image, host, &build);
 
     let mut cmd = Command::new(SH_CMD);
     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) {
     // anything requiring us to distribute a license, but it's likely the
     // install will *also* include the rust-mingw package, which also needs
     // licenses, so to be safe we just include it here in all MinGW packages.
-    //
-    // FIXME: this script should be rewritten into Rust
     if host.contains("pc-windows-gnu") {
-        let mut cmd = Command::new(build.python());
-        cmd.arg(build.src.join("src/etc/make-win-dist.py"))
-           .arg(&image)
-           .arg(tmpdir(build))
-           .arg(host);
-        build.run(&mut cmd);
+        make_win_dist(&image, &tmpdir(build), host, build);
 
         let dst = image.join("share/doc");
         t!(fs::create_dir_all(&dst));
diff --git a/src/etc/make-win-dist.py b/src/etc/make-win-dist.py
deleted file mode 100644
index 4699fefbb20..00000000000
--- a/src/etc/make-win-dist.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
-# file at the top-level directory of this distribution and at
-# http://rust-lang.org/COPYRIGHT.
-#
-# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-# option. This file may not be copied, modified, or distributed
-# except according to those terms.
-
-# Script parameters:
-#     argv[1] = rust component root,
-#     argv[2] = gcc component root,
-#     argv[3] = target triple
-# The first two correspond to the two installable components defined in the setup script.
-
-import sys
-import os
-import shutil
-import subprocess
-
-
-def find_files(files, path):
-    found = []
-    for fname in files:
-        for dir in path:
-            filepath = os.path.normpath(os.path.join(dir, fname))
-            if os.path.isfile(filepath):
-                found.append(filepath)
-                break
-        else:
-            raise Exception("Could not find '%s' in %s" % (fname, path))
-    return found
-
-
-# rust_root - root directory of the host binaries image
-# plat_root - root directory of the target platform tools and libs image
-#             (the two get overlayed on top of each other during installation)
-# target_triple - triple of the target image being layed out
-def make_win_dist(rust_root, plat_root, target_triple):
-    # Ask gcc where it keeps its stuff
-    gcc_out = subprocess.check_output(["gcc.exe", "-print-search-dirs"])
-    bin_path = os.environ["PATH"].split(os.pathsep)
-    lib_path = []
-    for line in gcc_out.splitlines():
-        key, val = line.split(':', 1)
-        if key == "programs":
-            bin_path.extend(val.lstrip(' =').split(';'))
-        elif key == "libraries":
-            lib_path.extend(val.lstrip(' =').split(';'))
-
-    target_tools = ["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe",
-                    "libwinpthread-1.dll"]
-
-    rustc_dlls = ["libstdc++-6.dll", "libwinpthread-1.dll"]
-    if target_triple.startswith("i686-"):
-        rustc_dlls.append("libgcc_s_dw2-1.dll")
-    else:
-        rustc_dlls.append("libgcc_s_seh-1.dll")
-
-    target_libs = [ # MinGW libs
-                    "libgcc.a",
-                    "libgcc_eh.a",
-                    "libgcc_s.a",
-                    "libm.a",
-                    "libmingw32.a",
-                    "libmingwex.a",
-                    "libstdc++.a",
-                    "libiconv.a",
-                    "libmoldname.a",
-                    "libpthread.a",
-                    # Windows import libs
-                    "libadvapi32.a",
-                    "libbcrypt.a",
-                    "libcomctl32.a",
-                    "libcomdlg32.a",
-                    "libcrypt32.a",
-                    "libgdi32.a",
-                    "libimagehlp.a",
-                    "libiphlpapi.a",
-                    "libkernel32.a",
-                    "libmsvcrt.a",
-                    "libodbc32.a",
-                    "libole32.a",
-                    "liboleaut32.a",
-                    "libopengl32.a",
-                    "libpsapi.a",
-                    "librpcrt4.a",
-                    "libsetupapi.a",
-                    "libshell32.a",
-                    "libuser32.a",
-                    "libuserenv.a",
-                    "libuuid.a",
-                    "libwinhttp.a",
-                    "libwinmm.a",
-                    "libwinspool.a",
-                    "libws2_32.a",
-                    "libwsock32.a",
-                    ]
-
-    # Find mingw artifacts we want to bundle
-    target_tools = find_files(target_tools, bin_path)
-    rustc_dlls = find_files(rustc_dlls, bin_path)
-    target_libs = find_files(target_libs, lib_path)
-
-    # Copy runtime dlls next to rustc.exe
-    dist_bin_dir = os.path.join(rust_root, "bin")
-    for src in rustc_dlls:
-        shutil.copy(src, dist_bin_dir)
-
-    # Copy platform tools to platform-specific bin directory
-    target_bin_dir = os.path.join(plat_root, "lib", "rustlib", target_triple, "bin")
-    if not os.path.exists(target_bin_dir):
-        os.makedirs(target_bin_dir)
-    for src in target_tools:
-        shutil.copy(src, target_bin_dir)
-
-    # Copy platform libs to platform-specific lib directory
-    target_lib_dir = os.path.join(plat_root, "lib", "rustlib", target_triple, "lib")
-    if not os.path.exists(target_lib_dir):
-        os.makedirs(target_lib_dir)
-    for src in target_libs:
-        shutil.copy(src, target_lib_dir)
-
-if __name__ == "__main__":
-    make_win_dist(sys.argv[1], sys.argv[2], sys.argv[3])