[英]C++/CMake installable libraries with conflicting .so names
我在 linux 系統上安裝的 c++ 包中遇到庫名稱沖突的問題。 這兩個包都使用 cpack 構建到可安裝的 apt 包中。 安裝了兩個軟件包( A
和B
)。 請注意,雖然我可以控制這些包,因此我可以更改 CMake 等,但它們將被編譯為 debian 包並作為系統庫安裝,而不是安裝在/usr/local/
。
每個包都有自己的utils
模塊。 每個模塊都安裝有父項目的命名空間(所以A::utils
和B::utils
),庫 .so 文件在項目名稱的子文件夾中,而不是直接在/usr/lib
- 所以/usr/lib/A/libutils.so
和/usr/lib/B/libutils.so
。
作為安裝后腳本,具有項目名稱( A
或B
)的文件被添加到/etc/ld.so.conf.d
,其中包含已安裝庫的路徑(例如/usr/lib/A
)以庫路徑。
除了utils
項目A
還有一個依賴於A::utils
的庫foo
我有第三個項目C
,它有一個依賴於A::foo
的可執行文件,但是(據我所知)根本不使用B
。
在構建C
我遇到錯誤,指出存在未定義的引用。 通過進一步調查,我確定當C
構建並且A::foo
必須解析utils
它會發現B::utils
而不是A::utils
導致錯誤。 我希望得到一些關於為什么會發生這種情況/如何解決的解釋? 我的理解是命名空間(除了將庫放在子文件夾中以便文件本身不沖突之外)將解決這個庫命名沖突的問題。
以下是 CMakeLists 之一的安裝部分的示例
set(PROJECT_NAME A)
set(component utils)
add_library(${component} SHARED
src/UtilsExample.cpp
)
add_library(${PROJECT_NAME}::${component} ALIAS ${component})
#... stuff with the libraries and whatnot
install(TARGETS ${component} EXPORT ${component}Targets
COMPONENT ${component}
LIBRARY DESTINATION lib/${PROJECT_NAME}
ARCHIVE DESTINATION lib/${PROJECT_NAME}
RUNTIME DESTINATION bin
)
install(EXPORT ${component}Targets
FILE "${PROJECT_NAME}-${component}Targets.cmake"
NAMESPACE ${PROJECT_NAME}::
DESTINATION lib/cmake/${PROJECT_NAME}
COMPONENT ${component}
)
為了確保庫名稱是唯一的,我是否需要在項目名稱之前加上類似的名稱? 所以圖書館將被命名為A_utils
? 這似乎會使外部項目的別名變得很奇怪, A::A_utils
Linux 動態庫解析純粹是通過所需庫的名稱。 檢查所有搜索路徑,直到找到匹配的文件名,因此您不能有重復的 .so 文件名。
但是,實際上只有庫文件名必須是唯一的。 您可以為所有內部目的保留 CMake 命名空間名稱,並將輸出文件名設置為 A_utils:
set_target_properties(A::utils PROPERTIES LIBRARY_OUTPUT_NAME A_utils)
繼續將A::utils
用於target_link_libraries()
和整個項目中的類似內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.