文章目录
- AMC的了解
- 动静态库
- 1.理论理解
- 2.如何制作一个库??
- 了解
- 实验:制作库
- 交给别人使用
- 生成静态库
- 生成文件 删除文件 发布文件
- 使用静态库?
- 生成动态库
- 使用动态库
AMC的了解
Access:文件最近被访问的时间。
-
我们发现实际操作下来,文件时间貌似没有变化?
在比较新的Linux内核中,Access时间不会立即更新,而是存在一定的时间间隔OS才会自动更新时间。相比于修改文件,访问文件的次数会更多很多,如果一直进行更新时间,可能会造成刷盘的问题让操作系统越来越卡。
Modify:最后一次修改文件内容的时间,当我们修改文件内容的时候,有可能修改文件的属性,比如更改文件的大小属性。
Change:最后一次修改文件属性的时间
- 在更改文件后,makefile和gcc是如何判断文件是被修改的的?根据时间问题
根据可执行程序和文件的时间属性来判断文件是否已经被编译完毕了,指导系统那些文件需要编译。
如果可执行程序的时间更新,就说明已经完成对于文件的编译,Makefile就不让你继续make了。
反之……。
伪目标就是一直被编译,不考虑上述时间属性而touch一个已经存在的文件,就会造成文件的时间的更新,即使内容没有被修改仍然可以重新编译。
动静态库
1.理论理解
-
ldd +可执行程序:显示可执行程序依赖的库。
-
一般库是分两种:动态库和静态库,真正的存在于磁盘上的文件
-
在Linux中,如果是动态库:文件时以.so为后缀。静态库是以.a为后缀的。动静态库本身就是文件!
-
库文件的命名: libXXX.so or libYYY.a库的真是命名:去掉lib前缀,去掉.a-,.so(包含)后缀,剩下的就是库名。
-
gcc默认是动态链接编译,
一般的编译器可能没有内置语言的动态库,而只有动态库。
-
怎么证明命令是C语言写的呢?用到了C语言标准库
Linux操作系统中的指令都会引用到C标准库,如果删除了就会导致系统指令的不可使用。
2.如何制作一个库??
了解
首先,库本身就是第二进制的文件,vim -l /lib64/libc-2.17.so
-
我们如何得知一个库给我们提供了什么方法以及参数细节呢?
一套完整的库包含:1.库文件本身2.头文件3.说明文档。
头文件是文本的,会说明库中暴露出库中的基本使用方法。
-
我们在C中为什么写代码的时候,有时候是.h里面放上声明,.cpp放上实现?
因为我们要制作库!方便使用和安全(给别人的是头文件)
实验:制作库
mytest.c中只包含了.h文件,找得到声明但是找不到.c文件中的实现。
那么如何实现调用test_lib中的文件呢?
-
法一:
-
法二:
注意:1. 将test_lib中的.c文件全部生成.o文件放在当前文件夹。2. $<:是自动依次打开。3.配置Makefile时,%.o 的意思就是将目录下面的所有.o文件一次打开作为依赖对象,汇编之后形成的.o文件叫做目标文件。
交给别人使用
生成静态库
-
提供源代码 + 头文件
我们的 mytest形成是由所有的.o文件项链接,只需要给你提供.o文件也可以实现链接,将所有的.o文件打包就是库文件。 -
我们将自己写的库交给别人使用,我们只需要将生成所有的.o文件交给他就行,源文件不需要交给,给静态库。
-
生成静态库
-
Makefile配置
libmymath.a:sub.o add.o//没找到就先执行下面的生成.o文件的命令 ar -rc $@ $^ %.o:%.c gcc -c $<
ar:将.o文件打包形成归档文件。rc:replace creat 如果没有就创建,如果有就替换。
ar -tv 查看库中的内容
我们将所有的.o文件打包为.a文件,静态库来交给别人实现自己源代码的隐藏。
为了让别人知道我们的库中都实现了哪些方法,我们把.h文件的声明也给他就行了。
-
如果想在生成的过程中也直接安装到系统当中,可以在Makefile后添加:
.PHONY:install install: cp *.h /usr/include cp libmymath.a /lib64
然后执行时make install就行。
-
使用静态库?
原文件包含头文件,直接gcc test.c会发生报错,因为包含的头文件是在lib目录之下,编译器在找的时候只会找统计目录下的.h文件并不会到统计目录中的目录中再去找,也就是说.h文件要和源文件在同级目录下,所以添加-I ./lib告诉他头文件搜索路径,-L指明库文件搜索路径(否则是连接时报错)。而头文件我们在源文件头已经指明包含,但是库你并没指明要连接目录下面的哪一个库名,所以还需要添加-l mymath这个库。
gcc test.c -I./lib -L./lib -l mymath
指明头文件搜索路径 指明库文件搜索路径,指明要连接那一个库。
- 那么我们之前写的代码,为什么没有这些指明选项呢?
之前的库,在系统的默认路径下:/lib64,/usr/lib,/usr/include等编译器是能识别这些路径的 - 如果我不想带这些选项,我们可以把对应的库和头文件拷贝到默认路径下,但是不推荐。
上面的过程就是一般软件的安装过程,使用静态库就完成了。 - 我们给别人交付output的就是一个库文件加一套头文件。
生成动态库
- 交给别人使用,配置Makefile。-shared:形成一个共享库,使得别人使用的时候直接gcc就行。
使用动态库
出现可编译不可执行的问题:
-l mymath 只是告诉了编译器头文件在哪里,当编译好之后,与编译器无关了。想运行时,要有加载器加载到内存,所以运行时要告诉加载器库在哪里。
- 将动态库放到/lib64目录下,不推荐。2. 环境变量LD_LIBRARY_PATH指明程序启动之后,库的搜索路径,默认是没有设置的,设置语句之后你不用加上库的名字,因为在链接的时候就已经指明知道是哪个库了,知道连接什么库只是没找到罢了。
- 环境变量设置之后,再次登录时没有的了,为了让他每次都生效,可以配置全局环境变量。
总结:
我们其实一直在直接或者间接的使用第三方库(C/C++)。
-
如何使用呢?拿着别人的库和头文件,加入到自己的项目中。
-
如何制作呢?
首先,.o可重定向目标文件,每一个.c对应一个.o文件。所有的源代码都需要先被编译为.o文件。
-
可以先把自己的源文件编译为.o文件。
-
制作动静态库的本质,就是将所有的.o打包。使用ar 静态库或者gcc打包动态库。
-
交付include + .a 或者.so文件。
-
静态库:ar -rc。
-
动态库:gcc -fPIC -shared
-
如果只提供静态库,我们只能将我们的库静态连接到我们的程序中。
如果只提供动态库,只能将我们的库采用动态链接 ±static静态连接一下,但是只有动态库是无法这样静态连接的,一般需要提供两个版本的库文件。
gcc g++优先链接动态库,所以你想静态连接必须在Makefile中手动添加-static
如果现在系统中没有安装静态库,/usr/bin/ld:cannot find -lc显示无法找到c库。- 为什么我们之前所写的所有代码都没有/usr/bin/ld :cannot find -lc报错呢?默认是动态的,因为我们之前一定有动态库。因为系统中的很多命令是用C语言写的,而且是动态链接。
使用外部库:
系统中有很多库通常由一组互相关联的用来完成某项常见的工作的函数构成。比如,
- pow(a,b);求a的b次方,包含#include<math.h>,-lm表示要连接libm.so或者libm.a库文件。