linux中静态库和动态库的生成以及使用

1. 目的

最近工作中需要用到静态库和动态库,以前这些都学习过的,但很久没用,就忘记了,这次学习决定要记下来。

2. 说明

本文要生成的静态库名称是libopt.a,动态库名称是libopt.so。首先先介绍下本文中的创建库的文件路径:

$ /testlib/tree 
.
├── include       ==>这个是库的头文件,到时候安装库的时候需要拷贝到用户指定的头文件路径中,方便引用。本文是/usr/local/include/opt/
│   ├── add.h
│   └── mul.h
├── Makefile     ==》makefile,这个makefile用于创建动态库的。
├── Makefile_lib_a  ==》 这个makefile用于创建静态库,这里我是分别测试学习的,所以被重命名了。
├── objs            ==》这个目录用于存放编译生成的.o文件和临时存放库文件.
└── src	      ==》生成库文件的源码 
    ├── add.c  
    └── mul.c

 源码和头文件中内容都很简单,add.c提供两个整数相加的函数,add.h提供函数申明,供外部使用。mul.c和mul.h类似,代码就不贴了。

3. 静态库生成与使用

3.1 Makefile文件

CC= gcc
AR= ar
CFLAG=-Wall -Wpointer-arith -Wno-unused-parameter -Werror -g

INC_DIR=include/
SRC_DIR=src/
OBJS_DIR=objs/
TARGET_LIB=$(OBJS_DIR)libopt.a   ==》静态库名称
MY_LIB_DIR=/usr/local/lib/
MY_INC_DIR=/usr/local/include/
OUTPUT_FILES= $(OBJS_DIR)add.o $(OBJS_DIR)mul.o

$(TARGET_LIB):$(OUTPUT_FILES)

	$(AR) -r $(TARGET_LIB) $(OUTPUT_FILES)      ==》最关键的命令,生成静态库

$(OBJS_DIR)add.o:	$(INC_DIR)add.h $(SRC_DIR)add.c
	$(CC) -c $(CFLAGS)  -o $(OBJS_DIR)add.o $(SRC_DIR)add.c

$(OBJS_DIR)mul.o:	$(INC_DIR)mul.h $(SRC_DIR)mul.c
	$(CC) -c $(CFLAGS)  -o $(OBJS_DIR)mul.o $(SRC_DIR)mul.c

install:
	test -f $(TARGET_LIB) || make              
	cp -rf $(INC_DIR) $(MY_INC_DIR)opt/            ==》 将库和头文件拷贝到指定的目录
	cp $(TARGET_LIB) $(MY_LIB_DIR)
clean:
	rm -f objs/*

3.2 使用方法

编译一个简单的程序main.c,里面包含库里面的头文件(make install时已经拷贝到/usr/local/include/目录了),该程序内部调用静态库中提供的接口,编译时,应该带上库的选项,如下:
gcc  -o main main.c -lopt    ==>我们生产的库名称是libopt.a,那么此处我们应该用-lopt,-l 其实是一个gcc的选项,用于指定静态库。接着运行main可以成功得到预期的结果。

4. 动态库生成与使用

4.1 Makefile文件

CC= gcc
CFLAG=-fPIC -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g  # -fPIC for share lib
==》这里编译选项中增加了 -fPIC,也是生成动态库的必须项。

INC_DIR=include/
SRC_DIR=src/
OBJS_DIR=objs/
TARGET_LIB=$(OBJS_DIR)libopt.so
MY_LIB_DIR=/usr/local/lib/
MY_INC_DIR=/usr/local/include/
OUTPUT_FILES= $(OBJS_DIR)add.o $(OBJS_DIR)mul.o


$(TARGET_LIB):$(OUTPUT_FILES)


$(CC) -shared -o  $(TARGET_LIB) $(OUTPUT_FILES)   ==》 与生成静态库不一样,生成动态库使用该语句。


$(OBJS_DIR)add.o:$(INC_DIR)add.h $(SRC_DIR)add.c
	$(CC) -c $(CFLAG)  -o $(OBJS_DIR)add.o $(SRC_DIR)add.c


$(OBJS_DIR)mul.o:$(INC_DIR)mul.h $(SRC_DIR)mul.c
        $(CC) -c $(CFLAG)  -o $(OBJS_DIR)mul.o $(SRC_DIR)mul.c


install:
        test -f $(TARGET_LIB) || make
        cp -rf $(INC_DIR) $(MY_INC_DIR)opt/
        cp $(TARGET_LIB) $(MY_LIB_DIR)
clean:
        rm -f objs/*

4.2 使用方法

同样,还是用刚刚的测试程序main.c,重新编译该文件,只不过这次使用动态库,而不使用静态库,编译方法如下:
gcc  -o main main.c  /usr/local/lib/libopt.so    ==>我们生成的库名称是libopt.so,且make install时拷贝到/usr/local/lib/目录了,注意这里使用动态库一定要加路径,否则会出现找不到库的提示,除非环境变量中有这个路径,比如,我这里将/usr/local/lib/这个路径加到环境变量中去就可以省略。

5. 总结

使用静态库时实际上是直接将其代码嵌入到目标程序中,编译完成后静态库删除不会给目标程序造成影响。而动态库则不一样,是在程序运行的时候才加载的,因此需即使编译完成后也要保证动态库的完整性。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值