简体   繁体   中英

C++ Shared library creation - linking against other shared libraries

I'm creating a C++ shared library which links against some Boost libraries (Boost version 1.55 on my local machine).

I can use my library on my machine, but I can't use it on another system with a different version of Boost (let's say 1.54) because of undefined references.

I am using CMake, here the CMakeLists.txt file:

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)

I'm new to library creation and I'm struggling for days on that issue. I'm wondering if I must create a static library instead with Boost inside. But I would like my library to be the smallest as possible.

EDIT: When I check my lib dependencies I got this for Boost regex: libboost_regex.so.1.55.0 => /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.55.0 (0x00007fe228a27000)

Is it possible to update this to NOT link against a particular version of Boost?

When you link to a shared library, such as Boost, it is essential that the ABI of the library that is actually loaded in run time is compatible to the one that was used when compiling and linking. Boost does not maintain ABI compatibility between releases. This is why there is a strict dependency on a particular Boost version. There is no way to build an executable or library that will be version-agnostic to the Boost version it uses.

In Linux world it is normal to open source your code so that it can be compiled for each Linux distribution individually. This way, the Boost version used during compilation and run time will be the same - the one that the distro maintainers ship.

If open source model is not suitable for you, you can either do the package building yourself for different Linux distributions or attempt to hide the dependency somehow. One way to do the latter is to build your library as a shared object but link with static libraries of Boost. You must take a great care though to not expose Boost in any of your public interfaces and not export any Boost symbols from your library. This includes type info and consequently Boost exceptions cannot be thrown from your library. Basically, the fact that you're using Boost must be absolutely hidden from your library users. Otherwise there will be difficult to resolve conflicts between your Boost and the Boost that might be used by the user of your library.

Note that for some Boost libraries even static linking is not an option as there may be a requirement to link with shared libraries in some configurations. You should consult with the documentation of each Boost library you use to see if such constraints exist.

You should not create static library, as it just an archive of object files. Also static libraries are not created by compilers, it created using arching tools

ar cr libtemp.a obj/*.o

In contrary Shared libraries are supported by Compilers.

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

And you can use tools like "nm", "ldd" and "objdump" to inspect into your library for symbols.

Read about linker and loaders, it will give a better idea about this topic.

Also standard practice for CMAKE is to use find_package instead of liking directlty.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM