Deploying a Qt 5.5.1 C++ application on multiple Linux distributions - c++

I have an application written in pure C++ and Qt 5.5.1. It compiles fine in both GCC (Lubuntu 15.10 x86) and MSVC 14.0 (Windows 8.1 x64), and works properly on both those platforms. I now want to distribute it so that it will run on other Linux distros without recompiling them there.
I'm not entirely sure how to achieve this; the Qt docs page generally suggests to link everything statically, but this is not what most other sources say (from what I understand it is a bad idea to link with glibc statically). In any case I cannot really link everything statically because GCC complains that Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking and from what I understand this isn't a warning one can simply ignore. I've tired linking statically against only libgcc and libstdc++, I copied the other missing libraries - libXau.so.6, libXdmcp.so.6 and libxcb.so.1 on a clean CentOS 7 installation and tried to run the program there, but that gave me a segmentation fault; possibly because the system is 64 bit as opposed to the platform I compiled the application on?
How can I distribute the application in a form runnable by most common configurations? Static linking is not an issue because the source is going to be released anyway.
Is it better to link against Qt statically or dynamically (if maximum binary portability is the priority)?
Do I need to provide two separate versions of the binary, 32 and 64 bit, or will a 32 bit build suffice?

My suggestion would be to offer two builds: an unsupported, fully static build that will work "anywhere" with an asterisk that there's no way you can support it if it's a commercial offering. People'll try to run it on their fridges, I kid you not. The officially supported builds must be for specific platforms only, and you can't but have VMs/test targets that run these platforms, and where you build and test on.

Related

MSVC or MinGW for distributing close-source C++ executables for Windows?

I've heard that 98% of companies use MSVC when distributing closed-source binaries for Windows.
The management of my company doesn't like the idea of paying Microsoft for compiling our own C++ software, so we use MinGW and distribute the 64-bit executables as-is, no installers either.
We statically link to MinGW runtime libraries.
On Linux we also distribute raw binaries that we compile on Ubuntu 16.04.7 and dynamically link to glibc and glibcxx.
Everything seems to just somehow work.
Are there any pitfalls that we might encounter, or other reasons why we should be doing what everyone else seems to be doing, which is to compile with MSVC and use Inno Setup? It there anything wrong with doing things simple?

Compiling a C++ program with all libs it needs

When I compile C++ code that uses openmp libs with visual studio, the program is very portable - because it runs in other machines with Windows without problems.
When I compile the C++ code with Eclipse CDT (oxygen and g++ cygwin) for Windows, in general, I need to install the correct runtime libs in the other machines to be able to run the program. I don't find it practical.
Based on this:
1) What is the right way to compile the code including all libs (g++ and openmp) to run in another Windows system?
2) How can do this in Eclipse CDT for Windows?
The problem is not in compiling, but in distributing. Windows and windows toolchains intend to use dynamic linking. Now, if created software are dependent on particular version of runtime, which includes side-by-side build, they can be run only if exactly that build is installed. Several builds of same library version may exist, they are fetched using side-by-side (SxS) mechanics.
On Linux platform this problem is solved through package manager and dependencies. On Windows you have to create an installer, which would contain or have ability to download proper version of libraries. Also installer may do proper changes to OS settings, and register them , for future rollback.
Note, that runtime libraries have debug variants which cannot be distributed and debug build of software must be run on developer system only.
"Portable" apps that appear here and there and can be run without installation, have special status not to be dependant on SxS run-time library. To my knowledge cygwin and mingw32 allowed to create such, the 64bit project of mingw had problems with that. But they are still dependant on particular versions of system .dll and may break or malfunction in case of mismatch.
Even in that case you still need some .dll, from mingw, cygwin, Qt, whatever you use and what is not a part of OS, to place them where program can reach them. Which can be folder comtaining the executable. Static linking became a gimmick of past for desktops, because of code bloat - dynamic library size easily can be dozens of megabytes.
And last: you don't compile anything with Visual Studio or with Eclipse CDT. Both designed to use various compilers, it's juse environments. You have to specify normal;y, what compiler your IDE uses, not what IDE you use to run ot.

Building application for multiple version of RedHat

