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 ARCH_EXPORT_H
25 #define 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 /// The only way to do that is to put the whole class into the API.
87 ///
88 /// Note that template classes do not get added to the API that way.
89 /// Instead they are added when explicitly instantiated like so:
90 ///
91 /// \code
92 /// template class FOO_API FooTemplateClass<FooArgType>;
93 /// \endcode
94 ///
95 /// It's also sometimes necessary to indicate that an instantiation exists
96 /// in the API and that a client should not do any of its own instantiation.
97 /// This is necessary, for example, when the template has static data members
98 /// and is done by using extern template in the header file that provides the
99 /// type. Two of the macros above will do that:
100 ///
101 /// \code
102 /// FOO_API_TEMPLATE_CLASS(FooTemplateClass<FooArgType>);
103 /// FOO_API_TEMPLATE_STRUCT(FooTemplateClass<FooArgType>);
104 /// \endcode
105 ///
106 /// Which you use depends on if FooTemplateClass is a class or struct. The
107 /// macro is used because we don't want to always use extern template, but
108 /// only when we're importing a dynamic library.
109 ///
110 /// A template that is completely inlined does not need to be added to the
111 /// API since it's simply instantiated where needed.
112 ///
113 /// Functions, methods and variables can also be put into the API:
114 ///
115 /// \code
116 /// struct FooLocalClass {
117 /// ~FooLocalClass();
118 /// FOO_API void MoveTheThing();
119 /// };
120 /// FOO_API FooLocalClass* FooNewThing();
121 /// FOO_API extern int doNotUseGlobalVariables;
122 /// \endcode
123 ///
124 /// Just because FooLocalClass is not in the API doesn't mean clients can't
125 /// have pointers and references to instances. What they can't do is call
126 /// member functions not in the API (or, as indicated above, use RTTI for
127 /// it). So, for example:
128 ///
129 /// \code
130 /// FooLocalClass* thing = FooNewThing();
131 /// thing->MoveTheThing();
132 /// (void)dynamic_cast<FooLocalClass*>(thing); // Link error!
133 /// delete thing; // Link error!
134 /// \endcode
135 ///
136 /// Deleting the FooLocalClass instance attempts to use the (non-API) d'tor
137 /// and fails to link. If we had an implicitly defined d'tor then the
138 /// deletion would have worked, presuming FooLocalClass didn't have any
139 /// data members with non-API d'tors.
140 ///
141 /// A method of a class added to the API is itself in the API but on some
142 /// platforms (i.e. not Windows) you can remove it from the API using
143 /// FOO_LOCAL:
144 ///
145 /// \code
146 /// struct FOO_API FooSemiAPI {
147 /// void DoSomethingPublic();
148 /// FOO_LOCAL void _DoSomethingPrivate();
149 /// };
150 /// \endcode
151 ///
152 /// Clients of the library will fail to link if they use _DoSomethingPrivate()
153 /// if FOO_LOCAL is supported. If not then the symbol will remain in the API.
154 
155 #include "pxr/base/arch/defines.h"
156 
157 #if defined(ARCH_OS_WINDOWS)
158 # if defined(ARCH_COMPILER_GCC) && ARCH_COMPILER_GCC_MAJOR >= 4 || defined(ARCH_COMPILER_CLANG)
159 # define ARCH_EXPORT __attribute__((dllexport))
160 # define ARCH_IMPORT __attribute__((dllimport))
161 # define ARCH_HIDDEN
162 # else
163 # define ARCH_EXPORT __declspec(dllexport)
164 # define ARCH_IMPORT __declspec(dllimport)
165 # define ARCH_HIDDEN
166 # endif
167 #elif defined(ARCH_COMPILER_GCC) && ARCH_COMPILER_GCC_MAJOR >= 4 || defined(ARCH_COMPILER_CLANG)
168 # define ARCH_EXPORT __attribute__((visibility("default")))
169 # define ARCH_IMPORT
170 # define ARCH_HIDDEN __attribute__((visibility("hidden")))
171 #else
172 # define ARCH_EXPORT
173 # define ARCH_IMPORT
174 # define ARCH_HIDDEN
175 #endif
176 #define ARCH_EXPORT_TEMPLATE(type, ...)
177 #define ARCH_IMPORT_TEMPLATE(type, ...) extern template type ARCH_IMPORT __VA_ARGS__
178 
179 #endif // ARCH_EXPORT_H