【QT开发(4)】Qt Creator编译器修改,应用程序二进制接口(ABI)的版本;API、ABI、系统调用是什么?版本的选择(ABI和CPU版本)

文章目录

  • 1.编译器的简介
  • 2 应用程序二进制接口(ABI)的版本
  • 3 API、ABI、系统调用是什么,以及这三个词的区别。
    • 3.1 什么是API?
    • 3.2 什么是ABI?
    • 3.3 API和系统调用有什么区别
  • 4 Qt for Android——关于版本的选择(ABI和CPU版本)
  • 参考

1.编译器的简介

编译器就是将“高级语言”翻译为“机器语言(低级语言)”的程序,在之前的博客3月25日 编译的四个过程不明白的可以看看。

几个常见的编译器:

(1)GCC(GNU Compiler Collection) 是一个针对于Linux和OS X的编译器。
(2)MinGW(Minimalist GNU for Windows)是一个GCC和GNU Binutils的原生软件端口,用于在Windows上开发原生的Microsoft Windows应用程序。MinGW和Qt Creator以及Qt installers for Windows一起发布。
(3)MSVC:微软的可视C++开发平台。在qt5.9以前,windows版本细分了一些版本,包括MinGW和MSVC,其中MSVC用的VS编译器,还需要安装一些Visual C++的库什么的,总之,如果你的电脑中没有安装VS那就不要安装这个版本了,否则使用时编译通不过。而在之后的版本中,就没有了这种细分,所以我们可以发现5.9之后的安装包都要比之前的大不少。
(4)Linux ICC (Intel C++ Compiler)是针对于Linux的C和C ++编译器。
(5)Clang是一个针对于Windows、Linux和OS X的C、C++、Objective C轻量级编译器。
(6)QCC是编译QNX的C++应用程序的接口。
(7)Custom自定义编译器,需手动添加编译器路径。

想要使用GCC、MinGW、Clang或QCC构建一个应用程序:

  • 首先指定路径到编译器所在的目录中,
  • 然后从可用版本的列表中选择应用程序二进制接口(ABI)的版本,也可以创建一个自定义的ABI定义。

例如设置,编译器类型为GCC

【QT开发(4)】Qt Creator编译器修改,应用程序二进制接口(ABI)的版本;API、ABI、系统调用是什么?版本的选择(ABI和CPU版本)_第1张图片

想要复制所选择的编译器,可以选择Clone。

  1. 在Name字段中,输入编译器的名称以便在Qt Creator中定义它。

  2. 在Compiler path字段中,输入路径到编译器所在的目录中。

  3. 在Platform codegen flags字段中,检查在目标平台中指定架构传递给编译器的标志。

  4. 在Platform linker flags字段中,检查在目标平台上指定架构传递给连接器的标志,当构建Qbs时只能使用连接器标志。其他设置依赖于编译器的指定。

  5. 在ABI字段中,为目标架构提供一个标识,用来警告包中错误的ABI配置。

2 应用程序二进制接口(ABI)的版本

ABI(Application Binary Interface):应用程序二进制接口,描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低接口。它描述了应用程序与OS之间的底层接口。

一套完整的ABI(比如:Intel Binary Compatibility Standard (iBCS)),可以让程序在所有支持该ABI的系统上运行,而无需对程序进行修改。

ABI掩盖了各种细节,例如:

  • 调用约定控制着函数的参数如何传送以及如何接受返回值;
  • 系统调用的编码和一个应用如何向操作系统进行系统调用;
  • 以及在一个完整的操作系统ABI中,对象文件的二进制格式、程序库、目标文件格式、数据类型、数据对齐、函数调用约定以及函数如何传递参数、如何返回值、系统调用号、如何实现系统调用等。

一个完整的ABI,像 Intel二进制兼容标准 (iBCS) ,允许支持它的操作系统上的程序不经修改在其他支持此ABI的操作系统上运行。

其他的 ABI 标准化细节包括C++ name decoration和同一个平台上的编译器之间的调用约定,但是不包括跨平台的兼容性。在Unix的操作系统中,存在很多运行在同一件平台上互相相关但是不兼容的操作系统(尤其是80386兼容系统)。

【QT开发(4)】Qt Creator编译器修改,应用程序二进制接口(ABI)的版本;API、ABI、系统调用是什么?版本的选择(ABI和CPU版本)_第2张图片

3 API、ABI、系统调用是什么,以及这三个词的区别。

简单介绍一下API、ABI、系统调用是什么,以及这三个词的区别。

这些词在习惯于像 C 这样的低级编程语言的工程师中是众所周知的,它必须考虑程序的二进制表达式。然而,最近大多数开发人员通常不知道这类知识,因为他们通常使用 Python 等高级语言。

我猜 API 对大多数开发人员来说意味着 Web API。此外,他们听说过 ABI 和系统调用,但不知道这些是什么。为了缓解这种情况,我会尽量简单地解释这些词的含义。

3.1 什么是API?

ABI不同于API ,API定义了源代码和库之间的接口,因此同样的代码可以在支持这个API的任何系统中编译 ,然而ABI允许编译好的目标代码在使用兼容ABI的系统中无需改动就能运行。

API 是(Application Programming Interface)应用程序编程接口的首字母缩写。它是对源代码级别的函数(包括 OOPL 中的方法)的规范,这个函数是什么,应该设置什么样的参数,以及返回值是什么。它不负责这些的二进制表达式。

该示例是我在第一节中描述的 Web API。它定义了我们应该访问什么 URL 以及应该设置什么样的数据来从网站获取服务。现在的API和Web API都在使用,没有区别,现在我们理解Web API就是Web服务的API。换句话说,API 是比 Web API 更广泛的词。

