1. 环境准备与工具链配置在开始QT6.6.0的交叉编译之前我们需要确保开发环境和工具链准备就绪。i.MX6ULL开发板采用ARM Cortex-A7架构因此需要对应的交叉编译工具链。这里我推荐使用gcc-linaro-14.0.0这是经过验证的稳定版本。首先下载并安装工具链wget https://releases.linaro.org/components/toolchain/binaries/14.0.0-2023.06/arm-linux-gnueabihf/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf.tar.xz sudo tar -xvf gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf.tar.xz -C /usr/local/arm/安装完成后需要配置环境变量以便系统能够找到交叉编译器echo export PATH$PATH:/usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin ~/.bashrc source ~/.bashrc验证工具链是否安装成功arm-linux-gnueabihf-gcc --version如果看到类似gcc version 14.0.0的输出说明工具链已经正确安装。接下来需要准备QT6.6.0的源代码wget https://download.qt.io/official_releases/qt/6.6/6.6.0/single/qt-everywhere-src-6.6.0.tar.xz tar -xvf qt-everywhere-src-6.6.0.tar.xz2. 编写CMake工具链文件交叉编译的核心是正确配置工具链文件。我们需要创建一个toolchain.cmake文件告诉CMake如何使用我们的交叉编译工具链。# toolchain.cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(CROSS_COMPILER /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf) set(CMAKE_C_COMPILER ${CROSS_COMPILER}-gcc) set(CMAKE_CXX_COMPILER ${CROSS_COMPILER}-g) set(CMAKE_SYSROOT /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc) set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -stdc17) # 标准路径设置 set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)这个文件做了几件重要的事情指定目标系统为Linux处理器架构为ARM设置交叉编译器的路径配置sysroot路径这是交叉编译时查找库和头文件的基础目录设置各种查找模式确保编译时能找到正确的库和头文件3. 配置QT的mkspecsQT使用mkspecs文件来描述特定平台的编译配置。对于i.MX6ULL我们需要创建一个自定义的mkspecs文件。在qt-everywhere-src-6.6.0/mkspecs/devices/目录下创建linux-imx6ull-g目录并添加qmake.conf文件# qmake configuration for i.MX6ULL using Linux armv7 hard-float ABI include(../common/linux_device_pre.conf) QMAKE_CFLAGS -marcharmv7-a -mfpuneon -mfloat-abihard QMAKE_CXXFLAGS $$QMAKE_CFLAGS QMAKE_LFLAGS -static-libstdc QMAKE_CC /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc QMAKE_CXX /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g QMAKE_LINK /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g QMAKE_LINK_SHLIB /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g QMAKE_AR /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ar cqs QMAKE_OBJCOPY /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-objcopy QMAKE_STRIP /usr/local/arm/gcc-linaro-14.0.0-2023.06-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-strip QMAKE_INCDIR_POST \ $$[QT_SYSROOT]/usr/include \ $$[QT_SYSROOT]/usr/include/arm-linux-gnueabihf这个配置文件特别重要它指定了编译器标志-marcharmv7-a指定目标架构-mfpuneon启用NEON指令集-mfloat-abihard使用硬件浮点各种工具链程序的路径额外的头文件搜索路径4. 执行QT6.6.0的交叉编译现在我们可以开始实际的编译过程了。首先创建一个构建目录并进入mkdir qt6-build cd qt6-build然后运行CMake配置命令sudo cmake /path/to/qt-everywhere-src-6.6.0 \ -GNinja \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_TOOLCHAIN_FILE/path/to/toolchain.cmake \ -DCMAKE_INSTALL_PREFIX/path/to/qt_arm \ -DCMAKE_STAGING_PREFIX/path/to/qt_arm \ -DQT_HOST_PATH/path/to/qt6-host \ -DQT_QMAKE_TARGET_MKSPECdevices/linux-imx6ull-g \ -DQT_QPA_PLATFORMlinuxfb \ -DFEATURE_openglOFF \ -DINPUT_openglno \ -DFEATURE_xcbOFF \ -DFEATURE_tslibOFF \ -DINPUT_tslibno \ -DFEATURE_graphsOFF \ -DINPUT_graphsno \ -DBUILD_qtgraphsOFF \ -DQT_BUILD_EXAMPLESOFF \ -DQT_BUILD_TESTSOFF \ -DQT_FEATURE_brotliOFF这里有几个关键参数需要注意-GNinja使用Ninja作为构建系统比make更快-DCMAKE_TOOLCHAIN_FILE指定我们之前创建的工具链文件-DQT_QMAKE_TARGET_MKSPEC指定我们创建的i.MX6ULL mkspecs-DQT_QPA_PLATFORMlinuxfb指定使用Linux帧缓冲作为显示后端各种FEATURE_*选项根据实际需求关闭不需要的功能可以减小最终生成的库大小配置完成后清理可能的缓存文件sudo rm -rf CMakeCache.txt CMakeFiles/ cmake_install.cmake Makefile qtbase/CMakeFiles qtbase/CMakeCache.txt qtbase/Makefile然后开始构建sudo cmake --build . --parallel 8这里的--parallel 8表示使用8个线程并行编译可以根据你的CPU核心数调整。构建完成后安装sudo cmake --install .5. 部署到i.MX6ULL开发板编译完成后我们需要将生成的QT库部署到开发板上。首先将安装目录/path/to/qt_arm打包tar -czvf qt_arm.tar.gz /path/to/qt_arm然后将压缩包复制到开发板上并解压scp qt_arm.tar.gz root开发板IP:/opt ssh root开发板IP tar -xzvf /opt/qt_arm.tar.gz -C /opt在开发板上设置环境变量echo export QT_QPA_PLATFORMlinuxfb /etc/profile echo export QT_QPA_FB_DRM1 /etc/profile echo export LD_LIBRARY_PATH/opt/qt_arm/lib:$LD_LIBRARY_PATH /etc/profile source /etc/profile测试QT应用程序/opt/qt_arm/bin/qtdemo如果一切正常你应该能在开发板的屏幕上看到QT的演示程序。6. 常见问题与解决方案在实际操作中可能会遇到各种问题。这里分享几个我遇到过的典型问题及解决方法问题1编译时找不到交叉编译器解决方法检查工具链路径是否正确确保环境变量已设置并生效。可以尝试直接运行arm-linux-gnueabihf-gcc --version测试。问题2链接时找不到库解决方法检查CMAKE_SYSROOT设置是否正确确保交叉编译器的库路径包含在查找路径中。问题3运行时报错找不到Qt平台插件解决方法确保QT_QPA_PLATFORM环境变量设置正确并且平台插件存在于/opt/qt_arm/plugins/platforms/目录下。问题4应用程序运行缓慢解决方法检查是否启用了硬件加速确保在mkspecs中正确配置了NEON指令集和硬件浮点。问题5触摸屏不工作解决方法可能需要配置tslib或直接使用QT的evdev输入插件设置环境变量QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS。7. 优化建议经过多次实践我发现以下几个优化点可以显著提升开发体验使用ccache加速编译安装ccache并设置环境变量export CCACHE_DIR/path/to/ccache和export CCccache gcc可以缓存编译结果大幅减少重复编译时间。选择性编译模块QT6非常庞大如果只需要部分功能可以通过-DBUILD_qt*OFF选项关闭不需要的模块节省编译时间和存储空间。使用strip减小体积部署前使用arm-linux-gnueabihf-strip处理可执行文件可以显著减小文件大小。静态链接标准库在mkspecs中添加QMAKE_LFLAGS -static-libstdc可以避免依赖目标板上的标准库版本。交叉编译应用使用编译好的qmake可以方便地交叉编译自己的QT应用程序/opt/qt_arm/bin/qmake -makefile make