• GCC编译器


    简介

    GCC是LINUX环境下的编译工具集,是GNU Compiler Collection的缩写,其中包含gcc、g++等编译器及ar、nm等工具集。
    GCC工具集不仅能编译C/C++语言,其他如Objective-C、Pascal、Fortran、Java、Ada等语言均能编译。

     

    编译程序的基本知识

    源文件、目标文件和可执行文件是编译过程中经常用到的名词
    • 源文件指的是存放可编辑代码的文件,如存放C/C++代码的文件;
    • 目标文件指的是经过编译器的编译生成的CPU可识别的二进制代码;目标文件不能执行,因为其中的一些函数过程没有相关的指示和说明;
    • 可执行文件是目标文件与相关的库链接后的文件,它是可执行的。
     
    GCC编译器对程序的编译分为4个阶段:预编译、编译和优化、汇编、链接
      • 预编译过程将程序中引用的头文件包含进源代码中,并对一些宏进行替换;
      • 编译过程将用户可识别的语言翻译成一组处理器可识别的操作码,生成目标文件。通常翻译成汇编语言,而汇编语言通常和机器操作码之间是一种一对一的关系。
      • 链接的作用是将所有的目标文件用某种方式组合起来才能运行。目标文件中通常仅解析了文件内部的变量和函数,对于引用的函数和变量还没有解析,这需要将其他已经编写好的目标文件引用进来,将没有解析的变量和函数进行解析,通常引用的目标是库,链接完成后生成可执行文件。
     

    使用GCC编译器编译hello.c源文件

    文件hello.c内容如下
    /*hello.c*/
    #include <stdio.h>
    int main(void)
    {
        printf("Hello World!
    ");
        return 0;
    }
    

    GCC命令格式如下:

    gcc [options] file...
    

    编译可执行文件

    运行如下命令可将hello.c源文件直接编译成可执行文件。运行如下命令时,gcc编译器实际上执行了4个步骤:选择编译器、将源文件编译成目标文件、将目标文件链接成可执行文件、删除目标文件。
    gcc hello.c
    

    以上命令编译的最终可执行文件名称为a.out,如果希望生成指定的文件名,-o选项使编译器生成指定文件名。如下命令将生成的可执行文件的名称为hello

    gcc -o hello hello.c
    

    编译目标文件

    GCC的-c选项用于生成目标文件。默认情况下生成的目标文件的文件名与源文件的名称一样,只是扩展名为.o,例如下面的命令将生成一个名字为hello.o的目标文件
    gcc -c hello.c
    

    如果希望生成指定的文件名,可以使用-o选项,例如下面的命令将生成一个名字为test.o的目标文件

    gcc -c -o test.o hello.c
    

    使用GCC编译器编译string.h、string.cmain.c源文件

    文件string.h内容如下
    /*string.h*/
    #ifdef STRING_H
    #define STRING_H
    int StrLen(const char *str);
    #endif // !STRING
    

    文件string.c内容如下

    /*string.c*/
    #define ENDSTRING ''
    int StrLen(const char *str)
    {
        int len = 0;
        while(*str++ != ENDSTRING)len++;
        return len;
    }    
    

    文件main.c内容如下

    /*main.c*/
    #include <stdio.h>
    #include "string.h"
    int main(void)
    {
        const char *src = "Hello Dymatic";
        printf("String length is:%d
    ", StrLen(src));
        return 0;
    }
    

    下面的命令将两个源文件编译成一个名称为test的可执行文件

    gcc -o test main.c string.c
    

    下面的命令将两个源文件编译成目标文件main.o和string.o

    gcc -c main.c string.c
    

    下面的命令将两个目标文件main.o和string.o链接成可执行文件test

    gcc -o test main.o string.o
    

    静态链接

    生成静态库或者将一个目标文件加到已经存在的静态库的命令为"ar -r 库文件名 目标文件1 目标文件2 ..."。如下命令生成目标文件,给目标文件创建库
    gcc -c string.c                生成目标文件
    ar -r libstr.a string.o        生成静态库libstr.a
    gcc -o test main.c libstr.a    链接静态库libstr.a
    

    也可以使用如下命令链接静态库,“-L”选项指定搜索路径,“-l”选项指定搜索库文件名。

    gcc -c string.c
    ar -r libstr.a string.o
    gcc -o test main.c -L./ -lstr    // 链接当前目录下的str库
    

    动态连接库

    动态链接库是目标文件的集合,目标文件在动态链接库中的组织方式是安装特殊方式形成的。
    动态链接库的名称
    • 别名(soname)
    前缀"lib"加"库名字"加后缀".so"组成。如libstring.so
    • 真名(realname)
    真名是动态链接库的真实名称,一般总是在别名的基础上加版本号、发布版本等组成。
    • 链接名(linker name)。
    程序链接时使用的库名称。
     
    生成/使用动态链接库
    运行如下命令可生成真名为“libstr.so.1”的动态链接库。注意“,"不能有空格。
    gcc -shared -Wl,-soname,libstr.so -o libstr.so.1 string.c
    

    运行如下命令生成动态链接库的别名"libstr.so“,这个别名在上一条命令中指定,其中~/books/2.2是动态链接库所在目录,ldconfig是动态链接库管理命令。

    sudo ldconfig ~/books/2.2
    

    运行如下命令链接动态链接库。得到可执行文件test

    gcc -o test main.c -L./ -lstr
    

    如果系统的搜索路径下同时存在静态链接库和动态链接库,默认情况下链接动态链接库。可使用“-static”选项强制链接静态链接库。命令如下

    gcc -o test main.c -static -L./ -lstr
    
  • 相关阅读:
    VirtualBox的四种网络连接方式详解
    need to be root
    Unreachable catch block for IOException. This exception is never thrown from the try statement body
    git fetch 拉取而不合并
    IOS开发的哪些异常之异常断点
    duplicate报ORA-01017权限问题
    Woody的Python学习笔记4
    微软100题第51题:和为n连续正数序列
    C语言scanf函数详解
    火星人乘坐核动力飞船回故乡
  • 原文地址:https://www.cnblogs.com/LandyTan/p/12029922.html
Copyright © 2020-2023  润新知