From 76c02af434a7447824b3c0c105c4af57d3d6c50e Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Wed, 3 Sep 2014 00:41:53 -0700 Subject: [PATCH 1/4] Remove dependency on GCC's LTO linker plugin, since Rust does its' own LTO. --- src/librustc/back/link.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index bf026560c6afd..e418284ffce7a 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -929,6 +929,9 @@ fn link_args(cmd: &mut Command, cmd.arg("-nodefaultlibs"); } + // Rust does its' own LTO + cmd.arg("-fno-lto").arg("-fno-use-linker-plugin"); + // If we're building a dylib, we don't use --gc-sections because LLVM has // already done the best it can do, and we also don't want to eliminate the // metadata. If we're building an executable, however, --gc-sections drops From c05ba8a298e904cabcaa1d96367b058537f541e4 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Wed, 3 Sep 2014 00:46:23 -0700 Subject: [PATCH 2/4] Append target-specific tools directory ($(RUST)/bin/rustlib//bin/) to PATH during linking, so that rustc can invoke them. --- src/librustc/driver/driver.rs | 22 +++++++++++++++++++--- src/librustc/metadata/filesearch.rs | 20 ++++++++++++++++---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 4c71c2df44d3e..018bfecd369a7 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -32,6 +32,7 @@ use serialize::{json, Encodable}; use std::io; use std::io::fs; +use std::os; use arena::TypedArena; use syntax::ast; use syntax::attr; @@ -258,18 +259,26 @@ pub fn phase_2_configure_and_expand(sess: &Session, // dependent dlls. Note that this uses cfg!(windows) as opposed to // targ_cfg because syntax extensions are always loaded for the host // compiler, not for the target. + let mut _old_path = String::new(); if cfg!(windows) { - sess.host_filesearch().add_dylib_search_paths(); + _old_path = os::getenv("PATH").unwrap_or(_old_path); + let mut new_path = sess.host_filesearch().get_dylib_search_paths(); + new_path.push_all_move(os::split_paths(_old_path.as_slice())); + os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap()); } let cfg = syntax::ext::expand::ExpansionConfig { deriving_hash_type_parameter: sess.features.default_type_params.get(), crate_name: crate_name.to_string(), }; - syntax::ext::expand::expand_crate(&sess.parse_sess, + let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, cfg, macros, syntax_exts, - krate) + krate); + if cfg!(windows) { + os::setenv("PATH", _old_path); + } + ret } ); @@ -509,11 +518,18 @@ pub fn phase_5_run_llvm_passes(sess: &Session, pub fn phase_6_link_output(sess: &Session, trans: &CrateTranslation, outputs: &OutputFilenames) { + let old_path = os::getenv("PATH").unwrap_or_else(||String::new()); + let mut new_path = os::split_paths(old_path.as_slice()); + new_path.push_all_move(sess.host_filesearch().get_tools_search_paths()); + os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap()); + time(sess.time_passes(), "linking", (), |_| link::link_binary(sess, trans, outputs, trans.link.crate_name.as_slice())); + + os::setenv("PATH", old_path); } pub fn stop_after_phase_3(sess: &Session) -> bool { diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 49c24b190b22b..bdabb3efb98ba 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -13,7 +13,6 @@ use std::cell::RefCell; use std::os; use std::io::fs; -use std::dynamic_lib::DynamicLibrary; use std::collections::HashSet; use util::fs as myfs; @@ -134,11 +133,24 @@ impl<'a> FileSearch<'a> { } } - pub fn add_dylib_search_paths(&self) { + // Returns a list of directories where target-specific dylibs might be located. + pub fn get_dylib_search_paths(&self) -> Vec { + let mut paths = Vec::new(); self.for_each_lib_search_path(|lib_search_path| { - DynamicLibrary::prepend_search_path(lib_search_path); + paths.push(lib_search_path.clone()); FileDoesntMatch - }) + }); + paths + } + + // Returns a list of directories where target-specific tool binaries are located. + pub fn get_tools_search_paths(&self) -> Vec { + let mut p = Path::new(self.sysroot); + p.push(find_libdir(self.sysroot)); + p.push(rustlibdir()); + p.push(self.triple); + p.push("bin"); + vec![p] } } From 0ac9e9b561e361718abc5df10af216e52fc4fc3e Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Wed, 10 Sep 2014 21:32:36 -0700 Subject: [PATCH 3/4] Update license notice. --- src/etc/third-party/README.txt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/etc/third-party/README.txt b/src/etc/third-party/README.txt index a77c0e77efd3f..2544bfa2da363 100644 --- a/src/etc/third-party/README.txt +++ b/src/etc/third-party/README.txt @@ -1,8 +1,5 @@ -Certain files in this distribution are covered by a different license than the rest of the Rust Project. -Specifically: +Certain binaries in this distribution do not originate from the Rust project, but are distributed with it in its binary form. These binaries, including gcc and other parts of the GNU compiler toolchain, are licensed either under the terms of the GNU General Public License, or the GNU General Public License with the GCC Runtime Library Exception, as published by the Free Software Foundation, either version 3, or (at your option) any later version. See the files COPYING3 and COPYING.RUNTIME respectively. - - libgcc_s_dw2-1.dll and libstdc++6.dll are distributed under the terms of the GNU General Public License - with the GCC Runtime Library Exception as published by the Free Software Foundation; either version 3, - or (at your option) any later version. See the files COPYING3 and COPYING.RUNTIME respectively. - You can obtain a copy of the source of these libraries either here: http://sourceforge.net/projects/mingw/files/MinGW/Base/gcc/Version4/gcc-4.5.2-1/, - or from the project website at http://gcc.gnu.org +You can obtain a copy of the source of these libraries from the MinGW-w64 project[1]. + +[1]: http://mingw-w64.sourceforge.net/ From 7085b3edd96d5c3244422449edb2b5144b7d50f9 Mon Sep 17 00:00:00 2001 From: Vadim Chugunov Date: Tue, 2 Sep 2014 01:56:54 -0700 Subject: [PATCH 4/4] Package rustc's mingw dependencies into Windows installer. gcc, ld, ar, dlltool, windres go into $(RUST)/bin/rustlib//bin/ platform libraries and startup objects got into $(RUST)/bin/rustlib//lib/ --- mk/dist.mk | 2 +- src/etc/copy-runtime-deps.py | 24 ----------- src/etc/make-win-dist.py | 82 ++++++++++++++++++++++++++++++++++++ src/etc/snapshot.py | 6 +-- 4 files changed, 86 insertions(+), 28 deletions(-) delete mode 100644 src/etc/copy-runtime-deps.py create mode 100644 src/etc/make-win-dist.py diff --git a/mk/dist.mk b/mk/dist.mk index 4d86af37171b4..26169f3a13bd0 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -123,7 +123,7 @@ PKG_EXE = dist/$(PKG_NAME)-$(CFG_BUILD).exe $(PKG_EXE): rust.iss modpath.iss upgrade.iss LICENSE.txt rust-logo.ico \ $(CSREQ3_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \ dist-prepare-win - $(CFG_PYTHON) $(S)src/etc/copy-runtime-deps.py tmp/dist/win/bin $(CFG_BUILD) + $(CFG_PYTHON) $(S)src/etc/make-win-dist.py tmp/dist/win $(CFG_BUILD) @$(call E, ISCC: $@) $(Q)"$(CFG_ISCC)" $< diff --git a/src/etc/copy-runtime-deps.py b/src/etc/copy-runtime-deps.py deleted file mode 100644 index fd829cd0ab70f..0000000000000 --- a/src/etc/copy-runtime-deps.py +++ /dev/null @@ -1,24 +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 or the MIT license -# , at your -# option. This file may not be copied, modified, or distributed -# except according to those terms. - -# Copies Rust runtime dependencies to the specified directory. - -import snapshot, sys, os, shutil - -def copy_runtime_deps(dest_dir, triple): - for path in snapshot.get_winnt_runtime_deps(snapshot.get_platform(triple)): - shutil.copy(path, dest_dir) - - lic_dest = os.path.join(dest_dir, "third-party") - if os.path.exists(lic_dest): - shutil.rmtree(lic_dest) # copytree() won't overwrite existing files - shutil.copytree(os.path.join(os.path.dirname(__file__), "third-party"), lic_dest) - -copy_runtime_deps(sys.argv[1], sys.argv[2]) diff --git a/src/etc/make-win-dist.py b/src/etc/make-win-dist.py new file mode 100644 index 0000000000000..bb9a112b7b28a --- /dev/null +++ b/src/etc/make-win-dist.py @@ -0,0 +1,82 @@ +# 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 or the MIT license +# , at your +# option. This file may not be copied, modified, or distributed +# except according to those terms. + +import sys, os, shutil, 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 + +def make_win_dist(dist_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", "windres.exe"] + + rustc_dlls = ["libstdc++-6.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 = ["crtbegin.o", "crtend.o", "crt2.o", "dllcrt2.o", + "libadvapi32.a", "libcrypt32.a", "libgcc.a", "libgcc_eh.a", "libgcc_s.a", + "libimagehlp.a", "libiphlpapi.a", "libkernel32.a", "libm.a", "libmingw32.a", + "libmingwex.a", "libmsvcrt.a", "libpsapi.a", "libshell32.a", "libstdc++.a", + "libuser32.a", "libws2_32.a", "libiconv.a", "libmoldname.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(dist_root, "bin") + for src in rustc_dlls: + shutil.copy(src, dist_bin_dir) + + # Copy platform tools (and another copy of runtime dlls) to platform-spcific bin directory + target_bin_dir = os.path.join(dist_root, "bin", "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-spcific lib directory + target_lib_dir = os.path.join(dist_root, "bin", "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) + + # Copy license files + lic_dir = os.path.join(dist_root, "bin", "third-party") + if os.path.exists(lic_dir): + shutil.rmtree(lic_dir) # copytree() won't overwrite existing files + shutil.copytree(os.path.join(os.path.dirname(__file__), "third-party"), lic_dir) + +if __name__=="__main__": + make_win_dist(sys.argv[1], sys.argv[2]) diff --git a/src/etc/snapshot.py b/src/etc/snapshot.py index 24255c0cc5df2..268b82bdca38e 100644 --- a/src/etc/snapshot.py +++ b/src/etc/snapshot.py @@ -157,9 +157,9 @@ def get_winnt_runtime_deps(platform): path_dirs = os.environ["PATH"].split(os.pathsep) for name in deps: for dir in path_dirs: - matches = glob.glob(os.path.join(dir, name)) - if matches: - runtime_deps.append(matches[0]) + filepath = os.path.join(dir, name) + if os.path.isfile(filepath): + runtime_deps.append(filepath) break else: raise Exception("Could not find runtime dependency: %s" % name)