# HG changeset patch # User Bruno Haible # Date 1238624826 -7200 # Node ID 925138552c7601b9b6d9ef6c1c672385392a14a1 # Parent e89e1991ce0196d8257b26bd0f77d7bc6f388794 Rename module 'visibility'. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-04-01 Bruno Haible + + Rename module 'visibility'. + * modules/lib-symbol-visibility: Renamed from modules/visibility. + * doc/lib-symbol-visibility.texi: Renamed from visibility.texi. + * doc/gnulib.texi: Update. + * MODULES.html.sh (Misc): Update. + * NEWS: Mention the change. + 2009-04-01 Simon Josefsson * modules/lib-msvc-compat: New module. Thanks to Bruno Haible diff --git a/MODULES.html.sh b/MODULES.html.sh --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -3102,6 +3102,7 @@ func_module getloadavg func_module getpagesize func_module getusershell + func_module lib-symbol-visibility func_module nproc func_module physmem func_module posixver @@ -3113,7 +3114,6 @@ func_module sysexits func_module u64 func_module verror - func_module visibility func_end_table element="Support for building libraries and executables" diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ Date Modules Changes +2009-04-01 visibility Renamed to lib-symbol-visibility. + 2009-04-01 ld-version-script Renamed to lib-symbol-versions. 2009-03-20 close The substituted variable LIB_CLOSE is removed. diff --git a/doc/gnulib.texi b/doc/gnulib.texi --- a/doc/gnulib.texi +++ b/doc/gnulib.texi @@ -5912,7 +5912,7 @@ @include havelib.texi -@include visibility.texi +@include lib-symbol-visibility.texi @include ld-version-script.texi diff --git a/doc/lib-symbol-visibility.texi b/doc/lib-symbol-visibility.texi new file mode 100644 --- /dev/null +++ b/doc/lib-symbol-visibility.texi @@ -0,0 +1,160 @@ +@node Exported Symbols of Shared Libraries +@section Controlling the Exported Symbols of Shared Libraries + +@c Documentation of gnulib module 'lib-symbol-visibility'. + +@c Copyright (C) 2005-2006, 2009 Free Software Foundation, Inc. + +@c Permission is granted to copy, distribute and/or modify this document +@c under the terms of the GNU Free Documentation License, Version 1.3 or +@c any later version published by the Free Software Foundation; with no +@c Invariant Sections, with no Front-Cover Texts, and with no Back-Cover +@c Texts. A copy of the license is included in the ``GNU Free +@c Documentation License'' file as part of this distribution. + +The @code{lib-symbol-visibility} module allows precise control of the +symbols exported by a shared library. This is useful because + +@itemize @bullet +@item +It prevents abuse of undocumented APIs of your library. Symbols that +are not exported from the library cannot be used. This eliminates the +problem that when the maintainer of the library changes internals of the +library, maintainers of other projects cry "breakage". Instead, these +maintainers are forced to negotiate the desired API from the maintainer +of the library. + +@item +It reduces the risk of symbol collision between your library and other +libraries. For example, the symbol @samp{readline} is defined in several +libraries, most of which don't have the same semantics and the same calling +convention as the GNU readline library. + +@item +It reduces the startup time of programs linked to the library. This is +because the dynamic loader has less symbols to process. + +@item +It allows the compiler to generate better code. Within a shared library, +a call to a function that is a global symbol costs a "call" instruction +to a code location in the so-called PLT (procedure linkage table) which +contains a "jump" instruction to the actual function's code. (This is +needed so that the function can be overridden, for example by a function +with the same name in the executable or in a shared library interposed +with @code{LD_PRELOAD}.) Whereas a call to a function for which the compiler +can assume that it is in the same shared library is just a direct "call" +instructions. Similarly for variables: A reference to a global variable +fetches a pointer in the so-called GOT (global offset table); this is a +pointer to the variable's memory. So the code to access it is two memory +load instructions. Whereas for a variable which is known to reside in the +same shared library, it is just a direct memory access: one memory load +instruction. +@end itemize + +There are traditionally three ways to specify the exported symbols of a +shared library. + +@itemize @bullet +@item +The programmer specifies the list of symbols to be exported when the +shared library is created. Usually a command-line option is passed +to the linker, with the name of a file containing the symbols. + +The upside of this approach is flexibility: it allows the same code to +be used in different libraries with different export lists. The downsides +are: 1. it's a lot of maintenance overhead when the symbol list is platform +dependent, 2. it doesn't work well with C++, due to name mangling. + +@item +The programmer specifies a "hidden" attribute for every variable and +function that shall not be exported. + +The drawbacks of this approach are: Symbols are still exported from +the library by default. It's a lot of maintenance work to mark every non- +exported variable and function. But usually the exported API is quite small, +compared to the internal API of the library. And it's the wrong paradigm: +It doesn't force thinking when introducing new exported API. + +@item +The programmer specifies a "hidden" attribute for all files that make up +the shared library, and an "exported" attribute for those symbols in these +files that shall be exported. + +This is perfect: It burdens the maintainer only for exported API, not +for library-internal API. And it keeps the annotations in the source code. +@end itemize + +GNU libtool's @option{-export-symbols} option implements the first approach. + +This gnulib module implements the third approach. For this it relies on +GNU GCC 4.0 or newer, namely on its @samp{-fvisibility=hidden} command-line +option and the "visibility" attribute. (The "visibility" attribute +was already supported in GCC 3.4, but without the command line option, +introduced in GCC 4.0, the third approach could not be used.) + +More explanations on this subject can be found in +@url{http://gcc.gnu.org/wiki/Visibility} - which contains more details +on the GCC features and additional advice for C++ libraries - and in +Ulrich Drepper's paper @url{http://people.redhat.com/drepper/dsohowto.pdf} +- which also explains other tricks for reducing the startup time impact +of shared libraries. + +The gnulib autoconf macro @code{gl_VISIBILITY} tests for GCC 4.0 or newer. +It defines a Makefile variable @code{@@CFLAG_VISIBILITY@@} containing +@samp{-fvisibility=hidden} or nothing. It also defines as a C macro and +as a substituted variable: @@HAVE_VISIBILITY@@. Its value is 1 when symbol +visibility control is supported, and 0 otherwise. + +To use this module in a library, say libfoo, you will do these steps: + +@enumerate +@item +Add @code{@@CFLAG_VISIBILITY@@} or (in a Makefile.am) +@code{$(CFLAG_VISIBILITY)} to the CFLAGS for the compilation of the sources +that make up the library. + +@item +Add a C macro definition, say @samp{-DBUILDING_LIBFOO}, to the CPPFLAGS +for the compilation of the sources that make up the library. + +@item +Define a macro specific to your library like this. +@smallexample +#if BUILDING_LIBFOO && HAVE_VISIBILITY +#define LIBFOO_DLL_EXPORTED __attribute__((__visibility__("default"))) +#else +#define LIBFOO_DLL_EXPORTED +#endif +@end smallexample +This macro should be enabled in all public header files of your library. + +@item +Annotate all variable, function and class declarations in all public header +files of your library with @samp{LIBFOO_DLL_EXPORTED}. This annotation +can occur at different locations: between the @samp{extern} and the +type or return type, or just before the entity being declared, or after +the entire declarator. My preference is to put it right after @samp{extern}, +so that the declarations in the header files remain halfway readable. +@end enumerate + +Note that the precise control of the exported symbols will not work with +other compilers than GCC >= 4.0, and will not work on systems where the +assembler or linker lack the support of "hidden" visibility. Therefore, +it's good if, in order to reduce the risk of collisions with symbols in +other libraries, you continue to use a prefix specific to your library +for all non-static variables and functions and for all C++ classes in +your library. + +Note about other compilers: MSVC support can be added easily, by extending +the definition of the macro mentioned above, to something like this: +@smallexample +#if BUILDING_LIBFOO && HAVE_VISIBILITY +#define LIBFOO_DLL_EXPORTED __attribute__((__visibility__("default"))) +#elif BUILDING_LIBFOO && defined _MSC_VER +#define LIBFOO_DLL_EXPORTED __declspec(dllexport) +#elif defined _MSC_VER +#define LIBFOO_DLL_EXPORTED __declspec(dllimport) +#else +#define LIBFOO_DLL_EXPORTED +#endif +@end smallexample diff --git a/doc/visibility.texi b/doc/visibility.texi deleted file mode 100644 --- a/doc/visibility.texi +++ /dev/null @@ -1,160 +0,0 @@ -@node Exported Symbols of Shared Libraries -@section Controlling the Exported Symbols of Shared Libraries - -@c Documentation of gnulib module 'visibility'. - -@c Copyright (C) 2005-2006, 2009 Free Software Foundation, Inc. - -@c Permission is granted to copy, distribute and/or modify this document -@c under the terms of the GNU Free Documentation License, Version 1.3 or -@c any later version published by the Free Software Foundation; with no -@c Invariant Sections, with no Front-Cover Texts, and with no Back-Cover -@c Texts. A copy of the license is included in the ``GNU Free -@c Documentation License'' file as part of this distribution. - -The @code{visibility} module allows precise control of the symbols -exported by a shared library. This is useful because - -@itemize @bullet -@item -It prevents abuse of undocumented APIs of your library. Symbols that -are not exported from the library cannot be used. This eliminates the -problem that when the maintainer of the library changes internals of the -library, maintainers of other projects cry "breakage". Instead, these -maintainers are forced to negotiate the desired API from the maintainer -of the library. - -@item -It reduces the risk of symbol collision between your library and other -libraries. For example, the symbol @samp{readline} is defined in several -libraries, most of which don't have the same semantics and the same calling -convention as the GNU readline library. - -@item -It reduces the startup time of programs linked to the library. This is -because the dynamic loader has less symbols to process. - -@item -It allows the compiler to generate better code. Within a shared library, -a call to a function that is a global symbol costs a "call" instruction -to a code location in the so-called PLT (procedure linkage table) which -contains a "jump" instruction to the actual function's code. (This is -needed so that the function can be overridden, for example by a function -with the same name in the executable or in a shared library interposed -with @code{LD_PRELOAD}.) Whereas a call to a function for which the compiler -can assume that it is in the same shared library is just a direct "call" -instructions. Similarly for variables: A reference to a global variable -fetches a pointer in the so-called GOT (global offset table); this is a -pointer to the variable's memory. So the code to access it is two memory -load instructions. Whereas for a variable which is known to reside in the -same shared library, it is just a direct memory access: one memory load -instruction. -@end itemize - -There are traditionally three ways to specify the exported symbols of a -shared library. - -@itemize @bullet -@item -The programmer specifies the list of symbols to be exported when the -shared library is created. Usually a command-line option is passed -to the linker, with the name of a file containing the symbols. - -The upside of this approach is flexibility: it allows the same code to -be used in different libraries with different export lists. The downsides -are: 1. it's a lot of maintenance overhead when the symbol list is platform -dependent, 2. it doesn't work well with C++, due to name mangling. - -@item -The programmer specifies a "hidden" attribute for every variable and -function that shall not be exported. - -The drawbacks of this approach are: Symbols are still exported from -the library by default. It's a lot of maintenance work to mark every non- -exported variable and function. But usually the exported API is quite small, -compared to the internal API of the library. And it's the wrong paradigm: -It doesn't force thinking when introducing new exported API. - -@item -The programmer specifies a "hidden" attribute for all files that make up -the shared library, and an "exported" attribute for those symbols in these -files that shall be exported. - -This is perfect: It burdens the maintainer only for exported API, not -for library-internal API. And it keeps the annotations in the source code. -@end itemize - -GNU libtool's @option{-export-symbols} option implements the first approach. - -This gnulib module implements the third approach. For this it relies on -GNU GCC 4.0 or newer, namely on its @samp{-fvisibility=hidden} command-line -option and the "visibility" attribute. (The "visibility" attribute -was already supported in GCC 3.4, but without the command line option, -introduced in GCC 4.0, the third approach could not be used.) - -More explanations on this subject can be found in -@url{http://gcc.gnu.org/wiki/Visibility} - which contains more details -on the GCC features and additional advice for C++ libraries - and in -Ulrich Drepper's paper @url{http://people.redhat.com/drepper/dsohowto.pdf} -- which also explains other tricks for reducing the startup time impact -of shared libraries. - -The gnulib autoconf macro @code{gl_VISIBILITY} tests for GCC 4.0 or newer. -It defines a Makefile variable @code{@@CFLAG_VISIBILITY@@} containing -@samp{-fvisibility=hidden} or nothing. It also defines as a C macro and -as a substituted variable: @@HAVE_VISIBILITY@@. Its value is 1 when symbol -visibility control is supported, and 0 otherwise. - -To use this module in a library, say libfoo, you will do these steps: - -@enumerate -@item -Add @code{@@CFLAG_VISIBILITY@@} or (in a Makefile.am) -@code{$(CFLAG_VISIBILITY)} to the CFLAGS for the compilation of the sources -that make up the library. - -@item -Add a C macro definition, say @samp{-DBUILDING_LIBFOO}, to the CPPFLAGS -for the compilation of the sources that make up the library. - -@item -Define a macro specific to your library like this. -@smallexample -#if BUILDING_LIBFOO && HAVE_VISIBILITY -#define LIBFOO_DLL_EXPORTED __attribute__((__visibility__("default"))) -#else -#define LIBFOO_DLL_EXPORTED -#endif -@end smallexample -This macro should be enabled in all public header files of your library. - -@item -Annotate all variable, function and class declarations in all public header -files of your library with @samp{LIBFOO_DLL_EXPORTED}. This annotation -can occur at different locations: between the @samp{extern} and the -type or return type, or just before the entity being declared, or after -the entire declarator. My preference is to put it right after @samp{extern}, -so that the declarations in the header files remain halfway readable. -@end enumerate - -Note that the precise control of the exported symbols will not work with -other compilers than GCC >= 4.0, and will not work on systems where the -assembler or linker lack the support of "hidden" visibility. Therefore, -it's good if, in order to reduce the risk of collisions with symbols in -other libraries, you continue to use a prefix specific to your library -for all non-static variables and functions and for all C++ classes in -your library. - -Note about other compilers: MSVC support can be added easily, by extending -the definition of the macro mentioned above, to something like this: -@smallexample -#if BUILDING_LIBFOO && HAVE_VISIBILITY -#define LIBFOO_DLL_EXPORTED __attribute__((__visibility__("default"))) -#elif BUILDING_LIBFOO && defined _MSC_VER -#define LIBFOO_DLL_EXPORTED __declspec(dllexport) -#elif defined _MSC_VER -#define LIBFOO_DLL_EXPORTED __declspec(dllimport) -#else -#define LIBFOO_DLL_EXPORTED -#endif -@end smallexample diff --git a/modules/lib-symbol-visibility b/modules/lib-symbol-visibility new file mode 100644 --- /dev/null +++ b/modules/lib-symbol-visibility @@ -0,0 +1,26 @@ +Description: +Control of symbols exported by shared libraries. + +Files: +m4/visibility.m4 + +Depends-on: + +configure.ac: +gl_VISIBILITY + +Makefile.am: +# The value of $(CFLAG_VISIBILITY) needs to be added to the CFLAGS for the +# compilation of all sources that make up the library. This line here does it +# only for the gnulib part of it. The developer is responsible for adding +# $(CFLAG_VISIBILITY) to the Makefile.ams of the other portions of the library. +AM_CFLAGS += $(CFLAG_VISIBILITY) + +Include: + +License: +unlimited + +Maintainer: +Bruno Haible + diff --git a/modules/visibility b/modules/visibility deleted file mode 100644 --- a/modules/visibility +++ /dev/null @@ -1,26 +0,0 @@ -Description: -Control of symbols exported by shared libraries. - -Files: -m4/visibility.m4 - -Depends-on: - -configure.ac: -gl_VISIBILITY - -Makefile.am: -# The value of $(CFLAG_VISIBILITY) needs to be added to the CFLAGS for the -# compilation of all sources that make up the library. This line here does it -# only for the gnulib part of it. The developer is responsible for adding -# $(CFLAG_VISIBILITY) to the Makefile.ams of the other portions of the library. -AM_CFLAGS += $(CFLAG_VISIBILITY) - -Include: - -License: -unlimited - -Maintainer: -Bruno Haible -