Deploy a Qt project on linux - linux

This may be a noob question, but I have been stuck trying to work out how to statically build my qt project on linux. I tried doing what it said on http://doc.qt.io/qt-5/linux-deployment.html , but I do not understand the 1st step. When I cd to the location of my qt project and run
cd /path/to/Qt
./configure -static -prefix /path/to/Qt <otherparameters>
make
it says no such file or directory. Am I misunderstanding what paths I need to use? I want to make my qt project a stand alone executable which doesnt require the computer it is on to have qt. I have read about dynamically linking the libraries, but I dont really know what to do with that either. The deploy option is greyed out in qtcreator, is there a way to use this?
Thanks

/path/to/Qt should be the path to Qt's sources, not your project's. That section of the documentation is about building Qt statically, which you must do before trying to statically link your application to Qt. For example, if you downloaded/cloned the sources to /home/jxb458/qt5, then you'd replace /path/to/Qt with that:
cd /home/jxb458/qt5
./configure -static -prefix /home/jxb458/qt5/qtbase
make

Static linking is great when it works, but it can be an effort - I have found especially when using GUI. As Mitch said you need to actually re-build the Qt source code
I made some notes back when I was building statically quite a bit here: Notes on static building (derived from many sources) they should at least point you in the right direction - you can probably ignore the part about installing Ubuntu - the notes assume a new install.
However I have more recently returned to the dynamic linking deployment since I feel this is a better way to deploy now. You don't need to install Qt on the target machine you just need to collect the qt dlls and copy them with your application (using ldd executable-name which produces a list of dlls you need - but just take the Qt ones not the system/generic ones). For plugins you need to do a bit more (but its fairly simple). I even wrote a bash script to do this automatically (i'll send it to you if you need it), in windows there is a qt script called windeployqt (not sure why there is not a linux variant).
If I where to start again looking into deployment I would go for dynamic linking. Maybe try with a simple project to start with (like a hello world proj).

Related

Using Eclipse (with Debian) to modify applications from the official repository

For a university project, I am trying to find a not so cumbersome way to effectively modify certain applications from the official Debian repository, such as eog. I want to clarify that I am unfamiliar with Linux and GTK. My idea was to be able to work comfortably in terms of finding variable and function definitions, trying step by step debugging while getting used to gtk+ and the application's source code. I tried to understand the code while working from the terminal, but in my opinion, it was a pain i* t** a**.
So far, I managed to install the application's build dependencies with
sudo apt build-dep eog
and I received the source-code with
apt-get source eog
After I installed eclipse, I tried to get gtk+ running with the minimum example from the gtk+ reference manual. I found a very useful easy explanation here. It's the answer from Wed, 04 November 2015 12:51.No problem so far. So in theory, I should be able to write GTK+ applications in Eclipse. But when I am trying to make a new project and include eog's .src and .h files, I am running into a mass of unresolved inclusions, missing header files, undefined references etc...
So I wanted to ask: Did anybody work on similar tasks and can provide some help? Or: Does anyone have a better idea maybe?
If anybody should come across this ever again: I found an alternative solution: When you download the source-files of eog, you will come across the meson-build system. Eclipse supports C meson-build projects. I just copied all downloaded source files into the meson-build project in eclipse in could compile it right away.

Build a linux static library

