【Linux】静态库和动态库
创始人
2024-05-13 12:15:23
0

Linux为什么不允许普通用户给目录建立硬链接呢?

image-20230116092715777

系统层面上有.和…硬链接指向目录。假设我们是超级用户,允许给目录建立硬链接,给根目录建立硬链接,从根目录开始查找,当查找硬链接的时候就是根目录,这时候递归式查找,形成了环路查找,最后导致软件无法正常进行查找工作!所以不允许普通用户给目录建立硬链接。

文章目录

    • 一、动态库和静态库
    • 二、理解库
    • 三、制作静态库
    • 四、制作动态库
    • 五、动静态库的加载

一、动态库和静态库

具体的动态库和静态库的相关内容👉点击跳转

Linux的库一般分为动态库和静态库:

静态库(.a):库文件以.a为后缀,程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):库文件以.so为后缀,程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

链接的本质:无非就是我们调用库函数的时候和标准库是如何关联的问题

库的名称:去掉前缀lib去掉后缀.so/.a剩下的就是库名称,比如libc.so就是C库

gcc 在编译时默认使用动态链接,而生成静态链接,我们需要在末尾带上-static:

img

安装静态库:

sudo yum install -y glibc-static
sudo yum install -y libstdc++-static

二、理解库

如果不想给对方我们的源代码,我们可以选择给用户提供我们的.o可重定位目标二进制文件(gcc -c 文件)与.h头文件。让用户用我们提供的.o文件进行链接即可。在编译时,只要把源文件编译成.o文件在将其链接便可形成一个可执行的程序

img

通过gcc -o生成,不出意外,编译运行成功:

image-20230116133214810

难道就这么简单吗?我们可以给对方提供.o(方法的实现),同时还有提供.h(里面包含着都有哪些方法),此时对方是能用的。但是如果存在很多.c文件呢?难道我们要把几千个.c文件全部编译成.o在加上头文件全部一个一个提供吗?那样太过于麻烦,为了让用户更好的使用库,我们就有把所有的.o文件打成一个包,给对方提供一个库文件即可!把多个.o合并成一个文件,这个文件就是库,把包方式的不同就分为了动态库和静态库*。

库的本质就是.o文件的集合。


准备的文件:

image-20230118130259209

三、制作静态库

我们如果想自己写一个库,要不要在这个库里面写main函数呢?答案肯定是不要的,库是被别人用的,自己写的main会和库里的main发生冲突。我们可以站在编写库的角度和使用者的角度来制作:

编写库:创建Makefile:

image-20230117175841393

将文件编译成.o文件

ar命令:把所有的.o打包起来,ar是归档。

-rc代表replace和create;比如:

ar -rc libmymath.a my_add.o my_sub.o

output:而我们要交付库,实际上要把库文件a.so以及匹配的头文件都交付给用户,而output就是一个发布的过程

image-20230117182852030

使用

image-20230117222131413

image-20230117215933458

此时,我们用户如果需要只要把mylib.tgz拷贝过去:比如:cp mylib.tgz …/test,拷贝过去之后进行解压: tar xzf mylib.tgz

image-20230117222548962

而所谓的安装其实就是在拷贝。直接把安装好的库使用起来:

头文件找不到?

编译器搜索头文件时默认在当前目录下搜索,在系统默认指定路径下搜索。虽然此时的mylib在当前路径下,但是头文件太深了,编译器找不到头文件,所以我们需要给gcc指定路径。带上-I ,指明在当前目录下的mylib目录下查找

image-20230117225023455

问题又来了,找不到库函数的实现。我们在形成可执行程序的时候,库文件要使用的话也要知道库所在的路径在哪里,系统的默认路径是/lib64。所以我们要带上-L。告诉库的路径在哪里。

但是如果要链接第三方的库,必须去指明库的名称(注意去掉前缀和后缀!)!!!也就是说,一定要告知路径下哪一个库,即使只有一个库,也要明确告知gcc要链接哪一个库(虽然我们以前写代码的时候,从来没有指明过库名称,这是因为gcc/g++默认帮我们填了,可以识别C/C++自带的库。自己写的要指明)

image-20230117231655995

最终终于顺利完成!

上面说了那么多,总结一下:

-I:指明头文件的搜索路径

-L:指明库文件的搜索路径

-l:指明要链接哪个库,带上库的名称(去掉前缀和后缀)

gcc默认是动态链接的(建议行为)对于特定的一个库,究竟是动静态库,取决你提供的是动态库还是静态库。

库的安装(把库安装到系统头文件路径下):

把头文件和库文件拷贝进系统的路径下,gcc对于头文件的默认路径是:/usr.include;对于库文件的默认路径是:/lib64:

image-20230117235724073

但是不太推荐这样使用:第三方库并没有经过测试,自己写的会污染库里面的其他文件。


四、制作动态库

首先我们需要把库文件全部编译成.o文件,这里与静态库不同,需要带上选项 -fPIC,形成与位置无关码:

gcc -c -fPIC my_add.c

什么是与位置的无关码的目标二进制文件:

静态库采用的是绝对编址

动态库采用的是相对编址,动态库中的指定函数的地址通过相对编址(库中的偏移地址+段起始地址):

image-20230118134110242

动态库打包:-shared

gcc -shared -o libmymath.so my_add.o my_sub.o

image-20230118105431940

image-20230118110420288

使用动态库

image-20230118110927754

但是这样子就可以吗?我们直接运行mymath:

image-20230118111042185

运行不了,这是为什么?找不到库

