* config/ltmain.m4sh (func_mode_link): Drop `expr: command line too long' error. (func_mode_link) [ gnu, aix ]: Rewrite ld script creation to avoid repeated file opening. (func_mode_link): Rewrite partial linking to avoid quadratic scaling by use of temp files, fold, split, and OUTPUT_LONG_LIST. --- config/ltmain.m4sh 27 Apr 2005 20:30:38 -0000 1.66 +++ config/ltmain.m4sh 19 May 2005 20:18:50 -0000 @@ -5065,14 +5123,14 @@ fi fi - if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*"` && + if test "X$skipped_export" != "X:" && len=`expr "X$test_cmds" : ".*" 2>/dev/null` && test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. - func_echo "creating reloadable object files..." + func_echo "command line too long for linking..." # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we @@ -5087,70 +5145,63 @@ fi save_output=$output output_la=`$ECHO "X$output" | $Xsed -e "$basename"` - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= delfiles= - last_robj= - k=1 if test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_echo "creating GNU ld script: $output" - $ECHO 'INPUT (' > $output - for obj in $save_libobjs - do - $ECHO \""$obj"\" >> $output - done - $ECHO ')' >> $output + ( echo 'INPUT (' + OUTPUT_LONG_LIST([$save_libobjs], ["$always_gentop/scratch3"], ['s/^/"/;s/$/"/']) + echo ')' + ) >"$output" delfiles="$delfiles $output" elif test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_echo "creating linker input file list: $output" - : > $output - for obj in $save_libobjs - do - $ECHO "$obj" >> $output - done + OUTPUT_LONG_LIST([$save_libobjs], ["$always_gentop/scratch3"]) >"$output" delfiles="$delfiles $output" - output=\"$file_list_spec$output\" + output="$file_list_spec$output" else func_echo "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext - # Loop over the list of objects to be linked. - for obj in $save_libobjs + # Clear the reloadable object creation command queue and + # initialize k to one. + concat_cmds= + objlist= + last_robj= + save_libobjs_file=$always_gentop/save_libobjs + save_libobjs_base=$always_gentop/save_libobjs_sep + + OUTPUT_LONG_LIST([$save_libobjs], + ["$always_gentop/scratch3"]) >"$save_libobjs_file" + eval test_cmds=\"$reload_cmds $objlist $last_robj\" + len_netto=`expr "X$test_cmds" : ".*"` \ + || func_fatal_error "too many arguments in \`reload_cmds'" + test "$len_netto" -lt "$max_cmd_len" \ + || func_fatal_error "too many arguments in \`reload_cmds'" + len_allowed=`expr "$max_cmd_len" - "$len_netto"` + func_show_eval "${RM} \"$save_libobjs_base\"?*" + # `fold' accepts long lines, `split' should too. + # We have to split, because `read' is limited to text files. + ( $NL2SP <"$save_libobjs_file"; echo ) \ + | fold -b -s -w "$len_allowed" \ + | split -l 1 - "$save_libobjs_base" + k=0 + kmax=`( set X "$save_libobjs_base"?*; shift; echo $#)` + for objfile in $save_libobjs_base?* do - eval test_cmds=\"$reload_cmds $objlist $last_robj\" - if test "X$objlist" = X || - { len=`expr "X$test_cmds" : ".*"` && - test "$len" -le "$max_cmd_len"; }; then - objlist="$objlist $obj" + k=`expr $k + 1` + output=$output_objdir/$output_la-${k}.$objext + objlist=' '`cat "$objfile"` + if test "$k" -eq 1 ; then + # The first file doesn't have a previous command to add. + eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - eval concat_cmds=\"$reload_cmds $objlist $last_robj\" - else - # All subsequent reloadable object files will link in - # the last one created. - eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - k=`expr $k + 1` - output=$output_objdir/$output_la-${k}.$objext - objlist=$obj - len=1 + # All subsequent reloadable object files will link in + # the last one created. + eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\" fi + last_robj=$output done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if ${skipped_export-false}; then func_echo "generating symbol list for \`$libname.la'" @@ -5164,7 +5215,7 @@ # Set up a command to remove the reloadable object files # after they are used. i=0 - while test "$i" -lt "$k" + while test "$i" -lt "$kmax" do i=`expr $i + 1` delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"