如何使用libtool从一堆静态库创建一个静态库

10

我大约有80个静态库,我想从中创建一个静态库。

这个答案对我没有用,因为我收到了以下错误:

libtool: unrecognized option `-static'

我也不确定应该使用哪种模式,是"link"还是"install"?由于有20多个库,我是否可以使用“*”来指定全部?

我在文档中没有找到任何信息,除了这里的内容,但它并没有真正回答我的问题。

请注意,这些是可用的模式:

MODE must be one of the following:

      clean           remove files from the build directory
      compile         compile a source file into a libtool object
      execute         automatically set library path, then run a program
      finish          complete the installation of libtool libraries
      install         install libraries or executables
      link            create a library or an executable
      uninstall       remove libraries from an installed directory

使用libtool创建静态库时,这80个静态库必须使用libtool --mode=compile编译,而不是普通的gcc。另外,请分享您的输出结果,包括which libtoolls -l <which libtool命令中的路径> - askmish
3个回答

6
我可能有些天真地忽略了某些后果,但您是否可以直接将文件视为存档来处理呢?
for i in *.a; ar x $i; done
ar r libfoo.a *.o
ranlib libfoo.a

当然,如果任何.o文件是相同的,你需要一些重命名方案。可能是libname_objectname.o这样的格式。

1
如果不同的*.a库中存在重复的*.o文件,它将无法工作。它们将被覆盖。 - thinkdeep

2
第一个链接的答案是关于Mac OS的libtool,而不是GNU libtool。
第二个链接实际上可能有效(这里用Makefile变量包装),如果你不介意编写安装钩子:
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(AR) cru "$(DESTDIR)$(libdir)/libsponge.a" libfoo.a libbar.a ...

libtool的“link”模式对静态库非常挑剔。我能够做到这一点,但是它会给我警告——每个静态库都有一个警告,这对你来说可能是一个巨大的级联。

在这种情况下,绕过libtool可能更容易。这将适用于GNU ar:

lib_LIBRARIES=libsponge.a
libsponge.a : libfoo.a libbar.a ...
        echo "CREATE $@" > libsponge-script
        list='$^'; for p in $$list; do \
            echo "ADDLIB $$p" >> libsponge-script; \
        done
        echo "SAVE" >> libsponge-script
        $(AR) -M < libsponge-script
        $(RANLIB) $@

如果需要可移植性,可以使用类似以下的代码:
lib_LIBRARIES=libsponge.a
libsponge.a : libfoo.a libbar.a ...
        $(AR) cru $@
        $(MKDIR_P) tmpar
        list='$^'; for p in $$list; do \
            (cd tmpar; $(AR) x "../$$p"; $(AR) q "../$@" *.o; rm *.o;) \
        done
        rm -rf tmpar
        $(RANLIB) $@

1
谢谢,但是最后一个解决方案不起作用。即使我运行了ranlib,我仍然得到“无法读取符号:存档没有索引;运行ranlib添加一个”的错误提示。ar t linspnge.a会列出库而不是目标文件,我认为这是个问题。 - Nikhil
据我所知,您首先必须提取.o文件,然后从中创建新的存档文件。文档并未建议它会自动从输入存档中提取对象。不过我可能是错的。 - ams
@Nikhil,所以你是在说你的一个输入文件.a没有索引吗? - ldav1s
1
不,输出库没有索引。提取输出库后,其中包含的是 .a 文件而不是 .o 文件。 - Nikhil
抱歉,@Nikhil,我忘记了在这种情况下ar不会查找存档文件。我确实记得GNU ar有一种有点模糊的方法可以做到你想要的事情。也许那个方法对你有用。 - ldav1s

1

libtool会查看gcc的参数,所以你应该有类似下面的内容

$ cat Makefile
all: libone libtwo
        rm *.o
        @libtool --mode=link gcc -all-static -o libcombo.a libone.a libtwo.a

libone: one.c
        @libtool --mode=compile gcc -c one.c -o one.lo
        @libtool --mode=link gcc -static -o libone.a one.lo

libtwo: two.c
        @libtool --mode=compile gcc -c two.c -o two.lo
        @libtool --mode=link gcc -static -o libtwo.a two.lo

clean:
        rm -rf .libs *.lo *.o *.a

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接