静态库中的符号在链接到共享库时不会导出

问题描述 投票:1回答:1

共享库的代码是模块化的,由几个独立的单元组成。每个单元都内置到静态库中。


unit1.c

#include <stdio.h>

void HelloWorld() {
  printf("Hello World!\n");
}

unit2.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.version

    merged {
      global: HelloWorld; GoodbyeWorld;
      local: *;
    };
    
  • 也尝试强制加载静态库,但未成功
    set_target_properties(merged PROPERTIES LINK_FLAGS -Wl,-force_load,libunit1.a)
    
c cmake clang
1个回答
0
投票

一种选择是为OBJECTSTATIC创建unit1而不是unit2个库。

CMakeLists.txt

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)                                                                

导出的符号

$ nm -D --defined-only libmerged.so
000000000000065d T GoodbyeWorld
000000000000064a T HelloWorld
0000000000201028 B __bss_start
0000000000201028 D _edata
0000000000201030 B _end
0000000000000670 T _fini
0000000000000520 T _init
© www.soinside.com 2019 - 2024. All rights reserved.