当前位置:   article > 正文

Linux动静态库的创建和使用_linux persist. 保存路径

linux persist. 保存路径


一、动静态库的概念

在写C语言程序的时候,都知道要包含头文件,才能使用printf、scanf等库函数,为什么没有实现这些函数就可以使用呢?

C语言程序的编译过程熟知的四个步骤:预处理、编译、汇编、链接。经过前面三个步骤形成的目标文件(二进制文件)需要经过最后一步链接形参可执行文件。

本质上库就是一个目标文件,它里面包含了库函数的实现,最后和我们自己写的文件(包含系统的头文件)链接起来就可以使用库函数了,这样程序就可以正常执行了。

Linux下常见的库有分为两种,静态函数库(简称静态库)和动态函数库(也称为共享函数库,简称动态库或共享库)。它们有什么区别呢?

1.1 动静态库的区别

动态库:

  • 以.so结尾
  • 命名规则: 例如 libxxxx.so 这个库, 库名是xxxx,库名前需要加lib,后缀为.so
  • 特点: 动态库没有编译进可执行程序,而是程序运行时动态的申请调用使用到的函数,
  • 优点:实现进程的资源共享,当程序在运行的时候需要调用某个动态链接库函数时候,OS会先查看所有正在运行的程序,看内存里面是否已经有此函数的拷贝了,有责共享那个拷贝,没有才会链接载入,这样会大大节省OS的内存资源;
  • 升级容易,升级动态链接库即可,不需要重新编译可执行程序;
  • 缺点:程序不可独立运行

静态库:

  • 以.o结尾
  • 命名规则: 和动态库类似,例如 libxxxx.o 这个库, 库名是xxxx,库名前需要加lib,后缀为.o
  • 特点: 静态库的链接是将整个函数库的所有数据都整合进了目标代码,编译后的执行程序不在需要外部的函数库支持,可独立运行。
  • 优点:编译后,可执行文件不需要外部支持;
  • 缺点:生成的可执行程序大;静态库改变了,就需要重新编译可执行程序。

1.2 动静态库的基本使用

使用命令ldd 可执行文件就可以查看它依赖的库。
在这里插入图片描述
使用file命令(查看文件类型)也可以看到使用的是动态链接
在这里插入图片描述
可以看出来,默认情况下,编译器自动使用动态库链接,若要链接静态库需要在编译命令后面添加 -static 选项

如果报错的,需要安装静态库sudo yum -y install glibc-static 。可以看到它没有了依赖的库,因为需要的已经全部拷贝进程序里面。
在这里插入图片描述
静态链接生成的可执行文件比动态链接生成的文件大很多。
在这里插入图片描述

二、自定义动静态库的创建和使用

一套完成的库,包含三个部分

  1. 头文件.h , 头文件用来说明库中暴露出来的方法的使用
  2. 库文件本身, 即对应函数的实现编译为.o目标文件
  3. 说明文档,如何使用库

所以,制作一个简单的库只需要将.o文件打包,加上对应头文件即可使用。

2.1 静态库的创建

假如向创建一个数学库,里面简单的实现加减法。

  1. 实现库内容代码:可以先写出对应功能的代码,用.h声明函数,对应.cpp文件实现,得到四个文件

在这里插入图片描述
对应的内容
在这里插入图片描述

  1. 再生成对应的.o文件: 命令 gcc -c add.o add.cgcc -c sub.c -o sub.o

  2. 打包形成库:现在就有了创建库的基础条件了,创建名为math的静态库
    创建静态库的命令:ar -rc libmymath.a add.o sub.o
    ar是gnu归档工具,rc表示(replace and create) 这样就可以的到 libmymath.a 静态库了。

  3. 发行:为了方便管理或者给其他人使用库,可以创建一个文件夹,存放库和头文件。

上面的步骤是很麻烦的在Linux下可以使用make快速完成

编写对应的makfile

libmymath.a:add.o sub.o
  ar rc $@ $^
*.o:*.c
  gcc -c $<  # 对每个依赖文件执行                                                                                            
.PHONY:clean                   
clean:    
  rm -rf libmymath.a *.o output    
.PHONY:output    
output:    
  mkdir output     
  cp *.h output     
  cp libmymath.a output  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述
命令ar -tv libmymath.a 可以查看库里面的目标文件
t : 列出静态库中的文件
v : verbose 详细信息
在这里插入图片描述

2.2 静态库的使用

假设朋友文件需要使用我们的库,直接把发行拷贝到他的目录下例如:
在这里插入图片描述
将output文件名改为lib更加具体
在这里插入图片描述

  1. 查阅静态链接库的.h文件
    获取发布的静态链接库后,查看.h文件,看静态链接库的各个函数功能和函数声明。

  2. 使用静态链接库的某个函数
    使用静态链接库时需要声明静态链接库的.h文件

#include "add.h"    
#include "sub.h"    
      
  int main()    
  {    
    int x = 10, y = 5;                                                                                                       
    printf("add: %d\n",add(x, y));                
    printf("sub: %d\n",sub(x, y));                
    return 0;                                     
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 编译文件

编译工程文件时,需要在编译链接时添加相关选项:

  • -Ipath: 表示在path路径下搜索头文件
  • -Lpath:表示在path路径中搜索库文件
  • -lxxx:表示要链接的静态链接库为libxxx.a ,记住是库名,不是库文件名
  • -static:表示将所有链接的库静态加载
    在这里插入图片描述
    之前写C语言不用加路径,是因为头文件和库文件在默认的路径下,编译器能够自动识别。

2.3 动态库的创建

在这里插入图片描述

  1. 编写源码库文件,与上面相同
  2. 编译源码库文件
    gcc -fPIC $<生成目标文件
    -fPIC选项的作用是使得gcc生成的代码是位置无关的
  3. 生成动态链接库
    gcc -shared -o $@ $^
    生成动态链接库文件
    -shared选项告诉编译器生成一个动态链接库
  4. 发行成一个真正的库

2.4 动态库的使用

假设有第二个朋友要使用
在这里插入图片描述

在这里插入图片描述

前三步静态库相同

  1. 查阅动态链接库的.h文件
  2. 使用动态链接库的某个函数
  3. 编译文件
    编译工程文件时,需要在编译链接时添加相关选项:
  • Ipath: 表示在path路径下搜索头文件
  • -Lpath:表示在path路径中搜索库文件
  • -lxxx:表示要链接的静态链接库为libxxx.a ,记住是库名,不是库文件名

在这里插入图片描述
发现可以编译但是不能运行,这就是动态库,编译和运行都到指定位置取,Makefile里面只指定了编译查找的路径,但是动态库运行的时候也需要去找,所以就需要第四步。

  1. 运行动态库,一般有三种方法

    • 拷贝.so文件到系统共享库路径下, 一般指/usr/lib 这样就可以自动查找,但是不推荐,容易出错。
    • 更改 LD_LIBRARY_PATH 环境变量,它可以指明程序启动后,库的搜索路径,默认没有配置。
      在这里插入图片描述
      环境变量定义好了。
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    1. ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
      在这里插入图片描述
      创建一个文件写入刚才的路径,但是要root
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

这样就可以使用动态库了。


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/605964
推荐阅读
相关标签
  

闽ICP备14008679号