@@ -1170,26 +1170,39 @@ fn link_args(cmd: &mut Command,
11701170 // The default library location, we need this to find the runtime.
11711171 // The location of crates will be determined as needed.
11721172 let lib_path = sess. target_filesearch ( ) . get_lib_path ( ) ;
1173- cmd. arg ( "-L" ) . arg ( lib_path) ;
1173+ cmd. arg ( "-L" ) . arg ( & lib_path) ;
11741174
11751175 cmd. arg ( "-o" ) . arg ( out_filename) . arg ( obj_filename) ;
11761176
11771177 // 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).
11821183 //
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!
11861188 //
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+ }
11931206
11941207 // When linking a dynamic library, we put the metadata into a section of the
11951208 // executable. This metadata is in a separate object file from the main
0 commit comments