@@ -1774,66 +1774,25 @@ impl Build {
17741774 }
17751775
17761776 fn assemble ( & self , lib_name : & str , dst : & Path , objs : & [ Object ] ) -> Result < ( ) , Error > {
1777- // Delete the destination if it exists as the `ar` tool at least on Unix
1778- // appends to it, which we don't want .
1777+ // Delete the destination if it exists as we want to
1778+ // create on the first iteration instead of appending .
17791779 let _ = fs:: remove_file ( & dst) ;
1780-
1781- let objects: Vec < _ > = objs. iter ( ) . map ( |obj| obj. dst . clone ( ) ) . collect ( ) ;
17821780 let target = self . get_target ( ) ?;
1783- if target. contains ( "msvc" ) {
1784- let ( mut cmd, program) = self . get_ar ( ) ?;
1785- let mut out = OsString :: from ( "-out:" ) ;
1786- out. push ( dst) ;
1787- cmd. arg ( out) . arg ( "-nologo" ) ;
1788- for flag in self . ar_flags . iter ( ) {
1789- cmd. arg ( flag) ;
1790- }
1791-
1792- // Similar to https://github.com/rust-lang/rust/pull/47507
1793- // and https://github.com/rust-lang/rust/pull/48548
1794- let estimated_command_line_len = objects
1795- . iter ( )
1796- . chain ( & self . objects )
1797- . map ( |a| a. as_os_str ( ) . len ( ) )
1798- . sum :: < usize > ( ) ;
1799- if estimated_command_line_len > 1024 * 6 {
1800- let mut args = String :: from ( "\u{FEFF} " ) ; // BOM
1801- for arg in objects. iter ( ) . chain ( & self . objects ) {
1802- args. push ( '"' ) ;
1803- for c in arg. to_str ( ) . unwrap ( ) . chars ( ) {
1804- if c == '"' {
1805- args. push ( '\\' )
1806- }
1807- args. push ( c)
1808- }
1809- args. push ( '"' ) ;
1810- args. push ( '\n' ) ;
1811- }
1812-
1813- let mut utf16le = Vec :: new ( ) ;
1814- for code_unit in args. encode_utf16 ( ) {
1815- utf16le. push ( code_unit as u8 ) ;
1816- utf16le. push ( ( code_unit >> 8 ) as u8 ) ;
1817- }
1818-
1819- let mut args_file = OsString :: from ( dst) ;
1820- args_file. push ( ".args" ) ;
1821- fs:: File :: create ( & args_file)
1822- . unwrap ( )
1823- . write_all ( & utf16le)
1824- . unwrap ( ) ;
1781+ let objs: Vec < _ > = objs
1782+ . iter ( )
1783+ . map ( |o| o. dst . clone ( ) )
1784+ . chain ( self . objects . clone ( ) )
1785+ . collect ( ) ;
18251786
1826- let mut args_file_arg = OsString :: from ( "@" ) ;
1827- args_file_arg. push ( args_file) ;
1828- cmd. arg ( args_file_arg) ;
1829- } else {
1830- cmd. args ( & objects) . args ( & self . objects ) ;
1831- }
1832- run ( & mut cmd, & program) ?;
1787+ for chunk in objs. chunks ( 100 ) {
1788+ self . assemble_progressive ( dst, chunk) ?;
1789+ }
18331790
1791+ if target. contains ( "msvc" ) {
18341792 // The Rust compiler will look for libfoo.a and foo.lib, but the
18351793 // MSVC linker will also be passed foo.lib, so be sure that both
18361794 // exist for now.
1795+
18371796 let lib_dst = dst. with_file_name ( format ! ( "{}.lib" , lib_name) ) ;
18381797 let _ = fs:: remove_file ( & lib_dst) ;
18391798 match fs:: hard_link ( & dst, & lib_dst) . or_else ( |_| {
@@ -1848,6 +1807,29 @@ impl Build {
18481807 ) ) ;
18491808 }
18501809 } ;
1810+ }
1811+
1812+ Ok ( ( ) )
1813+ }
1814+
1815+ fn assemble_progressive ( & self , dst : & Path , objs : & [ PathBuf ] ) -> Result < ( ) , Error > {
1816+ let target = self . get_target ( ) ?;
1817+
1818+ if target. contains ( "msvc" ) {
1819+ let ( mut cmd, program) = self . get_ar ( ) ?;
1820+ let mut out = OsString :: from ( "-out:" ) ;
1821+ out. push ( dst) ;
1822+ cmd. arg ( out) . arg ( "-nologo" ) ;
1823+ for flag in self . ar_flags . iter ( ) {
1824+ cmd. arg ( flag) ;
1825+ }
1826+ // If the library file already exists, add the libary name
1827+ // as an argument to let lib.exe know we are appending the objs.
1828+ if dst. exists ( ) {
1829+ cmd. arg ( dst) ;
1830+ }
1831+ cmd. args ( objs) ;
1832+ run ( & mut cmd, & program) ?;
18511833 } else {
18521834 let ( mut ar, cmd) = self . get_ar ( ) ?;
18531835
@@ -1877,10 +1859,7 @@ impl Build {
18771859 for flag in self . ar_flags . iter ( ) {
18781860 ar. arg ( flag) ;
18791861 }
1880- run (
1881- ar. arg ( "crs" ) . arg ( dst) . args ( & objects) . args ( & self . objects ) ,
1882- & cmd,
1883- ) ?;
1862+ run ( ar. arg ( "crs" ) . arg ( dst) . args ( objs) , & cmd) ?;
18841863 }
18851864
18861865 Ok ( ( ) )
0 commit comments