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!\n");
    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 '\0'
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\n", 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

 

posted @ 2019-12-12 16:22  LandyTan  阅读(1517)  评论(0编辑  收藏  举报