Linux下静态库生成和使用

2023-11-12

一.静态库概念

1.库是预编译的目标文件(object  files)的集合,它们可以被链接进程序。静态库以后缀为”.a”的特殊的存档(archive file)存储。

2.标准系统库可在目录/usr/lib与/lib中找到。比如,在类Unix系统中C语言的数序库一般存储为文件/usr/lib/libm.a。该库中函数的原型声明在头文件/usr/include/math.h中。

3.C标准库本身存储为/usr/lib/libc.a,它包含ANS1/ISO标准指定的函数,比如printf。对每一个C程序来说,libc.a都默认被链接。

在 Linux 中静态库以 lib 作为前缀,以.a 作为后缀,中间是库的名字自己指定即可,即: libxxx.a
在 Windows 中静态库一般以 lib 作为前缀,以 lib 作为后缀,中间是库的名字需要自己指定,即: libxxx.li

二.静态库的创建

生成静态库,需要先对源文件进行汇编操作 (使用参数 -c) 得到二进制格式的目标文件 (.o 格式), 然后在通过 ar 工具将目标文件打包就可以得到静态库文件了 (libxxx.a)。

生成静态链接库的具体步骤如下:

1.需要将源文件进行汇编,得到 .o 文件,需要使用参数 -c

# -c 参数位置没有要求
$ gcc 源文件(*.c) -c    

2.将得到的 .o 进行打包,得到静态库

$ ar rcs 静态库的名字(libxxx.a) 原材料(*.o)

3.发布静态库

# 发布静态库
    1. 提供头文件 **.h
    2. 提供制作出来的静态库 libxxx.a

三.静态库举例

1. 准备测试程序

加法计算源文件 add.c:

#include <stdio.h>
#include "head.h"

int add(int a, int b)
{
    return a+b;
}


减法计算源文件 sub.c:

#include <stdio.h>
#include "head.h"

int subtract(int a, int b)
{
    return a-b;
}


乘法计算源文件 mult.c:

#include <stdio.h>
#include "head.h"

int multiply(int a, int b)
{
    return a*b;
}


除法计算的源文件 div.c:

#include <stdio.h>
#include "head.h"

double divide(int a, int b)
{
    return (double)a/b;
}


头文件 head.h:

#ifndef _HEAD_H
#define _HEAD_H
// 加法
int add(int a, int b);
// 减法
int subtract(int a, int b);
// 乘法
int multiply(int a, int b);
// 除法
double divide(int a, int b);
#endif

测试文件 main.c:

#include <stdio.h>
#include "head.h"

int main()
{
    int a = 11;
    int b = 28;
    printf("a = %d, b = %d\n", a, b);
    printf("a + b = %d\n", add(a, b));
    printf("a - b = %d\n", subtract(a, b));
    printf("a * b = %d\n", multiply(a, b));
    printf("a / b = %f\n", divide(a, b));
    return 0;
}


1.2 生成静态库

第一步:将源文件 add.c, div.c, mult.c, sub.c 进行汇编,得到二进制目标文件 add.o, div.o, mult.o, sub.o

# 1. 生成.o
$ gcc add.c div.c mult.c sub.c -c


# 提示头文件找不到, 添加参数 -I 重新头文件路径即可
$ gcc add.c div.c mult.c sub.c -c -I ./include/

# 查看目标文件是否已经生成
$ ls

 第二步:将生成的目标文件通过 ar 工具打包生成静态库

# 2. 将生成的目标文件 .o 打包成静态库
$ ar rcs libmytest.a add.o div.o mult.o sub.o    # add.o div.o mult.o sub.o在同一个目录中可以写成 *.o

# 查看目录中的文件
$ ls

第三步:将生成的的静态库 libcalc.a 和库对应的头文件 head.h 一并发布

# 3. 发布静态库
	1. head.h    => 函数声明
	2. libmytest.a => 函数定义(二进制格式)


