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

发布于 2024-09-25 06:07:18 字数 191 浏览 2 评论 0原文

我有 2 个静态 Linux 库,由 ar crlibabc.alibxyz.a 创建。
我想将它们合并到一个静态库 libaz.a 中。
我该怎么办呢。

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

I have 2 static Linux libraries, created by ar cr, libabc.a and libxyz.a.
I want to merge them into one static library libaz.a.
How can I do this.

I want to create a merged static library, not to give both libraries to final link of applications.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

素衣风尘叹 2024-10-02 06:07:18

至少有三种方法可以本地执行此操作。第一种也是最便携的方法是使用 libtool。在使用 libtool 构建其他库之后,您可以通过将 .la 库添加到 automake libaz_la_LIBADD 变量来组合它们,或者直接从 Makefile 中使用类似的内容:

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

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

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

然后执行 ar 作为:

ar -M <libaz.mri

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

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

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

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

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

There are at least three ways to do this natively. The first and most portable way is to use libtool. After having built the other libraries also with libtool, you can combine them just by adding the .la libs to an automake libaz_la_LIBADD variable, or directly from a Makefile with something like:

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

The other two are at least available when using GNU ar. You can use an MRI script (named for example libaz.mri), such as:

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

and then execute ar as:

ar -M <libaz.mri

Or you can use a thin archive (option -T), which will allow adding other archives without getting them nested inside, although the downside is that if you want to distribute the static library, the detached object will be missing:

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

All the above methods gracefully handle overlapping member names from the original archives.

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
黯淡〆 2024-10-02 06:07:18

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

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

You can extract the object from both the .a files and create your .a file using the extracted .os:

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o
停顿的约定 2024-10-02 06:07:18

如果你简单地这样做:

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

此外,如果您运行ar x aa,一个档案中可能有多个同名的成员(例如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
...

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

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

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

这样链接器将为您处理所有事情!

If you simply do it as :

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

you will lost some object files if there are members with same name in both a.a and b.a
so, you need to extract members of different archives into different folder:

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

further more, it is posible that there are multiple members of same name in one archive (say in a.a), if you run ar x a.a, you will get only one for those members of same name.

The only way to extract all members of same name in one archive is to specify the member number by option '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
...

this would be a tedious work, so you will have to write a more sophisticate script to do that job.

One optional solutions is that you can combine multiple archives into one shared library:

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

this way the linker will handle all things for you!

夜光 2024-10-02 06:07:18

您始终可以进行部分链接:

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

You can always do partial linking:

gcc -r -o libnew.o -Wl,--whole-archive libabc.a libxyz.a
ar cr libnew.a libnew.o
带上头具痛哭 2024-10-02 06:07:18

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

您可以使用 so 进行部分链接

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

Even better you perform partial linking on each library and them make an archive of the two resulting object files. That way it operates like shared libraries would

You do partial linking with

gcc -r --nostdlib

so either instead of making the intermediate archive or after
reextracting it, run

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

then

ar -cr $LIBNAME_JOINED.a $LIBNAME_A.o $LIBNAME_B.o
无法言说的痛 2024-10-02 06:07:18

这个问题是针对 Linux 的。如果您正在寻找如何在 macOS 上执行此操作,答案是 libtool如此处所述:

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

This question is specific to Linux. If you're looking for how to do this on macOS, the answer is libtool, as explained here:

libtool -static -o new.a old1.a old2.a
恋你朝朝暮暮 2024-10-02 06:07:18

这是一个 bash 脚本,用于将指定目录中的所有 .a 库链接到单个库中。

用法:
./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."

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

Usage:
./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."

慕巷 2024-10-02 06:07:18
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 -x libx264.a
mkdir sub && cd sub
ar -m ../libx264.a `ar -t ../libx264.a |sort|uniq|grep "\.o"`
ar -x ../libx264.a

now you have two version of "macroblock-10.o"

陌路黄昏 2024-10-02 06:07:18
ar crsT libaz.a libabc.a libxyz.a

在这里,您创建存档的存档,然后使用 T 标志“展平”(稀疏)结果。
不确定它如何处理可能包含在其中的同名 .o 文件。

ar crsT libaz.a libabc.a libxyz.a

Here, you create archive of archives and then 'flatten' (thinning) result with T flag.
Not sure how it'll work with same name .o files that might be contained within.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文