简述 LLVM 与 Clang 及其关系 (c++ 编译 文章三)

2024-03-16 11:48

本文主要是介绍简述 LLVM 与 Clang 及其关系 (c++ 编译 文章三),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

可以简单理解为 clang 编译器的前端,负责解析源代码,检查语法错误,并将其翻译为抽象的语法树(或者简单理解为把代码翻译成中间代码),狭义的llvm是编译器的后端,负责优化中间代码和把中间代码转换为目标机器的代码。和java有点像,生成与系统无法的中间代码,之后在jvm上运行。

 

 

------------------------------------------------------------------------------------------------

随着 Android P 的逐步应用,越来越多的客户要求编译库时用 libc++ 来代替 libstdc++。libc++ 和 libstdc++ 这两个库有关系呢?它们两个都是 C++ 标准库,libc++ 是针对 Clang 编译器特别重写的 C++ 标准库,而 libstdc++ 则是 GCC 的对应 C++ 标准库了。从 Android 市场来说,Android NDK 已在具体应用中放弃了 GCC,全面转向 Clang,正如很早前 Android NDK 在 Changelog 中提到的那样:

Everyone should be switching to Clang. 
GCC in the NDK is now deprecated.

Android NDK 从 r11 开始建议大家切换到 Clang,并且把 GCC 标记为 deprecated,将 GCC 版本锁定在 GCC 4.9 不再更新; 
Android NDK 从 r13 起,默认使用 Clang 进行编译,但是暂时也没有把 GCC 删掉,Google 会一直等到 libc++ 足够稳定后再删掉 GCC; 
Android NDK 在 r17 中宣称不再支持 GCC 并在后续的 r18 中删掉 GCC,具体可见 NDK 的版本历史。

接下来,简要的介绍一下 Clang。Clang 是一个 C、C++、Objective-C 和 Objective-C++ 编程语言的编译器前端,采用底层虚拟机(LLVM)作为后端。至于为什么有了 GCC 还要开发 Clang?Clang 相比 GCC 又有什么优势呢?网上有很多信息可以参考,这里只简单提两点:(1)Clang 采用的是 BSD 协议的许可证,而 GCC 采用的是 GPL 协议,显然前者更为宽松;(2)Clang 是一个高度模块化开发的轻量级编译器,编译速度快、占用内存小、有着友好的出错提示。

然后说下 Clang 背后的 LLVM(Low Level Virtual Machine)。LLVM 是以 BSD 许可来开发的开源的编译器框架系统,基于 C++ 编写而成,利用虚拟技术来优化以任意程序语言编写的程序的编译时间、链接时间、运行时间以及空闲时间,最早以 C/C++ 为实现对象,对开发者保持开放,并兼容已有脚本。LLVM 计划启动于 2000 年,最初由 University of Illinois at Urbana-Champaign 的 Chris Lattner 主持开展,2006 年 Chris Lattner 加盟苹果公司并致力于 LLVM 在苹果公司开发体系中的应用,所以苹果公司也是 LLVM 计划的主要资助者。目前 LLVM 因其宽松的许可协议,更好的模块化、更清晰的架构,成为很多厂商或者组织的选择,已经被苹果 IOS 开发工具、Facebook、Google 等各大公司采用,像 Swift、Rust 等语言都选择了以 LLVM 为后端。

在理解 LLVM 之前,先说下传统编译器的工作原理,基本上都是三段式的,可以分为前端、优化器和后端。前端负责解析源代码,检查语法错误,并将其翻译为抽象的语法树;优化器对这一中间代码进行优化,试图使代码更高效;后端则负责将优化器优化后的中间代码转换为目标机器的代码,这一过程后端会最大化的利用目标机器的特殊指令,以提高代码的性能。基于这个认知,我们可以认为 LLVM 包括了两个概念:一个广义的 LLVM 和一个狭义的 LLVM 。广义的 LLVM 指的是一个完整的 LLVM 编译器框架系统,包括了前端、优化器、后端、众多的库函数以及很多的模块;而狭义的 LLVM 则是聚焦于编译器后端功能的一系列模块和库,包括代码优化、代码生成、JIT 等。

下面大概讲一讲 LLVM 和 Clang 的关系。我们将它们对应于传统的编译器当中的几个独立的部分,这样能够更加方便明确的表述出它们之前的关系。

 

对应到这个图中,可以非常明确的找出它们的关系。整体的编译器架构就是 LLVM 架构;Clang 大致可以对应到编译器的前端,主要处理一些和具体机器无关的针对语言的分析操作;编译器的优化器和后端部分就是之前提到的 LLVM 后端,即狭义的 LLVM。

此外,由于 LLVM 的命名最早源自于底层虚拟机(Low Level Virtual Machine) 的首字母缩写,但这个项目的范围并不局限于创建一个虚拟机,这个缩写导致了大量的疑惑。LLVM 成长之后已成为众多编译工具及低级工具技术的统称,使得这个名字变得更不贴切,所以开发者决定放弃这个缩写的涵义,现在 LLVM 已独立成为一个品牌,适用于 LLVM 下的所有项目,包括 LLVM 中介码、LLVM 除错工具、LLVM C++ 标准库等。
--------------------- 
作者:艾蔓草 
来源:CSDN 
原文:https://blog.csdn.net/xhhjin/article/details/81164076 
版权声明:本文为博主原创文章,转载请附上博文链接!

这篇关于简述 LLVM 与 Clang 及其关系 (c++ 编译 文章三)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/815405

相关文章

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

C++作用域和标识符查找规则详解

《C++作用域和标识符查找规则详解》在C++中,作用域(Scope)和标识符查找(IdentifierLookup)是理解代码行为的重要概念,本文将详细介绍这些规则,并通过实例来说明它们的工作原理,需... 目录作用域标识符查找规则1. 普通查找(Ordinary Lookup)2. 限定查找(Qualif

C/C++ chrono简单使用场景示例详解

《C/C++chrono简单使用场景示例详解》:本文主要介绍C/C++chrono简单使用场景示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录chrono使用场景举例1 输出格式化字符串chrono使用场景China编程举例1 输出格式化字符串示

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元