libtool-patches
[Top][All Lists]
Advanced

[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: Mon, 01 Nov 2010 10:12:01 +0100
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-31 20:51 skrev Peter Rosin:
> Hi Ralf,
> 
> Den 2010-10-31 10:13 skrev Ralf Wildenhues:
>>>> This should have a cross reference to just that documentation.
>>>
>>> ...if I write:
>>>
>>> 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
>>> (@pxref{Options, , --enable-auto-import, ld, The GNU linker})
>>>
>>> that renders as:
>>>
>>>    With contemporary GNU tools, auto-import often saves the day, but see
>>> the GNU ld documentation and its `--enable-auto-import' option for some
>>> corner cases when it does not (*note -enable-auto-import: (ld)Options.)
>>>
>>> with my info reader.  Why is one dash eaten?  Can I stop that from
>>> happening?  Should I care? (i.e. the link works, at least for me)  And...
>>
>> Have you tried using @option{--enable-auto-import} here?  Please check
>> for all render forms (info, PDF, DVI, HTML) for whether they cope with
>> this correctly.  The point is that '--' means a longer dash; see info
>> texinfo Conventions.
> 
> It seems to work (but I don't know if the link "works" in the PDF version)
> but both the PDF and DVI versions have what looks like a triple quote:
> 
>    With contemporary GNU tools, auto-import often saves the day, but see the 
> GNU ld
> documentation and its ‘--enable-auto-import’ option for some corner cases 
> when it does
> not (see Section “‘--enable-auto-import’” in The GNU linker)
> 
> But a triple quote is better than one missing dash, agreed?  But maybe
> the section “‘--enable-auto-import’” is a bad reference?  I would have liked
> it to (also) mention the “Options” section.
> 
> Also, the info rendering is "(*note ... (ld)Options.)" with an included
> ending period, but not so in the other renderings.  How do I handle that?

I did some more tests, and I'm going with this text:

With contemporary GNU tools, auto-import often saves the day, but see
the GNU ld documentation and its @option{--enable-auto-import} option
for some corner cases when it does not
(@pxref{Options, @option{--enable-auto-import}, Options specific to
i386 PE targets, ld, Using address@hidden the GNU linker}).

This looks ok in info:

   With contemporary GNU tools, auto-import often saves the day, but see
the GNU ld documentation and its `--enable-auto-import' option for some
corner cases when it does not (*note `--enable-auto-import':
(ld)Options.).

and the link takes me all the way to the specific option.

In html, I get a link to the Options section <a 
href="../ld/Options.html#Options">
and the text looks like this:

With contemporary GNU tools, auto-import often saves the day, but see the
GNU ld documentation and its --enable-auto-import option for some corner
cases when it does not (see --enable-auto-import). 

For PDF and DVI, the text looks like this:

   With contemporary GNU tools, auto-import often saves the day, but see the 
GNU ld
documentation and its ‘--enable-auto-import’ option for some corner cases when 
it does
not (see Section “Options specific to i386 PE targets” in Using ld, the GNU 
linker).

But the link in the PDF document is only useful to open the ld.pdf file,
I'm not successful in getting the link to take me further than that no
matter how I feebly try to put it.

So, pushing as below.

Cheers,
Peter

>From 7a6ca6e6942ddad9f0dc95e8c6d32e062c9cedbc Mon Sep 17 00:00:00 2001
From: Peter Rosin <address@hidden>
Date: Mon, 1 Nov 2010 10:10:36 +0100
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        |    4 +
 doc/libtool.texi |  195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 199 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d3ecba7..5d1ec7c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2010-11-01  Peter Rosin  <address@hidden>
 
+       docs: Windows DLLs and headers.
+       * doc/libtool.texi (Platform quirks): Add new subsection
+       'Windows DLLs'.
+
        * doc/libtool.texi (Platform quirks): Fix typo.
 
 2010-10-30  Ralf Wildenhues  <address@hidden>
diff --git a/doc/libtool.texi b/doc/libtool.texi
index 152d491..2f48a09 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
@@ -5775,6 +5776,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
@@ -6328,6 +6330,199 @@ 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
+
address@hidden
+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 interestingly 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 whether the library is built or 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 @code{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 digs through the object files that make up
+the library, looking for non-static symbols to automatically export.
+I.e., Libtool with Microsoft tools tries to mimic the auto-export feature
+of contemporary GNU tools.  It should be noted that the GNU auto-export
+feature is turned off when an explicit @code{__declspec(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 @option{-export-symbols} or
address@hidden
+
+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 @command{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 @option{--enable-auto-import} option
+for some corner cases when it does not
+(@pxref{Options, @option{--enable-auto-import}, Options specific to
+i386 PE targets, ld, Using address@hidden the GNU linker}).
+
+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 unavoidable 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://alain.frisch.fr/@/flexdll.html, FlexDLL} and
address@hidden://edll.sourceforge.net/, edll}.
+
+
 @node libtool script contents
 @section @code{libtool} script contents
 @cindex implementation of libtool
-- 
1.7.2.3





reply via email to

[Prev in Thread] Current Thread [Next in Thread]