我将使用以下 C 源代码再展示一个 API 示例。

int plus(int x, int y) {
  return x + y;
}

int main(void) {
  int a = 1;
  int b = 2;
  ..
  plus(a, b):
  ..
}

在本源代码中,plus() 函数的 API 如下。

  • 返回第一个参数和第二个参数之和
  • 参数和返回值的类型都是int

这里 API 并不关心更多的细节,比如 int 类型有多少字节。

3.2 什么是ABI?

ABI 来自应用程序二进制接口。它定义了函数和数据的二进制表达式。它定义了比 API 更详细的规范。它负责一个参数占用多少字节以及数据应该设置在哪里,例如堆栈顶部或 CPU 的寄存器。在某些情况下,它还定义了数据的字节序。

如果您对 x86_64 CPU 架构有基本的了解,还请参见以下 URL。

  • [calling convention维基百科页面
  • System V 应用程序二进制接口-> “3.2 函数调用序列”

例如,当从非 C 语言调用像 C 库这样的二进制库时,您应该考虑 ABI

3.3 API和系统调用有什么区别

理解 API 和系统调用之间的区别有点困难。但是,现在您可以理解它,因为您知道 API 和 ABI 是什么。

我将解释 POSIX C API、Linux 的 C API 和 Linux 的系统调用之间的区别。首先,POSIX 是类 Unix 操作系统的国际标准。 POSIX API 定义了很多东西,比如 POSIX C API,即访问操作系统服务的 C API。

Linux C API 是访问 Linux 服务的 C API。 Linux 尽量提供 POSIX C API 以兼容 POSIX C API。但是,这些与以下不同。

  • Linux 的 C API 中的一些函数与 POSIX 不兼容
  • Linux 不提供某些 POSIX C API
  • Linux提供了许多POSIX不存在的功能

系统调用是操作系统的接口。 Linux 为开发人员提供了许多系统调用,也提供了许多 C API 来使用这些系统调用。此外,本质上,我们必须执行特殊的 CPU 指令才能使用具有 CPU 相关系统调用 ABI 的系统调用。如果你对 Linux 的系统调用 API 感兴趣,请参考这个文档的 A.2.1 调用约定。它定义了 x86_64 CPU 的系统调用 ABI。

有趣的是,Linux 的 C API 中有许多函数不使用与这些函数同名的系统调用。比如Linux提供了fork()函数,但是这个函数是通过clone()系统调用来实现的。

描述了以下内容。

  • API、ABI 和系统调用是什么
  • 这两个词有什么区别
  • POSIX C API、Linux的C API、系统调用有什么区别

如今,这种知识对许多开发人员来说并不重要。但是,总有一天,您必须与低层编程作斗争。那么这篇文章会对你很有帮助。

4 Qt for Android——关于版本的选择(ABI和CPU版本)

开发Qt for Android程序的时候,不知道如何选择套件的版本,乱选一通,经常是程序开发完,到了运行选择设备的时候告诉我设备不匹配,不支持这个ABI。下面就来讲讲这些版本。

Qt中套件对应的版本

在我们安装Qt的时候,会有Android相关的选项供我们勾选,我选择了如下图所示的三个选项:
【QT开发(4)】Qt Creator编译器修改,应用程序二进制接口(ABI)的版本;API、ABI、系统调用是什么?版本的选择(ABI和CPU版本)_第3张图片
从名字已经可以很直观的看到 ,每个版本对应的是哪个ABI和CPU架构。我记得当时是全选了,5.12.2版的Qt貌似只提供了这三个Android的版本。

套件版本和CPU的关系

对于这两者之间的关系,有一个向下兼容的原则。选择哪个套件来构建工程,取决于你的手机CPU的架构,比如你的安卓手机CPU的架构是ARMv7,那么它可以运行armeabi-v7a编译生成的程序,也能兼容ARMv5,但是Qt没有提供这个版本。如果CPU架构是ARMv8,那么套件可以选择arm64-v8a,也能选择armeabi-v7a。

总而言之一个原则,构建工程的套件版本不能高于手机CPU架构的版本,它只能兼容比它低的版本。

详细的对应关系,如下图所示 (图片来源网络,抱歉我忘记是哪篇博客了,如果侵权请联系):
【QT开发(4)】Qt Creator编译器修改,应用程序二进制接口(ABI)的版本;API、ABI、系统调用是什么?版本的选择(ABI和CPU版本)_第4张图片

引入第三方库

如果想要引入第三方库,并且是用Android相关套件编译生成的库,那么同样需要注意版本的问题。跟上面一样,也是向下兼容。编译库文件所选择的套件版本,不能高于引入它的工程的套件版本。

比如我有个库文件叫libAndroid.a,我的工程要引入它,如果我的工程用的是arm64-v8a,那么编译库文件的时候套件可以选择arm64-v8a,也能选择armeabi-v7a;如果工程用的是armebi-v7a,那么编译库文件的时候套件就不能选择arm64-v8a了。

总结
以上就是在选择构建套件版本的选择问题,不是太深,但是作为C++人员来说,进行Qt for Android的开发应当是够用了。如果有存在问题的地方请不吝赐教,感谢!

参考

https://blog.csdn.net/xi_gua_gua/article/details/56999099
https://blog.csdn.net/xi_gua_gua/article/details/56999099
https://devpress.csdn.net/linux/62eed4a0c6770329307f4243.html
https://blog.51cto.com/xiaohaiwa/5437306
https://blog.csdn.net/zhounixing/article/details/89886636/

你可能感兴趣的:(嵌入式数据结构C++工具链,qt,开发语言)