交叉编译qt源码常见问题-交叉编译原生缓冲(QtonAndroid)。

原因

笔者在Qt开发的桌面应用中使用了protobuffer消息传输合约,现在需要移植到Android手机上,为了节省开发时间,我不准备改变服务器程序(如果我不继续在移动应用上使用protobuffer合约,我将面临改变服务器程序和提供JSON消息格式供移动使用)。为了充分发挥Qt的跨平台特性,在QtforAndroid下使用了桌面程序的通信模块,决定针对Android手机编译arm版本的probuffer库。我计划在Unbuntu下交叉编译原型缓冲区动态链接库,然后在Windows下的QtforAndroid开发环境中使用它。

绕道一趟

本段记录了图书馆

GNUGCC编译在最初编译protobuffer库时遇到的函数调用问题,不感兴趣的读者可以直接跳过这一段,从“正式编译”一章开始。最初,作者的开发和编译环境如下:

安卓开发环境:

- 视窗 1064 位

-Qtfor安卓5.12-

安卓-NDK-R16B-Windows-x86

原型缓冲库交叉编译环境:

-Unbuntu14.04LTS-

android-ndk-r16b-linux-x86_64

-GNUGCC

-原始缓冲区 3.3.0 源代码

相关下载

普罗托布夫下载地址:

NDK下载地址:后来发现,

在这样的交叉编译环境下编译的原生缓冲库在开发环境中是不支持的交叉编译qt源码常见问题,因为后者QtforAndroid SDK使用的编译器使用的是Clang,而前者的库编译环境使用了GNUGCC。因此,开发环境增加到Qt5.9 + ndkrc15(因为QtforAndroid 5.9仍然使用GNUGCC)。最终遇到了一个问题,调用库函数AppendPartialToString()导致程序崩溃。最后,我在一个美国网站上找到了一个修复程序,说有必要切换到Clang编译器。请参阅以下部分。(应更改脚本文件中涉及的路径以匹配您自己的编译环境。)

编译即将推出

开发和编译环境与上述相同,但不再使用 GNUGCC,使用 Clang 编译工具链(通过 NDK 生成)。

注意:读者可以尝试使用

nkdr18 版本的 ndk,因为在我使用 ndkr16b 的时候,链接在开发环境中遇到了 llvm-readobj.exe 和 llvm-strip.exe 的问题,最后把这两个文件从 ndkr18 复制到指定位置;读者也可以尝试更高版本的原生缓冲库。

1. 首先在 Linux 下编译原型缓冲区

这里我们主要是为了获取编译生成的 protoc 可执行文件,用于将 protobuffer 消息定义文件 .proto 生成为C++文件。

- 编译适用于 Linux 的原始缓冲区库脚本,如下所示:

#!/bin/sh

echo "here"
cd $HOME/Linux/works/protobuff/protobuf-3.3.0
make clean
echo "end"
./autogen.sh
./configure --enable-shared --prefix=$HOME/Linux/works/protobuff_linux
make -j4
make install

如果脚本执行没有问题,将生成以下三个目录

- 以C++文件命令格式生成 .proto 文件:

>原型-I=--cpp_out=

例如:

protoc-I='home/user/Linux/works/protobuffer_linux/bin'--cpp_out='home/user/Linux/works/protobuffer_linux/bin''home/user/Linux/works/protobuffer_linux/ protomessage.proto'

最后,保存生成的protomessage.pb.h和 protomessage.pb.cc 文件,以便在QtforAndroid应用程序项目中使用。

2. 在 ndk 的帮助下生成 Clang 工具链

ndk 附带了生成 clang 工具链的脚本

make-standalone-toolchain.sh,我将执行脚本所需的参数写入新脚本文件的make_clang_toolchain.sh,如下所示:

#!/bin/sh

cd $HOME/Linux/works/android/ndk/android-ndk-r16b/build/tools
./make-standalone-toolchain.sh --arch=arm --platform=android-26 --toolchain=arm-linux-android-clang5.0 --install-dir=$HOME/Linux/works/arm-26-toolchain-clang --use-llvm --stl=libc++

脚本执行后,arm-26-toolchain-clang 目录

包含 clang 编译工具链将在定义的 install-dir 目录中手动生成,该目录将在下面的脚本中使用。

3. 交叉编译原生缓冲库

脚本

arm_combile_clang_ndk_r16.sh内容如下:

export PREFIX=$HOME/Linux/works/protobuf_arm_3.0.0_clang/
export PATH=$HOME/Linux/works/arm-26-toolchain-clang/bin:$PATH
export SYSROOT=$HOME/Linux/works/arm-26-toolchain-clang/sysroot
export CC="arm-linux-androideabi-clang --sysroot $SYSROOT"
export CXX="arm-linux-androideabi-clang++ --sysroot $SYSROOT"
cd $HOME/Linux/works/protobuff/protobuf-3.3.0
make clean
./autogen.sh
./configure --prefix=$PREFIX 
--host=arm-linux-androideabi 
--with-sysroot="${SYSROOT}" 
--enable-shared 
--enable-cross-compile 
--with-protoc=$HOME/Linux/works/protobuff_linux/bin/protoc 
CFLAGS="-march=armv7-a -D__ANDROID_API__=26" 
CXXFLAGS="-frtti -fexceptions -march=armv7-a -D__ANDROID_API__=26" 
LIBS="-llog -lz -lc++_static"
make -j 4
make install

