首页 > 系统相关 >linux——动静态库

linux——动静态库

时间:2024-11-26 19:32:07浏览次数:10  
标签:文件 静态 当中 linux 动态 环境变量 加载

Linux——文件系统清尾、动静态库-CSDN博客


文章目录

目录

文章目录

前言

一、静态库使用

静态库使用方法:

二、动态库

1.创建动态库

 打包:

伪目标 .PHONY

​编辑

2.使用

3、解决动态库的加载问题

三、共享库

动态库是怎么做到对所有进程进行共享的?


前言

在上一篇博客中,已经解释动静态库的概念

在上一篇博客中已经创建了一个静态库,并且使用了一下静态库。

库搜索路径

从左到右搜索-L指定的目录。

由环境变量指定的目录 (LIBRARY_PATH)

由系统指定的目录

/usr/lib       

/usr/local/lib

/lib64/

1、第三方库,在往后使用时,必须要用gcc -l 来指定文件名;

2、深度理解errno本质;

3、查看动静态库链接

ldd a.out

4、gcc 默认是动态库链接,如果没有动态库,只能用静态库链接;

5、如果需要链接多个库,gcc可以链接多个库;

6、当我们把头文件加载到了系统文件当中,就不用再指明路径了。但是需要加-l指明文件名;

7、软硬链接 ln -s 目标路径


一、静态库使用

静态库使用方法:

 1、指令 gcc main.c -I 指定头文件路径 -L 指定方法路径 -l方法文件名

这个方法在上篇博客已经介绍过了。

2、将目标路径加载到系统文件加当中,也就是将静态库mv或者cp当系统文件当中;

将头文件拷贝到/usr/include当中

将静态库拷贝到/lib64/

 

3、添加软链接,将目标文件软链接到系统文件当中。

 

 为什么还是报错呢?因为我们main函数中包含的是没有math.h这个文件,而我们链接文件名为myinc,main函数中也就需要更改;

以上就是静态库的所有用法 

二、动态库

1.创建动态库

创建mylog.c mylog.h myprint.c myprint.h

mylog.c

#include "mylog.h"

void Log(const char*info)
{
    printf("Warning: %s\n", info);
}

 mylog.h

#pragma once

#include <stdio.h>


void Log(const char*);

 myprint.c

#include "myprint.h"


void Print()
{
    printf("hello new world!\n");
    printf("hello new world!\n");
    printf("hello new world!\n");
    printf("hello new world!\n");
    printf("hello new world!\n");
}

myprint.h

#pragma once

#include <stdio.h>


void Print();

 创建好了进行打包

无论是动态库还是静态库,我们都要的是.o文件

用.o文件进行链接

动态库生成.o命令:

gcc -fPIC -c 要编译文件

fPIC:产生位置无关码(position independent code)

这里我们将动态库和静态库分开,那么mymath.o是用不上的。rm 掉。

 打包:

方法一:命令行方式

打包命令

gcc -shared -o 目标文件名.so *o

shared: 表示生成共享库格式

gcc提供了动态库打包指令

静态库需要借助第三方工具 ar

这个文件是跑不了的,它连main函数都没有。

静态库再别人使用时是不需要加载到内存的,当编译时,编译器将静态库以二进制的方式拷贝过来。

动态库再使用时,是需要加载的,需要加载到内存,和我们的程序形成关联,我们要用动态库的函数时,会跳转的动态库当中。所有我们的libmymethod.so是带有x权限的;

方法二:makefile

科普一下makefile,大家可以找一篇博客看一下。

"="是最普通的等号,在Makefile中容易搞错赋值等号,使用 “=”进行赋值,变量的值是整个Makefile中最后被指定的值。

$符号表示取变量的值,当变量名多于一个字符时,使用"( )"
$符的其他用法

$^ 表示所有的依赖文件
$@ 表示生成的目标文件
$< 代表第一个依赖文件

伪目标 .PHONY

伪目标只是一个标签,clean是个伪目标没有依赖文件,只有用make来调用时才会执行
当目录下有与make 命令 同名的文件时 执行make 命令就会出现错误。

通常也会把ALL设置成伪目标

dy-lib=libmymethod.so
static-lib=libmymath.a

.PHONY:all
all: $(dy-lib) $(static-lib)

$(static-lib):mymath.o
	ar -rc $@ $^
mymath.o:mymath.c
	gcc -c $^

$(dy-lib):mylog.o myprint.o
	gcc -shared -o $@ $^
mylog.o:mylog.c
	gcc -fPIC -c $^
myprint.o:myprint.c
	gcc -fPIC -c $^

.PHONY:clean
clean:
	rm -rf *.o *.a *.so mylib

