Linux编译器——gcc

1.简介

GNU CC(简称gcc)是GNU项目中符合ANSI C标准的编译系统,能够编C、C++、Object C、java、Fortran、Pascal、Modula-3和Ada等多种语言,而且gcc是一个交叉平台编译器,能够在当前CPU平台上为多种不同体系结构的硬件平台开发软件,因此尤其适合在嵌入式领域的开发编译。

gcc所支持后缀名解释
后缀名 所对应的语言 后缀名 所对应的语言
.c C原始程序 .s/.S 汇编语言原始程序
.C/.cc/.cxx C++原始程序 .h 预处理文件(头文件)
.m Objective-C原始程序 .o 目标文件
.i 已经过预处理的C原始程序 .a/.so 编译后的库文件
.ii 已经过预处理的C++原始程序 ... ...

2.gcc编译流程解析

gcc的编译流程分为四个步骤:

(1)预处理(Pre-Processing)

在这个阶段,编译器将对包含的头文件(#include)和宏定义(#define、#ifdef)等编译进文件中。

如:gcc -E hello.c -o hello.i (-E的作用是让gcc在预处理结束后停止编译过程)

(2)编译阶段

在编译阶段,gcc首先要检测代码的规范性、是否错误等,在检测无误后将代码翻译成汇编语言。

如:gcc -S hello.i -o hello.s(-S的作用是让gcc在编译阶段结束后停止编译过程)

(3)汇编阶段

汇编阶段是把编译阶段生成的.s文件转成目标文件。

如:gcc  -c hello.s -o hello.o(-c的作用是将.s文件转化为.o文件(二进制代码))

(4)链接阶段

链接阶段有一个重要的概念:库函数(库函数分为静态库和动态库两种)。

     1)静态库:指编译链接时,将库文件的代码全部加入可执行文件中,因此生成的文件比较大,但是运行时就不再需要库文件,后缀通常为.a。

     2)动态库:在编译链接阶段,并没有将库代码添加到可执行文件中,而是在程序运行时加载库,这样可以节省系统的开销,后缀通常为.so。

如:gcc hello.o -o hello,接着执行./hello则可获得正确的结果。

3.gcc编译选项分析

PS:gcc可用选项主要包括总体选项、告警和出错选项、优化选项和体系结构相关选项。

(1)常用选项

gcc常用选项列表
选项 含义
-c 只编译不链接,生成目标文件.o
-S 只编译不汇编,生产汇编代码.s
-E 只进行预处理,不做其他处理
-g 在可执行程序中包含标准调试信息
-o file 将file文件指定为输出文件
-v 打印出编译器内部编译各过程的命令行星系和编译器的版本
-I dir 在头文件的收索路径列表中添加dir目录

PS:在include语句中,“<>”表示在标准路径中搜索头文件,“ “” ”表示在本目录中搜索。

(2)库选项

gcc库选项列表
选项 含义
-static 进行静态编译,即链接静态库,禁止使用动态库
-shared

1.可以生成动态库文件

2.进行动态编译,尽可能地链接动态库,只有当没有动态库时才会链接同名的静态库(默认选项,可省略)

-L dir 在库文件的搜索路径列表中添加dir路径
-lname 链接称为libname.a(静态库)或者libname.so(动态库)的库文件。若两个库都存在,则根据编译方式(-static还是-shared)而进行链接
-fPIC(或-fpic) 生成使用相对地址的位置无关的目标代码(Position Independent Code)。然后通常使用gcc的-static选项从该PIC目标文件生成动态库文件

(3)告警和出错选项

gcc警告和出错选项列表
选项 含义
-ansi 支持符合ANSI标准的C程序
-pedantic 允许发出ANSI C标准所列的全部警告信息
-pedantic-error 允许发出ANSI C标准所列的全部出错信息
-w 关闭所有告警
-Wall 允许发出gcc提供的所有有用的告警信息
-werror 吧所有的告警信息转化为错误信息,并在告警发生时终止程序编译过程

(4)优化选项

        gcc可以对代码进行优化,它通过编译选项“-On”来控制优化代码的生成,其中n是一个代表优化级别的整数。

        虽然优化选项可以加速代码的运行速度,但是经过优化后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。

(5)体系结构相关选项

gcc体系结构相关选项列表
选项 含义
-mcpu=type 针对不同的CPU使用相应的CPU指令。可选择的type有i386、i486、pentium及i686等
-mieee-fp 使用IEEE标准进行浮点数的比较
-mno-ieee-fp 不使用IEEE标准进行浮点数的比较
-msoft-float 输出包含浮点库调用的目标代码
-mshort 把int类型作为16位处理,相当于short init
-mrtd 强行将函数参数个数固定的函数用ret NUM返回,节省调用函数的一条指令

你可能感兴趣的:(Linux)