【问题标题】:Problems cross compiling Qt 4.7 from source for ARM从源代码为 ARM 交叉编译 Qt 4.7 的问题
【发布时间】:2014-02-11 16:17:36
【问题描述】:

我正在尝试从源代码交叉编译 Qt 4.7.1,以下是关于我的设置的一些注意事项:

  1. 我的预期输出是运行 Qt 应用程序所需的共享对象库。
  2. 我的目标平台是 TI AM335x 处理器,它是 ARM Cortex-A8 架构。
  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,它的 arm 工具位于: [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.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

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

./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,这就是它开始失败的地方:

/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
{标准输入} :汇编程序消息:
{标准输入}:1294:错误:所选处理器不支持 Thumb 模式 'swp r6,r4,[r3]'
ma​​ke[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: * [sub-corelib-make_default-ordered] 错误 2

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

对出了什么问题以及如何解决此问题有任何想法吗?

【问题讨论】:

  • 您是否尝试过Buildroot 或手动交叉编译?请参阅这些slides

标签: c++ linux qt embedded arm


【解决方案1】:

{标准输入}:1294: 错误:所选处理器不支持 Thumb 模式 '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编译。有another question 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。出于某种原因,我有 huge 构建了其他优化和更新的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");

将使用更新的 gccbinutils 进行编译。它还使用较少的寄存器,并且最适合 Qt 当前使用它的方式;在某些情况下,ret 可能需要保留以与newval 进行比较,但它目前只是一个用户空间自旋锁

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

【讨论】:

  • 感谢您的帮助,我将删除 -fast 以供后代使用,并查看其他一些标志。这是我第一次进行 Qt 交叉编译,AFAIK 将 QMAKE_CFLAGSQMAKE_CXXFLAGS 添加到 qmake.conf 是添加要传递给实际 make 的标志的正确方法(即这是正确的传递位置-marm-mthumb 等)。你知道这是否正确吗?
  • 是的,这些看起来是正确的。有一百万个变量,但大多数只是汇总。 Advanced QmakeLinux journal crossBuilding Qt for embedded 等。我很确定我对 mkspec 有很好的参考,但也许它适用于 Qt5.x,我现在找不到...
  • 呃,这些家伙说 -embedded armv7 哪里是 they have the same problem。如果可行的话,这可能是比使用 mkspecs 更好的解决方案;只需验证这是否传递了良好的 -mcpu-march 值,因此您的代码是最佳的(以及编译)。
【解决方案2】:

usr 的回答:artless noise 确实解决了我的问题,但是由于我想确保自己(如果需要)或其他人有一个非常清晰的线索,我想准确说明修复的是什么:

首先,我将.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

这是为了避免关于 a: .pch 的错误 目录和文件在侧面显示“没有这样的文件或目录”

【讨论】:

    猜你喜欢
    • 2020-04-10
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 2021-07-26
    相关资源
    最近更新 更多