本页使用了标题或全文手工转换

GCC

维基百科,自由的百科全书
跳到导航 跳到搜索
GNU编译器套裝
GNU Compiler Collection logo.svg
GCC 10.2编译自身源代码截图
GCC 10.2编译自身源代码截图
開發者GNU計劃
初始版本1987年5月23日 (1987-05-23)
穩定版本
12.2[1]在维基数据编辑
(2022年8月19日)
源代码库 編輯維基數據鏈接
编程语言C++
操作系统跨平台
文件大小约一千五百万行[2]
语言英语
类型编译器
许可协议GNU通用公共许可证第三版或更新
网站gcc.gnu.org

GNU编译器套裝(英語:GNU Compiler Collection,縮寫為GCC)是GNU計劃制作的一种优化编译器,支持各种编程語言操作系统计算机系统结构。该编译器是以GPLLGPL許可證所發行的自由軟體,也是GNU計劃的关键部分,还是GNU工具链的主要組成部份之一。GCC(特别是其中的C语言编译器)也常被认为是跨平台编译器的事实标准。1985年由理查德·马修·斯托曼開始發展,現在由自由軟體基金會負責維護工作。截至2019年,GCC大约有1500万行代码,是现存最大的自由程序之一。[2] 它在自由软件的发展中发挥了重要作用,不仅是一个工具,还是一个典例。

原名為GNU C語言編譯器GNU C Compiler),因為它原本只能處理C語言。同年12月,新的GCC编译器可以编译C++语言。后来又为FortranPascalObjective-CJavaAdaGo等其他語言开发了前端。C和C++编译器也支持OpenMPOpenACC规范。

GCC编译器已经被移植到比其他编译器更多的平台和指令集架构上,并被广泛部署在开发自由和专有软件的工具中。GCC还可用于许多嵌入式系统,包括基于ARMPower ISA英语Power ISA的芯片。

GCC不仅是GNU操作系统的官方编译器,还是许多类UNIX系统和Linux发行版的标准编译器。BSD家族中的大部分操作系统也在GCC发布之后转用GCC;不过FreeBSD、OpenBSD和Apple macOS已经转向了Clang编译器[3],主要是因为许可问题。[4][5][6]GCC也可以编译WindowsAndroidiOSSolarisHP-UXIBM AIXDOS系统的代码。GCC原本用C開發,後來因為LLVMClang的崛起,它更快地將開發語言轉換為C++。許多C的愛好者在對C++一知半解的情況下主觀認定C++的性能一定會輸給C,但是Ian Lance Taylor給出了不同的意見,並表明C++不但性能不輸給C,而且能設計出更好,更容易維護的程式[7][8]

历史[编辑]

1983年底,为了引导GNU操作系统,理查德·马修·斯托曼向阿姆斯特丹编译器套件(自由大学编译器套件)的作者安德鲁·塔能鲍姆请求允许使用该编译器GNU;但是作者告知他该编译器仅对大学免费。因此,他打算开发一个不同的编译器。[9]一开始他打算与Len Tower和其他人将勞倫斯利佛摩國家實驗室的一个现有编译器从Pastel改写成C。[10][11]但是他在给利弗莫尔编译器写了一个新的C前端后,发现它需要数兆字节的堆栈空间,只有64KB的68000 Unix系统上无法运行。因此,他打算自己从头写一个编译器。[10]总而言之,尽管斯托曼确实使用了他自己写的C前端,他并没有将任何Pastel编译器的代码放在GCC中。[10][12]

GCC于1987年3月22日在麻省理工学院文件传输协议上发布[13],斯托曼被列为作者,也提及了其他人并感谢他们的贡献:Jack Davidson和Christopher Fraser给出了使用暫存器傳遞語言作为中间语言的思路;Paul Rubin为预处理器贡献良多;以及Leonard Tower写了“部分解析器、RTL生成器、RTL定义和Vax机器描述”。[14]Peter H. Salus英语Peter H. Salus誉为“自由软件第一击”的GNU编译器发布正值太阳微系统将其操作系统与其开发工具解绑,并提价单独出售。这使得许多客户购买或下载GCC而非供应商的工具。[15]尽管斯托曼认为GNU Emacs是他的主要工程,但截至1990年,GCC支持13种电脑架构,性能比其他编译器优越并为商业所用。[16]