静态库的使用

编译测试程序 main.c
$ gcc main.c -o test
/tmp/ccF94vUK.o:在函数‘main’中:
main.c:(.text+0x3a):对‘add’未定义的引用
main.c:(.text+0x5c):对‘subtract’未定义的引用
main.c:(.text+0x7e):对‘multiply’未定义的引用
main.c:(.text+0xa0):对‘divide’未定义的引用
collect2: error: ld returned 1 exit status
上述错误分析:

编译的源文件中包含了头文件 head.h, 这个头文件中声明的函数对应的定义(也就是函数体实现)在静态库中,程序在编译的时候没有找到函数实现,因此提示 对‘xxxxxx’未定义的引用。

解决方法:在编译的时将静态库的路径和名字都指定出来

-L: 指定库所在的目录 (相对或者绝对路径)
-l: 指定库的名字,需要掐头 (lib) 去尾 (.a) 剩下的才是需要的静态库的名字


#  编译的时候指定库信息
	-L: 指定库所在的目录(相对或者绝对路径)
	-l: 指定库的名字, 掐头(lib)去尾(.a) ==> mytest
# -L -l, 参数和参数值之间可以有空格, 也可以没有  -L./ -lmytest
$ gcc main.c -o test -L ./ -l mytest

# 查看目录信息, 查看可执行程序是否生成
$ ls

# 执行生成的可执行程序
$ ./test
a = 20, b = 12
a + b = 32
a - b = 8
a * b = 240
a / b = 1.666667

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux下静态库生成和使用 的相关文章

