How to use libtool to create a static library from a bunch of static libraries
Asked Answered
C

3

10

I have around 80 static libraries. I would like to create one static library from that.

This answer didn't work for me since I get the following error:

libtool: unrecognized option `-static'

I am also confused as to which mode it needs to be done in. Is it "link" or "install" Since there 20 odd libraries, can I also use "*" to specify all?

I didn't find any information in document expect this which doesn't really answer my question.

FYI..These are the modes:

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
Camouflage answered 25/7, 2014 at 11:28 Comment(1)
To create a static library using libtool, all those 80 static libraries must have been compiled with libtool --mode=compile and not plain gcc. Also, could you share your output for which libtool and ls -l <the path output in the which libtool command>Barmy
E
7

I'm probably naively ignoring some consequence, but couldn't you just treat the files directly as archives?

for i in *.a; ar x $i; done
ar r libfoo.a *.o
ranlib libfoo.a

Of course, you'll need some kind of renaming scheme if any of the .o files are the same. Probably something like libname_objectname.o.

Evertor answered 1/8, 2014 at 21:50 Comment(1)
This won't work if there are duplicate *.o files in different *.a library. They will be overwritten.Manful
S
2

The first linked answer is about the Mac OS libtool, not GNU libtool.

The second link actually might work (shown here wrapped with Makefile variables), if you don't mind writing an install hook:

$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(AR) cru "$(DESTDIR)$(libdir)/libsponge.a" libfoo.a libbar.a ...

The libtool "link" mode seems very fussy with respect to static libs. I was able to do it but it gave me warnings -- one for each static library, which would be a huge cascade for you.

It might be easier to bypass libtool in this case, though. This will work with 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) $@

If this must be portable, something like this will work:

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) $@
Sickening answered 27/7, 2014 at 4:17 Comment(5)
Thanks but The last solution does not work. I get "could not read symbols: Archive has no index; run ranlib to add one" even though I ran ranlib. ar t linspnge.a gives a list of libraries and not object files which I think is a problemCamouflage
As far as I know, you have to extract the .o files first, and then create the new archive from those. The docs do not suggest that it will automatically extract objects from input archives. I might be wrong though.Pelasgian
@Nikhil, so you are saying that one of your input .a files has no index?Sickening
No. The output library doesn't have an index. The output library when extracted contains .a's instead of .o'sCamouflage
Sorry, @Nikhil, I forgot that ar doesn't look in the archive in this case. I did remember that GNU ar does have kind of an obscure way of doing what you want. Maybe that will work for you.Sickening
B
1

libtool looks at the parameters of gcc, so you should have something like below

$ 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
Bonzer answered 30/7, 2014 at 18:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.