I am looking for tips on how to package my Qt-based application for Ubuntu/Debian distributions. Let's say the application (executable) is myapp. Running objdump -p myapp | grep NEEDED, I see that it has the following dependencies:
libicuuc.so.44
libicui18n.so.44
libicudata.so.44
libQtGui.so.4
libQtCore.so.4
libpthread.so.0
libstdc++.so.6
libm.so.6
libgcc_s.so.1
libc.so.6
I have gone through several online documents (listed at the end of this question), but am still fuzzy on where to install the actual files.
The Debian Filesystem Hierarchy Standard would suggest (I think) installing myapp in /usr/local/bin but I'm not sure about the ICU and Qt libs. It's important that the exact version of some of these libraries are used. (They have draft APIs which are being utilized that might break in future versions.)
I want to avoid "shared library hell" so that would incline me to place them in the application directory (/usr/local/bin), but the Debian Filesystem Heirarchy Standard would seem to discourage that.
I could place them in /usr/local/lib/myapp but then how do I ensure the correct version is linked dynamically? And if I do this, what do I have to do to add this directory to LD_LIBRARY_PATH on the target system?
As you can tell, I'm quite new to packaging for Ubuntu systems, so the direction I'm going may be completely wrong. I'm interesting in hearing from others who are doing this as to what they have found works best, particularly from a stability and ease-of-maintenance perspective.
Here are some of the docs I have gone through thus far:
Ubuntu Packaging Guide
Create Ubuntu deb-package from a Qt-application
Debian Filesystem Hierarchy Standard
Debian Policy Manual (on system)
Debian Developer's Reference (on system)
Debian New Maintainers' Guide (on system)
You need to look at the control section. You should not be distributing those shared libraries unless you are building them from source in your code. Those libraries belong to other packages that you need to list as Depends or Build-Depends for your package.
You say you are new to packaging on Ubuntu systems, what platforms have you packaged for? If it was only Windows, you are used to dll hell. It is much easier to avoid on Linux since you can say it requires certain libraries to be installed and the package installer knows how to find those libraries.
If you really want to make sure that your application uses the libraries that you ship it with, it probably makes sense to just do static linking of the license allows it. Since you are using a special, specific version of the libraries, you don't really want any other applications to use your libraries instead of the system libs supplied by the package management system. I've built static version of Qt before, and it's somewhat inconvenient, but not enormously moreso than building the usual dynamically linked version of Qt. I haven't worked with ICU, but I imagine it's no worse.
Failing that... Yeah, stuff it all in the application's directory, neatly away from the rest of the system. In my experience, most apps that do that sort of thing don't follow any official distribution standards for doing so, so users don't have very specific expectations in that regard.
Related
I got an app, that is ready to release. On windows, I simply type 'windeployqt.exe MyApp.exe' inside 'release' folder of app build in special qt cmd. I'm trying to do the same on kali linux (I dont have time to install other deb based distro). I'm searching for solution for three hours, and I cant find anything good. So, how to make application executable on other linux computer without Qt Creator installed?
There are many ways to deploy Qt applications on Linux. AppImage created with the help of linuxdeployqt or linuxdeploy-plugin-qt is one option, perhaps even the simplest one but it has its drawbacks. From my personal experience I can think of two:
Your app won't generally be able to use native icon/font/other themes.
Sometimes your AppImages might occasionally cease to work due to some unexpected system update which would, for example, break the binary compatibility of OpenSSL libraries.
Other packaging options for Linux include:
Linking the application with static version of Qt. It is the
approach used e.g. by Telegram. The instructions can be found
here.
Beware, however, that using this approach for commercial closed
source applications generally requires commercial Qt license.
Probably it is possible to get away with LGPL but it would be very
cumbersome: you'd have to provide customers with compiled object
files so that they can replace them and re-link the app. Also beware
of the fact that if the application you intend to create is going to
be an open source one, the maintainers of Linux distributions would
generally not agree to distribute statically linked applications -
that violates the basic rules for many distros according to which
applications should not bundle their dependencies but instead should
use the system provided libraries. It is important from e.g.
security perspective - if some security threat is found in Qt in
future, it can be fixed within a Qt library itself and all
applications using that library would then also be secure -
something not that easily achievable with application built with
static version of Qt.
Creating native packages for target systems - i.e. deb packages for
Debian/Ubuntu systems and their derivatives, rpms for Fedora,
OpenSUSE and other rpm-based distros,
PKGBUILD for Arch
Linux and various other kinds of packages for various other distros,
hundreds of them. The advantage is good integration with the rest of the system: native themes etc. Also you get all the advantages of the security fixes for shared libraries.
Using flatpak or snap packages - these are modern app packaging formats developed by RedHat and Canonical respectively with the goal to simplify the management of app's dependencies.
Using the generic approach using shared libraries - with this approach you'd need to package your app as an archive containing a directory containing you app and all its dependencies in the form of shared libraries - something similar to the approach of deployment on Windows where you put the dlls alongside the app.
I would recommend trying an AppImage first and then creating native packages for target distros.
I am looking for a way to create a minimal static build of Qt 5.1. By minimal, I mean a build with only the basic set of widget classes available (including 2D graphics acceleration through an OpenGL canvas/widget). I am aiming for a static build on Windows 7 32-bit using MinGW-builds GCC 4.8.1 as well as their bundle of MSYS and tools.
I have downloaded the entire source tree, and have met some problems with compiling due to the dependency of packages such as OpenSSL and ICU (the latest OpenSSL did not compile). I wanted to see, if I could avoid dependencies of these packages and, at the same time, achieve a minimal static build of Qt 5.1 so my final executable is not gigantic in size.
I took a look at this list:
http://download.qt-project.org/official_releases/qt/5.1/5.1.0/submodules/.
Q1: Which of these modules, do I need to select to have a basic Qt build without all the fancy stuff?
Q2: Are these modules interdependent on each other in some way (I assume they are all dependent on "qtbase")?
Q3: Do I use the names from that list, (for example: "qtxmlpatterns", "qtx11extras", "qtwebkit", etc.), to deselect them in the configuration of my Qt build?
It would also be nice, with an explanation of the various submodules of Qt 5? If someone could point to any links or docs with illuminating words on this subject, that would also be great.
I shared this same goal. I wanted to "minify" Qt, building only a small subset of the libraries/DLL(s) and omitting the rest.
I did succeed, at least on Mac OS X. I assume that this approach will work on other platforms, too.
I thought that the trick would be to find some kind of exclusion flags for the "configure" script, but that turned out not to be the case.
Here is what I did:
Download the source distribution (in my case, qt-everywhere-opensource-src-5.1.1). of course, extract it all.
Edit the following three "pro" files. these files are in a qt-specific format (but plain text). They are platform-independent project files that Qt (via qmake) uses to generate makefiles.
qtbase/src/src.pro
qtbase/src/plugins/plugins.pro
qtbase/examples/examples.pro
All the changes that I made to the "pro" files were deletions. I deleted references to: dbus, ipc, network, qtconcurrent, sql, xml, sqldrivers, qdbusxml2cpp, qdbuscpp2xml, src_dbus, src_concurrent, src_sql, src_network.
That last part may sound scary. It really wasn't.
The pro files contain a list of module names, plugin names, and directory names. It seemed fairly straightforward how to delete (for example) all SQL-related lines.
Step 3.
The usual configure/make/install. However, note the "module-qtbase" argument passed to make:
./configure -prefix ~/my_test_dir/
make -j2 module-qtbase
make -j2 module-qtbase-install_subtargets
Success. This built and installed only the essentials (QtCore, QtGui, QtOpenGL, QtWidgets) and skipped all the supporting dylibs like QtConcurrent, QtMultimedia, QtSql, and QtWebKit.
ICU can link statically, and you can customize it (see docs) to reduce size. By default the data is also large, I don't know how much data you need. You could include only enough data to run in one language.
Only part of an answer.
There's no need to disable Qt modules. Each application that uses Qt decides what modules it uses and links with. A basic console-only application may use the core module only. That's what you'd use when creating, say, a web service in Qt.
I downloaded the qt embedded demo source code recently on my linux machine. Following are the outcomes during running of the program
I compiled it statically on my x86 machine and run the application on x86 machine it runs fine. But when i took the statically compiled binary file to other machine with Atom platform It run with some missing widgets. I found that the plugins cant be ported with static compilation. Can anybody tell me is it true? If no can anybody tell me the steps for it?
I compiled it dynamically with shared libraries. Then got an executalbe on linux. I did "ldd MyAppName". It show me the shared library files it is using. But I dont know how to package these. Can anybody tell me the steps to package it?
I checked in the article on deploying qt applications on X11-linux platforms. But its not complete. Can anybody give me the detailed steps?
Any help will be appreciated......
you either have a distro, that does'nt support atom, or libraries, that are not compiled with support for it. either way - something somewhere on your system (or your qt) is not compiled for atom
The problem is that you are compiling your app, and its libraries (static or dynamic) work for x86, not for Atom. Perhaps you are able to create some sort of fat binary (lipo?) so that pieces of your app will function on x86 and Atom, but bits using the x86-only libraries will not function on Atom. (Right? That's a concise definition of your problem?)
If you have the source code for the libraries that don't run on Atom, and they're important to you, you should consider porting the code to Atom. If it's open-source code, you can contribute to the project. While you didn't give many details, my (very generic) approach to this would be to get the code on an Atom machine, write a very short test application for the library, and work out the issues.
Re #2: There's little difference between compiling an app and linking to shared libraries or dynamic libraries. On your x86 machine, if you have this code (these "plugins") compiled as dynamic libraries, it's pretty much the same as statically linking those binaries into the app. These libraries will work on x86, whether they're dynamically or statically linked.
I'm not sure if that helps very much -- if you're getting binary Qt plugins as static or dynamic libraries without source, you're out of luck. Submit a bug report. If you have source code, you can do a lot more.
I just dynamically compiled my application and ported to atom platform. I found the dependencies and ported them also and set the environment variable LD_LIBRARY_PATH on target machine to my ported shared libraries and It worked. Thanks everybody for your suggestions
I want to created a JAR file and I want to run it on a client machine.So, I have a couple of questions:
How can I convert the JAR file to an EXE file?
How can I encrypt the JAR file's contents? The jar file could be extracted with WinRAR and the classes could be decompiled with any Java decompiler.
How can I create an installer? My clients doesn't have any JVM and I don't want to ship JDK or JRE along, because they have big size.
See this link: Java to Exe. It also explains what valid reasons are to do this, and when you should not.
You can't really encrypt binaries as the machine has to understand them. That said, an optimized executable is very difficult to decompile, while plain class files are ease.
If you have an exe there are installers enough.
JSmooth is a application which will wrap your Jar in an exe
it also allows you to check if the correct version of JRE is available on the system you're deploying to
http://jsmooth.sourceforge.net/
As for 1): I guess you can not. There may be tools out there, but you cannot do that with standard tools shipped with JDK, as it would destroy platform independance. (See other answers providing links to such 3rd party tools)
As for 3): Use InnoSetup to create the installer. Include JRE within setup and let InnoSetup install it on the fly.
You can't prevent decompilation. The best you can do is make it harder or more time-consuming to do so. As an answer to your question though, I believe you can use gcj to compile Java into EXEs.
May be Excelsior JET will satisfy your needs.) IMHO very mature product.
1) I have recently tried the program jarToExe and like it.
Some features are:
free basic version or very cheap ($30) for 'enterprise'
ability to have windows task manager list your app's name instead of the default java.exe
extra obfuscation
runtime check that java is installed
2) You can make it harder to reverse engineer using proguard or other obfuscator
3) nsis is a very powerful, free scripting language to create windows installers. Good documentation on the site wiki and support on stack overflow as well.
Launch4j worked for me while some tools hadn't been working. It also have a good guide here.
Hope this help!
We use a 7zip SFX install launcher. This is an open source simple tool. It will package your jar, a version of jre so it's not mandatory for the installing systems to have jre installed and a self extracting version of 7zip. Here is a tutorial which explains how to bundle and GitHub link
The project is not maintained but works perfectly(tested until Java 1.8)
1) To create the exe, you can use Launch4j
2) As I have seen, you cannot encrypt the jar contents. I'm not sure though.
3) To create the installer you can use the exe you just created and use InnoSetup to create the files. You have to embed the jre inside the installer and also any other libraries and extra files that may need in the runtime. When embedding the jre, the setup gets large and if you want to avoid that, you can ask the clients to install java in the machines. That way, you wont need to ship with the jre.
I come from UNIX world, I'm quite familiar with Linux, Solaris, Cygwin
and MinGW development. Recently I ported one of my
big projects (cppcms) to support MSVC,
including building static and dynamic libraries with CMake.
And I get all the time absolutely weird issues:
I had CMake build issues because Windows programming
lacks naming convention
for import and static libraries.
Now I discovered that I should use different versions of ICU (debug/release builds) according to the
actual build I do (Debug/RelWithDebInfo -- should use Debug ICU, Release release ICU) and so I should
change actual conventions for searching libraries according to debug/release mode only under MSVC.
Otherwise application just would not start giving a error on missing DLL.
I don't have any such issues under Mingw or Cygwin with GCC, Open Solaris with Sun Studio or Linux with gcc or intel compilers.
And I still have numerous wired issues and wired bugs and very strange behavior -- even some trivial things do not work
under MSVC builds, when everything works absolutely fine under Solaris/Linux/Cygwin/Mingw using GCC from 3.4 up to 4.4,
Sun Studio and Intel compilers). But not under MSVC.
To be honest, I have no idea how to deal with Last one! Because it looks like for me more like environment issues.
I know that the question is not really well defined. I think I'm quite experienced
developer and I know how to write portable and good C++ code. But using Microsoft native
tools drives me crazy with issues I just don't know how to solve.
Question: What should experienced Unix programmer with quite good base in Win32 API should know when it
starts using Genuine Microsoft Tools?
P.S.: Can someone explain why "Release With Debug Info" requires Debug version of MSVC runtime? And why there two versions of runtime exist at all?
P.P.S.: Please note I don't have issues with Win32 API, in fact Windows GCC build works absolutely fine.
Clarifications:
I'm looking for pitfalls that programmer that come from Unix world would may fall into.
For example, when moving from Linux to Solaris: make sure you compile code with -mt or
-pthreads when using multi threaded programs, linking with -lpthread is not enough.
P.S.: Can someone explain why "Release
With Debug Info" requires Debug
version of MSVC runtime?
It doesn't.
And why there
two versions of runtime exist at all?
Because the debug version does more error checking.
And I still have numerous wired issues
and wired bugs and very strange
behavior -- even some trivial things
do not work under MSVC builds,
* What am I doing wrong?
Not telling us what "wired issues and wired bugs and very strange behavior" you get.
* Where should I start?
By telling us the specific errors and problems you encounter.
* What do I miss?
Reading the documentation and learning the tools.
If your question is "What do I read to become a good Windows programmer?" then my answer is: Everything from Jeff Richter, as a start.
There is no magic bullet which will automatically make you an experienced Windows developer. Windows is a very different land compared to Unix. There are lots of quirks, weird behavior, and stuff which is just plain different. The only way to get out with your sanity intact is to tackle the transition one small problem at a time. Concentrate on a specific problem and try to understand the problem. Don't just "get it to work", but really understand what is happening. A good book about Windows programming will help.
There are huge amounts of Windows knowledge and experience accumulated in the SO community, but the only way to access it is to ask concrete questions about specific problems.
The release and debug versions of DLL's use different ways of allocating memory, that is why it is not advisable to mix release and debug versions. If you allocate something in a debug mode DLL and pass it back to the application which was compiled in release mode you may get into trouble.
In the case of your naming issues you may want to have different directories where you place your static / dll's. You can do do this in visual studio by using the configuration manager, not sure how it is under the express version.
I think you need to try and actually understand the new toolset rather than just try and squish it into your current understanding of your existing tools. For that, the best way, IMHO, is for you to try and start to use Visual Studio as Microsoft intended and then once you can build a simple project in the IDE you can move to building it using your preferred make system but do so with an understanding of how the IDE is using its make system to set things up for that build (which WILL work).
So, for example, for part 1 of your question you want to create a simple static library project and a simple dll project and look at the linker options tabs. Jump to the 'Command line' view and you'll see that a DLL uses the /OUT linker option to set the name and location of the dll file and the /LIB linker option to set the name and location of the import library. With a static library only the /OUT option is used and it indicates the name of the static lib. It's true that if you're building a static lib and a DLL from the same source and you have both the /LIB for the dll set to MyCrossPlatformCode.lib and /OUT set to MyCrossPlatformCode.dll then you may have problems if you also build a static lib with an /OUT switch of MyCrossPlatformCode.lib... Simply don't do that; either build the static libs to a different output directory (which is what OpenSSL does), or, better (IMHO), mangle the names somewhat so that you have MyCrossPlatformCode.lib/.dll and MyCrossPlatformCode_static.lib (which is what STLPort does).
Note that you might also want to mangle in (or account for) building with different versions of the Microsoft tool chain (so you might end up with stlport_vc8_x64d_static.5.1, perhaps).
An alternative approach, if you really can't face the thought of understanding your toolset, is that you could take a look at some of the popular open source systems that build quite fine on Windows and Unix systems; OpenSSL and STLPort for a start, perhaps.