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

文章详细介绍了静态库和动态库的概念、区别、优缺点,以及如何制作和使用静态库与动态库。静态库在编译时被嵌入到可执行文件中,而动态库在运行时动态加载。静态库优点包括代码自包含,而动态库则能节省资源并方便更新。文章还提供了制作静态库和动态库的步骤,并讲解了如何在程序中使用这些库。
摘要由CSDN通过智能技术生成

0

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个打印函数
0

  • 🙋🏿‍♀️ 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

3
生成了可执行对应的.o文件

用gcc 编译一下生成的.o文件
5
就得到了a.out

  • 🤚🏼运行
    6
  • 🖐🏼达到预期
  • 🤏🏼很多.o文件在一起用起来操作比较繁琐 有没有什么方式处理一下呢?

🍉归档

6

  • ✋🏼命名规则:
    生成的静态库名.a +依赖的.o文件
    ar - rc 生成的静态库名.a +依赖的.o文件

  • 🖖🏼编译结果:
    7
    生成了 libsatitic静态库!!!

🍇静态库发布

  • 👌🏼 makefile
    9
  • 形成
    10

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   

11

  • 代码讲解
  • 这个 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 项目。

  • 运行:
    12

4️⃣使用 静态库

直接包头文件使用
13
报错了:
在这里插入图片描述
找不到!!

🍍 头文件搜索路径规则

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

🚴🏼‍♀️ 库的安装

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

== 语法:-I +搜索路径 ==
gcc test.c -o test -I ./lib-static/include/
在这里插入图片描述

-I -L -l介绍

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

🚴🏼 🚴🏼‍♂️

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

5️⃣使用动态库

![01](https://img-blog.csdnimg.cn/5948037db116421c8546943410ab6883.png)

在这里插入图片描述
成功~

软件工程学学渣一枚,如有发现错误 敬请斧正 创作不易 点赞支持 拒绝白嫖
~在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值