【发布时间】: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 方库与所需的插件捆绑到安装程序中,最重要的是,与所需的系统/编译器库(libgomp、libstdc++ 等)捆绑在一起。
可能的解决方案
令我惊讶的是,在 Windows 上,这项任务相当简单,因为应用程序使用的每个 DLL(我的库、第 3 方库和系统/编译器库)都需要位于可执行文件所在的位置。我通过将所有使用的 DLL 导入到bin 目录中来让柯南参与其中。最后,以最幼稚的打包方式,我只需将bin 目录复制到安装程序中,它应该可以工作。但我不确定这种方法是否可行。
在 Linux 上,事情要复杂得多。首先,有一个包管理器。不幸的是,那里可用的库/编译器对我来说太旧了(例如,在 APT 上只有 Qt 5.9.6 )并且使用不同的编译选项构建。所以,对我来说,唯一的方法是将它们与我的软件一起发布(就像在 Windows 中一样)。通过ld 搜索动态库、RPATH 处理等也存在问题。目前,我看到的唯一解决方案是为我的应用程序编写类似“启动器”的东西,它在程序启动之前设置LD_LIBRARY_PATH。之后,在这种情况下,我们可以将bin 或lib 目录复制到DEB 安装程序,这应该可以工作。但是,我仍然不知道这是否是正确的方法。
其他解决方案
我还研究了其他解决方案。其中之一是来自 CMake 的 BundleUtilities。它对我不起作用。它在识别某些库是系统库还是本地库时存在很多问题。特别是在 WSL 中,它坚持处理对 USER32.dll、KERNEL32.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