[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC] w32 and Libtool.
From: |
Ralf Wildenhues |
Subject: |
Re: [RFC] w32 and Libtool. |
Date: |
Wed, 13 Oct 2010 20:50:56 +0200 |
User-agent: |
Mutt/1.5.20 (2010-08-04) |
Hi Peter,
* Peter Rosin wrote on Wed, Oct 13, 2010 at 08:19:27PM CEST:
> Can you spot any errors?
See below. I've only checked for things obvious to me; I hope somebody
else verifies the w32 semantics and details. ;-)
Thanks for writing this!
> (I have not actually tested the code samples. Yet)
Thanks in advance! :-)
> Windows DLLs.
> -------------
>
> This topic describes a couple of ways to portably create Windows Dynamic
> Link Libraries (DLLs). Libtool knows how to create DLLs using GNU tools
Two spaces after period.
> and using Microsoft tools.
>
> A typical library has a "hidden" implementation with an interface
> described in a header file. On just about every system, the interface
> could be something like this:
>
> Example foo.h:
>
> #ifndef FOO_H
> #define FOO_H
>
> int one (void);
> int two (void);
> extern int three;
>
> #endif /* FOO_H */
>
> And the implementation could be something like this:
>
> Example foo.c:
>
> #include "foo.h"
>
> int one (void)
> {
> return 1;
> }
>
> int two (void)
> {
> return 2;
> }
>
> int three = 3;
Isn't this less-than fully general, in the sense that having in addition
references to one and three from within two would possibly be more
complex to handle?
> When using contemporary GNU tools to create the Windows DLL, the above
> code will work there too, thanks to its auto-import/auto-export
> features. But that is not the case when using older GNU tools or perhaps
> more interesting when using proprietary tools. In those cases the code
> will need additional decorations on the interface symbols with
> __declspec(dllimport) and __declspec(dllexport) depending on if the
> library is built or if it's consumed and how it's built and consumed.
>
> Concentrating on how Libtool is using Microsoft tools, Libtool will dig
How about simplifying this to
With Microsoft tools, Libtool will dig ...
> through the object files making up the library looking for non-static
that make up the
> symbols to automatically export. I.e., Libtool with Microsoft tools is
> trying to mimic the auto-export feature of the contemporary GNU tools.
> It should be noted that the GNU auto-export feature in turned off when
s/ in / is /
> an explicit __declspec(dllexport) is seen. The GNU tools is doing this
s/is doing/do/ or s/is/are/
> to not make more symbols visible for projects that have already taken
> the trouble to decorate all symbols. There is no similar way to limit
s/all// ? (because how can you know that it did do so for all symbols,
when parts of the project may come from third parties?)
> which symbols are visible in the code when Libtool is using Microsoft
> tools. In order to limit symbol visibility in that case you need to use
> one of the -export-symbols or -export-symbols-regex options.
>
> No matching help with auto-import is provided by Libtool for neither
> proprietary tools nor older GNU tools, so symbols *must* be decorated in
> order to import them from a DLL for everything but contemporary GNU
> tools on Windows.
But can we not assume that older GNU tools are irrelevant? What would
keep people from updating them?
> When the objects that form the library are built, there are generally
> two copies built for each object. One copy is used when linking the DLL
> and one copy is used for the static library. On Windows systems, the
> copy used when creating the DLL is compiled with the flag -DDLL_EXPORT.
> It is common practice to also add a flag that is only present when the
> library is built, but that will not be present when it is consumed, such
> as -DBUILDING_LIBFOO. These defines are then used to discriminate how
> the interface symbols should be decorated.
This seems to be a bit reversed. From a narrative standpoint, the
"common practice" only appears out of necessity, and the necessity has
not been explained yet. Right?
> However, the matching double compile is not performed when consuming
> libraries. It is therefore not possible to reliably distinguish if the
> consumer is importing from a DLL or if it is going to use a static
> library. With contemporary GNU tools, auto-import saves the day.
because auto-import does what exactly?
(pointer to auto-import documentation from binutils?)
> With
> Microsoft tools you typically get away with always compiling the code as
> if it is going to be linked with a DLL. There are cases when this does
> not work, such as when only variables and no functions are imported from
> the library. There is also a price connected to this liberal use of
> imports in that an extra indirection is introduced when you are
> consuming the static version of the library. That extra indirection is
> always present when the DLL is consumed, but it is not needed when
> consuming the static library.
This paragraph is fairly vague. I understand if you don't want to tell
all the gory details about this, but in that case maybe a pointer to
more detailed documentation would be good here.
> For older GNU tools and other proprietary tools there is no generic way
> to make it possible to consume either of the DLL or the static library
> without user intervention, the tools needs to be told what is intended.
> Or, to be exact, the author are not aware of any generic way. One
s/are/is/ This sounds a bit awkward still.
> assumption that has been used is that if a DLL is being built
that is commonly used?
> (DLL_EXPORT is defined) then that DLL is going to consume any dependent
> libraries as DLLs. If that assumption is made everywhere, it is possible
> to select how an end user application is consuming libraries by adding a
end-user
> single flag -DDLL_EXPORT when a DLL build is required. This is of course
> an all or nothing deal, either everything as DLLs or everything as
> static libraries.
>
> To sum up the above, the header file of the foo library needs to be
> changed into something like this:
>
> Modified foo.h:
>
> #ifndef FOO_H
> #define FOO_H
>
> #if (defined _WIN32 || defined _WIN32_WCE) && !defined __GNUC__
> # ifdef BUILDING_LIBFOO
> # ifdef DLL_EXPORT
> # define LIBFOO_SCOPE extern __declspec (dllexport)
> # endif
> # elif defined _MSC_VER || defined DLL_EXPORT
> # define LIBFOO_SCOPE extern __declspec (dllimport)
> # endif
> #endif
> #ifndef LIBFOO_SCOPE
> # define LIBFOO_SCOPE extern
> #endif
>
> LIBFOO_SCOPE int one (void);
> LIBFOO_SCOPE int two (void);
> LIBFOO_SCOPE int three;
>
> #endif /* FOO_H */
>
> It should be noted that there are various projects that attempt to relax
> these requirements by various low level tricks, but they are not
> discussed here.
Pointers?
Cheers,
Ralf
- [RFC] w32 and Libtool., Peter Rosin, 2010/10/13
- Re: [RFC] w32 and Libtool., Vincent Torri, 2010/10/13
- Re: [RFC] w32 and Libtool.,
Ralf Wildenhues <=
- Re: [RFC] w32 and Libtool., Peter Rosin, 2010/10/13
- Re: [RFC] w32 and Libtool., Ralf Wildenhues, 2010/10/14
- Re: [RFC] w32 and Libtool., Simon Josefsson, 2010/10/14
- Re: [RFC] w32 and Libtool., Peter Rosin, 2010/10/14
- Re: [RFC] w32 and Libtool., Simon Josefsson, 2010/10/14
- Re: [RFC] w32 and Libtool., Peter Rosin, 2010/10/14
- Re: [RFC] w32 and Libtool., Simon Josefsson, 2010/10/14
Re: [RFC] w32 and Libtool., Peter Rosin, 2010/10/14