Skip to content

Commit d27bdc4

Browse files
committed
---
yaml --- r: 235899 b: refs/heads/stable c: 7bb585d h: refs/heads/master i: 235897: 97dfbed 235895: d5ad904 v: v3
1 parent bfcd4be commit d27bdc4

File tree

2 files changed

+77
-13
lines changed

2 files changed

+77
-13
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: 95ec4be02b72982246cf3b84133d1e5b1c44f3f6
32+
refs/heads/stable: 7bb585da5b198022e93cb9822fe53d5b1693c762
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc_trans/back/msvc/mod.rs

Lines changed: 76 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
4242
use std::env;
4343
use std::ffi::OsString;
4444
use std::fs;
45-
use std::path::PathBuf;
45+
use std::io;
46+
use std::path::{Path, PathBuf};
4647
use self::registry::{RegistryKey, LOCAL_MACHINE};
4748

4849
// When finding the link.exe binary the 32-bit version is at the top level
@@ -103,16 +104,32 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
103104
// VS shells, so we only want to start adding our own pieces if it's not
104105
// set.
105106
//
106-
// If we're adding our own pieces, then we need to add two primary
107+
// If we're adding our own pieces, then we need to add a few primary
107108
// 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+
// the VS install direcotry, the next is the Windows SDK directory, and the
110+
// last is the possible UCRT installation directory.
111+
//
112+
// The UCRT is a recent addition to Visual Studio installs (2015 at the time
113+
// of this writing), and it's in the normal windows SDK folder, but there
114+
// apparently aren't registry keys pointing to it. As a result we detect the
115+
// installation and then add it manually. This logic will probably need to
116+
// be tweaked over time...
109117
if env::var_os("LIB").is_none() {
110118
if let Some(mut vs_install_dir) = vs_install_dir {
111119
vs_install_dir.push("VC/lib");
112120
vs_install_dir.push(extra);
113121
let mut arg = OsString::from("/LIBPATH:");
114122
arg.push(&vs_install_dir);
115123
cmd.arg(arg);
124+
125+
if let Some((ucrt_root, vers)) = ucrt_install_dir(&vs_install_dir) {
126+
if let Some(arch) = windows_sdk_v8_subdir(sess) {
127+
let mut arg = OsString::from("/LIBPATH:");
128+
arg.push(ucrt_root.join("Lib").join(vers)
129+
.join("ucrt").join(arch));
130+
cmd.arg(arg);
131+
}
132+
}
116133
}
117134
if let Some(path) = get_windows_sdk_lib_path(sess) {
118135
let mut arg = OsString::from("/LIBPATH:");
@@ -189,7 +206,7 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
189206
return max_key
190207
}
191208

192-
fn get_windows_sdk_lib_path(sess: &Session) -> Option<PathBuf> {
209+
fn get_windows_sdk_path() -> Option<(PathBuf, usize)> {
193210
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows";
194211
let key = LOCAL_MACHINE.open(key.as_ref());
195212
let (n, k) = match key.ok().as_ref().and_then(max_version) {
@@ -199,10 +216,17 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
199216
let mut parts = n.to_str().unwrap().trim_left_matches("v").splitn(2, ".");
200217
let major = parts.next().unwrap().parse::<usize>().unwrap();
201218
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,
219+
k.query_str("InstallationFolder").ok().map(|folder| {
220+
(PathBuf::from(folder), major)
221+
})
222+
}
223+
224+
fn get_windows_sdk_lib_path(sess: &Session) -> Option<PathBuf> {
225+
let (mut path, major) = match get_windows_sdk_path() {
226+
Some(p) => p,
227+
None => return None,
205228
};
229+
path.push("Lib");
206230
if major <= 7 {
207231
// In Windows SDK 7.x, x86 libraries are directly in the Lib folder,
208232
// x64 libraries are inside, and it's not necessary to link agains
@@ -218,11 +242,9 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
218242
// depend on the version of the OS you're targeting. By default
219243
// choose the newest, which usually corresponds to the version of
220244
// 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,
245+
let extra = match windows_sdk_v8_subdir(sess) {
246+
Some(e) => e,
247+
None => return None,
226248
};
227249
["winv6.3", "win8", "win7"].iter().map(|p| path.join(p)).find(|part| {
228250
fs::metadata(part).is_ok()
@@ -231,6 +253,48 @@ pub fn link_exe_cmd(sess: &Session) -> Command {
231253
})
232254
}
233255
}
256+
257+
fn windows_sdk_v8_subdir(sess: &Session) -> Option<&'static str> {
258+
match &sess.target.target.arch[..] {
259+
"x86" => Some("x86"),
260+
"x86_64" => Some("x64"),
261+
"arm" => Some("arm"),
262+
_ => return None,
263+
}
264+
}
265+
266+
fn ucrt_install_dir(vs_install_dir: &Path) -> Option<(PathBuf, String)> {
267+
let is_vs_14 = vs_install_dir.iter().filter_map(|p| p.to_str()).any(|s| {
268+
s == "Microsoft Visual Studio 14.0"
269+
});
270+
if !is_vs_14 {
271+
return None
272+
}
273+
let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots";
274+
let sdk_dir = LOCAL_MACHINE.open(key.as_ref()).and_then(|p| {
275+
p.query_str("KitsRoot10")
276+
}).map(PathBuf::from);
277+
let sdk_dir = match sdk_dir {
278+
Ok(p) => p,
279+
Err(..) => return None,
280+
};
281+
(move || -> io::Result<_> {
282+
let mut max = None;
283+
let mut max_s = None;
284+
for entry in try!(fs::read_dir(&sdk_dir.join("Lib"))) {
285+
let entry = try!(entry);
286+
if let Ok(s) = entry.file_name().into_string() {
287+
if let Ok(u) = s.replace(".", "").parse::<usize>() {
288+
if Some(u) > max {
289+
max = Some(u);
290+
max_s = Some(s);
291+
}
292+
}
293+
}
294+
}
295+
Ok(max_s.map(|m| (sdk_dir, m)))
296+
})().ok().and_then(|x| x)
297+
}
234298
}
235299

236300
#[cfg(not(windows))]

0 commit comments

Comments
 (0)