schorr@ead.dsa.com (Andrew J. Schorr) (10/12/90)
My question is simple: how do you make shared libraries? As I understand it, the process is as follows: 1. compile the source into .o files as you would normally; are there any special compiler flags required here? 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 3. link the .o files into a shared object as follows: ld -r -o shared_object.o {object files} -bE:export.list \ -bM:SRE -T512 -H512 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. Thanks in advance, Andy
wlm@arnor.uucp (10/15/90)
Well, I think there are several ways of doing what you want. First, shared things are looked for in /usr/lib and /lib (I forget the order), so if you put that lib in one of those places, the system will find it. Second, I seem to recall that there is something like LIBPATH looked for by the linker, and it looks in the places named. I don't recall whether you have to say: setenv LIBPATH /lib:/usr/lib:/a/aragorn/homes/aragorn1/src/X11R4-new/mit/new-lib/X or whether setenv LIBPATH /a/aragorn/homes/aragorn1/src/X11R4-new/mit/new-lib/X is sufficient. Third, at link time, you can do something like: cc -o ico -O ico.o /a/aragorn/homes/aragorn1/src/X11R4-new/mit/new-lib/X/shared.\ o -L/a/aragorn/homes/aragorn1/src/X11R4-new/mit/new-lib/X -lm where shared.o is a shared version of the R4 libX11.a. Using the -L flag puts info in the load header of the resulting executable which allows the loader to find the shared part when you try to run it. Finally, there probably is a #![...] directive for the export file, but I can't find the documentation for that stuff at the moment. I would suggest judicious use of -L. Bill Moran
bengsig@oracle.nl (Bjorn Engsig) (10/15/90)
Article <1990Oct11.160027@ead.dsa.com> by schorr@ead.dsa.com (Andrew J. Schorr) says: |My question is simple: how do you make shared libraries? If you read the ld man page carefully between the lines, you will see that in your step 3: | 3. link the .o files into a shared object as follows: | ld -r -o shared_object.o {object files} -bE:export.list \ | -bM:SRE -T512 -H512 you are not allowed to use -r, but you should add -lc (plus anything else needed) to create a fully linked object without unresolved references. | The ld man page |is very vague on this subject. Indeed. -- Bjorn Engsig, E-mail: bengsig@oracle.com, bengsig@oracle.nl ORACLE Corporation From IBM: auschs!ibmaus!cs.utexas.edu!uunet!oracle!bengsig "Stepping in others footsteps, doesn't bring you ahead"
frank@gremlin.austin.ibm.com (Frank Feuerbacher) (10/16/90)
In article <1990Oct11.160027@ead.dsa.com>, schorr@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.