0

I'm working on a project, which targets both Windows and Linux (and possible in the future MacOS). It consists of some applications with several shared libraries. It is written in modern C++ and modern CMake. It also uses 3rd-party libraries like Qt, OpenCV, Boost, GraphicsMagick, samplerate, sndfile. Those dependencies are handled through Conan package manager. I'm building both on Linux (Ubuntu 18.04, GCC 8.1) and Windows (via WSL - also Ubuntu 18.04, MinGW-w64 8.1). I'm using fairly recent versions of 3rd-party libraries with custom built options (strictly speaking - different versions than available on Ubuntu's APT, e.g. Qt v5.11.3, or custom built of GraphicsMagick)

I'm using CPack. On Windows I'm building NSIS installer, but on Linux I would like to use DEB generator (may be other if needed). All of my targets (written apps and shared libs) have appropriate CMake's INSTALL configurations, so they are copied correctly into the generated installers (component based installation). The real problem comes with packaging of 3rd-party dependencies.

Problem

Strictly speaking, I have no idea, how to do it well using CMake+CPack+Conan, both on Linux and Windows. I've read a lot of articles and posts, but I'm stucked. I would like to have something, that automatically bundles into the installer all 3rd party libraries used by project with needed plugins and, what is the most important, with needed system/compiler libraries (libgomp, libstdc++ and so on).

Possible solution

To my surprise, on Windows, this task is fairly easy, because every DLL used by app (my libs, 3rd-party libs and system/compiler libs) needs to be located where executable is. I'm engaging Conan into this, by importing all used DLLs into bin directory. In the end, in most naive way of packaging, I will just copy the bin directory into the installer and it should work. But I'm not sure, if this approach is OK.

On Linux, things are more complicated. First, there is arleady a package manager. Unfortunately, libraries/compilers available there are too old for me (e.g. on APT there is only Qt 5.9.6 ) and are built using different compile options. So, the only way for me is to ship them with my software (like in Windows). There are also issues with searching for dynamic libraries by ld, RPATH handling and so on. At the moment, the only solution I see is to write something like 'launcher' for my app, which sets LD_LIBRARY_PATH before program starts. After that, in this case we can just copy bin or lib directory to the DEB installer and this should work. But still, I don't know if this is correct approach.

Other solutions

I've also looked into other solutions. One of them was BundleUtilities from CMake. It doesn't work for me. It has a lot of problems in recognizing, whether some library is system or local one. Especially in WSL, where it stucked in processing dependencies to USER32.dll, KERNEL32.dll. BundleUtilities in Windows worked for me only with MSYS, but in MSYS I've failed to compile some 3rd-party libraries (GraphicsMagicks via Conan) and that's the reason, why I'm using WSL.

Summary

I'm looking for good and verified method of packaging C++ projects with multiple apps, libs and shipped 3rd-party libs, both for Windows and Linux. How are you doing things like this? Are you just copying bin and/or lib dirs to the installers? How (in terms of CMake/CPack code) are you doing that? INSTALL(DIRECTORY ...), or similar? I'm not sure, but I think that this problem should be already solved in the industry. ;)

Thanks for all suggestions.

akowalew
  • 48
  • 4
  • For linux there exist things like SnapPak (https://www.flatpak.org/) and/or AppImages (https://appimage.org/). Maybe this is helpful for what you're trying to do – Raven Sep 23 '19 at 15:28

1 Answers1

1

First, Conan is a package manager for development, not for distribution, that's why you didn't find an easy way to solve your problem. Second, most of discussions are made at Conan issue, including bugs and questions. There you will find a big community + Conan devs which are very helpful.

with needed system/compiler libraries

This is not part of Conan. Why you don't use static linkage for system libraries?

Talking about CPack, we have an open discussion about it usage with Conan: https://github.com/conan-io/conan/issues/5655 Please, join us.

I see few options for your case:

  • on package method, run self.copy and all dependencies from self.cpp_deps, which includes all libraries, so you can run Cpack
  • Use Conan deploy generator to deploy all artifacts, and using a hook you can run cpack or any other installer tool

Out friend SSE4 is writing a new blog post about Deployment + Conan, I think it can help you a lot. You can read a preview here.

Regards!

uilianries
  • 3,363
  • 15
  • 28
  • Thank you, I will check that! According to system/compiler libraries: I've decided not to link statically against them because of unnecessary space overhead. This project consist of some shared libraries and some applications. Everything is compiled with exactly the same compiler set, even 3rd party libraries. With dynamic linking of e.g. `libstdc++` all resulting binaries are a bit smaller and there is no code duplication. In fact, to be honest, I didn't measure real size overhead of static linking... I will try. Your suggestion is also practical in terms of security. Thanks! – akowalew Sep 18 '19 at 12:11
  • I saw many times, that Conan is mainly focused on development, not on distribution. But, in my opinion, most of projects are going to be finally distributed! I really don't understand that barrier. ;) – akowalew Sep 18 '19 at 12:15
  • There is no barrier, but focus. For instance, Conan supports a lot of generators, since the old makefile until cmake. It demanded a big effort. So, to add this new support for deployment will be a big challenge, many changes on the code, a lot of work and by our feedback, is not big request from most of users. Anyway, I know what you talking about, because I had the same problem in the past. – uilianries Sep 18 '19 at 16:37
  • IIRC libstdc++ is ~24MB (depending version, OS, distro ...) If you want to provide installers, avoiding static linkage, you will need to provide one installer by distro (red hat, centos, debian, ubuntu, ...) and arch. I remember that I did a script with cmake, many time ago, for Gitlab. I needed to provide installer for linux, freebsd and Windows, that was a nice challenge. – uilianries Sep 18 '19 at 16:41
  • Thank you for the link to the blog post. It helped me the most. I will use `conan-deploy-tool` and look around generating an [AppImage](https://appimage.org/) binary. It looks most convenient for me and more projects are going this way. – akowalew Sep 23 '19 at 17:41