HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
export.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_ARCH_EXPORT_H
25 #define PXR_BASE_ARCH_EXPORT_H
26 
27 /// \file arch/export.h
28 /// \ingroup group_arch_SymbolVisibility
29 ///
30 /// Defines symbol visibility macros.
31 ///
32 /// Defines \c ARCH_EXPORT to indicate a symbol should be exported from
33 /// a library, \c ARCH_IMPORT to indicate an exported symbol should be
34 /// imported (which only matters on Windows), and \c ARCH_HIDDEN to
35 /// indicate that a symbol which would be exported should not be.
36 ///
37 /// The correct way to use these macros is for each library to make a
38 /// header that looks like this (for some hypothetical library named foo):
39 ///
40 /// \code
41 /// #ifndef FOO_API_H
42 /// #define FOO_API_H
43 ///
44 /// #include "pxr/base/arch/export.h"
45 ///
46 /// #if defined(FOO_STATIC)
47 /// # define FOO_API
48 /// # define FOO_API_TEMPLATE_CLASS(...)
49 /// # define FOO_API_TEMPLATE_STRUCT(...)
50 /// # define FOO_LOCAL
51 /// #else
52 /// # if defined(FOO_EXPORTS)
53 /// # define FOO_API ARCH_EXPORT
54 /// # define FOO_API_TEMPLATE_CLASS(...) ARCH_EXPORT_TEMPLATE(class, __VA_ARGS__)
55 /// # define FOO_API_TEMPLATE_STRUCT(...) ARCH_EXPORT_TEMPLATE(struct, __VA_ARGS__)
56 /// # else
57 /// # define FOO_API ARCH_IMPORT
58 /// # define FOO_API_TEMPLATE_CLASS(...) ARCH_IMPORT_TEMPLATE(class, __VA_ARGS__)
59 /// # define FOO_API_TEMPLATE_STRUCT(...) ARCH_IMPORT_TEMPLATE(struct, __VA_ARGS__)
60 /// # endif
61 /// # define FOO_LOCAL ARCH_HIDDEN
62 /// #endif
63 ///
64 /// #endif
65 /// \endcode
66 ///
67 /// Note that every library has its own unique _API and _LOCAL macros and
68 /// the expansion of these macros depends on whether the library is being
69 /// built or used (indicated by the externally set macro FOO_EXPORTS).
70 ///
71 /// Library headers then include this header and mark classes, methods,
72 /// functions and variables as part of the API or local. Each case is
73 /// described below.
74 ///
75 /// A class is added to the API like this:
76 ///
77 /// \code
78 /// class FOO_API FooClass ...
79 /// \endcode
80 ///
81 /// This will add every member to the API, including implicitly created
82 /// members like a default constructor, default assignment, the vtable
83 /// and the type_info. The type_info is especially important. If you
84 /// will dynamic_cast to the type or catch an exception using the type
85 /// outside of the library, you \b must put its type_info into the API.
86 /// To export the vtable & type_info specifically, use \c ARCH_EXPORT_TYPE.
87 /// However, due to compiler limitations, ARCH_EXPORT_TYPE may put the
88 /// whole class into the API as if ARCH_EXPORT were used.
89 ///
90 /// Note that template classes do not get added to the API that way.
91 /// Instead they are added when explicitly instantiated like so:
92 ///
93 /// \code
94 /// template class FOO_API FooTemplateClass<FooArgType>;
95 /// \endcode
96 ///
97 /// It's also sometimes necessary to indicate that an instantiation exists
98 /// in the API and that a client should not do any of its own instantiation.
99 /// This is necessary, for example, when the template has static data members
100 /// and is done by using extern template in the header file that provides the
101 /// type. Two of the macros above will do that:
102 ///
103 /// \code
104 /// FOO_API_TEMPLATE_CLASS(FooTemplateClass<FooArgType>);
105 /// FOO_API_TEMPLATE_STRUCT(FooTemplateClass<FooArgType>);
106 /// \endcode
107 ///
108 /// Which you use depends on if FooTemplateClass is a class or struct. The
109 /// macro is used because we don't want to always use extern template, but
110 /// only when we're importing a dynamic library.
111 ///
112 /// A template that is completely inlined does not need to be added to the
113 /// API since it's simply instantiated where needed.
114 ///
115 /// Functions, methods and variables can also be put into the API:
116 ///
117 /// \code
118 /// struct FooLocalClass {
119 /// ~FooLocalClass();
120 /// FOO_API void MoveTheThing();
121 /// };
122 /// FOO_API FooLocalClass* FooNewThing();
123 /// FOO_API extern int doNotUseGlobalVariables;
124 /// \endcode
125 ///
126 /// Just because FooLocalClass is not in the API doesn't mean clients can't
127 /// have pointers and references to instances. What they can't do is call
128 /// member functions not in the API (or, as indicated above, use RTTI for
129 /// it). So, for example:
130 ///
131 /// \code
132 /// FooLocalClass* thing = FooNewThing();
133 /// thing->MoveTheThing();
134 /// (void)dynamic_cast<FooLocalClass*>(thing); // Link error!
135 /// delete thing; // Link error!
136 /// \endcode
137 ///
138 /// Deleting the FooLocalClass instance attempts to use the (non-API) d'tor
139 /// and fails to link. If we had an implicitly defined d'tor then the
140 /// deletion would have worked, presuming FooLocalClass didn't have any
141 /// data members with non-API d'tors.
142 ///
143 /// A method of a class added to the API is itself in the API but on some
144 /// platforms (i.e. not Windows) you can remove it from the API using
145 /// FOO_LOCAL:
146 ///
147 /// \code
148 /// struct FOO_API FooSemiAPI {
149 /// void DoSomethingPublic();
150 /// FOO_LOCAL void _DoSomethingPrivate();
151 /// };
152 /// \endcode
153 ///
154 /// Clients of the library will fail to link if they use _DoSomethingPrivate()
155 /// if FOO_LOCAL is supported. If not then the symbol will remain in the API.
156 
157 #include "pxr/base/arch/defines.h"
158 
159 #if defined(ARCH_OS_WINDOWS)
160 # if defined(ARCH_COMPILER_GCC) && ARCH_COMPILER_GCC_MAJOR >= 4 || defined(ARCH_COMPILER_CLANG)
161 # define ARCH_EXPORT __attribute__((dllexport))
162 # define ARCH_IMPORT __attribute__((dllimport))
163 # define ARCH_HIDDEN
164 # define ARCH_EXPORT_TYPE
165 # else
166 # define ARCH_EXPORT __declspec(dllexport)
167 # define ARCH_IMPORT __declspec(dllimport)
168 # define ARCH_HIDDEN
169 # define ARCH_EXPORT_TYPE
170 # endif
171 #elif defined(ARCH_COMPILER_GCC) && ARCH_COMPILER_GCC_MAJOR >= 4 || defined(ARCH_COMPILER_CLANG)
172 # define ARCH_EXPORT __attribute__((visibility("default")))
173 # define ARCH_IMPORT
174 # define ARCH_HIDDEN __attribute__((visibility("hidden")))
175 # if defined(ARCH_COMPILER_CLANG)
176 # define ARCH_EXPORT_TYPE __attribute__((type_visibility("default")))
177 # else
178 # define ARCH_EXPORT_TYPE __attribute__((visibility("default")))
179 # endif
180 #else
181 # define ARCH_EXPORT
182 # define ARCH_IMPORT
183 # define ARCH_HIDDEN
184 # define ARCH_EXPORT_TYPE
185 #endif
186 #define ARCH_EXPORT_TEMPLATE(type, ...)
187 #define ARCH_IMPORT_TEMPLATE(type, ...) extern template type ARCH_IMPORT __VA_ARGS__
188 
189 #endif // PXR_BASE_ARCH_EXPORT_H