簡體   English   中英

將 --whole-archive 鏈接器選項與 CMake 和具有其他庫依賴項的庫一起使用

[英]Using --whole-archive linker option with CMake and libraries with other library dependencies

我有一個項目,它曾經是一組巨大的源文件,所有文件都被編譯然后鏈接為一個可執行文件。 作為使項目更加模塊化的第一步,我將構建分解為幾個更小的塊並使其成為靜態庫。 有一個層次結構,因此Exe1將鏈接到靜態庫Lib2ALib2B Lib2A將依賴於靜態Lib3Alib3Blib3C等。這里的數字顯示了它們在層次結構中的層。

問題是我需要在鏈接時使用--whole-archive ,否則找不到來自底層庫的某些符號。

當我為Exe1的鏈接添加以下內容時:

target_link_libraries(Exe1 -Wl,--whole-archive Lib2A Lib2B -Wl,--no-whole-archive)

我最終得到了一個實際的鏈接階段命令,例如:

g++ -o Exe1 -Wl,--whole-archive libLib2A.a libLib2B.a -Wl,--no-whole-archive libLib3A.a libLib3B.a libLib3C.a

不可避免地,一些第 3 層靜態庫中的符號會丟失,並且我會出現丟失符號錯誤。

我預計因為Lib2ALib3*庫作為依賴項,所以它們也將在鏈接器命令的--whole-archive部分“內部”,但它們會出現在外部。

我嘗試了許多不同的組合(例如將--whole-archive東西放在較低層),但還沒有遇到使用 CMake 的方法。 我究竟做錯了什么?

謝謝

對於 3.12 和更新版本的 CMake,我會使用對象庫。

我為早於該版本的版本找到的解決方法是創建一個中間靜態庫,該庫使用一些屬性魔法將所有鏈接依賴項放在 --whole-archive 部分中。 對我來說,頂級靜態庫被稱為“源”。 它本身實際上不包含任何內容,但對一堆其他靜態庫具有鏈接依賴關系。 我創建了“源組合”,如下所示:

add_library(source-combined STATIC "")
set_target_properties(source-combined PROPERTIES LINKER_LANGUAGE CXX)

target_link_libraries(source-combined PUBLIC
  -Wl,--whole-archive
  $<TARGET_PROPERTY:source,INTERFACE_LINK_LIBRARIES>
  -Wl,--no-whole-archive
)

現在,當我通過鏈接這個源組合庫來創建可執行文件或共享庫時,我得到了 --whole-archive 和 --no-whole-archive 作為整個靜態庫集的書擋,這些靜態庫是鏈接依賴項'資源'。 偶然發現這種技術需要很長時間,所以我正在分享它。

以下對我有用。 考慮兩個庫:

  • 我的平台
  • my_clib

我們想要 my_clib 的整個存檔,以及指向它的 my_platform 鏈接。

add_library(my_platform INTERFACE) # this could also be a regular library

add_library(my_clib STATIC)
target_sources(my_clib
PRIVATE 
    gcc_newlib_nano.c 
    gcc_newlib_nano_cpp.cc 
)

# Link my_clib and any other libs
target_link_libraries(my_platform
INTERFACE
    my_clib
)
# Ensure the whole archive is linked
target_link_options(my_platform
INTERFACE
-Wl,--whole-archive ${CMAKE_CURRENT_BINARY_DIR}/libmy_clib.a -Wl,--no-whole-archive
)

作為上述答案的替代方案,我需要快速而骯臟地查看添加整個存檔目標標志(或將代碼庫轉換為對象庫......)的努力是否是正確的解決方案。 通過遵循默認鏈接命令的CMake 源代碼,我將項目的命令修改為:

set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER>  <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--start-group -Wl,--whole-archive <LINK_LIBRARIES> -Wl,--no-whole-archive -Wl,--end-group")

它奏效了! 雖然不是最好的解決方案,但它至少會很快得到一些結果。

如果您需要使用鏈接器選項--whole-archive ,那么您肯定應該使用對象庫:

    # Lib2A/CMakeLists.txt
    add_library(Lib2A OBJECT ${Lib2A_SRC})
    # Lib2B/CMakeLists.txt
    add_library(Lib2B OBJECT ${Lib2B_SRC})

它是可移植的,不需要使用鏈接器選項--whole-archive

暫無
暫無

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

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