For a website of mine I'm trying to make wkhtmltopdf(Link) work. The website is hosted on a shared hosting, which are a bit troublesome when using libraries not installed.
After a few tries with multiple version of the library(some where supposed to be static but I still got error about shared library not being found) I ended up contacting the provider, who told me that it would work if I have a static version of the library.
Problem is, my linux knowledge is very limited.
If I understand correctly, a static library would be a version of wkhtmltopdf, one single file, including all dependencies ?
As the official site mention are the followings : zlib, fontconfig, freetype, X11 libs (libX11, libXext, libXrender)
Second question is, could you point me to where I could find a step by step guide to build such library ? as my research are unsuccessful so far..
my linux knowledge is very limited
I will assume you are more or less familiar with windows dlls, which are similar to linux .sos (shared objects).
A shared object can be shared (hence the name) between different programs. In most cases, when the executable is loaded, the library is loaded in memory too. You can see such dependencies with ldd.
A static library (or statically linked library, or static executable, or whatever) is a library that is embedded in the executable at compile time. To statically link your library, you need to rebuild your executable, and link with a .a static library file, which is similar to .lib files on windows (with the visual studio compiler, at least, IIRC).
This can be troublesome and time consuming. That's why I advise you to take another route:
On windows, .dll files that share the same folder as the executable are given a higher preference than the one on the path (IIRC). On Linux (and generally UNIX), this is regarded as a security flaw, as someone could easily drop a rogue .so file and alter the program's behavior. You can however control this behavior with two environment variables: LD_LIBRARY_PATH and LD_PRELOAD. The second one is a bit more powerful, and is just some kind of "dll" injection. The first one, however, controls the path in which .so files will be searched.
So, I advise you to look for the required dependencies with ldd, and do it once again on your server if you can. Look for every missing .so file. You could do so by issuing the command ldd wkhtmltopdf | grep not found.
Once you have this list of missing libraries, bundle them together and send them on your server (be aware that they can have some dependencies too). You can probably find them on a local Linux installation of matching architecture, but I encourage you to try to match the distribution with the one of your provider.
Then, issue the wkhtmltopdf call after setting the LD_LIBRARY_PATH environment variable. You can do it like so:
LD_LIBRARY_PATH='/home/me/my_libs':$LD_LIBRARY_PATH /home/me/programs/wkhtmltopdf
Note that I append the old LD_LIBRARY_PATH variable at the end. It is rarely set out of the box, but at least you shouldn't have any problem if you do it this way.
To answer your comment: it is indeed a bit like modifying the PATH on windows (just to make this clear once again: on Linux, you have the same PATH environment variable, but it only works for executables' search path; so we're changing another LD_LIBRARY_PATH environment variable to specify the libraries search path).
Please note that in the above example, I didn't change it system-wide, but only for calling wkhtmltopdf. On windows, there are multiple ways to change the PATH environment variable. You can open the dedicated gui, which will change the path variable in the registry. But you can also override it locally in a command prompt or batch script. This is exactly what I did here.
Once LD_LIBRARY_PATH is exported, it will be used for every program you call, so it might be dangerous to set it system wide, if you have some incompatibilities. Moreover, whatever you try, you won't be able to set it system-wide if you don't have root access. So, you will at most affect only your programs.
As a final note, you might pull a lot of dependencies with this project, since it is Qt-based. If you want to rebuild it statically, you have to build Qt first with -static. Next time, you might be interested in some containerization technology, such as docker (or even appimages/flatpack/snap), which is designed to work around this kind of problems.
For further reading on dynamic link libraries on Linux, you might be interested in this resource or similar.

When using someone else's application code do I need to run Cmake to get the project structure for my operating system.

I am getting into a position where I have to use other people code for projects, for example openTLD. I want to change some of the code to give it more functionality and use it in a diffrent way. What I have found is that many people have packaged their files in such a way that you are supposed to use
cmake
and then
make
and sometimes after that
make install
I don't want to install the software on my system. What I am looking to do is get these peoples code to a point where I can add to it in Eclipse or even just using Nano and then compile it.
At what point is the code in a workable/usable state. Can I use it after doing cmake or do I need to also call make? Is my thinking correct that it would be better to edit the code after calling cmake as opposed to before? I am not going to want my finished code to be cross platform supported, it will only be on Linux. Is it easer to learn cmake and edit the code befor running cmake as opposed to not learning cmake and using the code afterwards, if that is possible?
You question is a little open ended.
Looking at the opentld project, there is a binary and a library available for use. If you are interested in using the binary in your code, you need to download the executables(Linux executables are not posted). If you are planning to use the library, you have two options. Either you use the pre-built library or build it during your build process. You would include the header files in your custom application and link with the library.
If you add more details, probably others can pitch in with new answers or refine the older ones.

How can I know if my executable will also to run on other computers (linux)?

I have an executable I want to be able to distribute and run in other Linux systems. Is there a way to be reasonably sure if this will work, without access to the final runtime environment?
For example, I am concerned my executable could be using a dynamic library that is only present on my development machine.
Supply any relevant shared libraries with the executable, and set $LD_LIBRARY_PATH in a shell script that invokes the executable to tell the linker where to find the shared libraries. See the ld.so(8) man page for more details, and be sure to follow the appropriate licenses.
Take a look at the Debian (.deb) and Redhat (.rpm) packaging stuff. This is the installer for your package. They aren't all that difficult, and you can tell it to reference other packages that have the required shared objects.
The packaging tools can usually repair packages that are missing libraries and so on. It will also help you place your binaries in such a way that you don't need to set LD_LIBRARY_PATH or put a shell-script front end on your executable.
They aren't that difficult to learn either. Spend a day playing with each and you'll get a passable installer package.
Is there a way to be reasonably sure if this will work, without access to the final runtime environment?
One's environment could be a different architecture than yours, even while it stays Linux. Therefore, the only sure way to get your program to the widemost audience is to ship source code.
Couldn't you just statically linking everything into a supper massive black hole^W^W binary do the trick?