如果上述两个脚本执行没有问题,将在上面定义的 protobuf_arm_3.0.0_clang 目录中形成以下 protobuffer 库文件:

库目录的内容:

将 protoc 文件放在 bin 目录中,这是用于将 protobuffer 消息文件生成到 C++ 文件中的工具的 ARM 版本。我们将使用上面编译的 Linux 版本。

4. 文件名更改

将生成的包含目录复制到您的 QtforAndroid 项目目录,并将其配置为 pro 文件中的 INCLUDEPATH

- 将下面红框中的文件复制到你的QtforAndroidSDK目录下,在你的项目文件下创建一个lib目录,并制作一个副本

复制到:

D:QtQt5.12.15.12.1android_armv7lib 并将 .so.xx.x.x 更改为 .so

5. Qt项目文件.pro的配置

思潮

1. 编译低于 rc15 的 NDK 可能还需要 clang 编译器,而 Qt5.9 不支持,因此通常较低版本的 Qt 会与较低版本的 ndk 配对,反之亦然

Qt也在与时俱进交叉编译qt源码常见问题,QtforAndroid 5.9仍然使用gnugcc编译器,QtforAndroid 5.12使用clang编译器。(作者没有查阅该版本的具体更改)。

3. 安卓NDK很可能是rc15版本以后用clang编译器编译的,否则在配置检测过程中会提示c编译器启动失败;

4.当编译好的动态库在开发环境中使用时遇到错误时,请检查错误日志,如果是链接问题,可以查看C库是否是

在编译过程中连接的是GNU或clang,无论是动态库还是静态库,这样你就可以重新调整你的环境,使开发环境和编译环境相互匹配。

由于作者能力有限,如文中有任何疏忽或不妥之处,欢迎您的原谅。

参考链接

1. 交叉编译简介

1. 什么是交叉编译

1.1 本地编译

在解释什么是交叉编译之前,重要的是要了解一个概念:本地编译

我们之前常见的软件开发属于本地编译:在现在的PC下,在x86 CPU下,程序是

直接编译下来,可以运行的程序(或库文件)可以直接在当前环境中运行,即在x86 CPU下,在当前笔记本下运行。

此时的编译可以称为本地编译,即在当前目标平台下,编译后的程序只能在当前平台下运行。

2.2 交叉编译

交叉编译是与本地编译相对应的概念。

而所谓,交叉编译,就是:编译在

一个平台,编译好的程序,放在其他平台上运行,即编译环境,和运行环境不同,属于cross,这就是所谓的cross。

交叉编译,这个概念,主要与嵌入式开发有关。

例 1.1.. 在 x86 平台上编译并在 ARM 平台上运行

最常见的例子之一是:

在进行嵌入式开发时,

你有一个嵌入式开发板,CPU是在arm之后的x86平台下开发的,比如Ubuntu的Linux,或者Win7之后:

在 x86 平台上,编译代码(使用交叉编译器)。

编译(可执行)程序在目标开发板Arm的CPU上运行

这个所谓的:在x86平台上编译,在ARM平台上运行交叉编译,

通常用英文写交叉编译,也有其他方式:交叉编译、交叉编译等

2. 为什么要进行交叉编译

交叉编译的主要原因是嵌入式系统中的资源太少

具体解释是:交叉编译的程序,要运行的目标环境,各种资源,都比较有限,所以很难进行直接本地编译

最常见的情况是:在进行嵌入式开发时,目标平台,即嵌入式开发板,如最大显存为200MHz的ARM的CPU,加上32M RAM,外加1G的Nand闪存等。在这样硬件资源相对紧张的前提下,在已经运行嵌入式Linux的前提下,直接在嵌入式Linux下编译,在本地编译,在ARM的CPU下编译,为ARM的CPU运行程序是不方便的。由于编译开发需要相对多的CPU、内存、硬盘等资源,而嵌入式开发上的资源只够嵌入式(Linux)系统运行,所以没有多少剩余资源可供你在本地编译。

BusyBox 包含与编译和开发相关的工具,例如

相应地,当你在后期熟悉了嵌入式开发和 Busybox,比如在 Buildroot 中配置 Busybox,或者单独交叉编译 BusyBox:

Ubuntu 为 QEMU 的 arm 平台交叉编译 BusyBox

你会看到后面的 BusyBox 在功能缩减后,已经包含了 一些与编译和开发相关的工具,比如 make 等等

而这个工具,原本只用在PC端,也就是在x86平台下开发的时候,交叉编译的时候,用的工具,现在,在嵌入式环境(BusyBox的)中也支持。

此时,如果在 BusyBox 中选择所有相关的开发工具

