动态库和静态库

简介: 动态库和静态库

文章目录


时间

Access:文件最近被访问的时间,

Modify: 最近一次修改文件内容的时间

Change:最近一次修改文件属性的时间

Change time


修改文件内容的时候,有可能也会修改文件的属性

比如: 可能会更改文件的大小属性



我们会发现操作下来, 文件时间貌似没有变化:

在较新的Linux内核中,Accsee中不会被立即刷新更新,而是有一定的时间间隔进行刷新


makefile更新的机制


makefile and gcc 会根据时间问题,来判定源文件和可执行文件次序谁更新,为就以谁为主

如gcc test.c -o test

如果test的modify时间比test.c的modify时间新,说明就已经更新了,反之,如果test.c的时间比test的时间新,说明makefile需要更新

对于这种伪目标的,他总是被执行,因为他不关心时间

touch会更新文件的时间,我们重新make也可以


静态库和动态库

查看可执行程序依赖库ldd 【可执行文件】

第二个是c标准库,我们查看了一下,发现是软链接,

我们发现这个文件也是有inode


linux当中,一般库分为两种: 动态库和静态库(库也是一个文件)

在Linux中,如果是库文件:库文件一般是以.so作为后缀的,如果是静态库,一般是以.a为后缀的


1.库文件的命名:

::libXXX.so- or libYYY.a-

2.库的真正名字

去掉包含lib前缀,去掉包含a-,so-的后缀

如/lib64/libc.so.1真实名字就是c

/lib64/libc-2.17.so真实名字就是c-2.17


c++标准库

也可以使用file查看连接库的情况

动态库只有一个,删除的话,其他文件都无法使用了

如何制作库

库本身就是一个二进制文件,

一套完整的库:

  1. 库文件本身
  2. 头文件.h(文本,会说明库中暴露出来的方法的基本使用!)
    我们在C/C++ 中,为什么在写代码的时候,有时候.h里面放上声明,在.c里面放上定义,为什么要这么设计


  因为我们要制作库!

  1. 方便使用 2. 私密,比较安全,用库对头文件进行封装保护,

  • 我们在other目录下面写一个add.cpp add.h这两个,一个声明,一个定义
  • 如果我们想要使用的话,要加上这个库的路径
  • 编译的时候

    添加上特定的路径中的定义,才能使用

如果没有库,我们想要编译要怎么编译呢

 mytest:%.o
      gcc -o $@ $^
 %.o:%.c
      gcc -c $<  

,o是我们汇编之后生成的

所以%.o 依赖所有的%.c

$<就是把上面的所有东西展开,一个一个的进行编译

  1 obj=mytest.o add.o sub.o
  2 
  3 mytest:$(obj)
  4     gcc -o $@ $^
  5 %.o:%.c
  6     gcc -c $<
  7 
  8 %.o:./other/%.c
  9     gcc -c $<    

先形成3个.o文件,最后在链接形成可执行

如果我们想把自己的代码给别人用

  1. 提供源代码+头文件
  2. 只提供.o文件也可以链接,所以库的思想:就是把所有的.o打包就是库了


打包成一个库

  1. 所有的源代码要先被编译成为.0文件(可重定向文件)
  2. 制作动静态库的本质就是将所有.0打包好,使用ar 或者gcc来打包
  3. 交付: inlcude + .a or .so文件


ar (类比tar)

-rc(replace and creat)查看静态库中的内容

libmymath.a:sub.o add.o
    ar -rc $@ $^  //把所有的.o文件都打包成一个静态库
%.o:%.c
    gcc -c $<   //把所有的.c都展开成.o文件



我们可以查看c标准静态库中的内容都是.o



这样我们就把我们自己的源文件都隐藏起来

别人想要用我们的库,就还需要一些头文件,因为二进制根本看不懂

所以我们可以发布一个output

PHONY:output
output:
    mkdir output 
    cp -rf *.h output 
    cp libmymath.a output


头文件和库文件都在

使用自己的库

#include"add.h"
#include"sub.h"
int main()
{
    int x=10;
    int y=2;
    int y1=add(x,y);
    printf("y1=%d" ,y1);
    return 0;
}
$ gcc demo.c -I./output -L./output -lmymath

这样编译才可以

-I 指明,我们要使用知名头文件搜索路径

-L 指明:我们要指明库文件的搜索路径

