]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
Support for piecewise linking to allow very large libraries to be built.
authorRobert Boehne <rboehne@ricardo-us.com>
Fri, 23 Feb 2001 20:12:00 +0000 (20:12 +0000)
committerRobert Boehne <rboehne@gnu.org>
Fri, 23 Feb 2001 20:12:00 +0000 (20:12 +0000)
ChangeLog
doc/libtool.texi
ltconfig.in
ltmain.in

index 329b5516096374a6c28d25bba471c29d2dcd63e9..965876c0734af425ba055da043140c1d0cb5853a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2001-02-22  Robert Boehne  <rboehne@ricardo-us.com>
+
+       * ltconfig.in: Add a test to find the approximate limit
+       to the length of command line arguments.  The number
+       calculated here should always be lower than the actual
+       limit.
+       * ltmain.in: Test the length of the command line to be
+       executed and use an incremtnal linking scheme if the
+       command is too long to be interpreted without error.
+       * doc: Test the length of the command line to be
+       executed and use an incremtnal linking scheme if the
+       command is too long to be interpreted without error.
+       * doc/libtool.texi (Reloadable Objects): Added a few
+       sentences to describe how piecewise linking is done
+       for shared objects by creating reloadable object files.
+
 2001-02-20  Gary Vaughan  <gvv@techie.com>
 
        * libltdl/ltdl.c (lt_dlcaller_register): dont set an unsigned
index 822780bc8a462a006aabf1a04dcc69f2a0c10a61..9137c406d0ef5f3d89698cb3b15f5de6095862e8 100644 (file)
@@ -4367,7 +4367,11 @@ Use @samp{-PIC} to generate PIC.
 On all known systems, a reloadable object can be created by running
 @kbd{ld -r -o @var{output}.o @var{input1}.o @var{input2}.o}.  This
 reloadable object may be treated as exactly equivalent to other
-objects.
+objects.  This is the piecewise method that libtool uses to get around
+shell limitations when building large libraries.  The object files
+created by libtool are linked together in as few steps as necessary
+into a single reloadable object file.  This temporary object file
+is then used to generate a shared library.
 
 @node Archivers
 @subsection Archivers
index f41cfb73c9e6f1db2572663e1606021f0c803390..2566190a98157c387c18b1b0667cf8b2347c8dbd 100755 (executable)
@@ -216,6 +216,7 @@ need_locks=yes
 ac_ext=c
 libext=a
 cache_file=
+max_cmd_len=
 
 ## Dependencies to place before and after the object being linked:
 predep_objects=
@@ -774,6 +775,37 @@ link_static_flag="$ac_cv_prog_cc_static"
 no_builtin_flag="$ac_cv_prog_cc_no_builtin"
 can_build_shared="$ac_cv_prog_cc_can_build_shared"
 
