How do I create an 'install' package for a Qt application? - linux

Generally to install a package on a linux-based operating system you use
./configure
make
make install
How does this work? And how do I create a package that can be installed this way?
My application uses the Qt framework and I think I'm aiming for something like "MyPackage.tar.gz"

You can create a debian package from your projects. As I understood you want to create a package intended for distibution so I would suggest creating a debian package from your project. Here is an introduction for Debian Packaging system. In the article they at some point describe how to create a "rules" file which is at the core of the build process. Here is a sample of it that I typically use for my Qt/KDE projects:
#!/usr/bin/make -f
#export DH_VERBOSE=1
# This is the debhelper compatability version to use.
#export DH_COMPAT=3
DESTDIR=$(CURDIR)/debian/project
TR_DIR=$(CURDIR)/debian/project/usr/share/qt4/translations
configure:
qmake project.pro
clean:
dh_testdir
dh_testroot
dh_clean
build: configure
dh_testdir
lrelease translations/project_en.ts
$(MAKE)
install: build
mkdir -p $(TR_DIR)
cp translations/project_en.qm $(TR_DIR)
$(MAKE) INSTALL_ROOT=$(CURDIR)/debian/project install
dh_installdirs
binary-arch: build install
dh_testdir
dh_testroot
dh_installmenu
dh_link
dh_strip
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
This is normally sufficent for small projects.

configure is usually part of GNU build system (autotools), which is not in use in a typical Qt project. qmake is used instead for build file generation and it internally handles most of the tasks configure does for non-qt projects.
The typical build install process for a Qt application is
qmake
make
make install
You could create a simple ./configure script that calls qmake if you need the command names to be identical. You can also use autotools with Qt if you need it, see e.g. Qt Creator Instructions For Autotools

Qt is often used with CMake, which I highly recommend. One notable point is that it likes out-of-source-builds.
Your configure script could be
#!/bin/bash
(mkdir build; cd build; ccmake ..)
and the makefile could be
#!/bin/bash
(cd build; make)

Newer versions of debhelper support qmake. A rules file like,
#!/usr/bin/make -f
%:
dh $# --buildsystem=qmake
Is all that is needed. You need,
bar.file = foo
bar.path = install/dir
INSTALLS += bar
Inside your projects 'pro' or qmake file. qmake will create install targets and the perl file /usr/share/perl5/Debian/Debhelper/Buildsystem/qmake.pm will get called and parse the qmake file. You need to create 'debian/' files, changelog, compat, control, copyright as well the rules file.

Related

Automake-1.14 is failing at make

I downloaded automake-1.14 by following this tutorial on Ubuntu 16.04
./configure passed without any error. But the moment I ran make it gave an error.
I actually removed automake-1.15 from linux because when I was
installing protobuf 2.6.1 it says that i can't find automake-1.14. Therefore I remove automake by apt-get autoremove automake. And ran the following commands
$ wget http://ftp.gnu.org/gnu/automake/automake-1.14.tar.gz
$ tar xvzf automake-1.14.tar.gz
$ cd automake-1.14
$ ./configure
$ make # FAIL HERE
$ sudo make install
The Error is the following:
anybody#anywhere:~/anyshare/automake-1.14$ make
GEN t/testsuite-part.am
GEN m4/amversion.m4
CDPATH="${ZSH_VERSION+.}:" && cd . && "/home/anybody/anyshare/automake-1.14/t/wrap/aclocal-1.14"
Can't locate /home/anybody/anyshare/automake-1.14/bin/aclocal in #INC (#INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.22.1 /usr/local/share/perl/5.22.1 /usr/lib/x86_64-linux-gnu/perl5/5.22 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.22 /usr/share/perl/5.22 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base .) at /home/anybody/anyshare/automake-1.14/t/wrap/aclocal-1.14 line 29.
Makefile:2494: recipe for target 'aclocal.m4' failed
make: *** [aclocal.m4] Error 2
Apparently, the original problem -- and likely the problem building Automake -- was an incorrect appearance that the packages' Autotools-based build systems were out of date.
Generally speaking, Autotools-based packages should be distributed with the Autotools outputs pre-built, even though technically, they are derived files. This avoids any need for the Autotools themselves to be installed on the build system for people who are just building the package on a supported system, not modifying or porting it. Distribution packages built by an Autotools-based build system via make dist will in fact include them.
By default and typically, Autotools-based build systems include rules for rebuilding the build system itself if it is out of date. This is a convenience for package maintainers. Autoconf has a built-in mechanism to provide an option for disabling those rules (so-called "maintainer mode") at configuration time, though not all packages make use of it.
Normal operation of tar preserves file timestamps, but if your particular tar fails to do so, whether in general or in your particular case, or if your filesystem's timestamps have poor resolution, then unpacking the source tarballs may produce a result in which the Autotools outputs appear to be out of date. In that case, unless suppressed, the rules for rebuilding the build system will be triggered when you run make.
If this happens to you, and the package's configure script supports the maintainer-mode option, then you can suppress the build-system rebuilding rules by including the --disable-maintainer-mode option when you configure the package. Hindsight being 20/20, I can confidently state that this solves the Protobuf-building problem for you.