我们此时已经告诉了库文件,路径和库名称,选项已经给gcc带上了。但是我们当编译完之后,和gcc还有关系吗?答案是无关的,接下来运行是和OS有关的,动态库是运行时才加载的,所以程序运行起来,OS和shell也是需要知道库是在哪里的!而我们自己制作的库并没有在系统路径下,OS无法找到!如何找到动态库:

把库路径添加到环境变量LD_LIBRARY_PATH,比如当前自己制作库的路径是 /home/hwc/dir/test/mylib/lib

image-20230118113229401

直接运行:

image-20230118113256657

但是我们自己定义的环境变量只是本次登录有效,如果想永久有效只能修改环境变量的配置,但是比较麻烦。想永久有效,除了把库拷贝到系统目录下之外,我们还有其他方法:

1.配置文件(/etc/ld.so.conf.d/):动态库进行对应搜索时可以采用自己定义conf文件找到动态库

image-20230118115114624

2.建立软链接直接找到对应的库

image-20230118121302599

把对应的动态库建立在系统的目录下:

image-20230118121733222

总结一下:

运行动态库

1、拷贝.so文件到系统共享库路径下, 一般指/usr/lib

2、更改 LD_LIBRARY_PATH

3、ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

4.创建软链接


五、动静态库的加载

静态库不需要加载,静态库把代码拷贝到可执行程序里,直接决定了当加载的时候在内存里代码和数据可能存在多份,会比较浪费空间,把静态库中拷贝到程序中的代码区里:

image-20230118135744938

动态库加上fPIC形成位置无关码,采用相对编址方案,在程序链接时对应库当中的偏移量添加到可执行程序,运行时一旦库加载进来,经过地址空间映射,把库映射到地址空间之后,库也就具备了起始地址,通过偏移地址和起始地址这样就可以找到访问的函数:

image-20230118141601439

系统层面上会维护动态库的起始地址,直接建立页表与内存的映射,也就可以跳转访问了,所以动态库加载一次就可以被多个进程共同使用了。而静态库可能有多个程序用了C库,加载到内存时,内存里可能会存在100份重复的代码。而动态链接不会出现重复的代码,减少内存。

相关内容

热门资讯

2022高考作文规范范文【优... 2022高考作文规范范文 篇一高考作文规范范文随着2022年高考的临近,作为考生的我们需要了解并掌握...
新高考语文题目格式范文(优选... 新高考语文题目格式范文 篇一题目:《生活中的美好瞬间》导语:生活中,我们时常会遇到一些让人感到温暖和...
高考英语满分作文【通用6篇】 高考英语满分作文 篇一:如何提高英语口语能力英语口语能力在高考英语考试中占据重要的比重,但很多学生在...
关于让高考成绩再提高的方法(... 关于让高考成绩再提高的方法 篇一如何提高高考成绩?这是每位学生都关心的问题。高考成绩对于学生的未来发...
议论文人物故事写作素材15例... 议论文人物故事写作素材15例 篇一1. 父母的无私奉献 故事背景:主人公的父母为了供他上大学,...
教育部考试中心称不会取消全国... 教育部考试中心称不会取消全国统一高考 篇一近日,教育部考试中心发表声明称,不会取消全国统一高考。这一...
高考报考志愿个人陈述范文【最... 高考报考志愿个人陈述范文 篇一我的高中三年时光即将结束,我心中充满了对未来的期待和憧憬。回顾过去的学...
手握一滴水高考满分作文【精简... 手握一滴水高考满分作文 篇一探寻水的力量水,是生命之源,也是大自然最神奇的力量之一。曾经,我手握着一...
语文高考全国一卷优秀作文【精... 语文高考全国一卷优秀作文 篇一题目:诗意的人生人生如诗,每个人都是一首独特的诗篇。我们的人生是由一段...
高考作文经典素材:正能量【实... 高考作文经典素材:正能量 篇一正能量:改变人生的力量正能量是指积极向上的思想、激励人心的言行,具有积...
庚子年高考作文范文【精简6篇... 庚子年高考作文范文 篇一我的成长历程人生就像一场马拉松,每个人都要经历各种各样的挑战与困难。而我,也...
高考作文语文范文欣赏(优选6... 高考作文语文范文欣赏 篇一《人生的价值》人生自古以来就是一个永恒的话题,而关于人生的探讨与思考也从未...
北京高考作文题目(优选5篇) 北京高考作文题目 篇一新时代下的北京高考近年来,随着社会的进步和发展,新时代给北京高考带来了新的挑战...
历年经典高考满分作文【实用6... 历年经典高考满分作文 篇一:成长的意义成长是每个人都要经历的过程,它伴随着我们从孩提时代向成年人迈进...
难忘的经历高考作文【精选6篇... 难忘的经历高考作文 篇一高考,是每个学生的一场关键考试,也是一段难以忘怀的经历。回忆起那段时光,我至...
高考作文复习【优秀3篇】 高考作文复习 篇一高考作文是考生最重要的一项考试内容,也是考察学生综合能力的重要指标。为了顺利应对高...
四川高考作文【精选5篇】 四川高考作文 篇一:探索自我,实现梦想高考作文题目:探索自我,实现梦想作文要求:请以“探索自我,实现...
高考复读学校招生模板范文(优... 高考复读学校招生模板范文 篇一:提升学业水平,实现梦想的机会尊敬的家长和考生:您好!感谢您对我们学校...
高考语文万能作文素材(优质6... 高考语文万能作文素材 篇一第一篇内容:文学与人生文学是人类的精神财富,是人类智慧的结晶。它以文字为媒...
高考作文预测与:兑现承诺(通... 高考作文预测与:兑现承诺 篇一在高考备考期间,很多学生会参加各种辅导班和模拟考试,以提高自己的成绩。...