【AI系统】GCC 主要特征

简介: GCC(GNU Compiler Collection)是由理查德·斯托曼于1987年创建,最初作为GNU项目的一部分,旨在为GNU/Linux系统提供高效C语言编译器。随着时间发展,GCC不仅支持多种编程语言如C++、Java、Swift等,还具备强大的可移植性、模块化设计及跨平台交叉编译能力,成为全球广泛使用的开源编译器之一。其编译过程分为预处理、编译、汇编和链接四个阶段,支持静态和动态链接方式,适用于本地编译和交叉编译场景。

GCC(GNU Compiler Collection,GNU 编译器集合)最初是作为 GNU 操作系统的编译器编写的,旨在为 GNU/Linux 系统开发一个高效的 C 编译器。其历史可以追溯到 1987 年,当时由理查德·斯托曼(Richard Stallman)创建,作为 GNU 课程的一部分。

最初,GCC 仅是一个用于编译 C 语言的编译器,但很快扩展以支持其他编程语言,其设计强调可移植性和模块化,使其能够适应多种硬件和操作系统环境。

在 1990 年代和 2000 年代,GCC 经历了几次重要的重构和扩展。改进包括引入新的优化技术、提升代码生成和分析能力,以及增强对新兴编程语言和硬件架构的支持。这些改进使得 GCC 成为编程社区中的重要工具,广泛应用于学术研究、商业开发和开源课程中。随着 GNU/Linux 系统的快速发展,GCC 逐渐扩展其支持范围,涵盖了包括 Microsoft Windows、BSD 系列、Solaris 和 Mac OS 在内的多种操作系统平台。

同时,GCC 的指导委员会根据其使命宣言做出重要决策,致力于持续发布高质量的版本。通过 Git 版本控制系统和每周的源代码快照,GCC 的最新源代码随时可供获取。任何人都被鼓励参与贡献或协助测试,以推动 GCC 的持续发展。

编译器

此外,GCC 还引入了与现代编程语言如 Swift 和 Java 相关的前端,使其成为一个全面而多功能的编译器。作为一个模块化设计的软件,GCC 提供了丰富的功能和灵活性,既能在本地平台上进行编译,也支持跨平台的交叉编译。作为自由软件的一部分,用户可以免费获取并自由使用 GCC,并且得到了自由软件基金会(Free Software Foundation,FSF)的强力支持。

GCC 具有以下主要特征:

  • 可移植性:支持多种硬件平台,使得用户可以在不同的硬件架构上进行编译。
  • 跨平台交叉编译:支持在一个平台上为另一个平台生成可执行文件,这对嵌入式开发尤为重要。
  • 多语言前端:除了 C 语言,还支持 C++、Objective-C、Fortran、Ada、Go 和 D 等多种编程语言。
  • 模块化设计:允许轻松添加新语言和 CPU 架构的支持,增强了扩展性。
  • 开源自由软件:源代码公开,用户可以自由使用、修改和分发。

GCC 编译流程

GCC 的编译过程可以大致分为预处理、编译、汇编和链接四个阶段。

编译器

源程序(文本)

当编写源程序时,通常会使用以 .c 或 .cpp 为扩展名的文件。下面以打印宏定义 HELLOWORD 为例,我们使用 C 语言编写 hello.c 源文件:

#include <stdio.h>

#define HELLOWORD ("hello world\n")

int main(void){
   
    printf(HELLOWORD);
    return 0;
}

预处理(cpp)

生成文件 hello.i

gcc -E hello.c -o hello.i

在预处理过程中,源代码会被读入,并检查其中包含的预处理指令和宏定义,然后进行相应的替换操作。此外,预处理过程还会删除程序中的注释和多余空白字符。最终生成的.i 文件包含了经过预处理后的代码内容。

当高级语言代码经过预处理生成.i 文件时,预处理过程会涉及宏替换、条件编译等操作。以下是对这些预处理操作的解释:

  • 头文件展开:

在预处理阶段,编译器会将源文件中包含的头文件内容插入到源文件中对应的位置,以便在编译时能够访问头文件中定义的函数、变量、宏等内容。

  • 宏替换:

在预处理阶段,编译器会将源文件中定义的宏在使用时进行替换,即将宏名称替换为其定义的内容。这样可以简化代码编写,提高代码的可读性和可维护性。

  • 条件编译:

通过预处理指令如 #if、#else、#ifdef 等,在编译前确定某些代码片段是否应被包含在最终的编译过程中。这样可以根据条件编译选择性地包含代码,实现不同平台、环境下的代码控制。

  • 删除注释:

