How to explicitly control exported symbols of dynamic shared libraries
Contents
Benefits of exporting symbols on demand
- Reduce the amount of time of loading the library.
- Reduce the size of library.
- Optimize the code generation.
- Improve library maintainability and make the library easier to use.
- Reduce the potential for symbol collision.
List the symbols of shared library
1. nm
https://llvm.org/docs/CommandGuide/llvm-nm.html
nm -gD libxxx.so
2. objdump
https://llvm.org/docs/CommandGuide/llvm-objdump.html
objdump -T libxxx.so
3. readelf
https://man7.org/linux/man-pages/man1/readelf.1.html
readelf -Ws libxxx.so
Option 1. the visibility attribute
1 |
Compile the code with -fvisibility=hidden
flag. This option forces the default visibility of all symbols to be hidden
.
1 | c++ -I. -fvisibility=hidden -o a.o -c a.cpp |
On Windows, using the keyword __declspec(dllexport) to export symbols . See https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=msvc-170
See more details: https://gcc.gnu.org/wiki/Visibility
Option 2. linker version scripts for ELF platforms (like Linux and Android)
For example, there is a file only_jni_exports.map
:
1 | { |
- After
global
, which symbols should be exported. - After
local
, which symbols should not be exported. - wildcards:
*
matches 0 or more characters,?
matches a single character. - This file specifies not to export all symbols except those explicitly exported by global.
Using this file in link options:
1 | gcc -shared a.o b.o \ |
Using this scripts file in CMakeLists.txt
, e.g:
1 | if (ANDROID) |
Option 3. exported symbols list file for Mach-O (macOS/iOS/…)
File libapp.exp :
1 | # Exported following symbols |
The list is a file with the names of symbols to export. The symbol names must include the underscore (_
) prefix
Using this file in comand line, e.g.:
1 | clang -dynamiclib a.c -exported_symbols_list libapp.exp -o libxxx.dylib |
Using this file in CMake, e.g:
1 | if (BUILDING_SHARED) |
Refs
- https://gcc.gnu.org/wiki/Visibility
- https://tldp.org/HOWTO/Program-Library-HOWTO/static-libraries.html
- https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
- https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Shared-Libraries.html
- https://www.gnu.org/software/gnulib/manual/html_node/LD-Version-Scripts.html
- https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html#//apple_ref/doc/uid/TP40001873-SW1
- https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html#//apple_ref/doc/uid/TP40002013-SW18
- https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-library-cpp?view=msvc-170
- https://learn.microsoft.com/en-us/cpp/build/reference/linker-options?view=msvc-170
- https://stackoverflow.com/a/34796
- https://sourceware.org/binutils/docs/ld/Options.html
- https://sourceware.org/binutils/docs/ld/Scripts.html