gcc 编译流程分析
//test.c
#include<stdio.h>
int main()
{
int x=,y=;
printf("x=%d y=%d\n",x,y);
return ;
}
1:预处理阶段,对包含的头文件(#include)和宏定义(#define,#ifdef等)进行处理。在上述的代码处理过程中,编译器将包含的头文件stdio.h编译进来,并且让用户使用选项”-E“
进行查看,该选项的作用是让gcc在预处理结束后停止编译过程。”.i“文件为已经过预处理的c程序。一下列出部分test.i文件的内容:
# "test.c"
# "<built-in>"
# "<command-line>"
# "test.c"
# "/usr/include/stdio.h"
# "/usr/include/stdio.h"
# "/usr/include/features.h"
# "/usr/include/features.h"
# "/usr/include/sys/cdefs.h"
# "/usr/include/sys/cdefs.h"
# "/usr/include/bits/wordsize.h"
# "/usr/include/sys/cdefs.h"
# "/usr/include/features.h"
# "/usr/include/features.h"
# "/usr/include/gnu/stubs.h"
..................................................
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ; extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# "/usr/include/stdio.h" # "test.c"
int main()
{
int x=,y=;
printf("x=%d y=%d\n",x,y);
return ;
}
2:编译阶段
接下来进行编译阶段,在这个阶段中,gcc首先要检查代码的规范性,是否有语法错误等,以确定代码实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。用户可以使用
“-S”选项来进行查看,该选项只进行编译而不进行汇编,结果生成汇编代码。
下面列出汇编代码test.s
.file "test.c"
.section .rodata
.LC0:
.string "x=%d y=%d\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-, %esp
subl $, %esp
movl $, (%esp)
movl $, (%esp)
movl $.LC0, %eax
movl (%esp), %edx
movl %edx, (%esp)
movl (%esp), %edx
movl %edx, (%esp)
movl %eax, (%esp)
call printf
movl $, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.4.6 20120305 (Red Hat 4.4.6-4)"
.section .note.GNU-stack,"",@progbits
3:汇编阶段
汇编阶段把编译生成的.s文件转换成目标文件,读者在此使用选项“-c"就可以看到汇编代码已经转换成”.o“的二进制目标代码了!
4:连接阶段
在成功编译后,之后进入连接阶段。这里涉及到一个重要的概念:函数库。
读者可以查看这个程序,在这个程序中并没有定义”printf"的函数实现,且在预编译中包含进来的“stdio"中也只有该函数的声明,而没有函数的实现,那么是在哪里实现了
“printf”函数呢?最后的答案是系统把这些函数的实现都放在名为lib.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径”/usr/bin"下进行查找,也就是链接到libc.so.6函数库中去,这样就能调用函数“printf"了,而这正是动态链接的作用。
函数库有静态库和动态库两种。静态库是指编译链接时,将库文件的代码全部加入可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名通常为”.a“。动态库与之相反,在编译链接时并没有将库文件的代码加入到可执行文件中,而是在程序执行时加载库,这样可以节省系统的开销。一般动态库的后缀名为”.so“,如前面所述的lib.so.6就是动态库。gcc在编译时默认使用动态库。
完了链接之后,gcc 就可以生成可执行文件。






gcc 编译流程分析的更多相关文章
- GCC编译流程浅析
GCC-GCC编译流程浅析 序言 对于大多数程序员而言,大家都知道gcc是什么,但是如果不接触到linux平台下的开发,鲜有人真正了解gcc的编译流程,因为windows+IDE的开发模式简直是一条龙 ...
- GCC 编译流程简介
GCC-GCC编译流程 序言 对于大多数程序员而言,大家都知道gcc是什么,但是如果不接触到linux平台下的开发,鲜有人真正了解gcc的编译流程,因为windows+IDE的开发模式简直是一条龙全套 ...
- GCC编译流程及常用编辑命令
GCC 编译器在编译一个C语言程序时需要经过以下 4 步: 将C语言源程序预处理,生成.i文件. 预处理后的.i文件编译成为汇编语言,生成.s文件. 将汇编语言文件经过汇编,生成目标文件.o文件. 将 ...
- 一次gcc编译失败分析
1. 场景: 在使用gcc编译时,编译器报错:xxx:'xxx'未定义的引用 2. 排查过程: 首先,我很自然的想到是不是自己使用了未定义的函数或者将函数名称写错了,在检查了一边过后,我发现自己使 ...
- gcc编译流程
gcc的编译流程分为四个步骤,分别为: 预处理(Pre-Processing) 编译(Compiling) 汇编(Assembling) 链接(Linking) 以hello.c为例子,在这四个步骤中 ...
- 面试题----gcc的编译流程
gcc编译流程 一. 编译与处理指令: gcc -E hello.c -o a.c 如果不使用-o指定输出的文件,会默认输出到终端.所以建议使用同时使用-o选项. 还要注意:编译时会保留#pra ...
- esp8266 SDK开发之编译流程
最近刚完成自己8266的小项目,已经发布在github上,有兴趣的朋友可以看一下 github地址:esp-ujn 1. 通过MQTT协议与服务器交互 2. 内置HTTP服务器,支持通过浏览器进行参数 ...
- [uboot] (第四章)uboot流程——uboot编译流程
http://blog.csdn.net/ooonebook/article/details/53000893 以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为 ...
- [uboot] (第二章)uboot流程——uboot-spl编译流程
http://blog.csdn.net/ooonebook/article/details/52949584 以下例子都以project X项目tiny210(s5pv210平台,armv7架构)为 ...
随机推荐
- Ubuntu简单搭建git私有服务
gitserver搭建过程 搭建gitserver过程记录 例如以下: 环境: serverUbuntu虚拟机(Boss),能通过网络訪问到(server地址:192.168.9.103). clie ...
- [简谈]绕过HR破门而入的求职智慧
以往我们在网上看到的非常多求职文章或指导性纲领,譬如啥自信.做功课.良好形象.华丽的简历.工作经验.口才啥的,事实上到了21世纪尤其是互联网快速发展的今天,前面这些技巧就显得无比空洞: 1.由于自信谁 ...
- PHP快速入门 如何配置Apache服务器
点击安装Apache,一直下一步 填写域名(Network Domain),服务器名(Server Name),和管理员邮箱(三条都可以任意填写) 下一步的时候选择(Custom),然后在Apache ...
- vue - 使用axios
1. 先安装axios 1.1 npm安装:npm i -D axios 1.2 yarn 安装:yarn add axios --dev 2. 配置main.js,在src目录下. 3. 使用
- Android相机基础基于camera2API
前言 最近,在使用Android做一个照相机的开发.因为不能使用系统提供的相机应用,所以只能自己写一个.Android以前提供相机的api叫camera,不过在level 21被Google抛弃了.网 ...
- 数据挖掘学习指引<一>
对于当前热门的大数据.云计算等技术,被百度.阿里等国内互联网巨头炒的非常火,数据挖掘作为一门非常有用的技术,在商业管理.市场分析.科学计算等大数据方面发挥着大作用. 数据挖掘技术也变得非常火,why? ...
- ant design pro (十)advanced 图表
一.概述 原文地址:https://pro.ant.design/docs/graph-cn Ant Design Pro 提供了由设计师精心设计抽象的图表类型,是在 BizCharts 图表库基础上 ...
- Java Tread多线程(1)实现Runnable接口
作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39347245 本文演示,Tread多线程实现Runnable接口,以及简单 ...
- 编译VLC for IOS
之前接触VLC是因为Winrt的项目,后来似乎ARM版本的始终搞不定(没有针对于ARM-COFF的GCC编译器),vlc for winrt的项目好久没有更新了,自己也没有深入研究.有一天跟同事聊,他 ...
- 从缓存行出发理解volatile变量、伪共享False sharing、disruptor
volatilekeyword 当变量被某个线程A改动值之后.其他线程比方B若读取此变量的话,立马能够看到原来线程A改动后的值 注:普通变量与volatile变量的差别是volatile的特殊规则保证 ...