在linux下开发难免会用到gcc编译。GCC(GNU Compiler Collection。GNU编译器套装),是由 GNU 开发的编程语言编译器。它是GNU编译器套装以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。

使用GCC编译程序时,编译过程能够被细分为四个阶段:
◆ 预处理(Pre-Processing)
◆ 编译(Compiling)
◆ 汇编(Assembling)
◆ 链接(Linking)

1、预处理 对源码文件里的文件包括(include)、预编译语句(如宏定义define等)进行分析,编译选项为gcc -E *.c

#define DEBUG "debug"int main()
{char *a = DEBUG;return 1;
}

经过上面的预处理后,能够看到DEBUG被替换成了提前定义的内容

# 1 "hello.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "hello.c"int main()
{char *a = "debug";return 1;
}

2、编译 调用cc1进行编译,使用gcc -S选项就能够生成汇编代码,这个阶段依据输入文件生成以.o为后缀的目标文件。生成的汇编代码例如以下:

        .file   "hello.c".section        .rodata
.LC0:.string "debug".text
.globl main.type   main, @function
main:
.LFB0:.cfi_startprocpushq   %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq    %rsp, %rbp.cfi_def_cfa_register 6movq    $.LC0, -8(%rbp)movl    $1, %eaxleave.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size   main, .-main.ident  "GCC: (GNU) 4.4.6 20110731 (Red Hat 4.4.6-3)".section        .note.GNU-stack,"",@progbits

3、汇编  汇编过程是针对汇编语言的步骤,调用as进行工作。一般来讲,.S为后缀的汇编语言源码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。此过程生成ELF格式的目标代码,使用gcc -c进行汇编

使用readelf -a hello.o能够看到具体的elf信息

ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              REL (Relocatable file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x0Start of program headers:          0 (bytes into file)Start of section headers:          296 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           0 (bytes)Number of program headers:         0Size of section headers:           64 (bytes)Number of section headers:         13Section header string table index: 10Section Headers:[Nr] Name              Type             Address           OffsetSize              EntSize          Flags  Link  Info  Align[ 0]                   NULL             0000000000000000  000000000000000000000000  0000000000000000           0     0     0[ 1] .text             PROGBITS         0000000000000000  000000400000000000000013  0000000000000000  AX       0     0     4[ 2] .rela.text        RELA             0000000000000000  000005680000000000000018  0000000000000018          11     1     8[ 3] .data             PROGBITS         0000000000000000  000000540000000000000000  0000000000000000  WA       0     0     4[ 4] .bss              NOBITS           0000000000000000  000000540000000000000000  0000000000000000  WA       0     0     4[ 5] .rodata           PROGBITS         0000000000000000  000000540000000000000006  0000000000000000   A       0     0     1[ 6] .comment          PROGBITS         0000000000000000  0000005a000000000000002d  0000000000000001  MS       0     0     1[ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000870000000000000000  0000000000000000           0     0     1[ 8] .eh_frame         PROGBITS         0000000000000000  000000880000000000000038  0000000000000000   A       0     0     8[ 9] .rela.eh_frame    RELA             0000000000000000  000005800000000000000018  0000000000000018          11     8     8[10] .shstrtab         STRTAB           0000000000000000  000000c00000000000000061  0000000000000000           0     0     1[11] .symtab           SYMTAB           0000000000000000  0000046800000000000000f0  0000000000000018          12     9     8[12] .strtab           STRTAB           0000000000000000  00000558000000000000000e  0000000000000000           0     0     1
Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)There are no section groups in this file.There are no program headers in this file.Relocation section '.rela.text' at offset 0x568 contains 1 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000008  00050000000b R_X86_64_32S      0000000000000000 .rodata + 0Relocation section '.rela.eh_frame' at offset 0x580 contains 1 entries:Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0There are no unwind sections in this file.Symbol table '.symtab' contains 10 entries:Num:    Value          Size Type    Bind   Vis      Ndx Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.c2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 6: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 7: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 8: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 9: 0000000000000000    19 FUNC    GLOBAL DEFAULT    1 main

4、链接 链接过程。生成可运行代码。链接分为两种,一种是静态链接,第二种是动态链接。

使用静态链接的优点是,依赖的动态链接库较少,对动态链接库的版本号不会非常敏感,具有较好的兼容性。缺点是生成的程序比較大。使用动态链接的优点是,生成的程序比較小,占用较少的内存。

gcc hello.o -o hello 就能够完毕最后的链接操作并生成可运行文件,至于怎样生成动态库和静态库,以及怎样链接动态库和静态库,以后会再作介绍。

转载于:https://www.cnblogs.com/lxjshuju/p/6928091.html

Linux下Gcc 的编译过程相关推荐

  1. linux下gcc的编译过程详解

    Linux系统下的Gcc(GNU C Compiler)是GNU推出的功能强大.性能优越的多平台编译器,是GNU的代表作品之一.gcc是可以在多种硬体平台上编译出可执行程序的超级编译器,其执行效率与一 ...

  2. Linux 的GCC的编译过程及方式

    GCC的使用 文章目录 GCC的使用 前言 一.编译过程分析 二.Linux中的编译链接 1.1 预编译阶段 1.2 编译阶段 1.3 汇编阶段 1.4 链接阶段 1.5 补充 二.编译链接命令 三. ...

  3. Linux下gcc编译c程序生成可执行文件的过程

    Linux下gcc编译c程序生成可执行文件 一.准备 hello.c 文件 1.在当前目录下新建c文件 $:vim hello.c 2.按i进入编辑模式.按esc退出编辑模式,输入源代码 #inclu ...

  4. linux下源码编译升级ssh版本,ssh打补丁过程

    linux下源码编译升级ssh版本过程 记录打补丁之ssh源码编译升级过程 安装前软件准备 升级步骤 结尾及一些坑 记录打补丁之ssh源码编译升级过程 应安全报告要求需要修复操作系统中的ssh协议,原 ...

  5. linux下gcc编译c文件生成可执行文件的四个步骤

    Linux下gcc编译c文件为可执行文件分为四个步骤: 分别是 预编译.编译.汇编.链接. 1.预编译( 生成 hello.i 文件) 预编译的处理规则: 1. 将所有的 "#define& ...

  6. 在Linux下gcc缺省编译,在Linux下用gcc编译hello world

    1. 确保Linux系统里已经装好了gcc 测试:输入gcc后是如下的结果就说明已经安装成功 2. 创建HelloWorld.c 使用 touch 创建一个空文件; 用vim编辑 按下A或者I 插入 ...

  7. 历史经验之Linux下PF_RING的编译和安装过程

    历史经验之Linux下PF_RING的编译和安装过程 1)确认是否安装PF_RING 2)从下载网址下载最新版本的PF_RING: 编译和安装PF_RING 1)编译pf_ring内核文件 2)编译p ...

  8. Linux系统怎么编译sin,linux下gcc编译sin函数出错的问题

    linux下gcc编译sin函数出错的问题 收藏 Q: I keep getting errors due to library functions being undefined, but I'm ...

  9. Linux中gcc的编译、静态库和动态库的制作

    欢迎大家关注笔者,你的关注是我持续更博的最大动力 Linux中gcc的编译.静态库.动态库 文章目录: 1 gcc的编译过程 1.1 gcc的编译过程 1.2 gcc的常用参数 2 gcc 静态库的制 ...

