Abhijatya Singh
Abhijatya Singh

Reputation: 642

Makefile shared library error

I was doing makefile test for creating static library and creating dynamic library from it. I have foo.h foo.c bar.c and main.c files in my directory. I wrote a Makefile as follows:

#This makefile demonstrate the shared and static library creation.

CFLAGS = -Wall -Werror -fPIC
CFLAGS1 = -Wall
inc = /home/betatest/Public/implicit-rule-archive

all : foo.o bar.o libfoo.a libfoo.so run

foo.o: foo.c foo.h
        @echo "Making the foo.o"
        $(CC) -c $(CFLAGS) $< -o  $@

bar.o : bar.c foo.h
        @echo "Making the bar.o"
        $(CC) -c $(CFLAGS) $< -o $@

libfoo.a(foo.o bar.o) : foo.o bar.o
        ar cr $@ $^

libfoo.so : libfoo.a
        $(CC) -shared -o $@ $^

run : main.c
        $(CC) -L$(inc) $(CFLAGS1) -o $@ $< -lfoo

.PHONY : clean

clean :
        -rm -f *.o run libfoo.*

while making it gives the following the following errors:

Making the foo.o
cc -c -Wall -Werror -fPIC  foo.c -o  foo.o
Making the bar.o
cc -c -Wall -Werror -fPIC  bar.c -o bar.o
make: *** No rule to make target 'libfoo.a', needed by 'all'.  Stop.

I have written the archive statement as :

libfoo.a(foo.o bar.o) : foo.o bar.o
        ar cr $@ $^

from this to:

libfoo.a(*.o) : *.o
        ar cr $@ $^

Can I write the statement like this because in both the cases the error is the same. I don't understand where I am going wrong. Thanks!!!!!

Upvotes: 0

Views: 317

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136256

Instead of libfoo.a(foo.o bar.o) you want plain libfoo.a : foo.o bar.o.


Another thing is that .a files are normally built for linking against the final executable, hence object files for .a are compiled as position-dependent code. Shared libraries, on the other hand, require code compiled as position independent.

Hence, you can:

  1. Get rid of libfoo.a.
  2. Produce header dependencies automatically.
  3. Establish complete dependencies on your targets so that make -j works robustly.
  4. Set rpath so that run always finds libfoo.so in its directory.

This way:

CFLAGS = -Wall -Werror 
LDFLAGS = -L/home/betatest/Public/implicit-rule-archive -Wl,-rpath,'$$ORIGIN'

all : run

run : main.o libfoo.so
    $(CC) $(LDFLAGS) -o $@ $^

libfoo.so : CFLAGS += -fPIC # Build objects for .so with -fPIC.
libfoo.so : foo.o bar.o
    $(CC) -shared -o $@ $^

# Compile any .o from .c. Also make dependencies automatically.
%.o : %.c
    $(CC) -c $(CFLAGS) -o $@ -MD -MP $<

# Include dependencies on subsequent builds.
-include $(wildcard *.d)

.PHONY : all clean

clean :
    -rm -f *.o *.d run libfoo.*

Upvotes: 1

Related Questions