从 ARM 源代码编译 Qt 4.7 的问题

Problems cross compiling Qt 4.7 from source for ARM

本文关键字:问题 Qt ARM 源代码 编译      更新时间:2023-10-16

我正在尝试从源代码交叉编译Qt 4.7.1,以下是有关我的设置的一些说明:

  1. 我的预期输出是运行Qt应用程序所需的共享对象库。
  2. 我的目标平台是采用 ARM Cortex-A8 架构的 TI AM335x 处理器。
  3. 我的开发平台是一个 x86 64 位 Ubuntu 虚拟机

我对这应该如何工作的理解是,我下载了目标平台的工具链(这是来自 TI 的 Linaro 工具链),我下载了 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-虚拟盒子:~$ 回声$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

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

我修改了linux-am335x-g++/qmake.conf以指向 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

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

./配置 -前缀/home/mike/qt4.7.1_source/my_qt -嵌入式手臂 -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,这就是它开始失败的地方:

/

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../../包括 -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-inline-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../../包括 -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
{标准输入}: 汇编程序消息:{标准输入}:1294: 错误:选定的处理器不支持拇指模式 'swp r6,r4,[r3]' make[1]: [.obj/release-shared-emb-arm/qobject.o] 错误 1* make[1]: 离开目录'/home/mike/qt4.7.1_source/qt-everywhere-opensource-src-4.7.1/src/corelib'make




*[子核心库-make_default-排序]错误 2

所以,问题... 为什么编译器抱怨不支持拇指模式?由于这是基于ARM的处理器的交叉编译工具链,因此应支持它。事实上,它并没有让我觉得make以某种方式选择了错误的 g++ 版本。

关于出了什么问题以及如何解决这个问题的任何想法?

{标准输入}:1294:错误:所选处理器不支持拇指模式"swp r6,r4,[r3]">

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

请注意,编译器抱怨swp指令不可用于拇指模式。 您的 CPU 支持thumbthumb2ARM。 Cortex 系列不赞成使用swp,更喜欢ldrex/strex对。

关于出了什么问题以及如何解决这个问题的任何想法?

你需要让gcc来定义__ARM_ARCH_7__;这是通过-mcpu=cortex-a8-mtune=cortex-a8-march=armv7-a的组合来完成的,或者你喜欢的任何方式,这取决于你希望Qt运行多少种类型的板。

有关详细信息,请参阅qatomic_arm.h以了解选择子文件的位置。 你选择了一个非常通用的ARM(我猜),所以你得到qatomic_armv5.hNote1,你可以在其中看到第125行周围的代码。 适合您的 CPU 的文件是 qatomic_armv7.h,主要只包括qatomic_armv6.h在此文件中,您可以找到ldrex/strex您的gcc所要求的有益健康的好处。

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

您可以尝试传递要配置的-armfpa./configure -embedded arm --help很有用。configure似乎选择了NEON,所以它似乎知道您拥有更高级的 CPU(armv5上没有NEON,但这可能是configure的错误)。

当然,您不想要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需要多长时间来编译。

注意1: qatomic_armv5.h代码相当混乱,即使这是正确的文件,较新的gccbinutils也会阻塞。

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二进制文件进行编译。 它还使用较少的寄存器,并且最适合Qt当前使用它的方式;在某些情况下,可能需要保留ret以与newval进行比较,但它目前只是一个用户空间旋转锁

括号[x]是一个内存操作数寄存器,必须与其他两个参数不同才能获得有效的swp。 我相信第一种形式被用来阻止%0%3相同。 第二种形式通过使%0%1相同来避免这种情况,因此%2必须不同。

usr 的答案:无艺术噪音确实解决了我的问题,但由于我想确保为自己(如果需要)或其他人有一个非常清晰的线索,我想确切地说出修复是什么:

首先,我将.configure命令更新为:

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

与问题的配置命令的唯一区别是删除了-fast选项。

然后在我的 linux-am335x-g++/qmake.conf 文件中,我添加了一些命令行选项:

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

通过这两个更改,我现在可以看到所有内容都成功构建和安装 Qt4.7.1。

我也尝试了 Qt4.8.5,除了必须在 ./configure 命令中添加一个选项外,一切都一样:

-no-pch

这是为了避免有关 .pch 的错误 目录和侧面显示"没有此类文件或目录"的文件