qt5.15.2 交叉编译总结

最近项目需要,qt源码需要交叉编译,以前对这块不是很熟悉,从开始的一脸懵逼到最终成功编译出qt源码库,还是有了很多收获,分享给大家,希望对大家有所帮助。

交叉编译详解

还是先说交叉编译的思想。这里我以为我的项目经历为例给大家讲解。

说到交叉编译,这里要给大家普及两个概念。

  • 构建机平台,这个意思是说要在那台机器进行交叉编译,我自己的项目中的构建平台是x86_64+银河麒麟v10。
  • 目标平台,这个更好理解了,就是编译出来的动态库要运行在哪个平台上,我自己项目中的目标平台是aarch64+银河麒麟v10。

通过上面的介绍,大家应该基本理解了这两个概念,下面就开始说说交叉交叉编译的思想,交叉编译顾名思义就是在构建机平台上编译出目标机平台的应用程序或者动态库/静态库。很多朋友会问为什么会存在交叉编译呢?因为有这样的场景,很多嵌入式平台因性能不足无法进行大规模软件编译的情况,也存在很多其它的情况,大家可以百度一下能够得到很多理由。

好了上面对交叉编译做了基本的介绍,下面先从本机编译开始说起,本机编译,顾名思义就是本机编译的程序或者动态在本机上运行(也可以在同平台的机器上运行,这里不做过多赘述),这个很好理解,要编译的程序或者动态库依赖的一些头文件或者库文件就在本机系统上,或在默认目录(以linux为例,/usr/include /usr/lib等),另外也可以通过人工指定的方式(例如qt中可以通过LIBS关键字或者INCLUDEPATH等指定库文件路径和头文件路径等)指明依赖的头文件和库文件位置。这个很好理解,对于程序源来说这是很基本的概念。

上面已经详细介绍了本机编译的情况,本机介绍交叉编译,交叉编译的思想与本机编译的思想类似,但是有一些区别,下面一一列出。

  • 必须选择交叉编译器,以arm为例,可以到arm官网:Arm GNU Toolchain Downloads – Arm Developer下载包含符合自己构建平台和目标平台的交交叉编译器,这里是提供的是版本比较新的交叉编译器。如果需要查找历史版本则可以从这两个路径去查找:GNU toolchain releases for Embedded processors (discontinued)和GNU toolchain releases for A-profile processors (discontinued),这二者的区别是一个是嵌入式处理器的交叉编译工具,另外一个是移动设备或者计算能力强的处理的交叉编译工具,如有感兴趣的朋友可以自己查找资料,这里仅简单描述。用户需要根据自己的需求下载对应的交叉编译工具,上面的连接中提供了多种不同的构建和目标平台的交叉编译版本,例如x86_64 Linux hosted cross toolchains表示该编译器是运行在x86_64架构上的;AArch64 GNU/Linux target表示是编译出的目标程序是运行在aarch64架构上且依赖的是linux操作系统的。也有一部分是与操作系统无关,我自己的理解是编译器中的没有依赖操作系统相关的接口。
  • 交叉编译过程中依赖的头文件和库需要从目标机上安装,下载到构建机使用,不能使用本机的头文件和库文件,因为构建机的库文件与目标机的库文件由于架构不同,往往不能通用。头文件在不同的平台下接口名称可能也不一样,为了保险起见,最好编译程序所依赖的头文件和库文件最好从平台拉取到本地,然后手动指定头文件和库文件的路径进行编译。这里我在交叉编译qt5.15.2的源码时,是通过sysroot关键字来制出依赖的头文件和库文件路径,下面会详细介绍,这里仅介绍方法。需要注意的是交叉编译过程中依赖的头文件和库文件需要在目标机上安装,然后下载到本地,直接在构建机上安装是不对的

上面涉及的两个步骤都做完后就可以开始交叉编译了,下面以qt5.15.2为例,详细介绍下是如何完成交叉编译的。

Qt 5.15.2交叉编译实例

构建平台: x86_64+银河麒麟v10

目标机平台:aarch64+银河麒麟v10

按照第一节讲解的步骤下载了9.2版本(gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu)的交叉编译器,同时将目标机的头文件和库文件下载到构建机。

步骤一

qt源码安装依赖很多库,需要提前在目标机(aarch64+银河麒麟V10)上安装,依赖库如下:

sudo apt install build-essential cmake unzip pkg-config gfortran
sudo apt build-dep qt5-qmake libqt5gui5 libqt5webengine-data libqt5webkit5 libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0 gdbserver
sudo apt install libxcb-randr0-dev libxcb-xtest0-dev libxcb-shape0-dev libxcb-xkb-dev

