[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC] w32 and Libtool.
From: |
Peter Rosin |
Subject: |
Re: [RFC] w32 and Libtool. |
Date: |
Fri, 29 Oct 2010 22:00:34 +0200 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101027 Thunderbird/3.1.6 |
Den 2010-10-14 12:31 skrev Peter Rosin:
> Den 2010-10-13 20:50 skrev Ralf Wildenhues:
>> 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! :-)
>
> Should have done that before the OP. Oh well. Here's a 3rd attempt
> with actual tested and working code. The lessons I relearned during
> testing should also have improved the descriptions in the text.
This time as a patch. Ok to push, or did I screw up the texification?
Cheers,
Peter
>From f5fea8ca059f47028799d470d6eccf2c3960bb5d Mon Sep 17 00:00:00 2001
From: Peter Rosin <address@hidden>
Date: Fri, 29 Oct 2010 21:58:51 +0200
Subject: [PATCH] docs: Windows DLLs and headers.
* doc/libtool.texi (Platform quirks): Add new subsection
'Windows DLLs'.
Signed-off-by: Peter Rosin <address@hidden>
---
ChangeLog | 6 ++
doc/libtool.texi | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 196 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index df41497..ea53815 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-29 Peter Rosin <address@hidden>
+
+ docs: Windows DLLs and headers.
+ * doc/libtool.texi (Platform quirks): Add new subsection
+ 'Windows DLLs'.
+
2010-10-15 Gary V. Vaughan <address@hidden>
libtool: remove redundant unsubstituted shell var defaults.
diff --git a/doc/libtool.texi b/doc/libtool.texi
index 076b67b..04e31f1 100644
--- a/doc/libtool.texi
+++ b/doc/libtool.texi
@@ -225,6 +225,7 @@ Platform quirks
* Archivers:: Programs that create static archives.
* Cross compiling:: Issues that arise when cross compiling.
* File name conversion:: Converting file names between platforms.
+* Windows DLLs:: Windows header defines.
@end detailmenu
@end menu
@@ -5768,6 +5769,7 @@ write your own.
* Archivers:: Programs that create static archives.
* Cross compiling:: Issues that arise when cross compiling.
* File name conversion:: Converting file names between platforms.
+* Windows DLLs:: Windows header defines.
@end menu
@node References
@@ -6321,6 +6323,194 @@ the source or build directory trees, and all
@option{-M*} options to
This is quite a fragile setup, but it has been in historical use, and so is
documented here.
address@hidden Windows DLLs
address@hidden Windows DLLs
address@hidden 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
+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 @file{foo.h}:
+
address@hidden
+#ifndef FOO_H
+#define FOO_H
+
+int one (void);
+int two (void);
+extern int three;
+
+#endif /* FOO_H */
address@hidden example
+
+And the implementation could be something like this:
+
+Example @file{foo.c}:
+
address@hidden
+#include "foo.h"
+
+int one (void)
address@hidden
+ return 1;
address@hidden
+
+int two (void)
address@hidden
+ return three - one ();
address@hidden
+
+int three = 3;
address@hidden example
+
+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
address@hidden(dllimport)} and @code{__declspec(dllexport)} depending
+on if the library is built or if it's consumed and how it's built and
+consumed. However, it should be noted that it would have worked also
+with Microsoft tools, if only the variable three hadn't been there, due
+to the fact the Microsoft tools will automatically import functions (but
+sadly not variables) and Libtool will automatically export non-static
+symbols as described next.
+
+With Microsoft tools, Libtool will dig through the object files that
+make up the library, looking for non-static 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 is turned off when an explicit
address@hidden(dllexport)} is seen. The GNU tools do this to not make
+more symbols visible for projects that have already taken the trouble to
+decorate symbols. There is no similar way to limit 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 options
address@hidden or @option{-export-symbols-regex}.
+
+No matching help with auto-import is provided by Libtool, which is why
+variables must be decorated to import them from a DLL for everything but
+contemporary GNU tools. As stated above, functions are automatically
+imported by both contemporary GNU tools and Microsoft tools, but for
+other proprietary tools the auto-import status of functions is unknown.
+
+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, a pair
+of defines are commonly used to discriminate how the interface symbols
+should be decorated. The first define is @samp{-DDLL_EXPORT} which is
+automatically provided by Libtool when Libtool builds the copy of the
+object that is destined for the DLL. The second define is
address@hidden (or similar) which is often added by the package
+providing the library and is used when building the library, but not
+when consuming the library.
+
+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 often saves the day, but see
+the GNU ld documentation and its @code{--enable-auto-import} option for
+some corner cases when it does not.
+
+With Microsoft tools you typically get away with always compiling the
+code such that variables are expected to be imported from a DLL and
+functions are expected to be found in a static library. The tools will
+then automatically import the function from a DLL if that is where they
+are found. If the variables are not imported from a DLL as expected, but
+are found in a static library that is otherwise pulled in by some
+function, the linker will issue a warning (LNK4217) that a locally
+defined symbol is imported, but it still works. In other words, this
+scheme will not work to only consume variables from a 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.
+
+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 need to be told what is intended.
+One common assumption is that if a DLL is being built (@samp{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 single
+flag @samp{-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 @file{foo.h}:
+
address@hidden
+#ifndef FOO_H
+#define FOO_H
+
+#if defined _WIN32 && !defined __GNUC__
+# ifdef LIBFOO_BUILD
+# ifdef DLL_EXPORT
+# define LIBFOO_SCOPE __declspec (dllexport)
+# define LIBFOO_SCOPE_VAR extern __declspec (dllexport)
+# endif
+# elif defined _MSC_VER
+# define LIBFOO_SCOPE
+# define LIBFOO_SCOPE_VAR extern __declspec (dllimport)
+# elif defined DLL_EXPORT
+# define LIBFOO_SCOPE __declspec (dllimport)
+# define LIBFOO_SCOPE_VAR extern __declspec (dllimport)
+# endif
+#endif
+#ifndef LIBFOO_SCOPE
+# define LIBFOO_SCOPE
+# define LIBFOO_SCOPE_VAR extern
+#endif
+
+LIBFOO_SCOPE int one (void);
+LIBFOO_SCOPE int two (void);
+LIBFOO_SCOPE_VAR int three;
+
+#endif /* FOO_H */
address@hidden example
+
+When the targets are limited to contemporary GNU tools and Microsoft
+tools, the above can be simplified to the following:
+
+Simplified @file{foo.h}:
+
address@hidden
+#ifndef FOO_H
+#define FOO_H
+
+#if defined _WIN32 && !defined __GNUC__ && !defined LIBFOO_BUILD
+# define LIBFOO_SCOPE_VAR extern __declspec (dllimport)
+#else
+# define LIBFOO_SCOPE_VAR extern
+#endif
+
+int one (void);
+int two (void);
+LIBFOO_SCOPE_VAR int three;
+
+#endif /* FOO_H */
address@hidden example
+
+This last simplified version can of course only work when Libtool is
+used to build the DLL, as no symbols would be exported otherwise (i.e.,
+when using Microsoft tools).
+
+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. Examples are address@hidden
+(@url{http://alain.frisch.fr/flexdll.html}) and address@hidden
+(@url{http://edll.sourceforge.net/}).
+
@node libtool script contents
@section @code{libtool} script contents
@cindex implementation of libtool
--
1.7.2.3
- Re: [RFC] w32 and Libtool., (continued)
- Re: [RFC] w32 and Libtool., Vincent Torri, 2010/10/13
- Re: [RFC] w32 and Libtool., Ralf Wildenhues, 2010/10/13
- 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
- Re: [RFC] w32 and Libtool.,
Peter Rosin <=