Skip to content

Commit 06c0b1d

Browse files
committed
auto merge of #16957 : vadimcn/rust/package-gcc, r=brson
Package rustc's mingw dependencies into Windows installer to avoid requiring a separate mingw install. Closes #11782
2 parents d24c824 + 7085b3e commit 06c0b1d

File tree

8 files changed

+128
-42
lines changed

8 files changed

+128
-42
lines changed

mk/dist.mk

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ PKG_EXE = dist/$(PKG_NAME)-$(CFG_BUILD).exe
123123
$(PKG_EXE): rust.iss modpath.iss upgrade.iss LICENSE.txt rust-logo.ico \
124124
$(CSREQ3_T_$(CFG_BUILD)_H_$(CFG_BUILD)) \
125125
dist-prepare-win
126-
$(CFG_PYTHON) $(S)src/etc/copy-runtime-deps.py tmp/dist/win/bin $(CFG_BUILD)
126+
$(CFG_PYTHON) $(S)src/etc/make-win-dist.py tmp/dist/win $(CFG_BUILD)
127127
@$(call E, ISCC: $@)
128128
$(Q)"$(CFG_ISCC)" $<
129129

src/etc/copy-runtime-deps.py

-24
This file was deleted.

src/etc/make-win-dist.py

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2+
# file at the top-level directory of this distribution and at
3+
# http://rust-lang.org/COPYRIGHT.
4+
#
5+
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
# option. This file may not be copied, modified, or distributed
9+
# except according to those terms.
10+
11+
import sys, os, shutil, subprocess
12+
13+
def find_files(files, path):
14+
found = []
15+
for fname in files:
16+
for dir in path:
17+
filepath = os.path.normpath(os.path.join(dir, fname))
18+
if os.path.isfile(filepath):
19+
found.append(filepath)
20+
break
21+
else:
22+
raise Exception("Could not find '%s' in %s" % (fname, path))
23+
return found
24+
25+
def make_win_dist(dist_root, target_triple):
26+
# Ask gcc where it keeps its' stuff
27+
gcc_out = subprocess.check_output(["gcc.exe", "-print-search-dirs"])
28+
bin_path = os.environ["PATH"].split(os.pathsep)
29+
lib_path = []
30+
for line in gcc_out.splitlines():
31+
key, val = line.split(':', 1)
32+
if key == "programs":
33+
bin_path.extend(val.lstrip(' =').split(';'))
34+
elif key == "libraries":
35+
lib_path.extend(val.lstrip(' =').split(';'))
36+
37+
target_tools = ["gcc.exe", "ld.exe", "ar.exe", "dlltool.exe", "windres.exe"]
38+
39+
rustc_dlls = ["libstdc++-6.dll"]
40+
if target_triple.startswith("i686-"):
41+
rustc_dlls.append("libgcc_s_dw2-1.dll")
42+
else:
43+
rustc_dlls.append("libgcc_s_seh-1.dll")
44+
45+
target_libs = ["crtbegin.o", "crtend.o", "crt2.o", "dllcrt2.o",
46+
"libadvapi32.a", "libcrypt32.a", "libgcc.a", "libgcc_eh.a", "libgcc_s.a",
47+
"libimagehlp.a", "libiphlpapi.a", "libkernel32.a", "libm.a", "libmingw32.a",
48+
"libmingwex.a", "libmsvcrt.a", "libpsapi.a", "libshell32.a", "libstdc++.a",
49+
"libuser32.a", "libws2_32.a", "libiconv.a", "libmoldname.a"]
50+
51+
# Find mingw artifacts we want to bundle
52+
target_tools = find_files(target_tools, bin_path)
53+
rustc_dlls = find_files(rustc_dlls, bin_path)
54+
target_libs = find_files(target_libs, lib_path)
55+
56+
# Copy runtime dlls next to rustc.exe
57+
dist_bin_dir = os.path.join(dist_root, "bin")
58+
for src in rustc_dlls:
59+
shutil.copy(src, dist_bin_dir)
60+
61+
# Copy platform tools (and another copy of runtime dlls) to platform-spcific bin directory
62+
target_bin_dir = os.path.join(dist_root, "bin", "rustlib", target_triple, "bin")
63+
if not os.path.exists(target_bin_dir):
64+
os.makedirs(target_bin_dir)
65+
for src in target_tools:
66+
shutil.copy(src, target_bin_dir)
67+
68+
# Copy platform libs to platform-spcific lib directory
69+
target_lib_dir = os.path.join(dist_root, "bin", "rustlib", target_triple, "lib")
70+
if not os.path.exists(target_lib_dir):
71+
os.makedirs(target_lib_dir)
72+
for src in target_libs:
73+
shutil.copy(src, target_lib_dir)
74+
75+
# Copy license files
76+
lic_dir = os.path.join(dist_root, "bin", "third-party")
77+
if os.path.exists(lic_dir):
78+
shutil.rmtree(lic_dir) # copytree() won't overwrite existing files
79+
shutil.copytree(os.path.join(os.path.dirname(__file__), "third-party"), lic_dir)
80+
81+
if __name__=="__main__":
82+
make_win_dist(sys.argv[1], sys.argv[2])

