CPPFLAGS += -Wall -Wcast-qual
LDFLAGS += -lm
#
# 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

#
# List of files that need to be generated before compilation and rules to
# generate them
#

generated_files := gen_tokenkind.h gen_strtokenkind.c 

gen_tokenkind.h gen_strtokenkind.c : tokenkind.txt | xgen_tokenkind
        ./xgen_tokenkind $^ gen_tokenkind.h gen_strtokenkind.c
#
# Define list of source files, object files, targets, etc
#

# all source files
src :=\
    $(filter-out gen_%,\
        $(wildcard *.c))

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

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

# all generators for source files
generator :=\
    $(filter xgen%,\
        $(patsubst %.c,%,\
            $(src)))

# objects that are required by the targets
lib.o :=\
    $(filter-out xtest% xgen%,\
        $(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
.DEFAULT_GOAL := all
all: $(target) $(obj) $(generator)

# 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

# rule for source file generators
xgen% : xgen%.c
        $(CC) -o $@ $^ $(LDFLAGS)

# 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) $(generated_files)
        $(CC) -c $(CPPFLAGS) $(CFLAGS) -MT $@ -MMD -MP -MF $<.d $<

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

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