使用带有cmake / cpack的boost库打包c ++程序

时间:2014-10-01 13:48:22

标签: c++ boost deployment packaging

我编写了一个简单的c ++程序,它使用boost,我希望在具有任何linux风格(暂时)的相同架构的机器上部署,可能安装或不安装某些增强版本。 我是部署新手但尝试阅读文档并想出一个CMakeLists.txt,它看起来像:

cmake_minimum_required(VERSION 2.8)
project( myprog )
FIND_PACKAGE( Boost 1.50 COMPONENTS thread system chrono program_options REQUIRED )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
add_executable( myprog myprog.cpp )
target_link_libraries( myprog -lpthread -lboost_system -lboost_chrono -lboost_program_options )

INSTALL( TARGETS myprog DESTINATION . )
SET( CPACK_GENERATOR "TGZ")
INCLUDE( CPack )

所有内容都编译并运行正常,但打包(make package)只打包可执行文件,而不是依赖的boost库“.so”

当我跑:ldd myprog 它告诉我它取决于:linux-vdso.so,libpthread.so,libboost_system.so,libboost_chrono.so,libboost_program_options.so libstdc ++。so libgcc_s.so libc.so librt.so libm.so

这些是我想要打包的共享库(也许我不需要打包标准库)

如何告诉cmake获取正确的共享对象库,并将它们放在可执行文件旁边,这样用户只需要解压缩文件夹并启动可执行文件而不进行任何安装?

静态链接不是一个选项,因为我将有一堆可执行文件将使用相同的boost库,并且可能还存在一些与libgcc静态链接的许可证问题。

2 个答案:

答案 0 :(得分:0)

在Ubuntu上,也许标准的打包方式遵循DEBIAN规则:

不是重新分发所有文件,而是通过设置指定依赖项  包含CPack之前的CPACK_DEBIAN_PACKAGE_DEPENDS,看看这个  例如:

https://github.com/thomas-moulard/visp-deb/blob/master/CMakeModules/CPackConfigDeb.cmake

dpkg将自动为您安装依赖包。

答案 1 :(得分:0)

尝试在分发包中包含所需的库是完全有效的。

我在 cmake 文件中执行此操作的方法是使用 ldd 从可执行文件中提取库名称,然后解析链接,然后将结果复制到我的包中:

从可执行文件中提取库名

execute_process(  # Get interesting dynamic libraries from binary
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    COMMAND ldd ${APPLICATION_NAME}
    COMMAND nawk "{print $3}"
    COMMAND sort -u
    COMMAND egrep "std|boost|ssl|crypto|z|mysql|sqlite" # Only libs I want to copy
    OUTPUT_VARIABLE INSTALL_FILES
    ERROR_VARIABLE INSTALL_FILES_ERROR
    OUTPUT_STRIP_TRAILING_WHITESPACE
    )

string(REGEX REPLACE "\n" ";" INSTALL_FILES "${INSTALL_FILES}") # Convert into list

message(" ----> ${INSTALL_FILES}")

if (${INSTALL_FILES_ERROR})
    message("----> ${INSTALL_FILES_ERROR}")
endif (${INSTALL_FILES_ERROR})

解析链接

foreach (_file ${INSTALL_FILES}) # Resolve links
    get_filename_component(_resolvedFile "${_file}" REALPATH)
    list (APPEND INSTALL_RESOLVED_FILES ${_resolvedFile} )
endforeach()

将库复制到包中

install(FILES                               # Copy all libraries and symlinks pointing to real paths
    ${INSTALL_FILES}
    DESTINATION "${PROJECT_VERSION}/lib/"
    COMPONENT core
    )
install(FILES                               # Copy all libraries real paths
    ${INSTALL_RESOLVED_FILES}
    DESTINATION "${PROJECT_VERSION}/lib/"
    COMPONENT core
    )