@@ -1170,26 +1170,39 @@ fn link_args(cmd: &mut Command,
1170
1170
// The default library location, we need this to find the runtime.
1171
1171
// The location of crates will be determined as needed.
1172
1172
let lib_path = sess. target_filesearch ( ) . get_lib_path ( ) ;
1173
- cmd. arg ( "-L" ) . arg ( lib_path) ;
1173
+ cmd. arg ( "-L" ) . arg ( & lib_path) ;
1174
1174
1175
1175
cmd. arg ( "-o" ) . arg ( out_filename) . arg ( obj_filename) ;
1176
1176
1177
1177
// Stack growth requires statically linking a __morestack function. Note
1178
- // that this is listed *before* all other libraries, even though it may be
1179
- // used to resolve symbols in other libraries. The only case that this
1180
- // wouldn't be pulled in by the object file is if the object file had no
1181
- // functions.
1178
+ // that this is listed *before* all other libraries. Due to the usage of the
1179
+ // --as-needed flag below, the standard library may only be useful for its
1180
+ // rust_stack_exhausted function. In this case, we must ensure that the
1181
+ // libmorestack.a file appears *before* the standard library (so we put it
1182
+ // at the very front).
1182
1183
//
1183
- // If we're building an executable, there must be at least one function (the
1184
- // main function), and if we're building a dylib then we don't need it for
1185
- // later libraries because they're all dylibs (not rlibs).
1184
+ // Most of the time this is sufficient, except for when LLVM gets super
1185
+ // clever. If, for example, we have a main function `fn main() {}`, LLVM
1186
+ // will optimize out calls to `__morestack` entirely because the function
1187
+ // doesn't need any stack at all!
1186
1188
//
1187
- // I'm honestly not entirely sure why this needs to come first. Apparently
1188
- // the --as-needed flag above sometimes strips out libstd from the command
1189
- // line, but inserting this farther to the left makes the
1190
- // "rust_stack_exhausted" symbol an outstanding undefined symbol, which
1191
- // flags libstd as a required library (or whatever provides the symbol).
1192
- cmd. arg ( "-lmorestack" ) ;
1189
+ // To get around this snag, we specially tell the linker to always include
1190
+ // all contents of this library. This way we're guaranteed that the linker
1191
+ // will include the __morestack symbol 100% of the time, always resolving
1192
+ // references to it even if the object above didn't use it.
1193
+ match sess. targ_cfg . os {
1194
+ abi:: OsMacos | abi:: OsiOS => {
1195
+ let morestack = lib_path. join ( "libmorestack.a" ) ;
1196
+
1197
+ let mut v = "-Wl,-force_load," . as_bytes ( ) . to_owned ( ) ;
1198
+ v. push_all ( morestack. as_vec ( ) ) ;
1199
+ cmd. arg ( v. as_slice ( ) ) ;
1200
+ }
1201
+ _ => {
1202
+ cmd. args ( [ "-Wl,--whole-archive" , "-lmorestack" ,
1203
+ "-Wl,--no-whole-archive" ] ) ;
1204
+ }
1205
+ }
1193
1206
1194
1207
// When linking a dynamic library, we put the metadata into a section of the
1195
1208
// executable. This metadata is in a separate object file from the main
0 commit comments