liberation
liberation

Reputation: 29

Adding a library to my makefile

I have set up a makefile that takes the sources main.c, word.c, and trim.c I also used a library which is called linkedList.a, however even after adding it it does not build as I keep getting undefined references to functions within linkedlist.

The following is my makefile code:

SHELL = /bin/sh
SRCDIR = .
CC = gcc
YACC = bison -y
CDEBUG = -g
COMPLIANCE_FLAGS =
CFLAGS = $(COMPLIANCE_FLAGS) $(CDEBUG) -I. -I$(SRCDIR)
LDFLAGS = -g

LIBRARY_FILES = linkedList.a

linkedList.a: $(LIBRARY_FILES).o
    $(RM) -f $(output)
    $(AR) cr $(output) $(inputs)
    ranlib $(output)

############################################################################################################
# List your sources here.
SOURCES = main.c word.c trim.c
############################################################################################################

############################################################################################################
# list the name of your output program here.
EXECUTABLE = wordCounter
############################################################################################################
# Create the names of the object files (each .c file becomes a .o file)
OBJS = $(patsubst %.c, %.o, $(SOURCES))

include $(SOURCES:.c=.d)

all : $(OBJS) $(EXECUTABLE)

$(EXECUTABLE) : $(OBJS)
    $(CC) -o $(EXECUTABLE)  $(OBJS)

%.o : %.c #Defines how to translate a single c file into an object file.
    echo compiling $<
    echo $(CC) $(CFLAGS) -c $<
    $(CC) $(CFLAGS) -E $< > $<.preout
    $(CC) $(CFLAGS) -S $<
    $(CC) $(CFLAGS) -c $<
    echo done compiling $<

%.d : %.c #Defines how to generate the dependencies for the given files.  -M gcc option generates dependencies.
    @set -e; rm -f $@; \
    $(CC) $(COMPLIANCE_FLAGS ) -M $< > $@.$$$$; \
    sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
     rm -f $@.$$$$

clean :   # Delete any and all artifacts from the build.  The only thing which is kept is the source code.
    rm -f *.o
    rm -f *.preout
    rm -f *.s
    rm -f *.S
    rm -f *d
    rm -f $(EXECUTABLE)

I feel I added the proper items in the proper places. My best guess is that my library_files is somehow wrong?

Upvotes: 0

Views: 448

Answers (2)

Craig Estey
Craig Estey

Reputation: 33601

The "all:" line needs enhancement and, yes, LIBRARY_FILES needs changing/splitting. You have an OBJS variable for the executable, but nothing similar for the library. Actually, a bit more to do, as follows ...

(1) Currently, you have one library, but let's go for two:

LIBRARY_FILES += lib1.a
LIBRARY_FILES += lib2.a

(2) We now need two variables, similar to your OBJS, but one for each library:

LIBOBJS1 += abc.o def.o
LIBOBJS2 += ghi.o jkl.o

(3) We now need two rules, one for each library, similar to your rule for your library, but different [Note that most modern "ar" programs do their own ranlib--YMMV]:

lib1.a: $(LIBOBJS1)
    ar crv $@ $(LIBOBJS1)

lib2.a: $(LIBOBJS2)
    ar crv $@ $(LIBOBJS2)

(4) Now, change the rule for the executable itself:

$(EXECUTABLE): $(OBJS) $(LIBRARY_FILES)
    $(CC) -o $(EXECUTABLE) $(OBJS) $(LIBRARY_FILES)

(5) Now, we need to change the "all:" line. With the other rule changes, this can be simplified to:

all: $(EXECUTABLE)

(6) Now add a command to the "clean:" target, either:

    rm -f *.a
Or:
    rm -f $(LIBRARY_FILES)

(7) Note that care must be taken so that LIBOBJS1/LIBOBJS2 don't overlap with SOURCES/OBJS. That is, you have to decide which sources build the libraries and which ones are strictly for the executable. I think you'll be fine on this, but I didn't see anything that spelled which .c/.o files you wanted to build your library from.

(8) All the build rules should probably be moved down the file after all the symbol definitions

Upvotes: 0

Beta
Beta

Reputation: 99084

Your $(EXECUTABLE) rule doesn't mention the library, it just tries to link main.o, word.o and trim.o. So we must rewrite that rule.

First try this from the command line (because we can't do something with Make until we know how to do it without Make):

gcc -o wordCounter main.o word.o trim.o -L. -llinkedList

If this works, then we can write the rule:

$(EXECUTABLE) : $(OBJS) linkedList.a
    $(CC) -o $@ $(OBJS) -L. -llinkedList

If it doesn't, we'll have to tweak it a little. And some further refinements are possible, once we have the makefile working.

Upvotes: 1

Related Questions