Linux——动静态库的制作和使用超详细(实操+代码+原理介绍)

编程入门 行业动态 更新时间:2024-10-08 02:19:54

Linux——动<a href=https://www.elefans.com/category/jswz/34/1771395.html style=静态库的制作和使用超详细(实操+代码+原理介绍)"/>

Linux——动静态库的制作和使用超详细(实操+代码+原理介绍)

动静态库的制作和使用

  • 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)。

🏈区别

  • 静态库的代码在编译时被复制到可执行文件中,使得可执行文件自包含,无需外部依赖。
  • 动态库的代码在运行时动态加载到内存中,多个程序可以共享同一个动态库,减少内存占用和可执行文件的大小。

🏐使用动态库的优点包括:

  1. 节省内存和磁盘空间,多个程序可以共享同一个动态库。
  2. 允许在运行时更新和升级库,而无需重新编译整个程序。
  3. 支持动态链接,使得程序更灵活、易于维护和分发。

🏉 使用静态库的优点包括:

  1. 代码的嵌入性,可执行文件自包含,无需外部依赖。
  2. 可以确保程序与特定版本的库文件完全兼容。
  3. 选择使用动态库还是静态库,通常取决于项目的需求、开发环境和目标平台等因素。在实际开发中,通常会根据实际情况进行权衡和选择。

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.ostatic.o: static.cgcc -c static.c -o static.ostatic2.o: static2.cgcc -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:allall:libstatic.so libstatic.alibstatic.so:static.o static2.ogcc -shared -o libstatic.so static.o static2.ostatic.o:static.cgcc -fPIC -c static.c -o static.ostatic2.o:static2.cgcc -fPIC -c static2.c -o static2.o libstatic.a:static_s.o static2_s.oar -rc libstatic.a static_s.o static2_s.ostatic_s.o:static.cgcc -c static.c -o static_s.ostatic2_s.o:static2.cgcc -c static2.c -o static2_s.o.PHONY:liblib:  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/includecp *.so lib-dyl/lib cp *.h lib-dyl/include.PHONY:cleanclean: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️⃣使用 静态库

直接包头文件使用

报错了:

找不到!!

🍍 头文件搜索路径规则

  • 👶🏼 在当前路径下找
  • 👧🏼在系统头文件路径下查找头文件

🚴🏼‍♀️ 库的安装

  1. 将头文件和自己的库文件拷贝到系统路径下!
    不推荐! 会污染系统的头文件和库…
  2. 指定头文件搜索路径(推荐)

== 语法:-I +搜索路径 ==
gcc test.c -o test -I ./lib-static/include/

-I -L -l介绍


-I:头文件查找的路径
-L: 库文件搜索的路径
-l:在-L指定的路径下 选择你要链接的库(有时候-L路径会有多个库文件)

🚴🏼 🚴🏼‍♂️

🧒🏼 👦🏼 👩🏼 🧑🏼 👨🏼 👩🏼‍🦱

5️⃣使用动态库

![01](.png)


成功~

软件工程学学渣一枚,如有发现错误 敬请斧正 创作不易 点赞支持 拒绝白嫖
~

更多推荐

Linux——动静态库的制作和使用超详细(实操+代码+原理介绍)

本文发布于:2024-03-14 00:33:40,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1735229.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:静态   原理   代码   详细   Linux

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!