linux下静态库与动态库的生成和调用

1 静态库生成

静态库在链接阶段,会将目标文件与引用的库一起链接打包到可执行文件中,静态库可以看做是把许多目标文件经过压缩打包后形成的一个文件。静态库的特点是:

  • 使可执行文件中包含了库代码的一份完整拷贝,程序在运行时与函数库再无瓜葛,移植方便。
  • 静态库对函数库的链接是放在编译时期完成的,但较为浪费空间和资源,因为所有相关的目标文件与牵涉到的函数库被链接合成一个可执行文件。
1.1 编译生成.o文件

用-c生成.o文件(用.o文件来生成库文件——包含静态库和动态库)

$ g++ -c staticlib.cpp

运行后会在目录下生成staticlib.o

2.2 生成静态库
$ ar rcsv libstaticlib.a staticlib.o
  • 使用linux ar命令辅助打包生成.a的静态库,注意库名必须以lib开头。
2.3 测试
$ g++ –o test test.cpp -I ../ –L ../  –lstaticlib -ldl
  • -o后接可执行文件test。
  • -I 指定头文件地址,-L指定库文件地址,当有多个不同地址时输入多个 -I 或 -L。
  • -l后接引用的库文件,注意-l表示lib所以后面接的库名需省去lib,另外库名不需要加后缀。
  • 如果程序依赖系统的动态库dlopen(),dlclose() , dlerror() , dlsym(),需要加上-ldl

2 动态库生成

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时才被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。动态库在程序运行是才被载入,也解决了静态库对程序的更新、部署和发布页会带来麻烦。用户只需要更新动态库即可完成增量更新。

2.1 编译生成.o文件
$ g++ -fPIC -Wall -c dynamiclib.cpp
  • -fPIC 表示是编译选项,PIC是 Position Independent Code 的缩写,表示要生成位置无关的代码,这是动态库需要的特性
  • -Wall 选项的意思是编译后显示所有警告
2.2 生成动态库
$ g++ -shared -o libdynmaiclib.so  dynamiclib.o
  • -shared是链接选项,告诉gcc生成.so的动态库而不是可执行文件

也可以合并2.1,2.2,直接使用

$ g++ -fPIC -shared -o libdynmaiclib.so  dynamiclib.cpp
2.3 测试
$ g++ –o test test.cpp -I ../ –L ../  –Wl,-rpath=.
  • -Wl,-rpath指令把链接需要的动态库地址写入到执行文件中,如果使用export LD_LIBRARY_PATH=.也可以把库文件链接过去,但是只是临时的,重启后链接关系消失。
2.4 动态库依赖静态库

如果一个动态库依赖静态库,则需要静态库在编译的时候加上-fPIC指令,否则会出现错误

relocation R_X86_64_32 against `.rodata’ can not be used when making a shared object;

3 使用makefile自动化编译链接过程

通常当项目较大文件较多时,编译链接会是一个非常繁琐复杂的过程。cmake是一款跨平台的工具,可以辅助完成这些工作。在linux中可以通过编写简单的makefile文件,达到自动化编译的功能。一下是一段简单的makefile文件代码。

// makefile
main: test.o
	g++ -o main test.o

test.o: test.cpp
	g++ -c test.o test.cpp

cmake的基本格式规则是:

目标项:依赖的项
tab键的空位执行命令行

注意,当依赖的项存在时会执行tab后的命令行,否则暂时跳过,运行后面的代码,等依赖的项存在后再执行。运行make即可运行makefile的代码,如上述示例,如果test.o文件已经存在,下面test.o的代码不会执行。

.PHONY:[项] 关键字可以使makefile文件分块,使后面的项可以独立实现功能。举例如下:

.PHONY: build clean

build: libopt.so

libopt.so: arterialCoordination.cpp interpreter.cpp optimization.cpp 
	g++ -fPIC -shared $^ -o $@ -L ../lpsolve64 -llpsolve55

clean:
	rm -f libopt.so

运行make build即可构建,make clean可以清除多余的文件。这里符号$^表示所有的依赖项,$@表示目标项。

参考资料
[1] C++静态库与动态库
[2] linux下编写C/C++代码须知———串讲
[3] Linux动态库生成以及调用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值