Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Message-ID: <39F54E98.7130D9BC@ece.gatech.edu> Date: Tue, 24 Oct 2000 04:55:52 -0400 From: "Charles S. Wilson" X-Mailer: Mozilla 4.75 [en] (WinNT; U) X-Accept-Language: en MIME-Version: 1.0 To: cygwin AT sources DOT redhat DOT com Subject: DLL naming flamefest Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Okay, I've just put the following packages up for test at http://cygutils.netpedia.net/testing zlib-1.1.3-5 libpng-1.0.8-2 jbigkit-1.2-3 jpeg-6b-3 tiff-3.5.503 gdbm-1.8.0-3 gettext-0.10.35-2 (cvs-1.11.0-1 not a library, but...) The seven library packages have been recompiled to follow this naming convention: static lib: libfoo.a (not versioned) import lib: libfoo.dll.a (not versioned) dll : cygfooX.dll (versioned -- usually) The header files have all been munged so that in 'normal' usage, exported functions and data are decorated with __declspec(dllimport). Thus, under 'normal' usage, the client objects will be linked with the dll. Since the default behavior of ld is to link with .dll.a (the import lib), this works. Dynamic linking is the default behavior with 'my' libraries. Usually, this means 'compile'N'go' -- dllized libs *should* be transparent to clients. However, on occaission a configure script in a client package will cheat, requiring some workarounds. To link statically, two changes are required. When compiling the client objects, a library-dependent -Ddefine must be used so that the library function declarations in the header files are not decorated. For zlib, this is -DZLIB_STATIC. Also, to force ld to link statically, the '-Bstatic' ld option must be supplied (or just give gcc the '-static' option). None of this is new; the only change is the name of the dll's. By using the 'cyg' prefix, cygwin-specific libraries won't clash with other system libraries with the same name. For instance, I just ran into a problem with MikTex -- it wants to use a particular native netpbm distribution that contains libjpeg.dll, libtiff.dll, libpng.dll, etc. -- all native libraries. Now, I can avoid conflicts by PATH settings so that in 'cygwin mode', D:\cygwin\usr\bin is in the front of the path, and in 'normal mode' D:\MikTek\netpbm is in the front. However, this problem WILL bite someone somewhere badly -- and in a way that cannot be finessed with PATH settings. With a recent addition to binutils-ld.exe (in cvs only, no cygwin-package available yet) the 'cygfoo.dll' convention still allows direct linking to the dll without using an import lib. Although, why you'd want to do this when an import lib is available, I dunno. I'll say more about this below. So, IMO, cygfoo.dll is an improvement over libfoo.dll for cygwin packages. It makes us 'good neighbors' for other packages, and prevents other packages from interfering with cygwin by using conflicting dlls. Okay, so why the versioning? Well, short answer: libpng. libpng-2.x.y is expected soon and will have an API that is incompatible libpng-1.x.y. So, clients that expect the libpng-1.x.y interface will NOT work with libpng-2 dll's. Clients that expect the 2.x.y interface will NOT work with libpng-1 dll's. What if you want two libpng clients on your system -- one that requires 1.x.y and the other requires 2.x.y. Somehow, you need both dll's on your system simultaneously. Fine -- version them. So, 1.x.y dll's are called "cygpng2.dll" and 2.x.y dll's are called "cygpng3.dll" (why not "1" and "2"? Don't ask me -- the png-developers specified "2" and "3" as the so-name versions on unix; so we'll use 'em on cygwin). So, IMO, cygfooX.dll is an improvement over cygfoo.dll. It helps us maintain a continuity of libraries and applications, so that when some library modifies its API you don't have to go recompile every blasted app on the system -- you can let both versions coexist, like the old/new libc do (sortof) on linux. I'll get to the drawbacks in a minute. Next, why not version the static libs or import libs? Well, because that would make linking too difficult (for now). Eventually, if you wanted to have 27 different incompatible versions of a library coexisting, then yeah -- you'd version the statlibs and implibs, and probably use symlinks to force whichever link you want at build time. However, since the windows loader has to find the dll's, you can't use symlinks for dlls because windows doesn't grok 'em. Or, instead of symlinking 'libfoo.a -> libfoo27.a', you'd specify -lfoo27 instead of -lfoo on your link line. But, since we probably only have one or two versions of any given library, it makes since to *typically* let libfoo.a BE the statlib for version #1. And let libfoo.dll.a BE the import lib for version #1. When version #2 comes out, THEN we worry about versioning statlibs & import libs. HOWEVER, you have to address the dll's NOW, because executables compiled NOW will need to work THEN. So, you can't rename dll's later; they must be versioned in advance. So what's this about a change to binutils? CVS versions of binutils accept a new '--dll-search-prefix=' option. This option changes the search order at link time, when doing a dynamic link, to the following: libfoo.dll.a (import libs are preferred) foo.dll.a libfoo.a (then static libs -- which MIGHT be an import lib. There's also a more esoteric reason why this has to be here; I don't want to go into that now.) foo.dll libfoo.dll foo.dll Eventually, (and don't pester the core team about this), the next cygwin-binutils release will include this functionality. At that time, I'd like to get a patch into cygwin-gcc so that gcc calls ld with '--dll-search-prefix=cyg'. Then, when you specify '-lfoo' and there is no import lib nor static lib, you can still link to cygfoo.dll using DJ's on-the-fly virtual import lib spiffyness. With these changes, 'cygfoo.dll' will be a fully supported, preferred *default* name for dlls. So, here's the downside: This won't work as seamlessly for versioned dll's -- you'd have to specify '-lfoo7' to link to cygfoo7.dll. BUT, remember, link-directly-to-dll-with-no-implib is an emergency fallback for dlls that we don't have implibs for. (Worse, if the dll is stripped you can't link to it -- all of the dll's in the seven packages above are stripped -- because I'm supplying implibs!) Second, all the libraries have to be rebuilt to follow the new convention. (Okay, I just did that. 'nuff said) However, if someone else out there has built, say, XEmacs, that depends on libpng.dll -- it won't work anymore with the latest dot-releases of the libpng. (That is, libpng-1.0.9 will have nifty features, and since it's API compatible with 1.0.8, you *could* just drop the new dll into /usr/bin and BANG! instant XEmacs update. However, the new libpng-1.0.9 dll will be called cygpng2.dll -- but XEmacs will still use the old libpng.dll. Or bomb if setup removes the old dll during the upgrade). Basically, we version the dll's because we can't use symlinks -- Windows is dumb. We don't version the statlibs or import libs because we can play symlink games later; all of our build tools DO understand symlinks. Also, dll's for 'frozen' libraries don't need to be versioned. zlib is NOT going to change its interface. Neither is gettext (libintl). WAY too many things would break if those ever changed their interface. So, of the seven libraries listed above, here's the breakdown: UNVERSIONED zlib-1.1.3-5 very stable gdbm-1.8.0-3 last update 2 yrs ago. next-to-last, 5 years. gettext-0.10.35-2 last update 1.5 yrs ago. VERSIONED libpng-1.0.8-2 jbigkit-1.2-3 jpeg-6b-3 tiff-3.5.503 Now, before flaming, please read the following thread (all of it -- almost 200 messages!). "DLL naming conventions" http://www.cygwin.com/ml/cygwin/2000-08/msg01128.html continues in the next month's archives: http://sources.redhat.com/ml/cygwin/2000-09/msg00000.html there are lots of ancilliary branches. "libtool" http://sources.redhat.com/ml/cygwin/2000-09/msg00137.html "linking against shared libraries" http://sources.redhat.com/ml/cygwin/2000-09/msg00551.html My opinions, and those of many others, underwent a shift during the course of that debate. My summary of the issue: (1) the core team doesn't care -- as long as they don't have to recompile the packages for which they are responsible, just to match this system. They don't. As it happens, every 'core' lib starts with 'cyg' anyway: cygwin, cygtcl, etc. (2) I was initially against it -- mostly out of laziness and the vain hope that there was a better solution. I now believe that hope was vain. So, I got off my lazy butt and recompiled. (3) Various other valid objections for a variety of good reasons. Michael Ring comes to mind here. Even a few of MY objections were valid. :-P (4) There's work going on in the libtool project that *may* eventually make all this easier. Gary Vaughan of the libtool group is up-to-date on the ld--dll-search-prefix thing, and is aware of the cygfooX.dll naming convention. If this naming convention is accepted, "they" will probably try to support it seamlessly (I may be speaking out of turn, but that's *my* impression of various messages.) Okay, I'm ready! --Chuck -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com