IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> LInux——动静态库制作与使用 -> 正文阅读

[系统运维]LInux——动静态库制作与使用

动静态库的基本概念

  • 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
  • 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
  • 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
  • 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间
    在这里插入图片描述

静态库的制作与使用

创建add.c add.h sub.c sub.h ,函数定义放在.c 文件中,声明放在.h文件中。

add.c add.h sub.c sub.h 内容如下:

//add.c
int add(int a,int b)
{
    return a+b;
}
//add.h
#pragma once
extern int add(int a ,int b);
//sub.c
int sub(int a,int b)
{
    return a-b;
}
//sub.h
#pragma once
extern int sub(int a,int b);

打包

有了上面4个源文件和头文件,我们现在生成一个静态库。

第一步:让所有源文件(.c文件)生成目标文件

gcc -c add.c
gcc -c sub.c

当前目录文件:

add.c add.h sub.c sub.h add.o sub.o

第二步:使用ar命令将所有目标文件打包为静态库

ar命令是gnu的归档工具,常用于将目标文件打包为静态库,下面我们使用ar命令的-r选项和-c选项进行打包。

  • -r(replace):若静态库文件当中的目标文件有更新,则用新的目标文件替换旧的目标文件。
  • -c(create):建立静态库文件。
ar -rc libcal.a add.o sub.o

当前目录文件:

add.c add.h sub.c sub.h add.o sub.o libcal.a

此外,我们可以用ar命令的-t选项和-v选项查看静态库当中的文件。

  • -t:列出静态库中的文件。
  • -v(verbose):显示详细的信息。
ar -tv libcal.a

第三步:将所有的头文件和静态库封装起来,目的为了给其他使用

