bazel 链接第三方动态库_如何自己制作静态库?
前言
在《一文带你了解静态库和动态库》一文中介绍了静态库的特点以及与动态库的区别。那么你有没有想过如何把自己写好的函数接口制作成静态库给别人用呢?本文教你如何制作属于自己的静态库。
编译成可重定位文件
在《一文带你了解静态库和动态库》简单介绍了可重定位文件。其中也有一位非常细心的读者发现,在ubuntu18.04的系统,使用gcc7.4编译出来的可执行文件的type是DYN,这是编译器生成了一种位置无关的可执行文件(PIE),它类似于动态库,其地址在加载时确定,从而更加安全。本文不再展开介绍。
本文实例代码test1.c代码如下:
//来源:公众号【编程珠玑】 网站:https://www.yanbinghu.com
编译成可重定位文件,即生成.o文件:
$ gcc -c test1.c
$ readelf -h test1.o
ELF Header:Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: REL (Relocatable file)Machine: Advanced Micro Devices X86-64
(省略部分内容)
关于编译的几个阶段,可以参考《代码是如何变成可执行文件的》。
制作成静态库
为了制作成静态库,我们需要使用ar命令。
$ ar -rcs libtest1.a test1.o #库名一般以.a为扩展名,以lib开头
$ ar -t libtest1.a #查看内容
test1.o
通常来说,静态库以.a作为后缀,且以lib开头。至此就将我们提供的test1函数做成了静态库,但是为了方便其他人使用,我们再提供一个头文件test1.h,代码如下:
#include<stdio.h>
void test1();
这个时候就可以将我们做好的静态库给其他人使用啦。
使用静态库
我们写一个main.c来调用test1():
//来源:公众号【编程珠玑】 网站:https://www.yanbinghu.com
编译运行:
$ gcc -o main main.c -L ./ -ltest1
$ ./main
I am test1
其中-L用于指定链接库的路径,由于我们要链接的库名为libtest1.a,在链接的时候,去掉开头的lib和后缀.a,前面再加l,就变成了-ltest1,其他库也是类似。例如,你如果看到程序链接使用-lm,说明它使用了名为libm.a的库。
特别说明,有的机器上默认生成的可执行文件类型为DYN,它是一种与位置无关的可执行文件(PIE)。
再看静态库使用
如果这时候还有一个库libtest0.a,库中调用了test1.c的函数,而main函数调用了libtest0.a中的函数呢?即,假设有test0.c中调用test1(),且两者位于不同的库中,test0.c代码如下:
#include
头文件test0.h:
#include"test1.h"
void test0();
还是以类似的方法制作静态库libtest0.a:
$ gcc -c test0.c
$ ar -rcs libtest0.a test0.o
改写main.c:
//来源:公众号【编程珠玑】 网站:https://www.yanbinghu.com
重新编译链接:
$ gcc -o main main.c -L ./ -ltest1 -ltest0
.//libtest0.a(test0.o): In function `test0':
test0.c:(.text+0x14): undefined reference to `test1'
collect2: error: ld returned 1 exit status
这里我们发现编译出错了,提示test1未定义,很显然是由于test0中调用了test1。至于解决办法也很简单,调整链接库的顺序即可,更加详细的原因可以参考《一个奇怪的链接问题》和《静态库和动态库的区别》。
我们调整之后再次编译链接并运行:
$ gcc -o main main.c -L ./ -ltest0 -ltest1
$ ./main
I am test0,I will call test1
I am test1
test0 call test1 end
可以看到,在调整两个库的顺序之后,编译链接正常,并且程序也按照我们预期的结果运行。
因此,我们在链接时,应该尽量把被需要的库放在后面。
本文作者:守望
来源:https://www.yanbinghu.com
ar命令详解
从前面的内容我们可以观察到,我们是通过ar命令来制作静态库(归档文件)的,它可以将多个按照一定的规则组织在一起。我们再来了解一下ar命令,ar命令常见参数如下:
- r 向归档文件中添加内容,如原先已存在,则替换
- c 创建归档文件
- s 添加索引信息
- d 从归档文件中删除
- t 查看归档文件的内容
- x 解压归档文件
- a/b 向归档文件中添加内容
- v 显示详细信息
rcs参数我们已经在前面用到了。-a(after)或者-b(before)参数可以向归档文件中添加文件,例如:
$ ar -ra test0.o libtest0.a test1.o
这里表示在libtest0.a中的test0.o之后,添加test1.o。
添加后内容如下:
$ ar -t libtest0.a
test0.o
test1.o
当然了,归档文件是可以解开的,比如:
$ ar -xv libtest0.a
x - test0.o
x - test1.o
你要删除其中的某个文件,也是没人阻止的:
$ ar -d test1.o libtest0.a
d - test1.o
-d参数后面跟着要移除的文件。
需要特别注意的是,这里ar归档的作用并不仅仅针对可重定位目标文件,而是几乎针对任何类型的普通文件。
总结
制作静态库不过是利用ar命令把一些文件可重定位文件打包在一起,其他程序在使用时需要通过链接动态将自己需要的内容“拷贝”到最终的可执行文件中。现在知道如何制作属于自己的静态库了吗?赶紧自己试试吧!
微信公众号【编程珠玑】:专注但不限于分享计算机编程基础,Linux,C语言,C++,数据结构与算法,工具,资源等编程相关[原创]技术文章。
bazel 链接第三方动态库_如何自己制作静态库?相关推荐
- bazel 链接第三方动态库_Linux 动态库与静态库制作及使用详解
Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 Linux 版本下不兼容的问题: 2)在 Linux 静态库的制作过程中发现有别于 Windo ...
- bazel 链接第三方动态库_惠州权威信息系统安全检测第三方
惠州权威信息系统安全检测第三方 dga55b69 惠州权威信息系统安全检测第三方 IOT渗透测试是一项基于STRIDE模型对功能业务进行威胁发现的服务.从而避攻击者通过IDAP等逆向工具反编译SO.M ...
- bazel 链接第三方动态库_C/C++编程知识:Linux 动态库相关知识整理
动态库和静态库在C/C++开发中很常见,相比静态库直接被编译到可执行程序,动态库运行时加载使得可执行程序的体积更小,更新动态库可以不用重新编译可执行程序等诸多好处.作者是一个Linux后台开发,这些知 ...
- bazel 链接第三方动态库_C语言学习篇(31)——linux中制作动态链接库
引言 前面我们讲解了什么是函数库(函数库就是一些事先写好的函数集合),函数库有什么作用(可以打包我们的编写的源代码,供他人使用,同时源码不可见,保护了自己的知识产权)以及函数库有2种提供方式:静态链接 ...
- python生成静态库_使用boost.python静态库
编译脚本为: bjam stage toolset=msvc link=static runtime-link=shared threading=multi variant=debug,release ...
- bazel 链接第三方动态库_nodejs 实现虎牙动态弹幕工具
概述: 最近迷上王者荣耀张大仙的虎牙直播,除了大仙幽默风趣解说之外,粉丝的弹幕互动也比较搞笑,一般大v的直播房间,弹幕满屏,不太方便看,突发奇想是是否可以做一款工具,动态获取直播房间的弹幕信息, 通过 ...
- bazel 链接第三方动态库_Windows最好用的动态壁纸软件,用了都说好!!
Wallpaper Engine相信不少小伙伴都听说过,是一款非常专业的动态壁纸软件,目前在Steam售价19元,其实也不算贵,但是个人总觉得花这钱整一个动态壁纸软件,不是很划算,毕竟不是必需品啊!用 ...
- xcode6制作静态库详解
开发IOS程序时我们使用的是Objective-c语言,Objective-c语言有.h .m 文件组成.静态库可以将 .m文件封装成一个.a文件,第三方应用程序只需要拿到这个.a文件和代码对应的.h ...
- 【C语言】标准库(头文件、静态库、动态库),windows与Linux平台下的常用C语言标准库
一.Introduction 1.1 C语言标准库 1.2 历代C语言标准 1.3 主流C语言编译器 二.C语言标准库 2.1 常用标准头文件 2.2 常用标准静态库 三.windows平台 四.Li ...
最新文章
- iOS之百度导航SDK的坐标转换
- (001) java后台开发之流程初识
- java实体类怎么写_Java中(entity)实体类的书写规范
- idea编译的文件怎么用cmd打开_JAVA学习册|基础语法|cmd输出HelloWorld
- CSS清除行内元素之间的HTML空白
- yctx mysql.sql_MySQL 安装指南
- 机器学习与深度学习常见面试题
- 电商seo培训之卖家搜索优化步骤
- Lecture 008-Heuristic algorithms
- 网络安全——WEP实现无线局域网安全
- html网页屏保,屏幕保护是什么
- echarts绘制嵌套环形图(南丁格尔玫瑰图)
- 恢复VMware误删虚拟机
- 2021-12-22 AndroidR 电池信息 简单分析记录
- java long保留两位小数
- 华为云数据库助力微鲤科技智能升级
- glassfish java ee_GlassFish 3.1.2发布 开源的JavaEE应用服务器
- 萧乾升:4.2黄金白银TD原油休市下周实时行情分析走势
- java编写家庭收支记录,Java家庭收支记账小项目(java基础)
- 大一计算机专业学生,该如何自学数据结构和算法
热门文章
- 高等数学二python实现导数与微分
- 基于JAVA+SpringMVC+Mybatis+MYSQL的药店门店管理系统
- [Reinforcement Learning] Value Function Approximation
- Macaca上手体验
- Python爬虫:用BeautifulSoup进行NBA数据爬取
- Perl opendir()函数
- SPSS数据分析之列联分析与卡方检验、方差分析与LSD方法【操作详解】
- 初学者python笔记(time模块、random模块功能分析)
- energy in transition课文翻译_思迪软件科技 招聘 字幕翻译(远程兼职)
- inset() php,inset.php · L@Y/studentscoremanagementsystem - Gitee.com