c6dcbb821d0706bb8121c4d0b9eed09e4ddbeb82
[gnulib.git] / doc / visibility.texi
1 @c Documentation of gnulib module 'visibility'.
2
3 @c Copyright (C) 2005-2006, 2009 Free Software Foundation, Inc.
4
5 @c Permission is granted to copy, distribute and/or modify this document
6 @c under the terms of the GNU Free Documentation License, Version 1.3 or
7 @c any later version published by the Free Software Foundation; with no
8 @c Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
9 @c Texts.  A copy of the license is included in the ``GNU Free
10 @c Documentation License'' file as part of this distribution.
11
12 The @code{visibility} module allows precise control of the symbols
13 exported by a shared library.  This is useful because
14
15 @itemize @bullet
16 @item
17 It prevents abuse of undocumented APIs of your library. Symbols that
18 are not exported from the library cannot be used. This eliminates the
19 problem that when the maintainer of the library changes internals of the
20 library, maintainers of other projects cry "breakage". Instead, these
21 maintainers are forced to negotiate the desired API from the maintainer
22 of the library.
23
24 @item
25 It reduces the risk of symbol collision between your library and other
26 libraries. For example, the symbol @samp{readline} is defined in several
27 libraries, most of which don't have the same semantics and the same calling
28 convention as the GNU readline library.
29
30 @item
31 It reduces the startup time of programs linked to the library. This is
32 because the dynamic loader has less symbols to process.
33
34 @item
35 It allows the compiler to generate better code. Within a shared library,
36 a call to a function that is a global symbol costs a "call" instruction
37 to a code location in the so-called PLT (procedure linkage table) which
38 contains a "jump" instruction to the actual function's code. (This is
39 needed so that the function can be overridden, for example by a function
40 with the same name in the executable or in a shared library interposed
41 with @code{LD_PRELOAD}.) Whereas a call to a function for which the compiler
42 can assume that it is in the same shared library is just a direct "call"
43 instructions. Similarly for variables: A reference to a global variable
44 fetches a pointer in the so-called GOT (global offset table); this is a
45 pointer to the variable's memory. So the code to access it is two memory
46 load instructions. Whereas for a variable which is known to reside in the
47 same shared library, it is just a direct memory access: one memory load
48 instruction.
49 @end itemize
50
51 There are traditionally three ways to specify the exported symbols of a
52 shared library.
53
54 @itemize @bullet
55 @item
56 The programmer specifies the list of symbols to be exported when the
57 shared library is created. Usually a command-line option is passed
58 to the linker, with the name of a file containing the symbols.
59
60 The upside of this approach is flexibility: it allows the same code to
61 be used in different libraries with different export lists. The downsides
62 are: 1. it's a lot of maintenance overhead when the symbol list is platform
63 dependent, 2. it doesn't work well with C++, due to name mangling.
64
65 @item
66 The programmer specifies a "hidden" attribute for every variable and
67 function that shall not be exported.
68
69 The drawbacks of this approach are: Symbols are still exported from
70 the library by default. It's a lot of maintenance work to mark every non-
71 exported variable and function. But usually the exported API is quite small,
72 compared to the internal API of the library. And it's the wrong paradigm:
73 It doesn't force thinking when introducing new exported API.
74
75 @item
76 The programmer specifies a "hidden" attribute for all files that make up
77 the shared library, and an "exported" attribute for those symbols in these
78 files that shall be exported.
79
80 This is perfect: It burdens the maintainer only for exported API, not
81 for library-internal API. And it keeps the annotations in the source code.
82 @end itemize
83
84 GNU libtool's @option{-export-symbols} option implements the first approach.
85
86 This gnulib module implements the third approach. For this it relies on
87 GNU GCC 4.0 or newer, namely on its @samp{-fvisibility=hidden} command-line
88 option and the "visibility" attribute. (The "visibility" attribute
89 was already supported in GCC 3.4, but without the command line option,
90 introduced in GCC 4.0, the third approach could not be used.)
91
92 More explanations on this subject can be found in
93 @url{http://gcc.gnu.org/wiki/Visibility} - which contains more details
94 on the GCC features and additional advice for C++ libraries - and in
95 Ulrich Drepper's paper @url{http://people.redhat.com/drepper/dsohowto.pdf}
96 - which also explains other tricks for reducing the startup time impact
97 of shared libraries.
98
99 The gnulib autoconf macro @code{gl_VISIBILITY} tests for GCC 4.0 or newer.
100 It defines a Makefile variable @code{@@CFLAG_VISIBILITY@@} containing
101 @samp{-fvisibility=hidden} or nothing. It also defines as a C macro and
102 as a Makefile variable: @@HAVE_VISIBILITY@@. Its value is 1 when symbol
103 visibility control is supported, and 0 otherwise.
104
105 To use this module in a library, say libfoo, you will do these steps:
106
107 @enumerate
108 @item
109 Add @code{@@CFLAG_VISIBILITY@@} or (in a Makefile.am)
110 @code{$(CFLAG_VISIBILITY)} to the CFLAGS for the compilation of the sources
111 that make up the library.
112
113 @item
114 Add a C macro definition, say @samp{-DBUILDING_LIBFOO}, to the CPPFLAGS
115 for the compilation of the sources that make up the library.
116
117 @item
118 Define a macro specific to your library like this.
119 @smallexample
120 #if @@HAVE_VISIBILITY@@ && BUILDING_LIBFOO
121 #define LIBFOO_DLL_EXPORTED __attribute__((__visibility__("default")))
122 #else
123 #define LIBFOO_DLL_EXPORTED
124 #endif
125 @end smallexample
126 This macro should be enabled in all public header files of your library.
127
128 @item
129 Annotate all variable, function and class declarations in all public header
130 files of your library with @samp{LIBFOO_DLL_EXPORTED}. This annotation
131 can occur at different locations: between the @samp{extern} and the
132 type or return type, or just before the entity being declared, or after
133 the entire declarator. My preference is to put it right after @samp{extern},
134 so that the declarations in the header files remain halfway readable.
135 @end enumerate
136
137 Note that the precise control of the exported symbols will not work with
138 other compilers than GCC >= 4.0, and will not work on systems where the
139 assembler or linker lack the support of "hidden" visibility. Therefore,
140 it's good if, in order to reduce the risk of collisions with symbols in
141 other libraries, you continue to use a prefix specific to your library
142 for all non-static variables and functions and for all C++ classes in
143 your library.
144
145 Note about other compilers: MSVC support can be added easily, by extending
146 the definition of the macro mentioned above, to something like this:
147 @smallexample
148 #if @@HAVE_VISIBILITY@@ && BUILDING_LIBFOO
149 #define LIBFOO_DLL_EXPORTED __attribute__((__visibility__("default")))
150 #elif defined _MSC_VER && BUILDING_LIBFOO
151 #define LIBFOO_DLL_EXPORTED __declspec(dllexport)
152 #elif defined _MSC_VER
153 #define LIBFOO_DLL_EXPORTED __declspec(dllimport)
154 #else
155 #define LIBFOO_DLL_EXPORTED
156 #endif
157 @end smallexample