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
  • 阅读 ( 321 )

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

0 条评论

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

8
提问
9
回答
5
文章