• Linux动静态库


    静态库

    程序在编译链接的时候,直接将该库拷贝一份到源文件,运行的时候不再需要该静态库。
    静态库的命名方式:以lib为前缀,以.a为后缀。

    制作静态库并发布

    1.把函数声明都放在一个或多个.h的头文件里
    2.把.h中的声明的函数实现放在.c文件里
    3.把这些.c文件生成.o文件
    4.把生成的多个.o文件打包放到.a文件里(其实.o文件就可以直接与我们的源文件进行链接形成可执行程序了,但为了方便使用,我们把多个.o文件打包放到了.a文件里)
    生成的库名称
    声明生成的库名字为libmymath.a

    #形成的库名字叫做libmymath.a
    lib=libmymath.a
    
    • 1
    • 2

    将.c文件生成.o文件

    # gcc命令只加$^ 默认把.c文件形成与$@同名的.o文件
    div.o add.o:div.c add.c
    	gcc -c $^
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    将.o文件打包放到静态库.a文件里

    #ar是生成静态库的命令 生成的库依赖的是.o文件
    $(lib):div.o add.o
    	ar -rc $@ $^
    
    • 1
    • 2
    • 3

    ar命令是打包命令,意为将$ ^文件都放到$ @文件里,
    这里的$ ^文件为div.o和add.o,$@文件为库文件libmymath.a
    在这里插入图片描述
    发布
    就是创建一个目录,用来存放头文件目录include和库文件目录,分别用来放头文件.h和库文件.a(.a文件里放的是.o文件集合)

    .PHONY:output
    output:
    	mkdir -p lib/include
    	mkdir -p lib/mymathlib
    	cp *.h lib/include
    	cp *.a lib/mymathlib
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    清除

    .PHONY:clean
    clean:
    	rm -rf *.a *.o lib
    
    • 1
    • 2
    • 3

    静态库可不可以不包含头文件呢?
    不可以,因为头文件是这个库文件所提供的方法的说明书,你不提供,使用者就不知道这个文件里有哪些方法,怎么去调用
    lib目录里面放的是库的集合
    Makefile文件

    #形成的库名字叫做libmymath.a
    lib=libmymath.a
    
    #ar是生成静态库的命令 生成的库依赖的是.o文件
    $(lib):add.o div.o 
    	ar -rc $@ $^
    
    # gcc命令只加$^ 默认把.c文件形成与$@同名的.o文件
    div.o add.o:div.c add.c
    	gcc -c $^
    
    .PHONY:clean
    clean:
    	rm -rf *.a *.o lib
    
    .PHONY:output
    output:
    	mkdir -p lib/include
    	mkdir -p lib/mymathlib
    	cp *.h lib/include
    	cp *.a lib/mymathlib
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    通过为 gcc 指令添加 -c 选项(注意是小写字母 c),即可让 GCC 编译器将指定文件加工至汇编阶段,并生成相应的目标.o文件

    如何使用第三方静态库

    方式一

    直接将已发布的第三方静态库拷贝到当前目录下
    在这里插入图片描述
    在这里插入图片描述

    1.先把库集合lib目录文件拷贝到当前目录下,不拷贝也行只要你能找到
    2.生成可执行程序
    生成可执行程序要指明要链接的库的路径和头文件,
    大I选项:用于指明头文件路径

    -I ./lib/include/
    
    • 1

    大L选项:用于指明要链接的库,需要在哪个路径下去搜索

    -L ./lib/mymathlib/
    
    • 1

    小l选项:用于指明要链接哪一个库
    这里的库名是libmymath.a,但库的真实名字是去掉前缀去掉后缀,留下来的才是真实的名字
    一般建议小l后面紧跟真实的名字

    -lmymath
    
    • 1

    1.为什么头文件指明搜索路径就可以了?不需要再指明具体是哪一个.h头文件呢?
    因为在.c源文件中我们已经指明了要包含哪一个头文件,例如这里的#include “add.h”
    2.源文件默认只会在当前路径下进行搜索或者默认的库路径下去搜索,当前路径是指在同一级别,main.c和lib是在同一目录下,但是和lib下的文件,就不属于同一目录级别的了,系统默认不会去搜索,因此需要我们手动的带选项去指明要去搜索的路径,且要指明要链接该路径下的哪一个文件。
    在这里插入图片描述
    -L 指定库路径
    -l 指定库名
    测试目标文件生成后,静态库删掉,程序照样可以运行

    方式二:

    将第三方库拷贝到默认库路径下
    头文件:
    拷贝到系统库文件/usr/include/下
    在这里插入图片描述
    库文件:
    拷贝到系统文件/lib64/路径下
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    注意即使拷贝到系统默认路径下了,也要指明要链接的库名称

    方式三

    建立软链接,链接到系统路径下
    这里要求把路径带全

    在这里插入图片描述
    在这里插入图片描述
    在生成可执行程序时,要指明要链接的库的名称

    动态库

    制作动态库并发布

    动态库的生成和发布与静态库,基本没有什么相同
    不同的是:
    1.动态库我们也以lib开头但以.so为后缀,与静态库进行区分。
    2.生成的库为共享库
    shared: 表示生成共享库格式
    fPIC:产生位置无关码(position independent code)
    库名规则:libxxx.so
    3.编译阶段使用动态库
    编译选项
    l:链接动态库,只要库名即可(去掉lib以及版本号)
    L:链接库所在的路径.
    库名为libmymethod.so
    生成可执行程序示例: gcc main.c –L… -I… -lmethod
    4.链接动态库方式有所不同
    1、拷贝.so文件到系统共享库路径下, 一般指/usr/lib64
    2.在系统默认的库路径下建立软链接 /usr/lib64
    3、将自己的库所在的路径,添加到系统的环境变量 LD_LIBRARY_PATH
    4、ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

    链接动态库

    方式一

    拷贝.so文件到系统共享库路径下, 一般指/usr/lib64

    在这里插入图片描述
    在这里插入图片描述

    方式二

    在系统默认的库路径下建立软链接 /usr/lib64

    方式三

    在这里插入图片描述

    将自己的库所在的路径,添加到系统的环境变量 LD_LIBRARY_PATH中
    在这里插入图片描述

    在这里插入图片描述

    方式四

    /etc/ld.so.conf.d/下建立自己的动态库路径的配置文件,然后重新ldconfig(这是更新配置文件命令)即可
    在这里插入图片描述

    生成共享库参数

    shared: 表示生成共享库格式
    fPIC:产生位置无关码(position independent code)
    库名规则:libxxx.so
    我们来了解一下产生位置无关码的fPIC是什么

    动静态库总结

    动静态库其实在使用上基本类似,不同点是
    静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
    动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。

  • 相关阅读:
    从裸机启动开始运行一个C++程序(八)
    【文末送书】2023年以就业为目的学习Java还有必要吗?
    uniapp 去掉默认导航栏
    抖音小店运营大全,从0到50W ,不用直播不拍视频猜你喜欢干货玩法
    集群所有进程查看脚本xcall.sh
    计算机网络常见概念
    CGLIB动态代理对象GC问题排查
    丐版设备互联方案:安卓linux互联局域网投屏,文件共享,共享剪切板
    【深度学习】Transformer
    2022-2028全球监控光电二极管(MPD)行业调研及趋势分析报告
  • 原文地址:https://blog.csdn.net/weixin_61488314/article/details/134358245