前记: 经常浏览博客园的同学应该会觉得本文有标题党之嫌,这个标题的句式来自于MiloYip大牛的大作《C++强大背后》,在此,向Milo兄致意。

GCC,全称GNU Compiler Collection,是一套GNU开发的编译器环境,它的创始人便是大名鼎鼎的Richard.M.Stallman。最初GCC刚开始开发时,它还叫做GNU C Compiler,随着开发的深入,GCC很快得到了扩展,不仅可以支持C语言,还可以处理C++,Pascal,Object-C,Java以及Ada等其他语言。目前,GCC不仅是GNU的官方编译器,也成为编译和创建其他操作系统的编译器,包括BSD家族以及MAC OS X等。另外,GCC也是跨平台交叉编译的首选,它不仅支持Intel的x86系列,同时也支持MIPS,ARM,PowerPC,SPARC等等处理器。可以这么说,即使GCC不是世界上效率最高的编译器,它也一定是世界上最全面的编译器。

1. GCC简介

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

gcc  hello.c  -o  hello

 
GCC接受hello.c作为输入,最后产生目标可执行代码hello。这个简单的流程实际上经历了很多步骤,如下图所示:
虽然我们只用了一条命令就完成了编译,但实际上gcc命令依次呼叫了cpp,gcc自己,gas以及ld来进行完整的编译流程,最后生成最终的可执行文件hello。
下面我们看一下分解动作:

cpp  hello.c  >  hello.i

gcc  -S  hello.i

as  hello.s  -o  hello.o

ld  -dynamic-linker  /lib/ld-linux.so.2  /usr/lib/crt1.o  /usr/lib/crti.o  /usr/lib/gcc/i686-linux-gnu/4.4.5/crtbegin.o -L/usr/lib/gcc/i686-linux-gnu/4.4.5 hello.o  -lgcc  -lgcc_eh  -lc  /usr/lib/gcc/i686-linux-gnu/4.4.5/crtend.o  /usr/lib/crtn.o  -o  hello

 
看完这些步骤有没有晕头转向的感觉呢?对于普通的用户来说,还是让GCC帮我们做这些事情比较好。
对于如何学习使用GCC,可以参考GCC官方的手册,如果大家觉得官方的手册太罗嗦,我这里推荐一本GCC的入门书籍《An Introduction to GCC》,这本书详尽的介绍了GCC的使用方法,内容浅显易懂,很适合初学者。
 

2. GCC强大的背后

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

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

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

GCC基本上也是这么实现的,不过不要误会,并没有一个统一的gcc执行程序能够处理如此多的前端和后端,每个语言的编译器都是一个独立的程序(如C语言的编译器是gcc,C++的编译器是g++),而不同的后端也要对应不同的可执行程序。你可以下载单独的一份GCC源代码,通过不同的configure来生成自己需要的编译器。

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

GCC强大的真正原因是什么?是因为它支持了众多的前端和后端吗?这些都不过是一个表象而已。GCC是一款真正自由的编译器,我们可以随时把代码拿过来修改以实现自己需要的功能。如果你的硬件平台增加了一些指令,而普通的编译器并不能产生这些指令怎么办?在GCC后端添加这些指令吧。如果你觉得C语言用的不太顺手,想给它添加一些功能怎么办?修改GCC的前端吧。因为有了GCC,我们才拥有这些自由,以及迅速实现自己想法的能力,而这些才是GCC强大背后的基础。

2010年1月份的时候,Google的Go语言前端被允许进入GCC编译器家族,GCC更加强大了。

3. GCC的多样性

GCC因为其灵活性被应用到了很多领域和系统,从PC上的开发到嵌入式开发,都可以见到GCC的影子。
 

3.1   PC开发

我们先看看PC。MAC自从投入Intel的怀抱,是否也可以看作是一种PC呢?

Linux

Linux系统应该是GCC的主战场,但也是最没必要去说的一个系统,除了GCC,难道我们还有更好的选择吗?Linux内核、Apache服务器、MySQL数据库,等等一系列伟大的作品都是通过GCC来构建的,GCC可以说是GNU/Linux系统的基石。

MAC OS X

MAC OS X也是GCC的重度用户,其应用程序开发环境Cocoa就是使用的GCC,所以在MAC OS X下开发也是离不开GCC的。

Windows

现在在Windows下开发C/C++程序一般都是用微软的编译器,当年的Borland已经成为传说。但是如果你不想付钱的话,也可以考虑Windows下的GCC。
在Windows下体验GCC最常用的有两种方式:一是在Cygwin下使用GCC,另外一种是使用MinGW。
Cygwin是一个自由软件的集合,最初由Cygnus Solutions开发,目的是在Windows系统上运行类Unix的软件。通过Cygwin编译的程序可以在Windows上运行,但必须使用cygwin.dll。
MinGW(Minimalist GNU for Windows),是将GNU开发工具移植到Windows平台的产物,包括一系列头文件、库和可执行文件,用MinGW开发的程序不需要额外的第三方DLL就可以直接在Windows上运行。Nokia的图形开发包QT在Windows下就是调用MinGW来编译的。

DOS