-l 指明:我们要链接那一个库


我们之前写的代码,也用了库,为什么就没有指明选项呢??

之前的库,在系统的默认路径下,/lib64,/user/lib,/user/include等

编译器是能够识别这些路径的,


换一句话说我们如果想不添加这些选项,我是不是可以把对应的库和头文件,拷贝到默认的路径之下

没有问题的,这也就是一般软件的安装过程


我们给别人交付的其实就是一个库文件+ 一套头文件

形成动态库

libmymath.so:add.o sub.o
  gcc -shared -o $@ $^ 
%.o:%.c
  gcc -fPIC -c $<
.PHONY:clean
clean:
  rm -f libmymath.so
.PHONY:lib 
lib:
  mkdir lib
  cp *.h lib
  cp libmymath.so lib

编译使用的方法和静态库一样的

我们在加载的时候,还要进一步高树系统,我们的库在哪里,因为动态库我们编译的时候需要,不编译的时候就不需要,不像静态库是一次性直接拷贝进去,在编译的时候就不需要去考虑库在哪里


编译

$ gcc x.c  -o x -I./lib -L./lib -lmymath 

导入环境变量

export LD_LIBRARY_PATH=/home/xvzewen/githubgovern/Linuxstudy/link/friend/lib

执行

./x

为什么我们之前写所有的代码都没有报错呢??

默认情况下我们都是动态的,因为我们一定有动态库!,因为我们linux很多都是用c语言写的

相关文章
|
编解码 缓存 算法
视频帧里的I帧、P帧、B帧是什么?
I帧、P帧、B帧是视频编码中的基本概念。I帧是帧内编码帧,无需参考其他帧即可解码;P帧是前向预测编码帧,基于前一帧解码;B帧是双向预测编码帧,基于前后帧解码。IDR帧是一种特殊的I帧,用于即时解码刷新,防止错误传播。GOP(Group of Pictures)是一组连续的画面,第一个帧为I帧,gop_size设置越大,画质越好,但解码延迟增加。OpenGOP允许GOP间的帧依赖,而ClosedGOP则不允许。DTS(解码时间戳)和PTS(显示时间戳)分别用于解码和显示时间控制。
|
机器学习/深度学习 运维 监控
高效运维:从自动化到智能化的演进之路
在当今信息技术飞速发展的时代,运维作为保障信息系统稳定、高效运行的重要环节,正经历着从传统手工操作向自动化、智能化转变的历史进程。本文将探讨自动化运维的实践价值与实施策略,阐述智能化运维的理念框架及其关键技术,并通过案例分析揭示这一演进路径如何助力企业提升运维效率、降低运营成本,并增强对复杂系统的掌控能力。通过深入剖析,本文旨在为读者呈现一幅从自动化迈向智能化的运维全景图,为寻求运维转型的企业提供参考与启示。
|
Unix Linux C语言
CentOS 7.6 编译安装最新版本glibc2.30 实录
基于CentOS上安装ScyllaDB数据库的朋友应该都会遇到glibc必须为2.28及以上版本的问题,哈目前阿里去上提供的最高版本CentOS7.6中的glibc版本为2.27,所以必须要升级,但升级glibc并不是一件容易的事,如果操作不当还会影响一些API和服务的正常运行,所以在升级之前请先做好备份。
|
移动开发 JavaScript 前端开发
为什么我们放弃了Vue?Vue和React深度比较
我使用Vue和React已经很长一段时间了,两个框架上实践代码量都在10万行以上。不得不说都是都很不错的,帮助开发者减少很多工作量,某种框架是现代化Vue和React在两者之间的选择并不像选择苹果或香蕉一样简单,两者在工程实践上的差异让我们逐渐放弃了Vue。此处以不一样的角度对彼此进行深度对比。
|
搜索推荐 算法 数据挖掘
淘宝如何拥抱短视频时代?视频推荐算法实战
本文就目前推荐算法的巨大潜力空间下,先是分析了整个行业短视频业务和淘宝段视频业务现状。而后就视频推荐算法框架以及基于视频的召回和视频排序做了详细的讲解。最后说明了业务策略的几个要点。
2909 0
淘宝如何拥抱短视频时代?视频推荐算法实战
|
SQL 存储 缓存
|
2天前
|
数据采集 人工智能 安全
|
11天前
|
云安全 监控 安全