UBuntu12.04下用gcc编译c文件过程详解
2016-03-21 23:16
363 查看
一 文件准备
因为正好要做作业,所以用vim写了如下两个文件:(是一个处理字符串的程序,不要在意,和gcc解释没什么关系。)放在~/Downloads1. reverse.h
#include<stdio.h> #include<string.h> void reverse(char *str);
2. reverse.c
#include"reverse.h" void reverse(char *str) { int i; int len; char c; len=strlen(str); for(i=0;i<len/2;i++) { c=*str+i; *(str+i)=*str+len-i-1; *(str+len-i-1)=c; } } int main() { char str[1024]; printf("Give me a word to reverse:\n"); scanf("%s",str); reverse(str); printf("REVERSED: %s\n",str); return 0; }文件如下:
二 一步式gcc编译C文件
在终端输入如下命令:gcc reverse.c -o reverse -I ./可以看到文件夹里出现了一个reverse可执行文件,如图:
在终端输入如下命令:
./reverse运行结果如图:
如上 -o选项就是链接,后面加上生成的可执行文件的名字,不输入默认为 a.out 。所有步骤都隐式被悄悄搞定了,生成的文件用完都删掉了。-I 选项后面加上 reverse.h 的路径,即告诉编译器在这个目录下找头文件,因为在 reverse.c 中用到了 reverse.h 。如果它们在同一个目录下是可以省略的。
也可以用如下形式一步搞定,终端输入:
rm reverse /*删掉刚才生成的可执行文件,此时终端已经进入Downloads*/ gcc reverse.c -o reverse.o ./reverse.o文件列表如下:
多了一个reverse.o。.o文件是目标文件类型,可以直接运行,因为已经完成了所有步骤,只是跟上一个的名字不一样而已就类似a.out。如果在reverse.o属性栏中把名称改成 reverse.out 就会变成 reverse 的类型,即可执行文件。如图:
三 分步详细解析
gcc编译C文件一共四步,预处理(Preprocess),编译(Compilation),汇编(Assembly)和链接(Linking)。
1. 预处理(Preprocess)
预处理是预处理中会展开以#起始的行,包括#if、#ifdef、#if ndef、 #else 、 #elif 、 # endif、#define、#include、#line、 #error、#pragma以及单独的#。其实就是把除了函数(包括main)以外的东西都展开成指定的形式,比如加上行号等,并将头文件里包含的东西所对应的文件(包括子文件夹)也都写入进去以便调用。同时也会把写在文件里的注释都删掉。在终端输入:
//rm reverse.out 删除刚才生成的reverse.out gcc -E reverse.c -o reverse.i可以看到生成一个名字为reverse.i的文件。
通过vim可以看到一共是1136行,多加了上千行,都是预处理做的事情。
-E是仅激活预处理程序,将生成的信息放入reverse.i。如果不写 -o reverse.i 就会生成到终端显示。相当于重定向。
2. 编译(compilation)
编译的作用就是把预处理完的文件进行一系列语法分析及优化后生成相应的汇编文件。终端输入:
gcc -S reverse.i -o reverse.s运行完后会生成一个 reverse.s 文件:
用vim打开后可以看到一共变成了129行,并且没有了源文件的内容,变成了一条条汇编指令。
3. 汇编(Assembly)
汇编就是把生成的汇编指令逐条翻译成机器可以识别的形式,即机器码,这一步会产生平台相关性,即决定了在哪种平台下运行。在终端输入:
gcc -c reverse.s -o reverse.o可以看到又生成了一个文件reverse.o。
是不是很熟悉,刚才第二种一步式就是生成它就可以直接运行了,现在依然可以,但还有最后一步才能生成可执行文件哦,reverse.o打开之后是乱码,改成十六进制之后虽然能看清楚是什么数字,但毕竟是二进制,还要进行翻译才能形成汇编指令。可以用vim进行转换。在vim的命令行模式(进入后按Esc后按:进入命令行模式),输入:
vim -b filename //文件名,注意替换 //进入命令行后: :%!xxd //要再输入一个:,一共两个:!
如图所示:仅仅比汇编指令多了13行(包括过滤掉了6行)
4. 链接(Linking)
这是最后一步,将生成的目标文件和其所依赖的库文件进行连接,生成一个可执行文件。细节方面这里就不研究啦,感兴趣的可以去度娘那里找对应的步骤的详细解释,有很多好文章。终端输入:
gcc reverse.o -o reverse ./reverse可以看到reverse可执行文件(菱形)就出来了,通过第二行命令就可以运行了。
运行结果与上面一步式相同,就不再列举了。到此就是整个gcc搞定C文件的全部步骤了。接下来就是gdb的调试了。
相关文章推荐
- sed && awk工具 及一些常用的shell脚本
- 渐变颜色的进度条WGradientProgress-备用
- caffe模型训练
- Gson详细使用,此Gson非彼Json,你值得拥有~
- C++学习
- Windows下安装MongoDB 3.2
- hihoCoder 1015 KMP算法
- Node.js与J2EE的CQRS框架整合的架构猜想
- bzoj 2428: [HAOI2006]均分数据
- 设置iOS项目BuildVersion自动增加-备用
- 同时具有get和post数据
- 项目运行报错:严重: A child container failed during start java.util.concurrent.ExecutionException: org.apache
- C++学习笔记(一)
- NSURLSession详解
- springMVC
- 完成价值管理系统merit的用户价值分值统计排序
- 面试问题
- openstack学习(一)kvm-libvirt
- 晴 15℃ 3.21日
- 2424: [HAOI2010]订货