ws_symbol_export.h 5.89 KB
Newer Older
laurent's avatar
laurent committed
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:
 */