怎么做wap网站,wordpress 信息分类模板,html5自建网站,网站仿站总言 文件系统与动静态库相关介绍。 文章目录 总言2、文件系统2.1、背景知识2.2、磁盘管理2.2.1、磁盘文件系统图2.2.2、inode与文件名 2.3、软硬链接 3、动静态库3.1、站在编写库的人的角度#xff1a;如何写一个库#xff1f;3.1.1、静态库制作3.1.3、动态库制作 3.2、站在…总言 文件系统与动静态库相关介绍。 文章目录 总言2、文件系统2.1、背景知识2.2、磁盘管理2.2.1、磁盘文件系统图2.2.2、inode与文件名 2.3、软硬链接 3、动静态库3.1、站在编写库的人的角度如何写一个库3.1.1、静态库制作3.1.3、动态库制作 3.2、站在使用库的人的角度如何用别人提供的库3.2.1、使用静态库3.2.2、使用动态库 2、文件系统
2.1、背景知识 说明一 掉电易失存储介质内存 永久性存储介质磁盘、SSD、U盘、flash卡、光盘、磁带 磁盘是外设且还是计算机中唯一一个机械设备与OS等相比其操作效率很慢因此OS会有一定的提速方式。 说明二 CHS与LBA之间的转换 说明三 虽然硬件层面扇区通常为512bit但操作系统(文件系统)与磁盘进行IO的基本单位是4kb原因如下 1、若IO交互的基本单位太小有可能导致多次IO降低效率。 2、使得硬件和软件解耦合。若IO交互使用和磁盘一样的单位当磁盘基本单位变大时OS也要随之修改。
2.2、磁盘管理
2.2.1、磁盘文件系统图 1、解释磁盘文件系统图各小块含义 整体说明 磁盘是典型的块设备硬盘分区被划分为一个个的block。上图为磁盘文件系统图Linux ext2文件系统不同内核内存映像有所不同。一个block的大小是由格式化的时候确定的并且不可以更改例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。上图中启动块Boot Block的大小是确定的。 1、数据区Data block多个4KB(扇区×8)大小的集合通常用于存放文件内容。 PS文件内容属性Linux在磁盘上存储文件时是将内容和属性分开存储的。 2、i节点表inode Tableinode是大小为128字节的空间保存着对应文件的属性如文件大小、所有者、最近修改时间等。inode table是该组块(block group)内所有文件的inode空间的集合为了标识每个inode的唯一性会为其附一个inode编号也存储在各自的inode空间中。 PS一般而言一个文件对应一个inode用于记录其文件属性同时该inode有一个标识编号(inode编号)。
[wjVM-4-3-centos T0730]$ ls -li //加-i选项可查看每个文件的inode编号
total 24
789948 -rw-rw-r-- 1 wj wj 51 Jul 30 21:45 log.txt
790002 -rw-rw-r-- 1 wj wj 65 Jul 30 12:24 makefile
790001 -rw-rw-r-- 1 wj wj 2929 Jul 30 21:45 myfile.c
789573 -rwxrwxr-x 1 wj wj 8568 Jul 30 21:45 myfile.o
[wjVM-4-3-centos T0730]$ 3、块位图Block BitmapBlock Bitmap中记录着Data Block中哪个数据块已经被占用哪个数据块没有被占用。将bit位与特定的data block中数据块一一对应若比特位为1则该数据块被占用为0表示未被占用。 4、inode位图inode Bitmap每个bit表示一个inode是否空闲可用。同理将比特位与inode一一对应为1表示占用为0表示未被占用。 PSblock bitmap和inode bitmap是用于管理信息的扫描这两区域即可查看该块组内inode和数据块使用程度。 5、块组描述符Group Descriptor TableGDT用户描述块组属性信息如该块组多大已经使用多少空间有多少个inode/data block占用和未占用情况。 格式化说明 如上述将块组分割成上述内容并写入相关的管理数据在磁盘内就能让一个文件的信息可追溯、可管理。将每个块组统一规定为如上格式那么整个分区就被写入 了文件系统信息。将这种操作称之为格式化。 2、其它说明 1、一个文件对应一个inode编号、inode属性节点那么一个文件只能有一个block吗 回答不一定。data block大小有限当文件内容很大时一个数据块不足以存储所有文件内容此时就需要多个数据块支持。 2、哪些block属于同一个文件如何找到它们 3、文件内容属性通过inode编号可以找到文件inode属性集合那么怎么找到文件内容呢 回答inode中除了保存文件的属性大小、权限、inode编号等还有一个其它属性用于保存同块组内对应文件的数据块编号。 4、当这个文件特别大时inode中的blocks也不够存储对应data blocks的量又该怎么办 2.2.2、inode与文件名 1、问题引入如何找到一个文件 回答找到一个文件首先要找到其inode编号根据inode编号获取特定的块组block group 在块组内的inode table中找到对应的inode从而能够获取到文件的属性与内容。 那么如何获取到文件的inode编号呢 2、文件inode编号与文件名说明 1、inode属性中并不存储文件名称文件名称实则是由该文件隶属的目的来保存的。 2、目录也是文件其内部可以具有多个文件同一个目录下的文件不能有重名。对于一个目录而言既然它是文件就具有自己的inode也有对应的data blocks。而根据1可知inode中不保存文件名称因此文件的文件名称实则是与其inode编号建立映射关系保存在目录的data blocks中的。 3、上述内容也解释了进入目录、创建文件、显示文件名与属性中权限需求说明。如创建一个文件需要把文件的inode编号和文件名称建立映射关系并保存在目录的data blocks中因此需要目录有w权限。读取文件时也需要先找到对应的inode编号就需要访问目录的data blocks因此目录要有r权限。 3、根据上述内容可回答三个问题 问题1、创建文件系统做了什么
[rootlocalhost linux]# touch abc
[rootlocalhost linux]# ls -i abc
263466 abc回答创建一个新文件主要有以下四个操作 ① 存储属性 内核先找到一个空闲的i节点这里是263466内核把文件的属性信息记录到其中。 ② 存储数据 假设该文件需要存储在三个磁盘块内核需要找到了三个空闲的数据块300,500800。将内核缓冲区的第一块数据复制到300下一块复制到500以此类推。 ③ 记录分配情况将文件内容按顺序300、500、800存放。内核在inode上的磁盘分布区记录了上述块列表。 ④添加文件名到目录新的文件名abc。内核将入口263466abc添加到目录文件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来。 问题2、删除文件系统做了什么 回答以文件名索引inode编号置零inode bitmap置零data bitmap断开目录中记录的映射关系。PS对应文件内容和inode table中的属性可以不用清除。类比参考数据结构阶段学习的各类删除接口 延伸删除的文件能够恢复吗 回答可以恢复找到inode编号就能找对对应文件。前提是对应位置的inode、data block没有被重复占用。 问题3、查看文件系统做了什么 回答以文件名为索引找到inode编号显示对应的文件信息。例如ls 只显示目录下的所有文件名称加各项选项会显示其它属性信息。 4、周边问题 1、组块中分区中各小块是由谁来划分的 回答格式化操作的过程就是在磁盘中写入文件系统的过程。 2、创建文件写入失败或者直接创建文件失败分析可能的原因 回答inode table大小固定data blocks大小固定。以下情况可能导致创建文件失败 ①inode已满data block未满 ②inode未满data block已满。
2.3、软硬链接 1、如何建立软硬链接 相关指令如下 ln -s创建软链接如ln -s testlink1.txt soft.link ln创建硬链接如ln testlink2.txt hard.link 代码演示如下
[wjVM-4-3-centos T0804]$ mkdir dir
[wjVM-4-3-centos T0804]$ touch testlink1.txt
[wjVM-4-3-centos T0804]$ touch testlink2.txt
[wjVM-4-3-centos T0804]$ touch testlink3.txt[wjVM-4-3-centos T0804]$ ls -li
total 4
790036 drwxrwxr-x 2 wj wj 4096 Aug 4 15:21 dir
790037 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink1.txt
790038 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink2.txt
790039 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink3.txt[wjVM-4-3-centos T0804]$ ln -s testlink1.txt soft.link
[wjVM-4-3-centos T0804]$ ln testlink2.txt hard.link[wjVM-4-3-centos T0804]$ ls -li
total 4
790036 drwxrwxr-x 2 wj wj 4096 Aug 4 15:21 dir
790038 -rw-rw-r-- 2 wj wj 0 Aug 4 15:21 hard.link
790040 lrwxrwxrwx 1 wj wj 13 Aug 4 15:25 soft.link - testlink1.txt
790037 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink1.txt
790038 -rw-rw-r-- 2 wj wj 0 Aug 4 15:21 testlink2.txt
790039 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink3.txt
[wjVM-4-3-centos T0804]$ 结果观察 PSunlink XXXX可删除链接关系。
[wjVM-4-3-centos uselib]$ ln -s main.c main.so #建立软链接
[wjVM-4-3-centos uselib]$ ll
total 28
-rw-rw-r-- 1 wj wj 157 Aug 4 21:57 main.c
-rwxrwxr-x 1 wj wj 8440 Aug 5 17:54 main.out
lrwxrwxrwx 1 wj wj 6 Aug 5 18:57 main.so - main.c
-rw-rw-r-- 1 wj wj 35 Aug 5 16:13 makefile
drwxrwxr-x 5 wj wj 4096 Aug 5 16:07 output
drwxrwxr-x 4 wj wj 4096 Aug 5 10:55 staticlib[wjVM-4-3-centos uselib]$ unlink main.so #删除
[wjVM-4-3-centos uselib]$ ll
total 28
-rw-rw-r-- 1 wj wj 157 Aug 4 21:57 main.c
-rwxrwxr-x 1 wj wj 8440 Aug 5 17:54 main.out
-rw-rw-r-- 1 wj wj 35 Aug 5 16:13 makefile
drwxrwxr-x 5 wj wj 4096 Aug 5 16:07 output
drwxrwxr-x 4 wj wj 4096 Aug 5 10:55 staticlib 2、软硬链接有什么区别 软硬链接本质区别 有无独立inode编号。 回答软链接有独立的inode说明软链接是一个独立的文件。硬链接没有独立的inode说明硬链接不是一个独立的文件。 问题它们之间的这种独立性的差距有什么意义 对软链接 特性软链接的文件内容指向被链接文件的对应路径。因此删除软链接文件被链接文件仍旧存在相当于Windows下删除快捷键但所指向程序仍旧存在。
[wjVM-4-3-centos test01]$ ls -li
total 0
790040 lrwxrwxrwx 1 wj wj 13 Aug 4 15:25 soft.link - testlink1.txt
790037 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink1.txt
790038 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink2.txt[wjVM-4-3-centos test01]$ rm soft.link //删除软链接文件实际被链接文件仍旧存在[wjVM-4-3-centos test01]$ ls -li
total 0
790037 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink1.txt
790038 -rw-rw-r-- 1 wj wj 0 Aug 4 15:21 testlink2.txt
[wjVM-4-3-centos test01]$ 相关应用相当于Windows下的快捷方式 对硬链接 硬链接的inode为被链接文件的inode不是真正的创建新文件。创建硬链接时只是在指定目录下建立文件名与指定indoe的映射关系相当于起别名。 属性中存在硬链接数用于确定多少个文件名与该indoe关联。实际删除文件时并不是把该文件真正删除而是减少其硬链接数直到其为0该文件才真正删除。 默认创建一个普通文件、目录其默认硬链接数说明 问题如下为什么默认创建一个普通文件其硬链接数为1为什么默认创建一个普通目录其硬链接数为2
[wjVM-4-3-centos test01]$ mkdir dir
[wjVM-4-3-centos test01]$ touch test.txt
[wjVM-4-3-centos test01]$ ls -li
total 4
790037 drwxrwxr-x 2 wj wj 4096 Aug 4 19:11 dir
790038 -rw-rw-r-- 1 wj wj 0 Aug 4 19:11 test.txt
[wjVM-4-3-centos test01]$ 对普通文件创建一个普通文件其自身文件名和自身inode建立关系故硬链接数为1。如上述例子中的790038test.txt 对目录创建一个空目录除了自身目录名和inode建立关联进入目录内可看到隐藏目录.(代表当前路径)也与该inode关联故而空目录的链接数2。PS若目录内还有其它子目录则子目录中隐藏文件..也和该inode关联。
[wjVM-4-3-centos test01]$ ls
dir test.txt
[wjVM-4-3-centos test01]$ ls -ali
total 12
790036 drwxrwxr-x 3 wj wj 4096 Aug 4 19:11 .
790035 drwxrwxr-x 4 wj wj 4096 Aug 4 15:47 ..
790037 drwxrwxr-x 2 wj wj 4096 Aug 4 19:11 dir
790038 -rw-rw-r-- 1 wj wj 0 Aug 4 19:11 test.txt
[wjVM-4-3-centos test01]$ cd dir
[wjVM-4-3-centos dir]$ ls -ali
total 8
790037 drwxrwxr-x 2 wj wj 4096 Aug 4 19:11 .
790036 drwxrwxr-x 3 wj wj 4096 Aug 4 19:11 ..
[wjVM-4-3-centos dir]$ 3、动静态库
3.1、站在编写库的人的角度如何写一个库
3.1.1、静态库制作 1、准备工作 为了方便演示此处写头文件与方法实现分离写一两个演示代码
[wjVM-4-3-centos test03]$ cat accum.h
#pragma once
#includestdio.hextern void accum(int from, int to);[wjVM-4-3-centos test03]$ cat accum.c
#include accum.hint accumulate(int from, int to)
{int sum 0;int i 0;for(i from; i to; i){sumi;}return sum;
}
[wjVM-4-3-centos test03]$ cat print.h#pragma once
#includestdio.h
#includetime.hextern void print(const char* str);[wjVM-4-3-centos test03]$ cat print.c
#include print.hvoid print(const char* str)
{printf(%s[%d]\n,str,(int)time(NULL));
} 假设以上两个为待封装库的相关内容实现这里我们分别使用两个目录用以演示库制作与库使用。注意制作库时库中不能存在main函数。
[wjVM-4-3-centos test03]$ ls
mklib uselib
[wjVM-4-3-centos test03]$ tree
.
|-- mklib
| |-- accum.c
| |-- accum.h
| |-- print.c
| -- print.h
-- uselib2 directories, 4 files
[wjVM-4-3-centos test03]$ 使用一个makefile来完成上述内容的编译过程。PS该文件后续还会改动
[wjVM-4-3-centos mklib]$ cat makefile
.PHONY:all
all:print.o accum.oprint.o:print.cgcc -c print.c -o print.o
accum.o:accum.cgcc -c accum.c -o accum.o.PHONY:clean
clean:rm -rf *.o[wjVM-4-3-centos mklib]$ 2、制作一个静态库 1、问题直接将.o文件和.h文件给别人是否能形成可执行程序以供使用 一点准备工作如下将形成的accum.o、accum.h、print.o、print.h拷贝一份放入uselib目录中用以演示
[wjVM-4-3-centos mklib]$ ll //当前文件
total 24
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 153 Aug 4 21:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h[wjVM-4-3-centos mklib]$ make
gcc -c print.c -o print.o
gcc -c accum.c -o accum.o[wjVM-4-3-centos mklib]$ ll //生成.o文件
total 28
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 1280 Aug 4 21:44 accum.o
-rw-rw-r-- 1 wj wj 153 Aug 4 21:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
-rw-rw-r-- 1 wj wj 1576 Aug 4 21:42 print.o 在ueslib目录中创建一个main.c文件在该文件中使用这两个拟库。
[wjVM-4-3-centos mklib]$ mv *.h *.o ../uselib //相关指令
[wjVM-4-3-centos mklib]$ cd ../uselib/ //转到uselib文件中
[wjVM-4-3-centos uselib]$ ls
accum.h accum.o print.h print.o main.c
[wjVM-4-3-centos uselib]$ cat main.c //写一个main.c在其中用到这两个文件
#include print.h
#include accum.hint main()
{print(hello main:);int ret accumulate(1,50);printf(result:%d\n,ret);return 0;
} 如下我们能成功使用
[wjVM-4-3-centos uselib]$ gcc -o main.out main.c print.o accum.o
[wjVM-4-3-centos uselib]$ ls
accum.h accum.o main.c main.out print.h print.o
[wjVM-4-3-centos uselib]$ ./main.out
hello main:[1691157514]
result:1275
[wjVM-4-3-centos uselib]$ 如上方式虽然能够演示成功 一旦用于制作的库文件过多这样交给方式有些繁琐属于一种野生级别的方式。因此我们还需要将库进行打包归档。 2、静态库制作使用ar指令整理打包库archive files归档文件 相关指令 ①gcc -c XXX.c -o XXX.o 获取.o二进制目标文件 ②ar -rc libXXX.a XXX.o XXX.o将库归档处理。 此处要注意 libXXX.a中lib、.a为语法格式中间名称可任意取。后面要打包几个.o文件就跟几个。 演示如下
[wjVM-4-3-centos mklib]$ ll //mklib中的文件
total 28
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 1280 Aug 4 21:46 accum.o
-rw-rw-r-- 1 wj wj 153 Aug 4 21:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
-rw-rw-r-- 1 wj wj 1576 Aug 4 21:46 print.o[wjVM-4-3-centos mklib]$ ar -rc libstatic.a accum.o print.o //对.o文件进行归档打包[wjVM-4-3-centos mklib]$ ll
total 32
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 1280 Aug 4 21:46 accum.o
-rw-rw-r-- 1 wj wj 3074 Aug 5 10:13 libstatic.a //新生成的静态库
-rw-rw-r-- 1 wj wj 153 Aug 4 21:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
-rw-rw-r-- 1 wj wj 1576 Aug 4 21:46 print.o
[wjVM-4-3-centos mklib]$ 使用makefile生成
libstatic.a:print.o accum.o //形成静态库step2ar -rc libstatic.a accum.o print.oprint.o:print.c //形成静态库step1gcc -c print.c -o print.o
accum.o:accum.c //形成静态库step1gcc -c accum.c -o accum.o.PHONY:clean
clean:rm -rf *.o libstatic.a
[wjVM-4-3-centos mklib]$ make clean
rm -rf *.o libstatic.a
[wjVM-4-3-centos mklib]$ ls
accum.c accum.h makefile print.c print.h
[wjVM-4-3-centos mklib]$ make
gcc -c print.c -o print.o
gcc -c accum.c -o accum.o
ar -rc libstatic.a accum.o print.o
[wjVM-4-3-centos mklib]$ ll
total 32
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 1280 Aug 5 10:29 accum.o
-rw-rw-r-- 1 wj wj 3074 Aug 5 10:29 libstatic.a //所形成的静态库
-rw-rw-r-- 1 wj wj 230 Aug 5 10:20 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
-rw-rw-r-- 1 wj wj 1576 Aug 5 10:29 print.o
[wjVM-4-3-centos mklib]$ 3、发布库 说明该静态库目录分为两部分其一为头文件目录include其二为打包的库目录lib这里我们仍旧使用makefile生成。 在上述的makefile中再加入这段指令
.PHONY:staticlib
staticlib:mkdir -p staticlib/includemkdir -p staticlib/lib cp -rf *.h staticlib/includecp -rf *.a staticlib/lib 由此我们就得到一个staticlib静态库目录其中.h头文件和.a静态库分开存放
[wjVM-4-3-centos mklib]$ make staticlib
mkdir -p staticlib/include
mkdir -p staticlib/lib
cp -rf *.h staticlib/include
cp -rf *.a staticlib/lib [wjVM-4-3-centos mklib]$ ll
total 36
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 1280 Aug 5 10:32 accum.o
-rw-rw-r-- 1 wj wj 3074 Aug 5 10:32 libstatic.a
-rw-rw-r-- 1 wj wj 373 Aug 5 10:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
-rw-rw-r-- 1 wj wj 1576 Aug 5 10:32 print.o
drwxrwxr-x 4 wj wj 4096 Aug 5 10:43 staticlib //静态库目录文件[wjVM-4-3-centos mklib]$ tree staticlib/
staticlib/
|-- include
| |-- accum.h
| -- print.h
-- lib-- libstatic.a2 directories, 3 files
[wjVM-4-3-centos mklib]$ 发布后如何使用静态库见3.2.1部分。
3.1.3、动态库制作 1、准备工作 此处使用静态库中的演示例子accum.c、accum.h、print.c、print.h具体内部代码见上述。
[wjVM-4-3-centos mklib]$ ll
total 24
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 373 Aug 5 10:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
drwxrwxr-x 4 wj wj 4096 Aug 5 10:43 staticlib2、制作一个库 相关指令 ①gcc -fPIC -c XXX.c -o XXX.o fPIC形成一个与位置无关的二进制目标文件。 ②gcc -shared XXX.o XXX.o -o libXXX.so -shared用于表示所形成的是动态库而非可执行程序。 演示如下
[wjVM-4-3-centos mklib]$ ll
total 24
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rw-rw-r-- 1 wj wj 373 Aug 5 10:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
drwxrwxr-x 4 wj wj 4096 Aug 5 10:43 staticlib[wjVM-4-3-centos mklib]$ gcc -fPIC -c print.c -o print_d.o #step1:生成一个与位置无关的二进制目标文件
[wjVM-4-3-centos mklib]$ gcc -fPIC -c accum.c -o accum_d.o
[wjVM-4-3-centos mklib]$ ls
accum.c accum_d.o accum.h makefile print.c print_d.o print.h staticlib[wjVM-4-3-centos mklib]$ gcc -shared accum_d.o print_d.o -o libdynamic.so #step2:生成一个动态库
[wjVM-4-3-centos mklib]$ ll
total 40
-rw-rw-r-- 1 wj wj 165 Aug 4 21:44 accum.c
-rw-rw-r-- 1 wj wj 1280 Aug 5 14:36 accum_d.o
-rw-rw-r-- 1 wj wj 75 Aug 4 21:44 accum.h
-rwxrwxr-x 1 wj wj 8152 Aug 5 14:36 libdynamic.so #动态库
-rw-rw-r-- 1 wj wj 373 Aug 5 10:42 makefile
-rw-rw-r-- 1 wj wj 96 Aug 4 21:07 print.c
-rw-rw-r-- 1 wj wj 1624 Aug 5 14:35 print_d.o
-rw-rw-r-- 1 wj wj 88 Aug 4 21:07 print.h
drwxrwxr-x 4 wj wj 4096 Aug 5 10:43 staticlib
[wjVM-4-3-centos mklib]$ 使用makefile生成
dynamiclib.so:print_d.o accum_d.ogcc -shared print_d.o accum_d.o -o libdynamic.soprint_d.o:print.cgcc -fPIC -c print.c -o print_d.o
accum_d.o:accum.cgcc -fPIC -c accum.c -o accum_d.o 3、发布库 这里我们直接生成动静态库两个版本makefile中相关写法如下
.PHONY:all
all::libdynamic.so libstatic.a##动态库##
libdynamic.so:print_d.o accum_d.ogcc -shared print_d.o accum_d.o -o libdynamic.soprint_d.o:print.cgcc -fPIC -c print.c -o print_d.o
accum_d.o:accum.cgcc -fPIC -c accum.c -o accum_d.o
######静态库##
libstatic.a:print.o accum.oar -rc libstatic.a accum.o print.oprint.o:print.cgcc -c print.c -o print.o
accum.o:accum.cgcc -c accum.c -o accum.o
####.PHONY:output
output:mkdir -p output/lib mkdir -p output/includecp -rf *.h output/includecp -rf *.a *.so output/lib .PHONY:clean
clean:rm -rf *.o *.a *.so output 演示结果 3.2、站在使用库的人的角度如何用别人提供的库
3.2.1、使用静态库 我们获取到别人归档后的库并不能直接使用还需要做一定操作以下为几种使用静态库的方法介绍。 1、做法一将我们所下载的库拷贝到系统库(系统默认路径)中 前提认知 头文件gcc默认搜索路径/usr/include 库文件云服务器默认搜索路径/lib64 或者 /usr/lib64 相关指令 拷贝libsudo cp XXX/XXX/*.a /lib64 -rf
sudo cp ./staticlib/lib/*.a /lib64 -rf拷贝头文件sudo cp XXX/XXX/*.h /usr/include -rf sudo cp ./staticlib/include/*.h /usr/include -rf 第三方库编译方法gcc XXX.c -lXXX要加-l后面跟的是库名称。libXXX.a中去掉前缀和后缀XXX为库的名称。
gcc main.c -lstatic -o main.out以下为演示过程及结果将库拷贝到系统默认路径下就叫做库的安装。 问题说明 上述使用静态库的方法容易污染系统库一般不建议这样使用。
[wjVM-4-3-centos uselib]$ sudo rm /usr/include/accum.h
[sudo] password for wj:
[wjVM-4-3-centos uselib]$ sudo rm /usr/include/print.h
[wjVM-4-3-centos uselib]$ sudo rm /lib64/libstatic.a2、做法二硬使用 相关指令 gcc XXX.c -I ./XXX/include/ -L ./XXX/lib/ -lXXX
gcc main.c -I ./staticlib/include/ -L ./staticlib/lib/ -lstatic -o main.out-I指定库的头文件搜索路径 -L指定搜索lib路径 -lXXX指定库名称 相关演示如下: 说明 上述方式中a、若只有静态库则只能静态链接。 b、动静态库同时存在时默认使用动态库。 c、动静态库同时存在但非要使用静态库如何操作 -static 强制静态链接。 该选项的意义摒弃默认优先使用动态库的原则直接使用静态库。 3.2.2、使用动态库 1、整体说明 1、同上述静态库中方法一可以在系统默认路径对动态库进行安装、卸载操作但同样不建议这样使用。 2、针对方法二中动态库无法运行的问题说明
[wjVM-4-3-centos uselib]$ gcc main.c -I ./output/include -L ./output/lib2 -loutput #使用相关指令
[wjVM-4-3-centos uselib]$ ls
a.out main.c makefile output staticlib[wjVM-4-3-centos uselib]$ file a.out
a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]41a35062c3b3113f93efd9ef58eeaf1f795adfb5, not stripped[wjVM-4-3-centos uselib]$ ./a.out #运行发现运行失败
./a.out: error while loading shared libraries: liboutput.so: cannot open shared object file: No such file or directory
[wjVM-4-3-centos uselib]$ 静态库将相应代码嵌入程序中程序执行时就在自己所处的代码区域动态库相应代码加载在共享区程序执行时在共享区和代码区反复跳转。动态库只用加载一次就能被多个进程同时使用即共享库。 我们使用gcc main.c -I ./output/include -L ./output/lib2 -loutput指令时只是针对gcc说明需要动态库但动态库运行加载是操作系统加载器来完成的故需要给OS说明。 1、解决方案 解决方案一系统的环境变量 LD_LIBRARY_PATH设置此环境变量export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/XXXXX/XXXXX
[wjVM-4-3-centos uselib]$ echo $LD_LIBRARY_PATH
:/home/wj/.VimForCpp/vim/bundle/YCM.so/el7.x86_641、上述方式关闭shell后设置好的内存级的环境变量被清空下次进入将重新设置。 2、这里export导环境变量也可以使用相对路径
[wjVM-4-3-centos uselib]$ export LD_LIBRARY_PATHLD_LIBRARY_PATH:./output/lib/
[wjVM-4-3-centos uselib]$ echo $LD_LIBRARY_PATH
LD_LIBRARY_PATH:./output/lib/
[wjVM-4-3-centos uselib]$ ldd main.outlinux-vdso.so.1 (0x00007fff066be000)/$LIB/libonion.so /lib64/libonion.so (0x00007f9da91f4000)libdynamic.so ./output/lib/libdynamic.so (0x00007f9da8ed9000)libc.so.6 /lib64/libc.so.6 (0x00007f9da8b0b000)libdl.so.2 /lib64/libdl.so.2 (0x00007f9da8907000)/lib64/ld-linux-x86-64.so.2 (0x00007f9da90db000)
[wjVM-4-3-centos uselib]$ ./main.out
hello main:[1691230176]
result:1275
[wjVM-4-3-centos uselib]$ 解决方案二修改配置文件 ls /etc/ld.so.conf.d/相对方案一该方案属于长久保存的一个方法。 操作在该目录下创建一个XXX.conf文件在该文件内填入对应的动态库搜索路径 ①sudo touch /etc/ld.so.conf.d/XXX.conf创建文件 ②sudo vim /etc/ld.so.conf.d/XXX.conf 填入路径 ③sudo ldconfig让配置文件更新生效 具体演示 解决方案三建立软链接 sudo ln -s XXX/XXX /lib64/libXXX.so注意使用绝对路径。 相关演示 除了上述方法还有其它方式可以支持。