aboutsummaryrefslogtreecommitdiffstats
path: root/ws_symbol_export.h
blob: 4c7a2f710af741a948163a0efb7892af7be5a662 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*
 * Cross platform defines for exporting symbols from shared libraries
 *
 * Wireshark - Network traffic analyzer
 * By Balint Reczey <balint@balintreczey.hu>
 * Copyright 2013 Balint Reczey
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "ws_compiler_tests.h"

/** Reset symbol export behavior.
 * If you {un}define WS_BUILD_DLL on the fly you'll have to define this
 * as well.
 */
#ifdef RESET_SYMBOL_EXPORT

#ifdef SYMBOL_EXPORT_H
#undef SYMBOL_EXPORT_H
#endif

#ifdef WS_DLL_PUBLIC
#undef WS_DLL_PUBLIC
#endif

#ifdef WS_DLL_PUBLIC_DEF
#undef WS_DLL_PUBLIC_DEF
#endif

#ifdef WS_DLL_LOCAL
#undef WS_DLL_LOCAL
#endif

#endif /* RESET_SYMBOL_EXPORT */

#ifndef SYMBOL_EXPORT_H
#define SYMBOL_EXPORT_H

/*
 * NOTE: G_HAVE_GNUC_VISIBILITY is defined only if all of
 *
 *    __attribute__ ((visibility ("hidden")))
 *
 *    __attribute__ ((visibility ("internal")))
 *
 *    __attribute__ ((visibility ("protected")))
 *
 *    __attribute__ ((visibility ("default")))
 *
 * are supported, and at least some versions of GCC from Apple support
 * "default" and "hidden" but not "internal" or "protected", so it
 * shouldn't be used to determine whether "hidden" or "default" is
 * supported.
 *
 * This also means that we shouldn't use G_GNUC_INTERNAL instead of
 * WS_DLL_LOCAL, as GLib uses G_HAVE_GNUC_VISIBILITY to determine
 * whether to use __attribute__ ((visibility ("hidden"))) for
 * G_GNUC_INTERNAL, and that will not use it even with compilers
 * that support it.
 */

/* Originally copied from GCC Wiki at http://gcc.gnu.org/wiki/Visibility */
#if defined _WIN32 || defined __CYGWIN__
  /* Compiling for Windows, so we use the Windows DLL declarations. */
  #ifdef WS_BUILD_DLL
    /*
     * Building a DLL; for all definitions, we want dllexport, and
     * (presumably so source from DLL and source from a program using the
     * DLL can both include a header that declares APIs and exported data
     * for the DLL), for declarations, either dllexport or dllimport will
     * work (they mean the same thing for a declaration when building a DLL).
     */
    #ifdef __GNUC__
      /* GCC */
      #define WS_DLL_PUBLIC_DEF __attribute__ ((dllexport))
    #else /* ! __GNUC__ */
      /*
       * Presumably MSVC.
       * Note: actually gcc seems to also support this syntax.
       */
      #define WS_DLL_PUBLIC_DEF __declspec(dllexport)
    #endif /* __GNUC__ */
  #else /* WS_BUILD_DLL */
    /*
     * Building a program; we should only see declarations, not definitions,
     * with WS_DLL_PUBLIC, and they all represent APIs or data imported
     * from a DLL, so use dllimport.
     *
     * For functions, export shouldn't be necessary; for data, it might
     * be necessary, e.g. if what's declared is an array whose size is
     * not given in the declaration.
     */
    #ifdef __GNUC__
      /* GCC */
      #define WS_DLL_PUBLIC_DEF __attribute__ ((dllimport))
    #elif ! (defined ENABLE_STATIC) /* ! __GNUC__ */
      /*
       * Presumably MSVC, and we're not building all-static.
       * Note: actually gcc seems to also support this syntax.
       */
      #define WS_DLL_PUBLIC_DEF __declspec(dllimport)
    #else /* ! __GNUC__  && ENABLE_STATIC */
      /*
       * Presumably MSVC, and we're building all-static, so we're
       * not building any DLLs.
       */
      #define WS_DLL_PUBLIC_DEF
    #endif /* __GNUC__ */
  #endif /* WS_BUILD_DLL */

  /*
   * Symbols in a DLL are *not* exported unless they're specifically
   * flagged as exported, so, for a non-static but non-exported
   * symbol, we don't have to do anything.
   */
  #define WS_DLL_LOCAL
#else /* defined _WIN32 || defined __CYGWIN__ */
  /*
   * Compiling for UN*X, where the dllimport and dllexport stuff
   * is neither necessary nor supported; just specify the
   * visibility if we have a compiler that supports doing so.
   */
  #if WS_IS_AT_LEAST_GNUC_VERSION(3,4) \
      || WS_IS_AT_LEAST_XL_C_VERSION(12,0)
    /*
     * GCC 3.4 or later, or some compiler asserting compatibility with
     * GCC 3.4 or later, or XL C 13.0 or later, so we have
     * __attribute__((visibility()).
     */

    /*
     * Symbols exported from libraries.
     */
    #define WS_DLL_PUBLIC_DEF __attribute__ ((visibility ("default")))

    /*
     * Non-static symbols *not* exported from libraries.
     */
    #define WS_DLL_LOCAL  __attribute__ ((visibility ("hidden")))
  #elif WS_IS_AT_LEAST_SUNC_VERSION(5,5)
    /*
     * Sun C 5.5 or later, so we have __global and __hidden.
     * (Sun C 5.9 and later also have __attribute__((visibility()),
     * but there's no reason to prefer it with Sun C.)
     */

    /*
     * Symbols exported from libraries.
     */
    #define WS_DLL_PUBLIC_DEF __global

    /*
     * Non-static symbols *not* exported from libraries.
     */
    #define WS_DLL_LOCAL __hidden
  #else
    /*
     * We have neither a way to make stuff not explicitly marked as
     * visible invisible outside a library nor a way to make stuff
     * explicitly marked as local invisible outside the library.
     */

    /*
     * Symbols exported from libraries.
     */
    #define WS_DLL_PUBLIC_DEF

    /*
     * Non-static symbols *not* exported from libraries.
     */
    #define WS_DLL_LOCAL
  #endif
#endif

/*
 * You *must* use this for exported data *declarations*; if you use
 * WS_DLL_PUBLIC_DEF, some compilers, such as MSVC++, will complain
 * about array definitions with no size.
 *
 * You must *not* use this for exported data *definitions*, as that
 * will, for some compilers, cause warnings about items being initialized
 * and declared extern.
 *
 * Either can be used for exported *function* declarations and definitions.
 */
#define WS_DLL_PUBLIC  WS_DLL_PUBLIC_DEF extern

#endif /* SYMBOL_EXPORT_H */

/*
 * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
 *
 * Local Variables:
 * c-basic-offset: 2
 * tab-width: 8
 * indent-tabs-mode: nil
 * End:
 *
 * vi: set shiftwidth=2 tabstop=8 expandtab:
 * :indentSize=2:tabSize=8:noTabs=true:
 */