随机推荐

  • shell脚本系列:3、shell命令

    shell脚本系列 3 shell命令 文章目录 shell脚本系列 3 shell命令 1 保留字 2 简单的命令 3 管道 4 命令列表 5 复合循环指令 5 1 循环结构 5 2 条件结构 5 3 分组命令 6 协程 7 GUN Pa
  • MATLAB遍历子文件夹及其下文件

    MATLAB遍历子文件夹及其下文件 以前从未遇到过用MATLAB批处理文件的情况 此次项目需要批量将二进制数据文件导入matlab进行svm分类 现将matlab遍历子文件夹及其文件的方法记录下来 文件目录结构 maindir subdir
  • Java基础必知必会

    基础知识笔记记录 持续更新ing 个人博客 www zhazhapeng cn 1 JDK JRE的区别 JDK Java Development Kit 开发工具 基本类库 javac 编译 javap 反编译 javadoc 编译文档
  • C++ 基础: cin和getline() 有啥区别?

    所谓温故而知新 所以时不时会回头来看看我们最最基础的知识 获取标准键盘输入的方法有多种 以C 语言来说 最常用的就是cin 和geline 那么它们之间有什么区别呢 我们总结一下 一 cin和geline的异同点 在 C 中 cin 和 g
  • Boost电源原理及工作过程详解

    1 Boost电路基本介绍 Boost电路在电池的一些场景非常常见 用于给电池电压升压后再给电路进行供电的场景比较多 随着电动汽车的飞速发展 在汽车电子的场景使用也越来越多 开关电源的主要部件包括 输入源 开关管 储能电感 控制电路 二极管
  • C1认证:作业四

    1 任务背景 为了摆脱 成为 只会CRUD 没有自我核心竞争力 无思想的编程的大龄码农 所以 开展了本次实验 目的是 去了解算法 去欣赏它的美 去感受它的优雅 使自己成为有灵魂的工程师 2 任务大纲 一 任务一 轮播图片 HTML CSS
  • 开源 LLM (大语言模型)整理(一)

    Large Language Model LLM 即大规模语言模型 是一种基于深度学习的自然语言处理模型 它能够学习到自然语言的语法和语义 从而可以生成人类可读的文本 所谓 语言模型 就是只用来处理语言文字 或者符号体系 的 AI 模型 发
  • C++模板类中的成员函数以及模板函数在类外定义的方式

    如下模板类 template
  • 零跑汽车财报解读:短跑“增程”双动力,长跑“自研”加速度

    3月21日晚间 零跑汽车交出了上市后的首份年度成绩单 纵观零跑汽车这份财报 其2022年的发展不乏亮点 2022年 零跑汽车实现营收123 85亿元 同比增长295 41 以远超行业的水平实现营收的迅速增长 充分证明了零跑汽车强大的经营韧性
  • opencv从内存缓冲区中读取图像数据

    1 从内存中加载图像数据 s Image Info stDispImgInfo spImgInfo gt m stDispInfo cv InputArray pic arr stDispImgInfo pImageBuf nWidth n
  • 如何ping一个网段下的所有IP地址,并保存返回结果

    循环的ping一个网段的所有IP地址 for L i in 1 1 255 do ping n 1 w 60 192 168 1 i find 回复 gt gt d pingall txt n 表示一次ping几次 w 表示一次ping60
  • 稳定性和高可用如何保障?一手测评华为云网站高可用解决方案

    一 前言 在如今科技高速发展的时代 几乎每个企业都依赖互联网 离不开互联网 很多企业的业务也都依托于互联网 比如我们熟知的电商 股市 直播 甚至是用于乘坐地铁 公交买票过闸的APP 如今可以说是一个互联网时代的完全体 但你们是否想过一个问题
  • 大神之路-起始篇

    欢迎关注 WeiyiGeek 公众号 设为 星标 每天带你 基础入门 到 进阶实践 再到 放弃学习 涉及 网络安全运维 应用开发 物联网IOT 学习路径 个人感悟 等知识 花开堪折直须折 莫待无花空折枝 文章目录 第 4 部分 计算机软件与
  • k8s学习(四) k8s使用nodeport方式配置service对外暴露服务

    Pod是有生命周期的 使用凡人皆有一死来描述pod很贴切 当一个工作节点 node 销毁时 节点上运行的pods也会被销毁 ReplicationController会动态地在其他节点上创建Pod来保持应用程序的运行 每一个Pod都有一个独
  • IDEA的作用

    IDEA IntelliJ IDEA 是一款由 JetBrains 开发的 Java 集成开发环境 IDE 它不仅支持 Java 开发 还支持多种其他编程语言和框架 包括 Kotlin Scala Groovy Android Spring
  • 【Linux运维】Ubuntu Server的无密码开机自动登录

    需求 最近我们在开发一个基于树莓派的小盒子 我们会采购一些树莓派 装好外盒 装好arm版本的 Ubuntu Server 20 04 系统 并且装上我们开发的配套软件 对接我们云端的服务 最终把小盒子卖给用户并提供一些收费的服务 我们在安装
  • ORACLE如何实现行转列

    可通过正则截取实现 例如下图 将 1 2 字符串通过 截取 分为两行数据 Select Regexp Substr 1 2 1 Level As SKU From Dual Connect By Regexp Substr 1 2 1 Le
  • 2022年安全员-C证操作证考试题库及在线模拟考试

    题库来源 安全生产模拟考试一点通公众号小程序 2022安全员 C证理论题库系安全员 C证全部考试题库上机考试练习题 2022年安全员 C证操作证考试题库及在线模拟考试根据安全员 C证最新教材汇编 安全员 C证考试模拟题随时根据安全生产模拟考
  • 一、robotframework 安装

    测试环境 windows 安装前提 已安装python robotframework基于python环境 python安装过程略过 安装的软件参考的这篇博文robot framework自动化测试参考手册 安装python库 安装robot
  • Linux下静态库生成和使用

    一 静态库概念 1 库是预编译的目标文件 object files 的集合 它们可以被链接进程序 静态库以后缀为 a 的特殊的存档 archive file 存储 2 标准系统库可在目录 usr lib与 lib中找到 比如 在类Unix系