Skip to content

Commit 389ba88

Browse files
committed
---
yaml --- r: 235198 b: refs/heads/stable c: 9d9e267 h: refs/heads/master v: v3
1 parent c008265 commit 389ba88

File tree

25 files changed

+615
-102
lines changed

25 files changed

+615
-102
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: 106f3826e913924573292fa1c9ad9759c5c56663
32+
refs/heads/stable: 9d9e2678f504b4e9389d6a62d27ba4f5ee17a2f6
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/mk/main.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ LLVM_BINDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --bindir)
295295
LLVM_INCDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --includedir)
296296
LLVM_LIBDIR_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libdir)
297297
LLVM_LIBDIR_RUSTFLAGS_$(1)=-L "$$(LLVM_LIBDIR_$(1))"
298-
LLVM_LIBS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --libs $$(LLVM_COMPONENTS))
299298
LLVM_LDFLAGS_$(1)=$$(shell "$$(LLVM_CONFIG_$(1))" --ldflags)
300299
ifeq ($$(findstring freebsd,$(1)),freebsd)
301300
# On FreeBSD, it may search wrong headers (that are for pre-installed LLVM),

branches/stable/mk/target.mk

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,9 @@ endef
249249

250250
$(foreach host,$(CFG_HOST), \
251251
$(foreach target,$(CFG_TARGET), \
252-
$(foreach stage,$(STAGES), \
253-
$(foreach crate,$(CRATES), \
254-
$(eval $(call SETUP_LIB_MSVC_ENV_VARS,$(stage),$(target),$(host),$(crate)))))))
252+
$(foreach crate,$(CRATES), \
253+
$(eval $(call SETUP_LIB_MSVC_ENV_VARS,0,$(target),$(host),$(crate))))))
255254
$(foreach host,$(CFG_HOST), \
256255
$(foreach target,$(CFG_TARGET), \
257-
$(foreach stage,$(STAGES), \
258-
$(foreach tool,$(TOOLS), \
259-
$(eval $(call SETUP_TOOL_MSVC_ENV_VARS,$(stage),$(target),$(host),$(tool)))))))
256+
$(foreach tool,$(TOOLS), \
257+
$(eval $(call SETUP_TOOL_MSVC_ENV_VARS,0,$(target),$(host),$(tool))))))

branches/stable/src/doc/trpl/comments.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ fn add_one(x: i32) -> i32 {
3838
}
3939
```
4040

41+
There is another style of doc comment, `//!`, to comment containing items (e.g.
42+
crates, modules or functions), instead of the items following it. Commonly used
43+
inside crates root (lib.rs) or modules root (mod.rs):
44+
45+
```
46+
//! # The Rust Standard Library
47+
//!
48+
//! The Rust Standard Library provides the essential runtime
49+
//! functionality for building portable Rust software.
50+
```
51+
4152
When writing doc comments, providing some examples of usage is very, very
4253
helpful. You’ll notice we’ve used a new macro here: `assert_eq!`. This compares
4354
two values, and `panic!`s if they’re not equal to each other. It’s very helpful

branches/stable/src/etc/mklldeps.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414

1515
f = open(sys.argv[1], 'wb')
1616

17-
components = sys.argv[2].split(' ')
18-
components = [i for i in components if i] # ignore extra whitespaces
17+
components = sys.argv[2].split() # splits on whitespace
1918
enable_static = sys.argv[3]
20-
llconfig = sys.argv[4]
19+
llvm_config = sys.argv[4]
2120