Assume in my company, we have same application written in C++, running in machines of RHEL5, 6 and 7.
I want to build from one single build server (which is running RHEL7) to get the executable that runs in old previous versions of RHEL. May I know if it is achievable?
I expect if I am building in RHEL7, with corresponding version of gcc and glibc (and other libs) available in RHEL5, the resulting executable should run in RHEL5. Is my understanding correct? Or are there more things to pay attention to?
I expect if I am building in RHEL7, with corresponding version of gcc and glibc (and other libs) available in RHEL5, the resulting executable should run in RHEL5.
In theory, yes. In practice, installing multiple versions of glibc and other libraries on your RHEL7 system is probably a lost cause - especially the very old ones required by RHEL5, especially glibc, which expects to know quite a lot about the system.
The reverse may be easier - build everything on RHEL5, link statically all you can but glibc (it's essentially impossible to link statically against glibc) and hope that forward binary compatibility holds well enough. This is the route that is usually taken ("build on the oldest Linux distribution you want to support"), but I doubt that forward binary compatibility of glibc will work, as RHEL5 is extremely ancient compared to RHEL7.
Getting back to the original plan, it's probably easier to install RHEL5 and 6 in containers inside the RHEL7 machine and build those versions. After all, it's a bit like installing their gcc and libraries versions on the RHEL7 machine, but in extremely well separated sysroots - but without the overhead of having different build machines (they are all clients of the same kernel).
Finally, the extreme route is to use an alternative libc (that depends only from the kernel, choosing the oldest one you want to support) and compiling everything statically. This can be done e.g. with musl, but you'll have to compile your compiler, your libc and all your dependencies. Still, the nice result is that you'll be able to build completely standalone executables, able to run on virtually any kernel after the one you decided is your minimum requirement.
Red Hat Developer Toolset (DTS) is a GCC offering where you can compile on one major OS release, and deploy on that version plus the next major release. This will cover your RHEL 6 and 7 work. For RHEL 5, you would continue to do that separately.
DTS installs new versions of GCC "along side" the original/base version, so it won't wreck your OS.
I also like the containers idea from Matteo.
See https://developers.redhat.com/products/developertoolset/overview/

Missing libraries when cross-compiling using mingw

I sometimes run into this problem:
1 - I develop a working C++/C program on Ubuntu Linux for Ubuntu, which uses some libraries (which are platform-independent, such as OpenSSL, Boost, GNU Scientific Library, DCMTK, and others: these are generally available from apt-get, and are installed properly).
2 - I would like to also cross-compile the program from Ubuntu to run on Windows, using mingw (x86_64-w64-mingw32-g++).
3 - The libraries are missing from mingw.
Is there a generic way to easily "convert" any library from linux-version (or source-code) into mingw installation so that it can be used to build windows a program? Each library seems to have it's own separate complicated installation instructions for mingw.
You certainly can't convert Linux libraries directly to Windows, since they almost certainly make use of Linux system calls and calling libraries (such as the C runtime library) that are specific to Linux (even if the code doesn't directly call anything else, the compiler may add function calls implicitly, such as memory allocation calls from template functions and such)
You may be able to find "replacement" Windows libraries that you can install, but yes, many probably come with a Windows installer, which makes it hard to install without using either Wine or having a "real" Windows (but then you need that to test your app, so I'm not sure how much hindrance it really is).
Some libraries may be possible to BUILD with the mingw compiler as a cross-compiler under Linux, if they are written in a portable way, which may be an easier choice than installing a ready-made Windows library. But it assumes you can find the sources...
Researching something similar right now and running into issues with libraries like openssl, boost, sqlite, libpcap,...
The best solution have found so far is to utilize WSL2 and Docker.
https://code.visualstudio.com/blogs/2020/03/02/docker-in-wsl2
WSL2 is a Linux environment for Windows (utilizes Hyper-V).
Docker allows you to make containers for both windows and Linux that can talk with each other.
I have the base code I need run under WSL2 in Linux and when I need to access it from windows I utilize docker.
This isn't a perfect solution but I hope it helps.
Some Linux programs can be compiled on Windows via Mingw.
Here is how to set the cross-compiler environment:
How to compile a Linux program with Mingw?

Some Issues About Cygwin[Linux in Windows] (socket,thread,other programming and shell issues)

I have some question about cygwin :
Can I use Cygwin develop socket based code?
Does Cygwin have read() and write() functions that work with file descriptors?
Can I use Pthread library in Cygwin?
Does code that compiles in Cygwin also
compile in Linux without any change or with little change?
Will an executable file that built by
Cygwin run in Linux ?
Why does Cygwin not need the linker
option -lpthread when I use pthread library?
why in #include <iostream> don't I need to use using namespace std; ?
Can I work with QT in Cygwin? If so,How?
Can I boot my Linux in other
partition with Cygwin and use it?
Can I access the other partition
that is EXT3 in Cygwin?
On 1:
Yes. Socket libraries are shipped with Cygwin - many socket based apps such as web servers are included in the base distribution.
On 2:
Yes. I think all of the 'section 2 and 3' system calls in the GNU C runtime and library are implemented by the cygwin runtume. You can check this in the man pages that come with Cygwin. A list of system calls and std lib calls implementd by Cygwin can be found here.
On 3: Yes. Pthread is included in Cygwin. The list referred to in the link above mentions pthreads as well.
On 4: Anything built against GNU libraries should work with little or no change between Cygwin and Linux (assuming there are no dependencies missing on Cygwin). Depending on CPU architecture you may have to worry about word alignment, endianness and other architecture-specific porting issues, but if you're targeting Windows and Linux on Intel your code would have few if any porting issues arising from CPU architecture.
On 5: Cygwin will build a program against its own shared libraries by default but GCC can cross-compile to target other platforms. You could (in theory) set GCC up to cross-compile to any target supported by the compiler. There are plenty of resources on the web about cross-compiling with GCC, and I don't think the process will be materially different on Cygwin.
Note that Cygwin binaries will not run on Linux - or Vice-versa. You will still need separate builds for both.
On 6: Not sure - at a guess it's included in the standard runtime, perhaps because it was necessary to wrap the Win32 threading API for some reason.
On 7: Don't know - it's probably the same on g++ on all platforms. Apparently a compiler bug. Dan Moulding's Answer covers this in more detail.
On 8: Yes. IIRC QT is available in the standard builds and it will certainly compile on Cygwin. As with Linux/Unix, QT on Cygwin uses an X11 backend so you will need to have an X server such as XMing running.
In order to avoid the dependency on an X server you may want to build QT apps against the Win32 API,. It is possible to do this with MinGW, which is a set of header files and libraries to build native Win32 apps with GCC. MinGW can be used from within a Cygwin environment (an example of GCC on Cygwin cross-compiling to a non-Cygwin target) and the installer from cygwin.com gives you the option of installing it.
MinGW is quite mature; it has all of the 'usual suspects' - libraries and header files you would expect to find on a Unix/Linux GCC development environment and is very stable. It
is often the tool of choice for building Win32 ports of open-source software because it is (a) free, (b) supports the libraries used by the software and (c) uses GCC so it is not affected by dialectic variations between MSVC and GCC.
However, these dialectic variations in the language and available libraries (for example MSVC doesn't come with an implementation of getopt) mean that porting programs between MinGW and MSVC can be quite fiddly. My experience - admittedly not terribly extensive as I've only done this a few times - is that porting applications between MinGW32 and Linux is easier than porting between MinGW and MSVC. Obviously apps with non-portable dependencies such as Win32 specific API usage would require the dependent components to be re-written for the new platform but you'll have far fewer problems with differences in the standard libs, header files and language dialect.
QT does a fairly good job of providing a platform abstraction layer. It provides APIs for database access, threading, I/O and many other services as well as the GUI. Using the QT APIs where possible should help with portability and the Unix/Linux flavoured libraries that come with MinGW mean that it might give you a good platform for making applications that will port between Win32 and Linux with relatively little platform dependent code.
EDIT: The qt development packages in Cygwin are:
qt4: Qt application framework (source)
qt4-devel-tools: Qt4 Assistant, Designer, and Linguist
qt4-doc: Qt4 API documentation
qt4-qtconfig: Qt4 desktop configuration app
qt4-qtdemo: Qt4 demos and examples
You'll probably also need gcc4-g++ and some other bits and pieces. This listing on the cygwin web site has a list of the packages.
"Yes" to all of those except 5. You'll have to build your executables separately for Linux, but that should be straightforward since the answer to 4 is "yes".
Make sure you install all the development headers you need on both platforms.
Yes, Yes, Yes, Yes (if you write it carefully and don't use anything specific to cygwin), No.
On 5: it may be possible to cross-compile from Cygwin to Linux, I really don't know. If it is, then technically some executables "built by Cygwin" would run on Linux. But Cygwin executables won't run on Linux.
1-4: The answers to these are all "yes", because all of these features you are asking about are part of the POSIX standard. Cygwin is basically a POSIX layer for Windows so, naturally, Cygwin includes all of these features.
5: No, Cygwin binaries will not execute under the Linux kernel, because ultimately the code generated by Cygwin is Windows native code. It will link with the usual Windows DLLs (like kernel32.dll), whereas Linux does not even have a notion of DLLs (it has shared objects which are similar, but different). More importantly, executables built under Cygwin will be in the PE format, but Linux generally uses the ELF format for executables. You could, of course, do cross-compiling under Cygwin, and thereby generate native Linux executables, but it doesn't sound like this is what you are looking for. Also, compiling a new version of GCC to use as a cross-compiler under Cygwin is probably no trivial task.
6: GCC under Cygwin doesn't require use of -lpthread because all of the pthread code under Cygwin is in cygwin1.dll which is always linked in by default.
7: This is a bug in GCC (on all platforms). It has been around for a long time and will probably never be fixed.
8: ConcernedOfTunbridgeWells did a great job of explaining this, so there's not much left for me to say. However, it's worth noting that Cygwin has the X.org X Window System in its package list. With Cygwin 1.7.x, setting it up and using it is a breeze and it seems pretty rock-solid. If you want to use Qt with X, I'd recommend using Cygwin's X server.
In response to #7, the version of the C++ compiler that you have is probably out of date. If you don't need linux/posix portability, I'd switch to the non-cygwin MinGW GCC compiler - you can get 4.4.1 at http://tdragon.net/recentgcc/
Regarding 6, you don't need -lpthread because Pthreads support is part of the Cygwin DLL.