Independent qt application and dependency packing in windows and linux - linux

I made an application for Linux using QtCreator. The application uses two external libraries, qextserialport and qwt. I want to deploy the app such that all libraries it depends on are deployed alongside the executable file.
When I made an application for Windows I just copied the .dll files into the app.exe folder, and it works. But how do I do this on Linux?

In Linux you can:
1) static-link the dependencies
or
2) pack dependencies windows-style and set environment variable LD_LIBRARY_PATH pointing to the subdirectory containing the dynamic libraries
[updated]
read man ld, may be you will have to compile static versions of the libraries if they are not compiled by default (look at this tutorial if you can't tell the difference).
Great comment by synthesizerpatel, if the library uses autoconf (a lot of linux software do), it has options like --enable-shared and --enable-static.

Related

scons environment configuration from Linux to Windows

I have a scons scrip that specifies Boost libraries. This script is specific to Linux.
env.Append(LINKFLAGS=['-lboost_program_options', '-lboost_filesystem', '-lboost_system'])
env.Append(CXXFLAGS=['-std=c++17', '-lboost_program_options', '-lboost_filesystem', '-lboost_system'])
env.Append(LIBS=['-lboost_program_options', '-lboost_filesystem', '-lboost_system' ])
I want to install the application on a Windows machine and have installed Boost on the Windows machine. But how to modify the scons script to point to Boost? The -std=c++17 is easy since Visual Studio can toggle standard from C/C++ Language in the Project setting. Don't know where to set boost_program_options, boost_filesystem, and boost_system in the script.
Some of this is incorrect for any platform. Here's what would be correct for linux.
env.Append(CXXFLAGS=['-std=c++17'])
env.Append(LIBS=['boost_program_options', 'boost_filesystem', 'boost_system' ])
Here's what would be correct for windows:
env.Append(CXXFLAGS=['/std:c++17'])
env.Append(LIBS=['boost_program_options', 'boost_filesystem', 'boost_system' ])
You should not specify -lLIBRARY_NAME anywhere for SCons.
Just the LIBRARY_NAME in LIBS.
You'll need to specify LIBPATH to point to the libraries on windows. (Or perhaps env['ENV']['PATH'] as well)

Where to "install" thirdparty libraries & header files to on Windows?

Where do you store your thirdparty libraries and header files to when developing C/C++ on Windows?
When developing on Linux the package managers usally installs thirdparty libraries to /usr/lib and /usr/include. So I know where to look for.
I am just starting to develop on Windows and made the mistake to install libraries to C:\Program Files which is a bad idea due to UAC and permission lookdown on Windows 10.
Is there some kind of best practice? Thanks in advance
Usually to one of these locations:
Commercial tools might have an installer and if so the location is indeed often Program Files [ (x86) ]
Libraries built from source (for example zlib for compression) go wherever you have your root folder for C++ projects. Using Visual Studio you might have a C: > VS17 folder with one sub-folder for each solution and each partner library. You then reference the H and LIB files using relative paths like ../../other-libraryname/include so that they will work if you move the VS17 library to a new drive or change its name.
In both cases, when building a setup package for deploying to another PC, you typically include only DLL files and code statically linked into your own EXE, you don't include H or LIB files. The default installation location for the setup will be Program Files, but if your third-party library includes COM objects they might recommend installing them to the Windows system32 folder.

Creating executable for Qt projects

I have a Qt application that run on Linux. I want to have its executable such that it can operate on Windows too without Qt being installed. I have seen the older posts too regarding this but couldn't understand them. Please guide me step by step to create executable file.
I have placed all the necessary dlls alongside and was successful to run the executable. But to run it I need to go inside the folder and than do that.
How can I wrap my application, such that user has the set up for that, he installs it and then run that (usually we have for the S/ws). How can I do this for the Qt application?
Download the setup for Qt for Windows with MinGW compiler here.
Once you install Qt IDE on a Windows machine, make necessary changes to your project's .pro file and build your application.
Now copy the executable you created into a different folder and run a dependency check on it. You can use Dependency Walker which you can download from here. Copy the dlls shown in the Dependency walker and place it next to your application. You will find the required dlls in the Qt's bin folder in the installation directory. Path might be something like C:\Qt\Qt\\mingw\bin. You will also need to copy the gcc and mingw dlls into your application directory.
Next you will have to copy the required plugins into your application directory. You will need the platforms plugins, iconengines and imageformats if you are using icons, sqldrivers if your application connects to a database. Copy the directories of the required plugins into your application folder.
Once you copy all required libraries, you should be able to open the application. You can now distribute your application along with all these dynamic link libraries and plugins.
For more details you can refer this link.
You should place Qt DLLs along the release version of your executable. These are Qt5Core.dll, Qt5Gui.dll, Qt5Widgets.dll and possibly the ones for other modules that you have used. These dll files are in your installed Qt Directory in bin folder.
You should also place msvcr100.dll and msvcp100.dll in case you are using MSVS2010.
If you are using MinGW, place MINGWM10.DLL, LIBGCC_S_DW2-1.dll and LIBSTDC++-6.dll alongside the executable.
If you are using plugins you should place their dll in a folder named plugins beside your exe. In case of using icons and images you should ship their dlls like qico.dll and qsvg.dll in a folder named imageformats.
You should also put qwindows.dll in a folder named platforms alongside the executable.

Combining existing rootfs with custom toolchain

I've got a Raspberry PI with Emdebian installed on it, and want to cross-compile projects.
There is plenty of documentation on how to obtain a toolchain and build a simple project with it. I myself managed to build a toolchain with crosstool-ng and wrote a hello world program which works fine.
What I don't get is how to handle cross-compiling more complex projects like Qt, which have dependencies on other libraries. Let's use libdbus as an example, as that is one of Qt's dependencies.
The installed Emdebian already contains libdbus.so, so naturally I'd prefer to use that, instead of cross-compiling my own libdbus.so, as compiling all of Qt's dependencies would take a lot of time.
For cross-compiling, there are two important directories, as far as I understand:
The "staging" directory, where all the installed libraries and applications live. This initially is a copy of the toolchain's sysroot directory, and gets populated with more libraries as they are cross-compiled.
The "rootfs" directory, which is equivalent to what is on the device - essentially a copy of the staging directory without unneeded stuff like documentation and header files. As far as I understand it, the best approach is to copy required files from the staging directory into the rootfs.
Getting the rootfs directory is easy, as that can be a NFS mount from the device. But how do I get a staging directory for the existing Emdebian installation on the PI? The staging directory needs to include things like dbus headers, which are not installed on the rootfs.
Some people simply install the dbus headers on the device, with apt-get install libdbus-dev, and then use the rootfs as the staging directory. With this setup, there is no distinction between rootfs and staging anymore, with the disadvantage that the rootfs is polluted with headers, documentation and so on. The advantage of course is that it is easy.
What is the best way to get the dbus headers into my staging directory on my host machine? What is the usual approach people use in this situation?
As a side question, why does the approach of obtaining a toolchain, compiling a program and then copying that on a target work at all? The toolchain ships its own versions of libc, libstdc++ etc, are they not incompatible with the versions that are installed on the target? Especially when creating using a custom toolchain compiled with crosstool-ng?
(Note that I am not asking how to compile Qt, I can figure that out myself. My question is more general, about the approach to take when combining a custom toolchain with an existing installation/rootfs)
In my experience, you don't need to compile your dbus. You can do it as
Create Debian cross rootfs by debootstrap by https://wiki.debian.org/EmDebian/CrossDebootstrap
Create your cros-compile toolchain by crosstool-ng, and make sure the kernel version and eglibc version are the same as rootfs created by 1st step
Build QT by
CPPFLAGS=-I<rootfs>/usr/include \
LDFLAGS=-L<rootfs>/lib -L<rootfs>/usr/lib -Wl,-rpath-link,<rootfs>/lib,<rootfs>/usr/lib \
./configure <your options>
make
Install QT into the stage directory by
make install DESTDIR=<stage directory>
Copy QT dependent libraries from rootfs the your stage directory
So you can see that, the stage directory is kept minimum without pollution.

How do I use cygwin to cross compile to linux, when I have an application that needs libX11.so, libGL.so, and libGLU.so?

Will I have to use the crosstool that cygwin provides to make the libX11.so, libGL.so, and libGLU.so libraries using their respective source code? Or do you know where I can find them compiled already for crosstool (I'm new to this cross compilation)?
Just for clarification: I'm on a windows 7 machine trying to get my application also to compile for linux systems by using cygwin's cross compilation. The application uses OpenGL. Thanks
To cross-compile for Linux you should install the needed development libs and headers on a linux box[1] and then copy /usr/lib and /usr/include your cygwin environment (e.g. /crosscompiler/linux/...). When you build the cross compiler in cygwin, tell it where those native linux headers and libs are so they'll be used when you compile your app.
[1] If you're looking to run on a wide variety of linux boxes make sure you pick an older linux distro (e.g. Red Hat 9) to ensure your app doesn't have dependencies on very new glibc, etc..
Why do you want to use Cygwin?
There is instructions on the OpenGL Wiki about how to use OpenGL on Windows using MinGW.
MinGW use the same GNU tools that are available on Linux (GCC, GDB, GMAKE, etc.) but produce Windows native executables. So, you shouldn't have trouble compiling your source code on both platforms.
I just ended up building on a native Linux machine.

Resources