./configure: No such file or directory cygwin Freeglut

I'm trying to generate the lib files for freeglut library. I've installed cygwin and according to README file that comes with the library,
Building and Installing the Libraries with Cygwin
=================================================
To build "freeglut" under Cygwin, you have two choices:
- You can build a normal Cygwin library, which depends on Cygwin's X11
libraries. To do this, you can just use the normal autotools incantation:
./configure && make install
- Alternatively, you can build a DLL which does not depend on X11 and links
against the opengl32 DLL. To do this, configure need a few more flags:
./configure CPPFLAGS=-mno-cygwin LDFLAGS=-mno-cygwin --without-x && make install
If you don't have MSVC, Open Watcom or Cygwin
=============================================
But If I run ./configure, I got this error
$ ./configure CPPFLAGS=-mno-cygwin LDFLAGS=-mno-cygwin --without-x && make install
-bash: ./configure: No such file or directory
Is there something I need to install in order to solve this issue? The contents of the folder doesn't have configure. These are the files in the folder
If you need freeglut, you need to install the cygwin package libglut-devel
Looking inside setup.ini you will find its description:
libglut-devel
sdesc: "OpenGL Utility Toolkit library"
ldesc: "freeglut
is a completely OpenSourced alternative to the OpenGL Utility Toolkit
(GLUT) library. GLUT was originally written by Mark Kilgard to support
the sample programs in the second edition OpenGL 'RedBook'. Since
then, GLUT has been used in a wide variety of practical applications
because it is simple, widely available and highly portable. GLUT (and
hence freeglut) allows the user to create and manage windows
containing OpenGL contexts on a wide range of platforms and also read
the mouse, keyboard and joystick functions."
category: X11

How do I Distribute my Haxe application with Hashlink?

I've got a Haxe Application that I want to make available to people with a Windows system. I use Hashlink to run the Application locally and it works very nicely.
I am wondering if I'm supposed to distribute my Application with Hashlink. Can it build me an .exe?
It looks like generating distributable binary files isn't supported out of the box today (March 10, 2017):
> haxe -main Main -hl main.c
Code generated in main.c automatic native compilation not yet implemented
Hopefully it will be supported soon!
Note: I'm talking about building a final executable using hashlink. An entirely separate approach I do not cover here is the possibility of delivering the hashlink virtual machine with your output hl bitcode.
Sane people stop reading here.
But in the meantime... it is possible to generate binaries with hashlink today if you build hashlink from source.
Warnings:
This isn't a generic, cross-platform answer to your question -- it's just my experience on Linux.
There will probably soon be a better way than this.
But I wanted to jot these notes down even for myself to recall later.
Here's what I had to do on Ubuntu 14.04, 64-bit:
Install prerequisite libraries for building hl (there may be others I already have installed, like build-essential, etc)
sudo apt-get install libvorbis-dev libturbojpeg libsdl2-dev libopenal-dev libssl-dev
Clone and build the mbedtls library: (rev note: b5ba28)
cd ~/dev/
git clone https://github.com/ARMmbed/mbedtls.git
cd mbedtls
make CFLAGS='-fPIC'
Clone the hashlink repo: (rev note: eaa92b)
cd ~/dev/
git clone https://github.com/HaxeFoundation/hashlink.git
cd hashlink
In the # Linux section of the Makefile, ~line 67, add these flags:
CFLAGS += -I ../mbedtls/include
LIBFLAGS += -L../mbedtls/library
Now build with make
If everything works, you'll see two important output files, hl and libhl.so
Ok, at this point, it's easiest if you just build your project in the hashlink directory. For example:
# Still in the hashlink directory
haxe -cp /path/to/my/project -debug -main Main.hx -hl src/_main.c
Now run make hlc, and if everything works, hlc is the output executable (which depends on libhl.so):
cp libhl.so hlc /tmp/
cd /tmp/
./hlc
Prints:
Main.hx:7: Hello world!

How do I configure Qt for cross-compilation from Linux to Windows target?

