#[ Rules and Depends ]##################################################{{{# AUTO_DEPENDS += filter_c filter_c = $(addprefix $2/,$(patsubst %.c,%.o,$(filter %.c,$1))) # this is some ad-hoc last resort dependency method %.a: FORCE @$(MAKE) -q -rC $(dir $(@D)) $(_cobjs)/$(@F) || $(MAKE) -rC $(dir $(@D)) $(_cobjs)/$(@F) # this implicit rule is used to force directory existence, without depending # on the directory itself, since its mtime changes too often. %/.exists: Makefile $(CONFDIR)/$(wildcard *.mk) @$(RM) -r $* @-mkdir -p $* @touch $@ # We don't want make to remove these files because of default rules. .PRECIOUS: %/.exists define RULE_C_tpl $(_cobjs)/$1/%.o: %.c $(_cobjs)/$1/.exists $(CC) $$(CFLAGS) $$($1_CPPFLAGS) $2 -MMD -MT "$$(@D)/$$*.d $$(@D)/$$*.o" -MF $$(@D)/$$*.d -g -c -o $$@ $$< $(_cobjs)/$1/%.d: %.c $(_cobjs)/$1/.exists @$(CPP) $$(CFLAGS) $$($1_CPPFLAGS) $2 -MM -MT "$$(@D)/$$*.d $$(@D)/$$*.o" -MF $$(@D)/$$*.d $$< -include $$(wildcard $(_cobjs)/$1/*.d) /dev/null endef ########################################################################}}}# #[ Classes ]############################################################{{{# deps_create = $(foreach f,$(AUTO_DEPENDS),$(call $f,$1,$2)) install-LIBRARIES/%:: mkdir -p $($*dir) cp $($*_LIBRARIES:=.so) $($*dir) uninstall-LIBRARIES/%:: rm -f $(patsubst %,$($*dir)/%.so,$($*_LIBRARIES)) rmdir -p $($*dir) || true 2> /dev/null define CLASS_LIBRARIES_tpl all:: $1.so install-LIBRARIES/$2:: $1.so install:: install-LIBRARIES/$2 uninstall:: uninstall-LIBRARIES/$2 $1.so: $(_cobjs)/$1/.exists $$(call deps_create,$$($1_SOURCES),$(_cobjs)/$1) $(CC) $$(CFLAGS) $$($1_CPPFLAGS) -fPIC -shared -o $$@ \ $$(filter %.o,$$^) $$(LDFLAGS) $$($1_LDFLAGS) $$($1_LIBADD) $$(eval $$(call RULE_C_tpl,$1,-fPIC)) clean:: $(RM) $1.so endef $(foreach v,$(filter %_LIBRARIES,$(.VARIABLES)), \ $(foreach x,$($v),$(eval $(call CLASS_LIBRARIES_tpl,$x,$(v:_LIBRARIES=))))) install-DATA/%:: mkdir -p $($*dir) cp $($*_DATA) $($*dir) uninstall-DATA/%:: rm -f $(patsubst %,$($*dir)/%,$($*_DATA)) rmdir -p $($*dir) || true 2> /dev/null define CLASS_DATA_tpl install:: install-DATA/$2 uninstall:: uninstall-DATA/$2 endef $(foreach v,$(filter %_DATA,$(.VARIABLES)), \ $(foreach x,$($v),$(eval $(call CLASS_DATA_tpl,$x,$(v:_DATA=))))) #define CLASS_EXE_tpl #all:: $1 #$1: $(_cobjs)/$1/.exists $$(call deps_create,$$($1_SOURCES),$(_cobjs)/$1) # $(CC) -o $$@ $$(CFLAGS) $$($1_CPPFLAGS) $$(filter %.o,$$^) \ # $$(LDFLAGS) $$($1_LDFLAGS) $$(filter %.a,$$^) # #$$(eval $$(call RULE_C_tpl,$1,$2)) # #clean:: # $(RM) $1 #endef #$(foreach x,$(__EXE__),$(eval $(call CLASS_EXE_tpl,$x,))) ########################################################################}}}# #[ Candy ]##############################################################{{{# echo-root: @echo $(DEPTH) echo-tags: @echo $(DEPTH)/.tags ifeq (".","$(DEPTH)") tags: ctags -o .$@ --recurse=yes --exclude=.svn --exclude=\*.mk --totals=yes; distclean clober:: $(RM) -f .tags else tags: $(MAKE) -C $(DEPTH) $@ endif .PHONY: tags ########################################################################}}}# all check clobber distclean:: @set -e $(patsubst %,; $(MAKE) -rC % $@,$(SUBDIRS)) CLEAN_RECURSE=1 clean:: $(RM) -r $(_cobjs) $(CLEANFILES) @$(if $(CLEAN_RECURSE),$(patsubst %,$(MAKE) -rC % $@;,$(SUBDIRS))) clobber distclean:: CLEAN_RECURSE= clobber distclean:: clean $(RM) -r .objs* $(DISTCLEANFILES) ifeq (".","$(DEPTH)") clobber distclean:: $(RM) $(patsubst %.in,%,$(wildcard $(CONFDIR)/*.in)) endif .PHONY: all check clean clobber distclean install FORCE