附加包如下所示,根据需要安装即可。

# additional (multimedia) packages
sudo apt install libjpeg-dev libpng-dev libtiff-dev
sudo apt install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt install libxvidcore-dev libx264-dev openjdk-8-jre-headless
# audio packages
sudo apt install libopenal-data libsndio7.0 libopenal1 libopenal-dev pulseaudio
# bluetooth packages
sudo apt install bluez-tools
sudo apt install libbluetooth-dev
# gstreamer (multimedia) packages
sudo apt install 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 gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio
sudo apt install libgstreamer1.0-dev  libgstreamer-plugins-base1.0-dev

步骤二

设置符号连接,这里我自己的理解是交叉编译工具需要一些特定的符号链接用于在编译过程中使用。需要下载SSymlinkerbash 脚本,这个脚本我从一[参考链接]中看到,但是按照他的方法没有下载下来,这里我把这个脚本上传到这里,供大家下载。脚本下载地址请在文章顶部提供的链接下载。下载脚本后执行如下操作,通过这些操作你能大概明白他的含义:

sudo chmod +x SSymlinker
./SSymlinker -s /usr/include/arm-linux-gnueabihf/asm -d /usr/include
./SSymlinker -s /usr/include/arm-linux-gnueabihf/gnu -d /usr/include
./SSymlinker -s /usr/include/arm-linux-gnueabihf/bits -d /usr/include
./SSymlinker -s /usr/include/arm-linux-gnueabihf/sys -d /usr/include
./SSymlinker -s /usr/include/arm-linux-gnueabihf/openssl -d /usr/include
./SSymlinker -s /usr/lib/arm-linux-gnueabihf/crtn.o -d /usr/lib/crtn.o
./SSymlinker -s /usr/lib/arm-linux-gnueabihf/crt1.o -d /usr/lib/crt1.o
./SSymlinker -s /usr/lib/arm-linux-gnueabihf/crti.o -d /usr/lib/crti.o

至此目标机(aarch64+银河麒麟V10)已经设置完成。

步骤三(配置构建机)

  • 构建机也需要安装一些基础软件包,安装的软件包如下所示:

sudo apt update
sudo apt dist-upgrade
sudo apt install build-essential cmake unzip gfortran
sudo apt install gcc git bison python gperf pkg-config gdb-multiarch wget
sudo apt-get -y install gcc g++ gperf flex texinfo gawk bison openssl pigz libncurses-dev autoconf automake tar figlet

设置目录结构,这个目录结构用来存放从目标机下载的库文件和头文件,供交叉编译器使用。

命令如下:

sudo mkdir ~/rk-qt
sudo mkdir ~/rk-qt/build
sudo mkdir ~/rk-qt/tools
sudo mkdir ~/rk-qt/sysroot
sudo mkdir ~/rk-qt/sysroot/usr
sudo mkdir ~/rk-qt/sysroot/opt
sudo chown -R consys:consys ~/rk-qt
cd ~/rk-qt

  •  接下来下载qt5.15.2源码到构建机,并解压缩到本地,目录自己指定即可。另外从arm官网下载的交叉编译工具也解压缩到本地。
  • 上述步骤完成,将交叉编译工具的bin目录添加到环境变量PATH中,方法如下:

vim .bashrc

在文件末尾添加export PATH=交叉编译工具bin目录:$PATH(以我的项目为例:/home/consys/tool/gcc-linaro-11.3.1-2022.06-x86_64_aarch64-linux-gnu/bin:$PATH)

source .bashrc 或者直接关闭该终端,再重新打开终端执行export命令查看PATH环境变量是否添加成功。

需要注意的是交叉编译工具bin目录下存放的是aarch64-linux-gnu-gcc。xxxxxxx-g++等工具,别找错目录了

  • 修改/home/consys/tool/qt-everywhere-src-5.15.2/qtbase/mkspecs目录下的qmake配置文件,我因为是要交叉编译aarhch+银河麒麟v10的程序,所以我选择的是修改linux-aarch64-gnu-g++目录下的qmake.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

修改为:

QMAKE_CC                = aarch64-none-linux-gnu-gcc   //注意这里的名字与交叉编译工具bin目录下的名字一致
QMAKE_CXX               = aarch64-none-linux-gnu-g++  //注意这里的名字与交叉编译工具bin目录下的名字一致
QMAKE_LINK              = aarch64-none-linux-gnu-g++  //注意这里的名字与交叉编译工具bin目录下的名字一致
QMAKE_LINK_SHLIB        = aarch64-none-linux-gnu-g++  //注意这里的名字与交叉编译工具bin目录下的名字一致

