################################################################################ # Desc: APC make script # Author: kgr # Date: 2016 ################################################################################ # This makefile builds APC, the Asset Package Compiler for Henge, on the system. ################################################################################ # Driver sources DRIVERS := apc testapc # Yacc YACC := bison YFLAGS ?= -v -d -Wall YCMD = $(strip $(YACC) $(YFLAGS) $(if $2,$(dir $2))$1) YCMD += $(if $2,&& mv $(notdir $(1:%.y=%.tab.[ch])) $(dir $2)) # Ragel RLC ?= ragel RLFALGS ?= -C RLCMD = $(strip $(RLC) $(RLFLAGS) $(if $2,-o $2 $(dir $2))$1) # C CC ?= gcc CFLAGS ?= -Wall CCMD = $(strip $(CC) $(CFLAGS) $(CPPFLAGS) -c $(if $2,-o $2) $1) # Linker LD ?= ld LDFLAGS ?= LDLIBS ?= -lunistring apcLIBS ?= apc-dLIBS ?= LDCMD = $(strip $(LD) $(LDFLAGS) $(LDLIBS) $($1LIBS) $(if $2,-o $2) $1) # APC is built from Ragel, Bison and C source code only. ySRC := $(shell find ./src -type f -name '*.y') rlSRC := $(shell find ./src -type f -name '*.rl') cSRC := $(shell find ./src -type f -name '*.c') # Generated files from Yacc/Bison and Ragel hGEN := $(ySRC:%.y=%.tab.h) cGEN := $(strip $(ySRC:%.y=%.tab.c) $(rlSRC:%.rl=%.c)) # Filter all other driver objects out of each driver's link commands. $(foreach drv,$(DRIVERS),\ $(eval $(drv)SRC := $(patsubst %.c,%.o,$(filter-out $(patsubst %,src/%.c,$(filter-out $(drv),$(DRIVERS))),$(cSRC) $(cGEN))))\ $(eval $(drv)-dSRC := $(patsubst %.o,%-d.o,$($(drv)SRC)))) # Unless cleaning, deps should be generated for each source file ifeq (,$(filter clean,$(MAKECMDGOALS))) cGENDEP = $(if $(wildcard $1),$(subst $(dir $1),,$(filter-out $1 \ %:,$(shell $(CC) -MM -MG $1))),\ $(info [<$1>: no deps - file not found])) endif # Construct the S2S function for generating source files during prerequisite # expansion: # If we are cleaning, stop. Else print the result of calling '1'. Then, unless # we are in -n mode, invoke the result of calling '1' in the shell $(if $(filter clean,$(MAKECMDGOALS)),,$(eval S2S += $$(info $$(call $$1,$$2,$$3)))\ $(if $(filter n,$(MAKEFLAGS)),,$(eval S2S += $$(shell $$(call $$1,$$2,$$3))))) # Rules .SECONDEXPANSION: $(DRIVERS:%=%-d) $(DRIVERS): $$($$@SRC) | $(hGEN) $(strip $(call LDCMD,$^,$@)) %-d.o: CFLAGS+= -Og -ggdb %.o %-d.o: %.c $$(call cGENDEP,$$(dir $$@)%.c) $(call CCMD,$<,$@) %.tab.h: %.tab.c ; %.tab.c: %.y $$(call S2S,YCMD,%.y,$$@) ; %.c: %.rl $$(call S2S,RLCMD,%.rl,$$@) ; clean: $(wildcard $(cGEN) $(hGEN) $(apcSRC) $(apc-dSRC)) $(if $^,rm $^)