Symbol Visibility
Controlling symbol visibility for executables and dynamic libraries allows to reduce the sets of symbols exported by them to what is actually necessary. Today, all relevant C/C++ compilers have (slightly different) syntax extensions to control in the C/C++ source code the set of exported symbols. The following describes how to enable these visibility features for a given executable or dynamic library X in the OOo code base:
- In all the
makefile.mk
s where C/C++ source code belonging to X is compiled or where X (or part of X) is linked,VISIBILITY_HIDDEN=TRUE
must be declared. (It is an error to have that declaration inmakefile.mk
s completely or partially controlling other stuff.) - If none of the symbols that shall be exported by X are declared in a header file that is used by code outside X (e.g., if X is a dynamic library that is a UNO component and only exports
component_getFactory
,component_getImplementationEnvironment
,component_writeInfo
):- Annotate the definitions of those entities (functions, classes) in the C/C++ source code that correspond to those symbols with
SAL_DLLPUBLIC_EXPORT
.
- Annotate the definitions of those entities (functions, classes) in the C/C++ source code that correspond to those symbols with
- If, however, there are symbols that shall be exported by X and that are declared in a header file that is used by code outside X:
- Chose a unique (all lowercase) token t to represent X.
- In all the
makefile.mk
s where C/C++ source code defining one of those symbols is compiled,CDEFS+=-DOOO_DLLIMPLEMENTATION_T
must be declared (where T is the all uppercase equivalent of t). (It is an error to have that declaration inmakefile.mk
s completely or partially controlling other stuff.) - Create a header file
tdllapi.h
resp.tdllapi.hxx
that contains
#include "sal/types.h" #if defined OOO_DLLIMPLEMENTATION_<var>T</var> #define OOO_DLLPUBLIC_<var>T</var> SAL_DLLPUBLIC_EXPORT #else #define OOO_DLLPUBLIC_<var>T</var> SAL_DLLPUBLIC_IMPORT #endif
- Include that header file in all header files that declare C/C++ entities corresponding to to-be-exported symbols and annotate those declarations with
OOO_DLLPUBLIC_T
. - (C/C++ entities corresponding to to-be-exported symbols that are not declared in header files can be annotated with
OOO_DLLPUBLIC_T
or directly withSAL_DLLPUBLIC_EXPORT
.)
- Include that header file in all header files that declare C/C++ entities corresponding to to-be-exported symbols and annotate those declarations with
- Declarations of C/C++ entities that would be exported due to the
SAL_DLLPUBLIC_EXPORT
/OOO_DLLPUBLIC_T
annotations but should not be exported (e.g., private class member functions) need to be annotated withSAL_DLLPRIVATE
. - See SAL_EXCEPTION_DLLPUBLIC_EXPORT, SAL_EXCEPTION_DLLPRIVATE for how to handle C++ types that are used as C++ exceptions.
- See Problems with deriving SAL_DLLPUBLIC classes from all-inline classes on MSC for a MSC-specific problem.
- See issue 95065 for a common GCC warning problem that is solved by turning on the visibility feature.
If you want to find out which symbols exported by a given library are actually used, the following is a relatively easy way that works on Linux (bash syntax):
find ${SOLARVER?}/${OUTPATH?}${PROEXT?}/bin${UPDMINOREXT?}/ ${SOLARVER?}/${OUTPATH?}${PROEXT?}/lib${UPDMINOREXT?}/ -type f -exec bash -c 'file "$0" | fgrep -q " ELF " && nm -D --undef "$0" | cut -c 12-' {} \; | sort | uniq > syms
produces a file syms
that contains all symbols needed anywhere. Then,
comm -1 -2 syms <(nm -D --def ${SOLARVER?}/${OUTPATH?}${PROEXT?}/lib${UPDMINOREXT?}/libcharttoolsli.so | cut -c 12- | sort) | c++filt
lists which of these symbols can be served by libcharttoolsli.so
(and similarly for any other library), and
comm -1 -3 syms <(nm -D --def ${SOLARVER?}/${OUTPATH?}${PROEXT?}/lib${UPDMINOREXT?}/libcharttoolsli.so | cut -c 12- | sort) | c++filt
lists those symbols exported by libcharttoolsli.so
that are not used anywhere.