Unix Programming - Building .a and .so with Same Makefile

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > March 2005 > Building .a and .so with Same Makefile





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Building .a and .so with Same Makefile
Michael B Allen

2005-03-19, 2:47 am

What is the proper method for building an archive?

My impression has been that you're supposed to do something like the
following:

$ cat Makefile
OBJS = src/foo.o src/bar.o

arch: libzap.a($(OBJS))

.c.a:
$(CC) $(CFLAGS) -c $< -o $*.o
$(AR) $(ARFLAGS) $@ $*.o
$ make
cc -c src/foo.c -o src/foo.o
ar rv libzap.a src/foo.o
a - src/foo.o
cc -c src/bar.c -o src/bar.o
ar rv libzap.a src/bar.o
a - src/bar.o

However I think it's a little neater if I built all the .o files and
then build the archive in one call to ar like:

$ cat Makefile
OBJS = src/foo.o src/bar.o

libzap.a: $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)

.c.o:
$(CC) $(CFLAGS) -c $< -o $*.o
$ make
cc -c src/foo.c -o src/foo.o
cc -c src/bar.c -o src/bar.o
ar rv libzap.a src/foo.o src/bar.o
r - src/foo.o
r - src/bar.o

The only problem with this is it uses the '.c.o' target so you cannot
build with different options for a shared library. For example if I want
to build a .so file with gcc I might have:

libzap.so: $(OBJS)
$(CC) -shared $(OBJS) -lc -Wl,-h,libzap.so.0.1 -o libzap.so.0.1.1

..c.o:
$(CC) $(CFLAGS) -fpic -c $< -o $*.o

So if I want to build a .so and a .a with the same Makefile how do I
specify '-fpic' for the .so but leave it out for the .a?

Mike
Gianni Mariani

2005-03-19, 5:49 pm

Michael B Allen wrote:
> What is the proper method for building an archive?

....
>
> So if I want to build a .so and a .a with the same Makefile how do I
> specify '-fpic' for the .so but leave it out for the .a?


One option is to just compile it -fpic allways. BTW, just because you
build a .a does not mean it won't end up in a .so.

Otherwise, you can run the Makefile twice but place the outputs into
different directories.

MakeXS (shameless plug) is a Makefile for GNU make that allows you to
build "debug" and "release" versions. It does this by defining 2
targets for all the standard targets (all and r_all, clean and r_clean
etc). The r_<target> builds the release version and places the binaries
in a subdirectory named "arch.release" vs the debug targets placing the
binaries in "arch.work". You could easily extend this concept to have a
so_<target> etc...

BTW, MakeXS is simply a monster Makefile that recusively invokes itself
for all the chosen directories in a source tree. The MakeXS makefile is
generated from a GNU m4 script.

Anyhow, take a look at MakeXS.

G
Ian Zimmerman

2005-03-19, 5:49 pm


Michael> The only problem with this is it uses the '.c.o' target so you
Michael> cannot build with different options for a shared library. For
Michael> example if I want to build a .so file with gcc I might have:

Michael> libzap.so: $(OBJS) $(CC) -shared $(OBJS) -lc
Michael> -Wl,-h,libzap.so.0.1 -o libzap.so.0.1.1

Michael> .c.o: $(CC) $(CFLAGS) -fpic -c $< -o $*.o

I take a clue from libfool (oops, tr '[f]' '[t]') and use a different
suffix --- .pic.o, but almost anything else works too --- and a separate
rule for compiling the PIC files.

For example:

%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) -DLOCALEDIR=\"$(localedir)\" -o $@ $<

ifeq ($(SHLIB_STATUS),supported)

%.pic.o : %.c
$(SHOBJ_CC) -c $(CFLAGS) $(SHOBJ_CFLAGS) $(CPPFLAGS) \
-DLOCALEDIR=\"$(localedir)\" -o $@ $<
endif

--
I wonder which is the best virus for unix and if I can write
a better one in Microsoft BASIC ?
Hans-Marc Olsen in comp.unix.programmer
Michael B Allen

2005-03-19, 5:49 pm

On Sat, 19 Mar 2005 11:29:53 -0500, Gianni Mariani wrote:

> Michael B Allen wrote:
> ...
>
> One option is to just compile it -fpic allways. BTW, just because you
> build a .a does not mean it won't end up in a .so.


Really? If -fPIC code can be used for both statically and dynamically
linked stuff then this is the obvious solution. Would there happen to
be any disadvantages at all to doing this?

