2015-10-05 205 views
1

我正在創建一個C++共享庫,它鏈接到一些Boost庫(本地機器上的Boost版本1.55)。C++共享庫創建 - 與其他共享庫鏈接

我可以在我的機器上使用我的庫,但由於未定義的引用,我不能在另一個系統上使用Boost的不同版本(比如說1.54)。

我使用CMake的,這裏的CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8) 
project(my_library) 

set(CMAKE_BUILD_TYPE Release) 
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib) 

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 

FILE(GLOB_RECURSE INCLUDE_FILES "include/*.hpp") 
FILE(GLOB_RECURSE SOURCE_FILES "src/*.cpp") 

add_library(${PROJECT_NAME} SHARED ${INCLUDE_FILES} ${SOURCE_FILES}) 

target_link_libraries(${PROJECT_NAME} -pthread -lboost_filesystem -lboost_regex -lboost_system) 

我是新來庫的創建,我掙扎在這個問題上天。我想知道是否必須創建一個靜態庫,而不是內部的Boost。但我希望我的圖書館儘可能最小。

編輯:當我檢查我的庫依賴我這對於加速的正則表達式: libboost_regex.so.1.55.0 => /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.55.0 (0x00007fe228a27000)

是否有可能更新該反對加速的特定版本連接不上?

+0

沒有..版本在這裏是非常重要的任何二進制編譯(鏈接)與一個特定版本需要相同的版本,而加載。 – gjha

回答

0

您不應該創建靜態庫,因爲它只是對象文件的存檔。另外,靜態庫不是由編譯器創建的,它使用拱形工具創建。

ar cr libtemp.a obj/*.o 

與此相反共享庫由編譯器支持。

g++ -fPIC -shared *.o -o libtemp.so 

你也可以使用,如「納米」,「LDD」和「objdump的」工具來檢查到你的庫符號。

閱讀關於鏈接器和裝載器,它會給這個主題更好的想法。

CMAKE的標準做法是使用find_package,而不是喜歡directlty。

find_package (Threads) 
find_package(Boost,file_system,regex,system) 
target_link_libraries (myapp ${CMAKE_THREAD_LIBS_INIT} ${BOOST_LIBS}) 
+0

謝謝Gautham,我用find_package命令更新了CMakeFiles.txt,但問題仍然是一樣的:( –

+0

你無法編譯代碼? – gjha

4

當您鏈接到一個共享庫,如升壓,至關重要的是,這是在運行時實際加載的庫的ABI是編譯和鏈接時使用的兼容。 Boost不會保持版本之間的ABI兼容性。這就是爲什麼嚴格依賴於特定的Boost版本。沒有辦法建立一個可執行文件或庫,它對於它使用的Boost版本是不受版本限制的。

在Linux世界中,開源代碼是很正常的,因此可以針對每個Linux發行版分別進行編譯。這樣,在編譯和運行時使用的Boost版本將是相同的 - 這是發行版維護人員發佈的版本。

如果開源模型不適合您,您可以爲不同的Linux發行版本構建自己的程序包,或嘗試以某種方式隱藏依賴項。做後者的一種方法是將你的庫建立爲共享對象,但是與Boost的靜態庫鏈接。您必須非常小心,不要在任何公共接口中暴露Boost,也不要從庫中導出任何Boost符號。這包括類型信息,因此Boost異常不能從庫中拋出。基本上,您使用Boost的事實必須完全隱藏在您的圖書館用戶身上。否則將很難解決您的Boost和您的庫的用戶可能使用的Boost之間的衝突。

請注意,對於某些Boost庫,即使靜態鏈接也不是一種選擇,因爲在某些配置中可能需要鏈接共享庫。你應該查閱你使用的每個Boost庫的文檔,看看是否存在這樣的約束。