文章目录

  • 简介
  • 一、拆解编译过程
    • 1、准备源程序
    • 2、分析拆解过程
    • 3、 多个程序文件的编译
    • 4、检错的编译选项
      • 1、-pedantic 编译选项
      • 2、-Wall 编译选项
      • 3、-Werror 编译选项
  • 二、分析 ELF 文件
    • 1.ELF 文件格式
    • 2.查看ELF文件的段内容,或查看指令与数据
      • 1、查看ELF文件的段内容
      • 2、查看指令与数据
  • 总结

简介

GCC 的意思也只是 GNU C Compiler 而已。经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言;它现在还支持 Ada 语言、C++ 语言、Java 语言、Objective C 语言、Pascal 语言、COBOL 语言,以及支持函数式编程和逻辑编程的 Mercury 语言,等等。而 GCC 也不再单只是 GNU C 语 言编译器的意思了,而是变成了 GNU Compiler Collection 也即是 GNU 编译器家族的意思了。另 一方面,说到 GCC 对于操作系统平台及硬件平台支持,概括起来就是一句话:无所不在。


一、拆解编译过程

1、准备源程序

一般来说编译一步到位的指令为

gcc test.c -o test

2、分析拆解过程

我们可以拆解成:预处理、编译为汇编代码、汇编、连接等,一步步来编译源程序。

1、预处理命令为:

gcc -E test.c -o test.i 或 gcc -E test.c

命令含义:

将源文件 hello.c 文件预处理生成 hello.i
GCC 的选项-E 使 GCC 在进行完预处理后即停止

预处理过程:

(1)将所有的#define 删除,并且展开所有的宏定义,并且处理所有的条件预编 译指令,比如#if #ifdef #elif #else #endif 等。
(2) 处理#include 预编译指令,将被包含的文件插入到该预编译指令的位置。
(3) 删除所有注释“//”和“/* */”。
(4) 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号。
(5) 保留所有的#pragma 编译器指令,后续编译过程需要使用它们

查看一下.i文件

打开 test.i 文件一看,就明白了。后 面那条指令,是直接在命令行窗口中输出预处理后的代码.

2、编译为汇编代码

gcc -S test.i -o test.s

命令含义:

将预处理生成的 hello.i 文件编译生成汇编程序 hello.s
gcc 的-S 选项,表示在程序编译期间,在生成汇编代码后,停止,-o 输出汇编代码文件。

处理内容:

编译过程就是对预处理完的文件进行一系列的词法分析,语法分析,语义分析及 优化后生成相应的汇编代码。

3、汇编

gcc -c test.s -o test.o

命令含义:

将编译生成的 hello.s 文件汇编生成目标文件 hello.o
GCC 的选项-c 使 GCC 在执行完汇编后停止,生成目标文件

处理内容:

汇编过程调用对汇编代码进行处理,生成处理器能识别的指令,保存在后缀为.o 的目标文件中。

需要注意的是目标文件已经是最终程序的某一部 分了,只是在链接之前还不能执行。
4、链接
链接又分为静态链接与动态链接:
详见:
https://blog.csdn.net/qq_52215423/article/details/127028762

gcc test.o -o test

生成可执行文件后,可以使用 Binutils 的 size 命令查看文件大小和使用 Binutils 的 ldd 命令查看链接的动态库。

size hello
ldd hello

3、 多个程序文件的编译

通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用 GCC 能够很好地管理 这些编译单元.

我们可以使用下面这行命令一步到位:

gcc test1.c test2.c -o test

如果同时处理的文件不止一个,GCC 仍然会按照预处理、编译和链接的过程依次进行。如果深究起 来,上面这条命令大致相当于依次执行如下三条命令:

gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test

4、检错的编译选项

1、-pedantic 编译选项

示例:

gcc -pedantic illcode.c -o illcode

-pedantic 选项能够帮助程序员发现一些不符合 ANSI/ISO C 标准的代码,但不是全部,事实上只有 ANSI/ISO C 语言标准中要求进行编译器诊断的 那些情况,才有可能被 GCC 发现并提出警告。

2、-Wall 编译选项

示例:

gcc -Wall illcode.c -o illcode

使用它也能够使 GCC 产生尽可能多的警告信息

3、-Werror 编译选项

示例:

gcc -Werror test.c -o test

在编译程序时带上-Werror 选项,那 么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改。

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二、分析 ELF 文件

1.ELF 文件格式


一个典型的ELF文件包含以下几个段:
说明:

.text:已编译程序的指令代码段。
.rodata:ro 代表 read only,即只读数据(譬如常数 const)。
.data:已初始化的 C 程序全局变量和静态局部变量。
.bss:未初始化的 C 程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试

2.查看ELF文件的段内容,或查看指令与数据

1、查看ELF文件的段内容

可以使用 readelf -S 查看其各个 section 的信息:

$ readelf -S 目标文件

2、查看指令与数据

由于 ELF 文件无法被当做普通文本文件打开,如果希望直接查看一个 ELF 文件包 含的指令和数据,需要使用反汇编的方法。 使用 objdump -D 对其进行反汇编。

$ objdump -D 目标文件

总结

