Linux 动态库、静态库的生成、使用和优缺点分析
一、介绍
在软件编程中,通常会把功能或接口函数封装成库的形式,供给其它模块或第三方使用。在linux系统中存在动态库和静态库两种形式。
静态库:以libxxx.a形式命名,编译程序时,会将静态库数据编译进可执行程序中。
动态库:以libxxx.so形式命名,编译程序时,不会被编译进可执行程序中,而在程序运行时,动态的加载该动态库
二、生成(以libmath_method.a/so为例)
2.1 静态库的生成
gcc -c math_method.c
ar cr libmath_method.a math_method.o
ranlib libmath_method.a
查看库中包含的文件:
ar -t libmath_method.a
math_method.o
2.2 动态库的生成
gcc -fPIC -c math_method.c
gcc -shared -o libmath_method.so math_method.o
三、编译链接
-L 指定搜寻库的目录
如指定当前目录 gcc -L .
-l 指定要链接的库的名称
加入库的名称是libmath_method.a(.so),则gcc -lmath_method
链接时,如果动态库和静态库同时存在,优先使用动态库。也可以通过以下的参数指定动态或静态库
-Wl,-dn :指定动态库
-Wl,-dy:指定动态库
四、查看程序链接的动态库库
$ ldd a.out
linux-vdso.so.1 => (0x00007ffff47cb000)
libmath_method.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd659906000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd659cdb000)
五、程序运行
4.1 静态库程序的运行
./a.out
4.2 动态库版本程序的运行
./a.out: error while loading shared libraries: libmath_method.so: cannot open shared object file: No such file or directory
出现上述错误是因为找不到动态库,有以下两种方式可以解决:
一、可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig
二、把当前路径加入环境变量LD_LIBRARY_PATH中,仅在当前环境有效
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
六、静态库和动态库优缺点
1. 静态库程序会将函数库编译时程序,因此程序较大, 而动态库程序较小
2. 由于静态库在编译时已经将函数库编译进程序中,因此运行时不需要库的支持;而动态库程序在运行时必须提供相应的库程序
3. 库文件变化时,静态库程序需要重新编译; 而动态库只需要替换运行环境中的库文件
4. 多个程序使用库文件时,静态库需要每个程序都编译时各自的程序中,而动态库只需要在运行环境共享一份即可
七、源码
Makefile:
CC=gcc
LIBRARY=-L. -Wl,-dy -lmath_method -Wl,-dy -lgcc_s
TARGET=a.out
$(TARGET): libmath_method.a libmath_method.so
gcc -o [email protected] main.c $(LIBRARY)
math_method.o: math_method.c
$(CC) -fPIC -c math_method.c
libmath_method.a: math_method.o
ar cr [email protected] $^
ranlib [email protected]
libmath_method.so: math_method.o
$(CC) -shared -o [email protected] $^
.PHONY:
clean:
-rm -rf *.o *.a
-rm $(TARGET)
main.c:
#include <stdio.h>
#include "math_method.h"
int main(int arc, char *argv[])
{
printf("hello world\n");
printf("%d + %d = %d\n", 1, 9, math_add(1, 9));
return 0;
}
math_method.c:
#include <stdio.h>
int math_add(int a, int b)
{
return a + b;
}
int math_sub(int a, int b)
{
return a - b;
}
math_method.h:
#ifndef __MATH_METHOD_H__
#define __MATH_METHOD_H__
int math_add(int a, int b);
int math_sub(int a, int b);
#endif
上一篇: pkg-config介绍与使用
下一篇: linux加载动态库的两种方式