views:

602

answers:

3

I can build a executable with gcc with static link:

gcc -static xxx.c -o xxx

So I can run xxx without any external dependent library.

But what if I want to build shared library without externel dependent library? which I mean I want the shared library statically linked its externel reference in.

+2  A: 

This will work:

# Generate position independent code (PIC)
gcc -fPIC -c -o xxx.o xxx.c

# Build a shared object and link with static libraries
ld -shared -static -o xxx.so xxx.o

# Same thing but with static libc
ld -shared -static -o xxx.so xxx.o -lc

A clarification: the -static flag, if given to gcc, is passed on to the linker (ld) and tells it to work with the static version (.a) of a library (specified with the -l flag), rather than the dynamic version (.so).

Another thing: On my system (Debian) the last example gives a libc.a ... recompile with -fPIC error. Pretty sure that means that the libc.a I have on my system wasn't compiled with -fPIC. An apt-cache search libc pic did give some results however.

See also: Program Library HOWTO, SO: combining .so libs, ld(1), gcc(1)

Inshallah
@Inshalla, I think the problem is that Possible we can link two .so to one. So far I tried and failed.
arsane
Please see the `"SO: combining .so libs"` link in my answer. There seems to be no easy way to combine dynamic libraries unless they have been linked with the `--relocatable` flag (see ld(1) manpage).
Inshallah
@Inshallah - if you want to link non-PIC code into a shared object, you can you use the gcc "-mimpure-text" flags. Non-PIC code in shared objects works fine but does have some tradeoffs (code pages can't be shared between processes and require swap space, relocations slow down the loading of the shared object although may be slightly faster at runtime as PIC code is ~5% slower).
R Samuel Klatchko
@R Samuel Klatchko, thanks for the tip. The manpage says, however, that the `-mimpure-text` option is only available on SunOS and Solaris. I wonder whether there is a technical reason for this, or whether it just hasn't been implemented for other architectures.
Inshallah
A: 

If you have any plans on portability for your shared library, use libtool(1). It will handle most of the details of compiler flags for you and will make your life infinitely easier. If you don't use libtool, but later decide you want to port your program to OS X or Windows, you're going to end up reinventing it anyway.

Chris Lutz
@Chris Lutz, build independent library may be used for close source or easier for customer's usage.
arsane
@arsane: libtool(1) will enable you to build libraries in a more platform independent manner. It will execute the appropriate commands to build a (static or shared) library for the platform it is run on; good thing to have even if you don't need it.
Inshallah
@arsane - In general, GNU tools don't require you to license your code under GNU licenses to use them. You can legally compile closed-source code with GCC and still get the benefits of GCC's portability in your closed source code, so I think you can use libtool to compile a shared library without having to GPL your library. I'm no lawyer or expert, so see the relevant license, but in general GNU doesn't do that.
Chris Lutz
+1  A: 

There's some neat hackery you can do with Rpath so that a ELF executable or .so will look for its dependent .so files first in the same directory as itself:

  • make a short script echo-rpath consisting of

    echo '-Wl,--rpath=$ORIGIN'

  • add that to your build command line as gcc -o file -lwhatever `echo-rpath ` objects

(The echo mechanism prevents Make or the shell from eating the $ sign and ensures it gets passed into ld.)

pjc50