From ian@cygnus.com Tue Nov 3 23:23 EDT 1998 Received: from grande.dcc.unicamp.br (grande.dcc.unicamp.br [143.106.7.8]) by amazonas.dcc.unicamp.br (8.8.5/8.8.5) with ESMTP id XAA22373 for ; Tue, 3 Nov 1998 23:23:22 -0200 (EDT) Received: from tweedledumb.cygnus.com (tweedledumb.cygnus.com [192.80.44.1]) by grande.dcc.unicamp.br (8.8.5/8.8.5) with ESMTP id XAA20164 for ; Tue, 3 Nov 1998 23:23:18 -0200 (EDT) Received: from subrogation.cygnus.com (subrogation.cygnus.com [192.80.44.76]) by tweedledumb.cygnus.com (8.8.5/8.8.5) with ESMTP id UAA13699; Tue, 3 Nov 1998 20:25:28 -0500 (EST) Received: (ian@localhost) by subrogation.cygnus.com (950413.SGI.8.6.12/8.6.4) id UAA01678; Tue, 3 Nov 1998 20:25:28 -0500 Date: Tue, 3 Nov 1998 20:25:28 -0500 Message-Id: <199811040125.UAA01678@subrogation.cygnus.com> From: Ian Lance Taylor To: gvaughan@oranda.demon.co.uk CC: tanner@gmx.de, oliva@dcc.unicamp.br, gord@trick.fig.org, bug-libtool@gnu.org In-reply-to: <363F3F85.2B31574@oranda.demon.co.uk> (gvaughan@oranda.demon.co.uk) Subject: Re: Inter-library dependencies in libtool Content-Type: text X-Content-Length: 3237 Xref: araguaia.dcc.unicamp.br libtool-cygwin32:2 Lines: 69 X-Gnus-Article-Number: 2 Wed Nov 4 01:39:12 1998 Date: Tue, 03 Nov 1998 17:38:13 +0000 From: "Gary V. Vaughan" It would seem that the dll code has bitrotted =(O| Pity. Ian, do you have time/want to fix this, or do you want to pass the torch on? I no longer have access to a Windows machine, nor do I have all that much interest in the problem, so I'd say that somebody else had better pick up the torch. Incidentally, I believe that DJ Delorie is working on adding DLL support directly to ld, which will mean that dlltool is no longer required, and should make it possible to greatly simplify the win32 hacks in dlltool, perhaps even simply using the standard GNU ld code. Shouldn't libtool notice that it is running on cygwin32 and pass the -no-undefined option by itself? It seems to go against the raison d'etre for libtool to force the Makefile developer to figure this out... This kind of goes to the heart of libtool. libtool wants to present a particular interface for using shared libraries. In order to do this, it assumes that the system supports certain capabilities. One of those is that the system can support undefined symbols in shared libraries. That means that on systems which do not permit shared libraries to have undefined symbols--AIX and Windows--libtool doesn't really work. The --no-undefined option is a hack which tells libtool that the shared library has special characteristics which permit libtool to create a shared library on AIX or Windows, or any other supported platform. I think the general idea is that you should use the --no-undefined option whenever possible. If you do, you will be able to create shared libraries on AIX and Windows. If you do not or can not, you will not be able to create them. libtool should not add a --no-undefined option itself. If it used that option inappropriately, then building the shared library would fail. Instead, libtool users should always use --no-undefined if they can. Of course, there are problems. For example, in the GNU binutils, I can arrange matters such that --no-undefined will work on Windows, but to do so I have to link various libraries together and I have to link against special Windows system libraries. So I do that, which means that I have to change the options I pass to libtool based on the system. In other words, the interface which libtool presents is deficient. It does not successfully hide the system on which it is running, and it forces the code which calls libtool to make adjustments. I doubt there is any wholly acceptable solution here. The only workable one I can see would be to effectively enhance Windows and AIX shared libraries such that they support creating shared libraries with undefined symbols. On Windows, this could be done by doing the link once, checking for undefined symbols, creating little stub routines for those symbols which track down the symbols in some other open DLL, compiling those stubs, and linking them into the DLL. Perhaps something similar is possible on AIX. Of course even that will not make Windows DLLs identical to ELF shared libraries. ELF shared libraries permit the main program to override a symbol in the shared library, and Windows DLLs do not. Ian When libtool links DLLs, it strips some command line switches. It's probably the case that this is ok for most situations. However, this potentially breaks Mingw32 support in the Cygwin environment. In order to get Mingw32 support in Cygwin, the compiler must be invoked with the -mno-cygwin switch. If libtool strips this switch out during the link process, the resulting binary will get linked with the wrong import libraries. The following is a small example. I've edited the output a bit for readability. When I send this email, long lines will get broken up, so it still might be a bit difficult to read. ------------------------- $ libtool --version ltmain.sh (GNU libtool) 1.3.3 (1.385.2.181 1999/07/02 15:49:11) $ cat xx.c extern __declspec(dllexport) int func(void); int func() { } $ libtool --mode=compile gcc -mno-cygwin -c xx.c mkdir .libs gcc -mno-cygwin -c -DPIC xx.c -o .libs/xx.lo mv -f .libs/xx.lo xx.o ln -s xx.o xx.lo $ libtool --mode=link gcc -mno-cygwin -o libxx.la xx.lo \ -version-info 0:0:0 -no-undefined -rpath /usr/local/lib rm -fr .libs/libxx.la .libs/libxx.* .libs/libxx.* generating symbol list for `libxx.la' test -f .libs/libxx-0-0-0.dll-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < /usr/local/bin/libtool > .libs/libxx-0-0-0.dll-ltdll.c test -f .libs/libxx-0-0-0.dll-ltdll.o || (cd .libs && gcc -c libxx-0-0-0.dll-ltdll.c) dlltool --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def .libs/libxx-0-0-0.dll-def .libs/libxx-0-0-0.dll-ltdll.o xx.o sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < .libs/libxx-0-0-0.dll-def > .libs/libxx.exp echo EXPORTS > .libs/libxx-0-0-0.dll-def _lt_hint=1; for symbol in `cat .libs/libxx.exp`; do echo " $symbol @ $_lt_hint; " >> .libs/libxx-0-0-0.dll-def; _lt_hint=`expr 1 + $_lt_hint`; done test -f .libs/libxx-0-0-0.dll-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here\*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < /usr/local/bin/libtool > .libs/libxx-0-0-0.dll-ltdll.c test -f .libs/libxx-0-0-0.dll-ltdll.o || (cd .libs && gcc -c libxx-0-0-0.dll-ltdll.c) gcc -Wl,--base-file,.libs/libxx-0-0-0.dll-base -Wl,--dll -nostartfiles -Wl,-e, __cygwin_dll_entry@12 -o .libs/libxx-0-0-0.dll .libs/libxx-0-0-0.dll-ltdll.o xx.o dlltool --as=as --dllname libxx-0-0-0.dll --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def .libs/libxx-0-0-0.dll-def --base-file .libs/libxx-0-0-0.dll-base --output-exp .libs/libxx-0-0-0.dll-exp gcc -Wl,--base-file,.libs/libxx-0-0-0.dll-base .libs/libxx-0-0-0.dll-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o .libs/libxx-0-0-0.dll .libs/libxx-0-0-0.dll-ltdll.o xx.o dlltool --as=as --dllname libxx-0-0-0.dll --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def .libs/libxx-0-0-0.dll-def --base-file .libs/libxx-0-0-0.dll-base --output-exp .libs/libxx-0-0-0.dll-exp gcc .libs/libxx-0-0-0.dll-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o .libs/libxx-0-0-0.dll .libs/libxx-0-0-0.dll-ltdll.o xx.o (cd .libs && rm -f libxx.a && ln -s libxx-0-0-0.dll libxx.a) dlltool --as=as --dllname libxx-0-0-0.dll --def .libs/libxx-0-0-0.dll-def --output-lib .libs/libxx.a creating libxx.la (cd .libs && rm -f libxx.la && ln -s ../libxx.la libxx.la) --------------- Notice how the 'gcc' lines do not contain the -mno-cygwin switch. This switch should not get stripped. Jon Leichter jon@symas.com "Gary V. Vaughan" wrote: > > On Wed, Aug 30, 2000 at 10:51:36AM -0400, Charles Wilson wrote: > > No, it can't. Currently, libtool itself doesn't support *building* > > dlls. > > Ouch. Yes it does. I added support around Christmas 1998, and have > been maintaining it ever since. Thanks for the correction. > > Yes it does. And provided your libraries don't trip over the stupid > dll limitation of "to export a non-function symbol you must edit your > sources", it works easily. Even if you do export data symbols, > libtool woll build and link against a dll for you (even generating an > import lib along the way). > > Unfortunately libtool was developed for Unix and assumes a featureful > shared library architecture, which doesn't map very easily onto win32 > dll's. > > I will be able to simplify the dll build process a little when DJ's > patches to binutils arrive in a cygwin release (did this happen in > 1.1? I have been so busy with m4 that I only upgraded from b20.1 a few > weeks ago). They landed in binutils-20000625, and were finetuned/tweaked to a fairly stable point by binutils-20000722 (the current version in /latest). Also, there were a few additions that changed ld's default search order for libraries: -Bstatic -lfoo : looks for libfoo.a -Bdynamic -lfoo : looks for libfoo.dll.a (default name for an import lib) then foo.dll.a (alt. name for an import lib) then libfoo.dll (link directly to a dll) then foo.dll (ditto, alt. name) finally, libfoo.a (fall back to static lib) The spec file for gcc (as of 2.95.2-2) changed so that: gcc -static calls 'ld -Bstatic' gcc calls 'ld -Bdynamic' Finally, 'gcc -shared' will build a dll, but you need to pass linker options like '-Wl,--out-implib=libfoo.dll.a' explicitly. FWIW, all of the (non-libtool) libraries I've dll-ized do not use dlltool at all, and rely only on gcc (and ld, indirectly). --Chuck -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe@sourceware.cygnus.com