clang编译内核_c 各种编译器(gcc clang)-程序员宅基地

技术标签: clang编译内核  

很多时候,出现一些类似GNU,GCC,CLANG,LLVM等与编译器有关的名词的时候,都不太清楚它到底是干嘛的,理解这些东西后,

对于xcode中很多配置型的需求修改起来都会得心应手,因此有必要了解透彻他们直接的关系与区别。

1 GUN

“GNU,名称来自Gnu's Not Unix"的缩写,一个类UNIX的操作系统,由GNU计划推动,目标在于创建一个完全兼容于UNIX的自由软件环境。”

由于当时UNIX系统是商业软件,是收费的,而且有一部分源码是没有开放的,所以在1983年,理查德·斯托曼提出GNU计划,希望发展出一套完整的开放源代码操作系统来取代Unix,计划中的操作系统,名为GNU。

因此,GNU的出现的目的就是为了取代UNIX系统。

但是操作系统是包括很多软件的,除了操作系统内核之外,还要有编辑器,编译器,shell等等一些软件来支持。

1989年,GNU项目中的其他部份,如编辑器、编译器、shell等都已经完成,独缺操作系统核心。1990年,自由软件基金会开始正式发展Hurd,作为GNU项目中的操作系统。

注意:linux并不是GNU计划的一部分。linux只是使用了许多GNU计划软件(包括GCC编译器,文本编译器等)。

1991年,Linux出现,所有GNU项目中,运行于用户空间的软件,都可以在Linux上使用。许多开发者转向于Linux,Linux成为常见的GNU计划软件运行平台。理查德·斯托曼主张,Linux操作系统使用了许多GNU计划软件,应正名为GNU/Linux,但没有得到Linux社区的一致认同,形成GNU/Linux命名争议。

1992年,Linux与其他GNU软件结合,完全自由的操作系统正式诞生。许多程序员参与了Linux的开发与修改,也经常将Linux当成开发GNU计划软件的平台。该操作系统往往被称为“GNU/Linux”或简称Linux。但Linux本身不属于GNU计划的一部份,GNU计划自己的内核Hurd依然在开发中,但直到2013年为止,都还没有稳定版本发布。

GNU工程十几年以来已经成为一个对软件开发主要的影响力量,创造了无数的重要的工具,例如:强健的编译器,有力的文本编辑器,甚至一个全功能的操作系统。这个工程是从1984年麻省理工学院的程序员理查德·斯托曼的想法得来的,他想要创建一个自由的、和UNIX类似的操作环境。从那时开始,许多程序员聚集起来开始开发一个自由的、高质量、易理解的软件。

GNU计划采用了部分当时已经可自由使用的软件,例如TeX排版系统和X

Window视窗系统等。不过GNU计划也开发了大批其他的自由软件,这些软件也被移植到其他操作系统平台上,例如Microsoft

Windows

许多UNIX系统上也安装了GNU软件,因为GNU软件的质量比之前UNIX的软件还要好。

所以,GNU计划中的许多软件目前在所有的操作系统中都应用广泛(Unix,mac,linux,windows,bsd...),最出名的就是GCC了

总结:

GNU计划本来是为了开发一个自由系统来取代UNIX的,但是由于开发的内核hurd一直不怎么样,这个系统至今都没出稳定版本,然而GNU计划中开发的其他一些自由软件,比如GCC编译器,却非常的好,在移植到各大操作系统上一直广泛使用至今。

注意一点:

文中说的自由软件,千万别与免费软件混淆了,自由是说你可以自由的使用,当然前提是获得了源码才能自由的使用。

比如,你在一个应用里面使用了gcc计划的软件,你卖自己的应用多少钱你自己定。免费的软件不一定是开源的。

2. GCC

“ GCC(GNU Compiler Collection,GNU编译器套装),是一套由GNU开发的编程语言编译器。它是一套以GPL及LGPL许可证所发布的自由软件,也是GNU项目的关键部分,亦是自由的类Unix及苹果电脑Mac

OS X操作系统的标准编译器。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。

GCC原名为GNU C语言编译器(GNU C Compiler),因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。之后也变得可处理Fortran、Pascal、Objective-C、Java、Ada,以及Go与其他语言。

原本用C开发,后来因为LLVM、Clang的崛起,令GCC更快将开发语言转换为C++。许多C的爱好者在对C++一知半解的情况下主观认定C++的性能一定会输给C,但是Taylor给出了不同的意见,并表明C++不但性能不输给C,而且能设计出更好,更容易维护的程序 ”

由于GCC已成为GNU系统的官方编译器(包括GNU/Linux家族),它也成为编译与创建其他操作系统的主要编译器,包括BSD家族、Mac

