How to deploy a Linux application with extra libraries - linux

So I am in the following situation:
We are writing an application which needs to be deployed onto the customer machines which are running either some older version of Ubuntu (16.04 or some older) or Debian 9. Till today our application was packaged as a standard .deb package and it had system dependencies in a way that a sane apt install could handle installing it together with all its dependencies (such as Qt, sqlite, gdal, proj, etc...).
Due to some requirements however recently we have developed a few features which require that some libraries, specifically gdal and proj are using the latest version of aforementioned libraries, which are not to be found on these older systems and we can't got to each of our customer and compile these libraries on their machines.
So, obviously the question comes:
What are the best recommendations to deploy our application in the most painless way with the new libraries onto the old systems?
I have looked into AppImage but I just can't get my head around it (and did not find a good tutorial on how to deploy a Qt application with it), and flatpak and snap are not good, since we don't want to depend on any other repositories.

Related

Distribute wxWidgets applications on Linux platforms

I started to learn wxWidgets some days ago and I found it really good, but when I tried to "export" it to another platform, it didn't work. I expected that, but when I searched how to distribute wxWidgets apps, I didn't find that much, except to install all the wxWidgets library on that platform.
I use Debian 10, while the other platform where I need to export my app uses Lubuntu. It says that it needs a wxgtk3.0 library, but I guess that library will need even more libraries.
How do I export my wxWidgets application without asking the user to manually install and build all the library on its platform? Maybe even using .deb package (if really needed). Thanks in advance.
Please understand that every single distribution uses it own format comparing to Windows where there is an Installation Wizard or OSX where there is a Bundle.
Now, you can create a deb file where you set everything up.
So you can create an rpm (which is basically the same thing as deb, just for different distribution).
This is the best way as it ensures that all dependencies and their versions are satisfied.
Hope this helps!
Many Linux distributions have wxWidgets packages, so one possibility would be to simply ask users to install these packages when they need to use your application. This is not really different from installing GTK libraries or even X11 (or Wayland) that your application also depends on -- the only difference is that these libraries are almost surely already installed on any Linux desktop system, while wxWidgets ones might not be.
Another alternative is to link your application statically with wxWidgets libraries. This will make it much bigger and will prevent the users from upgrading the libraries on their system to improve the application behaviour, but can be simpler for the users to install. Note that if you choose the static linking route, you typically need to build your application on the oldest distribution you want to support (which is probably not Debian 10, which is relatively recent), as this is a simple way to ensure that it doesn't require newer versions of the (other, non-wx) libraries than the ones already present on the user's system.

Application deployment with 3rd-party dependencies for both Linux and Windows, using CMake and Conan

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.
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!

Deploy a Qt Application Binary on Linux, compatible with LSB

