使用CMake和Conan为Linux和Windows部署具有第三方依赖关系的应用程序

使用CMake和Conan为Linux和Windows部署具有第三方依赖关系的应用程序,linux,windows,cmake,packaging,conan,Linux,Windows,Cmake,Packaging,Conan,我正在做一个项目,目标是Windows和Linux,并且可能在未来的MacOS上实现。它由一些具有多个共享库的应用程序组成。它是用现代C++和现代CMake编写的。它还使用第三方库,如Qt、OpenCV、Boost、GraphicsMagick、samplerate、sndfile。这些依赖关系通过Conan软件包管理器处理。我正在通过WSL在Linux Ubuntu18.04、GCC 8.1和Windows上构建—也就是Ubuntu18.04、MinGW-w64 8.1。严格地说,我使用的是第

我正在做一个项目,目标是Windows和Linux,并且可能在未来的MacOS上实现。它由一些具有多个共享库的应用程序组成。它是用现代C++和现代CMake编写的。它还使用第三方库,如Qt、OpenCV、Boost、GraphicsMagick、samplerate、sndfile。这些依赖关系通过Conan软件包管理器处理。我正在通过WSL在Linux Ubuntu18.04、GCC 8.1和Windows上构建—也就是Ubuntu18.04、MinGW-w64 8.1。严格地说,我使用的是第三方库的最新版本,带有自定义构建选项——与Ubuntu的APT上可用的版本不同,例如Qt v5.11.3或GraphicsMagick的自定义构建

我在用CPack。在Windows上,我正在构建NSIS安装程序,但在Linux上,如果需要,我希望使用DEB生成器。我的所有目标书面应用程序和共享库都有相应的CMake安装配置,因此它们会正确复制到生成的基于组件的安装程序中。真正的问题在于第三方依赖项的打包

问题 严格地说,我不知道如何在Linux和Windows上使用CMake+CPack+Conan做好这件事。我读过很多文章和帖子,但我都被绊倒了。我希望有一些东西,可以自动将project使用的所有第三方库与所需的插件捆绑到安装程序中,最重要的是,与所需的系统/编译器库libgomp、libstdc++等捆绑在一起

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

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

其他解决方案 我还研究了其他解决方案。其中一个是来自CMake的BundleUtilities。这对我不起作用。无论是系统图书馆还是地方图书馆,在识别上都存在很多问题。特别是在WSL中,它在处理对USER32.dll、KERNEL32.dll的依赖关系时遇到了问题。Windows中的BundleUtilities只适用于MSYS,但在MSYS中,我无法通过Conan编译一些第三方库图形控件,这就是我使用WSL的原因

总结 我正在寻找一个好的和验证的方法来封装C++项目,其中包括多个应用程序、LIBS和第三方LIB,既适用于Windows和Linux。你是怎么做的?您只是将bin和/或lib dir复制到安装程序吗?就CMake/CPack代码而言,您是如何做到这一点的?INSTALLDIRECTORY…,或类似的?我不确定,但我认为这个问题应该在业界已经解决了


谢谢你的建议。

首先,柯南是一个开发包经理,而不是分发包经理,这就是为什么你没有找到一个简单的方法来解决你的问题。其次,大多数讨论都是在会议上进行的,包括bug和问题。在那里你会发现一个很大的社区+柯南开发者,他们非常有帮助

使用所需的系统/编译器库

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

谈到CPack,我们与柯南就it使用进行了公开讨论: 请加入我们

我认为您的案例没有几个选择:

在package方法上,运行self.copy和self.cpp_deps中的所有依赖项,其中包括所有库,以便可以运行Cpack 用于部署所有工件,并使用cpack或任何其他安装工具运行 我们的朋友SSE4正在写一篇关于Deployment+Conan的新博文,我认为它可以帮到你很多。你可以阅读预览


问候

谢谢,我会检查的!根据系统/编译器库:由于不必要的空间开销,我决定不对它们进行静态链接。该项目由一些共享库和一些应用程序组成。所有内容都使用完全相同的编译器集进行编译,即使是第三方库。使用libstdc++等的动态链接,所有生成的二进制文件都有点小
r,并且没有代码重复。事实上,老实说,我没有测量静态链接的实际大小开销。。。我试试看。你的建议在安全方面也是可行的。谢谢我多次看到,柯南主要专注于发展,而不是分销。但是,在我看来,大多数项目都将最终分发!我真的不明白那个障碍;没有障碍,只有专注。例如,Conan支持很多生成器,从旧的makefile到cmake。这需要很大的努力。因此,添加这种新的部署支持将是一个巨大的挑战,对代码的许多更改、大量工作以及我们的反馈都不是大多数用户的大要求。不管怎样,我知道你在说什么,因为我在过去也遇到过同样的问题。IIRC libstdc++大约有24MB,具体取决于版本、操作系统、发行版。。。如果你想提供安装程序,避免静态链接,你将需要提供一个安装程序由发行版红帽,centos,debian,ubuntu。。。还有拱门。我记得很久以前,我用cmake为Gitlab编写了一个脚本。我需要为linux、freebsd和Windows提供安装程序,这是一个很好的挑战。感谢您提供博客文章的链接。这对我帮助最大。我将使用conan部署工具,并查看生成二进制文件的情况。对我来说,这似乎是最方便的,而且更多的项目都是这样做的。也许这对你想做的有帮助