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

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

本文关键字:文件 创建 C++ 何使用 CMake      更新时间:2023-10-16

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

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

我正在学习本教程,我的CMakeLists.txt正是本教程的副本。

这个软件运行良好,我就是不能分发它。有可能吗?

谢谢大家

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

...
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/目录,该目录已经包含了可执行文件和共享库文件。

测试用例

我针对自己的简单程序进行了测试,该程序依赖于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]
...

您有几个选项:

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