65

I have a third-party library which consists mainly of a large number of static (.a) library files. I can compile this into a single .a library file, but I really need it to be a single .so shared library file.

Is there any way to convert a static .a file into a shared .so file? Or more generally is there a good way to combine a huge number of static .a files with a few .o object files into a single .so file?

Eli Courtwright
  • 176,085
  • 65
  • 206
  • 255

5 Answers5

54

Does this (with appropriate -L's of course)

gcc -shared -o megalib.so foo.o bar.o -la_static_lib -lb_static_lib

Not do it?

Shahbaz
  • 44,690
  • 18
  • 114
  • 177
dicroce
  • 42,886
  • 27
  • 97
  • 139
  • 7
    Using gcc -shared did the trick, but only after I recompiled with -fPIC. Thanks for pointing me in the right direction! – Eli Courtwright Mar 17 '09 at 17:30
  • 1
    I know this is an old answert but it... doesn't work? With every static library I have tried this the resulting shared object does not export any of the original symbols anymore. – Peter Aug 12 '20 at 12:09
  • I encountered the same issue @Peter – André Cruz Jul 29 '21 at 13:18
  • @Peter: I'm guessing you're not using any `.o` files at all, and just trying to directly convert from static lib to dynamic lib providing all the same symbols. If so, there's [a trick to telling the linker to include all the unused names from the archive](https://stackoverflow.com/q/7935421/364696) you'll need to use. – ShadowRanger May 10 '22 at 17:40
29

You can't do this if objects within static library was compiled without -fPIC or like.

vitaly.v.ch
  • 2,388
  • 3
  • 25
  • 36
  • 3
    On well-supported targets, `PIC` is not essential for shared library code. It just results in much more efficient use of memory (the majority, instead of a minority, of pages can be shared) at the expense of some performance. – R.. GitHub STOP HELPING ICE Oct 04 '10 at 16:42
  • 4
    Missing of -fPIC or like at some conditions result in SegFault – vitaly.v.ch Nov 01 '10 at 09:33
20
g++ -shared -o megalib.so foo.o bar.o -Wl,--whole-archive -la_static_lib -lb_static_lib -Wl,--no-whole-archive -lc_static_lib -lother_shared_object

I'm not sure about gcc, but for g++ I had to add the --whole-archive linker option to include the objects from the static libraries in the shared object. The --no-whole-archive option is necessary if you want to link to libc_static_lib.a and libother_shared_object.so, but not include them as a whole in megalib.so.

thkala
  • 80,583
  • 22
  • 150
  • 196
Calm
  • 321
  • 3
  • 4
  • 6
    `-Wl--no-whole-archive` is necessary at the end of the command line. See [the question edit, here](http://stackoverflow.com/questions/7935421/linking-archives-a-into-shared-object-so). – ofavre Aug 07 '12 at 20:52
11

ar -x can be also useful if you want to focus on specific objects from your .as and you don't want to add anything on your own.

Examples:

ar -x lib***.a
gcc -shared *.o -o lib***.so
Anastasios Andronidis
  • 5,510
  • 4
  • 27
  • 47
  • `ar -x` doesn't support unpacking a list of archives, so `ar -x lib1.a lib2.a ...` will print `no entry lib2.a in archive`. The solution is to : `mk extracted; parallel ar --output extracted -x ::: *.a` and then run `gcc` in `extracted` – Samuel Prevost Mar 27 '21 at 17:13
7
ar -x lib***.a
gcc -shared *.o -o lib***.so
  • 1
    Wasn't this just taken from another earlier answer, and posted with less context / explanation? – Dan Sep 11 '19 at 17:34
  • No, there was not such answer by that time. See history. – Artur Shaikhullin Sep 13 '19 at 00:19
  • I could've sworn in the web browser it showed the date for the other one was earlier, but in the phone app it's showing this one was first. My apologies! – Dan Sep 13 '19 at 09:06