【问题标题】:Application deployment with 3rd-party dependencies for both Linux and Windows, using CMake and Conan使用 CMake 和 Conan 为 Linux 和 Windows 部署具有第三方依赖项的应用程序
【发布时间】:2019-09-18 09:45:59
【问题描述】:

我正在开发一个项目,该项目同时针对 Windows 和 Linux(并且可能在未来的 MacOS 中)。它由一些具有多个共享库的应用程序组成。它是用现代 C++ 和现代 CMake 编写的。它还使用第三方库,如 Qt、OpenCV、Boost、GraphicsMagick、samplerate、sndfile。这些依赖项是通过柯南包管理器处理的。我正在 Linux(Ubuntu 18.04、GCC 8.1)和 Windows(通过 WSL - 也是 Ubuntu 18.04、MinGW-w64 8.1)上构建。我正在使用具有自定义构建选项的相当新版本的 3rd 方库(严格来说 - 与 Ubuntu 的 APT 上可用的版本不同,例如 Qt v5.11.3,或自定义构建的 GraphicsMagick)

我正在使用 CPack。在 Windows 上,我正在构建 NSIS 安装程序,但在 Linux 上,我想使用 DEB 生成器(如果需要,可以使用其他)。我的所有目标(编写的应用程序和共享库)都具有适当的 CMake 的 INSTALL 配置,因此它们被正确复制到生成的安装程序(基于组件的安装)中。真正的问题在于打包 3rd 方依赖项。

问题

严格来说,我不知道如何在 Linux 和 Windows 上使用 CMake+CPack+Conan 做好它。我已经阅读了很多文章和帖子,但我被困住了。我想要一些东西,它会自动将项目使用的所有 3rd 方库与所需的插件捆绑到安装程序中,最重要的是,与所需的系统/编译器库(libgomplibstdc++ 等)捆绑在一起。

可能的解决方案

令我惊讶的是,在 Windows 上,这项任务相当简单,因为应用程序使用的每个 DLL(我的库、第 3 方库和系统/编译器库)都需要位于可执行文件所在的位置。我通过将所有使用的 DLL 导入到bin 目录中来让柯南参与其中。最后,以最幼稚的打包方式,我只需将bin 目录复制到安装程序中,它应该可以工作。但我不确定这种方法是否可行。

在 Linux 上,事情要复杂得多。首先,有一个包管理器。不幸的是,那里可用的库/编译器对我来说太旧了(例如,在 APT 上只有 Qt 5.9.6 )并且使用不同的编译选项构建。所以,对我来说,唯一的方法是将它们与我的软件一起发布(就像在 Windows 中一样)。通过ld 搜索动态库、RPATH 处理等也存在问题。目前,我看到的唯一解决方案是为我的应用程序编写类似“启动器”的东西,它在程序启动之前设置LD_LIBRARY_PATH。之后,在这种情况下,我们可以将binlib 目录复制到DEB 安装程序,这应该可以工作。但是,我仍然不知道这是否是正确的方法。

其他解决方案

我还研究了其他解决方案。其中之一是来自 CMake 的 BundleUtilities。它对我不起作用。它在识别某些库是系统库还是本地库时存在很多问题。特别是在 WSL 中,它坚持处理对 USER32.dllKERNEL32.dll 的依赖关系。 Windows 中的BundleUtilities 仅适用于 MSYS,但在 MSYS 中我无法编译一些 3rd-party 库(通过柯南的 GraphicsMagicks),这就是我使用 WSL 的原因。

总结

我正在寻找一种经过验证的良好方法,将 C++ 项目与多个应用程序、库和已发布的第 3 方库打包在一起,适用于 Windows 和 Linux。你怎么做这样的事情?您只是将bin 和/或lib 目录复制到安装程序吗?你是如何(就 CMake/CPack 代码而言)这样做的? INSTALL(DIRECTORY ...),或类似的?我不确定,但我认为这个问题在业界应该已经解决了。 ;)

感谢所有建议。

【问题讨论】:

  • 对于 linux,存在诸如 SnapPak (flatpak.org) 和/或 AppImages (appimage.org) 之类的东西。也许这对您尝试做的事情有帮助

标签: linux windows cmake packaging conan


【解决方案1】:

首先,Conan 是用于开发而非分发的包管理器,这就是为什么您没有找到解决问题的简单方法的原因。其次,大部分讨论都是在Conan issue 进行的,包括错误和问题。在那里你会发现一个非常有帮助的大型社区 + 柯南开发者。

带有所需的系统/编译器库

这不是柯南的一部分。为什么不为系统库使用静态链接?

谈到 CPack,我们与柯南就它的使用进行了公开讨论:https://github.com/conan-io/conan/issues/5655 请加入我们。

我认为您的情况很少有选择:

  • package 方法上,运行self.copy 和来自self.cpp_deps 的所有依赖项,其中包括所有库,因此您可以运行Cpack
  • 使用Conan deploy generator 部署所有工件,使用hook 可以运行cpack 或任何其他安装工具

朋友 SSE4 正在写一篇关于 Deployment + Conan 的新博文,我想对你有很大帮助。您可以阅读预览here

问候!

【讨论】:

  • 谢谢,我会检查的!根据系统/编译器库:由于不必要的空间开销,我决定不静态链接它们。该项目由一些共享库和一些应用程序组成。一切都是用完全相同的编译器集编译的,甚至是第 3 方库。与例如动态链接libstdc++ 所有生成的二进制文件都小了一些,并且没有代码重复。事实上,老实说,我没有测量静态链接的实际大小开销......我会尝试的。您的建议在安全性方面也很实用。谢谢!
  • 我多次看到,柯南主要专注于开发,而不是分发。但是,在我看来,大多数项目最终都会分发!我真的不明白那个障碍。 ;)
  • 没有障碍,只有专注。例如,柯南支持很多生成器,从旧的 makefile 直到 cmake。这需要很大的努力。因此,添加这种新的部署支持将是一个很大的挑战,对代码的许多更改,大量的工作以及我们的反馈,对于大多数用户来说并不是很大的要求。不管怎样,我知道你在说什么,因为我过去也遇到过同样的问题。
  • IIRC libstdc++ 约为 24MB(取决于版本、操作系统、发行版 ...)如果您想提供安装程序,避免静态链接,您需要通过发行版提供一个安装程序(red hat、centos、 debian, ubuntu, ...) 和拱门。我记得很多年前我用 cmake 为 Gitlab 做了一个脚本。我需要为 linux、freebsd 和 Windows 提供安装程序,这是一个很好的挑战。
  • 感谢您提供指向博客文章的链接。它对我帮助最大。我将使用conan-deploy-tool 并环顾四周生成AppImage 二进制文件。它看起来对我来说最方便,而且越来越多的项目正在这样做。
猜你喜欢
  • 2011-04-25
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 2017-03-18
  • 2012-04-15
  • 2016-07-02
  • 2023-03-06
  • 1970-01-01
相关资源
最近更新 更多