如何在Windows上开发Linux ARM版本QT程序
背景
当我们谈及Linux ARM的嵌入式开发时,通常都是在Windows上安装Linux虚拟机,然后在虚拟机上安装QT开发环境和交叉编译链,但是这样做的缺点是虚拟机的性能通常不是很好,开发效率也不高,而且还会占用比较多的系统资源。
解决思路
为了解决这个问题,我们可以在Windows上直接安装QT开发环境和交叉编译链,然后在Windows上直接编译ARM版本的QT程序。
难点分析
- 如何在Windows上编译arm linux程序
- 如何在Windows上编译arm linux版本QT
- 如何解决复杂的linux依赖库问题
解决方法
下载交叉编译器
- 我们可以从Linaro官网下载适用于Windows的交叉编译链,地址为:https://releases.linaro.org/components/toolchain/binaries/
- 根据目标板上的glibc版本和c++版本,选择对应版本的编译链,可以比目标板上的版本低一点,但是不要比目标板上的版本高,比如对于glibc 2.17和c++ 4.9,我们可以下载4.9.4版本的编译链。
- 根据目标板的处理器架构,选择对应的架构分支,比如:针对ARM v7架构的目标板,我们可以选择arm-linux-gnueabihf分支。
- 最后,根据开发的环境,选择对应的编译链二进制文件,因为我们是在Windows上开发,所以需要选择"gcc-linaro-4.9.4-2017.01-i686-mingw32_arm-linux-gnueabihf.tar.xz"下载
怎么理解这个编译链的名字
gcc-linaro-4.9.4-2017.01-i686-mingw32_arm-linux-gnueabihf.tar.xz
1. gcc
- 含义: GNU Compiler Collection,即 GNU 编译器套件。这是该压缩包的核心内容,包含了 C、C++ 等语言的编译器。
2. linaro
- 含义: 提供该工具链的组织名称。Linaro 是一个非营利性工程组织,由多家 ARM 领域的公司(如 ARM、Qualcomm、Samsung 等)联合创立,专门负责优化和开发 ARM 架构上的开源软件。以 "linaro" 开头的工具链通常对 ARM 处理器有良好的支持和优化。
3. 4.9.4
- 含义: GCC 编译器的版本号。这里是 4.9.4 版本。这是一个相对较旧的稳定版本。
4. 2017.01
- 含义 : Linaro 工具链的发布版本号。这通常以
年.月的格式表示,意味着这个工具链是在 2017 年 1 月由 Linaro 发布或构建的。
5. i686
- 含义 : 宿主系统架构 。这指明了这个交叉编译器运行在 什么样的计算机上。
i686指的是 Intel/AMD 的 32 位 x86 架构,大致对应 Pentium Pro 及以上的 CPU。所以这个编译器需要在 32 位的 Windows 上运行。
6. mingw32
- 含义 : 宿主系统环境 。这指明了这个交叉编译器是构建给哪个操作系统使用的。
mingw32是一个让 GNU 工具链(如 GCC)在 32 位 Windows 系统上原生运行的环境,而无需 Cygwin。所以,这个工具链本身是一个 Windows 上的可执行程序。
小结 (i686-mingw32) : 这两个字段合起来定义了 "在什么机器上运行" 。即:在一个 32 位的 Windows 操作系统上运行。
7. arm-linux-gnueabihf
- 含义 : 目标系统架构和ABI 。这指明了这个编译器生成的代码是给什么设备运行的 。这是交叉编译的精髓。
arm: 目标 CPU 架构是 ARM。linux: 目标设备运行的操作系统是 Linux。gnueabihf: 定义了使用的 ABI 。gnu: 使用 GNU libc(glibc)作为 C 库。eabi: 嵌入式应用二进制接口,规定了函数调用约定、文件格式等。hf: 硬浮点。这非常重要,它表示编译器会使用 ARM 芯片内置的硬件浮点运算单元来生成代码,而不是用效率低下的软件模拟。这要求目标 ARM 设备必须支持硬件浮点运算(通常是有 VFP 或 NEON 单元的 Cortex-A 系列处理器)。
小结 (arm-linux-gnueabihf) : 这两个字段合起来定义了 "编译出来的程序跑在什么机器上" 。即:编译出的程序是给运行 Linux 系统、带有硬件浮点单元的 ARM 设备使用的。
总结
这个文件名完整地描述了:
这是一个由 Linaro 于 2017 年 1 月发布的,基于 GCC 4.9.4 版本构建的交叉编译工具链。它本身是一个 32 位的 Windows 程序,用于在 Windows 电脑上编译出能在运行 Linux 的、带有硬件浮点单元的 ARM 设备上执行的程序。
通俗比喻 : 这是一个在 "Windows 工厂" 里使用的 "ARM-Linux 产品制造工具"。
安装交叉编译链
- 选择一个支持linux符号链接的解压工具,比如7-Zip,然后开启Windows的开发者模式。
- 解压下载的压缩包到一个目录,比如
C:\arm-linux-gnueabihf。 - 将解压后的目录添加到系统环境变量
PATH中,比如C:\arm-linux-gnueabihf\bin。 - 打开一个新的命令提示符窗口,输入
arm-linux-gnueabihf-gcc -v,如果能看到版本信息,说明安装成功。
编译测试
使用arm交叉编译器编译简单的helloWorld验证功能
- 创建一个新的文本文件,命名为
helloWorld.c,并在其中输入以下内容:
c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
- 打开一个新的命令提示符窗口,切换到
helloWorld.c所在的目录。 - 输入以下命令编译
helloWorld.c:
bash
arm-linux-gnueabihf-gcc -o helloWorld helloWorld.c
- 如果编译成功,会在当前目录生成一个名为
helloWorld的可执行文件。 - 将
helloWorld文件复制到运行 Linux 的 ARM 设备上。 - 在 ARM 设备上运行
helloWorld,如果能看到输出Hello, World!,说明交叉编译成功。
如何编译QT
下载QT源码
这里以QT5.X为例
-
在这里可以下载QT5.X的源码
-
注意:更新的QT可能需要更新的编译链,如何在上面的步骤中选择的是"gcc-linaro-4.9.4-2017.01-i686-mingw32_arm-linux-gnueabihf.tar.xz",那么,建议选择Qt5.7及以下的版本。
-
解压下载的QT源码到一个目录,比如
C:\qt5。 -
打开一个新的命令提示符窗口,切换到
C:\qt5目录。 -
新建build目录
bash
mkdir build
cd build
- 打开一个新的PowerShell窗口,切换到
C:\qt5\build目录。 - 在PowerShell窗口中输入以下命令配置编译:
bash
. ..\source\configure.bat -release -opensource -prefix "E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6" -extprefix "E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6" -nomake tests -nomake examples -no-opengl -skip qtvirtualkeyboard -xplatform linux-arm-gnueabihf-g++ -c++std c++11
解释一下这个配置命令
命令结构
..\source\configure.bat
执行位于上一级目录的source文件夹中的 Qt 配置脚本。
主要参数解析
-
-release编译 Release 版本 的 Qt 库(去除了调试信息,优化性能)。
-
-opensource选择 开源版本 的 Qt(对应 GPL/LGPL 许可证)。
-
-prefix与-extprefix-prefix "E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6"
指定 Qt 在 目标设备(ARM Linux) 上的安装路径。-extprefix "E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6"
指定 Qt 编译结果在 主机(Windows) 上的存放路径,便于后续部署到目标设备。
-
-nomake tests与-nomake examples不编译测试程序和示例代码,加快编译速度。
-
-no-opengl禁用 OpenGL 支持(可能是目标平台不支持或不需要)。
-
-skip qtvirtualkeyboard跳过编译虚拟键盘模块(减少编译时间和库体积)。
-
-xplatform linux-arm-gnueabihf-g++- 指定交叉编译的目标平台为 ARM Linux(硬浮点版本)。
- 使用对应的工具链
arm-linux-gnueabihf-g++。
错误排除
报错C++11相关
bash
`-c++std c++11`
启用 C++11 标准支持。
报错找不到 "rm、cp、mkdir"等命令
安装MSYS2,并在MSYS2中安装必要的工具,比如rm、cp、mkdir等,然后把这些工具的路径添加到系统环境变量PATH中。
如果需要支持QML以及openssl等功能
需要添加opengl以支持QML,需要指定ssl库以支持ssl
- 指定sysroot,这里我使用yocto的编译链
bash
-sysroot "E:\windows_qt_cross_compilers\fsl-imx-x11\4.1.15-2.1.0\sysroots\cortexa7hf-neon-poky-linux-gnueabi"
然后添加如下选项启用opengl和ssl的支持
bash
-opengl es2
-openssl-linked OPENSSL_LIBS="-lssl -lcrypto"
注意:如果你没有开发板的sysroot或者sysroot中缺少opengl和ssl的库,有以下解决方法
-
尝试从其他途径获取opengl和ssl的库,比如从源码编译或者联系供应商。
-
升级到更新版本的QT,可能支持软件opengl。
-
完整的配置命令
bash
. ..\source\configure.bat -release -opensource -prefix "E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6" -extprefix "E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6" -nomake tests -nomake examples -opengl es2 -skip qtvirtualkeyboard -xplatform linux-arm-gnueabihf-g++ -sysroot "E:\windows_qt_cross_compilers\fsl-imx-x11\4.1.15-2.1.0\sysroots\cortexa7hf-neon-poky-linux-gnueabi" -c++std c++11 -openssl-linked OPENSSL_LIBS="-lssl -lcrypto"
-
等待配置完成后,如果没有报错,说明配置成功。(如果有报错,根据报错信息进行排查)
-
编译QT
bash
mingw32-make -j4
- 安装QT
bash
mingw32-make install
测试QT
查看编译出来的QT版本
- 打开一个新的命令提示符窗口,切换到
E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6\bin目录。 - 输入以下命令查看QT版本:
bash
qmake -v
-
如果能看到输出类似以下内容,说明QT编译成功:
QMake version 3.1
Using Qt version 5.7.0 in E:\windows_qt_cross_compilers\qt5.7_arm_linux_imx6\lib\cmake\Qt5
测试QML
- 新建一个QT项目,选择"Qt Quick Application"模板。
- 查看默认的代码上面是否有IntelliSense报错,如果提示无法找到QtQuick2相关的文件,多半是QtQuick没有被编译,可能是上面的编译过程中没有添加-opengl es2选项。
- 尝试编译qml程序,如果有报错,要根据报错信息进行排查。