Index: [thread] [date] [subject] [author]
  From: Garrett Mitchener <wgm2@acpub.duke.edu>
  To  : 
  Date: 28 Feb 1999 19:19:30 -0500

Re: makefiles

David Cyrus Adkisson <dca3@duke.edu> writes:

> 	
> We're a little concerned with how libraries are supposed to be 
> implemented. We've found that the help page on creating libraries isn't 
> too helpful. 
> 
> Should we compile to program first to create all the .o files, then 
> create the libraries manually, or should the libraries be created by the 
> Makefile first by creating the .o files and then archiving them 
> automatically. The statement on the help page "Normally you'll use the ar 
> command in a makefile so you'll probably use a makefile variable rather 
> than *.o."  makes sense and I've figured out the *.o substitute, but I 
> don't know how to get makefile to accept a command like that without errors.
> 
> I guess my confusion is based on whether or not the libraries should be 
> made manually or automatically and how. Is there another more 
> comprehensive library page we should know about because this one assumes 
> we know what libraries are that we're good makefile programmers, and 
> they're dead wrong on both counts. 
> 
> Any clarifications on this stuff would be greatly appreciated. 
> 
> 	Cyrus Adkisson 

First, I reccomend you at least skim the makefile tutorial off the 108
help page.  The idea behind a static library is that it's just a bunch
of plain old .o files hooked together.  You must add a dependency line
in your makefile to construct one.  Instead of using an executable for
the target, you have a .a file, something like this:

libbreakfast.a: spam.o eggs.o pancakes.o
  <tab>  ar cq $@ $^

(I think this is right.  Read the makefile tutorial to see what $@ and
$^ do...)

The idea behind a shared library is that it is almost like an
executable, but has a list of function names and machine code.  When
you run an executable that needs a shared library, the operating
system loads the library into memory, then through the executable
looking for function calls to the library, and fills in the address of
the machine code to call.  This means the shared library machine
instructions must be relocatable, that is, not dependent on where
exactly it ends up in memory.  This means you must pass different
flags to the compiler to get it to generate position-independent code
(PIC).  In particular, you must compile with -shared.  According to
the gcc documentation, you also need -fPIC on Sparcs, although our web
page doesn't say.  I suggest you add it, because it won't hurt.  After
everything works, you can experiment with not including it.

The best way available at the moment to deal with having two kinds of
.o files is to have a fancier makefile.  I suggest something like
this:

VERSION=STATIC

CCFLAGS_STATIC=...
CCFLAGS_SHARED= -shared -fPIC ...

CCFLAGS=$(CCFLAGS_$(VERSION))

TARGET_STATIC=libstuff.a
TARGET_SHARED=libstuff.so

TARGET=$(TARGET_$(VERSION))

all: $(TARGET)

libstuff.a: ...your .o files...
  <tab>  ar cq ...

libstuff.so: ...your .o files...
  <tab>  ld -G ...

clean:
  <tab>  rm -f ...your .o files...

You can override definitions in makefiles by specifying them on the
command line.  The important one to override here is VERSION.  So to
compile both libraries, do this:

gmake clean
gmake VERSION=SHARED (To make -shared .o files and libstuff.so)
gmake clean (To get rid of your -shared .o files)
gmake VERSION=STATIC (To make normal .o files and libstuff.a)
gmake clean (To get rid of the normal .o files)

You should do all your development and debugging with the static
library for simplicity's sake.  When everything works, then try the
shared library.  Be careful about having both a .a file and a .so
file: If you link a program with a library, as in -lstuff, g++ will
prefer a shared library to a static one.  To force it to use the
static one, either remove the .so file or add the linker flag -static.

One last thing: If you link a program to a shared library and try to
run it, you may get an error about not being able to find your shared
library.  To fix it, set the value of your environment variable
LD_LIBRARY_PATH to include the directory where your .so files are,
something like this:

setenv LD_LIBRARY_PATH ...:~/108stuff/libdir/

Just tack it onto the end.  Use a colon : to separate.

	Good luck,
	-- Garrett :-)


Index: [thread] [date] [subject] [author]