EGCS克隆[编辑]

由于GCC是在GPL许可下授权的,其他为C以外语言编写接口的程序员可以自由的开发其自己的编译器分支,只要他们遵守GPL许可条款。但是,多分叉在日后体现出低效和不便的特点;而且人们很难使热爱稳定性胜过新特性的GCC官方项目接受他们的分支。[17]FSF对添加到GCC 2.x官方版本(1992年开始开发)中的内容进行了相当严格的控制,以至于被Eric S. Raymond在《大教堂与集市》中形容为 "大教堂 "开发模式。

在1997年,一群不滿GCC緩慢且封閉的創作環境者,組織了一個名為实验性/增强型GNU编译器系统(Experimental/Enhanced GNU Compiler System)的專案[17][12],将几个实验性分叉合并为一个项目。其基础是GCC的开发快照(大概取自2.7.2,后来跟进到2.8.1)。合并内容包括g77(Fortran)、PGCC(P5 Pentium优化的GCC)[12],许多C++的改进,以及许多新的架构和操作系统变种。[18]

这两个项目都密切观察着彼此的动态,但是EGCS的发展明显更活跃,因此FSF正式停止他们对GCC 2.x编译器的开发并希望EGCS成为GCC的官方版本。在1999年4月EGCS项目被任命为为GCC的维护者。随着1999年7月GCC 2.95的发布,这两个项目再次联合起来。[19][12]此后,GCC在一个指导委员会的指导下,来自各国的程序员小组会对其进行维护。[20]

由于缺乏维护,GCC 3 (2002)移除了CHILL的前端支持。[21]在版本4.0之前,GCC 3中的Fortran前端是g77,只支持FORTRAN 77。该前端后来被废弃,取而代之的是新GNU Fortran前端,支持Fortran 95Fortran 2003Fortran 2008的大部分内容 。[22][23]从GCC 4.8版开始,GCC由C++语言编写。[24]从GCC 5到GCC 7都保留了对Cilk Plus的支持。[25][26]

GCC已经被移植到各种指令集架构上,并被广泛部署为开发自由或专有软件的工具。GCC还可用于许多嵌入式系统,包括Symbian(称为gcce)[27]、基于ARM和基于Power ISA的芯片。[28]该编译器可以在各种平台上输出,包括游戏控制器中的PS2[29]Cell微处理器架构的PS3[30]以及Dreamcast[31]相比于其他编译器,GCC编译器被部署在更多的操作系统和处理器上。[32]

目前支持的语言[编辑]

截至2022年9月,GCC 12.2版内含Cgcc)、C++g++)、Objective-CFortrangfortran)、AdaGNAT)、Gogccgo)以及D (gdc,从9.1版开始)[33]编程语言的前端。[34]OpenMPOpenACC并行语言拓展从GCC 5.1开始支持。[35][36]GCC 7之前的版本也支持Javagcj),允许将java编译为机器语言。[37]

有关C++和C的语言版本支持,从GCC 11.1开始默认为gnu++17C++17超集;以及gnu11C11超集,还提供严格的标准支持。GCC也对C++20和即将到来的C++23标准提供实验性部分支持。[38]

有许多为其它语言编写的第三方前端,比如Pascalgpc英语GNU Pascal)、Modula-2Modula-3Mercury语言以及VHDLGHDL)。[34]一些实验性分支可支持更多语言,比如GCC UPC编译器还支持UPC[39]Rust[40]

支援的處理器架構[编辑]

GCC在Windows系统上编译Hello World程序

GCC 11.1版本支持的处理器包括:[41]

标准版本支持的少见处理器如下:

非FSF维护的GCC版本支持的处理器如下:

GCJ Java编译器可以输出机器语言或者Java虚拟机Java字节码[44]当重定向GCC到新的平台上,经常会用到自举英语bootstrapping (compilers)。 Motorola 68000,Zilog Z80以及其他处理器也可在为德州仪器惠普夏普以及卡西欧可编程图形计算器设计的GCC编译器上输出。[45]

