转自:http://blog.csdn.net/eastmoon502136/article/details/8190262/

上篇文章,知道了,C代码编译后存放在内存中的位置,那么C代码的整个编译过程又是怎样的呢?一条命令gcc hello.c就可以编译成可执行程序a.out,然后./a.out之后就可以执行hello.c这个程序的代码了。下面的文章分析的不错,就整理了下。

hello.c:

[html] view plaincopy
  1. #include<stdio.h>
  2. int main()
  3. {
  4. printf(“Hello World\n”);
  5. return 0;
  6. }

实际上gcc hello.c可以分解为4个步骤,分别是预处理(Preprocess),编译(Compilation),汇编(Assembly)和链接(Linking)。

一、预处理

预处理过程主要读取c源程序,对伪指令和特殊符号进行处理。包括宏,条件编译,包含的头文件,以及一些特殊符号。基本上是一个replace的过程。

[html] view plaincopy
  1. gcc –E hello.c –o hello.i

以下为预处理后的输出文件hello.i的内容

[html] view plaincopy
  1. # 1"hello.c"
  2. # 1"<built-in>"
  3. # 1"<command-line>"
  4. # 1"hello.c"
  5. # 1 "/usr/include/stdio.h"1 3 4
  6. # 28"/usr/include/stdio.h" 3 4
  7. /***** 省略了部分内容,包括stdio.h中的一些声明及定义  *****/
  8. # 2"hello.c" 2
  9. int main()
  10. {
  11. printf("Hello World\n");
  12. return 0;
  13. }

预处理过程主要处理规则如下:

1、将所有的#define删除,并且展开所有的宏定义;

2、处理所有条件编译指令,如#if,#ifdef等;

3、处理#include预编译指令,将被包含的文件插入到该预编译指令的位置。该过程递归进行,及被包含的文件可能还包含其他文件。

4、删除所有的注释//和 /**/;

5、添加行号和文件标识,如#2 “hello.c” 2,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号信息;

6、保留所有的#pragma编译器指令,因为编译器须要使用它们;

二、编译

编译过程通过词法和语法分析,确认所有指令符合语法规则(否则报编译错),之后翻译成对应的中间码,在Linux中被称为RTL(Register Transfer Language),通常是平台无关的,这个过程也被称为编译前端。编译后端对RTL树进行裁减,优化,得到在目标机上可执行的汇编代码。gcc采用as作为其汇编器,所以汇编码是AT&T格式的,而不是Intel格式,所以在用gcc编译嵌入式汇编时,也要采用AT&T格式。

[html] view plaincopy
  1. gcc –S hello.i –o hello.s

以下为编译后的输出文件hello.s的内容

[html] view plaincopy
  1. .file  "hello.c"
  2. .section    .rodata
  3. .LC0:
  4. .string      "HelloWorld"
  5. .text
  6. .globl main
  7. .type         main, @function
  8. main:
  9. pushl         %ebp
  10. movl          %esp, %ebp
  11. andl $-16, %esp
  12. subl  $16, %esp
  13. movl          $.LC0, (%esp)
  14. call   puts
  15. movl          $0, %eax
  16. leave
  17. ret
  18. .size main, .-main
  19. .ident        "GCC: (GNU)4.4.0 20090506 (Red Hat 4.4.0-4)"
  20. .section   .note.GNU-stack,"",@progbits

三、汇编

汇编器是将汇编代码转变成机器可以执行的命令,每一个汇编语句几乎都对应一条机器指令。汇编相对于编译过程比较简单,根据汇编指令和机器指令的对照表一一翻译即可。

[html] view plaincopy
  1. gcc –c hello.c –o hello.o

由于hello.o的内容为机器码,不能以文本形式方便的呈现。

四、链接

链接器ld将各个目标文件组装在一起,解决符号依赖,库依赖关系,并生成可执行文件。

[html] view plaincopy
  1. ld –static crt1.o crti.o crtbeginT.ohello.o –start-group –lgcc –lgcc_eh –lc-end-group crtend.o crtn.o

(省略了文件的路径名)。

当然链接的时候还会用到静态链接库,和动态连接库。静态库和动态库都是.o目标文件的集合。

