本文不完全记录,移植qt 6.4.3到rk3562 soc的过程。
首先需要移植libdrm和libmali。用来支持gpu加速。
编译后,libdrm和libmali分别位于:
/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm/usr/lib/pkgconfig
/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali/usr/lib/pkgconfig
后面会发现,根本原因是这两个库不是同一个目录。qt6的配置程序不支持。
qt6主要是卡在配置阶段,检测egl,opengl失败的问题上。
交叉编译toolchain.mk如下:
$ cat toolchain.cmake cmake_minimum_required(VERSION 3.15) include_guard(GLOBAL) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) set(ENV{PKG_CONFIG_PATH} "") set(ENV{PKG_CONFIG_LIBDIR} "/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm/usr/lib/pkgconfig:/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali/usr/lib/pkgconfig") set(CMAKE_C_COMPILER /home/yuanjp/toolchain/toolchain-rk3562/bin/aarch64-none-linux-gnu-gcc) set(CMAKE_CXX_COMPILER /home/yuanjp/toolchain/toolchain-rk3562/bin/aarch64-none-linux-gnu-g++) set(CMAKE_SYSROOT /home/yuanjp/toolchain/toolchain-rk3562/aarch64-none-linux-gnu/libc) 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)
注意:
1 需要指定CMAKE_SYSROOT,否则configure会检测到host的程序。
2 PKG_CONFIG_LIBDIR指定,libdrm和libmali的.pc搜索路径。
PKG_CONFIG=$(HOST)/scripts/pkg-config $(SDIR)/configure \ -verbose \ -prefix /opt/qt6 \ -extprefix $(STAGING) \ -opensource \ -confirm-license \ -release \ -shared \ -nomake examples \ -nomake tests \ -no-dbus \ -no-xcb \ -skip qtwebengine \ -skip qtwayland \ -no-openssl \ -no-cups \ -opengles3 \ -egl \ -gbm \ -- \ -DQT_HOST_PATH=$(qt_host_install) \ -DCMAKE_TOOLCHAIN_FILE=$(ODIR)/toolchain.cmake
configure失败了。
ERROR: Feature "opengles3": Forcing to "ON" breaks its condition:
QT_FEATURE_opengles2 AND TEST_opengles3
Condition values dump:
QT_FEATURE_opengles2 = "OFF"
TEST_opengles3 = "FALSE"
ERROR: Feature "egl": Forcing to "ON" breaks its condition:
( QT_FEATURE_opengl OR QT_FEATURE_openvg ) AND EGL_FOUND AND ( QT_FEATURE_dlopen OR NOT UNIX OR INTEGRITY )
Condition values dump:
QT_FEATURE_opengl = "OFF"
QT_FEATURE_openvg = "OFF"
EGL_FOUND = "FALSE"
QT_FEATURE_dlopen = "ON"
UNIX = "1"
INTEGRITY = "0"
ERROR: Feature "gbm": Forcing to "ON" breaks its condition:
gbm_FOUND
Condition values dump:
gbm_FOUND = "FALSE"
查看:./CMakeFiles/CMakeConfigureLog.yaml
3357 [1/2] /home/yuanjp/toolchain/toolchain-rk3562/bin/aarch64-none-linux-gnu-g++ --sysroot=/home/yuanjp/toolchain/toolchain-rk3562/aarch64-none-linux-gnu/libc -DHAVE_EGL -std=gnu++17 -fPIE -o CMakeFiles/cmTC_75fbf.dir/src.cxx.o -c /home/yuanjp/proj/zynqmp/staging /rk3562/app/qt-everywhere-src-6.4.3/CMakeFiles/CMakeScratch/TryCompile-KJPgPU/src.cxx
3358 FAILED: CMakeFiles/cmTC_75fbf.dir/src.cxx.o
3359 /home/yuanjp/toolchain/toolchain-rk3562/bin/aarch64-none-linux-gnu-g++ --sysroot=/home/yuanjp/toolchain/toolchain-rk3562/aarch64-none-linux-gnu/libc -DHAVE_EGL -std=gnu++17 -fPIE -o CMakeFiles/cmTC_75fbf.dir/src.cxx.o -c /home/yuanjp/proj/zynqmp/staging/rk356 2/app/qt-everywhere-src-6.4.3/CMakeFiles/CMakeScratch/TryCompile-KJPgPU/src.cxx
3360 /home/yuanjp/proj/zynqmp/staging/rk3562/app/qt-everywhere-src-6.4.3/CMakeFiles/CMakeScratch/TryCompile-KJPgPU/src.cxx:2:10: fatal error: EGL/egl.h: No such file or directory
3361 2 | #include <EGL/egl.h>
3362 | ^~~~~~~~~~~
3363 compilation terminated.
3364 ninja: build stopped: subcommand failed.
发现它编译没有使用egl package里面的头文件路径。
修改:
qtbase/cmake/3rdparty/extra-cmake-modules/find-modules/FindEGL.cmake
75
76 message("============== ${PKG_EGL_INCLUDE_DIRS}")
77
78 find_path(EGL_INCLUDE_DIR
79 NAMES
80 EGL/egl.h
81 HINTS
82 ${PKG_EGL_INCLUDE_DIRS}
83 )
加上76行,有多个目录,导致了搜索头文件失败了。
============== /home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/include;/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include;/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include/libdrm
-- Could NOT find EGL (missing: EGL_INCLUDE_DIR HAVE_EGL EGL_LIBRARY)
创建一个CMakeLists.txt,如下:
cmake_minimum_required(VERSION 3.30) project(Test) message("====CMAKE_C_COMPILER========== ${CMAKE_C_COMPILER}") include(CMakePushCheckState) include(CheckCXXSourceCompiles) find_package(PkgConfig QUIET) pkg_check_modules(PKG_EGL QUIET egl) 。。。
find_package一下的内容从FindEGL.cmake复制过来。
将之前的toolchain.cmake复制到这边的同一个目录。
执行,复现了问题。
$ cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake .. -- The C compiler identification is GNU 10.3.1 -- The CXX compiler identification is GNU 10.3.1 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /home/yuanjp/toolchain/toolchain-rk3562/bin/aarch64-none-linux-gnu-gcc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /home/yuanjp/toolchain/toolchain-rk3562/bin/aarch64-none-linux-gnu-g++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done ====CMAKE_C_COMPILER========== /home/yuanjp/toolchain/toolchain-rk3562/bin/aarch64-none-linux-gnu-gcc ====PKG_EGL_INCLUDE_DIRS========== /home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/include;/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include;/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include/libdrm ====PKG_EGL_CFLAGS_OTHER========== ====PKG_EGL_LIBRARY_DIRS========== /home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/lib;/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/lib ====EGL_LIBRARY========== EGL_LIBRARY-NOTFOUND ====CMAKE_REQUIRED_LIBRARIES========== EGL_LIBRARY-NOTFOUND ====EGL_INCLUDE_DIR========== EGL_INCLUDE_DIR-NOTFOUND ====CMAKE_REQUIRED_INCLUDES========== EGL_INCLUDE_DIR-NOTFOUND ====EGL_DEFINITIONS========== ====CMAKE_REQUIRED_DEFINITIONS========== -- Performing Test HAVE_EGL -- Performing Test HAVE_EGL - Failed -- Could NOT find EGL (missing: EGL_INCLUDE_DIR HAVE_EGL EGL_LIBRARY) -- Configuring done (0.5s) -- Generating done (0.0s) -- Build files have been written to: /home/yuanjp/test/cmake/build
toolchain.cmake指定了pkg-config的搜搜目录:PKG_CONFIG_LIBDIR
我们把pkg-config改成我们封装的wrapper脚本。在wrapper脚本里面打印出参数和输出。
PKG_CONFIG=$(HOST)/scripts/pkg-config $(SDIR)/configure
这种方式,就可以改变pkg-config了。应该是cmake是以这个环境变量确定的。
勾出来的内容如下:
========= --print-errors --short-errors --exists egl ========= --modversion egl 7.10 ========= --variable=prefix egl /home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr ========= --variable=includedir egl /home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/include ========= --variable=libdir egl /home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/lib ========= --libs-only-l egl -lmali-hook -lmali-hook-injector -lmali -ldrm ========= --static --libs-only-l egl -lmali-hook -lmali-hook-injector -lmali -ldrm -lm ========= --libs-only-L egl -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/lib -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/lib ========= --static --libs-only-L egl -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/lib -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/lib ========= --libs egl -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/lib -lmali-hook -Wl,--whole-archive -lmali-hook-injector -Wl,--no-whole-archive -lmali -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/lib -ldrm ========= --static --libs egl -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/lib -lmali-hook -Wl,--whole-archive -lmali-hook-injector -Wl,--no-whole-archive -lmali -L/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/lib -ldrm -lm ========= --libs-only-other egl -Wl,--whole-archive -Wl,--no-whole-archive ========= --static --libs-only-other egl -Wl,--whole-archive -Wl,--no-whole-archive ========= --cflags-only-I egl -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include/libdrm ========= --static --cflags-only-I egl -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include/libdrm ========= --cflags egl -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include/libdrm ========= --static --cflags egl -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libmali-rk3562/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include -I/home/yuanjp/proj/zynqmp/staging/rk3562/app/libdrm-2.4.120/staging/usr/include/libdrm ========= --cflags-only-other egl ========= --static --cflags-only-other egl
而linux主机勾出来的内容如下:
========= --print-errors --short-errors --exists egl ========= --modversion egl 1.5 ========= --variable=prefix egl /usr ========= --variable=includedir egl /usr/include ========= --variable=libdir egl /usr/lib64 ========= --libs-only-l egl -lEGL ========= --static --libs-only-l egl -lEGL ========= --libs-only-L egl -L/usr/lib64 ========= --static --libs-only-L egl -L/usr/lib64 ========= --libs egl -L/usr/lib64 -lEGL ========= --static --libs egl -L/usr/lib64 -lEGL ========= --libs-only-other egl ========= --static --libs-only-other egl ========= --cflags-only-I egl -I/usr/include ========= --static --cflags-only-I egl -I/usr/include ========= --cflags egl -I/usr/include ========= --static --cflags egl -I/usr/include ========= --cflags-only-other egl ========= --static --cflags-only-other egl
PKG_EGL_LIBRARY_DIRS
这个变量,是一个list,有两个目录。导致
find_library(EGL_LIBRARY
NAMES
EGL
HINTS
${PKG_EGL_LIBRARY_DIRS}
)
查找失败了。
用pkg-config是不靠谱的。直接为每个package单独指定include_dir和library。
然后要链接的库,使用CMAKE_EXE_LINKER_FLAGS。指定link选项了解决编译问题。
在toolchain.cmake里面添加:
set(CMAKE_SYSROOT /home/yuanjp/toolchain/toolchain-rk3562/aarch64-none-linux-gnu/libc)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,-rpath-link=%APPBLD%/libdrm/usr/lib/")
set(Libdrm_INCLUDE_DIR %APPBLD%/libdrm/usr/include)
set(Libdrm_LIBRARY %APPBLD%/libdrm/usr/lib/libdrm.so)
set(EGL_INCLUDE_DIR %APPBLD%/libmali/usr/include)
set(EGL_LIBRARY %APPBLD%/libmali/usr/lib/libmali.so)
set(GLESv2_INCLUDE_DIR %APPBLD%/libmali/usr/include)
set(GLESv2_LIBRARY %APPBLD%/libmali/usr/lib/libmali.so)
set(gbm_INCLUDE_DIR %APPBLD%/libmali/usr/include)
set(gbm_LIBRARY %APPBLD%/libmali/usr/lib/libmali.so)
配置不用-no-pkg-config
$(H)[ -f $(ODIR)/.configured ] || { cd $(ODIR) && $(Q) $(SDIR)/configure \
-verbose \
-prefix /opt/qt6 \
-extprefix $(STAGING) \
-no-pkg-config \
-opensource \
-confirm-license \
-release \
-shared \
-nomake examples \
-nomake tests \
-no-dbus \
-no-xcb \
-skip qtwebengine \
-skip qtwayland \
-no-openssl \
-no-cups \
-opengles3 \
-egl \
-gbm \
-- \
-DQT_HOST_PATH=$(qt_host_install) \
-DCMAKE_TOOLCHAIN_FILE=$(ODIR)/toolchain.cmake \
&& touch $(ODIR)/.configured ; }
参考:
https://doc.qt.io/qt-6/configure-linux-device.html
如何使用message进行打印
https://cmake.org/cmake/help/latest/command/message.html
find_path函数:
https://cmake.org/cmake/help/latest/command/find_path.html