+# find the maximum length of command line arguments
+echo "$progname:@LINENO@: finding the maximum length of command line arguments" 1>&5
+echo $ac_n "finding the maximum length of command line arguments... $ac_c" 1>&6
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  i=0
+  testring="ABCDEF"
+  while test `$CONFIG_SHELL $0 --fallback-echo "X$testring" >/dev/null 2>&1` == `echo "X$testring" >/dev/null 2>&1` &&
+          new_result=`expr "X$testring" : ".*" 2>&1` &&
+          lt_cv_sys_max_cmd_len=$new_result &&
+          test $i != 32 # 1 MB should be enough
+  do
+    i=`expr $i + 1`
+    testring=$testring$testring
+  done
+  testring=
+  # add a significant safety factor because C++ compilers can tack on massive amounts
+  # of additional arguments before passing them to the linker.  1/4 should be good.
+  len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+  lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len - $len`
+fi
+echo "$progname:@lineno@: result: $lt_cv_sys_max_cmd_len" 1>&5
+echo "${ac_t}$lt_cv_sys_max_cmd_len" 1>&6
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  max_cmd_len=$lt_cv_sys_max_cmd_len
+else
+  max_cmd_len=none
+fi
+
 # Check to see if options -o and -c are simultaneously supported by compiler
 echo $ac_n "checking if $compiler supports -c -o file.$objext... $ac_c" 1>&6
 $rm -r conftest 2>/dev/null
@@ -2222,6 +2254,9 @@ exeext="$exeext"
 pic_flag=$pic_flag
 pic_mode=$pic_mode
 
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
 # Does compiler simultaneously support -c and -o options?
 compiler_c_o=$compiler_c_o
 
index 504dedb227705e3081112f60901ca3b2729dcbac..b510409717c7a6c10ededb5fb7f28923738943eb 100644 (file)
--- a/ltmain.in
+++ b/ltmain.in
@@ -3007,13 +3007,90 @@ EOF
        else
          eval cmds=\"$archive_cmds\"
        fi
-       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
-       for cmd in $cmds; do
-         IFS="$save_ifs"
-         $show "$cmd"
-         $run eval "$cmd" || exit $?
-       done
-       IFS="$save_ifs"
+        if len=`expr "X$cmds" : ".*"` &&
+           test $len -le $max_cmd_len; then
+          :
+        else
+          # the command line is too long to link in one step, link piecewise
+          $echo "creating reloadable object files..."
+          # save the value of $output and $libobjs because we want to use them later
+          save_libobjs=$libobjs
+          save_output=$output
+          # clear the reloadable object creation command queue and initialize k to one.
+          test_cmds=
+          concat_cmds=
+          objlist=
+          delfiles=
+          last_robj=
+          k=1
+          output=$output_objdir/$save_output-${k}.$objext
+          # loop over the list of objects to be linked
+          for obj in $save_libobjs
+          do
+            eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+            if len=`expr "X$test_cmds" : ".*"` &&
+                  test $len -le $max_cmd_len; then
+              objlist="$objlist $obj"
+            else
+              # the command $test_cmds is almost too long
+              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/$save_output-${k}.$objext
+              k=`expr $k + 1`
+              output=$output_objdir/$save_output-${k}.$objext
+              objlist=$obj
+              len=1
+            fi
+          done
+          # handle the remaining objects by creating one last reloadable object file
+          # all subsequent reloadable object files will link in the last one created
+          eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+
+          # set up a command to remove the reloadale object files
+          i=0
+          while test $i -lt $k
+          do
+            i=`expr $i + 1`
+            delfiles="$delfiles $output_objdir/$save_output-${i}.$objext"
+          done
+
+          $echo "creating a temporary reloadable object file: $output"
+
+          # loop through the commands generated above and execute them
+          IFS="${IFS=  }"; save_ifs="$IFS"; IFS='~'
+          for cmd in $concat_cmds; do
+            IFS="$save_ifs"
+            $show "$cmd"
+            $run eval "$cmd" || exit $?
+          done
+          IFS="$save_ifs"
+
+          libobjs=$output
+          # restore the value of output
+          output=$save_output
+
+          # expand the library linking commands again to reset the value of $libobjs for piecewise linking
+          # Do each of the archive commands.
+          if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+            eval cmds=\"$archive_expsym_cmds\"
+          else
+            eval cmds=\"$archive_cmds\"
+          fi
+          # append the command to remove the reloadable object files to the just-reset $cmds
+          eval cmds=\"\$cmds~$rm $delfiles\"
+        fi
+        IFS="${IFS=    }"; save_ifs="$IFS"; IFS='~'
+        for cmd in $cmds; do
+          IFS="$save_ifs"
+          $show "$cmd"
+          $run eval "$cmd" || exit $?
+        done
+        IFS="$save_ifs"
 
        # Restore the uninstalled library and exit
        if test "$mode" = relink; then
@@ -3913,7 +3990,36 @@ fi\
 #        fi
 #      done
 
-       eval cmds=\"$old_archive_cmds\"
+        eval cmds=\"$old_archive_cmds\"
+
+        if len=`expr "X$cmds" : ".*"` &&
+             test $len -le $max_cmd_len; then
+          :
+        else
+          # the command line is too long to link in one step, link in parts
+          $echo "using piecewise archive linking..."
+          objlist=
+          concat_cmds=
+          save_oldobjs=$oldobjs
+          for obj in $save_oldobjs
+          do
+            oldobjs="$objlist $obj"
+            objlist="$objlist $obj"
+            eval test_cmds=\"$old_archive_cmds\"
+            if len=`expr "X$test_cmds" : ".*"` &&
+               test $len -le $max_cmd_len; then
+              :
+            else
+              # the above command should be used before it gets too long
+              oldobjs=$objlist
+              eval concat_cmds=\"\$old_archive_cmds~$concat_cmds\"
+              objlist=
+            fi
+          done
+          oldobjs=$objlist
+          eval concat_cmds=\"\$old_archive_cmds~$concat_cmds\"
+          eval cmds=\"$concat_cmds\"
+        fi
       fi
       IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
       for cmd in $cmds; do