This is the mail archive of the firstname.lastname@example.org
mailing list for the Cygwin project. See the Cygwin
home page for more information.
[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]
Re: Making DLL's.
On 22-Mar-1999, Gary V. Vaughan <email@example.com> 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
> 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
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
> # define EXTERN extern
> 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)
# define FOO_EXTERN extern
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 <http://www.cs.mu.oz.au/~fjh/gnu-win32/how-to-build-dlls.html> 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 <firstname.lastname@example.org> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger email@example.com | -- the last words of T. S. Garp.
Want to unsubscribe from this list?
Send a message to firstname.lastname@example.org