说明
[QT6.5](Qt 6.5 Release - Qt Wiki) 是目前(2023.4.23)最新的LTS版本,整体构建基础也和QT5不同,由原来的qmake迁移到了更通用和流行的CMake上,所以新版本的交叉编译等都有一定的变化,本文主要针对其中的不同进行一个简单记录,并以一个简单的程序为例来进行说明。
环境准备
- QT6.5
由于要交叉编译,安装是将源码也同时安装
这里的安装是必要的,因为QT6.5的交叉编译需要依托宿主机已编译安装好的QT6.5
cmake 的版本 需要 3.16 或者更高, 最好是稳定版
ninja没得特定要求,推荐1.11.1或更高
python版本需要 3 以上
- 交叉编译工具链
这是交叉编译必不可少的部分
交叉编译工具链
根据编译的目标平台系统进行选择
Distribution | Architecture | Compiler |
---|---|---|
Red Hat 8.4 | x86_64 | GCC 10 (toolset) |
Red Hat 9.0 | x86_64 | GCC 11 |
openSUSE 15.4 | x86_64 | GCC 9 |
SUSE Linux Enterprise Server 15 SP4 | x86_64 | GCC 10 |
Ubuntu 22.04 | x86_64 | GCC as provided by Canonical, GCC 11.x |
根据目标平台确认GCC的版本要求,然后下载想要的工具链
Linaro是一个很好的选择,但是由于我们是windows平台,linaro并没有提供合适的编译工具链。所幸它同时给了Arm Developer的跳转链接,很轻松我们就能找到想要的内容。
这里我们以 gcc11 的 aarch64-none-linux-gnu 为例
-
到linaro的下载页面,并选择gnu工具链
-
页面锚点定位到gun工具链部分,Linaro 提供了gnu工具的集成构建,但其中并没有x64 windows的gcc11版
-
去到 Arm Developer website页面,这里可以看到有我们需要的windows宿主机的工具链,但是版本不对,我们查看更多
-
这里有更多的版本,我们选择需要的版本
-
选择windows宿主机,aarch64的 linux 目标版本,下载解压即可。
交叉编译
- toolchain
cmake 本身提供 toolchain的交叉编译配置,这里我们简单配置一个toolchain
# 设置目标系统、处理器架构
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
# 设置工具链目录
set(TOOL_CHAIN_DIR $ENV{CPP_TOOLCHAIN_ARM_LINUX})
set(TOOL_CHAIN_INCLUDE ${TOOL_CHAIN_DIR}/aarch64-none-linux-gnu/include ${TOOL_CHAIN_DIR}/aarch64-none-linux-gnu/libc/usr/include)
set(TOOL_CHAIN_LIB ${TOOL_CHAIN_DIR}/aarch64-none-linux-gnu/lib ${TOOL_CHAIN_DIR}/aarch64-none-linux-gnu/libc/usr/lib)
# 设置编译器位置
set(CMAKE_C_COMPILER ${TOOL_CHAIN_DIR}/bin/aarch64-none-linux-gnu-gcc.exe)
set(CMAKE_CXX_COMPILER ${TOOL_CHAIN_DIR}/bin/aarch64-none-linux-gnu-g++.exe)
# 设置cmake查找主路径
set(CMAKE_FIND_ROOT_PATH ${TOOL_CHAIN_DIR}/aarch64-none-linux-gnu)
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)
# 包含工具链文件
include_directories(
${TOOL_CHAIN_DIR}/aarch64-none-linux-gnu/include
${TOOL_CHAIN_DIR}/aarch64-none-linux-gnu/libc/usr/include)
# 设置CMAKE_INCLUDE_PATH
set(CMAKE_INCLUDE_PATH ${TOOL_CHAIN_INCLUDE})
# 设置CMAKE_LIBRARY_PATH
set(CMAKE_LIBRARY_PATH ${TOOL_CHAIN_LIB})
其中 $ENV{CPP_TOOLCHAIN_ARM_LINUX}
是使用了环境变量 CPP_TOOLCHAIN_ARM_LINUX
,这里可以不必像笔者一样麻烦,直接使用之前 交叉编译工具链的文件位置就好
- configure
进入到 QT6.5 的源码位置, 即QT6.5安装目录下的Src目录下,这里为了好处理我们新建个build文件夹,进入并打开终端,执行 configure 命令进行配置,这里我们以 QT6.5的新模块 qthttpserver 为例
../configure -release -platform linux-aarch64-gnu-g++ -device linux-aarch64-gnu-g++ -no-pch -no-opengl -no-openssl -qt-sqlite -qt-zlib -qt-libjpeg -qt-libpng -qt-freetype -qt-pcre -qt-harfbuzz -submodules qthttpserver -qt-host-path $QT_HOME -prefix $INSTALL_PATH -- -DCMAKE_TOOLCHAIN_FILE=toolchain
QT6.5 不在有
xplatform
参数,device
参数也和QT5的含义不同
-no-pch
是不使用预编译
-no-opengl -no-openssl -qt-sqlite -qt-zlib -qt-libjpeg -qt-libpng -qt-freetype -qt-pcre -qt-harfbuzz
是一些第三方库配置,-qt
是指使用qt内置的三方库,-system
是指使用系统提供的库,参考如下:
Library Name Bundled in Qt Installed in System zlib -qt-zlib -system-zlib libjpeg -qt-libjpeg -system-libjpeg libpng -qt-libpng -system-libpng freetype -qt-freetype -system-freetype PCRE -qt-pcre -system-pcre HarfBuzz-NG -qt-harfbuzz -system-harfbuzz
-submodules
这是QT6.5编译一个重大亮点,再也不用像QT5一样写一大堆的skip
了,使用该参数则仅编译该参数指明的模块及其依赖的模块,而不是全部模块(这里指的是编译代码里出现的模块)。如果需要多个模块则使用逗号分隔, 例如-submodules qtsvg,qtnetworkauth
-skip
QT6.5 也是支持的,同时多个也是使用逗号分隔,例如-skip qtimageformats,qtsvg
-qt-host-path
这是重点, QT6.5的交叉编译,需要指定一个同版本的本地已安装的QT6.5路径,这也是开始说本地QT有必要安装的原因。这里$QT_HOME
换成相应的本地安装路径,比如C:\QT\6.5.0\mingw64
-prefix
没什么说的,编译后的安装路径,$INSTALL_PATH
自行设置, 例如D:\QT6_ARM_Linux
-- -DCMAKE_TOOLCHAIN_FILE=toolchain
指定cmake 参数CMAKE_TOOLCHAIN_FILE
,这里使用configure
进行配置,所有的cmake参数 都需要使用--
来进行传入 ;-DCMAKE_TOOLCHAIN_FILE=toolchain
是指明 cmake 的交叉编译配置文件,注意这个toolchain
文件的位置是相对configure
运行的位置也就是 QT6.5.0的源码位置,即开始说到的 Src目录下;放在其他位置自行修改就是。
- make && make install
配置完成后根据提示谁用 cmake --build . --parallel
进行并行编译即可,编译完成后使用cmake --install .
将会在之前指定prefix
位置安装编译好的文件