静态库是在链接过程中将相关代码提取出来加入可执行文件的库(即在链接的时候将函数的代码将从其所在地静态链接库中被拷贝到最终的可执行程序中),ar只是将一些别的文件集合到一个文件中。可以打包,当然也可以解包。

[html] view plaincopy
  1. ar -v -q  test.a test.o

上面指令可以生成静态链接库test.a

动态库在链接时只创建一些符号表,而在运行的时候才将有关库的代码装入内存,映射到运行时相应进程的虚地址空间。如果出错,如找不到对应的.so文件,会在执行的时候报动态连接错(可用LD_LIBRARY_PATH指定路径)。用file test.so可以看到test.so是shared object的ELF文件。

[html] view plaincopy
  1. gcc -sharedtest.so test.o

上面指令可以生成动态连接库test.so

好了,整个编译过程就如上所示了,那么对于gcc还有一些编译的选项的。具体如下:

GCC编译选项

1. -c

编译产生对象文件(*.obj)而不链接成可执行文件,当编译几个独立的模块,而待以后由链接程序把它们链接在一起时,就可以使用这个选项,如:

[html] view plaincopy
  1. gcc -c hello.c ===> hello.o
  2. gcc hello.o

2. -o

允许用户指定输出文件名,如

[html] view plaincopy
  1. gcc hello.c -o hello.o
  2. or
  3. gcc hello.c -o hello

3. -g

指明编译程序在编译的输出中应产生调试信息.这个调试信息使源代码和变量名引用在调试程序中或者当程序异常退出后在分析core文件时可被使用.

4. -D

允许从编译程序命令行定义宏符号

一共有两种情况:一种是用-DMACRO,相当于在程序中使用#define MACRO,另一种是用-DMACRO=A,相当于程序中的#define MACRO A.如对下面这代码:

[html] view plaincopy
  1. #ifdef DEBUG
  2. printf("debugmessage\n");
  3. #endif

编译时可加上-DDEBUG参数,执行程序则打印出编译信息

5. -I

可指定查找include文件的其他位置.例如,如果有些include文件位于比较特殊的地方,比如/usr/local/include,就可以增加此选项如下:

[html] view plaincopy
  1. gcc -c -I/usr/local/include -I/opt/include hello.c

此时目录搜索会按给出的次序进行.

6. -E

这个选项是相对标准的,它允许修改命令行以使编译程序把预先处理的C文件发到标准输出,而不实际编译代码.在查看C预处理伪指令和C宏时,这是很有用的.可能的编译输出可重新定向到一个文件,然后用编辑程序来分析:

[html] view plaincopy
  1. gcc -c -E hello.c >cpp.out

此命令使include文件和程序被预先处理并重定向到文件cpp.out.以后可以用编辑程或者分页命令分析这个文件,并确定最终的C语言代码看起来如何.

7. -O

优化选项,这个选项不是标准的

-O和 -O1指定1级优化

-O2 指定2级优化

-O3 指定3级优化

-O0指定不优化

gcc -c O3 -O0 hello.c

当出现多个优化时,以最后一个为准!!

8. -Wall

以最高级别使用GNU编译程序,专门用于显示警告用!!

[html] view plaincopy
  1. gcc -Wall hello.c

9. -L

指定连接库的搜索目录,-l(小写L)指定连接库的名字

[html] view plaincopy
  1. gcc main.o -L/usr/lib -lqt -o hello
[html] view plaincopy

10.-share   

此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库

11.-static  

此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么动态连接库

12.-fPIC

表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