.PHONY:output
output:
	mkdir -p mylib/include
	mkdir -p mylib/lib
	cp *.h mylib/include
	cp *.a mylib/lib
	cp *.so mylib/lib

make: 

make output 

 

2.使用

我们调用静态库还是可以的。

那么我们将动态库函数放开;

我们尝试使用静态库的调用方法来调用动态库。 

可以形成可执行文件但是跑不起来;发现报错了。

解释:

编译器是知道我们动态库在哪里了,但是动态库是加载到文件当中,在执行文件是遇到对应函数跳转过去的,所以编译时是没有文件了。但是运行文件时,系统不知道动态库是在那里的。

为什么c库的时候没有问题?可以加载呢?

因为c库在加载时有自己的路径,它加载了环境环境变量当中。

接下来我们研究动态库加载数据!!!

3、解决动态库的加载问题

1、直接将动态库拷贝到lib64当中,和静态库一样。(感兴趣看上面的静态库拷贝过程自己玩一玩)

 2、在lib64当中建立一个软链接(和静态库一样)

查看路径

 建立软链接

我们发现不用编译加载器都可以找到; 

 执行一下发现没有问题

3、将动态库加载到环境变量当中

和环境变量相关的命令

1.env: 显示所有环境变量。
2.printenv: 打印指定的环境变量。
3 export: 设置或显示环境变量。
4.unset: 删除环境变量。
5.echo: 输出环境变量的值。
6.set:显示本地定义的shell变量和环境变量

查看这个环境变量指令

echo $LD_LIBRARY_PATH

这个就是曾经加载的变量。

我们发现我们不需要将这个动态库的文件名加载进去,他会自己找,加载了就还是会找不到的。

我们知道我们的环境变量在退出后环境变量就没有了,那么再次打开时就又找不到了。

重新启动后:

我们想要不打开还在,我们就将环境变量加载到~/.bash_profile这个启动环境变量当中

借助当初的环境变量在看一下

linux进程的状态之环境变量_进程启动后 环境变量-CSDN博客

在这里加入这个环境变量即可;

4、ldconfig 配置/etc/ld.so.conf.d/,建立自己的动态库路径配置文件,然后ldconfig更新

随便打开一个文件 

我们发现这都是一个路径。

我们在这个路径下面创建一个 .conf的文件

在文件中把动态库文件路径放在这个里面

创建完成以后再将文件重新加载(更新)一下

ldconfig更新

然后这里就又有了。

当我们很多库在同一个路径当中时,我们不用把每一个路径都创建一个.conf文件,我们加它们放在一个文件当中就可以了,然后分别把每个路径列一下。

练习:

安装ncurses ---基于终端的图形界面库 

博客教程

三、共享库

动态库在进程运行时是需要加载的,静态库不需要

当我们形成可执行文件了,我们把静态文件删除

常见的动态库被所以的可执行文件(动态链接的),都要使用这个动态库,所以动态库也叫做共享库。

所以动态库在系统加载以后,会被所有进程共享。加载到了内存当中也就只用一份,大大节省了空间。

当我们用十几二十个动态库,它们都会被加载到内存,然后操作系统对这些库先描述在组织,形成链表,管理时就是对链表的增删查改。

动态库是怎么做到对所有进程进行共享的?

每个进程都有自己的pcb

事实上:系统在运行中,一定会存在多个动态库,--os管理,系统将这些进程还有动态库分别先描述,在组织串在一起;

所有系统对所有库的加载情况还有进程都是非常清楚的。
当进程共享同一个动态库时,我们的cpu调度进程的pcb,拿到pcb以后,到地址空间中去找代

码,代码是数据,数据存储在磁盘当中的;就会到物理内存当中去找代码,发现代码没有从磁盘加载过来,那么就会去找inode编号,那到inode编号然后到inode bitmap当中去看是否有数据,有数据通过inode编号在inode block当中拿到block编号,然后到对应的块当中去读取数据,一次读取4kb大小内存,也就是8个扇区的数据,将这些数据加载到物理内存当中,然后再通过页表映射到地址空间的代码区;

如果是共享块数据,那么将数据加载当地址空间的共享区,当调用代码时,就会到共享区去找代码,就做到执行任何代码都是再进程的地址空间中执行的;

总结:进程和进程都是独立的;建立映射,从此以后,我们执行的任何代码,都是在我们进程地址空间中执行的。

当动态库当中有全局变量,当我们一个进程将这个全局变量给修改了,但是我们另一个进程去访问时,是不会被修改的,这是因为我们的数据和页表之间存在写时拷贝,它们只会将共享区的数据分别拷贝一份,互相之间都是独立的


 总结