# modifications to linux.conf

QMAKE_AR                = aarch64-none-linux-gnu-ar cqs //注意这里的名字与交叉编译工具bin目录下的名字一致
QMAKE_OBJCOPY           = aarch64-none-linux-gnu-objcopy  //注意这里的名字与交叉编译工具bin目录下的名字一致
QMAKE_NM                = aarch64-none-linux-gnu-nm -P  //注意这里的名字与交叉编译工具bin目录下的名字一致
QMAKE_STRIP             =aarch64-none-linux-gnu-strip  //注意这里的名字与交叉编译工具bin目录下的名字一致

  •  从目标平台下载依赖的头文件、库文件和配置文件等。命令如下所示:

cd ~/rk-qt

 rsync -avz --rsync-path="sudo rsync" --delete consys@192.168.0.174:/lib sysroot
 rsync -avz --rsync-path="sudo rsync" --delete consys@192.168.0.174:/usr/include sysroot/usr
 rsync -avz --rsync-path="sudo rsync" --delete consys@192.168.0.174:/usr/lib sysroot/usr
 rsync -avz --rsync-path="sudo rsync" --delete consys@192.168.0.174:/opt/vc sysroot/opt

注意:rsync命令研究一下,只要从目标机下载到本机即可

将交叉编译依赖的文件下载到本地后执行下面命令,恢复链接

sudo chmod +x sysroot-relativelinks.py
./sysroot-relativelinks.py sysroot

  • 编译qt源码需要先执行configure脚本,然后执行make 和make install命令,但是在交叉编译过程中有一项千万要在执行configure脚本之前执行,即配置PKG_CONFIG_PATH环境变量,这个环境变量指明一些后缀为pc的文件,这些pc文件指令了依赖库的路径,是非常重要的一个步骤,我很长时间编译出错就是因为在执行configure后,才添加的这个环境变量,但是configure执行过程中如果不配置该环境变量,qt就认为一些依赖库不存在,但是其实依赖库是存在的,因为configure执行过程中会根据该环境变量,影响一些生成的文件中的内容,造成报错或者编译跳过问题。我遇到的问题是编译qwebegine模块时一直提示nns模块不存在,但是从目标机下载头文件和库文件中nss已经存在,被折腾了好久。
  • 到这里已经基本配置完成了,但是还是要啰嗦一下,就是最好写一个autoconfigre.sh脚本放到qt5.15.2的目录下,与configure脚本同级即可,这个就自己研究参数把,我把自己使用的autoconfigure.sh脚本放在下面,供参考使用。

#!/bin/sh

./configure -release   -qt-libjpeg -qt-libpng -qt-zlib -qt-pcre -xplatform linux-aarch64-gnu-g++ -sysroot ~/rk-qt/sysroot -prefix /home/consys/tool/aarch64-qt-output  -opensource -confirm-license -skip qtscript -skip qtwayland  -nomake tests  -skip qtlocation -skip qt3d  -no-opengl -skip qtcanvas3d -skip qtpurchasing -make libs -pkg-config  -v -recheck -L$HOME/rk-qt/sysroot/usr/lib/aarch64-linux-gnu -I$HOME/rk-qt/sysroot/usr/include/aarch64-linux-gnu

  •  最后赋予autoconfigure.sh脚本执行权限,执行该脚本就可以了

sudo chmod +x autoconfigure.sh

./autoconfiure.sh

make

make install

注意1:交叉编译qt5.15.2时会消耗大量的内存,我开始使用的笔记本交叉编译(配置为8G内存+9G交换空间),在上面的配置中依然内存不够,造成编译不通过,最后找了一台内存超大的机器后菜编译通过。

注意2:autoconfigure.sh中指定了prefix(/home/consys/tool/aarch64-qt-output),这个目录需要注意并不是绝对路径,如果指定了sysroot,那么生成路径就是在sysroot指定的路径下创建prefix路径,即最终的动态库生成路径是(/home/consys/rk-qt/sysroot/home/consys/tool/aarch64-qt-output),这一点不要搞混了。sysroot的作用是提供一个逻辑地址,configure指定该参数后,编译依赖的头文件和库文件会以sysroot指定的路径作为基地址,即交叉编译原本依赖的头文件路径是/usr/include,指定sysroot后,则变成/home/consys/sysroot/usr/include。

交叉编译过程中遇到的问题

