2015-10-05 146 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库的文档,看看是否存在这样的约束。