CPW Pt.4 Recursive Descent Parser, CPW Pt.5 Unique Strings

Fix the Makefile for the ABC Compiler Project!

The makefile from session 13 has a bug. If you have more than one test program you will get a linker error.

In the makefile you have to change the lines

1
2
3
# our rule: to build target link its object file against library object files
%: %.o $(obj) | $(obsolete.deps)
        $(CC) -o $@ $(LDFLAGS) $^

into

1
2
3
# our rule: to build target link its object file against library object files
%: %.o $(lib.o) | $(obsolete.deps)
        $(CC) -o $@ $^ $(LDFLAGS)

Here the complete makefile with the fix:

#
# patch: If user has not defined CC and default value does not exist use gcc
#
ifeq ($(origin CC),default)
    cc_check := $(shell $(CC) -v > /dev/null 2>&1 && echo "sane")
    ifneq ($(strip $(cc_check)),sane)
        CC := gcc
    endif
endif

#
# Define list of source files, object files, targets, etc
#

# all source files
src :=\
    $(wildcard *.c)

# all object files
obj :=\
    $(patsubst %.c,%.o,\
        $(src))

# all targets
target :=\
    $(filter xtest%,\
        $(patsubst %.c,%,\
            $(src)))

# objects that are required by the targets
lib.o :=\
    $(filter-out xtest%,\
        $(obj))

# dependency file that will be generated by compiler
deps :=\
    $(patsubst %,%.d,\
        $(src))

# dependency file leftovers of gone source files
obsolete.deps:=\
    $(filter-out $(deps),\
        $(wildcard *.c.d))

#
# Build rules
#
.PHONY: all
all: $(target) $(obj)

# rule for removing obsolete dependency files
.PHONY: $(obsolete.deps)
$(obsolete.deps) :
        $(RM) $(obsolete.deps)

# delete implicit rule for building an executable directly from its source file
% : %.c

# our rule: to build target link its object file against library object files
%: %.o $(lib.o) | $(obsolete.deps)
        $(CC) -o $@ $^ $(LDFLAGS)

# our rule to build objects: also generate a dependency file
%.o: %.c | $(obsolete.deps)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) -MT $@ -MMD -MP -MF $<.d $<

.PHONY: clean
clean:
        $(RM) $(target) $(obj) $(deps) $(obsolete.deps)

#
# Include dependencies (if already generated)
#
-include $(deps)

After the bug fix you should of course commit it to your git repository.

Optional Modification for the Makefile

We use variables like CC, CPPFLAGS, LDFLAGS in our makefile for selecting the compiler and specifying flags to the linker. You know that you can predefine these variables when you run make. For example

1
make CPPFLAGS="-Wall -DNDEBUG -O3" LDFLAGS=-lm

If you would like to have this value hard coded in the makefile simply add a definition like this (quotes are then not needed):

1
2
CPPFLAGS    := -Wall -O3
LDFLAGS     := -lm

Of course, hard coding values has disadvantages. You now longer change this values when you invoke make from the command line. A better alternative might be to add certain default values:

1
2
CPPFLAGS    += -Wall    # always use -Wall for the compiler
LDFLAGS     += -lm      # always link against the math library

It extends the variables for some additional values that you always want to have. Now with

1
make CPPFLAGS="-DNDEBUG -O3" LDFLAGS=-lm

you compile with CPPFLAGS=“-DNDEBUG -Wall -O3” and LDFLAGS=-lm. And with

1
make

you only use the defaults CPPFLAGS=“-Wall” and LDFLAGS=-lm.