OS X、NeXTSTEP与BeOS。

GCC通常是跨平台软件的编译器首选。有别于一般局限于特定系统与运行环境的编译器,GCC在所有平台上都使用同一个前端处理程序,产生一样的中介码,因此此中介码在各个其他平台上使用GCC编译,有很大的机会可得到正确无误的输出程序。

总结:

mac之前的cocoa框架便是用GCC编译的,所以ios与mac os都是默认使用的GCC编译器(现在是clang与llvm,下面会有介绍)

android的系统层因为是linux内核,自然也是GCC编译的,但是android的app因为是运行在Dalvik虚拟机,所以用的不是GCC。

windows的应用,大部分都是使用的vs系列的编译器,毕竟是windows自家的编译器,用到GCC的不多。

3.Clang

它的目标是提供一个GNU编译器套装(GCC)的替代品。 Clang项目包括Clang前端和Clang静态分析器等。

这个软件项目在2005年由苹果电脑发起,是LLVM编译器工具集的前端(front-end),目的是输出代码对应的抽象语法树(Abstract

Syntax Tree, AST),并将代码编译成LLVM Bitcode。接着在后端(back-end)使用LLVM编译成平台相关的机器语言 。Clang支持C、C++、Objective

C。

Clang本身性能优异,其生成的AST所耗用掉的内存仅仅是GCC的20%左右。FreeBSD 10将Clang/LLVM作为默认编译器.

测试证明Clang编译Objective-C代码时速度为GCC的3倍,还能针对用户发生的编译错误准确地给出建议。

总结:

GCC目前作为跨平台编译器来说它的兼容性无异是最强的,兼容最强肯定是以牺牲一定的性能为基础的,苹果为了提高性能,因此专门针对mac系统开发了专用的编译器clang与llvm,clang用于编译器前段,llvm用于后端。

3.LLVM

LLVM,它是一个编译器的基础建设,以C++写成。它是为了任意一种编程语言写成的程序,利用虚拟技术,创造出编译时期,链结时期,运行时期以及“闲置时期”的优化。

在Xcode4之后,苹果将Xcode的默认编译器变成了LLVM,为什么呢?

LLVM历史

Apple(包括中后期的NeXT) 一直使用GCC作为官方的编译器。GCC作为开源世界的编译器标准一直做得不错,但Apple对编译工具会提出更高的要求。

一方面,是Apple对Objective-C语言(甚至后来对C语言)新增很多特性,但GCC开发者并不买Apple的帐——不给实现,因此索性后来两

者分成两条分支分别开发,这也造成Apple的编译器版本远落后于GCC的官方版本。另一方面,GCC的代码耦合度太高,不好独立,而且越是后期的版本,

代码质量越差,但Apple想做的很多功能(比如更好的IDE支持)需要模块化的方式来调用GCC,但GCC一直不给做,从根本上限制了LLVM-GCC

的开发。 所以,这种不和让Apple一直在寻找一个高效的、模块化的、协议更放松的开源替代品,于是Apple请来了编译器高材生Chris

Lattner, LLVM就这样产生了。

Clang历史

Apple吸收Chris

Lattner的目的要比改进GCC代码优化宏大得多——GCC系统庞大而笨重,而Apple大量使用的Objective-C在GCC中优先级很低。此

外GCC作为一个纯粹的编译系统,与IDE配合得很差。加之许可证方面的要求,Apple无法使用LLVM

继续改进GCC的代码质量。于是,Apple决定从零开始写 C、C++、Objective-C语言的前端 Clang,完全替代掉GCC。

正像名字所写的那样,Clang只支持C,C++和Objective-C三种C家族语言。2007年开始开发,C编译器最早完成,而由于Objective-C相对简单,只是C语言的一个简单扩展,很多情况下甚至可以等价地改写为C语言对Objective-C运行库的函数调用,因此在2009年时,已经完全可以用于生产环境。C++的支持也热火朝天地进行着。

更详细的原因:

总结:

因为GCC的编译器已经慢慢无法满足苹果的需求,因此,苹果开发了Clang与LLVM来完全取代GCC,Xcode4之后,苹果的默认编译器已经是LLVM了。Clang作为编译器前端,LLVM作为编译器后端。

在Xcode6.0中查看默认编译器:

4.编译器相关知识

问题:苹果以clang作为编译器前端,llvm作为编译器后端,那么编译器的前后端到底是什么东西呢?

我们先回到一个常识性的问题,什么是编译器呢?简单地说,编译器可以看作是一个语言翻译器。就像把中文翻译成英语一样,编译器可以把高级语言翻译成计算机能够执行的机器语言。这样看来,GCC可以算得上是一个精通多国语言的高级翻译官了。

