上海珠宝网站建设,网页设计旅游网站,制作书签教案,wordpress讨论区1. 为什么要在RK3588上搭建Qt交叉编译环境#xff1f; 如果你手头有一块瑞芯微的RK3588开发板#xff0c;想用它来跑一个自己写的图形界面程序#xff0c;比如一个智能家居的控制面板#xff0c;或者一个工业设备的监控界面#xff0c;你可能会直接想到在开发板的Linux系统…1. 为什么要在RK3588上搭建Qt交叉编译环境如果你手头有一块瑞芯微的RK3588开发板想用它来跑一个自己写的图形界面程序比如一个智能家居的控制面板或者一个工业设备的监控界面你可能会直接想到在开发板的Linux系统里装个Qt然后像在电脑上一样编译运行。但实际操作过你就会发现这条路走不通。RK3588的CPU是ARM架构的而我们日常用的电脑无论是Windows还是Ubuntu基本都是x86架构。这就好比一个是说中文的大脑一个是说英文的大脑你直接用电脑编译出来的程序说英文的指令RK3588中文大脑根本听不懂无法执行。所以我们需要一个“翻译官”这个翻译官就是交叉编译工具链。它的作用是在你的x86电脑上模拟出ARM CPU的环境让你能用电脑的算力编译出ARM架构能直接运行的Qt程序。这个过程就叫做交叉编译。搭建好这个环境意味着你可以在性能强大的开发机上快速编译、调试然后把最终的可执行文件拷贝到RK3588上直接运行效率提升不是一点半点。我自己在多个嵌入式项目里都这么干实测下来开发体验和效率比直接在板卡上编译要舒服太多了。那么这个环境具体包含哪些东西呢简单来说你需要三样核心“食材”一个Linux开发环境通常是Ubuntu、目标版本的Qt源码、以及针对RK3588的交叉编译工具链。接下来我就带你一步步把这些“食材”备齐然后“炒”出一套能用的交叉编译环境。我会尽量把每一步的原理和可能遇到的“坑”都讲清楚让你不仅能照着做成功还能明白为什么这么做。2. 前期准备打造坚实的开发基础工欲善其事必先利其器。在开始动手编译之前我们需要把基础环境搭建好。这一步看似简单但却是后续所有操作的地基地基不稳后面楼盖得再高也容易塌。2.1 安装Ubuntu 20.04 LTS虚拟机为什么是Ubuntu 20.04首先LTS长期支持版本意味着系统稳定社区支持好遇到问题容易找到解决方案。其次很多嵌入式编译工具链和教程都是基于这个版本测试的兼容性最有保障。我试过在更新的22.04上搞有时会遇到一些依赖库版本冲突的问题对新手不太友好。安装方式强烈建议使用虚拟机。VirtualBox和VMware Workstation Player个人版免费都是不错的选择。用虚拟机的好处是环境隔离玩坏了可以快速回滚到快照不会影响你主机的系统。分配资源时建议给虚拟机至少4核CPU、8GB内存、80GB硬盘空间。编译Qt是个吃资源的大户配置给足了能节省大量时间。系统设置安装完成后第一件事是换源。默认的软件源可能在国外下载速度慢。换成国内的镜像源比如阿里云或清华大学的源速度会快很多。操作也简单在“软件和更新”里选择“其他站点”然后挑选一个即可。换完源后记得在终端里执行sudo apt update和sudo apt upgrade更新系统到最新状态。2.2 安装必要的系统依赖包这是非常关键的一步很多编译错误都是因为缺少某个开发库导致的。我们需要安装编译Qt和工具链所需的一系列基础软件包。打开终端一次性执行下面这条命令sudo apt install -y build-essential cmake git flex bison gperf libxcb* libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev libfontconfig1-dev libfreetype6-dev libpng-dev libjpeg-dev libsqlite3-dev libssl-dev libpcre2-dev libz-dev libbz2-dev libicu-dev libdouble-conversion-dev libcups2-dev libpulse-dev libwayland-dev libxext-dev libxfixes-dev libxrandr-dev libxcomposite-dev libxdamage-dev libxinerama-dev libxcursor-dev libxi-dev libnss3-dev libdbus-1-dev libatspi2.0-dev libasound2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev这条命令看起来很长它实际上是在安装编译器gcc, g、构建工具cmake, make、版本控制git以及Qt图形界面所依赖的X11、OpenGL、音频、多媒体等一系列库文件。放心执行它会自动处理所有依赖关系。安装过程可能需要一些时间取决于你的网速。3. 获取核心“食材”工具链与Qt源码基础系统准备好了现在要来准备我们最核心的编译材料了。这里有两个主角针对RK3588的交叉编译工具链以及Qt的源代码。3.1 获取RK3588交叉编译工具链RK3588的CPU是ARMv8-A架构的64位处理器Cortex-A55/A76。瑞芯微官方通常会提供对应的交叉编译工具链。你可以尝试在瑞芯微的开发者网站或相关的SDK发布页面寻找名称可能类似于gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu。这个工具链包含了能在x86机器上运行的编译器aarch64-linux-gnu-gcc、链接器、库文件等但它们生成的目标代码是给ARMv8aarch64架构的。如果你一时找不到官方最新的网络上也有一些经过验证可用的版本。请注意从非官方渠道获取任何工具链时务必注意安全性。假设你下载到的工具链压缩包叫gcc-linaro-7.5.0.tar.xz。我们将其解压到系统的一个固定目录比如/optsudo tar -xvf gcc-linaro-7.5.0.tar.xz -C /opt解压后工具链的路径大概是/opt/gcc-linaro-7.5.0/bin。为了能在终端里直接使用这个工具链的命令我们需要将其添加到系统的PATH环境变量中。编辑用户主目录下的.bashrc文件nano ~/.bashrc在文件末尾添加一行export PATH/opt/gcc-linaro-7.5.0/bin:$PATH保存退出后执行source ~/.bashrc让配置生效。现在你可以在终端里输入aarch64-linux-gnu-gcc --version来测试工具链是否安装成功如果能看到编译器的版本信息那就恭喜你第一步成功了。3.2 下载Qt 5.14.2源码为什么选择Qt 5.14.2这是一个长期支持版本LTS在稳定性和功能上达到了一个很好的平衡社区资源丰富很多嵌入式项目都在用。我们选择从源码编译而不是安装预编译包是因为我们需要针对我们的ARM架构和特定的交叉编译工具链进行定制确保生成的库文件能在RK3588上完美运行。你可以从Qt的官方存档站点或者国内的镜像站下载。这里以清华镜像为例找到qt-everywhere-src-5.14.2.tar.xz这个源码包。下载命令如下wget https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.tar.xz下载完成后将其解压到一个工作目录比如~/qt-buildmkdir -p ~/qt-build tar -xvf qt-everywhere-src-5.14.2.tar.xz -C ~/qt-build/解压后的源码目录结构非常庞大包含了Qt所有的模块。我们接下来的所有操作都将在这个源码目录的“影子构建shadow build”目录中进行。所谓影子构建就是在源码目录外另建一个目录进行编译这样保持源码目录的干净方便多次尝试不同的配置。4. 配置与编译核心攻坚战食材备齐厨房系统也收拾好了现在开始最关键的一步配置编译选项并执行编译。这一步就像炒菜的火候和调料搭配直接决定了最终成品的味道。4.1 创建编译配置脚本进入Qt源码目录我们先创建一个用于配置的脚本文件比如叫configure.sh。这样做的好处是如果编译中途出错需要重新配置我们不需要再手动输入一长串复杂的参数。cd ~/qt-build/qt-everywhere-src-5.14.2 nano configure.sh将以下内容写入configure.sh脚本中。请注意以下路径需要根据你实际的工具链安装位置进行调整#!/bin/bash ./configure \ -prefix /opt/qt-5.14.2-arm64 \ # 指定Qt的安装目录 -confirm-license \ -opensource \ -release \ # 发布模式优化性能 -shared \ # 编译为动态库 -xplatform linux-aarch64-gnu-g \ # 指定目标平台为ARM64 -linuxfb \ # 使用Linux帧缓冲驱动这是嵌入式设备最常用的显示后端 -no-opengl \ -no-xcb \ # 禁用X11相关因为我们用帧缓冲 -no-pch \ # 禁用预编译头避免兼容性问题 -no-use-gold-linker \ -nomake examples \ # 不编译示例节省时间 -nomake tests \ # 不编译测试 -skip qt3d \ # 跳过3D模块减少编译量和潜在错误 -skip qtquick3d \ -skip qtdoc \ -no-glib \ -no-cups \ -no-iconv \ -no-evdev \ -no-tslib \ -no-icu \ -no-fontconfig \ -no-dbus \ -no-openssl \ -no-gif \ -no-libjpeg \ -no-libpng \ -no-compile-examples \ -sysroot /opt/sysroot \ # 指定目标系统的根文件系统如果准备了的话 -I /opt/gcc-linaro-7.5.0/aarch64-linux-gnu/include \ -L /opt/gcc-linaro-7.5.0/aarch64-linux-gnu/lib这个配置脚本做了很多事情我挑几个关键的解释一下-prefix 这是编译后Qt库的安装路径。我们把它安装到/opt/qt-5.14.2-arm64方便管理。-xplatform 这是告诉Qt构建系统我们要为目标平台使用哪个mkspec编译规范。我们需要在Qt源码的qtbase/mkspecs目录下找到或创建一个对应的。通常工具链会提供模板。最直接的方法是复制linux-arm-gnueabi-g这个目录重命名为linux-aarch64-gnu-g然后修改里面的qmake.conf文件将编译器路径改为我们自己的aarch64-linux-gnu-g。-linuxfb和-no-xcb 对于没有桌面环境的嵌入式设备我们通常使用Linux的帧缓冲Framebuffer作为显示输出所以启用-linuxfb并禁用X11相关的-xcb。大量的-skip和-no选项 这是为了精简Qt库。嵌入式设备资源有限我们只编译需要的模块。跳过像qt3d、qtquick3d这些大型的、用不到的模块可以极大缩短编译时间并减少出错概率。4.2 处理平台编译规范mkspec正如上面提到的-xplatform参数指向的mkspec需要我们自己准备。这是一个关键步骤。进入qtbase/mkspecs目录cd qtbase/mkspecs cp -r linux-arm-gnueabi-g linux-aarch64-gnu-g cd linux-aarch64-gnu-g nano qmake.conf修改qmake.conf文件核心是修改编译器的定义。将其内容修改为类似下面这样# # qmake configuration for building with aarch64-linux-gnu-g # MAKEFILE_GENERATOR UNIX CONFIG incremental QMAKE_INCREMENTAL_STYLE sublib include(../common/linux.conf) include(../common/gcc-base-unix.conf) include(../common/g-unix.conf) # modifications to g.conf QMAKE_CC aarch64-linux-gnu-gcc QMAKE_CXX aarch64-linux-gnu-g QMAKE_LINK aarch64-linux-gnu-g QMAKE_LINK_SHLIB aarch64-linux-gnu-g # modifications to linux.conf QMAKE_AR aarch64-linux-gnu-ar cqs QMAKE_OBJCOPY aarch64-linux-gnu-objcopy QMAKE_NM aarch64-linux-gnu-nm -P QMAKE_STRIP aarch64-linux-gnu-strip load(qt_config)保存退出。这样Qt的构建系统就知道该调用我们工具链里的编译器了。4.3 执行编译与安装配置脚本准备好mkspec也修改好后我们就可以开始编译了。首先给配置脚本加上执行权限并运行chmod x configure.sh ./configure.sh这个过程会检查系统环境、工具链并生成Makefile。如果一切顺利你会看到一大串输出最后提示Qt is now configured for building。接下来就是最耗时的编译环节。使用make命令并加上-j参数来指定并行编译的作业数这能充分利用你电脑的多核性能显著加快速度。比如你的CPU有8个逻辑核心可以这样make -j8然后泡杯咖啡等待一段时间根据电脑性能可能从半小时到数小时不等。编译完成后执行安装命令sudo make install这会将编译好的Qt库、头文件、工具如qmake安装到之前-prefix指定的目录/opt/qt-5.14.2-arm64中。这个目录下的bin文件夹里会有一个非常重要的工具qmake。这个qmake是专门为交叉编译生成的它会在后续编译你的Qt应用程序时自动使用正确的交叉编译工具链。5. 常见错误与排坑指南编译这么庞大的工程不出错几乎是不可能的。下面我分享几个我踩过的坑以及解决办法希望能帮你节省大量折腾的时间。5.1 错误Project ERROR: Unknown module(s) in QT: openglextensions这个错误通常出现在配置阶段。错误信息说找不到openglextensions模块但它可能间接由其他模块如qt3d依赖引起。在嵌入式配置中我们往往不需要OpenGL ES 2.0以上的扩展功能。解决方法就像原始文章提到的最直接有效的方法是在配置时跳过引发问题的模块。在configure.sh脚本中我们已经添加了-skip qt3d和-skip qtquick3d。如果还出现类似问题可以检查错误日志看看是哪个模块报的错然后尝试用-skip 模块名将其跳过。这是一种“抓大放小”的策略先保证核心的qtbase包含GUI、Widgets等能编译通过。5.2 错误qconfig.cpp中的语法错误右单引号换行这是一个比较经典的源码与编译器兼容性问题。在某些版本的GCC下qtbase/src/corelib/global/qconfig.cpp文件里有一行代码的字符串字面量被意外换行了导致编译器认为语法错误。解决方法找到编译构建目录shadow build目录下的这个文件。路径类似于~/qt-build/build/qtbase/src/corelib/global/qconfig.cpp。用编辑器打开它找到报错的那一行通常是一个很长的字符串你会发现一个右单引号被单独放在了下一行。就像原始文章里说的手动编辑这个文件将这个右单引号移回上一行的末尾确保字符串被正确闭合。保存文件后重新执行make即可。5.3 错误缺少-fPIC相关错误或链接失败这类错误通常表现为链接阶段报错提示某些.o文件或库文件在重定位时有问题。根本原因是编译位置无关代码PIC的选项没设置好。解决方法确保你的交叉编译工具链是支持PIC的。此外可以在configure.sh的编译器标志中显式添加-fPIC。更常见的做法是在之前修改的qmake.conf文件里在QMAKE_CFLAGS和QMAKE_CXXFLAGS后面加上-fPIC。例如QMAKE_CFLAGS -fPIC QMAKE_CXXFLAGS -fPIC5.4 编译过程因内存不足被杀死编译Qt尤其是并行编译时对内存消耗极大。如果你在虚拟机里只分配了2GB或4GB内存很可能在编译某个大模块如WebEngine时系统因内存不足OOM而杀死编译进程。解决方法最根本的方法是给虚拟机分配更多内存8GB是推荐的起步配置。如果硬件条件有限可以降低并行编译的线程数比如用make -j2虽然慢点但更稳定。另外就是严格执行精简配置用-skip跳过所有非必要的模块。6. 查漏补缺单独编译缺失的模块有时候我们一开始为了求快跳过了很多模块比如-skip qtwebsockets但后来项目又需要用到这个模块的功能了。难道要重新编译整个Qt吗不需要。Qt支持模块的单独编译。假设我们现在需要QtWebSockets模块。首先确保你的主Qt库即之前编译安装的/opt/qt-5.14.2-arm64已经存在。进入模块源码目录cd ~/qt-build/qt-everywhere-src-5.14.2/qtwebsockets使用交叉编译版的qmake生成Makefile 关键点来了这里必须使用我们刚刚编译安装好的、那个针对ARM平台的qmake。/opt/qt-5.14.2-arm64/bin/qmake .这条命令会读取当前目录的.pro文件并根据我们交叉编译Qt时的配置生成适用于交叉编译的Makefile。编译和安装make -j4 sudo make install编译完成后执行make install这个模块的库文件就会被安装到/opt/qt-5.14.2-arm64目录下相应的位置与主Qt库集成在一起。这种方法非常灵活你可以按需编译任何之前跳过的模块如QtSerialPort、QtMqtt等极大地提升了开发效率。7. 验证与使用让第一个程序在板子上跑起来环境搭建好了库也编译完了是时候验收成果了。我们写一个最简单的“Hello World” Qt程序来测试。在你的开发机Ubuntu虚拟机上创建一个测试目录比如~/test_hello然后创建两个文件main.cpp:#include QApplication #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label(Hello from RK3588 Qt Cross-Compile!); label.show(); return app.exec(); }test_hello.pro(Qt项目文件):QT core gui widgets TARGET test_hello TEMPLATE app SOURCES main.cpp接下来使用交叉编译版的qmake来生成Makefile并编译cd ~/test_hello /opt/qt-5.14.2-arm64/bin/qmake . make如果编译成功你会生成一个名为test_hello的可执行文件。但是请注意这个文件不能在开发机的x86系统上运行用file命令查看一下它的属性file test_hello输出应该是test_hello: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked ...这确认了它是一个ARM64架构的程序。最后一步将这个test_hello文件以及它依赖的Qt库位于/opt/qt-5.14.2-arm64/lib中主要是libQt5Core.so.5,libQt5Gui.so.5,libQt5Widgets.so.5等通过SD卡、scp或NFS等方式拷贝到你的RK3588开发板上。在开发板的终端里确保程序有执行权限 (chmod x test_hello)并设置好库路径例如export LD_LIBRARY_PATH/path/to/your/qt/lib:$LD_LIBRARY_PATH然后运行./test_hello。当那个写着“Hello from RK3588 Qt Cross-Compile!”的窗口在开发板的屏幕或通过帧缓冲上弹出来时那一刻的成就感会让你觉得之前所有的折腾都是值得的。这套环境一旦搭建成功就会成为你开发RK3588图形应用的利器后续的开发、调试、部署效率都会成倍提升。