此外,如果你的目标开发板的硬件配置足够强大,比如CPU是以GHz为单位测量的,等等

交叉编译qt源码常见问题-交叉编译原生缓冲(QtonAndroid)。

此外,相关的开发库和工具齐全

其实至少在理论上,也可以在你的嵌入式Linux上进行,有限,甚至很大程度上是本地开发,即直接在ARM的开发板上,嵌入式Linux,直接嵌入式开发,本地编译为ARM

比如编译一个helloworld,估计还是有可能的这样,就

不存在,或者换句话说,避免了交叉编译和本地编译。

是制造的

它相当于之前在 x86 PC 端运行的本地编译,编译器放置在 x86 CPU 上

在ARM的CPU为什么要交叉编译qt源码,嵌入式Linux中,它也被实现。

但是,很明显,对于日益复杂的程序或库,直接在ARM开发板上编译的可行性和效率相对较低。

而如果是折腾Uboot之类的东西,目标运行时环境本身,没有完整的(嵌入式Linux)系统,那么在目标平台上实现本地编译就越来越不可能了。

那么只能进行,这里提到,交叉编译

2. 交叉工具链简介

1. 什么是工具链

所谓工具链的含义分为两部分:

a -- 工具工具

,即工具

交叉编译qt源码常见问题-交叉编译原生缓冲(QtonAndroid)。

工具用于工作;这里的工作目标是生成(可运行的)程序或库文件

为了实现这一目标,内部执行流程和逻辑主要包括:

1) 编译

编译的输入(对象)为:程序代码

编译输出(目标)为:目标文件

编译所需的工具是编译器

编译器,俗称 gcc

2) 链接

链接的输入(对象)是:库(文件)(程序运行的基础,或库所依赖的其他基础)。

链接的输出(目的地)是:程序的可执行文件,或者可以被其他人调用的完整库文件链接

所需的工具是链接器

链接器,即LD

那是

这里,为了将程序代码编译成可执行文件,涉及到编译、链接(等步骤),依靠很多相关工具,其核心是编译器GCC,linker ld。这里,所谓工具主要是指:gcc、ld等工具相关的程序编译链接

Binutils包括ld等工具

实际上,上面提到的LD只是处理操作目标文件和二进制文件的最重要工具

还有许多其他与文件相关的工具,例如操作目标:as,objcopy,strip,ar等

所以,在这方面,GNU官网提出了一个binutils,即二进制utils,二进制工具(包),与这个与操作二进制文件相关的工具集合集成在一起,称为binutils

所以,你在那之后看到的常用工具是著名的GNU Binutils。

b -- 链条链

,即链,链

之所以能叫链条,是因为你的意思不止一件事,然后,按照相应的逻辑,把它串在一起,链在一起。相应地,它涉及:

不止一件事:指上面提到的那种工具,即:gcc、binutils等与程序编译链接相关的工具

根据相应的

逻辑:是指根据程序本身进行编译和链接的顺序,即:先编译,再链接,后期再进行其他处理等,如使用objcopy操作对应的目标文件等。

因此,将:像

gcc 和 binutils 等与程序编译链接相关的工具,按照先编译后链接的编译器内部逻辑串在一起,这就变成了我们所说的工具链

2. 什么是跨工具链

通俗地说,工具链是指其当前本地平台的工具链。

用于交叉编译的工具链称为交叉工具链。也就是说,这些工具,即编译的gcc,链接的LD和相关工具,用于交叉编译的工具链,称为交叉工具链。显然,跨

工具链被take,交叉编译,跨平台的程序使用。跨工具链,类似于(本地)工具链,也包含很多相应的工具,GCC、LD、AS 等的交叉编译版本。但是,由于最重要的是用于编译的 GCC,所以我们也经常调用:跨工具链,简称交叉编译器

也就是说,严格来说,交叉编译器仅指GCC的交叉编译版本。但实际上,为了方便其他名称,我们经常提到交叉编译器,指的是交叉工具链。通常被称为 GCC 的交叉编译版本,例如 arm-linux-gcc,实际上是指跨工具链的一系列交叉编译版本(arm-linux-gcc、arm-linux-ld、arm-linux-as 等),在本文中,如果未指定,以下所有内容都使用交叉编译器来引用跨工具链。

总结交叉编译就是在一个平台上编译一个程序,可以在另一个架构不同的平台上运行,比如在PC平台(X86 CPU)上编译一个程序,可以在

以ARM为核心的CPU平台上运行,编译好的程序不能在X86 CPU平台上运行,必须放在ARM CPU平台上运行为什么要交叉编译qt源码, 尽管这两个平台都使用 Linux 系统。交叉编译工具链是由编译器、连接器和协程组成的综合开发环境,交叉编译工具链主要由 binutils、gcc 和 glibc 三部分组成。有时为了减小libc库的大小,可以用其他c库替换glibc,例如uClibc,dietlibc和newlib。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 交叉编译qt源码常见问题-交叉编译原生缓冲(QtonAndroid)。 https://www.wkzy.net/game/131854.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务