按照上面的步骤操作能够避免绝大多数问题,但是还是不可避免的遇到了一些问题,下面将他们一一列出,希望能够给朋友们一些帮助。

问题1

错误信息:编译的过程中提示缺少libdl.so 和librt.so等动态库,提示这些动态库的下符号找不到,例如dlOpen等。

修改方法:打开报错目录的makefile文件,手动在LIBS关键字中添加对应的so,缺少哪个就添加哪个,例如-ldl -lrt 如果名字不标准的,直接添加路径+so名称即可。

问题2

错误信息:jidctfst-neon.c:88:29: 错误: 用'int64x1_t'初始化'int_64' {或称‘long int’}时类型不兼容

int64_t left_ac_bitmap = vreinterpret_s64_s16(bitmap))

修改方法:此处是代码问题,需要修改代码,=号量表类型不一致,问题代码为:

int64_t left_ac_bitmap = vreinterpret_s64_s16(vget_low_s16(bitmap));

修改为

int64_t left_ac_bitmap = vget_lane_s64(vreinterpret_s64_s16(vget_low_s16(bitmap)),0);

其它报相同的问题按照相同方式修改即可。

问题3

错误信息:错误: 'vaddq_s8'的第2个实参类型不兼容

修改方法:代码问题,需要修改代码,实参类型与虚参类型不一致,问题代码为:

vaddq_s8(cols_01_s8,  vdupq_n_u8(CENTERJSAMPLE)));

修改为

vaddq_s8(cols_01_s8,  vreinterpretq_s8_u8(vdupq_n_u8(CENTERJSAMPLE))));

使用方法

交叉编译完成后,到生成的目录中将文件上传到目标平台,然后在目标平台执行如下命令:

echo /usr/local/qt5.15/lib | sudo tee /etc/ld.so.conf.d/qt5.15.conf
sudo ldconfig

最后运行程序即可。

参考链接:

树莓派4B——ubuntu20.04交叉编译QT5.15.2,_交叉编译qt 5.15_Li丶Chong的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/10409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

优化 PHP 数据库查询性能

优化 PHP 数据库查询性能可以从以下几个方面入手: 使用索引:在数据库中创建适当的索引可以大大提高查询性能。索引可以加快数据的查找速度,特别是在大型数据库中。选择合适的数据类型:选择正确的数据类型可以减少存储空间的占用&…

wordpress我的个人网站搭建