I have developed a small application in Qt Creator on Ubuntu 12.04 which I want should run on any other linux distro (mostly different versions of CentOS and ubuntu), just like any portable application on windows does.
I want to be able to simply share the binary file of the Application, and run the application.
I am able to successfully do this in windows, by just building the project in QT Creator and then putting the required libraries in the Application directory and then transfering them to other windows systems.
I searched all over and found out that I should be trying to build the project using LSB(Linux Standard Base) Compatibility, so that it runs on other linux distros. Is that the right way to do this?
I am very new to Qt and also to Linux (dont know much of Shell Scripting).
Thus, I dont know how I should proceed to make the Application LSB Compliant.
I have refered to, the following links:
Distributing Qt-based binaries on Linux and
Deploying Qt applications on Linux but have not beem able to understand what I am suposed to do.
I also found this question here which states a very similar situation as mine, but because I am a novice, I dont know how I should do this.
Moreover, considering that the first two articles were written 6 years back, shouldn't there be a simpler way to deploy Qt apps on the linux platform now?
I also saw something about static linking, is that the way to go?
Isn't there a way by which all of this can be done through Qt Creator itself?
If there is no hope of creating a portable Qt Application for Linux, then is there a way, say a shell script or something that would combine all the steps required to compile the Qt project on another computer and run it. Say, download Qt-SDK if not present, run qmake and make and then the newly compiled application, if not already there, so that the user can run the program just by running one script.
Your problem here is not the Linux Standard Base, but rather the presence or not of the specific version of Qt you need (or a later one).
Exactly like on a Windows machine, a user may have any of Qt installed, or they may not have it at all. On Windows it is easier to check for the presence of a certain version of Qt than it is on Linux, thus it is easier to write install tools that automate the experience.
To solve your problem there are a few ways:
Inform the user that your program requires a certain version of Qt or higher, and let the user handle the problem
Learn how to create packages for every distribution you want to target and create specific packages
Use a program like 0Install or Elf Statifier to create a package/executable containing all the necessary libraries.
The latter is similar to what many Windows and Mac programs do (they include every library they need within the installer), but it is not the preferred way on Linux, which relies heavily on shared libraries.
Making a binary application compatible with any other Linux distro is practically impossible since you will never know in advance which libraries are available in distro X, or what version of that library is available. Even among a single distro (e.g. Ubuntu), binary application are almost never backward-compatible, since anything built on Ubuntu 12.04 will have dependencies on versions libraries which are installed on that version of Ubuntu, and trying to run that binary on Ubuntu 10.04 will most probably fail simply because it doesn't have a recent enough version of glibc or some other necessary library.
However, the idea can be much more implementable if you limit yourself to a finite list of distros and versions of those distros. You can then know which libraries are available for those distros, and aim for the lowest common denominator. I used to maintain a binary application which had to support several distros (Ubuntu, Fedora, OpenSUSE, SLED, Mandriva), and the way I would do it is install the oldest distro I was targeting on my build machine. That way, the binary application would be linked to the oldest versions of the libraries available on those distros. Unless there's a new major version of such a library (which happens quite rarely, and even then, distros usually distribute the previous major version for a while for compatibility purposes), your compiled binary will then be compatible with all your targeted distros.
Therefore, the quick piece of advice I would give for your situation, use the oldest LTS version of Ubuntu which is still supported (10.04 at the moment) for your development, and you should be pretty safe for most recent popular distros. For the application you already developped on Ubuntu 12.04, you should have no problem simply recompiling the same source on 10.04. Understand that you will never however achieve 100% compatibility with a compiled C++ Qt application.
If Qt is not all that important to you, you could use a higher-level or interpreted language such as Python, Java, Perl or Ruby. With such languages, you can usually count on the language implementation already being installed on the target distro.
Deploy an application in Linux is a nightmare, luckily there are some solutions. Check this projects to build a portable binary with all their dependencies bundled:
http://statifier.sourceforge.net/statifier/main.html
http://www.magicermine.com/index.html
http://www.pgbovine.net/cde.html
Another solution is make a portable 0install package:
http://0install.net/
I recomend this solution. Personally I have been problems with the 3 first packagers.

RHEL5 Qt compiler/linker/qmake issues... advice?

