在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_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq $.LC0, -8(%rbp)
movl $1, %eax
leave
.cfi_def_cfa 7, 8
ret
.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: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 296 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 13
Section header string table index: 10 Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS 0000000000000000 00000040
0000000000000013 0000000000000000 AX 0 0 4
[ 2] .rela.text RELA 0000000000000000 00000568
0000000000000018 0000000000000018 11 1 8
[ 3] .data PROGBITS 0000000000000000 00000054
0000000000000000 0000000000000000 WA 0 0 4
[ 4] .bss NOBITS 0000000000000000 00000054
0000000000000000 0000000000000000 WA 0 0 4
[ 5] .rodata PROGBITS 0000000000000000 00000054
0000000000000006 0000000000000000 A 0 0 1
[ 6] .comment PROGBITS 0000000000000000 0000005a
000000000000002d 0000000000000001 MS 0 0 1
[ 7] .note.GNU-stack PROGBITS 0000000000000000 00000087
0000000000000000 0000000000000000 0 0 1
[ 8] .eh_frame PROGBITS 0000000000000000 00000088
0000000000000038 0000000000000000 A 0 0 8
[ 9] .rela.eh_frame RELA 0000000000000000 00000580
0000000000000018 0000000000000018 11 8 8
[10] .shstrtab STRTAB 0000000000000000 000000c0
0000000000000061 0000000000000000 0 0 1
[11] .symtab SYMTAB 0000000000000000 00000468
00000000000000f0 0000000000000018 12 9 8
[12] .strtab STRTAB 0000000000000000 00000558
000000000000000e 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 + 0 Relocation 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 + 0 There are no unwind sections in this file. Symbol table '.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c
2: 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 就能够完毕最后的链接操作并生成可运行文件,至于怎样生成动态库和静态库,以及怎样链接动态库和静态库,以后会再作介绍。

Linux下Gcc 的编译过程的更多相关文章

  1. Linux下指定版本编译安装LAMP

    说明: 操作系统:CentOS 6.5 64位 需求: 编译安装LAMP运行环境 各软件版本如下: MySQL:mysql-5.1.73 Apache:httpd-2.2.31 PHP:php-5.2 ...

  2. Linux C程序的编译过程

    Linux C程序的编译过程 学习一门语言程序,本人觉得还是得学习它的编译规则,现在,通过小例子小结下自己对C编译的认识. /*test.c     了解C程序的编译*/ #include <s ...

  3. linux下使用g++编译cpp工程

    C++编程中相关文件后缀 1.单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码: /* helloworld.cpp */ #includ ...

  4. Linux下使用javac编译

    Linux下使用javac编译Hadoop程序 首先要配置好Hadoop, 给出两个教程 Hadoop安装教程单机/伪分布式配置Hadoop2.6.0/Ubuntu14.04 Hadoop集群安装配置 ...

  5. [oracle] oracle的三种密码验证机制以及在windows和linux下的不同启动过程

    oracle数据库的密码验证机制: ① 操作系统验证 拥有SYSDBA和SYSOPER的用户用该方式验证此时数据库无需启动,也无需开启监听和实例服务. 要求:本地组ora_dba中有该操作系统的登录用 ...

  6. linux下gcc编译多个源文件、gdb的使用方法

    一. gcc常用编译命令选项 假设源程序文件名为test.c. 1. 无选项编译链接 用法:#gcc test.c 作用:将test.c预处理.汇编.编译并链接形成可执行文件.这里未指定输出文件,默认 ...

  7. linux下gcc编译的参数详细说明

    参考网址:1 http://hi.baidu.com/zengzhaonong/item/f1f9383565fa5c302e0f8125 gcc使用方法 汇总 2 http://s99f.blog. ...

  8. Linux下编辑、编译、调试命令总结——gcc和gdb描述

    GCC gcc是linux系统集成的编译器.在linux环境下编辑程序,首先需要克服的便是没有集成开发环境的一键式操作所带来的麻烦.这其中涉及命令行操作.编译选项的设定.文件依赖关系的书写(makef ...

  9. Linux下gcc和g++编译helloworld

    linux C(hello world) 1.使用vi/vim进行编写代码并保存为hello_world.c.如下: 1 2 3 4 5 6 /* This is my first C program ...

随机推荐

  1. 怎样从SpringMVC返回json数据

    Srping3中配置 maven依赖pom.xml 需要jackson库的依赖 <dependency> <groupId>org.codehaus.jackson</g ...

  2. vue 封装自定义组件

    组件结构 sjld >index.js >sjid.vue 最好单独放一个文件夹,有依赖的话装依赖 Sjld.vue 内容 <template id="sjld" ...

  3. Luogu P4299 首都 LCT

    既然是中文题目,这里便不给题意. 分析: 这个题的做法据说是启发式合并? 但是我不会啊…… 进入正题,LCT是怎样做掉这道题的.记得在前面的一篇<大融合>的题解中,介绍过LCT维护子树信息 ...

  4. 大项目之网上书城(八)——数据库大改&添加图书

    目录 大项目之网上书城(八)--数据库大改&添加图书 主要改动 1.数据库新增表 代码 2.数据库新增触发器 3.其他对BookService和BookDao的修改 代码 4.addBook. ...

  5. copy on write

    yl::string CBaseAutopProcessor::AddAuthorizedInfo(const yl::string & strOriginalUrl, const yl::s ...

  6. Servlet中的几个重要的对象(转)

    讲解四大类,ServletConfig对象,ServletContext对象.request对象,response对象 ServletConfig对象 获取途径:getServletConfig(); ...

  7. c#数据库连接学习

    /*通过C#winform程序访问数据库数据 用到的命名空间和变量类型: using System.Data.SqlClient; SqlConnection:数据库连接类 SqlCommand:数据 ...

  8. 闲着无聊 一个python的,三级菜单。装逼版。

    menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {}, '汽车之家': ...

  9. Leetcode 174.地下城游戏

    地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主. ...

  10. bzoj4553 [Tjoi2016&Heoi2016]序列 树状数组(区间最大值)+cqd

    [Tjoi2016&Heoi2016]序列 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1006  Solved: 464[Submit][ ...