How to explicitly control exported symbols of dynamic shared libraries
source link: https://yrom.net/blog/2023/04/19/how-to-explicitly-control-exported-symbols-of-dyamic-shared-libraries/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
How to explicitly control exported symbols of dynamic shared libraries
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
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
#if HAVE_VISIBILITY && BUILDING_LIBFOO
#define LIBFOO_EXPORTED __attribute__((__visibility__("default")))
#elif (defined _WIN32 && !defined __CYGWIN__) && BUILDING_SHARED && BUILDING_LIBFOO
#define LIBFOO_EXPORTED __declspec(dllexport)
#elif (defined _WIN32 && !defined __CYGWIN__) && BUILDING_SHARED
#define LIBFOO_EXPORTED __declspec(dllimport)
#else
#define LIBFOO_EXPORTED
#endif
Compile the code with -fvisibility=hidden
flag. This option forces the default visibility of all symbols to be hidden
.
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
:
{
global:
JNI_*;
Java_*;
local:
*;
};
- 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:
gcc -shared a.o b.o \
-Wl,--version-script,only_jni_exports.map \
-Wl,-soname,libxxx.so \
-o libxxx.so
Using this scripts file in CMakeLists.txt
, e.g:
if (ANDROID)
add_library(${TARGET} SHARED ${SOURCE})
set(VERSION_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/only_jni_exports.map)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--version-script=${VERSION_SCRIPT}")
set_target_properties(${TARGET} PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
endif()
Option 3. exported symbols list file for Mach-O (macOS/iOS/…)
File libapp.exp :
# Exported following symbols
_foo
_bar
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.:
clang -dynamiclib a.c -exported_symbols_list libapp.exp -o libxxx.dylib
Using this file in CMake, e.g:
if (BUILDING_SHARED)
add_library(${TARGET} SHARED ${SOURCE})
if (APPLE)
set(EXPORTED_SYMBOLS_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libapp.exp)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${EXPORTED_SYMBOLS_FILE}")
set_target_properties(${TARGET} PROPERTIES LINK_DEPENDS ${EXPORTED_SYMBOLS_FILE})
endif (APPLE)
endif (BUILDING_SHARED)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK