前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Linux】动静态库的制作与使用

【Linux】动静态库的制作与使用

作者头像
aosei
发布2024-01-23 15:36:37
1350
发布2024-01-23 15:36:37
举报
文章被收录于专栏:csdn-nagiYcsdn-nagiY

一.静态库的制作

静态库的名称格式为:libxxx.a   注意 xxx 才是静态库的真正名字。

代码语言:javascript
复制
lib=libprint.a   //静态库的名称

$(lib):print.o  //生成静态库 (依赖 .o 文件)
	ar -rc $@ $^   //使用 ar 命令 -rc 选项生成静态库

print.o:print.c   //g++ -c 选项生成 .o 文件
	g++ -c $^ 

.PHONY:clean
clean:
	rm -rf *.a *.o

output:
	mkdir -p Lib/include
	mkdir -p Lib/mylib
	cp *.h Lib/include
	cp *.a Lib/mylib

二.动态库的制作

动态库的名称格式为:libxxx.so   注意 xxx 才是动态库的真正名字。

注意动态库中生成 .o 文件时gcc 要带选项 -fPIC ,表示生成位置无关码。

代码语言:javascript
复制
dy-lib=liblog.so   //动态库名称


$(dy-lib):log.o   //生成动态库 (依赖 .o 文件)
	g++ -shared -o $@ $^   //g++ -shared 选项

log.o:log.c   //生成 .o 文件
	g++ -fPIC -c $^   //注意这里要带个 -fPIC 选项

.PHONY:clean
clean:
	rm -rf *.o *.so

output:
	mkdir -p Lib/include
	mkdir -p Lib/mylib
	cp *.h Lib/include
	cp *.so Lib/mylib

三.动静态库混合制作

代码语言:javascript
复制
static-lib=libprint.a
dy-lib=liblog.so

.PHONY:all   //生成多个目标文件时,可以定义一个伪目标
all: $(static-lib)  $(dy-lib)

$(static-lib):print.o
	ar -rc $@ $^

print.o:print.c
	g++ -c $^

$(dy-lib):log.o
	g++ -shared -o $@ $^

log.o:log.c
	g++ -fPIC -c $^

.PHONY:clean
clean:
	rm -rf *.a *.o *.so

output:
	mkdir -p Lib/include
	mkdir -p Lib/mylib
	cp *.h Lib/include
	cp *.a Lib/mylib
	cp *.so Lib/mylib

注意:不论是静态库还是动态库,都不可以有 main 函数 。

四.动静态库的使用

我们先在 main.cpp 文件中使用一下静态库

代码语言:javascript
复制
#include "print.h"  //静态库中的头文件

int main()
{
    print_func();  //静态库中定义的方法

    return 0;
}

g++ main.cpp 编译这个文件,出现了这样的结果:

 很显然是找不到头文件,可是我们不是包含了头文件吗,怎么会找不到呢?

其实 gcc 默认是在系统路径下查找的,而我们包含的头文件并不在系统路径中,如何解决?

-I (大写的 I):可以让 gcc 在指定路径下查找

那我们就 g++ main.cpp -I Lib/include  (因为我们代码中包含了头文件,所以不需要加头文件名称)

可以发现还是找不到,因为我们只提供了头文件的路径,gcc 还找不到库文件在哪儿

-L:可以让 gcc 在指定路径下寻找库文件 

继续 g++ main.cpp -I Lib/include -L Lib/mylib

还是找不到,因为一个库文件目录中可能有多个库文件,我们必须要指定库文件的名字

-l(小写的l)+静态库名称(注意之间没有空格)

继续  g++ main.cpp -I Lib/include -L Lib/mylib -lprint

可以发现,这次编译通过,生成了可执行文件。

如果有多个库文件,写 多个 -l(小写的l)后面跟库文件的名字就行了。

可是这也太麻烦了吧,每次编译都要写这么一长串?不可以像库函数那样,只包个头文件就行了?

下面介绍四种方法解决这个问题

五.解决找不到动态库的四种方法

1.拷贝到系统默认的库路径

  • 头文件拷贝到: /usr/include
  • 库文件拷贝到:/lib64

其实这个就是我们常说的安装。

下面演示:

拷贝

验证是否拷贝成功

之后,g++ main.cpp -lprint (注意要带库文件名) 编译文件

2.在系统默认的库路径下建立软链接

  •  头文件:/usr/include 下建立软链接
  • 库文件:/lib64 下建立软链接

建立软链接:

为头文件的目录建立软链接,因为一个目录里可能有很多头文件。

验证是否建立成功:

 现在只需要在main.cpp文件中这么包含头文件就行了

之后,g++ main.cpp -lprint (注意要带库文件名) 编译文件

3.将自己的库所在的路径,添加到系统的环境变量LD_LIBRARY_PATH中

LD_LIBRARY_PATH 是系统提供用户层的搜索路径,一般情况下,你的电脑上可能没有设置,如果你配置过vim,那么会有如下信息:

代码语言:javascript
复制
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:(库文件的路径)

4./etc/ld.so.conf.d建立自己的动态库路径的配置文件,然后重新ldconfig即可

最好切成root用户,然后进入 /etc/ld.so.conf.d 目录

代码语言:javascript
复制
cd /etc/ld.so.conf.d

这个目录下都是些 .conf 结尾的配置文件,这些文件里的内容都是路径。

我们只需要建立一个 .conf 文件,然后把对应动态库的路径放到这个文件里 ;

然后 ldconfig 把所有的配置文件重新加载一下

代码语言:javascript
复制
ldconfig

介绍了这么多方法,其实最常用的还是第一种,即我们常说的安装。 这里提一个比较好玩的库 :ncurse 库,用这个库可以做出很多好玩的东西。 想了解的话,可以自行搜索。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.静态库的制作
  • 二.动态库的制作
  • 三.动静态库混合制作
  • 四.动静态库的使用
  • 五.解决找不到动态库的四种方法
    • 1.拷贝到系统默认的库路径
      • 2.在系统默认的库路径下建立软链接
        • 3.将自己的库所在的路径,添加到系统的环境变量LD_LIBRARY_PATH中
          • 4./etc/ld.so.conf.d建立自己的动态库路径的配置文件,然后重新ldconfig即可
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档