设计[编辑]

GCC 的扩展编译流程概览,包括专门的程序如预处理器汇编器链接器
GCC 遵循多语言和多CPU编译器的典型三段架构。 所有程序树都在“中介界面”转换为通用代码,允许所有语言共享代码优化英语Program_optimization工具和二进制码英语Binary_code生成工具。

GCC的外部介面遵循UNIX使用惯例。用户输入特定语言的驱动程序码(C语言为gcc,C++为g++,如此不一而足),该程序解释命令语句,调用实际编译器,在输出界面上运行汇编器,然后选择性地运行链接器,产生一个完整的可执行二进制文件。

每种语言的编译器都是一个独立的程序,可读取源代码并输出机器码。所有語言的編譯器都擁有共通的中介架構:各语言前端解析符合此語言的原始碼,並產生一抽象語法樹。如有必要,这些代码会被转换为中介端的输入表示,即所谓的 GENERIC 形式;然后中介端会逐渐将程序转换为最终形式。编译器优化静态代码分析技术(例如FORTIFY_SOURCE[46],一种尝试发现緩衝區溢位的编译器指令)也会在源代码编译时应用。这些操作都是在多种表示法上工作,其中主要是独立于架构的GIMPLE表示法和独立于架构的RTL表示法。最终,机器码由傑克·戴維森英语Jack Davidson克里斯·弗雷澤英语Chris Fraser發明的算法产生。

除了Ada前端主要以Ada寫成,GCC大部分是用C语言编写的。GCC发行版包含主要以各自语言编写的Ada和C++标准库。[47]在一些平台上,GCC发行版还包括一个低级运行库libgcc该运行库由独立于机器的C语言和特定处理器的机器码组合编写,可处理目标处理器不能直接执行的复杂算术运算。[48]

GCC使用了许多额外的工具。虽然这些工具在UNIXLinux发行版中基本为默认安装的,但是Windows系统通常没有。这些工具包括PerlFlexBison和其他常用工具;还需要额外的依赖库GMP、MPC和MPFR英语MPFR[49]

2010年5月,GCC指导委员会决定允许使用C++编译器来编译GCC。[50] 编译器计划主要用C语言编写,并加上C++的一个子集特性。之所以这样做是为了了让GCC的开发者能够使用C++的析构器泛型功能。[51]2012年8月,GCC指导委员会宣布,GCC将以C++为源语言。[52]这意味着,要从源代码编写GCC编译器,需要一个能够理解ISO/IEC C++03标准的C++编译器。2020年5月18日,GCC从ISO/IEC C++03标准转向ISO/IEC C++11标准(即需要改写编译器本身;默认情况下可编译C++早期版本)。[53]

前端介面[编辑]

前端包括预处理词法分析语法分析(解析)和句意分析。编译器前端的目标是根据编程语言语法和语义接受或拒绝输入程序,识别错误并将有效的程序表述传递给编译器后端。这个例子展示了编译器前端对一个用C语言编写的简单程序进行词法分析和语法分析的步骤。

每个前端都使用一个分析器来产生给定的源代码的一个抽象语法树。由于语法树的抽象性,不同语言的源代码都可以被同一个后端处理。GCC一开始使用bison生成的LALR语法分析器,但在2004年逐渐转向用于C++的递归下降解析器[54],并在 2006 年用于CObjective-C[55]。2021年开始,所有前端都使用递归下降解析器

在 GCC 4.0 之前,程序的语法树结构不完全独立于输出的目标处理器架构。对于不同语言的前端来说,语法树的含义可能不同;而且前端可以提供它們特別的語法樹規則。随着 GENERIC 和 GIMPLE 的引入,这种情况得以避免。这是两种新的独立于语言的语法树形式,随GCC 4.0引入编译器前端。GENERIC更复杂,是一种基于 GCC 3.x Java 前端的中介表示。 GIMPLE 是一个简化的 GENERIC,其中各种结构被简化为多个 GIMPLE 指令。 C、C++ 和 Java 前端直接在前端生成 GENERIC。 相反,其他前端在解析后会有不同的中介表示,这些中介表示将转换为 GENERIC。前端生成GENERIC之後再使用「gimplifier」技術简化GENERIC的複雜結構,成為一較簡單的以SSA为基礎的GIMPLE形式,一种强大的,独立于语言和体系结构的全局(函数范围)优化的通用语言。