以上就是今天总结的内容,本文仅仅简单分析了GCC的编译与使用,还有一些检错选项来帮助我们查看警告,还介绍了ELF文件的格式等。

Linux GCC 编译过程分析及常用检错的编译选项相关推荐

  1. Linux gcc编译简介、常用命令

    gcc作为linux平台下的标准C编译器,功能很强大.格式如下: gcc [option] [filename] -x language 指定使用的语言 -c 对文件进行编译和汇编,但不进行连接 -S ...

  2. gcc编译命令的常用选项——强烈推荐大家使用 -Wall 选项

    C程序编编译的过程分为如下四个阶段 1.预处理:头文件展开(#include).宏替换(#define).条件编译(#ifdef)(.i)使用预处理器(预处理阶段处理的都是以#开头的代码) 2.编译: ...

  3. Linux里gcc编译过程分析和ELF文件格式学习

    GCC编译器背后的故事及常用命令.了解ELF文件格式 前言 一.GCC简介 二.GCC背后的战友 1.Binutils 2.C运行库 三.GCC编译流程及对应命令 1.编译流程图及命令框图 2.实践操 ...

  4. Ubuntu18.04系统下,gcc编译过程分析、命令参数介绍及ELF文件格式学习

    GCC编译器背后的故事及常用命令.了解ELF文件格式 文章目录 GCC编译器背后的故事及常用命令.了解ELF文件格式 前言 一.GCC简介 二.GCC背后的战友 1.Binutils 2.C运行库 三 ...

  5. linux gcc编译C程序 分享

    一个c语言程序从源文件到生成可执行文件,编译器需要共经历4个步骤: 1) 预处理:把c文件中预处理命令扫描处理完毕,即对源代码文件中的文件包含(#include).预编译语句(如宏定义#define等 ...

  6. Gcc编译链接及常用选项总结

    转载文章:http://www.franktly.com 前言 GNU CC(简称Gcc)是GNU项目中符合ANSI C标准的编译系统,能够编译用C.C++和Object- C等语言编写的程序.Gcc ...

  7. Linux gcc编译c/c++基本过程

    Linux系统下开发c++程序,那么gcc编译器就是我们绕不过去的一道坎.gcc是GNU出品的一款可以在多种硬件平台上编译处可执行程序的超级编译器,其执行效率比普通的编译器要高出20%~30%左右,而 ...

  8. linux gcc编译undefined reference to `stricmp'问题

    最近gcc编译遇到这样的问题:undefined reference to `stricmp'. 查了下,stricmp是Windows特有函数. 解决方法: stricmp是Microsoft's ...

  9. Linux gcc编译过程及动态/静态库制作

    Linux库概念及如何制作静态库和动态库 1: gcc编译的过程 2: 分文件编程 3: 库(静态库和动态库) 3.1: 库的基本介绍 3.2: 静态和动态库的区别 3.3: 库的制作及使用 3.3. ...

最新文章

  1. 普通帧,关键帧,空白关键帧的区别
  2. R语言使用ggplot2包使用geom_dotplot函数绘制分组点图(配置显示的分组)实战(dot plot)
  3. 贵港java_贵港人才网:经典java笔试题及答案分享
  4. 通过PowerShell开源社区的Win32-OpenSSH来管理你的Windows服务器
  5. 实现Excel数据导入到SQL2005中的方法(回顾)
  6. 一:redis 的string类型 - 相关操作
  7. 使用Oracle WebLogic对应用程序外部的EJB的引用
  8. 【STC15库函数上手笔记】7、PCA与PWM
  9. 总结一下HtmlAgilityPack
  10. 图像处理之卷积---任意卷积核的快速实现
  11. linux 定位 踩内存_运维常见问题故障定位,这里总结全了!
  12. python可视化计算器_使用Python自带GUI tkinter编写一个期权价格计算器
  13. [PLC]ST语言七:MOV_SMOV_CML_BMOV_FMOV_XCH_BCD_BIN
  14. 百度指数爬取+pyppeteer登录(解决旋转验证码)
  15. 用于暴露感测的太阳传感器_凯利讯半导体
  16. delphi学习笔记(2)-object pascal语言的语句 选择自 xmz2629 的 Blog
  17. 基于MATLAB的数字图像处理系统设计
  18. vertica MySQL_Vertica数据库简介
  19. 用户画像第一章(企业级360°全方位用户画像_环境搭建)
  20. solidwork放置螺丝孔以及显示螺纹的问题

热门文章

  1. ab.exe压力测试
  2. 三菱fx2n64mr说明书_FX2N-64MR-001手册三菱FX2N-64MR-001使用说明书 - 广州凌控
  3. RFID 卡片防复制
  4. Git 的暂存区(staging area)理解
  5. 微信会员卡管理系统:店铺智慧化管理和营销,只需一款软件
  6. 上海东方美谷JW万豪、福清喜来登、宁波杭州湾凯悦等酒店开业 | 中国酒店周刊...
  7. html5网页中的表格教程,javascript程序设计_达内javascript教程-达内web前端培训
  8. Python 多进程 multiprocessing.Pool类详解
  9. 高斯投影坐标计算例题_高斯投影坐标计算程序下载
  10. Android系统定位获取经纬度