From mboxrd@z Thu Jan 1 00:00:00 1970 From: Charles Wilson To: binutils@sources.redhat.com Cc: dj@delorie.com, cgf@cygnus.com Subject: [RFA]: dynamic library search order on pei386 Date: Sat, 15 Jul 2000 21:24:00 -0000 Message-id: <397139C6.90280A49@ece.gatech.edu> X-SW-Source: 2000-07/msg00224.html It appears that the recently-adopted search order for libraries, while well-intentioned, has caused serious backwards-compatibility problems on the cygwin platform (and possibly others). The "old" behavior is: ld -Bdynamic -o bar.exe bar.o -lfoo libfoo.dll.a (link to explicit import library) foo.dll.a (altername import lib name) libfoo.dll (link directly to dll if found in lib search path) foo.dll (alternate dll name) ------- libfoo.a (fall back to "static" lib if no dll/import lib found). The problem is that "link-directly-to-dll" needs to be the *last* resort -- even when linking dynamically -- because: 1. most (almost all!) packages ported to cygwin name their import lib "libfoo.a" NOT "libfoo.dll.a", and the import lib gets hidden by the dll itself, in this search order. But, often link-directly-to-dll (e.g. implicit import lib) fails because DATA objects require special handling that is not part of binutils. Also, import libs should be preferred because the often contain not only pointers for the functions exported by the dll, but also static initializers and functions (libcygwin.a --> cygwin1.dll is a good example). 2. the reason "link-directly-to-dll" was put into binutils in the first place, was as a last resort in those cases when a static lib and import lib did not exist, but a dll is distributed in binary form. e.g. windows dll's. So, dll's can be at the *bottom* of this list. This patch institutes the following behavior (when -Bdynamic): ld -Bdynamic -o bar.exe bar.o -lfoo libfoo.dll.a foo.dll.a libfoo.a <<<<< could be static, or could be import lib >>>>> libfoo.dll foo.dll --------- libfoo.a (can never get here, unless the library "foo" doesn't exist (see note 1) With this patch, the backwards compatibility issues on cygwin are eliminated, yet most of the benefits of the previous search order are retained. ============= Note 1: above the dashed line is the "dynamic search order". The basic behavior of ld (on most platforms, if I understand correctly) is to search for "dynamic libraries" in one section of code, and if that fails, fall back to search for the "static library" (below the dashed line). Here, I've added the "static library" name to the list of possible dynamic libraries, since it could (and often IS) really just a dynamic import lib. This means that if none of the possible library names are found, you'd search for libfoo.a twice -- once in the "dynamic" section, and again in the "static" section. So, there's a linking small speed penalty -- but it only happens when the link will fail anyway because the library wasn't found. ============= --Chuck 2000-07-16 Charles Wilson * src/ld/emultempl/pe.em (gld_${EMULATION_NAME}_open_dynamic_archive): New search order for dynamic library '-lfoo' on pei386: libfoo.dll.a, foo.dll.a, libfoo.a, libfoo.dll, foo.dll. This fixes compatibility errors introduced by the old dynamic lib search order. Index: src/ld/emultempl/pe.em =================================================================== RCS file: /cvs/src/src/ld/emultempl/pe.em,v retrieving revision 1.29 diff -u -p -3 -r1.29 pe.em --- pe.em 2000/07/11 03:42:41 1.29 +++ pe.em 2000/07/16 00:29:53 @@ -1387,16 +1387,33 @@ gld_${EMULATION_NAME}_open_dynamic_archi sprintf (string, "%s/%s.dll.a", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { - /* Try "libfoo.dll" (preferred dll name) */ - sprintf (string, "%s/lib%s.dll", search->name, filename); +/* + Try libfoo.a next. Normally, this would be interpreted as a static + library, but it *could* be an import library. For backwards compatibility, + libfoo.a needs to ==precede== libfoo.dll and foo.dll in the search, + or sometimes errors occur when building legacy packages. + + Putting libfoo.a here means that in a failure case (i.e. the library + -lfoo is not found) we will search for libfoo.a twice before + giving up -- once here, and once when searching for a "static" lib. + for a "static" lib. +*/ + /* Try "libfoo.a" (import lib, or static lib, but must + take precedence over dll's) */ + sprintf (string, "%s/lib%s.a", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) - { - /* Finally, try "foo.dll" (alternate dll name) */ - sprintf (string, "%s/%s.dll", search->name, filename); + { + /* Try "libfoo.dll" (preferred dll name) */ + sprintf (string, "%s/lib%s.dll", search->name, filename); if (! ldfile_try_open_bfd (string, entry)) { - free (string); - return false; + /* Finally, try "foo.dll" (alternate dll name) */ + sprintf (string, "%s/%s.dll", search->name, filename); + if (! ldfile_try_open_bfd (string, entry)) + { + free (string); + return false; + } } } } begin 664 pe.patch.gz M'XL(",<"<3D``W!E+G!A=&-H`*54VV[;,`Q]CK^""S:LB6^Y=.N:(D.+H04* MK-VP=<^!8M.)4%DV)#EI4/3?1\G)DK9);].+)9KG\)`B=2Y3O!F`5DDLTACS M2AC,2Q&7&&'N#?]_>;^^_8:,"QQ`G,QT;"-MCQ;,/(5&<9QQ.0%%'\T+"=VH M=^BE/,L@K"`L(>Q#J*P1:HUA&-:[1J_3Z<2=@[C;A4Y_L-\;['<;#NW[_D.7 MS]#I#'J'@T]][_@8PF[_RT%`1M]M^GT@XT2DH_>WIQ=_OI]7)S> MC8H2Y2A=2);S9,14,N4>U$N7BDN3P9ZF).0D@.8''7_042I$Q)H!:+3NX5>" M8N!*8G>MHQ6>$_0=B-3^&1FUJ$.-LW3-B)+LK=8*`7#KA?_V$+?A2BV@*?@X M*PH;MPE[I<(,E<(4Z`PN(K3C3=A6W<112W]*N!^W/9\8;-1E4`82;TP$EX7* MF1"+`,R4:Y@7E4AAC$"14)$F0X*8!@;:,,,31T,4BBF"C"L#W$`[L:BVA3$) M/"\+959.$9P5"L8LN9XSE6I(BKPDHC$7W"R"%=U*$9*'*6`XI,@)IC@7O;$5&C;B^O\"5U*'KH[WOO-)FDX&68=<( MRQNS\HH9*MO%'[5KX0WG)UKX)9/WRND+-T7>WC^ZU,^X7/:^K<%Z%AD]=THR M@SMG\9EWY,EA;#0:5D]CVWI0V5<]%?X+Y+WHN;C/\Z;W;F?5[/4SL;9>WA>2M%_B8Z14EVH*V9=IJ?E2J'5[/E@O@[O'=/#!M ,'.^\OP'*[&5O"``` ` end