当前位置: 首页 > news >正文

linux gcc 静态库的简单介绍

在 Linux 上,使用 GCC 编译器来创建和调用静态库时,涉及的实现原理和调用机制可以分为以下几个步骤:

1. 静态库的创建

静态库(通常以 .a 结尾)是由多个目标文件(.o 文件)打包在一起的归档文件。它们在编译期间被直接链接到应用程序中。

创建静态库的过程

  • 首先编译源文件,生成目标文件(

    .o
    

    文件)。

gcc -c foo.c -o foo.o
gcc -c bar.c -o bar.o
  • 然后使用

    ar
    

    (archive)命令将多个目标文件打包成静态库。

    Copy code
    ar rcs libmylib.a foo.o bar.o
    

这里的 ar 命令的参数:

  • r 表示插入文件或替换已存在的文件。
  • c 表示创建库文件。
  • s 表示创建库文件索引,以便在链接时快速查找函数。

2. 静态库的调用机制

当使用静态库时,库中的代码在编译时被复制到可执行文件中。这意味着:

  • 所有需要的函数和数据从静态库被直接嵌入到最终的可执行文件中。
  • 链接静态库后,生成的可执行文件不需要在运行时再依赖静态库。

链接静态库的过程

  • 编译并链接时,将静态库作为参数传递给 GCC。

    gcc main.c -L. -lmylib -o myapp
    

    这里的参数:

    • -L. 表示链接路径是当前目录。
    • -lmylib 表示链接名为 libmylib.a 的静态库(注意,lib 前缀和 .a 后缀可以省略)。

调用机制

  • 链接器会从静态库中提取所需的目标文件,并将其复制到生成的可执行文件中。
  • 因为所有必要的代码在编译时都被复制到可执行文件中,运行时不会再需要外部库文件。

3. 静态库的原理

  • 归档文件:静态库本质上是一个简单的归档文件,包含多个目标文件和一个索引。索引用于加速链接时对符号的查找。
  • 符号解析:在链接过程中,链接器会解析每个目标文件的符号(如函数和变量名),如果在目标文件中找不到定义,它会尝试在静态库中查找。如果找到匹配的定义,链接器会将静态库中的代码拷贝到可执行文件中。
  • 代码嵌入:静态库中的代码会被直接嵌入到生成的可执行文件中,因此静态库不需要像动态库那样在运行时被加载。结果是可执行文件会变得更大。

4. 优缺点

  • 优点

    • 运行时无需库文件:静态库的代码在编译时就已嵌入,因此在运行时不需要依赖外部库文件,分发程序时只需要分发一个可执行文件即可。
    • 性能:由于不涉及动态加载库,静态库的调用没有额外的运行时开销。
  • 缺点

    • 代码冗余:多个使用同一个静态库的程序会各自拥有该库的一份副本,导致二进制文件变大。
    • 更新不便:一旦静态库更新,所有使用它的程序都需要重新编译。

5. 示例

假设有如下 C 文件:

foo.c:

void foo() {printf("Hello from foo\n");
}

main.c:

#include <stdio.h>void foo(); // 函数声明int main() {foo();return 0;
}

创建静态库:

gcc -c foo.c -o foo.o
ar rcs libfoo.a foo.o

链接并编译:

gcc main.c -L. -lfoo -o myapp

运行程序:

./myapp

总结

静态库在编译时被直接链接到程序中,生成的可执行文件包含了库的所有代码。它的实现原理依赖于目标文件的归档和符号解析,调用机制通过在编译期间将库中的代码复制到最终的可执行文件中完成。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 438 找到字符串中所有字母异位词
  • 以太网传输出现不分包
  • Facebook主页,广告账户,BM被封分别怎么解决?
  • HTTP请求工具类
  • 在 Java 中使用 bean 有什么好处
  • 【人工智能】OpenAI发布GPT-o1模型:推理能力的革命性突破,这将再次刷新编程领域的格局!
  • 使用 Docker 进入容器并运行命令的详细指南
  • c++ 编辑器 和 编译器 的详细解释
  • centos 7 升级Docker 与Docker-Compose 到最新版本
  • Android以及IoT设备传感器软件开发总结
  • Docker 安装配置和基本命令详解以及案例示范
  • Vue安装及环境配置【图解版】
  • Fisco Bcos 2.11.0通过网络和本地二进制文件搭建单机节点联盟链网络(搭建你的第一个区块链网络)
  • SAP自动化-ME12批量更新某行价格
  • 京东广告投放平台整洁架构演进之路
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • Elasticsearch 参考指南(升级前重新索引)
  • EventListener原理
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • JavaScript 奇技淫巧
  • Sublime Text 2/3 绑定Eclipse快捷键
  • TypeScript迭代器
  • vue-cli在webpack的配置文件探究
  • 不上全站https的网站你们就等着被恶心死吧
  • 官方解决所有 npm 全局安装权限问题
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 三栏布局总结
  • 小而合理的前端理论:rscss和rsjs
  • 云大使推广中的常见热门问题
  • ​​​​​​​STM32通过SPI硬件读写W25Q64
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #AngularJS#$sce.trustAsResourceUrl
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (02)Hive SQL编译成MapReduce任务的过程
  • (2015)JS ES6 必知的十个 特性
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (5)STL算法之复制
  • (C语言)球球大作战
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (十)c52学习之旅-定时器实验
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (十三)Flask之特殊装饰器详解
  • (五)activiti-modeler 编辑器初步优化
  • (学习总结16)C++模版2
  • (一)kafka实战——kafka源码编译启动
  • (转)母版页和相对路径
  • (状压dp)uva 10817 Headmaster's Headache
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET 材料检测系统崩溃分析
  • .NET 发展历程
  • .net(C#)中String.Format如何使用