序言
创建软链接和硬链接
不能为目录创建硬链接
为什么会这样?
在linux中,对于每一个目录文件最终都有指向根目录的指针,如果硬链接指向一个目录,那么最终有可能形成环形路径
软链接是一个链接文件,硬链接是一个普通文件,这也说明硬链接文件如果是目录文件,那么这个文件可能在中途被当做普通文件使用
这也会导致不可避免的事发生,所以系统也不允许建立硬链接
而对于这个. 和…这两个文件就是系统规定的两个硬链接(唯一的两个)
ACM时间:
access 最后访问时间
modifiy 文件最后修改时间
change 属性最后修改时间
静态库
在文件编译链接时,把库的代码连接到可执行文件中,程序运行不再需要静态库
本质就是将库中的源代码直接翻译成.o目标二进制文件, 进行打包
如何制作一个库?(以完成一个计算器为例)
补充:库内没有main函数
现存在这样的一个项目,存在很多的.c,.h文件,所以直接编译
gcc -o test Add.c Mul.c Div.c Sub.c
可是这样存在的问题就是每一个.c文件都会形成编译汇编链接这样的步骤,所以建议
将所有的.c文件进行编译形成.o文件然后进行链接
这也是vs编译器下会存在很多.obj文件的原因
这样的好处在于多语言环境下,直接将.o文件进行链接就能形成所需的个性化功能
%.o:%.c
gcc -c $< //将所有的.c文件通过gcc -c选项编译成对应的.o文件
补充:在编译时gcc -c sub.c会自动生成对应的.o文件
但实际上用户的使用程序并不需要.c文件,只需要这些.o文件即可
将这些.o文件进行打包,链接到自己的可执行程序即可
使用gcc *.o 形成可执行程序
可是当.o文件很多就不方便,所以进行打包
使用 ar指令 将所有的.o文件打包形成库文件
ar -rc $@(目标) $^(源)
rc代表replace and creat
怎么使用静态库?
gcc 含有main的.c文件 -l静态库名 -L路径
针对第三方库要指明库的静态库名和路径
静态库名 libmymath.a 去掉lib,去掉.a后缀,这个静态库名称是mymath -l紧跟静态库名称 -L紧跟路径
这只是针对第三方库
ldd
查看一个可执行程序依赖的动态库文件
静态库已经到可执行程序里了,不可查
一个程序默认是动静态混合链接的
-static选项可选
没有-static表示静态库文件已经在可执行程序里面了
有-static必须全部都使用静态库,最终形成一个可执行的静态程序
默认使用动态链接的
对于一个没有-static选项时,有静态库会默认添加进去
如果没有动态库 只有一个默认的静态库加到这个程序中去
gcc默认是动态链接的
但个别库只提供静态库,只能局部性的将指定的.a进行链接
同时为了方便将这些.c文件都放在include文件下面,将所有的.h文件放在lib文件下面
这一步使用makefile来完成
演示结果:
查看mymath_lib的目录
将来想把这个项目打包发给别人可以tar czf
同样的,将来得到一个.tgz的压缩文件,怎么去使用呢?
tar xzf mumath_lib.tgz 进行解压缩文件
将这个文件进行解压
系统头文件在/usr/inclcude下
库文件在/usr/lib64目录下
将这个对应的头文件和库文件拷贝到系统对应的目录下就叫做安装了
但是这样相当于污染系统环境
所以使用的时候直接""这样包含头文件就行
不过这样要带上绝对路径很麻烦
要想直接#include “Add.h”
且Add.h不在当前路径下面,那么必须要
gcc test.c -I mymath_lib/include
-I头文件路径
-l库文件名称
-L库文件路径
连起来,知道一个解压好的静态库文件,知道头文件,main文件已经写好,只差链接这一步,应该怎么c操作呢?
gcc TestMain.c -I mymath_lib/include -l mymath -L mymath_lib/lib
如果这个库被拷贝到系统路径下面了,那么这个-I 和 -L 的选项就不用做了
动态库
程序在运行时才去链接动态库的代码,多个程序共享使用库的代码
如何制作动态库?
与静态库一样,需要将所有源文件编成.o将所有的.o文件进行打包
细节:
1.编成的.o文件
gcc -fPIC -c *.c //fPIC表示产生位置无关码(稍后解释)
2.进行打包(形成共享库)由此可见,动态库是更需要的一种需求,gcc不仅能编译源程序,更能打包生成动态库文件
gcc -shared -o libmymath.so
动态库生成
PS:讲一个文件内容进行备份
mv makefile makefile.backup
cp makefile.backup makefile
这样原先的makefile和makefile.backup的内容一样,完成备份
生成:
此时对应的头文件和库文件就存在了
打包使用与静态库一样.
现在,现在对这个动态库进行编译
生成了a,out,运行
出错了???
动态库和可执行程序是分离的,所以程序运行必须同时找到并加载可执行程序和库的位置
动态链接很依赖动态库
使用ldd 查看这个程序依赖的动态库
可以看到这个可执行程序找不到依赖的动态库,所以要给定确切的路径
总结:
动静态库在编译形成链接.o
文件时不同
在执行程序要对动态库制定动态库文件
这两点不一样
四种方法
1.将头文件和库文件放在系统路径下
这时在进行编译就没有编译不同的原因,而是提示库文件找不到
库文件找不到,接下来只要进行库文件的链接即可
这个库文件也能找到
以上均为实验,现在删除自定义库文件,头文件,防止污染系统
删除成功
2.软链接方式
当然可以选择将软链接文件放在系统路径下面(这边的路径建议从~路径开始 放置位置从/lib64开始)
同样,为防止污染系统,去掉这个软链接
方法三:LD_LIBRARY_PATH(加载库环境变量)
将库添加到环境变量
当执行程序的时候,./a.out说明程序已经找到,是库文件找不到
OS除了会去lib64找,还会去LD_LIBRARY_PATH下找
导入环境变量(只需要添加文件路径即可(跟win一样))
方法三在下次登录时就没有了,因为那个只是内存级,
方法四:
直接更改系统关于配置库的加载文件
这个文件的存放处在/etc/ld.so.conf.d/
可以看到里面的文件内容只有一行数据
所以直接添加一个文件,将库路径输进去就行
有时候不立即显示,所以ldconfig,刷新一下
这种下,退出进去还是有效的
同一个库同时提供动静态库,默认使用动态库
除非
gcc TestMain.c -I mymath_lib/include/ -lmymath -L mymath_lib/lib -static
使用静态库加载程序
关于fPIC 形成位置无关码(下章见分晓)~~~
创作不易,来个三连支持一下吧~~~