• 【Linux】静态库的制作和使用详解


    在这里插入图片描述

    💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
    📃个人主页 阿然成长日记 👈点击可跳转
    📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++🔹Liunx
    🚩 不能则学,不知则问,耻于问人,决无长进
    🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

    前言:

    本篇博客讲解两个类型的库:动态库(.so) 和 静态库(.a).的制作。

    一、库的基础知识

    库的作用:提升开发效率。隐藏源代码

    库的本质:将所有的[.o]结尾的可执行目标二进制文件打包形成一个文件夹。

    二、如何编写静态库

    1.原理简述

    你编写了好几个文件,给别人使用,但是又不想让使用者看到内部源代码,此时有没有什么办法呢。

    本质就是隐藏.c源文件。

    • 第一步:将所有.c的文件形成.o文件

    • 第二步:将所有的.o使用ar指令打包成一个库文件。

    • 具体流程如下图:

    在这里插入图片描述

    这样做的好出有:
    (1)将所有的源文件打包好,防止使用者再拷贝时丢失原文件。提高了使用效率。
    (2)使用者无法查看源码,提高了安全性

    2.实际操作

    分别创建了4个文件:mymath.h mymath.c myprint.h myprint.c.

    • 1.
    #pragma once    
    #include    
        
    extern int addToTarget(int start, int end);//声明函数
    
    • 2.mymath.c
      #include "mymath.h"                                             #             
                                                                                         
      //这段函数的作用是计算start-end之间的和
      int addToTarget(int start, int end)                               
      {                                                                
        int sum = 0;                                                   
        int i = start;                                                 
        for(i; i <= end; i++)
        {                                                                                                                                 
          sum += i;                                                    
        }                                                              
        return sum;                                                    
      }  
    
    • 3.myprint.h
    #pragma once     
        
    #include    
    #include    
        
    extern void Print(const char* str);  
    
    • 4.myprint.c
    #include "myprint.h"                                                            
     
    //这段函数功能是输出传入的字符串,后面加上时间戳                                                                    
    void Print(const char* str)                                                          
    {
      printf("%s[%d]\n",str,(int)(time(NULL)));
    }       
    

    有了上面四个文件后,还需要写一个main方法使用这些函数。

    #include "myprint.h"    
    #include "mymath.h"    
        
    int main()    
    {    
      Print("hello,world");                                                                                                               
      int res = addToTarget(1,100);    
        
      printf("res: %d\n",res);    
        
      return 0;    
    }    
    

    开始制作静态库:
    第一步:将所有的.c文件–>.o文件
    使用gcc的【-c】选项,代码如下:

    gcc -o myprint.o -c myprint.c
    gcc -o mymath.o -c mymath.c
    

    注意:main函数不用参与,每个使用者都会有自己的main方法去调用库文件。

    第二步:o文件打包成名字叫hello的静态库
    知识补充:

    【ar】指令:
    ar -[选项] + lib+库文件名.a + 所有.o文件
    选项这里只说r(replace替换),c(create创建)就可以了,就足以让我们创建静态库了.
    注意: 格式一定是lib+库文件名.a。也就是说要形成的静态库的名字 前缀必须是lib,后缀必须是.a,中间可以随便起名字.

    执行代码:

    ar -rc libhello.a main.o myprint.o mymath.o
    

    在这里插入图片描述

    可以发现,此时目录下面就会存在刚打包好的库文件了,但是,还需要结合对应的头文件才能正确的使用库文件中的函数。往下学!

    3.使用makefile文件自动化构建

    理清楚一个文件形成静态库的过程后 总结来说: .c文件 —> .o文件 —>
    打包形成静态库

    既然是这么一套固定的流程,那么我们完全可以用Makefile来完成这些工作。需要注意的是搞清各个文件的依赖关系,然后再进行编写。

    所以最后的Makefile编写如下:

    libhello.a: mymath.o myprint.o                                                                                                        
      ar -rc libhello.a mymath.o myprint.o    
    mymath.o : mymath.c    
      gcc -o mymath.o -c mymath.c    
    myprint.o: myprint.c    
      gcc -o myprint.o -c myprint.c    
        
    .PHONY:clean    
    clean:    
      rm -rf *.o libhello.a    
    

    在这里插入图片描述

    这样还没有结束:还有对应的许多头文件呢。一般都是.h声明,然后从.o打包形成的库里面找。

    • 所以我们还需要做一件工作:将.h和.a文件规整到一起.在Makefile加入以内容:就是将头文件和库文件规整在一起,逻辑如下 在这里插入图片描述

    • 在这里插入图片描述

    • makefile代码如下

    .PHONY:hello    
    hello:    
      mkdir -p hello/lib    
      mkdir -p hello/include    
      cp -rf *.h hello/include    
      cp -rf *.a hello/lib  
    
    • 总结来说: .c文件 —> .o文件 —> 打包形成静态库–>最后将.h和.a文件规整到一起

    这样就制作好了一个静态库!如何去使用呢?

    四、静态库的使用

    方法一:直接拷贝到系统路径

    头文件gcc系统默认搜索路径是:/usr/include
    库文件gcc系统默认搜索路径是:/lib64 或者 /usr/lib64

    • 可以将你编写的静态库拷贝进/usr/lib64。头文件拷贝进/usr/include ;但是这样做会污染原来别人已经写好的库。不建议使用

    方法二:指定路径搜索

    我们可以直接在编译的时候加上头文件和库文件的路径.
    对于上面的代码我们执行:

    gcc main.c -I ./hello/include/ -L ./hello/lib/ -lhello
    
    

    就可以指定路径进行查找。

    选项:-I(i的大写)表示头文件的搜索路径
    -L表示库文件的搜索路径
    -l(小写的L)表示在特定路径下,要使用哪一个库.

  • 相关阅读:
    基于STM32温湿度传感器采集报警系统设计
    Nexus【应用 01】上传jar包到私有Maven仓库的两种方法:手动 Upload 和 mvn deploy 命令(配置+操作流程)
    java计算机毕业设计京东仓库管理系统源码+mysql数据库+系统+lw文档+部署
    Go短网址项目实战---下
    LeetCode:342(Python)—— 4 的幂
    投资理财:增额终身寿的优点和缺点
    k8s之三、pod生命周期/探针/调度策略/控制器
    Java线程和Go协程
    C++ ASIO 实现异步套接字管理
    onnxruntime C++推理
  • 原文地址:https://blog.csdn.net/luhaoran814/article/details/140173214