【问题标题】:packaging c++ program using boost libraries with cmake/cpack使用带有 cmake/cpack 的 boost 库打包 c++ 程序
【发布时间】:2014-10-01 13:48:22
【问题描述】:

我编写了一个使用 boost 的简单 c++ 程序,我想将它部署在具有任何 linux 风格(暂时)的相同架构的机器上,这些机器可能安装了也可能没有安装一些 boost 版本。 我是部署新手,但试图阅读文档并提出一个 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 时可能还会存在一些许可问题。

【问题讨论】:

  • 我找到了复制所需依赖的脚本h3manth.com/content/copying-shared-library-dependencies手动部署(将so放在可执行文件旁边),但启动并不容易。首先我们必须删除标准依赖项,然后 chmod 711 *,然后将 ld_library_path 设置为应用程序和共享库所在的文件夹。最后程序运行,但它不是用户友好的。任何人都可以建议用户友好的部署吗?
  • 回答部分我自己的评论,通过使用 set( CMAKE_EXE_LINKER_FLAGS "-Wl,-rpath='$ORIGIN' ") 似乎不再需要设置 ld_library_path 我仍然需要删除 linux -vdso.so, libpthread.so, libstdc++.so libgcc_s.so libc.so librt.so libm.so 让它运行。虽然它适用于我的机器(ubuntu 12.04 和 ubuntu 14.04),但我不确定它是否适用于任何相同架构的 linux 风格。
  • 看来除了set(CMAKE_EXE_LINKER_FLAGS "-Wl,-rpath='$ORIGIN'")之外,set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)这行也是必须的

标签: c++ boost deployment packaging


【解决方案1】:

在 Ubuntu 上,可能标准的打包方式是遵循 DEBIAN 规则:

不是重新分发so文件,而是通过设置指定依赖关系 包含 CPack 之前的 CPACK_DEBIAN_PACKAGE_DEPENDS,看看这个 示例:

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

dpkg 会自动为你安装依赖包。

【讨论】:

    【解决方案2】:

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

    我在 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
        )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 1970-01-01
      相关资源
      最近更新 更多