一、 静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库,因为他已经在你字节写的程序中。
编译静态库
将所有的.h文件拷贝到lib/include中,是为了实现头文件的包含,里面是方法的声明,将所有.a文件拷贝到lib/mymathlib中,里面是各种静态库。
生成静态库使用ar -将.o文件生成静态库
[root@localhost linux]# ar -rc libmymath.a add.o sub.o
ar是gnu归档工具,rc表示(replace and create)
在当前目录下创建test目录,然后进入test目录将上级目录的lib拷贝到test目录下
main.c程序使用带路径的头文件,但是却是找不到方法的实现,而且这样带路径的头文件一般是不常用的。然后直接使用头文件又会发生找不到的现象
可以使用-I链接找到头文件所在路径
给出头文件所在的路径在编译链接时会去这个路径下搜索头文件,并且不需要指出需要哪一个头文件因为在源文件中已经指出需要的头文件。若是没有指出头文件路径,那么会去系统指定路径下查找若是都找不到就会出错,然后还可以将头文件的路径拷贝到当前路径下,一般你在哪一个路径下创建的头文件他会去当前路径搜索,不过这是别处拷贝过来的,可以将头文件拷贝到当前路径下。
在链接时就不会在指定链接头文件的路径,只是找不到方法的实现,链接头文件已经就绪,接下来链接库
链接库需要先找到库所在路径然后还要指定链接哪一个库,因为使用时就算知道了路径但是这一个路径下可能会存在多个静态库,所以需要指定库名 用-L指定库路径,然后-l指定库名,不过静态库链接是需要去掉前缀和.a后缀,一般是l仅紧紧跟着库名
第三方库在使用的时候必定要使用gcc -l
库名=去掉前缀和后缀若是不想这么做应该将库和头文件安装到系统目录下(建立软链接)
查看一个可执行程序的链接库
它的链接库是.so,gcc默认链接库是以动态链接的方式链接,当有动态链接又有静态库,它会首先链接动态库,若是没有提供动态库,gcc会以静态链接的方式链接静态库,若是系统中有两者都有,可以用-static链接静态库。
直接用库,将其拷贝到系统路径下
将当前路径拷贝到系统路径下,普通用户需要提权
把头文件和库文件拷贝到系统路径下,那么直接gcc编译时就不会报错了,不过还是要指定链接库名
将来用其他人使用的库都是要先将库的地址拷贝到自己系统路径下,为库的安装!
不拷贝头文件和库文件安装直接用,可以使用软链接
建立软链接到系统路径下,建立到系统路径下都是需要提权的
建立软链接在使用时使用软链接即可。链接头文件和库到系统路径下这样不用每次gcc时都要使用很长的路径,不用这么麻烦使用起来方便!库要使用时将其拷贝到系统搜索路径下!
二、动态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
多个源文件形成动态库,即形成动态库又形成静态库
源文件编译成.o文件然后形成库!先源文件形成.o文件
-fPIC形成与位置无关码
把.o文件打包形成库,形成静态库是ar,形成动态库是gcc直接编译,将所有.o文件形成一个库需要用到shared形成一个共享库
动态库带着可执行的动态库要和可执行程序产生关联,也就是动态库要被加载,以可执行程序的方式加载到内存!他不能单独执行,并不是不能执行。即形成静态库有形成动态库在makefile中all,所有的都形成每一次都执行.PHONY:all
打包成库之后别人就可以使用
库中没有main函数
使用动态库也和静态库一样的,同样要找到路径然后链接库
链接动态库之后不能立即使用这个可执行程序,它要结合动态库才可以出结果,它要去找到动态库,因为它的实现在动态库中
not found
要告诉动态库在哪
把动态库拷贝到当前路径下,再gcc一次就可以执行了
程序形成和编译器没关系了,要去找动态库,所有动态库在哪里要告诉系统系统充当一个加载器的工作!那么这怎么找到动态库可以将动态库拷贝到系统路径下,系统去找的时候就去搜索路径下搜素即可–>建立软链接
对于一个程序加载器找不到动态库的方法:
1.建立软链接在系统路径/usr/lib64/
2.拷贝到系统默认路径/usr/lib64/下
3.将动态库添加到环境变量LD_LIBRARY_PATH中
LD_LIBRARY_PATH是动态库的搜素路径,可以将动态库路径加到环境变量中。
4./etc/ld.so.conf.d建立自己的动态库路径的配置文件,然后重新ldconfig即可,把动态库路径添加到配置文件中即可,这个配置文件中添加的是永久有效的!
这么多种方法,其实在用别人库的时候是用最简单方法直接安装到系统(拷贝)就可以了!
使用外部库
系统中其实有很多库,它们通常由一组互相关联的用来完成某项常见工作的函数构成。比如用来处理屏幕显示情况的函数(ncurses库),图形化界面的操作。
动态库在运行的时候是要被加载到内存的,而一个动态库会被多个源文件使用,常见的动态库被所有的可执行程序都要使用在动态链接时,这个动态库啊就是一一个共享的库,当将一个动态库给删除之后,那些与这个动态库相关的可执行程序都不能执行,共享库失去所有依赖共享库而生的可执行程序就不再能够执行它的功能,所有动态库在被加载之后,会被所有进程共享!!并且这个动态库不会被重复加载加载一次就够了,就像是一个共享区而在操作系统中可能存在多个共享库操作系统同样要对共享库管理!动态库共享是如何做到的?
动态库是一个文件,磁盘中的普通文件,他把所有的.o文件打包程库,然后这个库加载到内存中,在加载到内存中时并且将库的物理地址经过页表映射到进程地址空间中的共享区中这样就达到在进程地址空间上对共享库访问。所有建立映射之后,在执行任何代码时都是在我们的进程地址空间中进行执行,函数跳转即可。那么怎么跳转到共享库?共享库中有起始地址,然后库函数的地址相对于共享区的地址是一个绝对地址经过地址偏移就可以使跳转成功!