动态库在进程运行时是需要加载的,静态库不需要

当我们形成可执行文件了,我们把静态文件删除

常见的动态库被所以的可执行文件(动态链接的),都要使用这个动态库,所以动态库也叫做共享库。

所以动态库在系统加载以后,会被所有进程共享。加载到了内存当中也就只用一份,大大节省了空间。

动态库的创建和使用

理解动态库的加载

标签:文件,静态,当中,linux,动态,环境变量,加载
From: https://blog.csdn.net/2301_80687320/article/details/144056307

相关文章

  • 2024 最新 Kali Linux 定制化魔改,完整版添加常见60渗透工具
    系统版本:kalilinux2024.1固件类型:BIOS用户:zss密码:ss系统压缩大小:18.8GB,解出来:36.00GB左右,请提前预留好足够的空间下载链接https://pan.quark.cn/s/e5ca0a5847a4这个版本添加工具武器库比如我们pip命令后面忘了是什么了,我们就可以输入pip然后在......
  • Linux基础之浏览和创建文件
    如果您喜欢我的文章,还可以关注微信公众号,蜗牛全栈一、cat和less命令:显示文件内容在/var/log目录中主要记录程序数据和log日志文件,/var这个目录通常包含程序的数据。log文件通常会记录电脑中发生了什么事情 二、cat命令:一次性显示文件的所有内容cat是concatenate的缩写,表......
  • 掌握SHELL脚本基础,轻松驾驭Linux自动化利器
    文章目录解释器编写规则变量环境变量永久变量已经预设定好的变量脚本标量条件测试文件测试字符串测试命令执行测试控制语句if判断语句case判断语句for循环语句while循环语句until循环语句函数shell脚本之间相互调用与重定向相互调用函数调用参数传递重定向输出重定......
  • 2024最新绿豆UI6、UI7三套UI的TV端和手机版:后台搭建、伪静态设置、动态域名、仓库对接
    后台安装教程环境要求PHP>=PHP7.4+(必须是7.4及以上版本,低于7.4会出现异常)MySQL>=5.5.0<5.7(需支持InnoDB引擎,建议使用5.6版本)Apache或Nginx安装步骤1.上传源码到网站将下载的后台源码上传到您的网站服务器上。2.设置运行目录设置网站的运行目录为pu......
  • WPF笔记6——静态资源(StaticResource) 与 动态资源(DynamicResource)
    示例代码1前台代码:点击查看代码<Windowx:Class="TestWPF.Window1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://sc......
  • Linux搭建nginx+keepalived 高可用(主备+双主模式)
    keepalived简介反向代理及负载均衡参考:nginx反向代理与负载均衡当你了解会搭建nginx负载均衡后,需要考虑nginx这台服务器的安全性啦,如果只有一台,这台nginx一出问题,web就会无法访问的情况,所以为了应对这种情况,就需要两台nginx做主备服务器。nginx+keepalived如下图所示 在nginx......
  • Linux 上 MySQL 8.0 的备份与恢复实战指南
            在数据库运维过程中,备份与恢复是保障数据安全的重要手段。MySQL8.0在Linux环境中提供了多种备份和恢复方案,包括逻辑备份和物理备份。本文将介绍这些备份方式的操作步骤与逻辑实现,帮助您高效管理数据库。一、备份与恢复的作用和意义数据安全:防止因误操作......
  • linux之进程管理
    进程管理1进程基本概述运行起来的程序,就叫进程当程序运行之后,cpu会调度一块内存空间给程序使用, 以及进程运行的身份和权限进程在运行过程中,服务器会以各种状态来表示当前进程的指标信息线程是进程内的调度单位,进程可以包含一个或多个线程1.1进程和程序程序是静态的,是......
  • 腾讯通RTX最佳升级方案,兼容Linux内核国产系统与移动端
    一、腾讯通RTX停更后用户面临的核心问题随着腾讯通RTX停止更新并下架官网,用户无法再获取更新、技术支持及资源下载,同时用户不得不面临以下无法得到解决的问题:●不兼容国产系统与移动端:腾讯通RTX只支持Windows和Mac平台,在Linux内核国产操作系统以及移动设备上无法使用。●组织......
  • Tiny Core Linux 安装和配置
    TinyCoreLinux安装和配置https://blog.csdn.net/stevenldj/article/details/112852507目标通过最小的命令行版TinyCoreLinux系统光盘安装TinyCoreLinux桌面环境,设置中文界面,安装输入法,设置分辨率。所有软件包都从仓库下载,可以安装在虚拟机中,也可以安装在U盘中,实......