I want to cross compile the Qt libraries (and eventually my application) for a Windows x86_64 target using a Linux x86_64 host machine. I feel like I am close, but I may have a fundamental misunderstanding of some parts of this process.
I began by installing all the mingw packages on my Fedora machine and then modifying the win32-g++ qmake.conf file to fit my environment. However, I seem to be getting stuck with some seemingly obvious configure options for Qt: -platform and -xplatform. Qt documentation says that -platform should be the host machine architecture (where you are compiling) and -xplatform should be the target platform for which you wish to deploy. In my case, I set -platform linux-g++-64 and -xplatform linux-win32-g++ where linux-win32-g++ is my modified win32-g++ configuration.
My problem is that, after executing configure with these options, I see that it invokes my system's compiler instead of the cross compiler (x86_64-w64-mingw32-gcc). If I omit the -xplatform option and set -platform to my target spec (linux-win32-g++), it invokes the cross compiler but then errors when it finds some Unix related functions aren't defined.
Here is some output from my latest attempt: http://pastebin.com/QCpKSNev.
Questions:
When cross-compiling something like Qt for Windows from a Linux host, should the native compiler ever be invoked? That is, during a cross compilation process, shouldn't we use only the cross compiler? I don't see why Qt's configure script tries to invoke my system's native compiler when I specify the -xplatform option.
If I'm using a mingw cross-compiler, when will I have to deal with a specs file? Spec files for GCC are still sort of a mystery to me, so I am wondering if some background here will help me.
In general, beyond specifying a cross compiler in my qmake.conf, what else might I need to consider?
Just use M cross environment (MXE). It takes the pain out of the whole process:
Get it:
$ git clone https://github.com/mxe/mxe.git
Install build dependencies
Build Qt for Windows, its dependencies, and the cross-build tools;
this will take about an hour on a fast machine with decent internet access;
the download is about 500MB:
$ cd mxe && make qt
Go to the directory of your app and add the cross-build tools to the PATH environment variable:
$ export PATH=<mxe root>/usr/bin:$PATH
Run the Qt Makefile generator tool then build:
$ <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake && make
You should find the binary in the ./release directory:
$ wine release/foo.exe
Some notes:
Use the master branch of the MXE repository; it appears to get a lot more love from the development team.
The output is a 32-bit static binary, which will work well on 64-bit Windows.
(This is an update of #Tshepang's answer, as MXE has evolved since his answer)
Building Qt
Rather than using make qt to build Qt, you can use MXE_TARGETS to control your target machine and toolchain (32- or 64-bit). MXE started using .static and .shared as a part of the target name to show which type of lib you want to build.
# The following is the same as `make qt`, see explanation on default settings after the code block.
make qt MXE_TARGETS=i686-w64-mingw32.static # MinGW-w64, 32-bit, static libs
# Other targets you can use:
make qt MXE_TARGETS=x86_64-w64-mingw32.static # MinGW-w64, 64-bit, static libs
make qt MXE_TARGETS=i686-w64-mingw32.shared # MinGW-w64, 32-bit, shared libs
# You can even specify two targets, and they are built in one run:
# (And that's why it is MXE_TARGET**S**, not MXE_TARGET ;)
# MinGW-w64, both 32- and 64-bit, static libs
make qt MXE_TARGETS='i686-w64-mingw32.static x86_64-w64-mingw32.static'
In #Tshepang's original answer, he did not specify an MXE_TARGETS, and the default is used. At the time he wrote his answer, the default was i686-pc-mingw32, now it's i686-w64-mingw32.static. If you explicitly set MXE_TARGETS to i686-w64-mingw32, omitting .static, a warning is printed because this syntax is now deprecated. If you try to set the target to i686-pc-mingw32, it will show an error as MXE has removed support for MinGW.org (i.e. i686-pc-mingw32).
Running qmake
As we changed the MXE_TARGETS, the <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake command will no longer work. Now, what you need to do is:
<mxe root>/usr/<TARGET>/qt/bin/qmake
If you didn't specify MXE_TARGETS, do this:
<mxe root>/usr/i686-w64-mingw32.static/qt/bin/qmake
Update: The new default is now i686-w64-mingw32.static
Another way to cross-compile software for Windows on Linux is the MinGW-w64 toolchain on Archlinux. It is easy to use and maintain, and it provides recent versions of the compiler and many libraries. I personally find it easier than MXE and it seems to adopt newer versions of libraries faster.
First, you will need an arch-based machine (virtual machine or docker container will suffice). It does not have to be Arch Linux, derivatives will do as well. I used Manjaro Linux.
Most of the MinGW-w64 packages are not available at the official Arch repositories, but there is plenty in AUR. The default package manager for Arch (Pacman) does not support installation directly from AUR, so you will need to install and use an AUR wrapper like yay or yaourt. Then installing MinGW-w64 version of Qt5 and Boost libraries is as easy as:
yay -Sy mingw-w64-qt5-base mingw-w64-boost
#yaourt -Sy mingw-w64-qt5-base mingw-w64-qt5-boost #if you use yaourt
This will also install the MinGW-w64 toolchain (mingw-w64-gcc) and other dependencies.
Cross-compiling a Qt project for windows (x64) is then as simple as:
x86_64-w64-mingw32-qmake-qt5
make
To deploy your program you will need to copy corresponding dlls from /usr/x86_64-w64-mingw32/bin/. For example, you will typically need to copy /usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/qwindows.dll to program.exe_dir/platforms/qwindows.dll.
To get a 32bit version you simply need to use i686-w64-mingw32-qmake-qt5 instead. Cmake-based projects work just as easily with x86_64-w64-mingw32-cmake.
This approach worked extremely well for me, was the easiest to set-up, maintain, and extend.
It also goes well with continuous integration services. There are docker images available too.
For example, let's say I want to build QNapi subtitle downloader GUI. I could do it in two steps:
Start the docker container:
sudo docker run -it burningdaylight/mingw-arch:qt /bin/bash
Clone and compile QNapi
git clone --recursive 'https://github.com/QNapi/qnapi.git'
cd qnapi/
x86_64-w64-mingw32-qmake-qt5
make
That's it! In many cases, it will be that easy. Adding your own libraries to the package repository (AUR) is also straightforward. You would need to write a PKBUILD file, which is as intuitive as it can get, see mingw-w64-rapidjson, for example.
Ok I think I've got it figured out.
Based in part on https://github.com/mxe/mxe/blob/master/src/qt.mk and https://www.videolan.org/developers/vlc/contrib/src/qt4/rules.mak
It appears that "initially" when you run configure (with -xtarget, etc.), it configures then runs your "hosts" gcc to build the local binary file ./bin/qmake
./configure -xplatform win32-g++ -device-option CROSS_COMPILE=$cross_prefix_here -nomake examples ...
then you run normal "make" and it builds it for mingw
make
make install
so
yes
only if you need to use something other than msvcrt.dll (its default). Though I have never used anything else so I don't know for certain.
https://stackoverflow.com/a/18792925/32453 lists some configure params.
In order to compile Qt, one must run it's configure script, specifying the host platform with -platform (e.g. -platform linux-g++-64 if you're building on a 64-bit linux with the g++ compiler) and the target platform with -xplatform (e.g. -xplatform win32-g++ if you're cross compiling to windows).
I've also added this flag:
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32-
which specifies the prefix of the toolchain I'm using, which will get prepended to 'gcc' or 'g++' in all the makefiles that are building binaries for windows.
Finally, you might get problems while building icd, which apparently is something that is used to add ActiveX support to Qt. You can avoid that by passing the flag -skip qtactiveqt to the configure script. I've got this one out of this bug report: https://bugreports.qt.io/browse/QTBUG-38223
Here's the whole configure command I've used:
cd qt_source_directory
mkdir my_build
cd my_build
../configure \
-release \
-opensource \
-no-compile-examples \
-platform linux-g++-64 \
-xplatform win32-g++ \
-device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \
-skip qtactiveqt \
-v
As for yout questions:
1 - Yes. The native compiler will be called in order to build some tools that are needed in the build process. Maybe things like qconfig or qmake, but I'm not entirely sure which tools, exactly.
2 - Sorry. I have no idea what specs files are in the context of compilers =/ . But as far as I know, you wouldn't have to deal with that.
3 - You can specify the cross compiler prefix in the configure command line instead of doing it in the qmake.conf file, as mentioned above. And there's also that problem with idc, whose workaround I've mentioned as well.

Compile GCC and install to DESTDIR

I'm trying to install GCC into /my/custom/path/gcc
but for some reason it installs into the normal installation path.
the commands i'm using:
configure --target=i686-pc-linux-gnu --disable-nls --enable-languages=c,c++ --without-headers
make DESTDIR=/my/custom/path/gcc
make DESTDIR=/my/custom/path/gcc install
What am I doing wrong?
You should run (in a new build tree outside of the source tree)
/your/source/path/to/gcc/configure --target=i686-pc-linux-gnu --prefix=/my/custom/path/gcc ...
and then GCC will become installed in /my/custom/path/gcc/bin/ with include files in /my/custom/path/gcc/include/, libraries in /my/custom/path/gcc/lib/ etc etc
I suggest using /opt/ or $HOME/pub as your prefix and you might also be interested by the --program-suffix=-foo option
(do that in a fresh new build tree outside of the source tree; your previous one is rotten)
After successive compilation with make, you can run in your build tree
make install DESTDIR=/tmp/mygccinst/
and finally, you can copy the definitive files with something like
cp -va /tmp/mygccinst/ /
You may need to run this copy as root...
PS the installation prefix is built-in the gcc driver binary, which actually runs cc1 or cc1plus etc...

Resources