中介介面[编辑]

GENERIC 和 GIMPLE[编辑]

GENERIC 是一种中间表示语言,在将源代码编译成可执行二进制文件时用作“中介端”。GCC的所有前端都指向GENERIC的子集GIMPLE。GCC 的中间阶段进行所有的独立于编译语言和目标架构的代码分析和优化,从 GENERIC 表示法开始[56]将其转译为暫存器傳遞語言(RTL)。GENERIC 表示只包含中介端优化后的指令式编程结构的子集。

在将源代码转译为GIMPLE表示时[57],会使用临时变量将复杂表达式拆分为三位址碼。这种表示法的灵感来自于 Laurie J. Hendren[58] 在 McCAT 编译器[59]中提出的 SIMPLE 表示法,用于简化指令式程序的分析和优化。

优化[编辑]

一般編譯器作者會將語法樹的最佳化放在前端,但其實此步驟並不看語言的種類而有不同,且不需要用到語法解析器。因此GCC作者們將此步驟歸入通稱為中介階段的部分裡。此類的最佳化包括消解死碼消解重複運算全域數值重編碼等。許多最佳化技巧也正在實作中。

後端介面[编辑]

GCC後端的行為因不同的前處理器巨集和特定架構的功能而不同,例如不同的字元尺寸呼叫方式與大小尾序等。後端介面的前半部利用這些訊息決定其RTL的生成形式,因此雖然GCC的RTL理論上不受處理器影響,但在此階段其抽象指令已被轉換成目標架構的格式。

GCC的最佳化技巧依其釋出版本而有很大不同,但都包含了標準的最佳化演算法,例如迴圈最佳化執行緒跳躍共通程式子句消減指令排程等等。而RTL的最佳化由於可用的情形較少,且缺乏較高階的資訊,因此比較起近來增加的GIMPLE語法樹形式[1],便顯得比較不重要。

後端經由一重讀取步驟後,利用描述目標處理器的指令集時所取得的資訊,將抽象暫存器替換成處理器的真實暫存器。此階段非常複雜,因為它必須關照所有GCC可移植平台的處理器指令集的規格與技術細節。

後端的最後步驟相當公式化,僅僅將前一階段得到的組合語言碼藉由簡單的副函式轉換其暫存器與記憶體位置成相對應的機械碼。

替GCC程式除錯[编辑]

GNU除錯器是一個為GCC除錯的程式。其他特殊用途的除錯工具是Valgrind,用以發現内存泄漏(memory leak)。而GNU測量器(gprof)可以得知程式中某些函式花費多少時間,以及其呼叫頻率;此功能需要使用者在編譯時選定測量(profiling)選項。

GCC内嵌汇编[编辑]

内嵌汇编也称行内汇编,是把汇编语言代码块插在C语言语句之间。详情参见GCC-Inline-Assembly-HOWTO.html页面存档备份,存于互联网档案馆

参考文献[编辑]

