Panda3D
dtoolsymbols.h
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file dtoolsymbols.h
10  * @author drose
11  * @date 2000-02-18
12  */
13 
14 #ifndef DTOOLSYMBOLS_H
15 #define DTOOLSYMBOLS_H
16 
17 
18 /*
19  This file defines a slew of symbols that have particular meaning
20  only when compiling in the WIN32 environment. These symbols are
21  prefixed to each class declaration, and each global function, that
22  is to be made visible outside of a DLL.
23 
24  The problem is that in Windows, you must prefix each DLL-public
25  symbol with "__declspec(dllexport)" when you are compiling the DLL,
26  but with "__declspec(dllimport)" when you are compiling code that
27  links with the DLL. This strange convention means that you must, in
28  principle, have two different .h files for a DLL: one to use for
29  compiling the DLL (it must export all of the symbols), and a
30  different one for presenting the public interface for other users to
31  use (it must import all of the same symbols).
32 
33  In practice, of course, maintaining two different .h files is silly
34  and error-prone; almost everyone solves this problem by defining a
35  macro that evaluates to "__declspec(dllexport)" in one case and
36  "__declspec(dllimport)" in another case. Many systems use the
37  system macro _DLL to switch between these two case, which works well
38  in a simple system because _DLL is defined only if compiler is
39  currently generating code for a DLL. So you can export the symbols
40  if _DLL is defined, and import them if it is not defined.
41 
42  However, this fails if you are compiling a DLL that wants to import
43  symbols from another DLL, since in this case _DLL is defined, but
44  the symbols in the other DLL need to be imported, not exported.
45 
46  In the general case of compiling multiple DLL's that might reference
47  each other's symbols, we need have a separate macro for each DLL.
48  Then when we are compiling code for each DLL, the macro for that
49  particular DLL evaluates to "__declspec(dllexport)", exporting all
50  the symbols from the DLL, while all the other DLL's macros evaluate
51  to "__declspec(dllimport)", importing all the symbols from the other
52  DLL's.
53 
54  That is the approach we have taken here in Panda. When we are
55  compiling code for a particular DLL, the build scripts define the
56  macro BUILDING_libname on the command line. This file then uses
57  that macro to define EXPCL_libname appropriately for each DLL; this
58  macro is then used to prefix each symbol to be exported from the
59  DLL. The macro name stands for "export class", since it is used
60  most often to mark a class for export, although the same macro can
61  be used to export global functions. (We also define EXPTP_libname,
62  which is used in conjunction with exporting template instantiations,
63  another dicey task in Windows. It is used far less often.)
64 
65  Of course, this whole thing only matters under WIN32. In the rest
66  of the world we don't have to deal with this nonsense, and so we
67  can define all of these stupid symbols to the empty string.
68  */
69 
70 #ifdef BUILDING_DTOOL
71  #define BUILDING_DTOOL_DTOOLBASE
72  #define BUILDING_DTOOL_DTOOLUTIL
73 #endif
74 
75 #ifdef BUILDING_DTOOLCONFIG
76  #define BUILDING_DTOOL_PRC
77  #define BUILDING_DTOOL_DCONFIG
78 #endif
79 
80 #ifdef BUILDING_DTOOL_DTOOLBASE
81  #define EXPCL_DTOOL_DTOOLBASE EXPORT_CLASS
82  #define EXPTP_DTOOL_DTOOLBASE EXPORT_TEMPL
83 #else
84  #define EXPCL_DTOOL_DTOOLBASE IMPORT_CLASS
85  #define EXPTP_DTOOL_DTOOLBASE IMPORT_TEMPL
86 #endif
87 
88 #ifdef BUILDING_DTOOL_DTOOLUTIL
89  #define EXPCL_DTOOL_DTOOLUTIL EXPORT_CLASS
90  #define EXPTP_DTOOL_DTOOLUTIL EXPORT_TEMPL
91 #else
92  #define EXPCL_DTOOL_DTOOLUTIL IMPORT_CLASS
93  #define EXPTP_DTOOL_DTOOLUTIL IMPORT_TEMPL
94 #endif
95 
96 #ifdef BUILDING_DTOOL_PRC
97  #define EXPCL_DTOOL_PRC EXPORT_CLASS
98  #define EXPTP_DTOOL_PRC EXPORT_TEMPL
99 #else
100  #define EXPCL_DTOOL_PRC IMPORT_CLASS
101  #define EXPTP_DTOOL_PRC IMPORT_TEMPL
102 #endif
103 
104 #ifdef BUILDING_DTOOL_DCONFIG
105  #define EXPCL_DTOOL_DCONFIG EXPORT_CLASS
106  #define EXPTP_DTOOL_DCONFIG EXPORT_TEMPL
107 #else
108  #define EXPCL_DTOOL_DCONFIG IMPORT_CLASS
109  #define EXPTP_DTOOL_DCONFIG IMPORT_TEMPL
110 #endif
111 
112 #ifdef BUILDING_INTERROGATEDB
113  #define EXPCL_INTERROGATEDB EXPORT_CLASS
114  #define EXPTP_INTERROGATEDB EXPORT_TEMPL
115 #else
116  #define EXPCL_INTERROGATEDB IMPORT_CLASS
117  #define EXPTP_INTERROGATEDB IMPORT_TEMPL
118 #endif
119 
120 #ifdef BUILDING_MISC
121  #define EXPCL_MISC EXPORT_CLASS
122  #define EXPTP_MISC EXPORT_TEMPL
123 #else /* BUILDING_MISC */
124  #define EXPCL_MISC IMPORT_CLASS
125  #define EXPTP_MISC IMPORT_TEMPL
126 #endif /* BUILDING_MISC */
127 
128 
129 /* These two are always defined empty, because pystub is statically
130  built. But we leave the symbol around in case we change our minds
131  to make pystub once again be a dynamic library. */
132 #if __GNUC__ >= 4
133 /* In GCC, though, we still need to mark the symbols as visible. */
134 #define EXPCL_PYSTUB __attribute__((visibility("default")))
135 #else
136 #define EXPCL_PYSTUB
137 #endif
138 #define EXPTP_PYSTUB
139 
140 #endif