I have about a few problems with a new install of the Qt SDK. I probably only need advice, but specific answers are also welcome. Before I begin a mini-story, I am running RHEL5 on academic license under VirtualBox on OSX 10.6. Using Qt version 4.5.3. This is my situation...
1.) I couldn't compile because g++ wasn't found. I fixed this by creating a link: g++ -> g++34. This allowed me to compile but it generated more errors at link-time. I had installed the framework in my home directory unintentionally so I uninstalled/reinstalled the entire SDK to /usr/local/qt.
2.) At this point I could compile but the linker complained about a missing freetype package. I had that already installed but wasn't sure why it couldn't be found. So I installed a few packages that I thought might be missing like libqt4-devel and libqt4-devel-debug. I also installed a few other general programming packages for later use.
3.) Somehwere in this process I can no longer run qmake. I ran it before and I have it installed at /usr/local/qt/qt/bin/qmake. I could create a link to it (though I shouldn't have to OR I could ensure that the location was in the PATH var). However, at this point Qt Creator says there's no Qt installation found. I re-pointed it to the installation location (using Tools/Options) but it still won't run qmake or anything else for that matter...
I only need this linux install to compile and test my Qt projects which I am developing in OSX. So my question is, should I just wipe this RHEL install and start over? And if so, should I use something else like Ubuntu? I am having plenty of hassles that I don't want to deal with as is. Note, this project will require good OpenGL support.
Is there a particular reason that you don't simply use the Qt package that's part of RHEL?
If for some reason you need to build your own, you can get all of the build dependancies with:
$ yum install yum-utils
$ yum-builddep <whatever the qt package's name is>
#scotchi is right, and you should try to use the Qt package that comes with your system unless you need a very different version. I don't know what version of Qt comes with RHEL but if its not up-to-date enough for you (and it might not be, see below) then you could consider changing OS versions. I would only do this after trying his suggestion though, because you may be able to get things working without the hassle of a full OS install.
Now, as to why you might want to switch: RHEL is, as its name ("Enterprise Linux") indicates aimed at companies who want to run servers, or large deployments of desktops. It emphasizes stability and reliability over being cutting edge. Fairly often the version of the compiler and development libraries lag a little behind the curve. This is what their clients want: a stable platform they can develop against and run programs on for a period of time, not constantly needing to keep up with the latest changes, and thoroughly tested. But for people doing development at home it may not be necessary to stay that conservative. I don't know if this is for work, school or personal programming, but it sounds to me like you should move to one of the more desktop-oriented distros. Ubuntu is great, as is Fedora. If you prefer a RHEL-like environment, then choose Fedora.

Best approach to writing a generic installer for a Linux application?

We have a Linux server application that is comprised of a number of open-source tools as well as programs we've written ourselves. Ideally we would like to be able to install this application on any common Linux distribution.
In the past, we've written perl scripts to automate installs of this application. Unfortunately, due to idiosyncrasies of different Linux distros, the logic inside these install scripts gets horribly complex, and can change as new versions of each supported distro are released. Maintaining the installer thus becomes one of the most time-intensive parts of the project!
I'm looking for assistance, be it a framework, documentation, code samples, that can make this process less painful. Here are the types of things our installer needs to do:
Create user/group accounts
Create directory trees with specific ownership and permissions
Install open-source applications, potentially compiling them from source during install
Insert pre-compiled binaries, scripts, config files, and docs into specific directories
Register init-type startup and shutdown scripts
Generate encryption keys
Verify connectivity to a central server
Instead of the installer approach, I think a better way than having a single script that does it at install time is to have a build system which generates .deb or .rpm files suitable for installation on each system you have to support.
A poor man's way of going at that might be to use checkinstall, which creates packages from the files installed via 'make install'. So you'd build your app on each system and have the package magically created in the distro's native format.
I believe that most of the tasks which you describe are fairly standardized between Linux distros. In my experience, the following should work the Debian family (including Ubuntu) and the Red Hat family (including Fedora and CentOS):
Create user / group accounts - adduser command
Create directory trees - mkdir or install, or just expand a tarball
Install open source applications - Unless you have particularly esoteric needs, this should probably be left to the distro's package manager.
Install files - install, or just expand a tarball
Startup and shutdown scripts - install to /etc/init.d then symlink to /etc/rc*.d
VMware Server is freely available for Linux and does most of the tasks which you describe. It uses Perl and maybe shell for its installation and configuration, so you might see the approach that it takes.
However, speaking as a Linux admin, I strongly prefer applications that integrate with my package management system. In other words, create .deb and .rpm files, as Vinko Vrsalovic suggested. Building packages is extremely well documented:
Building RPMs for Fedora (or Red Hat or CentOS): draft documentation, RPM Guide
Building .debs for Debian (or Ubuntu): Debian Maintainer's Guide
I tried Autopackage a few years ago, don't know how universal it is but worked quite well (was the only truly universal way back then). Surely you have to provide some LSB-compatible ways of setting up proper directories on your own, but this piece of software should help you.
Though there's probably still too much diversity among linux distributions to do everything in a completely platform-agnostic way but I may be wrong.
You may want to try BitRock InstallBuilder. It is a cross platform installation tool that allows you to do exactly what you are looking for (adding users, installing services, install pre-compiled binaries, etc). Although some of the other posts mention a number of tools that you could use in your scripts, the problem is that every Linux distribution is a bit different and simple tasks like adding an user or installer a service are suddenly non-trivial when you need to do them across Debian, Ubuntu, Mandriva, RedHat, Gentoo, etc. A good cross platform installer should isolate you from all that. Many commercial open source companies like MySQL, SugarCRM, Zenoss, Jaspersoft, Groundwork etc. have built installers based on our technology exactly because of that (in addition to their regular source code tarballs, etc.) We also provide free licenses for open source projects.
Autopackage now merged with Listaller project. Documentation's not really thorough yet but seems to be working.

Resources