Mike
Michael B Allen

2005-03-19, 5:49 pm

On Sat, 19 Mar 2005 13:56:10 -0500, Ian Zimmerman wrote:
> %.o : %.c
> $(CC) -c $(CFLAGS) $(CPPFLAGS) -DLOCALEDIR=\"$(localedir)\" -o $@ $<
>
> ifeq ($(SHLIB_STATUS),supported)
>
> %.pic.o : %.c
> $(SHOBJ_CC) -c $(CFLAGS) $(SHOBJ_CFLAGS) $(CPPFLAGS) \
> -DLOCALEDIR=\"$(localedir)\" -o $@ $<
> endif


Ok, but one thing that's a little goofy about this is you need redundant
OBJS lines like:

OBJS = src/foo.o src/bar.o
PICOBJS = src/foo.pic.o src/bar.pic.o

Parhaps I can redefine CFLAGS with a recursive call like:

libzap.a: $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
libzap.so:
$(RM) $(OBJS)
CFLAGS=\"$(CFLAGS) -fPIC\" make libzap.so0
libzap.so0: $(OBJS)
$(CC) -shared $(OBJS) -lc -Wl,-h,libzap.so.0.1 -o libzap.so.0.1.1

.c.o:
$(CC) $(CFLAGS) -c $< -o $*.o

Mike
Malte Starostik

2005-03-19, 5:49 pm

Michael B Allen schrieb:
> On Sat, 19 Mar 2005 13:56:10 -0500, Ian Zimmerman wrote:
>
>
>
> Ok, but one thing that's a little goofy about this is you need redundant
> OBJS lines like:
>
> OBJS = src/foo.o src/bar.o
> PICOBJS = src/foo.pic.o src/bar.pic.o


Or have make do it for you:

OBJS = src/foo.o src/bar.o
PICOBJS = $(OBJS:.o=.pic.o)

Cheers,
Malte
James Antill

2005-03-19, 5:49 pm

On Sat, 19 Mar 2005 14:36:26 -0500, Michael B Allen wrote:

> On Sat, 19 Mar 2005 11:29:53 -0500, Gianni Mariani wrote:
>
>
> Really? If -fPIC code can be used for both statically and dynamically
> linked stuff then this is the obvious solution. Would there happen to
> be any disadvantages at all to doing this?


The -fPIC code is significantly slower.

--
James Antill -- james@and.org
Need an efficient and powerful string library for C?
http://www.and.org/vstr/

Måns Rullgård

2005-03-19, 5:49 pm

James Antill <james-netnews@and.org> writes:

> On Sat, 19 Mar 2005 14:36:26 -0500, Michael B Allen wrote:
>
>
> The -fPIC code is significantly slower.


That is mainly on intel hardware. On some architectures, all code is
position independent.

--
Måns Rullgård
mru@inprovide.com
Michael B Allen

2005-03-20, 2:51 am

On Sat, 19 Mar 2005 18:07:56 -0500, Malte Starostik wrote:
>
> Or have make do it for you:
>
> OBJS = src/foo.o src/bar.o
> PICOBJS = $(OBJS:.o=.pic.o)


Well that's good to know. I assume this is portable?

Mike
Malte Starostik

2005-03-20, 2:51 am

Michael B Allen schrieb:
> On Sat, 19 Mar 2005 18:07:56 -0500, Malte Starostik wrote:
>
>
>
> Well that's good to know. I assume this is portable?


*blush* now that you mention it, that one might be an extension of GNU
make, not sure as that's the only variant of make I currently have
access to.

Cheers,
Malte
Bjorn Reese

2005-03-20, 5:53 pm

Michael B Allen wrote:

> Really? If -fPIC code can be used for both statically and dynamically
> linked stuff then this is the obvious solution. Would there happen to
> be any disadvantages at all to doing this?


The compiled code tends to be larger. I once made an experiment on a
large-scale application suite on Solaris, and the executables and
libraries were 17% larger on average.

--
mail1dotstofanetdotdk
Henry Townsend

2005-03-20, 5:53 pm

Malte Starostik wrote:
> Michael B Allen schrieb:
>
>
>
> *blush* now that you mention it, that one might be an extension of GNU
> make, not sure as that's the only variant of make I currently have
> access to.


No, it's absolutely big-standard make and completely portable. GNU make
offers fancier ways (i.e. the $(subst) macro) but the usage shown above
is everywhere.

--
Henry Townsend
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com