最简单的GCC使用指令如下所示:

gcc  hello.c  -o  hello

GCC接受hello.c作为输入,最后产生目标可执行代码hello。这个简单的流程实际上经历了很多步骤,如下图所示:

虽然我们只用了一条命令就完成了编译,但实际上gcc命令依次呼叫了cpp,gcc自己,gas以及ld来进行完整的编译流程,最后生成最终的可执行文件hello。

学过编译原理这门课程的同学对下面这副图应该很熟悉,这是经典的编译流程。

下面以GCC编译器为例,GCC作为经典的编译器,自然也是遵循这个教科书流程(实际GCC的处理更复杂点,但本质上是一样的)。我们先简化一下上面这幅图,以中间代码为分界,前面的词法分析、语法分析、语义分析我们把它称之为前端处理,后面的优化和目标代码生成我们称之为后端处理。

试想一下,是否可以为不同的高级语言单独写一个前端,然后为不同的处理器架构单独写一个后端呢?

GCC基本上也是这么实现的,不过不要误会,并没有一个统一的gcc执行程序能够处理如此多的前端和后端,每个语言的编译器都是一个独立的程序(如C语言

的编译器是gcc,C++的编译器是g++),而不同的后端也要对应不同的可执行程序。你可以下载单独的一份GCC源代码,通过不同的configure

来生成自己需要的编译器。

而且,编译器的实现也比上图要复杂的多,前端的主要功能是产生一个可供后端处理的语法树,而语法树结构实际上很难与处理器架构脱钩,这些都是编译器应用中需要解决的问题。

GCC强大的真正原因是什么?是因为它支持了众多的前端和后端吗?这些都不过是一个表象而已。GCC是一款真正自由的编译器,我们可以随时把代码拿过来修

改以实现自己需要的功能。如果你的硬件平台增加了一些指令,而普通的编译器并不能产生这些指令怎么办?在GCC后端添加这些指令吧。如果你觉得C语言用的

不太顺手,想给它添加一些功能怎么办?修改GCC的前端吧。因为有了GCC,我们才拥有这些自由,以及迅速实现自己想法的能力,而这些才是GCC强大背后

的基础。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39921504/article/details/111484859

智能推荐

数字化证券:未来金融市场的驱动力-程序员宅基地

文章浏览阅读665次,点赞6次,收藏15次。1.背景介绍数字化证券是一种基于数字技术的金融产品,它利用区块链、人工智能、大数据等技术,为金融市场创造了一种全新的交易体验。这种新型金融产品的出现,不仅为金融市场带来了更高的效率和安全性,还为金融市场的发展提供了新的动力。数字化证券的发展历程可以分为以下几个阶段:初期阶段:数字化证券的诞生。在这个阶段,数字化证券的主要特点是基于数字技术的金融产品,它们利用区块链、人工智能、大数据等...

MATLAB对于矩阵函数的使用_logspace-程序员宅基地

文章浏览阅读4k次,点赞4次,收藏18次。MATLAB对于矩阵的使用1.单位矩阵eye(n)生成n*n的单位矩阵eye(n,m)生成n*m的单位矩阵eye(size(B))生成与B同样大小的单位矩阵2、全1矩阵ones (n) 生成n*n的全1矩阵ones (n,m) 生成n*m的全1矩阵ones(size(B)) 生成与B同样大小的全1矩阵ones(1,2)生成一行两列的..._logspace

驱动(设备驱动程序)到底是个什么玩意儿 stm32裸机驱动 linux平台总线设备驱动 USB驱动(usb driver)就是USB设备的接口驱动程序_stm32.驱动程序是什么意思-程序员宅基地

文章浏览阅读1.6k次。自己的总结我们在写stm32的裸机项目时,是怎么写一个iic驱动和IIC设备驱动的,要写哪些内容?1.配置iic总线对应的引脚GPIO,2.iic是数据传输协议,所以要写实现IIC的读写函数,3.然后就是写iic设备的驱动,也就是调用IIC总线的读写函数实现设备的读写函数。4.一般情况下写设备驱动时,要先写设备初始化等等对比linux的平台总线驱动模型写得很好的一篇文章----------一定要看原文链接:https://blog.csdn.net/pengliang528/article_stm32.驱动程序是什么意思

JAVA框架-程序员宅基地

文章浏览阅读783次,点赞18次,收藏20次。springboot是工具集,轻量级,整合了其他框架,方便开发,减少了配置约定大于配置Mybatis是一款持久层框架(Dao)框架,支持持久化SQL、存储过程及高级映射。Mybatis避免了几乎所有JDBC代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。且有缓存机制,可以提高查询效率。

