动静态库的制作和使用
- 1️⃣.动静态库介绍
- 🏀静态库
- ⚽️动态库
- 🏈区别
- 🏐使用动态库的优点包括:
- 🏉 使用静态库的优点包括:
- 2️⃣静态库的制作
- 🍊Q:库文件能不能有main()函数?
- 🍋准备好库函数.h和.c文件
- 🍉归档
- 🍇静态库发布
- 3️⃣ 动态库的制作
- 🍒规则
- 🍑实操代码
- 4️⃣使用 静态库
- 🍍 头文件搜索路径规则
- 🚴🏼♀️ 库的安装
- -I -L -l介绍
- 5️⃣使用动态库
- 🍓
1️⃣.动静态库介绍
🍏动态库(Dynamic Library)和静态库(Static Library)是在软件开发中常用的两种库文件形式。
🏀静态库
静态库是一组已编译的目标文件的集合,它们被打包成一个单独的文件。当程序链接时,编译器会将静态库的目标文件直接嵌入到最终的可执行文件中。静态库在编译时被完整地复制到可执行文件中,使得可执行文件成为一个独立、自包含的实体。这意味着程序运行时不需要额外的库文件支持,所有所需的代码都已嵌入到可执行文件中。静态库的扩展名通常是 .a(对于UNIX/Linux)或 .lib(对于Windows)。
⚽️动态库
相比之下,动态库是一组已编译的目标文件的集合,它们在运行时由操作系统动态加载到内存中。当程序链接时,编译器只会在可执行文件中包含动态库的引用,而不会将实际的代码嵌入到可执行文件中。程序在运行时,通过动态链接器(如 Windows 的 DLL 动态链接库或 UNIX/Linux 的共享对象文件 .so)将动态库加载到内存,并与可执行文件进行连接。动态库的扩展名通常是 .so(对于UNIX/Linux)或 .dll(对于Windows)。
🏈区别
- 静态库的代码在编译时被复制到可执行文件中,使得可执行文件自包含,无需外部依赖。
- 动态库的代码在运行时动态加载到内存中,多个程序可以共享同一个动态库,减少内存占用和可执行文件的大小。
🏐使用动态库的优点包括:
- 节省内存和磁盘空间,多个程序可以共享同一个动态库。
- 允许在运行时更新和升级库,而无需重新编译整个程序。
- 支持动态链接,使得程序更灵活、易于维护和分发。
🏉 使用静态库的优点包括:
- 代码的嵌入性,可执行文件自包含,无需外部依赖。
- 可以确保程序与特定版本的库文件完全兼容。
- 选择使用动态库还是静态库,通常取决于项目的需求、开发环境和目标平台等因素。在实际开发中,通常会根据实际情况进行权衡和选择。
2️⃣静态库的制作
🍊Q:库文件能不能有main()函数?
A:不能 ,制作的库函数是给别人使用的,两个main函数会引起冲突!
🍋准备好库函数.h和.c文件
这里我以static.c static.h static2.c static2.h 命名 写了2个打印函数
- 🙋🏿♀️ static.c
#include"static.h"
void _Printf(int i)
{
while(i>0)
{
printf("这是一个静态库\n");
i--;
}
}
- 🙋🏿static.h
#pragma once
#include <stdio.h>
void _Printf(int i);
- 🤦🏿♀️ static2.h
#pragma once
#include<stdio.h>
void Print2(int x);
- 🤦🏿static2.c
#include "static2.h"
void Print2(int x)
{
while(x>0)
{
printf("这是static2.....\n");
x--; }
}
然后在test.c中包含头文件 static.h 这里跟我们平时在VS下写代码 声明和定义分离是一样的道理
- 🙋🏿♂️test.c
#include"static.h"
int main()
{
_Printf(10) ;
Print2(5);
return 0;
}
~
- 👋🏼形成.o文件
gcc -c 源文件.c -o 生成件.o
这里我们直接把配置生成代码写在makefile
all: static.o static2.o
static.o: static.c
gcc -c static.c -o static.o
static2.o: static2.c
gcc -c static2.c -o static2.o
.PHONY:clean
clean:
rm -f *.o
生成了可执行对应的.o文件
用gcc 编译一下生成的.o文件
就得到了a.out
- 🤚🏼运行
- 🖐🏼达到预期
- 🤏🏼很多.o文件在一起用起来操作比较繁琐 有没有什么方式处理一下呢?
🍉归档
-
✋🏼命名规则:
生成的静态库名.a +依赖的.o文件
ar - rc 生成的静态库名.a +依赖的.o文件 -
🖖🏼编译结果:
生成了 libsatitic静态库!!!
🍇静态库发布
- 👌🏼 makefile
- 形成
3️⃣ 动态库的制作
🍒规则
- 🤞🏼shared: 表示生成共享库格式
- 🤘🏼fPIC:产生位置无关码(position independent code)
- 🤙🏼库名规则:libxxx.so
- 👈🏼示例: [root@localhost linux]# gcc -fPIC -c sub.c add.c [root@localhost linux]# gcc -shared -o libmymath.so
*.o [root@localhost linux]# ls add.c add.h add.o libmymath.so main.c sub.c sub.h sub.o
🍑实操代码
动态+静态
.PHONY:all
all:libstatic.so libstatic.a
libstatic.so:static.o static2.o
gcc -shared -o libstatic.so static.o static2.o
static.o:static.c
gcc -fPIC -c static.c -o static.o
static2.o:static2.c
gcc -fPIC -c static2.c -o static2.o
libstatic.a:static_s.o static2_s.o
ar -rc libstatic.a static_s.o static2_s.o
static_s.o:static.c
gcc -c static.c -o static_s.o
static2_s.o:static2.c
gcc -c static2.c -o static2_s.o
.PHONY:lib
lib:
mkdir -p lib-static/lib;
mkdir -p lib-static/include;
cp *.a lib-static/lib;
cp *.h lib-static/include;
mkdir -p lib-dyl/lib
mkdir -p lib-dyl/include
cp *.so lib-dyl/lib
cp *.h lib-dyl/include
.PHONY:clean
clean:
rm -f *.o *.a *.so
rm -rf lib-static lib-dyl
- 代码讲解
- 这个 Makefile 脚本是用来构建两个库文件:一个动态链接库 (libstatic.so) 和一个静态链接库 (libstatic.a),并将它们复制到对应的目录中。下面我会逐行解释这个脚本:
.PHONY: all:这行定义了一个伪目标 “all”。在 Makefile 中,伪目标并不对应任何文件,只是一个便于调用的标签。
all: libstatic.so libstatic.a:这行定义了目标 “all” 的依赖项。当你只输入 make (默认目标是 “all”)时,make 将会按照顺序构建 libstatic.so 和 libstatic.a。
3-4. libstatic.so: static.o static2.o 和 gcc -shared -o libstatic.so static.o static2.o:这两行定义了如何构建 libstatic.so。当 static.o 或 static2.o 发生变化时,make 将会重新生成 libstatic.so。
5-8. 这些行定义了如何生成 static.o 和 static2.o,都是从对应的 .c 文件编译得到。
10-11. libstatic.a: static_s.o static2_s.o 和 ar -rc libstatic.a static_s.o static2_s.o:这两行定义了如何构建 libstatic.a。
12-16. 这些行定义了如何生成 static_s.o 和 static2_s.o,都是从对应的 .c 文件编译得到。
.PHONY: lib:这行定义了另一个伪目标 “lib”。
20-28. 这些行定义了目标 “lib” 的行为,用于创建两个目录 lib-static 和 lib-dyl,并将构建好的库文件和头文件复制到对应的目录中。
.PHONY: clean:这行定义了另一个伪目标 “clean”。
30-32. 这些行定义了目标 “clean” 的行为,用于删除所有构建好的目标文件,以及 lib-static 和 lib-dyl 目录。这样可以方便地重建所有目标。
这个 Makefile 脚本使用了一些通用的 make 和 shell 命令,例如 gcc(C 编译器)、ar(用于创建、修改、提取静态库的工具)、mkdir(创建目录)、cp(复制文件)和 rm(删除文件)。在这个脚本中,它们被组合在一起,用于构建和管理 C 项目。
- 运行:
4️⃣使用 静态库
直接包头文件使用
报错了:
找不到!!
🍍 头文件搜索路径规则
- 👶🏼 在当前路径下找
- 👧🏼在系统头文件路径下查找头文件
🚴🏼♀️ 库的安装
- 将头文件和自己的库文件拷贝到系统路径下!
不推荐! 会污染系统的头文件和库… - 指定头文件搜索路径(推荐)
== 语法:-I +搜索路径 ==
gcc test.c -o test -I ./lib-static/include/
-I -L -l介绍
-I:头文件查找的路径
-L: 库文件搜索的路径
-l:在-L指定的路径下 选择你要链接的库(有时候-L路径会有多个库文件)
🚴🏼 🚴🏼♂️
🧒🏼 👦🏼 👩🏼 🧑🏼 👨🏼 👩🏼🦱
5️⃣使用动态库
6️⃣