src/etc/snapshot.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ def get_winnt_runtime_deps(platform):
157157
path_dirs = os.environ["PATH"].split(os.pathsep)
158158
for name in deps:
159159
for dir in path_dirs:
160-
matches = glob.glob(os.path.join(dir, name))
161-
if matches:
162-
runtime_deps.append(matches[0])
160+
filepath = os.path.join(dir, name)
161+
if os.path.isfile(filepath):
162+
runtime_deps.append(filepath)
163163
break
164164
else:
165165
raise Exception("Could not find runtime dependency: %s" % name)

src/etc/third-party/README.txt

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
Certain files in this distribution are covered by a different license than the rest of the Rust Project.
2-
Specifically:
1+
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.
32

4-
- libgcc_s_dw2-1.dll and libstdc++6.dll are distributed under the terms of the GNU General Public License
5-
with the GCC Runtime Library Exception as published by the Free Software Foundation; either version 3,
6-
or (at your option) any later version. See the files COPYING3 and COPYING.RUNTIME respectively.
7-
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/,
8-
or from the project website at http://gcc.gnu.org
3+
You can obtain a copy of the source of these libraries from the MinGW-w64 project[1].
4+
5+
[1]: http://mingw-w64.sourceforge.net/

src/librustc/back/link.rs

+3
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,9 @@ fn link_args(cmd: &mut Command,
929929
cmd.arg("-nodefaultlibs");
930930
}
931931

932+
// Rust does its' own LTO
933+
cmd.arg("-fno-lto").arg("-fno-use-linker-plugin");
934+
932935
// If we're building a dylib, we don't use --gc-sections because LLVM has
933936
// already done the best it can do, and we also don't want to eliminate the
934937
// metadata. If we're building an executable, however, --gc-sections drops

src/librustc/driver/driver.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use serialize::{json, Encodable};
3232

3333
use std::io;
3434
use std::io::fs;
35+
use std::os;
3536
use arena::TypedArena;
3637
use syntax::ast;
3738
use syntax::attr;
@@ -258,18 +259,26 @@ pub fn phase_2_configure_and_expand(sess: &Session,
258259
// dependent dlls. Note that this uses cfg!(windows) as opposed to
259260
// targ_cfg because syntax extensions are always loaded for the host
260261
// compiler, not for the target.
262+
let mut _old_path = String::new();
261263
if cfg!(windows) {
262-
sess.host_filesearch().add_dylib_search_paths();
264+
_old_path = os::getenv("PATH").unwrap_or(_old_path);
265+
let mut new_path = sess.host_filesearch().get_dylib_search_paths();
266+
new_path.push_all_move(os::split_paths(_old_path.as_slice()));
267+
os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap());
263268
}
264269
let cfg = syntax::ext::expand::ExpansionConfig {
265270
deriving_hash_type_parameter: sess.features.default_type_params.get(),
266271
crate_name: crate_name.to_string(),
267272
};
268-
syntax::ext::expand::expand_crate(&sess.parse_sess,
273+
let ret = syntax::ext::expand::expand_crate(&sess.parse_sess,
269274
cfg,
270275
macros,
271276
syntax_exts,
272-
krate)
277+
krate);
278+
if cfg!(windows) {
279+
os::setenv("PATH", _old_path);
280+
}
281+
ret
273282
}
274283
);
275284

@@ -509,11 +518,18 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
509518
pub fn phase_6_link_output(sess: &Session,
510519
trans: &CrateTranslation,
511520
outputs: &OutputFilenames) {
521+
let old_path = os::getenv("PATH").unwrap_or_else(||String::new());
522+
let mut new_path = os::split_paths(old_path.as_slice());
523+
new_path.push_all_move(sess.host_filesearch().get_tools_search_paths());
524+
os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap());
525+
512526
time(sess.time_passes(), "linking", (), |_|
513527
link::link_binary(sess,
514528
trans,
515529
outputs,
516530
trans.link.crate_name.as_slice()));
531+
532+
os::setenv("PATH", old_path);
517533
}
518534

519535
pub fn stop_after_phase_3(sess: &Session) -> bool {

src/librustc/metadata/filesearch.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use std::cell::RefCell;
1414
use std::os;
1515
use std::io::fs;
16-
use std::dynamic_lib::DynamicLibrary;
1716
use std::collections::HashSet;
1817

1918
use util::fs as myfs;
@@ -134,11 +133,24 @@ impl<'a> FileSearch<'a> {
134133
}
135134
}
136135

137-
pub fn add_dylib_search_paths(&self) {
136+
// Returns a list of directories where target-specific dylibs might be located.
137+
pub fn get_dylib_search_paths(&self) -> Vec<Path> {
138+
let mut paths = Vec::new();
138139
self.for_each_lib_search_path(|lib_search_path| {
139-
DynamicLibrary::prepend_search_path(lib_search_path);
140+
paths.push(lib_search_path.clone());
140141
FileDoesntMatch
141-
})
142+
});
143+
paths
144+
}
145+
146+
// Returns a list of directories where target-specific tool binaries are located.
147+
pub fn get_tools_search_paths(&self) -> Vec<Path> {
148+
let mut p = Path::new(self.sysroot);
149+
p.push(find_libdir(self.sysroot));
150+
p.push(rustlibdir());
151+
p.push(self.triple);
152+
p.push("bin");
153+
vec![p]
142154
}
143155
}
144156

0 commit comments

Comments
 (0)