ROS系统中从零开始部署YoloV4目标检测算法(3种方式)_detection_msgs-程序员宅基地

文章浏览阅读5k次,点赞8次,收藏143次。1 封装darknet框架为dll方式暂略2 封装TensorFlow或pytorch框架为dll方式暂略3 调用OpenCV中DNN模块方式3.0 需求说明在ROS系统下创建一个package目标检测程序,订阅realsense传感器的RGB流,进行行人检测,然后将检测结果信息发布出去。包和节点名称定义:该目标检测package名称为:detection_pkg 开展目标检测的节点名称为:yolo4 发布检测结果的节点名称为:yolo4_result接口定义:目标_detection_msgs

Windows共享文件夹与Iphone传输文件_iphone共享文件夹只读-程序员宅基地

文章浏览阅读5.8k次。文章目录Windows共享文件夹与Iphone传输文件一 Windows设定共享文件夹1.1 创建共享文件夹1.2 文件操作设置1.3 Windows-PC IP地址1.4 Windows-PC 登陆用户名和密码1.5 网络类型选择1.6 防火墙二 Iphone设定2.1 连接与PC机同一网段内2.1 打开文件,点击右上角三个点2.3 选择连接服务器2.4 登陆PC机账户和密码,点击下一步2.5 登陆成功之后,可以操作Windos系统下分享的共享文件夹内容Windows共享文件夹与Iphone传输文件_iphone共享文件夹只读

随便推点

Spring思维导图,让Spring不再难懂(mvc篇)-程序员宅基地

文章浏览阅读520次。2019独角兽企业重金招聘Python工程师标准>>> ..._multipartfile xmind

jdk tomcat环境变量配置-程序员宅基地

文章浏览阅读132次。1.安装JDK安装好JDK后,再配置JDK的环境变量:在“我的电脑”上点右键—>“属性”—>“高级”—> “环境变量(N)”。新建系统变量JAVA_HOME:C:/Program Files/Java/jdk1.5.0_06;新建系统变量CLASSPATH:.;%JAVA_HOME%/lib;(注意:点号表示当前目录,不能省略)在系统变量Path的值的前面加入..._新建 catalina_home:d:\jakarta-tomcat-5.0.30 在classpath 中加入 catalina_home

Spring容器中同名 Bean 加载策略_spring 对同名不同类的bean如何加载的-程序员宅基地

文章浏览阅读1.5k次。场景描述:两个同名 bean,均通过 xml 的 bean 标签声明。其实这就是上面的场景了。可以看出,最终使用的是后面的 xml 中声明的 bean。其实原因是“后面的 xml 中声明的 bean”把“前面的 xml 中声明的 bean”覆盖了。我们可以看到 Bebug 信息:scope=;scope=;_spring 对同名不同类的bean如何加载的

C语言伽罗华域乘法,伽罗瓦域上的乘法-程序员宅基地

文章浏览阅读1.3k次。一、前言伽罗瓦域上的乘法在包括加/解密编码和存储编码中经常使用,常见的AES 和Reed-Solomon 编码就使用了伽罗瓦域GF(28) 中的运算。以2 或者2w 形式的伽罗瓦域来说,加减法都是异或运算,乘法相对较复杂一些,本文就GF(2w) 上有限域的乘法运算和优化进行分析。现代计算机是为二进制普通运算所设计,对伽罗瓦域计算最多仅有指令集上的优化,而且仅限于某些处理器,因此在更高层次上优化伽罗..._面向伽罗瓦域的计算器

VBA使用PING测试网络连接_vba ping ip-程序员宅基地

文章浏览阅读3.4k次,点赞4次,收藏9次。Ping是测试网络连接的一个常用命令,可以向特定的目的主机(某个IP)发送 ICMP(Internet Control Message Protocol 因特网报文控制协议)Echo 请求报文,根据返回数据包的情况,可以了解其有关状态,当然某些服务器可以设置不响应ICMP消息,那么PING这些服务器得到的结果也就无效了。使用VBA开发一下和Internet相关的应用时,经常需要先测试网络主机是否可以触达,这时就需要使用PING命令,但是VBA中并没有提供这个命令,需要借助Wscipt来实现。_vba ping ip

使用Spring+CXF开发WebService-程序员宅基地

文章浏览阅读40次。Apache CXF 提供方便的Spring整合方法,可以通过注解、Spring标签式配置来暴露Web Services和消费Web Services各种类型的Annotation。@WebService和@WebMethod是WSDL映射Annatotion。这些Annotation将描述Web Service的WSDL文档元素和Java源代码联系在一起。@SOAPBind..._spring cxf sch=

推荐文章

热门文章

相关标签