use std::fs::{self, PathExt};
use std::io::{self, Read, Write};
use std::mem;
-use std::path::{Path, PathBuf};
+use std::path::{self, Path, PathBuf};
use std::process::Command;
use std::str;
use flate;
// target descriptor
let t = &sess.target.target;
- cmd.arg("-L").arg(&lib_path);
+ cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(&lib_path));
cmd.arg("-o").arg(out_filename).arg(obj_filename);
// stripped away as much as it could. This has not been seen to impact
// link times negatively.
//
- // -dead_strip can't be part of the pre_link_args because it's also used for partial
- // linking when using multiple codegen units (-r). So we insert it here.
+ // -dead_strip can't be part of the pre_link_args because it's also used
+ // for partial linking when using multiple codegen units (-r). So we
+ // insert it here.
cmd.arg("-Wl,-dead_strip");
}
has_rpath: sess.target.target.options.has_rpath,
is_like_osx: sess.target.target.options.is_like_osx,
get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
- realpath: &mut ::util::fs::realpath
};
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
}
}
});
} else {
- cmd.arg(cratepath);
+ cmd.arg(&fix_windows_verbatim_for_gcc(cratepath));
}
}
// Just need to tell the linker about where the library lives and
// what its name is
if let Some(dir) = cratepath.parent() {
- cmd.arg("-L").arg(dir);
+ cmd.arg("-L").arg(&fix_windows_verbatim_for_gcc(dir));
}
let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
}
}
}
+
+// Unfortunately, on windows, gcc cannot accept paths of the form `\\?\C:\...`
+// (a verbatim path). This form of path is generally pretty rare, but the
+// implementation of `fs::canonicalize` currently generates paths of this form,
+// meaning that we're going to be passing quite a few of these down to gcc.
+//
+// For now we just strip the "verbatim prefix" of `\\?\` from the path. This
+// will probably lose information in some cases, but there's not a whole lot
+// more we can do with a buggy gcc...
+fn fix_windows_verbatim_for_gcc(p: &Path) -> PathBuf {
+ if !cfg!(windows) {
+ return p.to_path_buf()
+ }
+ let mut components = p.components();
+ let prefix = match components.next() {
+ Some(path::Component::Prefix(p)) => p,
+ _ => return p.to_path_buf(),
+ };
+ let disk = match prefix.kind() {
+ path::Prefix::VerbatimDisk(disk) => disk,
+ _ => return p.to_path_buf(),
+ };
+ let mut base = OsString::from(format!("{}:", disk as char));
+ base.push(components.as_path());
+ PathBuf::from(base)
+}