在DOS系统下也是可以用GCC的,国内的DOS开发者可能更熟悉Turbo C或者Open Watcom,GCC的DOS版本DJGPP其实也是32位DOS程序开发的主流环境之一。最初DJGPP的发起人DJ Delorie曾经询问过Richard Stallman,FSF是否考虑过把GCC移植到MS-DOS下,当时Richard的回答是GCC太庞大,而MS-DOS只不过是个16位的操作系统,所以官方并没有考虑这件事。DJ Delorie并没有因此而退缩,最终给我们带来了这个优秀的开发平台。DJGPP刚开始开发时叫做djgcc,在引入了C++之后改为现在这个名字(DJ's GNU Programming Platform)。
 

3.2   嵌入式开发

对于嵌入式开发领域来说,因为开发板的能力限制,是无法运行编译环境的,这样就需要在PC上通过交叉编译来生成目标可执行程序,GCC的高度灵活性在嵌入式开发上发挥了极大的作用。

Android

看看当今最火的移动平台Android,就是完全用GCC来构建的,请注意,这里指的不是Android应用程序,Android下的应用程序是运行在Dalvik虚拟机上的Java程序。

iOS

Apple的iOS应用程序开发也是用Cocoa来进行,这怎么会离开GCC呢?

MeeGo/Symbian

在Apple和Google的冲击下,Nokia似乎已经日薄西山了,但对于中国国情来说,真的是这样吗?iPhone高高在上,拥有者只会是少数,Google退出中国之后,Android Market很难在国内有所作为,再加上Nokia手机一贯皮实的口碑,现在的Symbian以及将来的MeeGo的保有量应该不会低。Nokia已经把Symbian和MeeGo的开发环境统一到QT上了,这里依然是GCC的一亩三分田。
 
 
GCC是强大的,但它并不是一个人在战斗,在它的背后站着GNU工具链,包括make,GCC,Binutils,GDB等一系列工具,这些工具之间是相辅相成的,只有把它们组合起来使用才能发挥其最大的威力。

GCC 三的更多相关文章

  1. 在windows下安装flex和bison、GCC

    学习Stellar-core 需要依赖项flex .bison .gcc三个依赖项 下载得网址:链接: https://pan.baidu.com/s/1mitCLcs 密码: 3jaj   通过 w ...

  2. Linux下四款Web服务器压力测试工具(http_load、webbench、ab、siege)介绍

    一.http_load程序非常小,解压后也不到100Khttp_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把 ...

  3. python机器学习模块安装

    环境:RHEL6.5 离线安装 ############################################################################ 一,本地yum ...

  4. 在windows下安装flex和bison

    学习Stellar-core 需要依赖项flex .bison .gcc三个依赖项 下载得网址:链接: https://pan.baidu.com/s/1mitCLcs 密码: 3jaj   通过 w ...

  5. Google Closure Compiler高级压缩混淆Javascript代码

    一.背景 前端开发中,特别是移动端,Javascript代码压缩已经成为上线必备条件. 如今主流的Js代码压缩工具主要有: 1)Uglify http://lisperator.net/uglifyj ...

  6. Could not read symbols解决方法

    Could not read symbols 陈运文 Could not read symbols:Linux/UNIX系统下编译时,常见的一类报错信息. 通常情况下,该编译报错信息之前会给出出现错误 ...

  7. linux编译安装aria2

    一.安装aria2  [root@192-168-7-77 ~]# wget https://github.com/aria2/aria2/releases/download/release-1.33 ...

  8. GLIBCXX3.4.21 not find

    在执行世界杯的二进制代码和安装keepaway中会遇到GLIBCXX3.4.21 not find的问题,其解决办法就是升级安装GCC. 一.首先查看当前gcc版本 $ strings /usr/li ...

  9. JNI教程

    一.什么是JNI JNI(Java Native Interface ),它是Java SDK的一部分,主要用于实现Java对其他语言编写的代码和库的调用,比如C和C++.JNI提供的API也能让JV ...

随机推荐

  1. 20145221 《Java程序设计》第三周学习总结

    20145221 <Java程序设计>第三周学习总结 教材学习内容总结 第四章部分已在假期完成,详见博客: <Java程序设计>第四章-认识对象 第五章部分 何谓封装 封装实际 ...

  2. 20162314 Experiment 4 - Graph

    Experiment report of Besti course:<Program Design & Data Structures> Class: 1623 Student N ...

  3. Python3基础 三元运算符 简单示例

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  4. [JS] - level8 kata

    https://www.codewars.com/kata/57e3f79c9cb119374600046b function hello(name) { if(name == "" ...

  5. asp.net自定义控件之加载层

    知识点:JQuery.Ajax.自定义控件 该文旨在给大家开发自定义控件(结合js)一个思路,一个简单的示例,可能在实际项目中并不会这样做. 先来看看效果: 1.在静态页面里开发好想要的效果 jQue ...

  6. node的开发者环境设置丢失

    1.我看到的最简单的一种:evn 默认的值是  development var app = express(); if (app.get('env') === 'development') { req ...

  7. Undertow,Tomcat和Jetty服务器配置详解与性能测试

    undertow,jetty和tomcat可以说是javaweb项目当下最火的三款服务器,tomcat是apache下的一款重量级的服务器,不用多说历史悠久,经得起实践的考验.然而:当下微服务兴起,s ...

  8. 如何基于Netty处理粘包、拆包问题?

    涉及到相关重要组件: ByteToMessageDecoder MessageToMessageDecoder 这两个组件都实现了ChannelInboundHandler接口,这说明这两个组件都是用 ...

  9. Java 数组如何转成List集合

    问题描述:对于给定的如下数组,如何转换成List集合? String[] array = {"a","b","c"}; 参考stackove ...

  10. 雷林鹏分享:Ruby Dir 类和方法

    Ruby Dir 类和方法 Dir 是一个表示用于给出操作系统中目录中的文件名的目录流.Dir 类也拥有与目录相关的操作,比如通配符文件名匹配.改变工作目录等. 类方法 序号方法 & 描述 1 ...