GCC 编译器

一、GCC编译器

  1. 概念

    GCC 原名为 GNU C 语言编译器(GNU C Compiler),只能处理 C 语言。但其很快扩展,变得可处理 C++,后来又扩展为能够支持更多编程语言,如 Fortran、Pascal、Objective -C、Java、Ada、Go 以及各类处理器架构上的汇编语言等,所以改名 GNU 编译器套件(GNU Compiler Collection)

  2. 特点

    GCC(特别是其中的 C 语言编译器)也常被认为是跨平台编译器的事实标准。
    GCC 提供了 30 多条警告信息和 3 个警告级别,使用它们有助于增强程序的稳定性和可移植性。
    GCC 还对标准的 C/C++ 语言进行了大量的扩展,提高了程序的执行效率,有助于编译器进行代码优化,能够减轻编程的工作量
    
  3. 编译过程

1.预处理(Pre-Processing)(gcc -E main.c -o gcc.i)   //将源码生成.i文件
2.编译(Compiling)(gcc -S main.i -o main.s)检查语法错误 // 将 .i文件编译生成汇编源码
3.汇编(Assembling)(gcc -c main.s -o main.o)处理汇编为二进制文件 // 将汇编源码汇编成目标二进制文件
4.链接(Linking)(gcc main.o -o test)链接库变为可执行文件 // 通过连接将目标文件变为可执行文件
  1. GCC常用选项
-c,只编译,不连接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。

-o output_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。

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

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

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

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

-L  dirname,将dirname所指出的目录加入到程序函数档案库文件的目录列表中,是在链接过程中使用的参数。
  1. 条件编译

一般情况下,C语言源程序中的每一行代码都要参加编译。但有时候出于对程序代码优化的考虑,希望只对其中一部分内容进行编译,此时就需要在程序中加上条件,让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译(conditional compile)

1. 根据宏定义
#ifdef  
  ……
#else
 ……
#endif

实例
#define  _DEBUG_

#ifdef  _DEBUG_

printf(“The macro _DEBUG_ is defined\n”);

#else

printf(“The macro _DEBUG_ is not defined\n”);

#endif

2.根据宏的值
  #if  

   ……

  #else

   ……

  #endif
实例
#define  _DEBUG_   1

#if  _DEBUG_

printf(“The macro _DEBUG_ is defined\n”);

#else

printf(“The macro _DEBUG_ is not defined\n”);

#endif

3.编译时条件编译
#ifdef UMP_TO_FILE

  //do something here...

 #endif

gcc myprogram.c  -D  UMP_TO_FILE

-D加上宏UMP_TO_FILE,相当于你在代码中#define  UMP_TO_FILE

-D UMP_TO_FILE = 1,相当于你在代码中#define  UMP_TO_FILE 1

  1. 生成静态库

    gcc -o libstr.a string.o // lib+str是静态库名,通过目标文件生成静态库
    
  2. 使用静态库

    第一种:gcc -o test hello.c libstr.a
    第二种:gcc -o test hello.c -L ./ -lstr //-L指在指定目录中查找静态库,str库文件名
    
  3. 动态链接库

    概念:动态链接库是程序运行时加载的库,当动态链接库安装成功后,所有的程序都可以使用动态链接库;动态链接库是目标文件的集合。动态链接库的名称有 别名(soname,有个前缀lib,例如libstr.so)、真名(realname)、连接名(linker name)

  4. 生成动态链接库

    gcc -shared -Wl,soname,libstr.so -o libstr.so.1 string.c
    //-soname,libstr.so  表示生成的动态链接库的别名是libstr.so;
    //-o libstr.so.1 表示实际生成的动态链接库的名字
    
  5. 安装动态链接库

    一般情况下将生成的动态链接库复制到默认的动态链接库的搜索路径下,例如/lib,/usr/lib,/usr/local/lib

  6. 动态链接库管理命令

    为了让新增加的动态链接库能够被系统共享,需要运行ldconfig,作用是在默认搜索路径,动态链接库的配置文件中列出的目录中搜索动态链接库,当用户的动态链接库不在系统动态链接库配置文件/etc/ld.so.conf中时,通过ldconfig 用户目录,将用户指定目录中的动态链接库放入系统中共享

  7. 使用动态链接库

    gcc -o test hello.c -L ./ -lstr
    // -L 指定搜索动态链接库的路径,-lstr 指定链接库的名字
    //运行test发现报错,./test: error while loading shared libraries: libstr.so: cannot open shared object file: No such file or directory
    //这是因为程序运行时没有找到动态链接库,程序编译时的俩姐动态链接库和运行时连接动态链接库的概念是不一样的
    // 运行时,程序连接的动态链接库必须时在系统搞得目录下才行。
    
    
    //1. LD_LIBRARY_PATH是Linux环境变量名,该环境变量主要用于指定查找共享库(动态链接库)时除了默认路径之外的其他路径
    为什么修改LD_LIBRARY_PATH呢
    因为运行时动态库的搜索路径的先后顺序是:
    1.编译目标代码时指定的动态库搜索路径;
    2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
    3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
    4.默认的动态库搜索路径/lib和/usr/lib;
    
    //如果系统路径下同时存在静态链接库和动态链接库,默认有限连接动态链接库。如果强制连接静态链接库,增加-static
    gcc -o test hello.c -static -lstr
    

你可能感兴趣的:(C语言,c语言)