mkdir -p mlib/include
mkdir -p mlib/lib
cp ./*.h mlib/include
cp ./*.so mlib/lib

mlib目录的tree结构

mlib
|---include
	| -- add.h
	| -- sub.h
|---lib
	| -- libcal.a

使用makefile

如果你看不懂makefile

我们可以把上述的命令通过makefile的语法转换写到makefile文件里,通过make搭配的指令,生成静态库,封装静态库和头文件可以一步到位。

  1 mylib=libcal.a
  2 CC=gcc
  3 
  4 %.o:%.c
  5    $(CC) -c $<  #把所有的.c 挨个挨个倒进来
  6 
  7 $(mylib):add.o sub.o
  8    ar -rc -o $(mylib) $^
     
  9 .PHONY:clean
 10 clean:
 11    rm -rf ./*.o ./*.a 
 12
 13 .PHONY:output
 14 output:
 15    mkdir -p mlib/include
 16    mkdir -p mlib/lib
 17    cp ./*.h mlib/include
 18    cp ./*.a mlib/lib

1.生成静态库

make

2.封装

make output

3.清理

make clean

是不是很简单!

使用

假如你的朋友要使用你的静态库,假如你的朋友就是friend目录

mkdir friend

现在你要把静态库的包给你的朋友

cp mlib friend -r

现在你的朋友要使用一下你的库,你的朋友创建里一个main.c

touch main.c
// main.c
#include<stdio.h>
#include"add.h"
#include"sub.h"
int main()
{
	int a=10,b=11;
    printf("a+b=%d\n",add(a,b));
    return 0;
}

你的朋友写好main.c 了,

现在如何编译生成可执行文件?

第一步:gcc

此时使用gcc编译main.c生成可执行程序时需要携带三个选项:

  • -I:指定头文件搜索路径。
  • -L:指定库文件搜索路径。
  • -l:指明需要链接库文件路径下的哪一个库。(库名规则:libxxx.so )
gcc main.c -I./mlib/include -L./mlib/lib -lcal

此时生成的a.out即可使用;

动态库的制作与使用

打包

  1. shared: 表示生成共享库格式
  2. fPIC:产生位置无关码(position independent code)
  3. 库名规则:libxxx.so

过程如下:

当前目录文件:

add.c add.h sub.c sub.h

第一步:让所有的.c 文件生成 .o目标文件

在生成 ,需要加上-fPIC 选项;

gcc -fPIC -c add.c
gcc -fPIC -c sub.c

生成目标文件后,当前目录文件

add.c add.h add.o sub.c sub.h sub.o

关于-fPIC

第二步:使用-shared 选项将所有生成的目标文件进行打包为动态库

gcc -shared -o libcal.so add.o sub.o

生成库后,当前目录文件

add.c add.h add.o sub.c sub.h sub.o libcal.so

第三步:将头文件和动态cal 放到一个目标里

目的:为了方便给其他人用

mkdir -p mlib/include
mkdir -p mlib/lib
cp ./*.h mlib/include
cp ./*.so mlib/lib

生成目标后,当前目录文件

add.c add.h add.o sub.c sub.h sub.o libcal.so mlib

mlib目录包

mlib
|---include
	| -- add.h
	| -- sub.h
|---lib
	| -- libcal.so

使用 makefile 生成

如果你看不懂makefile

  1 mylib=libcal.so
  2 CC=gcc
  3 
  4 %.o:%.c
  5    $(CC) -fPIC -c $< #把所有的.c 挨个挨个倒进来
  6 
  7 $(mylib):add.o sub.o
  8    $(CC) -shared -o $(mylib) $^
  9 .PHONY:clean
 10 clean:
 11    rm -rf ./*.o ./*.so 
 12 
 13 .PHONY:output
 14 output:
 15    mkdir -p mlib/include
 16    mkdir -p mlib/lib
 17    cp ./*.h mlib/include
 18    cp ./*.so mlib/lib

使用

现在我把mlib目录给我的朋友friend

mkdir friend
cp mlib friend -r

当前friend 目录文件:

mlib 

现在我的朋友要使用我的库mlib

第一步:编写源文件main

写一个main.c 源文件

#include <stdio.h>
#include <add.h>

int main()
{
	int x = 20;
	int y = 10;
	
	printf("%d + %d = %d\n", x, y, add(x, y));
    printf("%d - %d = %d\n", x, y, sub(x, y));
	return 0;
}

当前friend 目录文件:

mlib main.c

第二步:编译 main.c 生成可执行文件

gcc main.c -I./mlib/include -L./mlib/lib -lcal

此时使用gcc编译main.c生成可执行程序时,需要用-I选项指定头文件搜索路径,用-L选项指定库文件搜索路径,最后用-l选项指明需要链接库文件路径下的哪一个库,只要库名即可(去掉lib以及版本号) 。

当前friend 目录文件:

mlib main.c a.out

与静态库的使用不同的是,此时我们生成的可执行程序a.out并不能直接运行。

需要注意的是,我们使用-I-L-l这三个选项都是在编译期间告诉编译器我们使用的头文件和库文件在哪里以及是谁,但是当生成的可执行程序生成后就与编译器没有关系了,此后该可执行程序运行起来后,操作系统找不到该可执行程序所依赖的动态库,我们可以使用ldd命令进行查看。

ldd a.out

显示部分如下:

libcal.so => not found

可执行程序没有找到依赖的动态库。

解决方案:

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

 sudo cp mlib/lib/libcal.so /lib64

f2、更改 LD_LIBRARY_PATH

LD_LIBRARY_PATH是程序运行动态查找库时所要搜索的路径,我们只需将动态库所在的目录路径添加到LD_LIBRARY_PATH环境变量当中即可。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/hoeme/linux_-lerning/lesson9/friend/mlib/lib

f3、ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

1.创建一个以.conf后缀的文件

touch my.conf     

2.把库路径写入my.conf

echo /hoeme/linux_-lerning/lesson9/friend/mlib/lib >my.conf

3.把my.conf 拷贝到 /etc/ld.so.conf.d/

cp my.conf /etc/ld.so.conf.d/

4.更新一下配置文件

sudo ldconfig
Y_PATH=$LD_LIBRARY_PATH:/hoeme/linux_-lerning/lesson9/friend/mlib/lib

f3、ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新

1.创建一个以.conf后缀的文件

touch my.conf     

2.把库路径写入my.conf

echo /hoeme/linux_-lerning/lesson9/friend/mlib/lib >my.conf

3.把my.conf 拷贝到 /etc/ld.so.conf.d/

cp my.conf /etc/ld.so.conf.d/

4.更新一下配置文件

sudo ldconfig

然后就可以运行 a.out了-------

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-04-24 09:50:00  更:2022-04-24 09:50:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:43:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码