![](/img/trans.png)
[英]How to prevent all symbols from static library to load and why other symbols from same .o file get exported to test while linking static library
[英]Symbols from a static library are not exported while linking to a shared library
共享库的代码是模块化的,由几个独立的单元组成。 每个单元都内置在 static 库中。
单元1.c
#include <stdio.h>
void HelloWorld() {
printf("Hello World!\n");
}
单元2.c
#include <stdio.h>
void GoodbyeWorld() {
printf("Goodbye World!\n");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
add_library(unit1 STATIC unit1.c)
target_compile_options(unit1 PRIVATE -fPIC)
add_library(unit2 STATIC unit2.c)
target_compile_options(unit2 PRIVATE -fPIC)
add_library(merged SHARED)
target_link_libraries(merged unit1 unit2)
set_target_properties(merged PROPERTIES LINKER_LANGUAGE C)
构建步骤:
cmake . && cmake --build .
libmerged.so 导出的符号:
$ nm -D --defined-only libmerged.so
0000000000201020 B __bss_start
0000000000201020 D _edata
0000000000201028 B _end
00000000000005a0 T _fini
0000000000000458 T _init
Q为什么符号 HelloWorld 和 GoodbyeWorld 没有导出? 如何解决?
我试过--version-script
没有成功。
CMakeLists.txt 中的附加设置
set_target_properties(merged PROPERTIES LINK_FLAGS -Wl,--version- script=merged.version)
合并版本
merged { global: HelloWorld; GoodbyeWorld; local: *; };
set_target_properties(merged PROPERTIES LINK_FLAGS -Wl,-force_load,libunit1.a)
您需要将 --whole --whole-archive
选项传递给 linker。 在 CMake 中,可以按如下方式进行。
cmake_minimum_required(VERSION 3.0.2)
add_library(unit1 STATIC unit1.c)
target_compile_options(unit1 PRIVATE -fPIC)
add_library(unit2 STATIC unit2.c)
target_compile_options(unit2 PRIVATE -fPIC)
add_library(merged SHARED)
set_target_properties(merged PROPERTIES LINKER_LANGUAGE C)
target_link_libraries(merged
"-Wl,--whole-archive libunit1.a libunit2.a -Wl,--no-whole-archive"
unit1 unit2
)
注意: target_link_libraries
命令也可用于指定 linker 标志,而不仅仅是库名称。 引号很重要,否则 CMake 可能会重新排列标志并删除重复项。
$ nm libmerged.so | grep " T "
000000000000065d T GoodbyeWorld
000000000000064a T HelloWorld
0000000000000670 T _fini
0000000000000520 T _init
为避免该问题,另一种选择是为unit1
和unit2
创建OBJECT
而不是STATIC
库。
cmake_minimum_required(VERSION 3.0.2)
add_library(unit1 OBJECT unit1.c)
target_compile_options(unit1 PRIVATE -fPIC)
add_library(unit2 OBJECT unit2.c)
target_compile_options(unit2 PRIVATE -fPIC)
add_library(merged SHARED $<TARGET_OBJECTS:unit1> $<TARGET_OBJECTS:unit2>)
set_target_properties(merged PROPERTIES LINKER_LANGUAGE C)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.