簡體   English   中英

鏈接到共享庫時,不會導出 static 庫中的符號

[英]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: *; };
  • 還嘗試強制加載 static 庫但未成功
    set_target_properties(merged PROPERTIES LINK_FLAGS -Wl,-force_load,libunit1.a)

您需要將 --whole --whole-archive選項傳遞給 linker。 在 CMake 中,可以按如下方式進行。

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)
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

為避免該問題,另一種選擇是為unit1unit2創建OBJECT而不是STATIC庫。

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM