问题
I'm trying to cross-compile Qt 4.7.1 from source, here are some notes on my setup:
- my expected output is the shared object libraries that are required to be present in order to run a Qt application.
- My target platform is a TI AM335x processor which is of the ARM Cortex-A8 architecture.
- My development platform is a x86 64-bit Ubuntu virtual machine
My understanding of how this should work is that I download the toolchain for my target platform (this is the Linaro toolchain from TI), I download the source code for Qt 4.7.1, I set the mkspec to use my tool chain, run configure
, then just need to run make
/make install
and I should be able to find all the .so
's where I told it to install to. I'm having a lot of problems getting this idea to work however.
First I downloaded the TI SDK version: ti-sdk-am335x-evm-06.00.00.00 which has the arm tool's at:
[root_install_dir]/linux-devkit/sysroots/i686-arago-linux/usr/bin
I updated my $PATH
with that directory:
mike@mike-VirtualBox:~$ echo $PATH /home/mike/ti-sdk-am335x-evm-06.00.00.00/linux-devkit/sysroots/i686-arago-linux/usr/bin :/usr/local/Trolltech/Qt-4.8.5/bin:/home/mike/bin:/usr/lib/lightdm/lightdm: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/mike/bin
I then created my own mkspec based on the closest example:
cp -R [qt_install_dir]/mkspecs/qws/linux-arm-gnueabi-g++/ [qt_install_dir]/mkspecs/qws/linux-am335x-g++
and I modified the linux-am335x-g++/qmake.conf
to point to the tools from the TI sdk:
# modifications to g++.conf
QMAKE_CC = arm-linux-gnueabihf-gcc
QMAKE_CXX = arm-linux-gnueabihf-g++
QMAKE_LINK = arm-linux-gnueabihf-g++
QMAKE_LINK_SHLIB = arm-linux-gnueabihf-g++
# modifications to linux.conf
QMAKE_AR = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabihf-objcopy
QMAKE_STRIP = arm-linux-gnueabihf-strip
Then I ran a configure command:
./configure -prefix /home/mike/qt4.7.1_source/my_qt -embedded arm -platform qws/linux-x86_64-g++ -xplatform qws/linux-am335x-g++ -no-mmx -no-3dnow -no-sse -no-sse2 -no-glib -no-cups -no-largefile -no-accessibility -no-openssl -no-gtkstyle -fast -opensource
It runs for a while then completes and says it's ready to do make
/make install
at this point I run make
and that's where it starts to fail:
/home/mike/qt4.7.1_source/qt-everywhere-opensource-src-4.7.1/bin/moc -DQT_SHARED -DQT_BUILD_CORE_LIB -DQT_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT3_SUPPORT -DQT_MOC_COMPAT -DQT_USE_FAST_OPERATOR_PLUS -DQT_USE_FAST_CONCATENATION -DELF_INTERPRETER=\"/lib64/ld-linux-x86-64.so.2\" -DHB_EXPORT=Q_CORE_EXPORT -DQT_HAVE_NEON -DQT_NO_DEBUG -I../../mkspecs/qws/linux-am335x-g++ -I. -I../../include -I../../include/QtCore -I.rcc/release-shared-emb-arm -Iglobal -I../3rdparty/harfbuzz/src -I../3rdparty/md5 -I../3rdparty/md4 -I.moc/release-shared-emb-arm kernel/qobject.h -o .moc/release-shared-emb-arm/moc_qobject.cpp arm-linux-gnueabihf-g++ -c -include .pch/release-shared-emb-arm/QtCore -pipe -fno-exceptions -mfpu=neon -O2 -fvisibility=hidden -fvisibility-inlines-hidden -Wall -W -D_REENTRANT -fPIC -DQT_SHARED -DQT_BUILD_CORE_LIB -DQT_NO_USING_NAMESPACE -DQT_NO_CAST_TO_ASCII -DQT_ASCII_CAST_WARNINGS -DQT3_SUPPORT -DQT_MOC_COMPAT -DQT_USE_FAST_OPERATOR_PLUS -DQT_USE_FAST_CONCATENATION -DELF_INTERPRETER=\"/lib64/ld-linux-x86-64.so.2\" -DHB_EXPORT=Q_CORE_EXPORT -DQT_HAVE_NEON -DQT_NO_DEBUG -I../../mkspecs/qws/linux-am335x-g++ -I. -I../../include -I../../include/QtCore -I.rcc/release-shared-emb-arm -Iglobal -I../3rdparty/harfbuzz/src -I../3rdparty/md5 -I../3rdparty/md4 -I.moc/release-shared-emb-arm -o .obj/release-shared-emb-arm/qobject.o kernel/qobject.cpp
{standard input}: Assembler messages:
{standard input}:1294: Error: selected processor does not support Thumb mode 'swp r6,r4,[r3]'
make[1]: [.obj/release-shared-emb-arm/qobject.o] Error 1*
make[1]: Leaving directory
'/home/mike/qt4.7.1_source/qt-everywhere-opensource-src-4.7.1/src/corelib'
make: * [sub-corelib-make_default-ordered] Error 2
So, the question...
Why is the compiler complaining that the thumb mode is not supported? Since this is a cross compile tool chain for an ARM based processor, it should be supported. The fact that it's not makes me feel that make
is somehow picking up the wrong version of g++.
Any thoughts on what went wrong and how to fix this?
回答1:
{standard input}:1294: Error: selected processor does not support Thumb mode 'swp r6,r4,[r3]'
Why is the compiler complaining that the thumb mode is not supported?
Note, the compiler is complaining about the swp
instruction not being available for thumb mode. Your CPU supports thumb, thumb2, and ARM. The Cortex series deprecates the use of swp
and prefers ldrex/strex
pairs.
Any thoughts on what went wrong and how to fix this?
You need to get gcc to define __ARM_ARCH_7__
; this is done with either -mcpu=cortex-a8
or the combination -mtune=cortex-a8
and -march=armv7-a
or what ever you like depending on how many types of boards you want Qt to run on.
In detail, see qatomic_arm.h for where a sub-file is selected. You have a very generic ARM selected (I guess), so you get qatomic_armv5.hNote1 where you can see the code around line 125. The right file for your CPU is qatomic_armv7.h, which mainly just includes qatomic_armv6.h. In this file you can find ldrex/strex
which is the wholesome goodness that your gcc
is requesting.
I also suggest you do not compile with -fast. There is another question where the OP says this solved his issue; but I think this is different.
You can try to pass -armfpa
to configure. ./configure -embedded arm --help
is useful. configure
appears to have selected NEON, so it seems to know you have a more advanced CPU (there is no NEON on an armv5, but this maybe a fault of configure
).
For certain, you don't want the swp
code and the ldrex/strex
is preferred for your system, even if swp
could somehow work. I would at least resolve this. Alter the -xplatform qws/linux-am335x-g++
to update -mcpu
or possibly pass an explicit -D__ARM_ARCH_7__
. You can get a list of defines with arm-gcc -mcpu=cortex-a8 -dM -E - < /dev/null, to verify that the __ARM_ARCH_7__
is being defined. It looks like it is moc
failing, so maybe the -D__ARM_ARCH_7_
solution will be needed.
You might also try to alter -mthumb
in the compiler option. It is probably best to use -mcpu=cortex-a8
and -mthumb
for your system, if you can get that to compile/build. Omitting -mthumb
will make the code slightly larger. You might also try -Os
. For some reason, I have huge builds with other optimizations and more recent gcc
versions. It appears to be due to some C++ feature as normal 'C' doesn't behave this way; but this may just be my compiler. I looked and believe it is the exception tables, but I never confirmed anything and moved on. I am sure you are aware of how long Qt takes to compile.
Note1: The qatomic_armv5.h code is fairly confused and newer gcc
or binutils will choke even when this is the correct file to use.
asm volatile("swpb %0,%2,[%3]"
: "=&r"(ret), "=m" (*ptr)
: "r"(newval), "r"(ptr)
: "cc", "memory");
This specifies some inline assembler parameters which are never used. Not to mention the condition codes are not used, etc.
asm volatile("swpb %0,%1,[%2]"
: "=r"(ret)
: "0"(newval), "r"(ptr)
: "memory");
will compile with newer gcc
and binutils. It also uses less registers and is optimal for the way Qt is currently using it; there maybe cases where ret
needs to be preserved to compare to newval
but it is just a user space spin lock currently.
The bracket [x]
is a memory operand register and must be different than the other two parameters for a valid swp
. I believe the first form was used to stop %0
from being the same as %3
. The 2nd form avoids this by making %0
and %1
the same, so %2
must be different.
回答2:
the answer by usr: artless noise did in fact fix my issue, but since I want to make sure there is a very clear trail for myself (if needed) or others, I want to state exactly what the fix was:
First, I updated my .configure
command to:
./configure -prefix /home/mike/qt4.7.1_source/my_qt -embedded arm -platform qws/linux-x86_64-g++ -xplatform qws/linux-am335x-g++ -no-mmx -no-3dnow -no-sse -no-sse2 -no-glib -no-cups -no-largefile -no-accessibility -no-openssl -no-gtkstyle -opensource -qt-mouse-tslib
The only difference from the question's configure command is the removal of the -fast
option.
Then in my the linux-am335x-g++/qmake.conf file, I added a few command line options:
QMAKE_CFLAGS= -march=armv7-a -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
QMAKE_CXXFLAGS= -march=armv7-a -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8
With these two change I can now see everything build and install Qt4.7.1 successfully.
I also tried Qt4.8.5 and everything works the same except one more option has to be added to the ./configure command:
-no-pch
This is to avoid an error regarding a: .pch directory and files in side showing "No such file or directory"
来源:https://stackoverflow.com/questions/21268833/problems-cross-compiling-qt-4-7-from-source-for-arm