# Linux下静态链接库 Linux 平台上将 C 语言库文件转换为静态链接库,常用的转换工具是 GCC 编译器,几乎所有的 Linux 发行版(Red Hat、Ubuntu、CentOS 等)都默认装有 GCC,本节使用的系统为 Ubuntu。 如果您不确定当前 Linux 发行版是否装有 GCC,打开 Terminal 命令行工具并输入`gcc --version`指令: ``` test@ubuntu:~$ gcc --version gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ``` 这是笔者在 Ubuntu 系统上的执行结果,当前系统安装的 GCC 编译器的版本为 9.3.0。反之,如果输出信息为: ``` bash: /usr/bin/gcc: No such file or directory ``` 表明当前系统没有安装 GCC,您可以阅读《[GCC编译器下载和安装教程](http://c.biancheng.net/view/7933.html)》一文下载并安装 GCC 编译器。 ## 静态链接库的创建 Linux 平台上,GCC 编译器将 myMath.c 转换为静态链接库需要经历以下两步: \1) 编译所有的 .c 库文件,生成对应的目标文件。本节我们以 myMath.c 库文件为例,因此只编译这 1 个文件即可。 首先,准备好要编译的 myMath.c 库文件和 myMath.h 头文件(具体内容可从《[Windows下静态链接库的创建和使用](http://c.biancheng.net/dll/vip_8704.html)》一节中获得): ``` test@ubuntu:~/myMath$ ls myMath.c myMath.h ``` 执行如下指令: ``` test@ubuntu:~/myMath$ gcc -c myMath.c -o myMath.o <-- 编译 myMath.c 文件 test@ubuntu:~/myMath$ ls <-- 查看生成的 myMath.o 文件 myMath.c myMath.h myMath.o ``` `-c myMath.c`表示对 myMath.c 进行编译,`-o myMath.o`表示将编译后生成的目标文件的文件名置为 myMath.o。再次执行 ls 命令,可以看到新生成的 myMath.o 目标文件。 \2) 将所有的目标文件打包成一个静态链接库。例如,下面的指令将 myMath.o 打包成了一个静态链接库: ``` test@ubuntu:~/myMath$ ar rcs libmyMath.a myMath.o <-- 将 myMath.o 打包为 libmyMath.a test@ubuntu:~/myMath$ ls libmyMath.a myMath.c myMath.h myMath.o ``` ar 命令常用于创建静态链接库,其中 r、c、s 是 ar 命令创建静态链接库所需要设定的参数,libmyMath.a 是新静态链接库的名称。 > 需要注意的是,Linux 平台上静态链接库的名称不是随意的,通常遵循 libxxx.a 格式,xxx 部分可以自定义。 经过以上两步,我们就成功地创建了一个静态链接库文件。 ## 静态链接库的使用 静态链接库的用法很简单,就是和其它目标文件一起参与链接,最终生成一个可执行文件。 以 libmyMath.o 为例,同目录下再创建一个 main.c 文件,其内容如下: ``` #include #include "myMath.h" int main() { int a = 3, b = 5; printf("a+b=%d\n", add(3, 5)); printf("a-b=%d\n", sub(3, 5)); printf("a*b=%d\n", mul(3, 5)); printf("a/b=%d", div(3, 5)); return 0; } ``` 首先,我们对 main.c 执行编译操作得到对应的目标文件,执行如下指令: ``` test@ubuntu:~/myMath$ ls libmyMath.a main.c myMath.c myMath.h myMath.o test@ubuntu:~/myMath$ gcc -c main.c -o main.o test@ubuntu:~/myMath$ ls libmyMath.a main.c main.o myMath.c myMath.h myMath.o ``` 由此,我们得到了 main.o 和 libmyMath.a 这两个文件,接下来就可以开始将它们链接成一个可执行文件,实现链接的指令有两种: ``` test@ubuntu:~/myMath$ gcc -static main.o libmyMath.a -o main <-- 第 1 种 test@ubuntu:~/myMath$ gcc main.o -o main -static -lmyMath -L /home/test/myMath <-- 第 2 种 ``` 第一种实现方式中,-static 的作用是强制 GCC 编译器使用静态链接库,最终生成的可执行文件的名称为 main。第二种实现方式中,-l 后紧跟静态链接库的名称 myMath(它是 libxxx.a 中的 xxx 部分),-L /home/test/myMath 用于指定 libmyMath.a 的存储位置。 以上两种方式都可以将 main.o 和 libmyMath.a 链接成一个可执行文件,该文件的名称为 main。执行该文件,可以看到程序的执行结果: test@ubuntu:~/myMath$ ./main a+b=8 a-b=-2 a*b=15 a/b=0