1: /* Exporting symbols from Cygwin shared libraries.
2: Copyright (C) 2006, 2011-2018 Free Software Foundation, Inc.
3: Written by Bruno Haible <bruno@clisp.org>, 2006.
4:
5: This program is free software: you can redistribute it and/or modify
6: it under the terms of the GNU General Public License as published by
7: the Free Software Foundation; either version 3 of the License, or
8: (at your option) any later version.
9:
10: This program is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program. If not, see <https://www.gnu.org/licenses/>. */
17:
18: /* There are four ways to build shared libraries on Cygwin:
19:
20: - Export only functions, no variables.
21: This has the drawback of severely affecting the programming style in use.
22: It does not let the programmer use full ANSI C. It lets one platform
23: dictate the code style on all platforms. This is unacceptable.
24:
25: - Use the GNU ld --enable-auto-import option. It is the default on Cygwin
26: since July 2005. But it has three fatal drawbacks:
27: - It produces executables and shared libraries with relocations in the
28: .text segment, defeating the principles of virtual memory.
29: - For some constructs such as
30: extern int var;
31: int * const b = &var;
32: it creates an executable that will give an error at runtime, rather
33: than either a compile-time or link-time error or a working executable.
34: (This is with both gcc and g++.) Whereas this code, not relying on
35: auto-import:
36: extern __declspec (dllimport) int var;
37: int * const b = &var;
38: gives a compile-time error with gcc and works with g++.
39: - It doesn't work in some cases (references to a member field of an
40: exported struct variable, or to a particular element of an exported
41: array variable), requiring code modifications. Again one platform
42: dictates code modifications on all platforms.
43:
44: This is unacceptable. Therefore we disable this option, through the
45: woe32-dll.m4 autoconf macro.
46:
47: - Define a macro that expands to __declspec(dllexport) when building
48: the library and to __declspec(dllimport) when building code outside
49: the library, and use it in all header files of the library.
50: This is acceptable if
51: 1. the header files are unique to this library (not shared with
52: other packages), and
53: 2. the library sources are contained in one directory, making it easy
54: to define a -DBUILDING_LIBXYZ flag for the library.
55: Example:
56: #ifdef BUILDING_LIBASPRINTF
57: #define LIBASPRINTF_DLL_EXPORTED __declspec(dllexport)
58: #else
59: #define LIBASPRINTF_DLL_EXPORTED __declspec(dllimport)
60: #endif
61:
62: We use this technique for the libintl and the libasprintf libraries.
63:
64: - Define a macro that expands to __declspec(dllimport) always, and use
65: it in all header files of the library. Use an explicit export list for
66: the library.
67: This is acceptable if
68: 1. the programming language is not C++ (because the name mangling of
69: static struct/class fields and of variables in namespaces makes it
70: hard to maintain an export list).
71: The benefit of this approach is that the partitioning of the source files
72: into libraries (which source file goes into which library) does not
73: affect the source code; only the Makefiles reflect it.
74: The performance loss due to the unnecessary indirection for references
75: to variables from within the library defining the variable is acceptable.
76:
77: We use this technique for libgettextlib (because it contains many gnulib
78: modules) and for libgettextsrc (because this makes it easy to move source
79: code from an msg* program to libgettextsrc). The macro is called
80: DLL_VARIABLE.
81:
82: This file allows building an explicit export list. You can either
83: - specify the variables to be exported, and use the GNU ld option
84: --export-all-symbols to export all function names, or
85: - specify the variables and functions to be exported explicitly.
86:
87: Note: --export-all-symbols is the default when no other symbol is explicitly
88: exported. This means, the use of an explicit export on the variables has
89: the effect of no longer exporting the functions! - until the option
90: --export-all-symbols is used.
91:
92: See <https://haible.de/bruno/woe32dll.html> for more details. */
93:
94: #if defined __GNUC__ /* GCC compiler, GNU toolchain */
95:
96: /* IMP(x) is a symbol that contains the address of x. */
97: # define IMP(x) _imp__##x
98:
99: /* Ensure that the variable x is exported from the library, and that a
100: pseudo-variable IMP(x) is available. */
101: # define VARIABLE(x) \
102: /* Export x without redefining x. This code was found by compiling a \
103: snippet: \
104: extern __declspec(dllexport) int x; int x = 42; */ \
105: asm (".section .drectve\n"); \
106: asm (".ascii \" -export:" #x ",data\"\n"); \
107: asm (".data\n"); \
108: /* Allocate a pseudo-variable IMP(x). */ \
109: extern int x; \
110: void * IMP(x) = &x;
111:
112: #else /* non-GNU compiler, non-GNU toolchain */
113:
114: # define VARIABLE(x) /* nothing */
115:
116: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>