@@ -1331,12 +1331,46 @@ impl Build {
1331
1331
)
1332
1332
}
1333
1333
} ;
1334
+
1334
1335
let mut out = OsString :: from ( "/OUT:" ) ;
1335
1336
out. push ( dst) ;
1336
- run (
1337
- cmd. arg ( out) . arg ( "/nologo" ) . args ( & objects) . args ( & self . objects ) ,
1338
- "lib.exe" ,
1339
- ) ?;
1337
+ cmd. arg ( out) . arg ( "/nologo" ) ;
1338
+
1339
+ // Similar to https://github.com/rust-lang/rust/pull/47507
1340
+ // and https://github.com/rust-lang/rust/pull/48548
1341
+ let estimated_command_line_len =
1342
+ objects. iter ( ) . chain ( & self . objects ) . map ( |a| a. as_os_str ( ) . len ( ) ) . sum :: < usize > ( ) ;
1343
+ if estimated_command_line_len > 1024 * 6 {
1344
+ let mut args = String :: from ( "\u{FEFF} " ) ; // BOM
1345
+ for arg in objects. iter ( ) . chain ( & self . objects ) {
1346
+ args. push ( '"' ) ;
1347
+ for c in arg. to_str ( ) . unwrap ( ) . chars ( ) {
1348
+ if c == '"' {
1349
+ args. push ( '\\' )
1350
+ }
1351
+ args. push ( c)
1352
+ }
1353
+ args. push ( '"' ) ;
1354
+ args. push ( '\n' ) ;
1355
+ }
1356
+
1357
+ let mut utf16le = Vec :: new ( ) ;
1358
+ for code_unit in args. encode_utf16 ( ) {
1359
+ utf16le. push ( code_unit as u8 ) ;
1360
+ utf16le. push ( ( code_unit >> 8 ) as u8 ) ;
1361
+ }
1362
+
1363
+ let mut args_file = OsString :: from ( dst) ;
1364
+ args_file. push ( ".args" ) ;
1365
+ fs:: File :: create ( & args_file) . unwrap ( ) . write_all ( & utf16le) . unwrap ( ) ;
1366
+
1367
+ let mut args_file_arg = OsString :: from ( "@" ) ;
1368
+ args_file_arg. push ( args_file) ;
1369
+ cmd. arg ( args_file_arg) ;
1370
+ } else {
1371
+ cmd. args ( & objects) . args ( & self . objects ) ;
1372
+ }
1373
+ run ( & mut cmd, "lib.exe" ) ?;
1340
1374
1341
1375
// The Rust compiler will look for libfoo.a and foo.lib, but the
1342
1376
// MSVC linker will also be passed foo.lib, so be sure that both
0 commit comments