Linux中gcc编译器的用法

在Linux环境下进行开发,gcc是非常重要的编译工具,所以学习gcc的基本常见用法时非常有必要的。

一.首先我们先说明下gcc编译源文件的后缀名类型

.c为后缀的文件,C语言源代码文件;

.a为后缀的文件,是由目标文件构成的档案库文件;

.C,.cc或.cxx 为后缀的文件,是C++源代码文件;

.h为后缀的文件,是程序所包含的头文件;

.i 为后缀的文件,是已经预处理过的C源代码文件;

.ii为后缀的文件,是已经预处理过的C++源代码文件;

.m为后缀的文件,是Objective-C源代码文件;

.o为后缀的文件,是编译后的目标文件;

.s为后缀的文件,是汇编语言源代码文件;

.S为后缀的文件,是经过预编译的汇编语言源代码文件。

二.接下来,我们就具体介绍下gcc命令的具体用法了

gcc的基本命令格式是:gcc [options] [filenames]

其中[options]就是编译器需要制定的相应选项,filenames就是相关文件的名称,下面我就介绍下做常用的几个options

(注意:一定要区分编译选项里的大小写,他们时代表不同的含义)

(1) -c :只是进行编译而不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。

(2) -o output_filename :确定输出的文件的名称为output_filename,如果不给出这个选项,gcc就给出预设的可执行文件a.out。

(3) -g: 产生符号调试工具(GNU的gdb)所必要的符号信息,要想对源代码进行调试,我们就必须加入这个选项。

(4) -O: 对程序进行优化编译、连接,采用这个选项,整个源代码会在编译、连接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、连接的速度就相应地要慢一些。

(5) -O2 : 比-O更好的优化编译、连接,当然整个编译、连接过程会更慢。

(6) -Idirname:将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。

C程序中的头文件包含两种情况∶

a.#include

b.#include "myinc.h"

其中a类时使用的是<>来包含头文件,b类则使用“”来包含头文件。他们之间的主要差别是:对于a类,预处理程序源文件在系统预设包含文件目录(如/usr/include等等)中搜寻相应的文件,而对于b类,源文件则在当前目录中搜寻头文件,这个选项的作用是告诉源文件,如果在当前目录中没有找到需要的头文件,就到指定的dirname目录中去寻找。在程序设计中,如果我们需要的这种包含文件分别分布在不同的目录中,就需要逐个使用-I选项给出搜索路径。

(7) -Ldirname:将dirname所指出的目录加入到程序函数链接库文件的目录列表中,它是在连接过程中使用的参数。在预设状态下,连接程序ld在系统的预设路径中(如/usr/lib)寻找所需要的链接库文件。而这个选项告诉连接程序,首先到-L指定的目录中去寻找,然后再到系统预设路径中寻找,如果函数库存放在多个目录下,就需要依次使用这个选项,给出相应的存放目录。

(8) -lname:程序在连接时,装载名字为“libname.a”的函数库,该函数库位于系统预设的目录或者由-L选项确定的目录下。例如,-lm表示连接名为“libm.a”的数学函数库,

"-lpthread"则表示链接线程函数链接库文件。

(9) -shared:这主要是在生成共享库文件时使用。

(10) -Wall : 生成所有警告信息。

(11) -w : 不生成任何警告信息。

(12) -S : 生成汇编语言文件。

三.最后,我还想向大家阐明下平时大家都没怎么注意的一个问题-------gcc是怎么查找源文件中的头文件和链接时所需的链接库文件

(1) 查找头文件

step1:在源文件所在的目录下进行查找

step2:在我们在编译程序用选项“-Idirname”所指的路径去寻找头文件。

step3:查找gcc相关的环境变量所设置的路径:C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH

step4:查找gcc内定的目录:

/usr/include

/usr/local/include

/usr/lib/gcc-lib/i386-linux/2.95.2/include

(2) 查找动态链接库

什么时链接库?我再罗嗦一句吧。就像我们C语言中常用的printf函数为例,你们知道printf函数是怎么实现的吗?其实它是系统把这些函数实现都被做到名为libc.so.6的库文件中去了,在没有特别指定时,gcc会到系统默认的搜索路径”/usr/lib”下进行查找,也就是链接到libc.so.6库函数中去,这样就能实现函数”printf”了,而这也就是链接的作用。其中函数库又分为静态函数库和动态函数库两种。静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为”.a”。动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为”.so”,如前面所述的libc.so.6就是动态库。

好了,言归正传,其实动态链接库的查找过程其实和查找头文件类似。

step1: 在选项“-Ldirname”所指定的目录中查找。

step2: gcc的环境变量LIBRARY_PATH指定的路径中查找。

step3: 在gcc内定的目录中查找,如 /usr/lib/ /usr/local/lib/

原文链接: https://www.cnblogs.com/woshijpf/p/3840672.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/137642

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月11日 上午5:59
下一篇 2023年2月11日 上午6:06

相关推荐