Skip to content

Commit 7bd7163

Browse files
committed
Auto merge of #25134 - alexcrichton:fix-issue-25072-for-realsies, r=brson
Turns out that a verbatim path was leaking through to gcc via the PATH environment variable (pointing to the bundled gcc provided by the main distribution) which was wreaking havoc when gcc itself was run. The fix here is to just stop passing verbatim paths down by adding more liberal uses of `fix_windows_verbatim_for_gcc`. Closes #25072
2 parents 252b544 + 2dc0e56 commit 7bd7163

File tree

6 files changed

+51
-31
lines changed

6 files changed

+51
-31
lines changed

src/librustc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ pub mod util {
147147
pub mod nodemap;
148148
pub mod lev_distance;
149149
pub mod num;
150+
pub mod fs;
150151
}
151152

152153
pub mod lib {

src/librustc/metadata/filesearch.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use std::io::prelude::*;
1919
use std::path::{Path, PathBuf};
2020

2121
use session::search_paths::{SearchPaths, PathKind};
22+
use util::fs as rustcfs;
2223

2324
#[derive(Copy, Clone)]
2425
pub enum FileMatch {
@@ -191,7 +192,10 @@ pub fn get_or_default_sysroot() -> PathBuf {
191192
fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
192193
path.and_then(|path| {
193194
match fs::canonicalize(&path) {
194-
Ok(canon) => Some(canon),
195+
// See comments on this target function, but the gist is that
196+
// gcc chokes on verbatim paths which fs::canonicalize generates
197+
// so we try to avoid those kinds of paths.
198+
Ok(canon) => Some(rustcfs::fix_windows_verbatim_for_gcc(&canon)),
195199
Err(e) => panic!("failed to get realpath: {}", e),
196200
}
197201
})

src/librustc/session/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ pub struct Session {
4646
pub entry_type: Cell<Option<config::EntryFnType>>,
4747
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
4848
pub default_sysroot: Option<PathBuf>,
49-
// The name of the root source file of the crate, in the local file system. The path is always
50-
// expected to be absolute. `None` means that there is no source file.
49+
// The name of the root source file of the crate, in the local file system.
50+
// The path is always expected to be absolute. `None` means that there is no
51+
// source file.
5152
pub local_crate_source_file: Option<PathBuf>,
5253
pub working_dir: PathBuf,
5354
pub lint_store: RefCell<lint::LintStore>,

src/librustc/util/fs.rs

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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+
use std::path::{self, Path, PathBuf};
12+
use std::ffi::OsString;
13+
14+
// Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...`
15+
// (a verbatim path). This form of path is generally pretty rare, but the
16+
// implementation of `fs::canonicalize` currently generates paths of this form,
17+
// meaning that we're going to be passing quite a few of these down to gcc.
18+
//
19+
// For now we just strip the "verbatim prefix" of `\\?\` from the path. This
20+
// will probably lose information in some cases, but there's not a whole lot
21+
// more we can do with a buggy gcc...
22+
pub fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
23+
if !cfg!(windows) {
24+
return p.to_path_buf()
25+
}
26+
let mut components = p.components();
27+
let prefix = match components.next() {
28+
Some(path::Component::Prefix(p)) => p,
29+
_ => return p.to_path_buf(),
30+
};
31+
let disk = match prefix.kind() {
32+
path::Prefix::VerbatimDisk(disk) => disk,
33+
_ => return p.to_path_buf(),
34+
};
35+
let mut base = OsString::from(format!("{}:", disk as char));
36+
base.push(components.as_path());
37+
PathBuf::from(base)
38+
}

src/librustc_driver/driver.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,8 @@ pub fn phase_2_configure_and_expand(sess: &Session,
479479
let mut _old_path = OsString::new();
480480
if cfg!(windows) {
481481
_old_path = env::var_os("PATH").unwrap_or(_old_path);
482-
let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
482+
let mut new_path = sess.host_filesearch(PathKind::All)
483+
.get_dylib_search_paths();
483484
new_path.extend(env::split_paths(&_old_path));
484485
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
485486
}

src/librustc_trans/back/link.rs

+2-27
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ use middle::ty::{self, Ty};
2626
use util::common::time;
2727
use util::ppaux;
2828
use util::sha2::{Digest, Sha256};
29+
use util::fs::fix_windows_verbatim_for_gcc;
2930
use rustc_back::tempdir::TempDir;
3031

3132
use std::ffi::OsString;
3233
use std::fs::{self, PathExt};
3334
use std::io::{self, Read, Write};
3435
use std::mem;
35-
use std::path::{self, Path, PathBuf};
36+
use std::path::{Path, PathBuf};
3637
use std::process::Command;
3738
use std::str;
3839
use flate;
@@ -1333,29 +1334,3 @@ fn add_upstream_native_libraries(cmd: &mut Command, sess: &Session) {
13331334
}
13341335
}
13351336
}
1336-
1337-
// Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...`
1338-
// (a verbatim path). This form of path is generally pretty rare, but the
1339-
// implementation of `fs::canonicalize` currently generates paths of this form,
1340-
// meaning that we're going to be passing quite a few of these down to gcc.
1341-
//
1342-
// For now we just strip the "verbatim prefix" of `\\?\` from the path. This
1343-
// will probably lose information in some cases, but there's not a whole lot
1344-
// more we can do with a buggy gcc...
1345-
fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
1346-
if !cfg!(windows) {
1347-
return p.to_path_buf()
1348-
}
1349-
let mut components = p.components();
1350-
let prefix = match components.next() {
1351-
Some(path::Component::Prefix(p)) => p,
1352-
_ => return p.to_path_buf(),
1353-
};
1354-
let disk = match prefix.kind() {
1355-
path::Prefix::VerbatimDisk(disk) => disk,
1356-
_ => return p.to_path_buf(),
1357-
};
1358-
let mut base = OsString::from(format!("{}:", disk as char));
1359-
base.push(components.as_path());
1360-
PathBuf::from(base)
1361-
}

0 commit comments

Comments
 (0)