Making shared libraries

Frank Feuerbacher frank at gremlin.austin.ibm.com
Tue Oct 16 03:28:17 AEST 1990


In article <1990Oct11.160027 at ead.dsa.com>, schorr at ead.dsa.com (Andrew J.
Schorr) writes:

> My question is simple: how do you make shared libraries?
>
>   1. compile the source into .o files as you would normally;
>      are there any special compiler flags required here?

  No, there are no special flags.

>      I don't seem to see anything analogous to -pic on a Sun.
>
>   2. create an export list for the library;
>      I'm using nm to make it automatically as follows:
>       nm -g {object files} | \
>       awk '$(NF-1) == "D" {print $NF}' > export.list

If this gets you a list of all symbols (code & data) that is defined in these
object files that you want to export, then this is correct.  Here is what
I have used: (Its slower, but it works)
  First archive all .o's into scratch.a
  then,
    nm scratch.a | egrep 'extern.*((\.text$$)|(\.data$$)|(\.bss$$))'
>shared.syms
    sed "s/[        ]*\|.*//g" shared.syms >shared.exports
    sed "s/^\.//g" shared.exports | sort | uniq >shared.exp
    rm -f shared.syms shared.exports

>
>   3. link the .o files into a shared object as follows:
>       ld -r -o shared_object.o {object files} -bE:export.list \

This looks okay, but if shared_object.o references things like libc, then
you would want to add "-lc" to this.
        -bM:SRE -lc

>
>   4. insert the resulting shared_object.o into an archive (if so desired)
>
> Everything seems to work, but when I run a program linked against
> the library, I get the following messages:
>
>    Could not load program test_program
>    Could not load library libtest.0.1.a[shared_object.o]
>    Error was: No such file or directory
>
> Apparently, the loader can't find the library at run-time.  How
> do you tell it where to look?  It seems that this might involve
> putting a special line in the export.list that starts with #!,
> but I'm not sure exactly.  Can someone help me?  The ld man page
> is very vague on this subject.

First #! lines don't belong in export lists, they go with import lists.
The import list tells the binder that the listed symbols are to be
resolved at execution time.  The #! gives the path & member name of the
library that the loader should find these symbols in.  I can't quite remember
what the default path rules are.

In your case, you don't seem to need an import file, so you don't need the #!
line.

When you bind with a shared library, I believe that the bound object remembers
the path to the shared library.  I believe that the LIBPATH environment
variable is also used in the event that the library is not found there.  You
might want to look at the documentation on 'exec' or 'load' subroutine calls.

As a final note, one important thing that people tend to miss is that
a shared library MUST NOT refer to a symbol that is defined outside of a
shared library (i.e. a shared library must not refer to a function or data
object that is defined outside of a shared library).

I hope this helps a little bit, and that I have not made any mistakes.

- Frank Feuerbacher


Disclaimer: I don't speak for my employer and they don't speak for me.



More information about the Comp.unix.aix mailing list