无法为 Raspberry PI 零 w 交叉编译 Qt 5.14.2,因为它“需要 C++11 编译器”

Unable to cross-compile Qt 5.14.2 for Raspberry PI zero w because it “requires a C++11 compiler”

以前版本的 Qt5 已经遇到过此问题:Stack-overflow post (尚未回答)。我在更新的版本中遇到了同样的问题,我已经在线学习了几个教程:

即使这些教程都过时了,但是交叉编译Qt5的方法还是一样的。我的目标板是 Raspberry pi 零 w 运行 Raspbian Buster。配置步骤运行良好(没有任何错误)。

我在执行 make 时遇到以下错误:

~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/thread/qbasicatomic.h:61:4: error: #error "Qt requires C++11 support"
 #  error "Qt requires C++11 support"
    ^
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/thread/qbasicatomic.h:94:13: error: ‘QAtomicOps’ does not name a type
     typedef QAtomicOps<T> Ops;
             ^
In file included from ~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/qglobal.h:1:0,
                 from ~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/src/corelib/global/qt_pch.h:56:
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/thread/qbasicatomic.h:97:23: error: ‘QAtomicOpsSupport’ was not declared in this scope
     Q_STATIC_ASSERT_X(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform");
                       ^
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/global/qglobal.h:121:68: note: in definition of macro ‘Q_STATIC_ASSERT_X’
 #  define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
                                                                    ^
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/thread/qbasicatomic.h:97:51: error: ‘::IsSupported’ has not been declared
     Q_STATIC_ASSERT_X(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform");
                                                   ^
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/global/qglobal.h:121:68: note: in definition of macro ‘Q_STATIC_ASSERT_X’
 #  define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
                                                                    ^
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/global/qglobal.h:121:49: error: non-constant condition for static assertion
 #  define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
                                                 ^
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/thread/qbasicatomic.h:97:5: note: in expansion of macro ‘Q_STATIC_ASSERT_X’
     Q_STATIC_ASSERT_X(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform");
     ^
~/Documents/Raspbian/raspi/qt-everywhere-src-5.14.2/qtbase/include/QtCore/../../src/corelib/thread/qbasicatomic.h:97: confused by earlier errors, bailing out
make[3]: *** [Makefile:1836: .pch/Qt5Core.gch/c++] Error 1
make[3]: Leaving directory '~/Documents/Raspbian/raspi/qt5build/qtbase/src/corelib'
make[2]: *** [Makefile:228: sub-corelib-make_first] Error 2
make[2]: Leaving directory '~/Documents/Raspbian/raspi/qt5build/qtbase/src'
make[1]: *** [Makefile:51: sub-src-make_first] Error 2
make[1]: Leaving directory '~/Documents/Raspbian/raspi/qt5build/qtbase'
make: *** [Makefile:88: module-qtbase-make_first] Error 2

您使用的编译器太旧了。您从共享的 link 获得的版本是 4.8.3,而您至少需要 gcc 5。(在此处查看:https://codereview.qt-project.org/c/qt/qtdoc/+/288825

您得到的错误可能有点误导,因为 gcc 本身声明它完全支持 4.8.1 中的 C++11,如下所述:https://gcc.gnu.org/projects/cxx-status.html#cxx11

我建议您使用更新版本的 gcc。如 qt-docs 中所述,它至少应为 gcc 版本 5 或更高版本。

有多种方法供您选择(从简单到复杂排序):

  1. 尝试使用系统的包管理器(例如 sudo apt install gcc-arm-linux-gnueabihf)
  2. 从别处下载一个。 (例如这里:https://toolchains.bootlin.com/
  3. 建立你自己的。 (也许使用 crosstool-ng)。但请注意!这可能很棘手。尽管我有使用 crosstool-ng 或类似工具的良好经验。

最后但同样重要的是,不要忘记更改 ./configure 步骤的设置!查明您正在尝试使用的新工具链。

亲切的问候

对于未来的读者,正如指出的那样,交叉编译器由:https://github.com/raspberrypi/tools is outdated and cannot be used. I have tried all the methods described above but the one that worked out-of-the-box (for Raspberry Pi 0 W which is based on older ARMv6 architecture) is : https://github.com/Pro/raspi-toolchain 这个 repo 提供了一个 Docker 图像,它从源代码编译一个更新的工具链,甚至提供一个测试代码,您可以使用生成的工具链交叉编译并在 pi 上执行。

我遇到了同样的问题。

我最终通过以下操作对仅支持 EGL 的 Qt 5.15.0 进行了正确的交叉编译(以避免在如此小的 Rpi 零上使用 X11):

1- 正如@glamis 所提议的,我使用了编译工具链来自:https://github.com/Pro/raspi-toolchain v1.0.1

版本中的 pre-built 工具链

2-(蹩脚的)在 Qt 源中被黑 qtdeclarative/src/3rdparty/masm/wtf/OSAllocatorPosix.cpp:我用硬编码值 4096

替换了常量 PATH_MAX(此工具链中不存在?)

3- 仍然在 Qt 源中,编辑文件 qtbase/mkspecs/devices/linux-rasp-pi-g++/qmake.conf

3.a) 将所有出现的 -lEGL -lGLESv2 -lOpenVG 替换为 -lbrcmEGL -lbrcmGLESv2 -lbrcmOpenVG

3.b) 将 QMAKE_LIBS_OPENGL_ES2 = -lbrcmGLESv2 -lbrcmEGL 移动到 if 语句之外,以在所有情况下强制执行

备注:

  • raspberry pi 零,带有“Raspberry Pi OS Lite”(又名 raspbian Lite)版本,基于 debian buster,版本 2020 -05-27

  • 安装的依赖项:apt install build-essential libfontconfig1-dev libdbus-1-dev libfreetype6-dev libicu-dev libinput-dev libxkbcommon-dev libsqlite3-dev libssl-dev libpng-dev libjpeg-dev libglib2.0-dev libgbm-dev libraspberrypi-dev libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0

  • 使用的 qt 存档:qt-everywhere-src-5.15.0.tar.xz

  • 我的配置如下:configure -release -opensource -confirm-license -opengl es2 -device linux-rasp-pi-g++ -device-option CROSS_COMPILE=/opt/cross-pi-gcc/bin/arm-linux-gnueabihf- -sysroot $HOME/rpi/rootfs -prefix /usr/local/qt-5.15.0-rpi -extprefix $HOME/rpi/qt-5.15.0-rpi -hostprefix $HOME/rpi/tools -make libs -no-use-gold-linker -skip qtwayland -skip qtlocation -skip qtscript -v -no-gbm -ssl