【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份重复的代码。而动态链接不会出现重复的代码,减少内存。

相关内容

热门资讯

南越王墓葬群导游词 南越王墓葬群导游词  西汉南越王墓_导游词  西汉南越王墓  一、概况  各位游客,今天我将带大家参...
火山口国家地质公园导游词 火山口国家地质公园导游词  朋友们,相信你一定知道火山,在电视或电影里看过火山爆发的场景,一定会被它...
秦兵马俑导游词 秦兵马俑导游词15篇  作为一名尽职尽责的导游,编写导游词是必不可少的,导游词是我们引导游览时使用的...
晋祠导游词 晋祠导游词  作为一名专门为游客提供帮助的导游,通常需要准备好一份导游词,导游词具有极强的实用性,涉...
昆明大观楼导游词 昆明大观楼导游词  作为一名专门为游客提供帮助的导游,常常要写一份好的导游词,导游词是导游员在游览时...
许昌西湖公园的导游词 许昌西湖公园的导游词  今天,我带领大家来游览位于许昌市中心的西湖公园,希望我们能一起渡过一段快乐的...
刘公岛导游词 刘公岛导游词范文(精选5篇)  作为一名乐于助人的导游,总归要编写导游词,导游词是导游员同游客交流思...
九龙洞风景区导游词贵州导游词 九龙洞风景区导游词贵州导游词  作为一名默默奉献的导游,时常需要编写导游词,导游词一般是根据实际的游...
云南澜沧江导游词 云南澜沧江导游词  澜沧江是湄公河上游在中国境内河段的名称,藏语拉楚,意思为“獐子河”。它也是中国西...
新疆概况旅游导游词 新疆概况旅游导游词范文(精选3篇)  作为一名尽职尽责的导游,有必要进行细致的导游词准备工作,借助导...
颐和园的导游词资料 关于颐和园的导游词资料  导游词是导游人员引导游客观光游览时的讲解词,是导游员同游客交流思想,向游客...
北京导游词 北京导游词(合集15篇)  作为一名优秀的旅游从业人员,时常要开展导游词准备工作,一篇完整的导游词,...
泰山景点介绍导游词 泰山景点介绍导游词(通用5篇)  作为一位不辞辛劳的导游,通常需要准备好一份导游词,导游词可以加深游...
校园导游词 校园导游词  作为一名专门引导游客、助人为乐的导游,就难以避免地要准备导游词,导游词一般是根据实际的...
韩国景点导游词 韩国景点导游词  大家好!  首先,欢迎大家到韩国首尔来旅游,下面就由我给大家介绍一下这个具有东方神...
介绍洛阳的导游词 介绍洛阳的导游词  洛阳位于河南,在那里有许多的特色文化,那么关于介绍洛阳的导游词都有哪些呢?下面是...
桂林聚龙潭导游词 桂林聚龙潭导游词  作为一位无私奉献的导游,时常需要用到导游词,导游词不是以一代百、千篇一律的,它必...
炳灵寺石窟导游词 炳灵寺石窟导游词  作为一名尽职尽责的导游,常常要根据讲解需要编写导游词,导游词是导游人员引导游客观...
西安大雁塔导游词 西安大雁塔导游词500字  游客朋友们:  大家好!  欢迎大家到西安大雁塔观光旅游!  大雁塔位于...