在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 <myinc.h>

    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/

Linux中gcc编译器的用法的更多相关文章

  1. Linux中yum和apt-get用法及区别

    Linux中yum和apt-get用法及区别   一般来说著名的linux系统基本上分两大类:   1.RedHat系列:Redhat.Centos.Fedora等   2.Debian系列:Debi ...

  2. 一.复习GCC编译器的用法

    1.复习GCC编译器的用法 欲善其工,那么要先利其器.在这个C语言巩固与提高的阶段中,如果想要更好的达成预期目标,首先就要熟练掌握GCC编译器的用法.以下是GCC相关知识: GCC使用语法 gcc 选 ...

  3. Linux中find命令的用法汇总

    Linux中find命令的用法汇总 https://www.jb51.net/article/108198.htm

  4. linux中memset的正确用法

    linux中memset的正确用法 [起因]希望对各种类型的数组进行初始化,避免野值 [函数头文件] 提示:在linux中可以在terminal中输入 "man memset"进行 ...

  5. Linux安装gcc编译器详解

    本人使用的是CentOS 6.5 64位系统,由于在安装系统的时候并没有勾选安装gcc编译器,因此需要自行安装gcc编译器. 使用yum安装gcc 对于配备了yum的Linux发行版而言,安装gcc编 ...

  6. Linux下gcc与g++用法以及编写makefile

    1.         gcc与g++编译流程: 1)         编译流程: 2)         预处理:生成.i的预处理文件. Ø 只激活预处理,这个不生成文件,需要把它重定向一个输出文件. ...

  7. linux中[gcc -shared -fPIC]的含义

    linux在gcc编译时加上 -shared 参数时,目的是使源码编译成动态库 .so 文件: 而-fPIC的作用是 告知编译器 生成位置无关代码(编译产生的代码没有绝对位置,只有相对位置):从而可以 ...

  8. linux中grep命令的用法

    作为linux中最为常用的三大文本(awk,sed,grep)处理工具之一,掌握好其用法是很有必要的. 首先谈一下grep命令的常用格式为:[grep  [选项]  "模式"  [ ...

  9. linux中find命令高级用法

    前言 在<Linux中的文件查找技巧>一文中,我们已经知道了文件查找的基本方法,今天我们介绍find命令的一些高级使用技巧.它能满足我们一些更加复杂的需求. 查找空文件或空目录 有时候需要 ...

随机推荐

  1. Serverless无服务应用架构纵横谈

    Serverless无服务应用架构纵横谈 一.Serverless是啥 自从互联网兴起以来,Server就成了网络的核心部件.所以围绕Server的生意圈,也发展得如火如荼. 从最早的电信托管,到虚拟 ...

  2. SpringCache与redis集成,优雅的缓存解决方案

    缓存可以说是加速服务响应速度的一种非常有效并且简单的方式.在缓存领域,有很多知名的框架,如EhCache .Guava.HazelCast等.Redis作为key-value型数据库,由于他的这一特性 ...

  3. 再说Postgres中的高速缓存(cache)

    表的模式信息存放在系统表中,因此要访问表,就需要首先在系统表中取得表的模式信息.对于一个PostgreSQL系统来说,对于系统表和普通表模式的访问是非常频繁的.为了提高这些访问的效率,PostgreS ...

  4. 运行期以索引获取tuple元素-C++17

    //运行期以索引获取tuple元素-C++17 //需支持C++17及以上标准的编译器,VS2017 15.5.x.CodeBlocks 16.01 gcc 7.2 //参见:http://purec ...

  5. 使用邮件激活授权/ LightningChart license

    在无网络连接的情况下,可以采用邮件的方式激活授权. 先打开License Manager,然后选 Activate/Deactivate via email, 如下图所示: 此邮件将自动发送到 lic ...

  6. Zookeeper 集群安装

    负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据[均匀]分摊到多个操作单元上执行,负载均衡的关键在于[均匀].常见互联网分布式架构如上,分为客户端 ...

  7. 解决 PclZip 中文乱码问题

        在使用 Pclzip 时出现无法压缩/解压文件的现象,追踪错误信息发现无法打开文件/文件夹.可是文件夹权限正确,打印文件路径之后发现是乱码. 出现这个问题的解决办法是windows下zip内的 ...

  8. HLJU 1223: 寻找区间和 (交替推进法)

    1223: 寻找区间和 Time Limit: 3 Sec  Memory Limit: 128 MB Submit: 13  Solved: 4 [Submit][Status][pid=1223& ...

  9. Python绘制3d螺旋曲线图实例代码

    Axes3D.plot(xs, ys, *args, **kwargs) 绘制2D或3D数据 参数 描述 xs, ys X轴,Y轴坐标定点 zs Z值,每一个点的值都是1 zdir 绘制2D集合时使用 ...

  10. Java项目中使用Redis缓存案例

    缓存的目的是为了提高系统的性能,缓存中的数据主要有两种: 1.热点数据.我们将经常访问到的数据放在缓存中,降低数据库I/O,同时因为缓存的数据的高速查询,加快整个系统的响应速度,也在一定程度上提高并发 ...