如何交叉编译qmake?能否为目标设备编译Qt5.9.2的qmake/moc/rcc/uic工具?
一、如何实现QMake的交叉编译?
要让QMake支持交叉编译,核心是给它指定目标平台的编译工具链和专属配置,具体步骤如下:
1. 准备交叉编译工具链
先确保你已经安装了目标平台对应的交叉编译工具链(比如针对ARM架构的arm-linux-gnueabihf-gcc、arm-linux-gnueabihf-g++),工具链路径要么添加到系统PATH环境变量,要么后续在配置里明确指定。2. 创建/修改Qt交叉编译配置文件
Qt源码的qtbase/mkspecs目录下存放着不同平台的编译模板。你可以复制一个现有配置目录(比如linux-g++),重命名为目标平台对应的名称(比如linux-arm-gnueabihf-g++),然后修改目录下的qmake.conf文件:- 将
QMAKE_CC、QMAKE_CXX、QMAKE_LINK等变量替换为交叉编译工具,例如: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++ - 根据目标平台的硬件特性,添加额外编译选项(比如ARM架构的
-march=armv7-a)。
- 将
3. 配置并编译Qt源码
进入Qt5.9.2源码根目录,运行configure脚本指定交叉编译参数:./configure -prefix /opt/qt5.9.2-arm \ -xplatform linux-arm-gnueabihf-g++ \ -device-option CROSS_COMPILE=arm-linux-gnueabihf- \ -nomake examples -nomake tests \ -release关键参数说明:
-prefix:指定交叉编译后Qt的安装路径;-xplatform:指定刚才修改的mkspec配置文件;-device-option CROSS_COMPILE:明确交叉编译工具的前缀;-nomake examples/tests:跳过示例和测试编译,节省时间;-release:编译发布版本的Qt库。
配置完成后,执行
make -j$(nproc)(多线程加速编译),再运行make install完成安装。4. 使用交叉编译的QMake
安装完成后,直接调用/opt/qt5.9.2-arm/bin/qmake即可编译目标平台的Qt项目,它会自动调用交叉工具链生成适配目标设备的程序。
二、能否为目标设备交叉编译qmake、moc、rcc、uic这些工具?
答案是可以,但先明确一个核心前提:默认交叉编译Qt时生成的这些工具是主机版本的——因为开发过程中,我们需要在主机上用这些工具处理源码(比如moc生成元对象代码、uic转换UI文件),所以Qt的构建系统会优先编译主机版本工具来支撑交叉编译流程。
如果确实需要目标设备版本的这些工具(比如要在嵌入式设备上直接开发、编译Qt程序),可以通过以下两种方式实现:
方法1:分两次编译
- 先编译主机版本的Qt工具:用主机编译器正常编译Qt(不加交叉参数),或者在
configure时加上-hostprefix /path/to/host-tools,单独安装主机工具。这一步生成的qmake、moc等将作为后续交叉编译的"引导工具"。 - 用主机版本的
qmake配置交叉编译:运行configure时指定目标平台参数,同时开启目标工具编译:
执行/path/to/host-tools/bin/qmake \ -spec linux-arm-gnueabihf-g++ \ CONFIG+=release \ PREFIX=/opt/qt5.9.2-arm \ QT_BUILD_TARGET_TOOLS=1make和make install后,会同时生成主机工具和目标工具(目标工具会安装到PREFIX/bin目录下)。
- 先编译主机版本的Qt工具:用主机编译器正常编译Qt(不加交叉参数),或者在
方法2:单独编译目标工具
如果你已经完成Qt的交叉编译,可以单独进入每个工具的源码目录(比如qtbase/src/tools/moc、qtbase/src/tools/uic),用交叉编译好的qmake生成Makefile后编译:cd qtbase/src/tools/moc /opt/qt5.9.2-arm/bin/qmake make -j$(nproc) # 将生成的moc拷贝到目标设备或指定目录
不过要提醒的是:绝大多数场景下不需要目标版本的这些工具。Qt项目的常规开发流程是在主机上完成预处理、编译,最后把二进制程序部署到目标设备运行,目标设备只需要Qt的运行库即可。
内容的提问来源于stack exchange,提问作者Fatih Erol

