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

我有2个静态 Linux 库,由 ar crlibabc.alibxyz.a创建。
我想把它们合并到一个静态库 libaz.a中。
How can I do this.

我希望创建一个合并的静态库,而不是将两个库都提供给应用程序的最终链接。

100741 次浏览

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

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o

如果你只是这样做:

ar x a.a
ar x b.a
ar c c.a  *.o

如果 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

此外,一个归档文件中可能有多个同名成员(比如 a.a) ,如果运行 Ar x a a,那么对于这些同名成员,只能得到一个。

在一个存档中提取所有相同名称的成员的唯一方法是通过选项‘ 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
...

这将是一项乏味的工作,因此您必须编写一个更复杂的脚本来完成这项工作。

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

g++ -shared -o c.so -Wl,--whole-archive a.a b.a

这样连接器会为你处理所有的事情!

至少有三种方法可以做到这一点。第一种也是最可移植的方法是使用 libtool。在使用 libtool 构建了其他库之后,可以通过添加。La libs 转换为自动生成的 libaz _ la _ LIBADD 变量,或者直接从 Makefile 转换为:

libtool --mode=link cc -static -o libaz.la libabc.la libxyz.la

另外两个至少在使用 GNUar 时是可用的。您可以使用 MRI 脚本(例如 libaz.MRI) ,比如:

create libaz.a
addlib libabc.a
addlib libxyz.a
save
end

and then execute ar as:

ar -M <libaz.mri

或者你可以使用一个 存档(选项 -T) ,这将允许添加其他存档,而不需要将它们嵌套在内部,虽然缺点是,如果你想分发静态库,分离的对象将丢失:

ar -rcT libaz.a libabc.a libxyz.a

所有上述方法都能很好地处理来自原始档案的重叠成员名称。

Otherwise, you'd have to unpack into different directories and repack again, to avoid replacing overlapping member names:

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz

更好的方法是对每个库执行部分链接,并对两个生成的目标文件进行归档。这样它的运行方式就像共享库一样

进行部分链接

gcc -r --nostdlib

所以要么不做中间档案,要么在 重新提取,快跑

gcc -r --nostdlib $CFLAGS $OBJECTS_A -o $LIBNAME_A.o
gcc -r --nostdlib $CFLAGS $OBJECTS_B -o $LIBNAME_B.o

那么

ar -cr $LIBNAME_JOINED.a $LIBNAME_A.o $LIBNAME_B.o
ar -x libx264.a
mkdir sub && cd sub
ar -m ../libx264.a `ar -t ../libx264.a |sort|uniq|grep "\.o"`
ar -x ../libx264.a

现在你有了两个版本的“ macroblock-10.o”

ar crsT libaz.a libabc.a libxyz.a

在这里,您将创建归档文件的归档文件,然后使用 T 标志“扁平化”(细化)结果。 不确定如何使用可能包含在其中的同名.o 文件。

This question is specific to Linux. If you're looking for how to do this on macOS, the answer is libtool, 就像这里解释的那样:

libtool -static -o new.a old1.a old2.a

您总是可以进行部分链接:

gcc -r -o libnew.o -Wl,--whole-archive libabc.a libxyz.a
ar cr libnew.a libnew.o

Here is a bash script to link all .a libs from a specified directory into a single library.

用法: ./unify-static-libs.sh myFinalLib.a /path/to/input/libs

#!/bin/bash
#
# Creates one static library from several.
#
# Usage: copy all your libs to a single directory and call this script.
#
if [[ $# -ne 2 ]]; then
echo "Usage: unify-static-libs.sh output-name path-to-libs"
exit 2
fi
# Inputs
LIBNAME=$1
LIBSDIR=$2
# Tmp dir
OBJDIR=/tmp/unify-static-libs
mkdir -p ${OBJDIR}
# Extract .o
echo "Extracting objects to ${OBJDIR}..."
for i in ${LIBSDIR}/*.a
do
echo $i
ar --output $OBJDIR -x $i
done
# Link objects into a single lib
echo "Creating $LIBNAME from objects..."
ar -crs $LIBNAME $OBJDIR/*.o
# Clean up
rm -rf ${OBJDIR}
echo "Done."