#[ Rules and Depends ]##################################################{{{# AUTO_DEPENDS += filter_c filter_c = $(addprefix $2/,$(patsubst %.c,%.o,$(filter %.c,$1))) # 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)) ## ## rules for *_PROGRAMS ## install-PROGRAMS/%:: $(if $($*dir),$(INSTALL_DIR) $(DESTDIR)$($*dir)) $(if $($*dir),$(INSTALL_PROGRAMS) $($*_PROGRAMS:=.so*) $(DESTDIR)$($*dir)) define CLASS_PROGRAMS_tpl all:: $1 install-PROGRAMS/$2:: $1 install:: install-PROGRAMS/$2 $1: $$(call deps_create,$$($1_SOURCES),$(_cobjs)/$1) $(CC) $$(CFLAGS) $$($1_CPPFLAGS) -o $$@ $$(filter %.o,$$^) \ $$(LDFLAGS) $$($1_LDFLAGS) $$($1_LIBADD) $$(eval $$(call RULE_C_tpl,$1,)) clean:: $(RM) $1 endef $(foreach v,$(filter %_PROGRAMS,$(.VARIABLES)), \ $(foreach x,$($v),$(eval $(call CLASS_PROGRAMS_tpl,$x,$(v:_PROGRAMS=))))) ## ## rules for *_LIBRARIES ## install-LIBRARIES/%:: $(if $($*dir),$(INSTALL_DIR) $(DESTDIR)$($*dir)) $(if $($*dir),$(INSTALL_DATA) $($*_LIBRARIES:=.so*) $(DESTDIR)$($*dir)) define CLASS_LIBRARIES_tpl all:: $1.so$3 install-LIBRARIES/$2:: $1.so$3 install:: install-LIBRARIES/$2 $1.so$3: $$(call deps_create,$$($1_SOURCES),$(_cobjs)/$1) $(CC) $$(CFLAGS) $$($1_CPPFLAGS) -fPIC -shared -o $$@ $$(filter %.o,$$^) \ $$(LDFLAGS) $$($1_LDFLAGS) $$($1_LIBADD) $$(if $$(word 2,$$(subst ., ,$3)),ln -sf $$@ $1.so.$$(word 1,$$(subst ., ,$3))) $$(if $$($1_VERSION), ln -sf $$@ $1.so) $$(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=),$(...\ ...)$(if $($x_VERSION),.$($x_VERSION)))))) ## ## rules for *_DATA ## install-DATA/%:: $(if $($*dir), $(INSTALL_DIR) $(DESTDIR)$($*dir)) $(if $($*dir), $(INSTALL_DATA) $($*_DATA) $(DESTDIR)$($*dir)) install:: $(foreach v,$(filter %_DATA,$(.VARIABLES)),$(patsubst %_DATA,install-DATA/%,$v)) ## ## rules for *_SCRIPTS ## install-SCRIPTS/%:: $(if $($*dir), $(INSTALL_DIR) $(DESTDIR)$($*dir)) $(if $($*dir), $(INSTALL_PROGRAMS) $($*_SCRIPTS) $(DESTDIR)$($*dir)) install:: $(foreach v,$(filter %_SCRIPTS,$(.VARIABLES)),$(patsubst %_SCRIPTS,install-SCRIPTS/%,$v)) ## ## rules for *_HEADERS ## install-HEADERS/%:: $(if $($*dir), $(INSTALL_DIR) $(DESTDIR)$($*dir)) $(if $($*dir), $(INSTALL_DATA) $($*_HEADERS) $(DESTDIR)$($*dir)) install:: $(foreach v,$(filter %_HEADERS,$(.VARIABLES)),$(patsubst %_HEADERS,install-HEADERS/%,$v)) ########################################################################}}}# #[ 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 install:: @$(if $(SUBDIRS),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) @[ -f Makefile.in ] && $(RM) Makefile ifeq (".","$(DEPTH)") clobber distclean:: $(RM) $(patsubst %.in,%,$(wildcard $(CONFDIR)/*.in)) endif .PHONY: all check clean clobber distclean install FORCE