Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Statically link libstdc++ on windows-gnu #65911

Merged
merged 1 commit into from
Nov 5, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
@@ -657,11 +657,11 @@ pub fn build_codegen_backend(builder: &Builder<'_>,
if let Some(ref s) = builder.config.llvm_ldflags {
cargo.env("LLVM_LINKER_FLAGS", s);
}
// Building with a static libstdc++ is only supported on linux right now,
// Building with a static libstdc++ is only supported on linux and mingw right now,
// not for MSVC or macOS
if builder.config.llvm_static_stdcpp &&
!target.contains("freebsd") &&
!target.contains("windows") &&
!target.contains("msvc") &&
!target.contains("apple") {
let file = compiler_file(builder,
builder.cxx(target).unwrap(),
2 changes: 1 addition & 1 deletion src/bootstrap/dist.rs
Original file line number Diff line number Diff line change
@@ -236,7 +236,7 @@ fn make_win_dist(
}

let target_tools = ["gcc.exe", "ld.exe", "dlltool.exe", "libwinpthread-1.dll"];
let mut rustc_dlls = vec!["libstdc++-6.dll", "libwinpthread-1.dll"];
let mut rustc_dlls = vec!["libwinpthread-1.dll"];
if target_triple.starts_with("i686-") {
rustc_dlls.push("libgcc_s_dw2-1.dll");
} else {
4 changes: 2 additions & 2 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
@@ -159,7 +159,7 @@ impl Step for Llvm {

// For distribution we want the LLVM tools to be *statically* linked to libstdc++
if builder.config.llvm_tools_enabled || builder.config.lldb_enabled {
if !target.contains("windows") {
if !target.contains("msvc") {
if target.contains("apple") {
cfg.define("CMAKE_EXE_LINKER_FLAGS", "-static-libstdc++");
} else {
@@ -395,7 +395,7 @@ fn configure_cmake(builder: &Builder<'_>,
cfg.define("CMAKE_C_FLAGS", cflags);
let mut cxxflags = builder.cflags(target, GitRepo::Llvm).join(" ");
if builder.config.llvm_static_stdcpp &&
!target.contains("windows") &&
!target.contains("msvc") &&
!target.contains("netbsd")
{
cxxflags.push_str(" -static-libstdc++");
6 changes: 5 additions & 1 deletion src/librustc_llvm/build.rs
Original file line number Diff line number Diff line change
@@ -279,7 +279,11 @@ fn main() {
let path = PathBuf::from(s);
println!("cargo:rustc-link-search=native={}",
path.parent().unwrap().display());
println!("cargo:rustc-link-lib=static={}", stdcppname);
if target.contains("windows") {
println!("cargo:rustc-link-lib=static-nobundle={}", stdcppname);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may cause distribution issues since we ship rustc_llvm and users like clippy/plugins will link to rustc_llvm transitively through rustc_driver, was there a reason though static didn't work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think quite nasty or I'm just misunderstanding.

First let's take a look at static libstdc++:

nm /mingw64/lib/gcc/x86_64-w64-mingw32/9.2.0/libstdc++.a | grep pthread_mutex_init
                 U __imp_pthread_mutex_init
                 U pthread_mutex_init
                 U pthread_mutex_init
                 [..]

There are references to both static and dynamic symbols!

Now using static failed undefined with 2 undefined symbols: __imp_pthread_mutex_{destroy,init}. I honestly have no idea why picked dynamic symbols, though I haven't chased that rabbit.
It could be mitigated by dynamically linking to winpthread library (by removing static in line 298), windows-gnu ships libwinpthread-1.dll anyway because. But I felt it's just replacing one problem with another.

With some guidance I could try to investigate why picks dynamic pthread symbols when using static but static-nobundle seems to fit here (I asked for try build in OP to be sure).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same issue in #65646, with a similar workaround: a505735

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm ok, I'm not really sure what's going on with static vs static-nobundle, but now that I think about this we're linking this into librustc_driver.so where the "nobundle" part won't keep propagating, so this doesn't actually affect consumers, and as a result should be fine to land.

} else {
println!("cargo:rustc-link-lib=static={}", stdcppname);
}
} else if cxxflags.contains("stdlib=libc++") {
println!("cargo:rustc-link-lib=c++");
} else {