環境:
主機平臺:Ubuntu22.04.5 x86_64
目標平臺:IMX8QM Ubuntu22.04.5 arm64
Qt版本:Qt6.5.3 LST
GUI實現:QML
一、獲取Ubuntu22.04.5 x86_64 系統鏡像文件
1、鏡像下載與安裝
使用國內鏡像下載對應版本的Ubuntu鏡像,我使用的是阿里云的鏡像
2、安裝虛擬機
3、安裝后的一些問題的解決
Ubuntu18.6 學習QT問題記錄以及虛擬機安裝Ubuntu后的設置
4、C/C++ 開發環境安裝
二、目標平臺安裝 Qt 6.5.3
1、下載在線安裝程序
在Qt 官網下載Qt在線安裝包,這里需要在官網注冊一個賬號,登陸后才可以下載,我下載Linux x64版本。
2、Ubuntu開啟ftp服務,上傳qt在線安裝程序。
3、命令行啟動,使用阿里云鏡像
給在線安裝程序可執行權限
./qt-online-installer-linux-x64-4.10.0.run --mirror https://mirrors.aliyun.com/qt/
4、下載所需版本
Qt提示需要安裝庫
使用apt安裝庫文件,下載所需版本和組件
5、配置Qt所需環境(在步驟4時已安裝)
sudo apt install libxcb-cursor0 libxcb-cursor-dev
sudo apt-get install build-essential libgl1-mesa-dev
1、libxcb-cursor0 和 libxcb-cursor-dev 是與 XCB(X C Binding) 相關的庫,主要用于在 Linux 系統中處理鼠標光標(cursor)相關的功能。
2、build-essential這是一個元包(meta-package),它會自動安裝一系列編譯 C/C++ 程序所需的基礎工具和庫,包括:
編譯器:gcc(GNU C 編譯器)、g++(GNU C++ 編譯器)
構建工具:make(用于解析 Makefile 并執行編譯流程)
標準庫:libc6-dev(GNU C 標準庫的開發文件)等
作用:提供編譯 C/C++ 程序的最小環境。幾乎所有需要編譯源碼的場景(包括 Qt 項目構建)都需要先安裝它,否則會出現 “缺少編譯器”“無法識別 make 命令” 等錯誤。
3、這是 Mesa 3D 圖形庫的開發包,主要提供:OpenGL 接口的實現(用于 2D/3D 圖形渲染)頭文件(如 GL/gl.h)和鏈接庫,供程序編譯時調用
作用:
Qt(尤其是涉及圖形渲染的模塊,如 Qt Widgets、Qt Quick)依賴 OpenGL 進行界面繪制。如果缺少這個包,編譯 Qt 項目時可能會出現 “找不到 GL 庫”“無法鏈接 OpenGL” 等錯誤,導致圖形界面程序無法構建或運行。
** 注意:使用在線安裝工具安裝qt后,第一次運行工程出現error: cmake project configuration failed. no cmake configuration for build type “debug” found. check general messages for more information.錯誤,可能是沒有設置Qt運行環境**
6、創建示例工程并測試
創建工程運行報錯,安裝如下庫后回復正常,錯誤內容為:error: cmake project configuration failed. no cmake configuration for build type “debug” found. check general messages for more information.
安裝OpenGl相關依賴庫
sudo apt update && sudo apt install libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev
安裝xcb 插件依賴
sudo apt install libxcb-cursor0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxcb-xinerama0
7、運行從git 下載的Qt項目
這個項目時從我的另一臺電腦上的Ubuntu虛擬機上傳到GIT的,Qt版本一致,運行前先配置項目中的CAMKE等設置,因為兩臺Ubuntu虛擬機安裝Qt的目錄不同,否則會報錯
三、交叉編譯環境搭建(參考野火教程)
野火Qt6交叉編譯教程
1、宿主機下載相關庫與工具
sudo apt update
sudo apt install libssl-dev gperf pkg-config git bison ninja-build
sudo apt install make build-essential libclang-dev \libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev \libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev \libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev \libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev \libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev \libatspi2.0-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev
2、獲取并安裝交叉編譯器
這里我直接用命令下載的編譯器
wangju@wangju-virtual-machine:~$ which aarch64-linux-gnu-g++
/usr/bin/aarch64-linux-gnu-g++
wangju@wangju-virtual-machine:~$ which g++
/usr/bin/g++
wangju@wangju-virtual-machine:~$
3、構建sysroot目錄
板卡下載相關庫
# 安裝一些庫和工具等,按自己需要安裝
sudo apt update# x11相關
sudo apt-get install -y libx11-dev freetds-dev libsqlite0-dev libpq-dev libiodbc2-dev firebird-dev \libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev \libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev \libxcb-icccm4 libxcb-icccm4-dev libxcb-sync1 libxcb-sync-dev libxcb-render-util0 \libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev \libxcb-glx0-dev libxi-dev libdrm-dev libxcb-xinerama0 libxcb-xinerama0-dev libatspi2.0-dev \libxcursor-dev libxcomposite-dev libxdamage-dev libxss-dev libxtst-dev libpci-dev libcap-dev \libxrandr-dev libdirectfb-dev libaudio-dev libxkbcommon-x11-dev# gst 1.0相關
sudo apt-get install -y libgstreamer1.0-0 gstreamer1.0-plugins-base \gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools libunwind-dev# 其他等等
sudo apt-get install -y libfreetype6-dev libicu-dev libsqlite3-dev libasound2-dev libnss3-dev \libxss-dev libxtst-dev libpci-dev libcap-dev libsrtp0-dev libxrandr-dev libdirectfb-dev libaudio-dev \libavcodec-dev libavformat-dev libswscale-dev libts-dev libfontconfig1-devsudo apt-get install -y libssl-dev libdbus-1-dev libglib2-dev libegl1-mesa-dev \libgbm-dev libgles2-mesa-dev libgles2-mesa rsyslog libjpeg-dev
然后我將 /lib /usr 這兩個目錄通過ftp全部下載到了主機上。具體可以參考野火教程
4、安裝CMAKE(源碼編譯安裝)
先用命令安裝cmake。
按照野火教程,先為主機編譯安裝qt源碼。
然后新建一個cmake 工具鏈文件,用來指定CMAKE相關參數(交叉編譯需要)
# 這里設置cmake支持的最小版本
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)# 指定sysroot目錄 需要自己修改
set(TARGET_SYSROOT /home/wangju/develope/sysroot) # 指定前面獲取的交叉編譯器路徑 需要自己修改
set(CROSS_COMPILER /usr/bin/aarch64-linux-gnu)set(CMAKE_SYSROOT ${TARGET_SYSROOT})set(CMAKE_C_COMPILER ${CROSS_COMPILER}-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER}-g++)set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)# 庫路徑
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -Wl,-rpath-link,${CMAKE_SYSROOT}/lib/${CMAKE_LIBRARY_ARCHITECTURE} -fPIC -Wl,-rpath-link,${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/lib -L${CMAKE_SYSROOT}/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} -L${CMAKE_SYSROOT}/usr/lib -I${TARGET_SYSROOT}/usr/include -I${TARGET_SYSROOT}/usr/include/${CMAKE_LIBRARY_ARCHITECTURE}")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")# pkg config路徑
set(ENV{PKG_CONFIG_PATH} ${TARGET_SYSROOT}/usr/lib/pkgconfig:${TARGET_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${TARGET_SYSROOT}/usr/share/pkgconfig/)
set(ENV{PKG_CONFIG_LIBDIR} ${TARGET_SYSROOT}/usr/lib/pkgconfig:${TARGET_SYSROOT}/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${TARGET_SYSROOT}/usr/share/pkgconfig/)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})set(QT_COMPILER_FLAGS "-march=armv8-a")
set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-fuse-ld=gold -ldbus-1")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(CMakeInitializeConfigs)function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)if (DEFINED QT_COMPILER_FLAGS_${config})set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")endif()endforeach()
endif()if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")foreach (config SHARED MODULE EXE)set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")endforeach()
endif()_cmake_initialize_per_config_variable(${ARGV})
endfunction()
然后在qt源碼目錄執行cmake配置命令
cat arm64_cmake
cmake ../ -GNinja -DCMAKE_BUILD_TYPE=Release -DINPUT_opengl=es2 -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DQT_HOST_PATH=/home/wangju/develope/qt/qt6Host -DCMAKE_STAGING_PREFIX=/home/wangju/develope/sysroot/opt/prefix -DCMAKE_INSTALL_PREFIX=/home/wangju/develope/sysroot/opt/prefix -DCMAKE_TOOLCHAIN_FILE=/home/wangju/develope/lubancat_toolchain.cmake -DQT_QMAKE_TARGET_MKSPEC=devices/linux-imx8-g++ -DQT_FEATURE_xcb=OFF -DFEATURE_xcb_xlib=OFF -DQT_FEATURE_xlib=OFF -DQT_FEATURE_eglfs=ON -DQT_FEATURE_wayland=ON -DFEATURE_qtwebengine_build=OFF
因為我的sysroot 缺少 X11 相關德 庫,所以將xcb 編譯選項關閉,-DQT_FEATURE_xcb=OFF -DFEATURE_xcb_xlib=OFF -DQT_FEATURE_xlib=OFF。 開啟了-DQT_FEATURE_eglfs=ON -DQT_FEATURE_wayland=ON ,對于 i.MX8QM 這樣的嵌入式設備,使用 EGLFS 或 Wayland 作為圖形后端比使用傳統的 X11/XCB 更加合適,i.MX8QM 具有強大的 Vivante GPU,EGLFS 可以直接利用硬件加速。對于野火文件中的設備文件,我發現qt源碼中有 NXP 的 imx8系列設備的模板,我直接用的官方的設備文件。
#
# qmake configuration for the NXP i.MX8 based boards (64-bit)
#
# The configuration below is set up for running with the fbdev-style
# Vivante graphics stack. (so eglfs with the eglfs_viv backend, no
# direct drm use via eglfs_kms)# Wayland should also be functional. However, when writing Wayland
# *compositors* with Qt, the eglfs backend will have to be switched to
# eglfs_viv_wl by setting the QT_QPA_EGLFS_INTEGRATION environment
# variable.
#
# Below is an example configure line that assumes there is an AArch64
# toolchain and sysroot available in $HOME/imx8. On device Qt is
# expected to be placed under /usr/local/qt514 whereas on the host
# 'make install' will copy the host tools and the target libraries to
# $HOME/imx8/qt5.
#
# ./configure -release -opengl es2 -device linux-imx8-g++ \
# -device-option CROSS_COMPILE=~/imx8/toolchain/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux- \
# -sysroot ~/imx8/sysroot \
# -opensource -confirm-license -make libs -prefix /usr/local/qt514 -extprefix ~/imx8/qt5 -vinclude(../common/linux_device_pre.conf)QMAKE_LIBS_EGL += -lEGL
QMAKE_LIBS_OPENGL_ES2 += -lGLESv2 -lEGL -lGAL
QMAKE_LIBS_OPENVG += -lOpenVG -lEGL -lGALIMX8_CFLAGS = -march=armv8-a -mtune=cortex-a72.cortex-a53 -DLINUX=1 -DEGL_API_FB=1
QMAKE_CFLAGS += $$IMX8_CFLAGS
QMAKE_CXXFLAGS += $$IMX8_CFLAGSDISTRO_OPTS += aarch64# Preferred eglfs backend
EGLFS_DEVICE_INTEGRATION = eglfs_vivinclude(../common/linux_arm_device_post.conf)load(qt_config)
最后執行cmake 編譯命令、編譯完后安裝。這里要注意編譯所需空間大,如果按照野火教程,先為主機編譯qt源碼,所需空間較大,建立虛擬機時應該一次性剛給100G 左右的空間,大一點最好,不然在編譯或者安裝時會出現空間不足導致安裝失敗的情況。建立好虛擬機后擴展磁盤或者添加磁盤比較麻煩,最好一次給夠。
問題記錄
1、QT 引用資源文件報錯問題(已解決)
2、QT工程 Windows 移動到 Linux ,編譯報錯問題
3、上傳到git的Qt項目在另一臺虛擬機再次下載后編譯報錯問題
4、如何下載目標平臺對應版本的編譯器
最好是開發板系統和主機系統版本一致。
5、使用在線安裝安裝qt后創建項目報錯,CAMKE找不到Qt6Quick 、QtWidget等組件
依次安裝了 C/C++開發工具、OpenGL 依賴、xcb依賴,具體是那個的問題不清楚,具體安裝步驟在上文列舉了。
6、下載公版arm sysroot ,使用 chroot 為 sysroot 下載必要庫文件
1、chroot使用前更換sysroot apt源為國內源
sudo chroot /path/to/arm-sysroot /bin/bash
cp /etc/apt/sources.list /etc/apt/sources.list.bak
# 清空原有內容并寫入清華源
cat > /etc/apt/sources.list << EOF
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ focal-security main restricted universe multiverse
EOF
# 更新源列表
apt update# 測試是否能正常下載(可選)
apt install -y vim # 安裝一個小工具驗證
使用apt前要將宿主機文件系統掛在到sysroot,否則無網絡
2、chroot使用前掛在必要的文件系統,如網絡等
sudo mount --bind /dev /path/to/arm-sysroot/dev
sudo mount -t proc /proc /path/to/arm-sysroot/proc
sudo mount --bind /sys /path/to/arm-sysroot/sys
# 使用完畢,卸載
sudo umount /path/to/arm-sysroot/dev
sudo umount /path/to/arm-sysroot/proc
sudo umount /path/to/arm-sysroot/sys
3、chroot 在x86上運行 arm的sysroot,需要下載QEMU 模擬器
sudo apt update
sudo apt install qemu-user-static binfmt-support
sudo cp /usr/bin/qemu-arm-static sysroot/usr/bin/
4、掛載文件系統后沒網,可能是sysyroot DNS需要設置
sudo cp /etc/resolv.conf sysroot/etc/
sudo nano sysroot/etc/resolv.conf
nameserver 114.114.114.114
nameserver 8.8.8.8
nameserver 223.5.5.5