QT building applications for arm linux - linux

I got a little confused when it comes to QT and cross compiling
appliations for my arm-linux:
So far I have a linux running on my AT91SAM9263-EK and an appropriate
filessystem including QT libs build via buildroot.
Also I have build QT-4.8 on my ubuntu.
Now I want to build an example application:
I created a makefile in an examples folder in QT on my ubuntu using
qmake; I used the given qmake.conf in mkspecs/qws/linux-arm-g++.
when executing make I get an error because it includes qatomic_i386.h
and the message "error: impossible constraint in 'asm'".
this header file does obviously not match to my arm toolchain.
my question:
how to configure Qt on my ubuntu to build Qt binaries for my embedded linux
on arm? Do I need to include any libs build by the arm toolchain?
any help is appreciated!
regards
EDIT:
I use the -spec flag and pass the path to "mkspecs/qws/arm-linux-g++" where a "qmake.conf" is located. I did not change anything in here because I dont know wich qmake variable are relevant to link to my arm related libs.
So the right compiler is used, which I could verify when the make process starts. But I observed that in a config file called qconfig.h there is an ARCH flag which is set to i386 but I didnt figure out how one can configure this. I dont think I should manually edit this file.
EDIT2:
someone knows whats behind the file qconfig.h?? should I adjust it manually?

I will solve it by myself :)
After struggling a while and scanning the web I got a little deeper involved how everything works together. I did not understand how to generate an executable for my ARM target device. I figured out two things:
do not add your QT path for X11 at the beginning in your PATH variable. this might mess up your cross compilation.
edit the qmake.conf correspondingly. add your libs build for the target device which in my case are located within buildroot. Add theses lines to your qmake.conf file:
QMAKE_CFLAGS += -O3 -march=armv5te
QMAKE_CXXFLAGS += -O3 -march=armv5te
QMAKE_INCDIR_QT = /home/user/arm/toolchain/buildroot-2010.11/output/staging/usr/include
QMAKE_LIBDIR_QT = /home/user/arm/toolchain/buildroot-2010.11/output/staging/usr/lib
I got it running now. thanks to everyone!

Yes, either you provide the Qt libraries in your toolchain or you tell qmake where to find them. Also, I suspect you're calling qmake without the -spec parameters. If you are using the qmake you find in your distribution, it will use the default spec, which is not arm I guess. Add the -spec parameter and point it to the arm mkspec. Also, make sure the generated g++ commands link to the correct Qt libs compiled for arm.

You shall install QtSDK for embedded linux befor you use it to build your application. I'm afraid you just have QtSDK for x86 right now. After QtSDK for embedded linux installed, it has qws/linux-arm-g++ as the default mkspace typically. If you don't have QtSDK for embedded linux, you can build it from source. Then run qmake to create Makefile for you application.
$QTDIR_FOR_ARM/qmake
Reference:
Installing Qt for Embedded Linux and Cross-Compiling Qt for Embedded Linux Applications

Related

How do I build a newlib RISC-V toolchain with a modified linker script?

I'm trying to build a GCC/newlib cross compilation toolchain targeting an embedded OS on RISC-V. For this purpose, I need to modify the virtual addresses that binaries are linked at.
One way to achieve this is to modify the default linker script that ships with the toolchain.
I'm trying to find the best location in the involved components (newlib, binutils, gcc) where I can tweak the default linker script that is shipped with the toolchain.
For some platforms, newlib already provides partial or complete linker scripts. It seems for RISC-V the default linker script produced by binutils is used.
I'm fine with patching binutils, but I can't find how the RISC-V linker script is actually built or how I would modify anything in it. Any pointers are appreciated!
The different linker scripts for riscv are build from :
binutils/ld/scripttempl/elf.sc
binutils/ld/emulparams/elf32lriscv*
binutils/ld/emulparams/elf64lriscv*
You will need to modifiy these files or create your own and modify the Makefiles.

how to configure QT creator cross compiling

