Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm Sender: cygwin-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com Message-ID: <19990323095031.A15545@murlibobo.cs.mu.OZ.AU> Date: Tue, 23 Mar 1999 09:50:31 +1100 From: Fergus Henderson To: "Gary V. Vaughan" Cc: cygwin AT sourceware DOT cygnus DOT com Subject: Re: Making DLL's. References: <1 DOT 5 DOT 4 DOT 32 DOT 19990318210722 DOT 0067d298 AT lola DOT univ-lemans DOT fr> <3564 DOT 990319 AT is DOT lg DOT ua> <36F258AB DOT CC1A1788 AT atos-group DOT com> <199903191530 DOT KAA01054 AT envy DOT delorie DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 0.93.2i In-Reply-To: ; from Gary V. Vaughan on Mon, Mar 22, 1999 at 10:31:32AM +0000 On 22-Mar-1999, Gary V. Vaughan wrote: > The only fly in the ointment for libtool's dll support is handling the export > of data items from a dll. Specifically, an object that will be linked into > an executable which will in turn be linked with a handful of libraries (some > static and some dll's, for argument's sake) needs to produce different code > depending on what particular combinations of dll and static libraries it will > ultimately be linked with. > > That is I need to make sure that any data item that will be imported from a > dll has __attribute__((dllimport)), and any data item imported from a static > library cannot have this attribute. Obviously, in a makefile driven build > environment there is no easy way to know which combination of libraries this > object will eventually be linked with... is there a way around this problem? > Or do I have to come up with some kind of makefile scanner to figure out > which attributes to attach to each symbol? > > Actually, libtool compounds the problem, because it wants to produce both > static and dll libraries for each library object, and thus a given data symbol > may be: > 1) exported from this object if the object will be part of a dll > 4) externed in the tradition way if it will be part of a static lib The difference between 1) and 4) is already important on many Unix systems, where you need to compile with `-fpic' in case 1), but you don't need any special options in case 4). So your Makefile ought to already be set up to handle this. On Windows, just replace `-fpic' with `-DCOMPILING_FOO_DLL' and then use the #ifdefs you mentioned. (N.B. You should really use `COMPILING_FOO_DLL' rather than `_COMPILING_FOO_DLL_', because according to ISO C and C++, the latter is reserved for use by the implementation.) > 2) imported from another dll > 3) imported from a static library This distinction is not present in Unix, and yes, it is a real pain. I have avoided it by either always using a static library or always using a DLL for any given library. > So, my question is: do I really have to figure out whether this object is > destined to become part of a static library, a dll, or an executable, and > which libraries that destination will depend on and whether each of them will > be a dll or not in order to produce the correct code for each exported data > symbol? Basically yes. And it is a real pain. But it's not _quite_ as bad as you make out. > My (flawed) best solution so far is: > > /* foo.h */ > #ifdef __CYGWIN__ > # ifdef _COMPILING_FOO_DLL_ > # define EXTERN __declspec(dllexport) > # else > # define EXTERN extern __declspec(dllimport) > # endif > #else > # define EXTERN extern > #endif > > EXTERN int foo; A potentially better alternative is /* foo.h */ #if defined(__CYGWIN__) && defined(DEFINE_FOO_DLL) # define FOO_EXTERN __declspec(dllexport) #elif defined(__CYGWIN__) && defined(USE_FOO_DLL) # define FOO_EXTERN extern __declspec(dllimport) #else # define FOO_EXTERN extern #endif FOO_EXTERN int foo; (I prefer the name DEFINE_FOO_DLL rather than COMPILING_FOO_DLL.) Note that if you're using C rather than C++, then it is in fact possible to simplify this a little, so that you don't need to add all those FOO_EXTERN symbols to all the declarations in the header files. See for details. Note that the stuff there is fairly old; it dates back to version b18 or thereabouts. I haven't tested it with more recent versions. > When building the dll, I need: > > /* foo.c */ > #define _COMPILING_FOO_DLL_ > #include "foo.h" ... > Which works fine, until I try to build an equivalent static libfoo.a from the > foo sources on cygwin, when ofcourse I get `undefined __imp_foo' errors =(O| It's better to pass -D_COMPILING_FOO_DLL_ or -DDEFINE_FOO_DLL on the command line via make, rather than hard-coding it in your source file. That way you can avoid passing it when you build your static libraries. -- Fergus Henderson | "I have always known that the pursuit WWW: | of excellence is a lethal habit" PGP: finger fjh AT 128 DOT 250 DOT 37 DOT 3 | -- the last words of T. S. Garp. -- Want to unsubscribe from this list? Send a message to cygwin-unsubscribe AT sourceware DOT cygnus DOT com