软链接的建立
显示出inode
软链接就是一个普通文件,有自己独立的inode,类似于一个桌面上的快捷方式。保存的是指向所链接文件的路径。
硬链接的建立
硬链接拥有与链接文件相同的inode,没有自己独立的inode,类似C++的引用&(别名)。
本质是在该目录的数据块中创建了硬链接名与inode的映射关系,并没有创建新文件。
第三列数字代表的是硬链接数,可以发现普通文件也至少会有一个,是当前目录的数据块中存放了一组文件名与inode的映射关系。
为什么目录硬链接数默认就是2呢?
简单来说就是目录自己和该目录内的路径是一个东西,类似原理还有上一路径的…
这样设置是为了方便路径的快速转换或者设置相对路径。
文件被修改的频率不高,而文件被访问频率较高,所以为了提高效率,单纯访问文件其实并不会修改access时间,如cat
touch文件名,可以刷新所有时间。
通过时间之间的比对,在编译代码的过程中判断哪些代码不需要再被重复编译了。
为什么要使用别人的代码?
提高开发效率和代码的鲁棒性(特殊情况下也不崩溃)。
如何使用别人的代码?
调用库
开源代码
网络功能的调用(语音识别)
动态库:libc.so
静态库:libc.a
去掉前缀lib,去掉.之后的内容,就是库的名字。
生成可执行程序前会有链接过程,有动态链接和静态链接,就对应了动态库和静态库。
动态链接:去库中执行我的可执行程序中对应库中的代码,返回结果到可执行程序。
特点:体积小,节省资源。一旦库丢失,bin不可执行。
静态链接:将库中包括我的可执行程序中的二进制代码,拷贝进我的可执行程序。
特点:体积大,浪费资源。但不依赖库,库丢失不影响。
为了支持开发,第三方库or语言库都必须要提供两个库,可根据需要进行使用。
ldd + 文件名
默认为动态
gcc选项+ -static
变为静态
示例为:将自己写的加减法代码(Add.c .h/Sub.c .h)打包给别人并不让别人看到源码。
头文件的作用是让使用者知道包含的方法。
gcc -c Add.c
默认生成.o文件,在链接前停下
使用ar工具将多个.o文件打包
这样可以使多个.o文件可以被同时链接。
ar -cr libmymath.a Add.o Sub.o
这时候只需要将打包好的.a文件和头文件交付给别人即可。
**gcc选项之在指定路径下查找头文件**
gcc -I + 路径
-I
告诉gcc除了在默认路径以及当前路径,也在指定路径找头文件。
gcc选项之在指定路径下查找库文件
gcc -L + 路径 + -l库名
-L
告诉gcc除了在默认路径以及当前路径,也在指定路径找库文件。
-l库名
具体要链接哪一个库。
为什么之前C语言在编译的时候,从来没有用过这些选项呢?
1、库文件和头文件在默认路径下
2、gcc用来编译c,默认就会链接libc
如果我们也不想使用这些选项呢?
头文件和库文件拷贝到默认路径下,这个过程为库的安装
第三方库也需要带上-l库名
makefile方式生成目标文件
gcc选项,fPIC产生与位置无关码
进程地址空间内的共享区位于堆区与栈区之间,存放动态库的代码。
这样做的意义是:所有进程的共享区都可以映射到同一块物理地址,提高空间的利用率。
fPIC即为库的代码所加载到的物理内存与不同进程的共享区的映射关系或所在位置无关。
举个例子:甲乙进行跑步比赛,甲离终点80米,乙离终点60米,要是终点位置变化,甲乙相对终点的距离会变化。终点可理解为物理内存中的库代码,甲乙可理解为两个不同进程,而甲乙相对位置为20米是产生与位置无关码。
gcc -fPIC -c $^
打包动态库
gcc -shared -o $@ $^
上图使用动态库还需要加上-o选项
但运行a.out文件会报错,说这个动态库找不到。
为什么之前动态链接的其他程序可以直接运行呢?因为可以直接找到。
ldd可执行文件
查看库的链接情况,会发现自定义库的路径找不到
环境变量:LD_LIBRARY_PATH 记录默认寻找库的路径。
将自定义动态库导入该环境变量。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:动态库路径
注意:动态库路径不加动态库的文件名
如果同时存在动静态库,编译链接时加上-static选项。
file+可执行文件名 可以查看链接状态。