Hi! I have been tinkering with a text describing the hoops to jump when prepping a library for Windows. At some point it should be texified and added to the manual, but I'm not the best candidate for that job so this is plain ASCII for now.
Can you spot any errors? (I have not actually tested the code samples. Yet) Cheers, Peter 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 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; 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 through the object files making 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 in turned off when an explicit __declspec(dllexport) is seen. The GNU tools is doing this 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 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. 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. 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. 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. 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 assumption that has been used is that if a DLL is being built (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 -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. _______________________________________________ http://lists.gnu.org/mailman/listinfo/libtool