从ARM的源代码交叉编译Qt 4.7 [英] Problems cross compiling Qt 4.7 from source for ARM

查看:561
本文介绍了从ARM的源代码交叉编译Qt 4.7的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从源代码交叉编译Qt 4.7.1,以下是我的设置中的一些注释:


  1. 我的预期输出是为了运行Qt应用程序而需要存在的共享对象库。

  2. 我的目标平台是具有ARM Cortex-A8架构的TI AM335x处理器。

  3. 我的开发平台是一个x86 64位Ubuntu虚拟机

这应该是我下载我的目标平台的工具链(这是 Linaro TI的工具链),我下载了 Qt 4.7.1 的源代码,我设置mkspec使用我的工具链,运行 configure ,然后只需要运行 make / make install ,我应该可以找到我要求安装的所有 .so 。我有很多问题让这个想法工作,但是。






首先我下载了​​TI SDK版本:ti -sdk-am335x-evm-06.00.00.00它的手臂工具在:
[root_install_dir] / linux-devkit / sysroots / i686-arago-linux / usr / bin



我更新了我的 $ PATH 与该目录:


mike @ mike-VirtualBox:〜$ echo $ PATH
/home/mike/ti-sdk-am335x-evm-06.00.00/linux-devkit / home / mike / bin:/ usr / lib / lightdm / lightdm:
/ usr / local / sbin:/ usr / local / bin:/ usr / sbin:/ usr / bin:/ sbin:/ bin:/ usr / games:/ home / mike / bin >

然后我根据最接近的例子创建了自己的mkspec:
cp -R [qt_install_dir] / mkspecs / qws / linux-arm-gnueabi-g ++ / [qt_install_dir] / mkspecs / qws / linux-am335x-g ++



Linux的am335x-G ++ / qmak e.conf 指向TI sdk中的工具:

 #修改为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 ++

#修改linux.conf
QMAKE_AR = arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY = arm-linux-gnueabihf-objcopy
QMAKE_STRIP = arm -linux-gnueabihf-strip

然后我运行了一个配置命令:


./ 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


它运行一段时间然后完成,并说已经准备好了在这一点上,我执行 make / make install make运行 make 这就是它开始失败的地方:


/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_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 - 我../../ 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} :汇编消息:

{标准输入}:1294:错误:选定的处理器不支持Thumb模式swp r6,r4,[r3]

make [1]: [.obj / release-shared-emb-arm / qobject.o]错误1 *
make [1]:离开目录< br>
'/home/mike/qt4.7.1_source/qt-everywhere-opensource-src-4.7.1/src/corelib'

make: * [sub-corelib-make_default-ordered]错误2


所以,问题...
为什么编译器抱怨不支持拇指模式?由于这是一个用于基于ARM 的处理器的交叉编译工具链,所以它应该支持。事实上,这并不让我觉得使以某种方式拾起错误的g ++版本。



有什么问题和如何解决这个问题的任何想法?

解决方案

blockquote>

{标准输入}:1294:错误:选定的处理器不支持Thumb模式'swp r6,r4,[r3]'



为什么编译器抱怨拇指模式不受支持?


请注意,编译器抱怨 swp 指令不可用于缩略图模式。您的CPU支持 thumb , thumb2 和 ARM 。 Cortex系列不推荐使用 swp ,并喜欢 ldrex / strex 对。


有什么问题和如何解决这个问题的任何想法?


你需要获取gcc定义 __ ARM_ARCH_7 __ ;这可以通过 -mcpu = cortex-a8 或组合 -mtune = cortex-a8 -march = armv7-a 或者你喜欢什么,取决于你想要执行几种类型的主板 Qt



详细信息请参阅 qatomic_arm.h 选择子文件的位置。您有一个非常通用的 ARM (我猜想),所以你得到 qatomic_armv5.h Note1 您可以在其中看到第125行的代码。您的CPU的正确文件是 qatomic_armv7.h ,其主要仅包括 qatomic_armv6.h 。在这个文件中,您可以找到 gcc 正在请求的 ldrex / strex

我还建议您不要使用 -fast 进行编译。 OP说的是另一个问题这解决了他的问题;但我认为这是不同的。



您可以尝试通过 -armfpa 进行配置。 ./ configure -embedded arm --help 是有用的。 配置似乎选择了 NEON ,所以似乎知道你有一个更高级的CPU(没有NEON 在 armv5 上,但这可能是配置的错误)。



确实,你不想要 swp 代码和 ldrex / strex 是您的系统的首选,即使 swp 可以以某种方式工作。我至少会解决这个问题。更改 -xplatform qws / linux-am335x-g ++ 以更新 -mcpu 或可能通过一个显式的 -D__ARM_ARCH_7 __ 。您可以通过 arm-gcc -mcpu = cortex-a8获取定义列表。 dM -E- / dev / null ,以验证正在定义 __ ARM_ARCH_7 __ 。它似乎是 moc 失败,所以也许需要 -D__ARM_ARCH_7 _ 解决方案。



您也可以尝试在编译器选项中更改 -mthumb 。对于您的系统,最好使用 -mcpu = cortex-a8 -mthumb ,如果可以得到编译/构建。省略 -mthumb 将使代码稍大。您也可以尝试 -Os 。由于某些原因,我有巨大的构建与其他优化和更多最近的 gcc 版本。这似乎是由于一些C ++功能正常,C不这样做;但这可能只是我的编译器。我看起来相信这是异常表,但我从来没有确认任何事情,并继续前进。我确定你知道Qt需要多长时间才能编译。



Note1: qatomic_armv5.h 代码相当困惑,较新的 gcc binutils 即使这是正确的文件使用也会阻塞。

  asm volatile(swpb%0,%2,[%3]
:=& r(ret),= m * ptr)
:r(newval),r(ptr)
:cc,memory);

这指定了一些从未使用过的内嵌汇编器参数。更不用说没有使用条件代码等。

  asm volatile(swpb%0,%1,[%2 ]
:= r(ret)
:0(newval),r(ptr)
:memory);

将使用较新的 gcc 的binutils 。它也使用较少的寄存器,并且是最适合 Qt 正在使用它的方式;有可能需要保留 ret 以与 newval 进行比较,但它只是一个用户空间旋转锁定



括号 [x] 是一个内存操作数寄存器,必须不同于 swp 的其他两个参数。我相信第一个表单被用来停止%0 %3 相同。第二种形式通过使%0 %1 相同来避免这种情况,所以%2 必须不同。


I'm trying to cross-compile Qt 4.7.1 from source, here are some notes on my setup:

  1. my expected output is the shared object libraries that are required to be present in order to run a Qt application.
  2. My target platform is a TI AM335x processor which is of the ARM Cortex-A8 architecture.
  3. 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?

解决方案

{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.

这篇关于从ARM的源代码交叉编译Qt 4.7的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