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
Community
  • 1
  • 1
Nikhil
  • 2,168
  • 6
  • 33
  • 51
  • 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 ` – askmish Aug 02 '14 at 12:36

3 Answers3

6

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.

laindir
  • 1,650
  • 1
  • 14
  • 19
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) $@
ldav1s
  • 15,885
  • 2
  • 53
  • 56
  • 1
    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 problem – Nikhil Jul 30 '14 at 10:39
  • 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. – ams Jul 30 '14 at 13:19
  • @Nikhil, so you are saying that one of your input `.a` files has no index? – ldav1s Aug 01 '14 at 06:09
  • 1
    No. The output library doesn't have an index. The output library when extracted contains .a's instead of .o's – Nikhil Aug 01 '14 at 07:04
  • 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. – ldav1s Aug 03 '14 at 03:47
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
Groleo
  • 584
  • 1
  • 4
  • 7