4

I want to create a .so file with all libraries (GMP and PROTOBUF) statically linked into it so that it can be used in other systems without installing those libraries.

This is what I did for MAC:

gcc -I /usr/local/include -shared -o xyz.so -g xyz.c /usr/local/lib/libprotobuf-c.a /usr/local/lib/libgmp.a

But it doesn't work for Linux. How can I make it work for Linux?

user3219492
  • 774
  • 1
  • 10
  • 18

1 Answers1

2

A shared library should (on Linux) practically contain position-independent code (PIC). So the correct way to build a shared library libxyz.so out of a single source file xyz.c is

gcc -Wall -g -shared -I/usr/local/include -o libxyz.so -fPIC xyz.c

(and you could -and probably want to- add rpath related options)

A static library don't contain PIC (unless it was specially built as such, which is very uncommon on Linux ; on Debian the only example I know is the special libc6-pic package provided to facilitate build of customized and extended libc*so).

You need to link PIC variants of these libraries; so you should build them from their source code.

Read Drepper's How To Write Shared Libraries for more, and also Program Library HowTo.

(In some few theoretical weird cases, you could link a shared library which don't contain PIC, but that will make their dynamic linking extremely slow, since a lot of relocations would be processed and their code segment won't be shared -between several processes- by appropriate calls to mmap(2) done by ld-linux(8); this is not recommended at all, is very brittle, and often won't work well; I never did that)

I want to create a .so file with all libraries (GMP and PROTOBUF) statically linked into it

Don't do that. I explained why. And doing that is against the (social) rules on Linux (because your users don't want to have zillions of variants of libgmp, etc...).

You can however link a shared library with some previous other (more basic) shared libraries. In your case, I recommend doing that. So require your user to have installed GMP and PROTOBUF packages.

Consider also providing packages for your (or common) Linux distributions (e.g. a .deb file for Ubuntu or Debian)

Alternatively, publish your library code as free software; you might then hope that several users would download its source, and perhaps (eventually) some distribution would package it. You could wait years for that to happen; or at least you get help to package it.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thanks. Ok I understand that I must not use static files. I instead tried runtime search path like this: gcc -Wall -g -shared -I/usr/local/include -o module.so -fPIC module.c -Wl,-rpath,/usr/local/lib/libprotoc.so . After this, module.so got created successfully. But when the module is loaded, it stops loading and says "undefined symbol: protobuf_c_message_pack". So that means, the library is not searched at my rpath location right? Note: I don't need GMP for this .so creation. It doesn't use GMP – user3219492 Jun 28 '17 at 07:06
  • I strongly recommend spending one day reading Drepper's [*How To Write Shared Libraries*](https://www.akkadia.org/drepper/dsohowto.pdf). You need the knowledge there. – Basile Starynkevitch Jun 28 '17 at 07:10
  • Okay I will do that ASAP – user3219492 Jun 28 '17 at 07:13