Linux 平台如何制作自己的 C /C++ 静态库

《Linux 平台基于 C /C++ 的静态库和动态库的区别》 一文中介绍了静态库的特点以及与动态库的区别。那么你有没有想过如何把自己写好的函数接口制作成静态库给别人用呢?本文教你如何制作属于自己的静态库。

1. 编译成可重定位文件

《Linux 平台基于 C /C++ 的静态库和动态库的区别》 简单介绍了可重定位文件。其中也有一位非常细心的读者发现,在 Ubuntu18.04 的系统,使用 gcc7.4 编译出来的可执行文件的 type 是 DYN,这是编译器生成了一种位置无关的可执行文件(PIE),它类似于动态库,其地址在加载时确定,从而更加安全。本文不再展开介绍。

本文实例代码 test1.c 代码如下:

#include"test1.h"
void test1()
{
    printf("I am test1
");
}

编译成可重定位文件,即生成。o 文件:

$ gcc -c test1.c
$ readelf -h test1.o
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
(省略部分内容)

2. 制作成静态库

为了制作成静态库,我们需要使用 ar 命令。

$ ar -rcs libtest1.a test1.o   #库名一般以。a 为扩展名,以 lib 开头 
$ ar -t libtest1.a  #查看内容
test1.o

通常来说,静态库以。a 作为后缀,且以 lib 开头。至此就将我们提供的 test1 函数做成了静态库,但是为了方便其他人使用,我们再提供一个头文件 test1.h,代码如下:

#include
void test1();

这个时候就可以将我们做好的静态库给其他人使用啦。

使用静态库

我们写一个 main.c 来调用 test1():

#include"test1.h"
int main(void)
{
    test1();
    return 0;
}

编译运行:

$ gcc -o main main.c -L ./  -ltest1
$ ./main
I am test1

其中 - L 用于指定链接库的路径,由于我们要链接的库名为 libtest1.a,在链接的时候,去掉开头的 lib 和后缀。a,前面再加 l,就变成了 -ltest1,其他库也是类似。例如,你如果看到程序链接使用 -lm,说明它使用了名为 libm.a 的库。

3. 静态库使用

如果这时候还有一个库 libtest0.a,库中调用了 test1.c 的函数,而 main 函数调用了 libtest0.a 中的函数呢?即,假设有 test0.c 中调用 test1(),且两者位于不同的库中,test0.c 代码如下:

#include"test0.h"
void test0()
{
    printf("I am test0,I will call test1
");
    test1();
    printf("test0 call test1 end
");
}

头文件 test0.h:

  • 分享于 · 2019.07.29 14:54 · 阅读 · 2003

[版权声明] :本文系网友分享,仅以非商业性的交流和科研为目的,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本网( friends@stuch.cn )联系!我们将协调给予处理。转载授权码:确权中,请原作者尽快与我们取得联系,阅读原文(请登录)..

0 条评论

请先 登录 后评论
猜猜我是谁
甜也 -研究生

8
提问
13
回答
6
文章