Skip to content

Commit 4069647

Browse files
committed
Auto merge of #67429 - mati865:mingw-ultimate-fix, r=<try>
[WIP] windows-gnu: prefer system crt libraries if they are available This is my proposal (based on `Amanieu`'s idea) on how to fix #47048 and related issues. The origin of the issue is the fact Rust ships mingw-w64 libraries but no headers and prefers own libraries over the system ones. This leads to situation when headers aren't compatible with libraries (mingw-w64 doesn't provide any forward compatibility and AFAIK backwards compatibility is guaranteed only within major release series). It's easier to understand how this PR works when looking at the linker invocation before and with this PR: https://www.diffchecker.com/GEuYFmzo It adds system libraries path before Rust libraries so the linker will prefer them. It has potential issue when system has files with the same names as Rust but that could be avoided by moving Rust shipped mingw-w64 libraries from `lib/rustlib/x86_64-pc-windows-gnu/lib` to say `lib/rustlib/x86_64-pc-windows-gnu/lib/mingw`. Then adding linker paths in this order: Rust libraries, system libraries, Rust shipped mingw-w64 libraries. I don't know if it's worth to cache system libraries path. You can look for `cache: ` string during build Rust: https://pastebin.com/kGEQZGWP I think there are enough calls to justify caching. Obvious shortcoming here is this version works only on windows-gnu host because of `#[cfg(all(windows, target_env = "gnu"))]` but you should get the idea.
2 parents 25434f8 + 0e093bb commit 4069647

File tree

4 files changed

+62
-56
lines changed

4 files changed

+62
-56
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -3392,6 +3392,7 @@ dependencies = [
33923392
"bitflags",
33933393
"cc",
33943394
"jobserver",
3395+
"lazy_static 1.3.0",
33953396
"libc",
33963397
"log",
33973398
"memmap",

src/ci/azure-pipelines/try.yml

+13-56
Original file line numberDiff line numberDiff line change
@@ -15,59 +15,16 @@ jobs:
1515
strategy:
1616
matrix:
1717
dist-x86_64-linux: {}
18-
dist-x86_64-linux-alt:
19-
IMAGE: dist-x86_64-linux
20-
21-
# The macOS and Windows builds here are currently disabled due to them not being
22-
# overly necessary on `try` builds. We also don't actually have anything that
23-
# consumes the artifacts currently. Perhaps one day we can reenable, but for now
24-
# it helps free up capacity on Azure.
25-
# - job: macOS
26-
# timeoutInMinutes: 600
27-
# pool:
28-
# vmImage: macos-10.13
29-
# steps:
30-
# - template: steps/run.yml
31-
# strategy:
32-
# matrix:
33-
# dist-x86_64-apple:
34-
# SCRIPT: ./x.py dist
35-
# RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc
36-
# DEPLOY: 1
37-
# RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
38-
# MACOSX_DEPLOYMENT_TARGET: 10.7
39-
# NO_LLVM_ASSERTIONS: 1
40-
# NO_DEBUG_ASSERTIONS: 1
41-
# DIST_REQUIRE_ALL_TOOLS: 1
42-
#
43-
# dist-x86_64-apple-alt:
44-
# SCRIPT: ./x.py dist
45-
# RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc
46-
# DEPLOY_ALT: 1
47-
# RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
48-
# MACOSX_DEPLOYMENT_TARGET: 10.7
49-
# NO_LLVM_ASSERTIONS: 1
50-
# NO_DEBUG_ASSERTIONS: 1
51-
#
52-
# - job: Windows
53-
# timeoutInMinutes: 600
54-
# pool:
55-
# vmImage: 'vs2017-win2016'
56-
# steps:
57-
# - template: steps/run.yml
58-
# strategy:
59-
# matrix:
60-
# dist-x86_64-msvc:
61-
# RUST_CONFIGURE_ARGS: >
62-
# --build=x86_64-pc-windows-msvc
63-
# --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
64-
# --enable-full-tools
65-
# --enable-profiler
66-
# SCRIPT: python x.py dist
67-
# DIST_REQUIRE_ALL_TOOLS: 1
68-
# DEPLOY: 1
69-
#
70-
# dist-x86_64-msvc-alt:
71-
# RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
72-
# SCRIPT: python x.py dist
73-
# DEPLOY_ALT: 1
18+
- job: Windows
19+
timeoutInMinutes: 600
20+
pool:
21+
vmImage: 'vs2017-win2016'
22+
steps:
23+
- template: steps/run.yml
24+
strategy:
25+
matrix:
26+
dist-x86_64-mingw:
27+
SCRIPT: python x.py dist
28+
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-gnu --enable-full-tools --enable-profiler
29+
CUSTOM_MINGW: 1
30+
DIST_REQUIRE_ALL_TOOLS: 1

src/librustc_codegen_ssa/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ bitflags = "1.2.1"
1414
cc = "1.0.1"
1515
num_cpus = "1.0"
1616
memmap = "0.7"
17+
lazy_static = "1"
1718
log = "0.4.5"
1819
libc = "0.2.44"
1920
jobserver = "0.1.11"

src/librustc_codegen_ssa/back/link.rs

+47
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,48 @@ pub fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLibrary
918918
}
919919
}
920920

921+
fn get_compiler_libs_path(sess: &Session) -> Option<PathBuf> {
922+
use std::sync::Mutex;
923+
924+
lazy_static::lazy_static! {
925+
static ref SYSTEM_LIBS: Mutex<Option<PathBuf>> = Mutex::new(None);
926+
}
927+
928+
let system_libs = SYSTEM_LIBS.lock().unwrap().clone();
929+
if let Some(compiler_libs_path) = system_libs {
930+
println!("cache: hit");
931+
return Some(compiler_libs_path);
932+
} else {
933+
println!("cache: miss");
934+
let compiler = if let Some(linker) = &sess.opts.cg.linker {
935+
linker.clone().into_os_string()
936+
} else if let Some(linker) = &sess.target.target.options.linker {
937+
linker.into()
938+
} else {
939+
return None;
940+
};
941+
if let Ok(output) = Command::new(compiler).arg("-print-file-name=crt2.o").output() {
942+
if let Some(compiler_libs_path) =
943+
PathBuf::from(std::str::from_utf8(&output.stdout).unwrap()).parent()
944+
{
945+
let compiler_libs_path = fix_windows_verbatim_for_gcc(compiler_libs_path);
946+
*SYSTEM_LIBS.lock().unwrap() = Some(compiler_libs_path.clone());
947+
return Some(compiler_libs_path);
948+
}
949+
}
950+
}
951+
None
952+
}
953+
921954
pub fn get_file_path(sess: &Session, name: &str) -> PathBuf {
955+
if sess.target.target.llvm_target.contains("windows-gnu") {
956+
if let Some(compiler_libs_path) = get_compiler_libs_path(sess) {
957+
let file_path = compiler_libs_path.join(name);
958+
if file_path.exists() {
959+
return file_path;
960+
}
961+
}
962+
}
922963
let fs = sess.target_filesearch(PathKind::Native);
923964
let file_path = fs.get_lib_path().join(name);
924965
if file_path.exists() {
@@ -1100,6 +1141,12 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
11001141
// target descriptor
11011142
let t = &sess.target.target;
11021143

1144+
if sess.target.target.llvm_target.contains("windows-gnu") {
1145+
if let Some(compiler_libs_path) = get_compiler_libs_path(sess) {
1146+
cmd.include_path(&compiler_libs_path);
1147+
}
1148+
}
1149+
11031150
cmd.include_path(&fix_windows_verbatim_for_gcc(&lib_path));
11041151

11051152
for obj in codegen_results.modules.iter().filter_map(|m| m.object.as_ref()) {

0 commit comments

Comments
 (0)