如何将两个"ar"静态库合并为一个?

osg*_*sgx 80 linux static-libraries unix-ar

我有2个静态的Linux库,通过创建ar cr,libabc.alibxyz.a.
我想将它们合并到一个静态库中libaz.a.
我怎样才能做到这一点.

我想创建一个合并的静态库,而不是让两个库都给应用程序的最终链接.

Gui*_*ver 100

至少有三种方法可以做到这一点.第一种也是最便携的方法是使用libtool.在使用libtool构建其他库之后,只需将.la库添加到automake libaz_la_LIBADD变量中,或者直接从Makefile中添加类似于以下内容的组合它们:

libtool --mode=link cc -static -o libaz.la libabc.la libxyz.la
Run Code Online (Sandbox Code Playgroud)

使用GNU ar时,另外两个至少可用.您可以使用MRI脚本(例如libaz.mri命名),例如:

create libaz.a
addlib libabc.a
addlib libxyz.a
save
end
Run Code Online (Sandbox Code Playgroud)

然后执行ar as:

ar -M <libaz.mri
Run Code Online (Sandbox Code Playgroud)

或者您可以使用精简存档(选项-T),这将允许添加其他存档而不会将它们嵌套在内部,但缺点是如果您要分发静态库,则分离的对象将丢失:

ar -rcT libaz.a libabc.a libxyz.a
Run Code Online (Sandbox Code Playgroud)

以上所有方法都可以优雅地处理原始存档中的重叠成员名称.

否则,您必须解压缩到不同的目录并再次重新打包,以避免替换重叠的成员名称:

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz
Run Code Online (Sandbox Code Playgroud)

  • 对于那些想要正常存档(不是瘦)的人来说,可以做的一件简单事就是创建一个瘦存档,然后将其转换为普通存档.类似于:`ar cqT libaz.a libabc.a libxyz.a && echo -e'create libaz.a \naddlib libaz.a \nsave \nend'| ar -M`.这会创建一个临时的瘦`libaz.a`,然后将瘦存档转换为普通存档(这样你就可以移动/分发它).当你的库名称有特殊字符(间隔,加号或逗号)时,这也可以优雅地处理(即`ar cqT libbundle.a libfoo ++.'libbar baz.a'.).但是来自我的+1! (12认同)
  • 嘿,当我尝试使用“libtool”命令时,我收到以下错误:“libtool:链接:无法推断标记配置 libtool:错误:用“--tag”指定标签“有什么想法如何解决这个问题吗? (2认同)

cod*_*ict 52

您可以从两个.a文件中提取对象,并.a使用提取的.os 创建文件:

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o
Run Code Online (Sandbox Code Playgroud)

  • 威尔罗宾逊,危险!如果libabc.a和libxyz.a中成员的名称不重叠,则此方法_only_.否则你将覆盖一个,它将丢失. (53认同)
  • `ar -c`对我不起作用(Ubuntu 14.04).我得到了'ar:没有指定操作'.我做了'ar -qc`而且效果很好. (13认同)
  • 而且,`libabc.a`可能包含具有相同名称的对象(源自不同的目录) - 重新组装将不起作用! (5认同)

小智 8

如果您只是这样做:

ar x a.a
ar x b.a
ar c c.a  *.o 
Run Code Online (Sandbox Code Playgroud)

如果在aa和ba中都有同名的成员,你将丢失一些目标文件,因此,你需要将不同档案的成员提取到不同的文件夹中:

ar x a.a && mv *.o a_objs
ar x b.a && mv *.o b_objs
ar c c.a a_objs/*.o b_objs/*.o
Run Code Online (Sandbox Code Playgroud)

更重要的是,在一个档案中有多个同名的成员(比如说aa),如果你运行ar x aa,你只能得到一个同名的成员.

在一个存档中提取同名的所有成员的唯一方法是通过选项'N'指定成员编号:

ar xN 1 a.a  xxx.c.o && mv xxx.c.o xxx.c.1.o
ar xN 2 b.a  xxx.c.o && mv xxx.c.o xxx.c.2.o
...
Run Code Online (Sandbox Code Playgroud)

这将是一项繁琐的工作,所以你必须编写一个更复杂的脚本来完成这项工作.

一个可选的解决方案是您可以将多个归档组合到一个共享库中:

g++ -shared -o c.so -Wl,--whole-archive a.a b.a 
Run Code Online (Sandbox Code Playgroud)

通过这种方式,链接器将为您处理所有事情!

  • 塞缪尔,谢谢你。但在组合到共享库中时,所有对象都应该使用“-fPIC”进行编译。 (2认同)