在预处理阶段,编译器会删除源文件中的注释,包括单行注释(//)和多行注释(/.../),这样可以提高编译速度并减少编译后代码的大小。

  • 添加行号和文件名标识:

通过预处理指令如 #line,在预处理阶段添加行号和文件名标识到源文件中,便于在编译过程中定位错误信息和调试。

  • 保留 #pragma 命令:

在预处理阶段,编译器会保留以#pragma 开头的预处理指令,如#pragma once、#pragma pack 等,这些指令可以用来指导编译器进行特定的处理,如控制编译器的行为或优化代码。

hello.i 文件部分内容如下,详细可见../code/gcc/hello.i 文件。

int main(void){
   
    printf(("hello world\n"));
    return 0;
}

在该文件中,已经将头文件包含进来,宏定义 HELLOWORD 替换为字符串"hello world\n",并删除了注释和多余空白字符。

编译(ccl)

在这里,编译并不仅仅指将程序从源文件转换为二进制文件的整个过程,而是特指将经过预处理的文件(hello.i)转换为特定汇编代码文件(hello.s)的过程。

在这个过程中,经过预处理后的 .i 文件作为输入,通过编译器(ccl)生成相应的汇编代码.s 文件。编译器(ccl)是 GCC 的前端,其主要功能是将经过预处理的代码转换为汇编代码。编译阶段会对预处理后的.i 文件进行语法分析、词法分析以及各种优化,最终生成对应的汇编代码。

汇编代码是以文本形式存在的程序代码,接着经过编译生成.s 文件,是连接程序员编写的高级语言代码与计算机硬件之间的桥梁。

生成文件 hello.s:

gcc -S hello.i -o hello.s

打开 hello.s 后输出如下:

    .section    __TEXT,__text,regular,pure_instructions
    .build_version macos, 10, 15    sdk_version 10, 15, 6
    .globl    _main                   # -- Begin function main
    .p2align    4, 0x90
_main:                                  # @main
    .cfi_startproc
# %bb.0:
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movl    $0, -4(%rbp)
    leaq    L_.str(%rip), %rdi
    movb    $0, %al
    callq    _printf
    xorl    %ecx, %ecx
    movl    %eax, -8(%rbp)          # 4-byte Spill
    movl    %ecx, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc
                                        # -- End function
    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 # @.str
    .asciz    "hello world\n"

.subsections_via_symbols

现在 hello.s 文件中包含了完全是汇编指令的内容,表明 hello.c 文件已经被成功编译成了汇编语言。

汇编(as)

在这一步中,我们将汇编代码转换成机器指令。这一步是通过汇编器(as)完成的。汇编器是 GCC 的后端,其主要功能是将汇编代码转换成机器指令。

汇编器的工作是将人类可读的汇编代码转换为机器指令或二进制码,生成一个可重定位的目标程序,通常以 .o 作为文件扩展名。这个目标文件包含了逐行转换后的机器码,以二进制形式存储。这种可重定位的目标程序为后续的链接和执行提供了基础,使得汇编代码能够被计算机直接执行。

生成文件 hello.o

gcc -c hello.s -o hello.o

链接(ld)

链接过程中,链接器的作用是将目标文件与其他目标文件、库文件以及启动文件等进行链接,从而生成一个可执行文件。在链接的过程中,链接器会对符号进行解析、执行重定位、进行代码优化、确定空间布局,进行装载,并进行动态链接等操作。通过链接器的处理,将所有需要的依赖项打包成一个在特定平台可执行的目标程序,用户可以直接执行这个程序。

gcc -o hello.o -o hello

添加-v 参数,可以查看详细的编译过程:

gcc -v hello.c -o hello
  • 静态链接

静态链接是指在链接程序时,需要使用的每个库函数的一份拷贝被加入到可执行文件中。通过静态链接使用静态库进行链接,生成的程序包含程序运行所需要的全部库,可以直接运行。然而,静态链接生成的程序体积较大。

  • 动态链接

动态链接是指可执行文件只包含文件名,让载入器在运行时能够寻找程序所需的函数库。通过动态链接使用动态链接库进行链接,生成的程序在执行时需要加载所需的动态库才能运行。相比静态链接,动态链接生成的程序体积较小,但是必须依赖所需的动态库,否则无法执行。

GCC 编译方法

本地编译

所谓"本地编译",是指编译源代码的平台和执行源代码编译后程序的平台是同一个平台。这里的平台,可以理解为 CPU 架构+操作系统。比如,在 Intel x86 架构或者 Windows 平台下、使用 Visual C++ 编译生成的可执行文件,在同样的 Intel x86 架构/Windows 10 下运行。

交叉编译

所谓"交叉编译(Cross_Compile)",是指编译源代码的平台和执行源代码编译后程序的平台是两个不同的平台。比如,在 Intel x86 架构/Linux(Ubuntu)平台下、使用交叉编译工具链生成的可执行文件,在 ARM 架构/Linux 下运行。

与传统编译区别

传统的三段式划分是指将编译过程分为前端、优化、后端三个阶段,每个阶段都有专门的工具负责。

编译器

而在 GCC 中,编译过程被分成了预处理、编译、汇编、链接四个阶段 。其中 GCC 的预处理、编译阶段属于三段式划分的前端部分,汇编阶段属于三段式划分的后端部分。

GCC 的链接阶段是三段式划分后端部分的优化阶段合并,但其与端部分的目的一致,都是为了生成可执行文件。

GCC 编译过程的四个阶段与传统的三段式划分的前端、优化、后端三个阶段有一定的重合和对应关系,但 GCC 更为详细和全面地划分了编译过程,使得每个阶段的功能更加明确和独立。

如果您想了解更多AI知识,与AI专业人士交流,请立即访问昇腾社区官方网站https://www.hiascend.com/ 或者深入研读《AI系统:原理与架构》一书,这里汇聚了海量的AI学习资源和实践课程,为您的AI技术成长提供强劲动力。不仅如此,您还有机会投身于全国昇腾AI创新大赛和昇腾AI开发者创享日等盛事,发现AI世界的无限奥秘~

目录
相关文章
|
4天前
|
人工智能 自动驾驶 大数据
预告 | 阿里云邀您参加2024中国生成式AI大会上海站,马上报名
大会以“智能跃进 创造无限”为主题,设置主会场峰会、分会场研讨会及展览区,聚焦大模型、AI Infra等热点议题。阿里云智算集群产品解决方案负责人丛培岩将出席并发表《高性能智算集群设计思考与实践》主题演讲。观众报名现已开放。
|
21天前
|
存储 人工智能 弹性计算
阿里云弹性计算_加速计算专场精华概览 | 2024云栖大会回顾
2024年9月19-21日,2024云栖大会在杭州云栖小镇举行,阿里云智能集团资深技术专家、异构计算产品技术负责人王超等多位产品、技术专家,共同带来了题为《AI Infra的前沿技术与应用实践》的专场session。本次专场重点介绍了阿里云AI Infra 产品架构与技术能力,及用户如何使用阿里云灵骏产品进行AI大模型开发、训练和应用。围绕当下大模型训练和推理的技术难点,专家们分享了如何在阿里云上实现稳定、高效、经济的大模型训练,并通过多个客户案例展示了云上大模型训练的显著优势。
|
25天前
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
16天前
|
并行计算 前端开发 物联网
全网首发!真·从0到1!万字长文带你入门Qwen2.5-Coder——介绍、体验、本地部署及简单微调
2024年11月12日,阿里云通义大模型团队正式开源通义千问代码模型全系列,包括6款Qwen2.5-Coder模型,每个规模包含Base和Instruct两个版本。其中32B尺寸的旗舰代码模型在多项基准评测中取得开源最佳成绩,成为全球最强开源代码模型,多项关键能力超越GPT-4o。Qwen2.5-Coder具备强大、多样和实用等优点,通过持续训练,结合源代码、文本代码混合数据及合成数据,显著提升了代码生成、推理和修复等核心任务的性能。此外,该模型还支持多种编程语言,并在人类偏好对齐方面表现出色。本文为周周的奇妙编程原创,阿里云社区首发,未经同意不得转载。
11588 12
|
10天前
|
人工智能 自然语言处理 前端开发
100个降噪蓝牙耳机免费领,用通义灵码从 0 开始打造一个完整APP
打开手机,录制下你完成的代码效果,发布到你的社交媒体,前 100 个@玺哥超Carry、@通义灵码的粉丝,可以免费获得一个降噪蓝牙耳机。
4082 14
|
16天前
|
人工智能 自然语言处理 前端开发
用通义灵码,从 0 开始打造一个完整APP,无需编程经验就可以完成
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。本教程完全免费,而且为大家准备了 100 个降噪蓝牙耳机,送给前 100 个完成的粉丝。获奖的方式非常简单,只要你跟着教程完成第一课的内容就能获得。
6830 10
|
28天前
|
缓存 监控 Linux
Python 实时获取Linux服务器信息
Python 实时获取Linux服务器信息
|
14天前
|
人工智能 自然语言处理 前端开发
什么?!通义千问也可以在线开发应用了?!
阿里巴巴推出的通义千问,是一个超大规模语言模型,旨在高效处理信息和生成创意内容。它不仅能在创意文案、办公助理、学习助手等领域提供丰富交互体验,还支持定制化解决方案。近日,通义千问推出代码模式,基于Qwen2.5-Coder模型,用户即使不懂编程也能用自然语言生成应用,如个人简历、2048小游戏等。该模式通过预置模板和灵活的自定义选项,极大简化了应用开发过程,助力用户快速实现创意。
|
3天前
|
机器学习/深度学习 人工智能 安全
通义千问开源的QwQ模型,一个会思考的AI,百炼邀您第一时间体验
Qwen团队推出新成员QwQ-32B-Preview,专注于增强AI推理能力。通过深入探索和试验,该模型在数学和编程领域展现了卓越的理解力,但仍在学习和完善中。目前,QwQ-32B-Preview已上线阿里云百炼平台,提供免费体验。
|
11天前
|
人工智能 C++ iOS开发
ollama + qwen2.5-coder + VS Code + Continue 实现本地AI 辅助写代码
本文介绍在Apple M4 MacOS环境下搭建Ollama和qwen2.5-coder模型的过程。首先通过官网或Brew安装Ollama,然后下载qwen2.5-coder模型,可通过终端命令`ollama run qwen2.5-coder`启动模型进行测试。最后,在VS Code中安装Continue插件,并配置qwen2.5-coder模型用于代码开发辅助。
743 5