Linux 创建静态库(.a)和动态库(.so)

0. 回顾一下 gcc 选项

==============================================

-E : 仅做预处理,例如去注释,宏展开,include 展开等

-S : 将源程序编译为汇编代码 *.s

-c :  预处理,汇编,生成目标文件 *.o

-o :  预处理,汇编,链接,生成可执行 ELF 文件

==============================================

-g :  编译时加入调试信息

-Wall : 编译时显示所有告警

-std=c99 : 编译时支持 c99 语法

-I directory : (i) 加入头文件搜索目录

-lxxx : (L) 链接静态库或动态库

==============================================

1. 创建和使用静态库

- 库文件 arithmetic.c

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b; }

- 头文件 arithmetic.h

#ifndef ARITHMETIC_H_
#define ARITHMETIC_H_

extern int add(int, int);
extern int sub(int, int);
extern int mul(int, int);
extern int div(int, int);

#endif

- 主测试文件 use_arithmetic_lib.c

#include "arithmetic.h"
#include <stdio.h>

int main(void)
{
    int x, y;
    printf("Enter two integers: ");
    scanf("%d%d", &x, &y);

    printf("add is: %d
", add(x, y));
    printf("sub is: %d
", sub(x, y));
    printf("mul is: %d
", mul(x, y));
    printf("div is: %d
", div(x, y));

    return 0;
}

生成静态库步骤:

1)编译 arithmetic.c 为目标文件,生成 arithmetic.o

$ gcc -c arithmetic.c

2)将 arithmetic.o 转换为静态库文件(注意,库文件命名规则,libxxx.a)

$ ar rcs libarithmetic.a arithmetic.o

 

使用静态库:

方法1:$ gcc use_arithmetic_lib.c -static ./libarithmetic.a -o use_arithmetic_lib

方法2:$ gcc use_arithmetic_lib.c -L. -larithmetic -o use_arithmetic_lib               # -L 指定静态库文件路径

正规使用静态库到方式: $ gcc use_arithmetic_lib.c  -static  -L.  -larithmetic  -o  use_arithmetic_lib

 

对于静态库,编译完成后,可执行文件可以脱离静态库运行。但是设想一下,如果一个静态库被调用很多次,则在内存中有这个库很多重复的加载,这是引入动态库的原因之一。以下介绍动态库。

 

2. 创建和使用动态库

(使用和上述静态库同样的c代码)

 

生成动态库步骤:

1)编译 arithmetic.c 为目标文件,生成 arithmetic.o

$ gcc -c arithmetic.c

2)将目标文件转换成动态库文件 (注意动态库文件的命名规则 libxxx.so.major.minor)

$ gcc -fPIC -shared -o libarithmetic.so.0.1 arithmetic.o

以上两步可以合在一起,

$ gcc -fPIC -shared -o libarithmetic.so.0.1 arithmetic.c

使用动态库文件:

$ gcc use_arithmetic_lib.c  -L.  -larithmetic  -o  use_arithmetic_lib

要使编译后的可执行文件能找到动态库文件,则,

1) 将动态库文件拷贝到 /usr/local/lib(建议自己生成的动态库文件放在此目录。默认动态库文件搜索路径是 /usr/lib, /lib, /usr/local/lib)

$ sudo cp libarithmetic.so.0.1 /usr/local/lib

2)创建一个软链接

$ sudo ln -sf libarithmetic.so.0.1 libarithmetic.so

3) 更新 ld 缓存

$ sudo ldconfig

使用可执行文件时,不能脱离动态库环境(例如,可执行文件不能放到其它机器上跑), run 结果如下,

=====================================================================================

有时编译完成后,执行时报错: cannot open shared object file: No such file or directory 解决方法有以下两种:

种: 在 .bashrc 中添加 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib  (假定动态链接文件.so 安装在 /usr/local/lib 下)

种: $ sudo vim /etc/ld.so.conf  添加 /usr/local/lib 然后执行 $ sudo ldconfig

=====================================================================================

动态库文件的好处是,可以动态更新库文件,不用重复编译可执行文件。如下,

更改 arithmetic.c 为 arithmetic_modify.c 为,

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }
int div(int a, int b) { return a / b + 100; }

编译生成目标文件:

$ gcc -c arithmetic_modify.c

生成动态库文件:

$ gcc -fPIC -shared -o libarithmetic.so.0.2 arithmetic.o

拷贝动态库文件到 /usr/local/lib

$ sudo cp libarithmetic.so.0.2 /usr/local/lib

更新软连接

$ sudo ln -sf libarithmetic.so.0.2 libarithmetic.so

再执行一下 use_arithmetic_lib

最后,使用命令 ldd 可以查看可执行文件的动态库依赖关系,如下,

$ ldd use_arithmetic_lib

完。

原文地址:https://www.cnblogs.com/gaowengang/p/6164461.html