-
2021-04-21 09:56:21
假设A.a, B.a C.a 在/usr/local/lib目录下
mkdir /tmp/libABC
cd /tmp/libABC
ar x /usr/local/lib/A.a
ar x /usr/local/lib/B.a
ar x /usr/local/lib/C.a
ar cru libABC.a *.o
ranlib libABC.a动态库改为so
更多相关内容 -
Linux编程:合并静态库
2022-04-19 10:39:52Linux编程:合并静态库 在项目开发过程中,会存在经常使用的模块,按照代码复用的思想,可以将这些通用的模块生成库,以此减少开发代码量。如果一个项目引用的库文件比较多,管理起来也不方便,也可以将这些库合并为...Linux编程:合并静态库
在项目开发过程中,会存在经常使用的模块,按照代码复用的思想,可以将这些通用的模块生成库,以此减少开发代码量。如果一个项目引用的库文件比较多,管理起来也不方便,也可以将这些库合并为一个。
1、
ar
基本用法ar
命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。
使用命令
ar -h
可以查看帮助,我们把{dmpqrtx}
部分称为操作选项,而[abcfilNoPsSuvV]
部分称为任选项。Usage: ar [emulation options] [-]{dmpqrstx}[abcDfilMNoOPsSTuvV] [--plugin <name>] [member-name] [count] archive-file file... ar -M [<mri-script] commands: d - delete file(s) from the archive m[ab] - move file(s) in the archive p - print file(s) found in the archive q[f] - quick append file(s) to the archive r[ab][f][u] - replace existing or insert new file(s) into the archive s - act as ranlib t[O][v] - display contents of the archive x[o] - extract file(s) from the archive command specific modifiers: [a] - put file(s) after [member-name] [b] - put file(s) before [member-name] (same as [i]) [D] - use zero for timestamps and uids/gids (default) [U] - use actual timestamps and uids/gids [N] - use instance [count] of name [f] - truncate inserted file names [P] - use full path names when matching [o] - preserve original dates [O] - display offsets of files in the archive [u] - only replace files that are newer than current archive contents generic modifiers: [c] - do not warn if the library had to be created [s] - create an archive index (cf. ranlib) [S] - do not build a symbol table [T] - make a thin archive [v] - be verbose [V] - display the version number @<file> - read options from <file> --target=BFDNAME - specify the target object format as BFDNAME --output=DIRNAME - specify the output directory for extraction operations optional: --plugin <p> - load the specified plugin emulation options: No emulation specific options ar: supported targets: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 pei-i386 pei-x86-64 elf64-l1om elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 srec symbolsrec verilog tekhex binary ihex plugin Report bugs to <http://www.sourceware.org/bugzilla/>
操作选项说明如下:
d
:从库中删除模块。按模块原来的文件名指定要删除的模块。如果使用了任选项v则列出被删除的每个模块。m[ab]
:该操作是在一个库中移动成员。当库中如果有若干模块有相同的符号定义(如函数定义),则成员的位置顺序很重要。如果没有指定任选项,任何指定的成员将移到库的最后。也可以使用a
,b
,或i
任选项移动到指定的位置。p
:显示库中指定的成员到标准输出。如果指定任选项v,则在输出成员的内容前,将显示成员的名字。如果没有指定成员的名字,所有库中的文件将显示出来。q[f]
:快速追加。增加新模块到库的结尾处。并不检查是否需要替换。a
,b
,或i
任选项对此操作没有影响,模块总是追加的库的结尾处。如果使用了任选项v则列出每个模块。 这时,库的符号表没有更新,可以用ar s
或ranlib
来更新库的符号表索引。r[ab][f][u]
:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。如果若干模块中有一个模块在库中不存在,ar
显示一个错误消息,并不替换其他同名模块。默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。s
: 作为ranlib
t[O][v]
:显示库的模块表清单。一般只显示模块名。x[o]
:从库中提取一个成员。如果不指定要提取的模块,则提取库中所有的模块。
任选项说明如下:
- a:在库的一个已经存在的成员后面增加一个新的文件。如果使用任选项
a
,则应该为命令行中member-name
参数指定一个已经存在的成员名。 - b:在库的一个已经存在的成员前面增加一个新的文件。如果使用任选项
b
,则应该为命令行中member-name
参数指定一个已经存在的成员名。 - c:创建一个库。不管库是否存在,都将创建。
- f:在库中截短指定的名字。缺省情况下,文件名的长度是不受限制的,可以使用此参数将文件名截短,以保证与其它系统的兼容。
- i:在库的一个已经存在的成员前面增加一个新的文件。如果使用任选项
i
,则应该为命令行中member-name
参数指定一个已经存在的成员名(类似任选项b
)。 - l:暂未使用
- N:与
count
参数一起使用,在库中有多个相同的文件名时指定提取或输出的个数。 - o:当提取成员时,保留成员的原始数据。如果不指定该任选项,则提取出的模块的时间将标为提取出的时间。
- P:进行文件名匹配时使用全路径名。
ar
在创建库时不能使用全路径名(这样的库文件不符合POSIX
标准),但是有些工具可以。 - s:写入一个目标文件索引到库中,或者更新一个存在的目标文件索引。甚至对于没有任何变化的库也作该动作。对一个库做
ar s
等同于对该库做ranlib
。 - S:不创建目标文件索引,这在创建较大的库时能加快时间。
- u:一般说来,命令
ar r...
插入所有列出的文件到库中,如果你只想插入列出文件中那些比库中同名文件新的文件,就可以使用该任选项。该任选项只用于r操作选项。 - v:该选项用来显示执行操作选项的附加信息。
- V:显示
ar
的版本。
2、合并静态库
假设存在三个静态库:
oldlib1.a、oldlib2.a、oldlib3.a
,需要合并为新静态库:newlib.a
- 方法一
LIB_OUTPUT=${PWD}/build/output # 解包,获取*.o文件,静态库的模块是.o文件 ar x oldlib1.a --output=${LIB_OUTPUT} ar x oldlib2.a --output=${LIB_OUTPUT} ar x oldlib3.a --output=${LIB_OUTPUT} # 打包 cd ${LIB_OUTPUT} ar crsv newlib.a *.o # 清理 rm *.o
- 方法二
ar crsT newlib.a oldLib1.a oldlib2.a oldlib3.a
- 方法三
(1)先编写一个
mri
脚本,如newlib.mri
,内容如下create newlib.a addlib oldlib1.a addlib oldlib2.a addlib oldlib3.a save end
(2)执行该脚本
ar -M <./newlib.mri
参考链接
-
linux 合并多个静态库为一个静态库
2020-11-19 17:22:09Linux 合并多个静态库为一个静态库 Linux 下可以使用 ar 命令对多个静态库做合并。可以按照如下方式合并静态库。 获取全部需合并的静态库 使用 ar -x 对 静态库解压为 .o 文件 使用 ar cr 对静态库做合并 # [可选]... -
cmakelists 生成静态库,然后用静态库生成动态库,然后生成测试程序
2020-10-12 19:43:291:模块化CMakeLists 的写法 2:每个模块先生成静态库 3:把各个静态库生成一个动态库 4:生成一个测试demo 验证动态库 -
linux静态库和动态库编译及使用
2021-05-12 00:33:31也可以通过设置环]境变量C_INCLUDE_PATH来指定头文件目录,怎样设置可参看http://www.voidcn.com/article/p-ecxrzhpz-xw.html 额外知识点: 1 Linux静态库的命名规则 static library filename = lib + + .a .../**************************************************************************/
/*add.c*/
int add(int x, int y)
{
return x + y;
return 0;
}
/*************************************************************************/
然后add.h代码为:
/*add.h*/
#ifndef _ADD_H_
#define _ADD_H_
int add(int, int);
#endif
/***************************************************************************/
main函数代码:
/*main.c*/
#include
int main(void)
{
printf("2+3= %d\n", add(2,3));
return 0;
}
/**********************************************************************************/
1 静态库的编译流程
将add.c 单独的源文件编译成静态库libadd.a
gcc -c add.c //生成 add.o
ar crv libadd.a add.o // 生成静态库libadd.a
2 静态库的使用
gcc -o main main.c -I. -L. -ladd (注: -I -L -l的意思在文章后面)
也可以: gcc -o main main.c -I ./libadd.a (注:这里 ./libadd.a 可以是相对地址或者绝对地址 如:./lib/libadd.a , /home/lisi/lib/lib.a)
3 动态库的编译流程
gcc -fPIC -c add.c // 生成add.o
gcc -shared -o libadd.so add.o // 或者使用 ar crv libadd.so add.o
上面可合并成一行: gcc -fPIC -shared -o libadd.so add.c
注: -fPIC 使输出的对象模块是按照可重定位地址方式生成的(即与位置无关).
-shared 指定把对应的源文件生成对应的动态链接库库文件libstr.so文件
4 动态库的使用
4.1 隐式调用
代码编写与静态库一样,不需要包含到处函数的头文件,若主函数是C++程序(即.cpp), 则需要在main.cpp中用extern "C"{} 包含被调用的函数(add.c)的头文件(这里需要包含头文件是与.cpp和.c混合编译有关,同静态\动态库无关),用g++或者用gcc(加上一个链接的参数 -lstdc++)编译.
1 )代码编写:与静态库一样
2 ) 编译main.c 生成可执行程序(动态库隐式调用的使用)
gcc -o main main.c ./libadd.so
或者 gcc -o main main.c -L. libadd.so
(
注:以上两种情况执行./main时会出现./main: error while loading shared libraries,cannot open shared object file: No such file or directory?
解决方案:
方法一: libadd.so放到/usr/lib 或 /lib 中去.
方法二: export LD_LIBRARY_PATH=$(pwd) 或者 export LD_LIBRARY_PATH=./ ,
方法三: 在/etc/ld.so.conf文件加入我们生成的库目录(只支持绝对路径),然后执行 #/sbin/ldconfig.
)
或者将libadd.so 拷贝到目录 /user/lib 或者 /lib 中,然后执行 gcc -o main main.c libadd.so //此时不需要指定搜索路径
4.2 显示调用
4.2.1 在main.c 中增加头文件 #include 引入dlopen , dlsym , dlclose , dlerror 几个系统调用
主要介绍dlopen()系统调用
第一个参数:指定共享库的名称,将会在下面位置查找指定的共享库.
-环境变量 LD_LIBARARY_PATH列出的用冒号间隔的所有目录
-文件/etc/ld.so.cache重找到库的列表,用 ldconfig 维护
-目录/usr/lib
-目录/lib
-当前目录
第二个参数:指定打开共享库.
-RTLD_NOW:将共享库重的所有函数加载到内存
-RTLD_LAZY:会退后共享库中的函数的加载操作,知道调用dlsym()时方加载某函数
返回值:返回动态库的句柄
#include
#include
int main()
{
int (*func)(int , int );
void *dl = dlopen("./libadd.so", RTLD_LAZY);
if (dl == NULL)
return -1;
func = dlsym(dl, "add");
if (func == NULL)
return -1;
printf("2+3=%d", func(2, 3));
dlclose(dl);
return 0;
}
4.2.2 编译main.c生成可执行程序,动态库已创建
gcc -o main main.c -ldl // 注:使用libld.so库进行系统调用
5 动态库使用中遇到的问题
gcc编译文件时出现undefined reference to 'xxxx'的错误?
这是链接错误,不是编译错误,源程序代码本身没有问题,是你的编译时参数用的不对.你没有指定连接程序要用到的库,比如你的程序里用到了一些数学函数sqrt ,那么你就要在编译参数里指定程序要链接数学库,eg:gcc -o math math.c -lm.
6 gcc中一些参数的作用
6.1 -l 参数和 -L参数
-l 参数就是用来指定程序要链接的库, -l 参数紧接着就是库名, 那么库名跟真正的库文件名有什么关系呢?拿数学库来说,他的库名是m ,他的库文件名是 libm.so ,很容易看出,把库文件名的lib和尾.so 去掉就是库名了. 如第三方库名字叫做libtest.so 那么我们只需要把libtest.so 拷贝到 /usr/lib 或者 /usr/local/lib里,在编译时加上 -ltest 参数,我们就能用上libtest.so库了.
注意:要用libtest.so 库里的函数,我们还需要与libtest.so 配套的头文件.eg:gcc -o test test.c -ltest(libtest.so 的隐式调用)
6.2 -include 和-I参数
-include 用来包含头文件,但是一般情况下包含头文件都在源码里用#include xxx 实现, -include 参数很少用. -I参数用来指定头文件目录.
/usr/include 目录一般是不用指定的,gcc 知道去那里找,但是如果头文件不在 /usr/include 里我们就要用 -I参数指定. 比如 头文件放在 /myinclude目录里,那么便以命令行就加上-I/myinclude 参数,如果不加就会得到 "xx.h: No such file or deirectory "的错误. (注-I参数也可以用相对路径,比如当前目录,可以用 -I. 来指定). 也可以通过设置环]境变量C_INCLUDE_PATH来指定头文件目录,怎样设置可参看http://www.voidcn.com/article/p-ecxrzhpz-xw.html
额外知识点:
1 Linux静态库的命名规则
static library filename =
lib + +
.a
静态库文件名中间那一部分是库的实际名称,链接器需要使用这个名称来进行链接。
2 Linux动态库命名规则
dynamic library filename =
lib + +
.so +
动态库文件名中间那一部分是库的实际名称,链接器会在随后的构建时库文件搜索过程中使用这个名称,装在器也会在运行时库文件搜索过程中使用这个名称。
3 动态库的版本信息
dynamic library version information =
..
其中,每个助记符可能使用一个或多个数字来表示
M:主版本号
m:次版本号
p:补丁(很小的代码改动)版本号
4 动态库的soname
library
soname = lib +
name> +
.so +
major version digit(s)>
举例来说,库文件libz.so.1.2.3.4的soname则是libz.so.1
实际上只有主版本好的数字在库soname中起作用,这意味着即使库的次版本好是不同的,也可能使用同一个soname值来表示。
动态库的soname通产由链接器嵌入二进制库文件的专有ELF字段中。通常使用特定的链接器选项,将表示库soname的字符串传递给链接器。比如
$ gcc -shared -Wl, -soname, libfoo.so.1 -o libfoo.so.1.0.0
-
静态库进行合并/添加成一个动态/静态库
2021-09-06 20:48:49静态库进行合并/添加成一个动态/静态库静态库静态库包含所有子静态库动态库动态库包含所有静态库总结参考博客链接 静态库 静态库包含所有子静态库 [root@ggy lib]# ls liblib1.a liblib2.a liblib3.a [root@ggy ... -
Linux下将多个静态库(.a)合并成一个静态库文件(.a)的命令操作,方法一
2016-05-26 00:38:00.a文件的结构和.tar文件就没有什么区别。x命令解出来,a命令添加,t命令列表 假设A.a,B.aC.a在/usr/local/lib目录下 mkdir/tmp/libABC cd/tmp/libABC arx/usr/local/lib/A.a ...arx/usr/local/lib/B.a ... -
Android 将多个静态库合并为一个静态库或动态库
2019-06-11 16:30:02有时我们使用第三方提供的静态库加上我们自己的代码需要重新编译出库文件或可执行文件,如果生成可执行文件直接参考https://blog.csdn.net/u013463707/article/details/90754571 即可。 但是如果还想生成库文件,... -
将多个静态库合并为一个静态库(使用安卓NDK编译链)
2020-10-17 23:06:25将多个静态库合并为一个静态库 先学习两个命令 静态库好比一个压缩包,使用ar x libxxx.a可将里面的.o文件还原 ar x libxxx.a 使用ar rc libtarget.a a.o b.o c.o xxx.o可将多个.o打包为一个.a ar rc ... -
gcc gdb 入门 以及合并linux静态库的方法
2012-12-20 17:59:04图文并茂,附带简单例子,非常适合新手入门 -
linux 动态库和静态库分析实例
2018-04-28 11:35:33今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻。在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情。 在Linux操作系统中,普遍使用ELF格式作为可执行程序... -
linux中如何将多个静态库合并成一个
2017-02-28 14:12:04 -
【名名的Bazel笔记】自定义规则实现将多个静态库合并为一个动态库或静态库
2020-09-19 14:46:11为了实现如标题所述的将多个静态库合并为一个动态库,内置的 Bazel 规则是没有这个功能的,Bazel C/C++ 相关的内置规则有: cc_binary :生成可执行文件 cc_import :允许用户导入预编译的 C/C++ 库,包括动态库、... -
Linux合并多个静态库.a为一个.a
2021-03-08 16:52:13Linux合并多个静态库.a为一个.a 其他标题索引: 静态库再打包 多个静态库打包成一个 思路: 再打包需要将当前的.a文件解包.o文件,然后统一打包成新的.a文件。 环境(将所有的.a文件放到lib目录下,在lib的... -
使用openCV的静态库编译
2021-05-13 03:47:52转载请注明出处:By 少侠阿朱摘要:本文主要讲述如何使用opencv静态库进行编译,生成脱离opencv环境可执行.exe文件。实现的效果:此方法生成的exe文件在其他没有配置openCV环境的电脑上可直接执行。使用到的工具:... -
FFmpeg----将多个静态库合并成一个动态库
2018-02-26 19:20:58# 这里选择最低支持android-14, arm架构,生成的so库是放在 # libs/armeabi文件夹下的,若针对x86架构,要选择arch-x86 PLATFORM=$NDK/platforms/android- 14 /arch-arm # 工具链的路径,根据编译的平台不同而... -
静态库的符号解析和重定义处理策略
2021-05-17 21:14:05一、什么是静态库将多个普通目标文件打包成为一个单独的文件,称为静态库。静态库是为了解决以下问题而出现的:(1)C用户需要使用大量的C函数库把所有的代码放在一个.c文件中,然后产品代码一起编译链接,虽然可以... -
Linux 合并多个.a 静态库文件
2020-07-16 18:46:04假设合并后的静态库名称为 newLib.a 方法一: ar x oldlib1.a ar x oldlib2.a ar x oldlib3.a ar crsv newLib.a *.o 方法 二: ar crsT newLib.a oldLib1.a oldlib2.a oldlib3.a 方法三: (1)先编写一... -
如何编译静态库及将多个.a静态库合并成一个.a静态库
2018-09-26 14:00:33所使用的命令为ar ...3 编译.a 静态库 1)生成对应的.o 文件 gcc -c a.c b.c 2)使用ar命令合成静态库 ar crs libjson.a *.o 3) 查看编译库使用的gcc 版本: strings libjson.a |grep GCC 4) 调用方法: gc... -
Linux平台下,静态库与动态库的创建
2022-04-23 16:01:34静态函数库名字一般是:libxxx...1.静态库的制作 ① 准备测试文件: // 源文件 add.c #include <stdio.h> #include "head.h" int add(int a, int b) { return a+b; } // 源文件 mult.c #include <st -
windows 、linux 下 多个静态库合并成一个静态库
2016-08-28 21:08:33第一步、 打开visual studio 下的对应平台...Linux下将多个静态库(.a)合并成一个静态库文件(.a)的命令操作 .a 文件的结构和.tar文件就没有什么区别。 x 命令解出来, a 命令添加, t命令列表 假设A.a, B.a C.a 在/us -
Linux系统中“动态库”和“静态库”那点事儿
2016-10-28 17:41:08今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻。在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情。 在Linux操作系统中,普遍使用ELF格式作为可执行... -
在linux上创建库文件,静态库和动态库的区别
2019-05-14 21:15:431.静态库 1)功能代码编译成中间文件 gcc -c *.c //生成.o的中间文件 2)使用命令 ar ar crv libxxxx.a *.o //"libxxxx"为前缀lib+库文件的名称(静态库后缀名为.a) 3)生成可执行文件 gcc -o main main.c -L库的... -
linux库概念、静态库、动态库学习
2022-01-06 01:51:07就是将源代码转化为二进制格式的源代码,相当于进行了加密,别人可以使用库,但是看不到库中的内容。 一、库是什么? 我们在编写程序的时候调用的库,会有<>和""。比如#include <stdio.... -
linux编程合并多个静态库.a为一个.a
2017-12-27 20:00:00现在说本文的重点,合并静态库。 有关制作静态库命令可以参考 linux ar命令 而静态库的使用,百度一下。 注意链接文章说的,静态库的模块是.o文件。 之前我一直想把一个静态库包含到另一个静态库里,比如:... -
linux上静态库和动态库的编译和使用
2018-12-30 23:02:02一、linux上静态库和动态库的编译和使用 1.1 特点 动态库特点: 1、库的代码不会编译进程序里面,所以动态库编译的程序比较小。 2、由动态库编译的程序依赖于系统的环境变量有没有这个库文件,没有则运行不... -
Linux 动态库和静态库
2017-09-07 16:14:56库分静态库和动态库两种。 静态库:这类库的名字一般是 libxxx.a,xxx为库的名字。利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序... -
linux 静态库,动态库编译
2022-04-10 20:43:09静态库编译 例子: 源文件fun.cpp gcc -c fun.cpp 生成 fun.o ar rcsv libname.a fun.o // 生成静态库libname.a 具体ar命令参数可查看帮助文档 动态库编译 gcc -fPIC -c fun.c // 生成 fun.o gcc -... -
Linux静态库(含依赖库)实战与简析
2014-08-08 09:41:43Linux中无论是动态库还是静态库,都有可能存在依赖关系。如 -
2022-3-15 封装静态库调用其他静态库
2022-03-15 20:55:24如何编译静态库及将多个.a静态库合并成一个.a静态库 .a文件拆分成.o文件然后再组合新.a库 静态库链接动态库时,如何使用该静态库 静态库libXXX.a并没有把动态库的函数copy到自己身上,只留了符号表,所以main.c要用...