WordPress介绍 WordPress是一个功能强大且易于使用的网站管理平台。它是基于PHP和MySQL构建的,可以在各种不同的主机上运行。 wordpress对服务器的要求 需求最低版本要求PHP7.4 或更高版本MySQL5.6 或更高版本Web服务器任意(如:Apache、Ng…

在CSDN学Golang云原生(Kubernetes Service)

一,service的定义与基本用法 在 Kubernetes 中,Service 是一种抽象概念,用于定义一组 Pod 并为它们提供访问入口。通过 Service,您可以将多个 Pod 组合成一个逻辑单元,并使用标签选择器来确定哪些 Pod 属于该 Service…

一套流程6个步骤,教你如何正确采购询价

采购询价(RFQ)是一种竞争性投标文件,用于邀请供应商或承包商就标准化或重复生产的产品或服务提交报价。 询价通常用于大批量/低价值项目,买方必须提供技术规格和商业要求,该文件有时也称为招标书或投标邀请书。询价流…

git恢复删除的分支

1.查看被删除的分支 git remote prune --dry-run origin 被删除的分支是191 2.找到被删除分支的最后一次提交记录的commit SHA值 git reflog 最后一次提交的commit SHA值是3fa7532 3.恢复分支 git checkout -b xiaomeng 3fa7532 4.恢复成功后提交到远端,over&…

ubuntu20.04 安装 docker engine

打开docker官网 点击上图中间的Linux,会是这样: 点击上图的左边栏的 Docker Engine,点击install, 点击 Ubuntu,会是这样: 把页面翻下来,先按照 Insstallation methods 中的 set up thre repository,执行这些…

pytorch工具——认识pytorch

目录 pytorch的基本元素操作创建一个没有初始化的矩阵创建一个有初始化的矩阵创建一个全0矩阵并可指定数据元素类型为long直接通过数据创建张量通过已有的一个张量创建相同尺寸的新张量利用randn_like方法得到相同尺寸张量,并且采用随机初始化的方法为其赋值采用.si…

压力测试-商场项目

1.压力测试 压力测试是给软件不断加压,强制其在极限的情况下运行,观察它可以运行到何种程度,从而发现性能缺陷,是通过搭建与实际环境相似的测试环境,通过测试程序在同一时间内或某一段时间内,向系统发送预…

数据结构--顺序表、单链表

线性表是指顺序表和单链表 //顺序表数据结构 typedef struct { ElemType data[MaxSize];//顺序表元素 int length; //顺序表当前长度 }SqList; //单链表结点数据结构 typedef struct LNode { ElemType data;//数据域 struct LNode *next;//指针域 }LNode,*LinkList; 顺序表 …

项目:点餐系统1

项目简介:实现一个http点餐系统服务器,能够支持用户在浏览器访问服务器获取餐馆首页,进行菜品以及订单管理。 具体模型如下: 用户分类: 管理员:进行订单以及菜品管理(菜品&订单的增删改查&a…

STM32MP157驱动开发——按键驱动(异步通知)

文章目录 “异步通知 ”机制:信号的宏定义:信号注册 APP执行过程驱动编程做的事应用编程做的事异步通知方式的按键驱动程序(stm32mp157)button_test.cgpio_key_drv.cMakefile修改设备树文件编译测试 “异步通知 ”机制: 信号的宏定义&#x…

protobuf安装教程

protobuf安装 一,Windows下安装下载protobuf配置环境变量检查是否安装成功 二,Linux下安装下载protobuf安装protobuf检查是否安装成功 一,Windows下安装 下载protobuf 下载地址 本次下载以v21.11为例,根据自己需求下载即可。 配…

2023年深圳杯数学建模 D题 基于机理的致伤工具推断

致伤工具的推断一直是法医工作中的热点和难点。由于作用位置、作用方式的不同,相同的致伤工具在人体组织上会形成不同的损伤形态,不同的致伤工具也可能形成相同的损伤形态。致伤工具品种繁多、形态各异,但大致可分为两类:锐器&…

【Spring Boot Admin】使用(整合Spring Cloud服务)

Spring Boot Admin 监控平台服务 pom依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>de.codecent…

【12】STM32·HAL库开发-STM32时钟系统 | F1/F4/F7时钟树 | 配置系统时钟

目录 1.认识时钟树&#xff08;掌握&#xff09;1.1什么是时钟&#xff1f;1.2认识时钟树&#xff08;F1&#xff09;1.2.1STM32F103时钟树简图1.2.2STM32CubeMX时钟树&#xff08;F103&#xff09; 1.3认识时钟树&#xff08;F4&#xff09;1.3.1F407时钟树1.3.2F429时钟树1.3…

linux修改时区

linux修改时区且设置24h格式 修改时区基本命令centos7修改时区并且自动ntp同步ubuntu时间改为24h显示 修改时区基本命令 timedatectl list-timezones #列出所有时区 timedatectl | grep local # 确定硬件时钟是否设置为本地时区 timedatectl set-local-rtc 1 # 将硬件…

FFmpeg AVFilter的原理(三)- filter是如何被驱动的

首先上官方filter的链接&#xff1a;https://ffmpeg.org/ffmpeg-filters.html 关于filter命令行&#xff1a;FFmpeg-4.0 的filter机制的架构与实现.之一 Filter原理 1、下面是一个avfilter的graph 上图是ffmpeg中doc/examples中filtering_video.c案例的示意图。 特别注意上面蓝…

HPC集群调度系统和计算系统

什么是计算云&#xff1f; 所谓的计算云指的是为计算业务优化的类云基础架构&#xff0c;它强调用云的方式解决计算问题&#xff0c;而不是将“计算”搬到现有的公有云或者容器云上。 目前公有云或者容器云&#xff08;例如k8s&#xff09;上的HPC解决方案本质上都是将现有的H…

Linux CentOS监控系统的运行情况工具 - top/htop/glances/sar/nmon

在CentOS系统中&#xff0c;您可以使用以下工具来监控系统的运行情况&#xff1a; 1. top&#xff1a; top 是一个命令行工具&#xff0c;用于实时监控系统的进程、CPU、内存和负载情况。您可以使用以下命令来启动 top&#xff1a; top 输出 2. htop&#xff1a; htop 是一…

【MySQL】数据库基础

今天我们来讲一讲使用MySQL必备的基础知识 目录 一、MySQL的登录选项 二、什么是数据库 三、一些主流数据库 四、 服务器&#xff0c;数据库&#xff0c;表关系 五、mysql的架构 5.1 存储引擎 5.1.1 查看存储引擎 5.1.2 不同存储引擎的对比 六、SQL语言的分类 一、MyS…