2221
f.write("""// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2322
// file at the top-level directory of this distribution and at
@@ -39,15 +38,15 @@ def run(args):
3938
out, err = proc.communicate()
4039

4140
if err:
42-
print("failed to run llconfig: args = `{}`".format(args))
41+
print("failed to run llvm_config: args = `{}`".format(args))
4342
print(err)
4443
sys.exit(1)
4544
return out
4645

4746
f.write("\n")
4847

4948
# LLVM libs
50-
args = [llconfig, '--libs', '--system-libs']
49+
args = [llvm_config, '--libs', '--system-libs']
5150

5251
args.extend(components)
5352
out = run(args)
@@ -69,13 +68,13 @@ def run(args):
6968
f.write(")]\n")
7069

7170
# LLVM ldflags
72-
out = run([llconfig, '--ldflags'])
71+
out = run([llvm_config, '--ldflags'])
7372
for lib in out.strip().split(' '):
7473
if lib[:2] == "-l":
7574
f.write("#[link(name = \"" + lib[2:] + "\")]\n")
7675

7776
# C++ runtime library
78-
out = run([llconfig, '--cxxflags'])
77+
out = run([llvm_config, '--cxxflags'])
7978
if enable_static == '1':
8079
assert('stdlib=libc++' not in out)
8180
f.write("#[link(name = \"stdc++\", kind = \"static\")]\n")

branches/stable/src/librustc_trans/back/link.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use super::archive::{Archive, ArchiveBuilder, ArchiveConfig, METADATA_FILENAME};
1212
use super::linker::{Linker, GnuLinker, MsvcLinker};
1313
use super::rpath::RPathConfig;
1414
use super::rpath;
15+
use super::msvc;
1516
use super::svh::Svh;
1617
use session::config;
1718
use session::config::NoDebugInfo;
@@ -358,10 +359,14 @@ pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> Stri
358359
mangle(path.chain(Some(gensym_name(flav))), None)
359360
}
360361

361-
pub fn get_cc_prog(sess: &Session) -> String {
362-
match sess.opts.cg.linker {
363-
Some(ref linker) => return linker.to_string(),
364-
None => sess.target.target.options.linker.clone(),
362+
pub fn get_linker(sess: &Session) -> (String, Command) {
363+
if let Some(ref linker) = sess.opts.cg.linker {
364+
(linker.clone(), Command::new(linker))
365+
} else if sess.target.target.options.is_like_msvc {
366+
("link.exe".to_string(), msvc::link_exe_cmd(sess))
367+
} else {
368+
(sess.target.target.options.linker.clone(),
369+
Command::new(&sess.target.target.options.linker))
365370
}
366371
}
367372

@@ -807,8 +812,7 @@ fn link_natively(sess: &Session, trans: &CrateTranslation, dylib: bool,
807812
let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
808813

809814
// The invocations of cc share some flags across platforms
810-
let pname = get_cc_prog(sess);
811-
let mut cmd = Command::new(&pname);
815+
let (pname, mut cmd) = get_linker(sess);
812816
cmd.env("PATH", command_path(sess));
813817

814818
let root = sess.target_filesearch(PathKind::Native).get_lib_path();
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// Copyright 2015 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+
//! MSVC-specific logic for linkers and such.
12+
//!
13+
//! This module contains a cross-platform interface but has a blank unix
14+
//! implementation. The Windows implementation builds on top of Windows native
15+
//! libraries (reading registry keys), so it otherwise wouldn't link on unix.
16+
//!
17+
//! Note that we don't have much special logic for finding the system linker on
18+
//! any other platforms, so it may seem a little odd to single out MSVC to have
19+
//! a good deal of code just to find the linker. Unlike Unix systems, however,
20+
//! the MSVC linker is not in the system PATH by default. It also additionally
21+
//! needs a few environment variables or command line flags to be able to link
22+
//! against system libraries.
23+
//!
24+
//! In order to have a nice smooth experience on Windows, the logic in this file
25+
//! is here to find the MSVC linker and set it up in the default configuration
26+
//! one would need to set up anyway. This means that the Rust compiler can be
27+
//! run not only in the developer shells of MSVC but also the standard cmd.exe
28+
//! shell or MSYS shells.
29+
//!
30+
//! As a high-level note, all logic in this module for looking up various
31+
//! paths/files is copied over from Clang in its MSVCToolChain.cpp file, but
32+
//! comments can also be found below leading through the various code paths.
33+
34+
use std::process::Command;
35+
use session::Session;
36+
37+
#[cfg(windows)]
38+
mod registry;
39+
40+
#[cfg(windows)]
41+
pub fn link_exe_cmd(sess: &Session) -> Command {
42+
use std::env;
43+
use std::ffi::OsString;
44+
use std::fs;
45+
use std::path::PathBuf;
46+
use self::registry::{RegistryKey, LOCAL_MACHINE};
47+
48+
// When finding the link.exe binary the 32-bit version is at the top level
49+
// but the versions to cross to other architectures are stored in
50+
// sub-folders. Unknown architectures also just bail out early to return the
51+
// standard `link.exe` command.
52+
let extra = match &sess.target.target.arch[..] {
53+
"x86" => "",
54+
"x86_64" => "amd64",
55+
"arm" => "arm",
56+
_ => return Command::new("link.exe"),
57+
};
58+
59+
let vs_install_dir = get_vs_install_dir();
60+
61+
// First up, we need to find the `link.exe` binary itself, and there's a few
62+
// locations that we can look. First up is the standard VCINSTALLDIR
63+
// environment variable which is normally set by the vcvarsall.bat file. If
64+
// an environment is set up manually by whomever's driving the compiler then
65+
// we shouldn't muck with that decision and should instead respect that.
66+
//
67+
// Next up is looking in PATH itself. Here we look for `cl.exe` and then
68+
// assume that `link.exe` is next to it if we find it. Note that we look for
69+
// `cl.exe` because MinGW ships /usr/bin/link.exe which is normally found in
70+
// PATH but we're not interested in finding that.
71+
//
72+
// Finally we read the Windows registry to discover the VS install root.
73+
// From here we probe for `link.exe` just to make sure that it exists.
74+
let mut cmd = env::var_os("VCINSTALLDIR").and_then(|dir| {
75+
let mut p = PathBuf::from(dir);
76+
p.push("bin");
77+
p.push(extra);
78+
p.push("link.exe");
79+
if fs::metadata(&p).is_ok() {Some(p)} else {None}
80+
}).or_else(|| {
81+
env::var_os("PATH").and_then(|path| {
82+
env::split_paths(&path).find(|path| {
83+
fs::metadata(&path.join("cl.exe")).is_ok()
84+
}).map(|p| {
85+
p.join("link.exe")
86+
})
87+
})
88+
}).or_else(|| {
89+
vs_install_dir.as_ref().and_then(|p| {
90+
let mut p = p.join("VC/bin");
91+
p.push(extra);
92+
p.push("link.exe");
93+
if fs::metadata(&p).is_ok() {Some(p)} else {None}
94+
})
95+
}).map(|linker| {
96+
Command::new(linker)
97+
}).unwrap_or_else(|| {
98+
Command::new("link.exe")
99+
});
100+
101+
// The MSVC linker uses the LIB environment variable as the default lookup
102+
// path for libraries. This environment variable is normally set up by the
103+
// VS shells, so we only want to start adding our own pieces if it's not
104+
// set.
105+
//
106+
// If we're adding our own pieces, then we need to add two primary
107+
// directories to the default search path for the linker. The first is in
108+
// the VS install direcotry and the next is the Windows SDK directory.
109+
if env::var_os("LIB").is_none() {
110+
if let Some(mut vs_install_dir) = vs_install_dir {
111+
vs_install_dir.push("VC/lib");
112+
vs_install_dir.push(extra);
113+
let mut arg = OsString::from("/LIBPATH:");
114+
arg.push(&vs_install_dir);
115+
cmd.arg(arg);
116+
}
117+
if let Some(path) = get_windows_sdk_lib_path(sess) {
118+
let mut arg = OsString::from("/LIBPATH:");
119+
arg.push(&path);
120+
cmd.arg(arg);
121+
}
122+
}
123+
124+
return cmd;
125+
126+
// When looking for the Visual Studio installation directory we look in a
127+
// number of locations in varying degrees of precedence:
128+
//
129+
// 1. The Visual Studio registry keys
130+
// 2. The Visual Studio Express registry keys
131+
// 3. A number of somewhat standard environment variables
132+
//
133+
// If we find a hit from any of these keys then we strip off the IDE/Tools
134+
// folders which are typically found at the end.
135+
//
136+
// As a final note, when we take a look at the registry keys they're
137+
// typically found underneath the version of what's installed, but we don't
138+
// quite know what's installed. As a result we probe all sub-keys of the two
139+
// keys we're looking at to find out the maximum version of what's installed
140+
// and we use that root directory.
141+
fn get_vs_install_dir() -> Option<PathBuf> {
142+
LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\VisualStudio".as_ref()).or_else(|_| {
143+
LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\VCExpress".as_ref())
144+
}).ok().and_then(|key| {
145+
max_version(&key).and_then(|(_vers, key)| {
146+
key.query_str("InstallDir").ok()
147+
})
148+
}).or_else(|| {
149+
env::var_os("VS120COMNTOOLS")
150+
}).or_else(|| {
151+
env::var_os("VS100COMNTOOLS")
152+
}).or_else(|| {
153+
env::var_os("VS90COMNTOOLS")
154+
}).or_else(|| {
155+
env::var_os("VS80COMNTOOLS")
156+
}).map(PathBuf::from).and_then(|mut dir| {
157+
if dir.ends_with("Common7/IDE") || dir.ends_with("Common7/Tools") {
158+
dir.pop();
159+
dir.pop();
160+
Some(dir)
161+
} else {
162+
None
163+
}
164+
})
165+
}
166+
167+
// Given a registry key, look at all the sub keys and find the one which has
168+
// the maximal numeric value.
169+
//
170+
// Returns the name of the maximal key as well as the opened maximal key.
171+
fn max_version(key: &RegistryKey) -> Option<(OsString, RegistryKey)> {
172+
let mut max_vers = 0;
173+
let mut max_key = None;
174+
for subkey in key.iter().filter_map(|k| k.ok()) {
175+
let val = subkey.to_str().and_then(|s| {
176+
s.trim_left_matches("v").replace(".", "").parse().ok()
177+
});
178+
let val = match val {
179+
Some(s) => s,
180+
None => continue,
181+
};
182+
if val > max_vers {
183+
if let Ok(k) = key.open(&subkey) {
184+
max_vers = val;
185+
max_key = Some((subkey, k));
186+
}
187+
}
188+
}
189+
return max_key
190+
}
191+
192+
fn get_windows_sdk_lib_path(sess: &Session) -> Option<PathBuf> {
193+
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows";
194+
let key = LOCAL_MACHINE.open(key.as_ref());
195+
let (n, k) = match key.ok().as_ref().and_then(max_version) {
196+
Some(p) => p,
197+
None => return None,
198+
};
199+
let mut parts = n.to_str().unwrap().trim_left_matches("v").splitn(2, ".");
200+
let major = parts.next().unwrap().parse::<usize>().unwrap();
201+
let _minor = parts.next().unwrap().parse::<usize>().unwrap();
202+
let path = match k.query_str("InstallationFolder") {
203+
Ok(p) => PathBuf::from(p).join("Lib"),
204+
Err(..) => return None,
205+
};
206+
if major <= 7 {
207+
// In Windows SDK 7.x, x86 libraries are directly in the Lib folder,
208+
// x64 libraries are inside, and it's not necessary to link agains
209+
// the SDK 7.x when targeting ARM or other architectures.
210+
let x86 = match &sess.target.target.arch[..] {
211+
"x86" => true,
212+
"x86_64" => false,
213+
_ => return None,
214+
};
215+
Some(if x86 {path} else {path.join("x64")})
216+
} else {
217+
// Windows SDK 8.x installes libraries in a folder whose names
218+
// depend on the version of the OS you're targeting. By default
219+
// choose the newest, which usually corresponds to the version of
220+
// the OS you've installed the SDK on.
221+
let extra = match &sess.target.target.arch[..] {
222+
"x86" => "x86",
223+
"x86_64" => "x64",
224+
"arm" => "arm",
225+
_ => return None,
226+
};
227+
["winv6.3", "win8", "win7"].iter().map(|p| path.join(p)).find(|part| {
228+
fs::metadata(part).is_ok()
229+
}).map(|path| {
230+
path.join("um").join(extra)
231+
})
232+
}
233+
}
234+
}
235+
236+
#[cfg(not(windows))]
237+
pub fn link_exe_cmd(_sess: &Session) -> Command {
238+
Command::new("link.exe")
239+
}

0 commit comments

Comments
 (0)