Actually i installed QT creator in my debian linux system which is having i386 processor.Now i need to cross compile the QT for debian linux with ARM processor.
So for this cross compile process i installed the compiler arm-linux-gnueabi-gcc-4.4 manually and add it in the QT creator "Tools->Options->Build&Run-->Compiler".
After that i have no idea of how to configure the installed (arm-linux-gnueabi-gcc-4.4) compiler in kit option. Because in kit option "Device Type" , it is expecting for the Qmake file of arm-linux-gnueabi-gcc-4.4.Here my doubt is
Is it possible to create Qmake file for the compiler (arm-linux-gnueabi-gcc-4.4)
If that case what is the procedure to create Qmake file for the compiler (arm-linux-gnueabi-gcc-4.4)
If not in the case any dependencies need to install.
By googling around for this solution finally i felt my head rotate because in QT documentQT document they mention 5 steps.Among 5 steps i stuck in 2nd step itself (./configure -embedded arm -xplatform qws/linux-arm-g++ ).In this step im not able to understand what is configure , embedded, arm, xplatform etc...
In some link link number 2 they suggested to install bitbake and some steps.Here im not able to install bitbake also.
In some qt documents they mentioned embedded linux (is embedded linux is a OS like debian) and mkspecs etc..
Finally i decided to create Qmake file for the compiler arm-linux-gnueabi-gcc-4.4 but not having the single clue also.So if anybody knows what exactly i need to configure QT creator (either Qmake for compiler arm-linux-gnueabi-4.4 or something else ) so that i will follow exactly the required thing without any confusion.
Qt cross compiling for arm based board can be sucessfully done using Angstrom cross compiler. Just download Angstrom cross compiler as per your board configuration , unpack it and create cross compiler using that package.

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.

How to run a *.o file in Android

I currently compiled a set of source code in C in Linux and the output is a *.o file which is a object file. This supposedly does image compression. Now I want to use/test this in Android.
Is this possible? I have only tried NDK examples from the Android NDK developer side. Have not came across any reference on how this can be done.
Thanks In Advance,
Perumal
You don't run object code files (*.o). You would need to turn it into an executable. To do this, assuming you are using GCC you would run gcc file1.o file2.o -o executable which would convert a two file program with file1.o and file2.o into an executable called executable.
Object files (ending in .o) usually contain code that is incomplete. For example, if your program uses some library to print something on screen, to produce an executable, you must link your compiled code (the .o file) with the library, so that when the operating system loads the executable knows all the code that will be used. You do this linking with a linker (such as ld in Linux, or /system/bin/linker in Android). In your case, it's easier to let gcc call the linker for you, as Jalfor notes.
The answer is Yes. But you have to do some fair amount of work to see it running on Android.
1) If you are compiling on Linux, it means the object file or the final executable is being built for the x86 or AMD processor(Mostly). But mostly all the mobile devices have ARM processors running on their phones. So, though you have an executable you will not be able to execute it in ANdroid if it is not built for ARM Cpu. This is what android NDK does exactly.
2) So, we have to build the same code again for Android(ARM), for which we need a cross-compiler and the source code of the object files you are talking about.
3) If you have source code avilable, you can do 2 things again.
To include it in JNI folder, build the shared library and then do the
stuff of calling and all.
Build the code into an executable(Note you need to have main
inside the code) using the android NDK and then push the executable inside Android using
adb.
Now finally you can login and then check the result. In case anything is not clear, please do let me know. I wont mind explaining. Thanks..

crosscompile glibc for arm

Good day
Currently, I'm working on an embedded device based on arm-linux. I want to build GCC for my target architecture with Glibc. GCC builds successful, but I have trouble with Glibc build.
I use the latest version of Glibc (ftp.gnu.org/gnu/glibc/glibc-2.12.1.tar.gz) and port for them (ftp.gnu.org/gnu/glibc/glibc-ports-2.12.1.tar.gz)
my configuration line:
../../glibc-2.12.1/configure --host=arm-none-linux-gnueabi --prefix=/home/anatoly/Desktop/ARM/build/glibc-build --enable-add-ons --with-binutils=/home/anatoly/Desctop/ARM/toolchain/arm/bin/
configuration script work fine, but i get some compile error:
...
/home/anatoly/Desktop/ARM/src/glibc-2.12.1/malloc/libmemusage_pic.a(memusage.os): In function me':
/home/anatoly/Desktop/ARM/src/glibc-2.12.1/malloc/lmemusage.c:253: undefined reference to__eabi+read_tp'
...
I also tried using the old version (2.11, 2.10) but have the same error.
Does anybody know the solution for this problem?
Use a precompiled toolchain, like those provided by code sourcery.
If you want to make your own, optimised (premature optimization is the root of all evil), use crosstool-NG, which is a tool dedicated to cross-compilation toolchain building.
If you are not convinced, and want to do everything with your own hands, ask your question on the crosstool-NG mailing list.
Try substituting arm-linux-gnueabi for arm-none-linux-gnueabi. Check that a compiler, loader etc. with the prefix you used for "host" exist on your path.

Resources