[Mingw-users] Solving the "relink exe's" libtool problem

Michael Bester michael.bester@gmx.net
Mon Jan 13 03:04:00 GMT 2003


Charles Wilson wrote:

> [cross posted.  Please keep (at least) cygwin@cygwin.com in all 
> replies, especially as the @gnu.org mailserver has not been archiving 
> all messages]
>
> There has been a long-standing problem with libtool on windows-ish 
> platforms (cygwin, mingw, others?), in which libtool relinks exe's 
> over and over and over, when the exe depends on a shared lib that is 
> also built as part of the same package.
>
> This behavior is due to the necessity that we must use a wrapper 
> script to set the PATH properly, so that the newly compiled exe can 
> "find" its shared lib, when run "in place" -- e.g. as part of a 
> test-suite.  Thus, we have
>
> <build-dir>/foo             (wrapper script)
> <build-dir>/.libs/foo.exe   (real exe)
>
> However, the Makefile target is "foo$(EXEEXT)" -- which isn't 
> satisfied by the "foo" wrapper script, so 'make' keeps trying to 
> create it. However, the wrapper script can NOT be named "foo.exe", for 
> a number of good reasons.
>
> For more information on this problem, see
>
> Cygwin List O' Issues (take 2): #3 relinking exe's
> http://mail.gnu.org/pipermail/libtool/2002-November/007153.html
> There is an attachment that demonstrates the problem; I've also 
> attached it directly to this email.
>
> EXEEXT and -link
> http://mail.gnu.org/pipermail/libtool/2002-October/007131.html
>
> Based on Earnie's suggestion in the second message, I have implemented 
> a solution, but it is TIGHTLY linked between automake and libtool.  
> This linkage is necessary because both libtool and automake 'use' the 
> value of EXEEXT in a number of places; by saving its value and 
> resetting it to null in libtool, we must re-supply the original value 
> *in some places, but not others* so that automake works properly -- 
> which means automake needs to "know" about the new variable that holds 
> the original value of EXEEXT.
>
> On non-windows platforms, EXEEXT is null.  (pre-existing, unchanged)
> On all platforms, LT_EXEEXT is null without the libtool changes.
>
> Thus, on non-windows platforms, the automake changes have no effect, 
> even if they are accepted (and used) without the corresponding libtool 
> changes.
>
> Similarly, on non-windows platforms, the libtool changes have no 
> effect, even if they are accepted (and used) without the corresponding 
> automake changes.
>
> However, on windows-ish platforms, you must have BOTH changes or 
> NEITHER -- or else things break.  (Actually, it's not QUITE that bad.  
> Even on windows, IF you have only the automake changes -- but don't 
> use libtool at all, then things are fine.  No probs.  But you can't 
> use an updated automake + non-updated libtool, and you can't use 
> non-updated automake + updated libtool.)
>
> So, for non-windows, each patch can be accepted and applied 
> independently.  For windows, they need to be synchronized -- but 
> perhaps the autotool maintainers for cygwin (me) and mingw/MSYS 
> (Earnie) can handle that *synchronization* "outside the tree" -- as 
> long as it is clear that *eventually* both patches will make it in to 
> their respective codebase.
>
> -----------------------
>
> For testing purposes, I've provided automake-devel-1.7.2-2 and 
> libtool-devel-20030103-2 packages for cygwin.  Just point setup.exe at
>
> http://www.neuro.gatech.edu/users/cwilson/cygutils/testing/
>
> and select the appropriate packages.
>
> -----------------------
>
> I've attached the changelogs and patches for both automake (against 
> 1.7.2) and libtool (against current CVS).  I've also attached a simple 
> testcase.  Just unpack, run ./bootstrap, ./configure, make.
>
> Then 'make' again.  Without these changes, program.exe will be 
> relinked.  With these changes it will not be.  'make install' and 
> 'make uninstall' work as expected -- without relinking, with these 
> changes.
>
> I've run the testsuites of both automake and libtool with these 
> changes, and have had no regressions -- but they ran a lot faster... <g>
>
> -----------------------
>
> Cygwin people: please test
> Mingw/MSYS people: please apply to your own packages, and test
> Libtool people: please apply?
>   I'd really like to make sure this or something like it
>   gets into 1.5...
> Automake people: please apply?
>
> I realize that, even if all of the cygwin and mingw people say "this 
> is great", we will still require some coordination between the libtool 
> and automake folks to insure both sets are eventually accepted and the 
> timing of that acceptance.
>
> --Chuck
> cygwin libtool maintainer
> cygwin automake co-maintainer
>
>------------------------------------------------------------------------
>
>2003-01-05  Charles Wilson  <cwilson@ece.gatech.edu>
>
>	* lib/am/program.am: when %?LIBTOOL%, use $(LT_EXEEXT)
>	not %EXEEXT%
>	* lib/am/progs.am (install-%DIR%PROGRAMS): when %?LIBTOOL%,
>	use $(LT_EXEEXT) not $(EXEEXT).  Insure that we test for 
>	both foo and foo$[LT_]EXEEXT.  Insure that we install 
>	foo$([LT_]EXEEXT) and not foo.
>	(uninstall-%DIR%PROGRAMS): when %?LIBTOOL%, use 
>	$(LT_EXEEXT) not $(EXEEXT)
>	(clean-%DIR%PROGRAMS): when %?LIBTOOL%, use $(LT_EXEEXT),
>	not $(EXEEXT). Insure that we remove both foo$(LT_EXEEXT)
>	and foo.
>
>  
>
>------------------------------------------------------------------------
>
>2002-01-05  Charles Wilson  <cwilson@ece.gatech.edu>
>
>	* libtool.m4 (_LT_EXEEXT): new function
>	(AC_LIBTOOL_SETUP): call it
>	* tests/Makefile.am: pass $(LT_EXEEXT) on to
>	TEST_ENVIRONMENT
>	* tests/build-relink.test: use $(LT_EXEEXT) 
>	instead of $(EXEEXT)
>	* tests/dryrun.test: ditto
>	* tests/noinst-link.test: ditto
>  
>
>------------------------------------------------------------------------
>
>diff -u automake-1.7.2-orig/lib/am/program.am automake-1.7.2/lib/am/program.am
>--- automake-1.7.2-orig/lib/am/program.am	2002-12-06 04:53:18.000000000 -0500
>+++ automake-1.7.2/lib/am/program.am	2003-01-05 18:09:01.000000000 -0500
>@@ -15,6 +15,12 @@
> ## along with this program; if not, write to the Free Software
> ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
> ## 02111-1307, USA.
>+if %?LIBTOOL%
>+%PROGRAM%%EXEEXT%: $(%XPROGRAM%_OBJECTS) $(%XPROGRAM%_DEPENDENCIES) %DIRSTAMP%
>+## take care of wrapper script, static executable, and dynamic executable
>+	@rm -f %PROGRAM% %PROGRAM%$(LT_EXEEXT) .libs/%PROGRAM%$(LT_EXEEXT) _libs/%PROGRAM%$(LT_EXEEXT)
>+	$(%XLINK%) $(%XPROGRAM%_LDFLAGS) $(%XPROGRAM%_OBJECTS) $(%XPROGRAM%_LDADD) $(LIBS)
>+else !%?LIBTOOL%
> %PROGRAM%%EXEEXT%: $(%XPROGRAM%_OBJECTS) $(%XPROGRAM%_DEPENDENCIES) %DIRSTAMP%
> ## Remove program before linking.  Otherwise the link will fail if the
> ## program is running somewhere.  FIXME: this could be a loss if
>@@ -23,3 +29,4 @@
> ## systems.
> 	@rm -f %PROGRAM%%EXEEXT%
> 	$(%XLINK%) $(%XPROGRAM%_LDFLAGS) $(%XPROGRAM%_OBJECTS) $(%XPROGRAM%_LDADD) $(LIBS)
>+endif !%?LIBTOOL%
>diff -u automake-1.7.2-orig/lib/am/progs.am automake-1.7.2/lib/am/progs.am
>--- automake-1.7.2-orig/lib/am/progs.am	2002-12-06 04:53:19.000000000 -0500
>+++ automake-1.7.2/lib/am/progs.am	2003-01-05 18:43:30.000000000 -0500
>@@ -36,8 +36,11 @@
> 	@list='$(%DIR%_PROGRAMS)'; for p in $$list; do \
> ## On Cygwin with libtool test won't see `foo.exe' but instead `foo'.
> ## So we check for both.
>-	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
>-	  if test -f $$p \
>+?LIBTOOL?	  p1=`echo $$p|sed 's/$(LT_EXEEXT)$$//'`; \
>+?LIBTOOL?	  p2=`echo $$p1|sed 's/$$/$(LT_EXEEXT)/'`; \
>+?!LIBTOOL?	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
>+?!LIBTOOL?	  p2=`echo $$p1|sed 's/$$/$(EXEEXT)/'`; \
>+	  if test -f $$p2 \
> ?LIBTOOL?	     || test -f $$p1 \
> 	  ; then \
> ## Compute basename of source file.  Unless this is a nobase_ target, we
>@@ -45,16 +48,17 @@
> ## not '$(DESTDIR)$(%NDIR%dir)/python/foo.yo'.
> ## However in all cases $(transform) applies only to the basename,
> ## so we have to strip the directory part.
>-	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
>+?LIBTOOL?	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(LT_EXEEXT)/'`; \
>+?!LIBTOOL?	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
> ## Prepend the directory part if nobase_ is used.
> ?!BASE?	    f=`echo "$$p1" | sed 's|[^/]*$$||'`"$$f"; \
> ## Note that we explicitly set the libtool mode.  This avoids any
> ## lossage if the install program doesn't have a name that libtool
> ## expects.
>-?LIBTOOL?	   echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(%DIR%PROGRAMS_INSTALL) $$p $(DESTDIR)$(%NDIR%dir)/$$f"; \
>-?LIBTOOL?	   $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(%DIR%PROGRAMS_INSTALL) $$p $(DESTDIR)$(%NDIR%dir)/$$f || exit 1; \
>-?!LIBTOOL?	   echo " $(INSTALL_PROGRAM_ENV) $(%DIR%PROGRAMS_INSTALL) $$p $(DESTDIR)$(%NDIR%dir)/$$f"; \
>-?!LIBTOOL?	   $(INSTALL_PROGRAM_ENV) $(%DIR%PROGRAMS_INSTALL) $$p $(DESTDIR)$(%NDIR%dir)/$$f || exit 1; \
>+?LIBTOOL?	   echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(%DIR%PROGRAMS_INSTALL) $$p2 $(DESTDIR)$(%NDIR%dir)/$$f"; \
>+?LIBTOOL?	   $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(%DIR%PROGRAMS_INSTALL) $$p2 $(DESTDIR)$(%NDIR%dir)/$$f || exit 1; \
>+?!LIBTOOL?	   echo " $(INSTALL_PROGRAM_ENV) $(%DIR%PROGRAMS_INSTALL) $$p2 $(DESTDIR)$(%NDIR%dir)/$$f"; \
>+?!LIBTOOL?	   $(INSTALL_PROGRAM_ENV) $(%DIR%PROGRAMS_INSTALL) $$p2 $(DESTDIR)$(%NDIR%dir)/$$f || exit 1; \
> 	  else :; fi; \
> 	done
> endif %?INSTALL%
>@@ -70,7 +74,8 @@
> 	@$(NORMAL_UNINSTALL)
> 	@list='$(%DIR%_PROGRAMS)'; for p in $$list; do \
> ## Remove any leading directory before applying $(transform).
>-	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
>+?LIBTOOL?	  f=`echo "$$p" | sed 's,^.*/,,;s/$(LT_EXEEXT)$$//;$(transform);s/$$/$(LT_EXEEXT)/'`; \
>+?!LIBTOOL?	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
> ## Prepend the directory part if nobase_ is used.
> ?!BASE?	  f=`echo "$$p" | sed 's|[^/]*$$||'`"$$f"; \
> 	  echo " rm -f $(DESTDIR)$(%NDIR%dir)/$$f"; \
>@@ -95,9 +100,10 @@
> ## FIXME: In the future (i.e., when it works) it would be nice to delegate
> ## this task to `libtool --mode=clean'.
> ?LIBTOOL?	@list='$(%DIR%_PROGRAMS)'; for p in $$list; do \
>-?LIBTOOL?	  f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
>-?LIBTOOL?	  echo " rm -f $$p $$f"; \
>-?LIBTOOL?	  rm -f $$p $$f ; \
>+?LIBTOOL?	  f1=`echo $$p|sed 's/$(LT_EXEEXT)$$//'`; \
>+?LIBTOOL?	  f2=`echo $$f1|sed 's/$$/$(LT_EXEEXT)/'`; \
>+?LIBTOOL?	  echo " rm -f $$f1 $$f2"; \
>+?LIBTOOL?	  rm -f $$f1 $$f2 ; \
> ?LIBTOOL?	done
> 
> 
>@@ -116,7 +122,8 @@
> 	  esac; \
> ## Strip the directory and $(EXEEXT) before applying $(transform).
> 	  f=`echo "$$p" | \
>-	     sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
>+?LIBTOOL?	     sed 's,^.*/,,;s/$(LT_EXEEXT)$$//;$(transform);s/$$/$(LT_EXEEXT)/'`; \
>+?!LIBTOOL?	     sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
> ## Insert the directory back if nobase_ is used.
> ?!BASE?	  f=`echo "$$p" | sed 's|[^/]*$$||'`"$$f"; \
> 	  for opt in --help --version; do \
>  
>
>------------------------------------------------------------------------
>
>? .build
>? .inst
>? .sinst
>? COPYING
>? CYGWIN-PATCHES
>? INSTALL
>? install-sh
>? missing
>? mkinstalldirs
>? libltdl/config-h.in
>Index: libtool.m4
>===================================================================
>RCS file: /cvsroot/libtool/libtool/libtool.m4,v
>retrieving revision 1.287
>diff -u -u -r1.287 libtool.m4
>--- libtool.m4	31 Dec 2002 05:43:23 -0000	1.287
>+++ libtool.m4	6 Jan 2003 07:34:06 -0000
>@@ -109,6 +109,7 @@
> # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
> AC_REQUIRE([AC_OBJEXT])dnl
> AC_REQUIRE([AC_EXEEXT])dnl
>+AC_REQUIRE([_LT_EXEEXT])dnl
> dnl
> 
> AC_LIBTOOL_SYS_MAX_CMD_LEN
>@@ -5510,6 +5511,17 @@
> AC_DEFUN([LT_AC_PROG_RC],
> [AC_CHECK_TOOL(RC, windres, no)
> ])
>+
>+AC_DEFUN([_LT_EXEEXT],
>+[lt_exeext=$ac_exeext
>+AC_SUBST([LT_EXEEXT], [$lt_exeext])dnl
>+# Don't allow calls to AC_EXEEXT again
>+define([AC_EXEEXT], [])
>+# keep definition of $ac_exeext, but insure that EXEEXT 
>+# is empty in makefiles
>+ac_cv_exeext=
>+EXEEXT=
>+])# _LT_EXEEXT
> 
> ############################################################
> # NOTE: This macro has been submitted for inclusion into   #
>Index: tests/Makefile.am
>===================================================================
>RCS file: /cvsroot/libtool/libtool/tests/Makefile.am,v
>retrieving revision 1.32
>diff -u -u -r1.32 Makefile.am
>--- tests/Makefile.am	18 Nov 2002 18:59:44 -0000	1.32
>+++ tests/Makefile.am	6 Jan 2003 07:34:07 -0000
>@@ -75,7 +75,8 @@
> TESTS_ENVIRONMENT = MAKE="$(MAKE)" CC="$(CC)" CFLAGS="$(CFLAGS)" \
> 	CPPFLAGS="$(CPPFLAGS)" LD="$(LD)" LDFLAGS="$(LDFLAGS)" \
> 	LIBS="$(LIBS)" LN_S="$(LN_S)" NM="$(NM)" RANLIB="$(RANLIB)" \
>-	OBJEXT="$(OBJEXT)" EXEEXT="$(EXEEXT)" FFLAGS="$(FFLAGS)" 
>+	OBJEXT="$(OBJEXT)" EXEEXT="$(EXEEXT)" LT_EXEEXT="$(LT_EXEEXT)" \
>+	FFLAGS="$(FFLAGS)" 
> 
> EXTRA_DIST = defs $(COMMON_TESTS) $(CXX_TESTS) $(F77_TESTS)
> 
>Index: tests/build-relink.test
>===================================================================
>RCS file: /cvsroot/libtool/libtool/tests/build-relink.test,v
>retrieving revision 1.13
>diff -u -u -r1.13 build-relink.test
>--- tests/build-relink.test	19 Nov 2002 09:42:39 -0000	1.13
>+++ tests/build-relink.test	6 Jan 2003 07:34:07 -0000
>@@ -105,8 +105,8 @@
> fi
> 
> if test "$shlibpath_overrides_runpath" != yes; then
>-  rm -f $objdir/lt-hell$EXEEXT || exit 1
>-  cp $objdir/hell$EXEEXT $objdir/lt-hell$EXEEXT || exit 1
>+  rm -f $objdir/lt-hell$LT_EXEEXT || exit 1
>+  cp $objdir/hell$LT_EXEEXT $objdir/lt-hell$LT_EXEEXT || exit 1
>   echo "running ../demo/hell with installed libhello.la"
>   if ./hell; then
>     echo "Worked, as expected"
>@@ -114,7 +114,7 @@
>     echo "shlibpath_overrides_runpath should be set to yes"
>     status=1
>   fi
>-  rm -f $objdir/lt-hell$EXEEXT
>+  rm -f $objdir/lt-hell$LT_EXEEXT
> fi
> 
> exit $status
>Index: tests/dryrun.test
>===================================================================
>RCS file: /cvsroot/libtool/libtool/tests/dryrun.test,v
>retrieving revision 1.9
>diff -u -u -r1.9 dryrun.test
>--- tests/dryrun.test	3 Mar 2002 03:19:55 -0000	1.9
>+++ tests/dryrun.test	6 Jan 2003 07:34:08 -0000
>@@ -89,7 +89,7 @@
> 
> echo "= Running $make uninstall in ../mdemo (dry run)"
> # Libtool does not uninstall the programs, remove them first
>-rm -f $prefix/bin/mdemo$EXEEXT $prefix/bin/mdemo_static$EXEEXT
>+rm -f $prefix/bin/mdemo$LT_EXEEXT $prefix/bin/mdemo_static$LT_EXEEXT
> ls -l . $objdir > $before
> ls -lR $prefix >> $before
> force_dry_run=yes $make uninstall 1>&2 || exit $?
>Index: tests/noinst-link.test
>===================================================================
>RCS file: /cvsroot/libtool/libtool/tests/noinst-link.test,v
>retrieving revision 1.3
>diff -u -u -r1.3 noinst-link.test
>--- tests/noinst-link.test	3 Mar 2002 03:19:55 -0000	1.3
>+++ tests/noinst-link.test	6 Jan 2003 07:34:08 -0000
>@@ -22,14 +22,14 @@
> cd ../demo || exit 77
> 
> echo "removing libhello.la and hell from ../demo"
>-rm -f libhello.la hell$EXEEXT
>+rm -f libhello.la hell$LT_EXEEXT
> 
> echo "linking hell with a broken ../demo/libhello.la"
>-if $make hell$EXEEXT libhello_la_OBJECTS=hello.lo; then
>+if $make hell$LT_EXEEXT libhello_la_OBJECTS=hello.lo; then
>   echo "= Succeeded: this means the installed library was used, which is wrong"
>   status=1
> fi
> 
>-rm -f libhello.la hell$EXEEXT
>+rm -f libhello.la hell$LT_EXEEXT
> 
> exit $status
>
Hi,
This is a change I was waiting for a long time now. Great!
No more endless installs and fights with the libtool.
Thanks.

Regards.
Michael Bester.






--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/



More information about the Cygwin mailing list