Linux下详解gcc编译过程(含代码示例)&& gcc使用教程

Posted 狱典司

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux下详解gcc编译过程(含代码示例)&& gcc使用教程相关的知识,希望对你有一定的参考价值。

准备: test.c

在正式开始之前,若是想要通过一个代码(.c文件)来熟悉gcc的编译流程,可以在你的测试目录下使用如下代码:

// 文件名:test.c
     1  #include <stdio.h>
     2  #include <stdlib.h>
     3
     4  int main(int argc, char *argv[])
     5   {
     6    int arg;
     7    for(arg = 0; arg < argc; arg++){
     8      if(argv[arg][0] ==-)
     9            printf("option:%s\\n",argv[arg]+1); 
    10      else
    11            printf("argument %d:%s\\n",arg,argv[arg]);
    12      }
    13    exit(0);
    14    }

1. 编译过程

在使用gcc编译程序时,编译过程可以简要划分为4个阶段:

  1. 预处理
  2. 汇编
  3. 编译
  4. 链接

1.1 预处理(Pre-Processing)

这个阶段主要处理源文件中的#indef、#include和#define预处理命令;
这里主要是把一些include的头文件和一些宏定义,放到源文件中。

  • 输入的是C语言的源文件
  • 输出 :生成一个中间/预加载文件 *.i(以 .i 结尾的文件)
  • 这个阶段对应的gcc命令如下:
    #gcc –E(预处理) test.c(源文件) -o test.i(将结果生成的文件)
  • 说明:它通过对源文件test.c使用E选项来生成中间文件test.i

1.2 汇编(Assembling)

  • 输入:中间文件*.i

  • 输出:编译后生成汇编编语言文件*.s

  • 这个阶段对应的gcc命令如下:
    #gcc -S(汇编) test.i -o test.s(汇编编语言文件)

  • 说明:它通过对源文件test.c使用S选项来生成汇编文件test.s

1.3 编译(Compiling)

  • 输入文件:汇编文件*.s
  • 输出文件:二进制机器代码*.o
  • 这个阶段对应的gcc命令如下:
    #gcc -c(编译) test.s -o test.o

* gcc -c

在功能上,预处理、编译、汇编是3个不同的阶段
但gcc在实际操作时可以把这3个步骤合并为一个步骤来执行,即使用 -c选项:

  • 输入文件:源码*.c文件
  • 输出文件:二进制机器代码*.o
  • 这个阶段对应的gcc命令如下:
    # gcc –c test.c -o test.o
    // -o指定了output_filename
    或 :
    #gcc -c test.c
    //省略-o output_filename
    //默认输出为test.o
    //与源文件同名,后缀为.o

1.4 链接(Linking)

  • 输入文件:二进制机器码*.o文件
  • 输出文件:与其它的机器代码和库文件汇集成一个可执行的二进制代码文件(无后缀)
  • 这个阶段对应的gcc命令如下:
    #gcc (没有选项符号) test.o example.o -o test

可用选项:
-L 指定库路径
-l (小写的L)指定库名称
-I (大写的i)指定头文件所在路径
-i 指定头文件名称

选项详解:

选项用法解释
-l(大写的i)-Idirname(没有间隔)将名为dirname的目录加入到程序头文件目录列表中,它是在预处理阶段使用的选项,I是指Include
-L-Ldirname将名为dirname的目录加入到程序的库文件搜索目录列表中,它是在链接过程中使用的参数, L是指Link
-l (小写的L)-lname指示编译器,在链接时,装载名为libname.a的函数库,该函数库位于系统预定义的目录或者由-L选项指定的目录下

· 例:-lm 表示链接名为libm.a的数学函数库

2. 简化过程 —— gcc

  • 上述过程可以简化为:
    #gcc test.c (源文件) -o test(可执行文件)
    注意:与链接的语句差别主要在指令中输入文件的后缀

注:
1.库是头文件的实现!
2.在编译过程中可以被装载/拷贝的库为静态库(.a后缀)
· 更多关于静态库/动态库的知识请参考这篇博客:详解Linux下静态库/动态库(含代码示例)

3. gcc常用选项总结

常用选项

选项功能
-c只编译,不链接成可执行文件,编译器只是由输入的.c等为后缀的源代码文件生成.o为后缀的标文件,通常用于编译不包含主程序的子程序文件
-ooutput_filename 确定输出文件的名称为output_filename,同时这个名称不能和源文件名。如果不给出这个选项,gcc就默认将输出的可执行文件命名为a.out
-g产生调试器gdb所必须的符号信息,要对源代码进行调试,就必须在编译程序时加入这个选项
-O对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率较高,但是,编译、链接的速度就相应地要慢一些。
-O2比-O更好的优化编译、链接
-Wall输出所有警告信息
-w关闭所有警告信息
-Idirname(没有间隔,大写 i )将名为dirname的目录加入到程序头文件目录列表中,它是在预处理阶段使用的选项,I是指Include
-Ldirname将名为dirname的目录加入到程序的库文件搜索目录列表中,它是在链接过程中使用的参数。
· L是指Link
-lname(小写的L)指示编译器,在链接时,装载名为libname.a的函数库,该函数库位于系统预定义的目录或者由-L选项指定的目录下
  • gcc使用例子:
    (1) gcc -Wall src.c –o dest -lpthread
    /*输出所有警告信息地编译src.c生成dest可执行文件
    /*并在链接时装入libpthread.a的函数库
    —————————————————————————
    (2)gcc -Wall -o sniffex sniffex.c -lpcap
    /*输出所有警告信息地编译sniffex.c生成sniffex可执行文件
    /*并在链接时装入libpcap.a的函数库

以上是关于Linux下详解gcc编译过程(含代码示例)&& gcc使用教程的主要内容,如果未能解决你的问题,请参考以下文章

GCC 编译详解

GCC编译器的使用

GCC使用入门

linux安装gcc的shell脚本

Linux下Gcc 的编译过程

Linux下gcc生成和使用静态库和动态库详解