zoukankan      html  css  js  c++  java
  • GCC编译过程

    以下是C程序一般的编译过程:

    gcc的编译流程分为四个步骤,分别为:
    · 预处理(Pre-Processing)

      对C语言进行预处理,生成*.i文件。
    · 编译(Compiling)

      将上一步生成的*.i文件编译生成汇编语言文件,后缀名为*.s
    · 汇编(Assembling)

      将汇编语言文件*.s经过汇编,生成目标文件,后缀名为*.o
    · 链接(Linking)

      将各个模块的*.o文件链接起来,生成最终的可执行文件

    示例代码:

    1 //hello.c源代码
    2 
    3 #include<stdio.h>
    4 int main()
    5 {
    6     printf("Hello World!
    ");
    7     return 0;
    8 }

    1.预编

    gcc -E hello.c -o hello.i

    编译器对各种预处理指令(#include #define #ifdef 等#开始的代码行)进行处理,还要删除注释,添加行号和文件名标识。

    预处理器(cpp)根据以字符#开头的命令(directives),修改原始的C程序。如hello.c中#include <stdio.h>指令告诉预处理器读系统头文件stdio.h的内容,并把它直接插入到程序文本中去。结果就得到另外一个C程序,通常是以.i作为文件扩展名的。

    2.编译

    gcc -S hello.i -o hello.s

    编译过程是把预处理完的文件进行一系列的词法分析、语法分析、语义分析及优化后生产相应的汇编代码文件。。

    3.汇编

    gcc -c hello.s -o hello.o

    汇编过程是编译器把汇编代码转换与计算机可认识的二进制文件。

    4.链接

    gcc hello.o -o hello

    在这个源程序中并没有定义”printf”的函数实现,且在预编译中包含进的”stdio.h”中也只有该函数的声明,而没有定义函数的实现,因为系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径”/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数”printf” 了,而这也就是链接的作用。

    函数库一般分为静态库和动态库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。
    (Linux下动态库文件的扩展名为".so"(Shared Object)。按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号)。这样,线程函数库被称作 libthread.so。静态库的文件名形式是libname.a。共享archive的文件名形式是libname.sa。共享archive只是一种过渡形式,帮助人们从静态库转变到动态库。)
    完成了链接之后,gcc就可以生成可执行文件

  • 相关阅读:
    Checking Types Against the Real World in TypeScript
    nexus pip proxy config
    go.rice 强大灵活的golang 静态资源嵌入包
    几个golang 静态资源嵌入包
    rpm 子包创建学习
    Rpm Creating Subpackages
    ava 类似jest snapshot 功能试用
    ava js 测试框架基本试用
    The Architectural Principles Behind Vrbo’s GraphQL Implementation
    graphql-compose graphql schema 生成工具集
  • 原文地址:https://www.cnblogs.com/zoneofmine/p/5565621.html
Copyright © 2011-2022 走看看