How to make binary distribution of Qt application for Linux

I am developing cross-platform Qt application.
It is freeware though not open-source. Therefore I want to distribute it as a compiled binary.
On windows there is no problem, I pack my compiled exe along with MinGW's and Qt's DLLs and everything goes great.
But on Linux there is a problem because the user may have shared libraries in his/her system very different from mine.
Qt deployment guide suggests two methods: static linking and using shared libraries.
The first produces huge executable and also require static versions of many libraries which Qt depends on, i.e. I'll have to rebuild all of them from scratches. The second method is based on reconfiguring dynamic linker right before the application startup and seems a bit tricky to me.
Can anyone share his/her experience in distributing Qt applications under Linux? What method should I use? What problems may I confront with? Are there any other methods to get this job done?
Shared libraries is the way to go, but you can avoid using LD_LIBRARY_PATH (which involves running the application using a launcher shell script, etc) building your binary with the -rpath compiler flag, pointing to there you store your libraries.
For example, I store my libraries either next to my binary or in a directory called "mylib" next to my binary. To use this on my QMake file, I add this line in the .pro file:
QMAKE_LFLAGS += -Wl,-rpath,\\$\$ORIGIN/lib/:\\$\$ORIGIN/../mylib/
And I can run my binaries with my local libraries overriding any system library, and with no need for a launcher script.
You can also distribute Qt shared libraries on Linux. Then, get your software to load those instead of the system default ones. Shared libraries can be over-ridden using the LD_LIBRARY_PATH environment variable. This is probably the simplest solution for you. You can always change this in a wrapper script for your executable.
Alternatively, just specify the minimum library version that your users need to have installed on the system.
When we distribute Qt apps on Linux (or really any apps that use shared libraries) we ship a directory tree which contains the actual executable and associated wrapper script at the top with sub-directories containing the shared libraries and any other necessary resources that you don't want to link in.
The advantage of doing this is that you can have the wrapper script setup everything you need for running the application without having to worry about having the user set environment variables, install to a specific location, etc. If done correctly, this also allows you to not have to worry about from where you are calling the application because it can always find the resources.
We actually take this tree structure even further by placing all the executable and shared libraries in platform/architecture sub-directories so that the wrapper script can determine the local architecture and call the appropriate executable for that platform and set the environment variables to find the appropriate shared libraries. We found this setup to be particularly helpful when distributing for multiple different linux versions that share a common file system.
All this being said, we do still prefer to build statically when possible, Qt apps are no exception. You can definitely build with Qt statically and you shouldn't have to go build a lot of additional dependencies as krbyrd noted in his response.
sybreon's answer is exactly what I have done. You can either always add your libraries to LD_LIBRARY_PATH or you can do something a bit more fancy:
Setup your shipped Qt libraries one per directory. Write a shell script, have it run ldd on the executable and grep for 'not found', for each of those libraries, add the appropriate directory to a list (let's call it $LDD). After you have them all, run the binary with LD_LIBRARY_PATH set to it's previous value plus $LDD.
Finally a comment about "I'll have to rebuild all of them from scratches". No, you won't have to. If you have the dev packages for those libraries, you should have .a files, you can statically link against these.
Not an answer as such (sybreon covered that), but please note that you are not allowed to distribute your binary if it is statically linked against Qt, unless you have bought a commercial license, otherwise your entire binary falls under the GPL (or you're in violation of Qt's license.)
If you have a commercial license, never mind.
If you don't have a commercial license, you have two options:
Link dynamically against Qt v4.5.0 or newer (the LGPL versions - you may not use the previous versions except in open source apps), or
Open your source code.
The probably easiest way to create a Qt application package on Linux is probably linuxdeployqt. It collects all required files and lets you build an AppImage which runs on most Linux distributions.
Make sure you build the application on the oldest still-supported Ubuntu LTS release so your AppImage can be listed on AppImageHub.
You can look into QtCreator folder and use it as an example. It has qt.conf and qtcreator.sh files in QtCreator/bin.
lib/qtcreator is the folder with all needed Qt *.so libraries. Relative path is set inside qtcreator.sh, which should be renamed to you-app-name.sh
imports,plugins,qml are inside bin directory. Path to them is set in qt.conf file. This is needed for QML applications deployment.
This article has information on the topic. I will try it myself:
http://labs.trolltech.com/blogs/2009/06/02/deploying-a-browser-on-gnulinux/
In a few words:
Configure Qt with -platform linux-lsb-g++
Linking should be done
with –lsb-use-default-linker
Package everything and deploy (will
need a few tweaks here but I haven't yet tried it sorry)

Resources