引用[编辑]

  1. ^ "GCC 12.2 Released";作者姓名字符串:Richard Biener;出版日期:2022年8月19日;检索日期:2022年8月19日。
  2. ^ 2.0 2.1 Víctor Rodríguez. Cutting Edge Toolchain (Latest Features in GCC/GLIBC). youtube.com. Linux Foundation. 2019-10-01 [2021-01-19]. (原始内容存档于2021-11-07). 
  3. ^ The LLVM Compiler Infrastructure Project. llvm.org. 
  4. ^ Apple's GPLv3 purge. meta.ath0.com. [2021-01-12] (美国英语). 
  5. ^ Linnemann, Reid. Why Clang. June 20, 2012 [2021-01-12]. 
  6. ^ August 29, 2007: FreeBSD Foundation Newsletter, August 29, 2007. 2007-10-11 [2021-01-12]. (原始内容存档于October 11, 2007). 
  7. ^ GCC's move to C++. [2013-05-01]. (原始内容存档于2013-06-14). 
  8. ^ Taylor的演讲簡報 (PDF). [2018-05-19]. (原始内容存档 (PDF)于2018-07-01). 
  9. ^ von Hagen, William. The Definitive Guide to GCC. Definitive Guides 2nd. Apress. 2006: XXVII. ISBN 978-1-4302-0219-6. So he wrote to VUCK's author asking if GNU could use it. Evidently, VUCK's developer was uncooperative, responding that the university was free but that the compiler was not. 
  10. ^ 10.0 10.1 10.2 Stallman, Richard. About the GNU Project. The GNU Project. September 20, 2011 [October 9, 2011]. 
  11. ^ Puzo, Jerome E. (编). Gnu's Zoo. GNU's Bulletin (Free Software Foundation). February 1986, 1 (1) [2007-08-11]. 
  12. ^ 12.0 12.1 12.2 12.3 von Hagen, William. The Definitive Guide to GCC. Definitive Guides 2nd. Apress. 2006: XXVII. ISBN 978-1-4302-0219-6. 
  13. ^ Richard M. Stallman (forwarded by Leonard H. Tower Jr.). GNU C compiler beta test release. Newsgroupcomp.lang.c 请检查|newsgroup=值 (帮助). March 22, 1987 [October 9, 2011]. 
  14. ^ Stallman, Richard M., Contributors to GNU CC, Using and Porting the GNU Compiler Collection (GCC), Free Software Foundation, Inc.: 7, June 22, 2001 [First published 1988] [June 18, 2015]. 
  15. ^ Salus, Peter H. Chapter 10. SUN and gcc. The Daemon, the Gnu and the Penguin. Groklaw. 2005. 
  16. ^ Garfinkel, Simson L. Get ready for GNU software. Computerworld. 6 August 1990: 102. 
  17. ^ 17.0 17.1 Henkel-Wallace, David, A new compiler project to merge the existing GCC forks, August 15, 1997 [May 25, 2012]. 
  18. ^ The Short History of GCC development. www.softpanorama.org. [2021-01-24]. 
  19. ^ History - GCC Wiki. gcc.gnu.org. [2020-09-28]. 
  20. ^ GCC steering committee - GNU Project. gcc.gnu.org. 
  21. ^ PATCH] Remove chill. gcc.gnu.org. [July 29, 2010]. 
  22. ^ Chart of Fortran 2003 Features supported by GNU Fortran. GNU. [2009-06-25]. 
  23. ^ Chart of Fortran 2008 Features supported by GNU Fortran. GNU. [2009-06-25]. 
  24. ^ GCC 4.8 Release Series — Changes, New Features, and Fixes - GNU Project. gcc.gnu.org. 
  25. ^ GCC 5 Release Series — Changes, New Features, and Fixes. gcc.gnu.org. 
  26. ^ GCC 8 Release Series — Changes, New Features, and Fixes. gcc.gnu.org. 
  27. ^ Symbian GCC Improvement Project. [2007-11-08]. 
  28. ^ Linux Board Support Packages. [2021-01-24]. (原始内容存档于2011-06-07). 
  29. ^ setting up gcc as a cross-compiler. ps2stuff. 2002-06-08 [2008-12-12]. (原始内容存档于December 11, 2008). 
  30. ^ CompileFarm - GCC Wiki. gcc.gnu.org. 
  31. ^ sh4 g++ guide. [2008-12-12]. (原始内容存档于2002-12-20). 
  32. ^ Linux Information Project. LINFO. [2010-04-27]. The GCC has been ported to (i.e., modified to run on) more than 60 platforms, which is more than for any other compiler. 
  33. ^ The D Language Front-End Finally Merged Into GCC 9 - Phoronix. phoronix.com. [2021-01-19]. 
  34. ^ 34.0 34.1 GCC Front Ends. gnu.org. 2022-04-16 [2022-09-25]. 
  35. ^ 引用错误:没有为名为:2的参考文献提供内容
  36. ^ GCC 5 Release Series — Changes, New Features, and Fixes - GNU Project. gcc.gnu.org. 2015-04-22 [2022-09-25]. 
  37. ^ GCC 7 Release Series. GCC 7 Release Series: Changes, New Features, and Fixes. gnu.org. 2017-05-02 [2022-09-25]. 
  38. ^ C++ Standards Support in GCC. gcc.gnu.org. 2022-09-09 [2022-09-25]. 
  39. ^ GCC UPC (GCC Unified Parallel C). Intrepid Technology, Inc. 2006-02-20 [2009-03-11]. 
  40. ^ Spengler, Brad. Open Source Security, Inc. Announces Funding of GCC Front-End for Rust. 12 January 2021. 
  41. ^ Option Summary (Using the GNU Compiler Collection (GCC)). gcc.gnu.org. [2020-08-21]. 
  42. ^ Hexagon Project Wiki. 
  43. ^ Google Code Archive - Long-term storage for Google Code Project Hosting.. code.google.com. 
  44. ^ The GNU Compiler for the Java Programming Language. [2010-04-22]. (原始内容存档于May 9, 2007).  已忽略未知参数|df= (帮助)
  45. ^ graphing calculators#programming
  46. ^ Security Features: Compile Time Buffer Checks (FORTIFY_SOURCE). Security Features. fedoraproject.org. [2022-09-26]. 
  47. ^ languages used to make GCC. 
  48. ^ GCC generates calls to routines in this library automatically, whenever it needs to perform some operation that is too complicated to emit inline code for.. 4 The GCC low-level runtime library. GCC.org. [2022-09-26]. 
  49. ^ Prerequisites for GCC - GNU Project. gcc.gnu.org. 2022-04-29 [2022-09-26]. 
  50. ^ GCC allows C++ – to some degree. The H. June 1, 2010. 
  51. ^ Re: Efforts to attract more users?. lists.gnu.org. 
  52. ^ GCC 4.8 Release Series: Changes, New Features, and Fixes. [October 4, 2013]. 
  53. ^ bootstrap: Update requirement to C++11.. GitHub. 19 May 2020 [2022-09-27] –通过github. 
  54. ^ GCC 3.4 Release Series — Changes, New Features, and Fixes - GNU Project. gcc.gnu.org. gcc.gnu.org. 2021-07-28 [2022-09-27]. 
  55. ^ GCC 4.1 Release Series — Changes, New Features, and Fixes - GNU Project. gcc.gnu.org. 2021-10-18 [2022-09-27]. 
  56. ^ GENERIC (GNU Compiler Collection (GCC) Internals). gcc.gnu.org. [2022-09-27]. 
  57. ^ GIMPLE (GNU Compiler Collection (GCC) Internals). gcc.gnu.org. [2022-09-27]. 
  58. ^ Laurie Hendren's Home Page. www.sable.mcgill.ca. [2022-09-27]. 
  59. ^ McCAT. [2022-09-27]. (原始内容存档于August 12, 2004).  已忽略未知参数|df= (帮助)

来源[编辑]

更多閱讀[编辑]

外部链接[编辑]

参见[编辑]

  • GCC目前包含了贝姆垃圾收集器,一個為C/C++所設計的垃圾回收器
  • distcc - 為分散式編譯所設計的軟體,以GCC為協同軟體。
  • ccache - 用于缓存编译的中间结果,加快重新编译的速度。
  • LLVM - 低層虛擬機器編譯器架構,其中的 clang (Obj-)C(++) 编译器实现了大部分 GNU C 拓展。
  • MinGW - 將GNU開發工具移植到Win32平臺下的計畫
  • Cygwin - 在 Windows 上執行 Unix 程式的模擬軟體。
  • GCC Summit
  • OpenWatcom - 另一個開放原碼的C++/Fortran編譯器。
  • Code Sourcery - 一個GCC顧問公司。
  • ggcc - 全球化GCC專案。