File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / woe32dll / export.h
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 13:38:46 2021 UTC (3 years, 9 months ago) by misho
Branches: libiconv, MAIN
CVS tags: v1_16p0, HEAD
libiconv 1.16

    1: /* Exporting symbols from Cygwin shared libraries.
    2:    Copyright (C) 2006, 2011-2018 Free Software Foundation, Inc.
    3:    Written by Bruno Haible <bruno@clisp.org>, 2006.
    4: 
    5:    This program is free software: you can redistribute it and/or modify
    6:    it under the terms of the GNU General Public License as published by
    7:    the Free Software Foundation; either version 3 of the License, or
    8:    (at your option) any later version.
    9: 
   10:    This program is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13:    GNU General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU General Public License
   16:    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
   17: 
   18: /* There are four ways to build shared libraries on Cygwin:
   19: 
   20:    - Export only functions, no variables.
   21:      This has the drawback of severely affecting the programming style in use.
   22:      It does not let the programmer use full ANSI C.  It lets one platform
   23:      dictate the code style on all platforms.  This is unacceptable.
   24: 
   25:    - Use the GNU ld --enable-auto-import option.  It is the default on Cygwin
   26:      since July 2005. But it has three fatal drawbacks:
   27:        - It produces executables and shared libraries with relocations in the
   28:          .text segment, defeating the principles of virtual memory.
   29:        - For some constructs such as
   30:              extern int var;
   31:              int * const b = &var;
   32:          it creates an executable that will give an error at runtime, rather
   33:          than either a compile-time or link-time error or a working executable.
   34:          (This is with both gcc and g++.) Whereas this code, not relying on
   35:          auto-import:
   36:              extern __declspec (dllimport) int var;
   37:              int * const b = &var;
   38:          gives a compile-time error with gcc and works with g++.
   39:        - It doesn't work in some cases (references to a member field of an
   40:          exported struct variable, or to a particular element of an exported
   41:          array variable), requiring code modifications.  Again one platform
   42:          dictates code modifications on all platforms.
   43: 
   44:      This is unacceptable.  Therefore we disable this option, through the
   45:      woe32-dll.m4 autoconf macro.
   46: 
   47:    - Define a macro that expands to  __declspec(dllexport)  when building
   48:      the library and to  __declspec(dllimport)  when building code outside
   49:      the library, and use it in all header files of the library.
   50:      This is acceptable if
   51:        1. the header files are unique to this library (not shared with
   52:           other packages), and
   53:        2. the library sources are contained in one directory, making it easy
   54:           to define a -DBUILDING_LIBXYZ flag for the library.
   55:      Example:
   56:          #ifdef BUILDING_LIBASPRINTF
   57:          #define LIBASPRINTF_DLL_EXPORTED __declspec(dllexport)
   58:          #else
   59:          #define LIBASPRINTF_DLL_EXPORTED __declspec(dllimport)
   60:          #endif
   61: 
   62:      We use this technique for the libintl and the libasprintf libraries.
   63: 
   64:    - Define a macro that expands to  __declspec(dllimport)  always, and use
   65:      it in all header files of the library.  Use an explicit export list for
   66:      the library.
   67:      This is acceptable if
   68:        1. the programming language is not C++ (because the name mangling of
   69:           static struct/class fields and of variables in namespaces makes it
   70:           hard to maintain an export list).
   71:      The benefit of this approach is that the partitioning of the source files
   72:      into libraries (which source file goes into which library) does not
   73:      affect the source code; only the Makefiles reflect it.
   74:      The performance loss due to the unnecessary indirection for references
   75:      to variables from within the library defining the variable is acceptable.
   76: 
   77:      We use this technique for libgettextlib (because it contains many gnulib
   78:      modules) and for libgettextsrc (because this makes it easy to move source
   79:      code from an msg* program to libgettextsrc).  The macro is called
   80:      DLL_VARIABLE.
   81: 
   82:    This file allows building an explicit export list.  You can either
   83:      - specify the variables to be exported, and use the GNU ld option
   84:        --export-all-symbols to export all function names, or
   85:      - specify the variables and functions to be exported explicitly.
   86: 
   87:    Note: --export-all-symbols is the default when no other symbol is explicitly
   88:    exported.  This means, the use of an explicit export on the variables has
   89:    the effect of no longer exporting the functions! - until the option
   90:    --export-all-symbols is used.
   91: 
   92:    See <https://haible.de/bruno/woe32dll.html> for more details.  */
   93: 
   94: #if defined __GNUC__ /* GCC compiler, GNU toolchain */
   95: 
   96:  /* IMP(x) is a symbol that contains the address of x.  */
   97: # define IMP(x) _imp__##x
   98: 
   99:  /* Ensure that the variable x is exported from the library, and that a
  100:     pseudo-variable IMP(x) is available.  */
  101: # define VARIABLE(x) \
  102:  /* Export x without redefining x.  This code was found by compiling a  \
  103:     snippet:                                                            \
  104:       extern __declspec(dllexport) int x; int x = 42;  */               \
  105:  asm (".section .drectve\n");                                           \
  106:  asm (".ascii \" -export:" #x ",data\"\n");                             \
  107:  asm (".data\n");                                                       \
  108:  /* Allocate a pseudo-variable IMP(x).  */                              \
  109:  extern int x;                                                          \
  110:  void * IMP(x) = &x;
  111: 
  112: #else /* non-GNU compiler, non-GNU toolchain */
  113: 
  114: # define VARIABLE(x) /* nothing */
  115: 
  116: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>