最新文章

  1. oracle只修改年份
  2. 检验入参合法性有哪些_验证用户输入的参数合法性的shell脚本
  3. python经典100例答案pdf-Python3基础训练经典100题(带答案)下载
  4. 关于子对话框的创建与销毁
  5. 2018第九届蓝桥杯C语言第九题 全球变暖
  6. mysql -uroot -proot tc -e select * from merchandise limit 1这个-E的命令作用是什么,用来什么什么的?
  7. Request_获取ServletContext
  8. equipment header attribute mapping - two settypes in middleware
  9. 事实--思维导图笔记
  10. 草稿 0242 ktv第一个页面
  11. python 字典和列表的遍历
  12. android取消自动获取焦点,Android 如何让EditText不自动获取焦点 (转)(示例代码)...
  13. Java我的世界forge安装失败,我的世界forge安装失败install怎么办
  14. adb shell 获取手机分辨率
  15. 获取 rabbitmq 实时数据
  16. 张远龙高性能服务器,荆楚匠人:张远龙巧手妙思 葫芦上绘出精彩人生
  17. 一个计算机网络由8台计算机组成,2016年真题824计算机组成原理+计算机网络(2016-B).doc...
  18. 泛癌种生物标志物介绍
  19. windows7经典开机音乐_糖豆人加入索尼克皮肤;三国群英传8上线Steam;疑似PS5开机音效...
  20. 信息安全相关从业人员必须收藏,100%有用!

热门文章

  1. C语言写文件到txt里有屯字,C语言10 文件.ppt
  2. 2清空所有表_拉链表(二)
  3. python flask 分页前后端分离_flask展示pyecharts图表前后端分离的问题
  4. kafka中LEO和HW
  5. Java泛型详解:<T>和Class<T>的使用,泛型类
  6. oracle 11g 修改 sga,oracle 11g 调整SGA
  7. 分步表单_角色创建分步指南
  8. 可能是全网首个前端源码共读活动,诚邀你加入一起学习
  9. 刚毕业的ERP实施顾问做甲方
  10. 缓冲运动之框架開始一级简单框架实例