@@ -5,7 +5,7 @@ use crate::command::Command;
5
5
use crate :: env:: env_var;
6
6
use crate :: path_helpers:: cwd;
7
7
use crate :: util:: set_host_rpath;
8
- use crate :: { is_msvc, is_windows, uname} ;
8
+ use crate :: { is_darwin , is_msvc, is_windows, uname} ;
9
9
10
10
/// Construct a new `rustc` invocation. This will automatically set the library
11
11
/// search path as `-L cwd()`. Use [`bare_rustc`] to avoid this.
@@ -344,10 +344,26 @@ impl Rustc {
344
344
// endif
345
345
// ```
346
346
let flag = if is_windows ( ) {
347
+ // So this is a bit hacky: we can't use the DLL version of libstdc++ because
348
+ // it pulls in the DLL version of libgcc, which means that we end up with 2
349
+ // instances of the DW2 unwinding implementation. This is a problem on
350
+ // i686-pc-windows-gnu because each module (DLL/EXE) needs to register its
351
+ // unwind information with the unwinding implementation, and libstdc++'s
352
+ // __cxa_throw won't see the unwinding info we registered with our statically
353
+ // linked libgcc.
354
+ //
355
+ // Now, simply statically linking libstdc++ would fix this problem, except
356
+ // that it is compiled with the expectation that pthreads is dynamically
357
+ // linked as a DLL and will fail to link with a statically linked libpthread.
358
+ //
359
+ // So we end up with the following hack: we link use static:-bundle to only
360
+ // link the parts of libstdc++ that we actually use, which doesn't include
361
+ // the dependency on the pthreads DLL.
347
362
if is_msvc ( ) { None } else { Some ( "-lstatic:-bundle=stdc++" ) }
363
+ } else if is_darwin ( ) {
364
+ Some ( "-lc++" )
348
365
} else {
349
366
match & uname ( ) [ ..] {
350
- "Darwin" => Some ( "-lc++" ) ,
351
367
"FreeBSD" | "SunOS" | "OpenBSD" => None ,
352
368
_ => Some ( "-lstdc++" ) ,
353
369
}
0 commit comments