如何使用 CMake 和 C++ 创建可分发的文件?

How can I create a distributable with CMake and C++?

我正在尝试构建一个基于 ros 的小可执行文件,我可以将其分发到不同的 Linux 机器,它在我正在开发它的机器上功能齐全(因为它包含所有 *.so 它已链接的文件),但是当我尝试 运行 另一台机器上的可执行文件时找不到它们。

有没有办法将这些 .so 文件添加到可执行文件或创建一个包含所有必要库的压缩目录,以便能够 运行 在任何机器上执行此可执行文件?

我正在关注 this tutorial and my CMakeLists.txt is an exact copy of this one

该软件运行良好,但我无法分发它。可以吗?

谢谢大家

您有多种选择:

  1. 构建所有静态库依赖项,然后生成一个大的静态链接可执行文件。
  2. 保持二进制链接,并使用 qt 安装程序框架或类似 InstallBuilder 的替代方案将您的应用程序及其依赖项打包。
  3. 创建发行版独立包:Snappy, Flatpak or AppImage

最少,你可以使用cpack(安装时已经作为cmake的一部分)通过在最底部添加以下内容你的 CMakeLists.txt

...
install(TARGETS myapp
    RUNTIME
    DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin)
install(CODE "
    include(BundleUtilities)
    fixup_bundle(${CMAKE_CURRENT_SOURCE_DIR}/bin/myapp \"\" \"\")
    ")
...
include(CPack)

主要在fixup_bundle,它会为您检查依赖库。

工作流程如下

  1. 创建一个临时构建目录(假设我们在根源目录)mkdir build
  2. cd build
  3. cmake ..
  4. cpack

您的二进制可执行文件结果(前提是您已经为此添加了这样的 cmake 命令)以及我们上面所做的 .so 文件将位于 <project-source-root-dir>/bin 目录中。

这还没有完全利用 cpack 提供的功能,即构建与我们选择的文件或源代码捆绑在一起的 .tar.gz 文件。但是我们可以简单地包含一个自定义脚本来处理结果 bin/ 目录,该目录已经打包了可执行文件和共享库文件。

测试用例

我针对我自己的 simple program 进行了测试,它依赖于 OpenSSL 的 SSL + Crypto 组件和 libcurl 的共享库。按照上面的步骤。我的 bin/ 目录中有以下内容。

libcrypto.so.1.1  libcurl.so  libssl.so.1.1  tt

并通过我得到的 readelf -d <executable-file> 进行验证

Dynamic section at offset 0x9be8 contains 30 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libcrypto.so.1.1]
 0x0000000000000001 (NEEDED)             Shared library: [libcurl.so]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
...