和菜鸟一起学linux之V4L2摄像头应用流程【转】相关推荐

  1. 和菜鸟一起学linux之V4L2摄像头应用流程

    一.概述 Video for Linuxtwo(Video4Linux2)简称V4L2,是V4L的改进版.V4L2是linux操作系统下用于采集图片.视频和音频数据的API接口,配合适当的视频采集设备 ...

  2. 我们一起学linux之V4L2摄像头应用流程

    一.概述 Video for Linuxtwo(Video4Linux2)简称V4L2,是V4L的改进版.V4L2是linux操作系统下用于采集图片.视频和音频数据的API接口,配合适当的视频采集设备 ...

  3. linux之V4L2摄像头应用流程

    对于v4l2,上次是在调试收音机驱动的时候用过,其他也就只是用i2c配置一些寄存器就可以了.那时只是粗粗的了解了,把收音机当作v4l2的设备后会在/dev目录下生成一个radio的节点.然后就可以操作 ...

  4. C语言高级应用---操作linux下V4L2摄像头应用程序

    目录(?)[-]采集方式V4L2操作流程点击这个网址说得很详细了这里不多说httpbaikebaiducomview5494174htm我们都知道,想要驱动Linux下的摄像头,其实很简单,照着V4L ...

  5. 和菜鸟一起学linux内核源码之启动篇

    又是一个周末,日子过得比较散,虽然期间也有不断地看书学习,总觉得有点小盲目.想想毕业也快要1年了,从事嵌入式linux的研发工作也1年多了.这1年多的从实习到正式工作到现在的自己,进步有,也很大,但是 ...

  6. 和菜鸟一起学linux内核源码之基础准备篇

    注:以下大部分内容摘自Linux内核编程入门篇和linux内核完全注释 在工作的这段时间,发现我的visio画图熟悉了点点,总喜欢把什么源码啊,结构啊之类的就当作流程图来画来理解,因为对于图,有一个很 ...

  7. 和菜鸟一起学linux之DBUS基础学习记录

    转自:http://blog.csdn.net/eastmoon502136/article/details/10044993 D-Bus三层架构 D-Bus是一个为应用程序间通信的消息总线系统, 用 ...

  8. 和菜鸟一起学linux之bluez学习记录2

    这里主要摘取对于hci,l2cap,sdp和rfcomm的一些应用编程. 关于hci 一.HCI层协议概述 1.HCI Command Packets 详见bluez源码:lib/hci.h /* L ...

  9. 和菜鸟一起学linux总线驱动之初识spi驱动数据传输流程【转】

    转自:http://blog.csdn.net/eastmoon502136/article/details/7921846 对于SPI的一些结构体都有所了解之后呢,那么再去瞧瞧SPI的那些长见的操作 ...

最新文章

  1. 4、jQuery实现的全选、反选和不选功能
  2. 史上最全GAN综述2020版:算法、理论及应用
  3. 【 FPGA 】FIR 滤波器之半带插值器(Half-band Interpolator)
  4. python快速编程入门课后简答题答案-Python编程:从入门到实践(第2版)第1章习题答案...
  5. 创建 .m2 文件夹
  6. 云炬随笔20161117
  7. vb.net2019-读逗号分隔csv等文件
  8. python变量定义类型_03_python的数据类型和变量的定义及使用
  9. mysql-查询二-分组与聚合
  10. linux模块导出符号 EXPORT_SYMBOL_GPLEXPORT_SYMBOL(转)
  11. 谈一下对c语言程序设计,谈《C语言程序设计》课程教学.doc
  12. 操作系统(4)状态机视角下的程序执行
  13. [六省联考2017]相逢是问候(线段树+拓展欧拉定理)
  14. Drools7.5.0教程-目录
  15. Swift最新的AES加密解密
  16. CF Stressful training优先队列加二分搜答案
  17. AUTODESK 卸载工具,完美彻底卸载清除干净autodesk各种软件残留注册表和文件
  18. 101.新拟物渐变加载特效
  19. 装在笔记本里的私有云环境:准备篇
  20. 关键帧与地图点(二):关键帧

热门文章

  1. 【Oracle】设置快速恢复区及reset快速恢复区
  2. 20-21-2网络管理quiz3
  3. Win8.1/Win10在某些程序输入中文变成问号的解决方法
  4. 微信JSSDK多图片上传并且解决IOS系统上传一直加载的问题
  5. IIS7 应用程序池自动回收关闭的解决方案
  6. 【异常(待解决)】org.apache.http.NoHttpResponseException: api.weixin.qq.com:443 failed to respond
  7. 利用顺序栈解决括号匹配问题(c++)-- 数据结构
  8. ActiveMQ代码示例
  9. pythonsocket自动化教程_Python基本socket通信控制操作示例
  10. java 单链表是否有环_数据结构与算法随笔之链表-链表是否有环(二)