» Friday, 9 April A.D. 2010

greenspun makefiles

Greenspun's Tenth Rule:

Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.

Can we apply that to Makefiles, too? This is what I wrote tonight:

find-hwm-sources = $(subst $(srcdir)/arch/$(ARCH_DIR)/,,\
                            $(wildcard $(HWM_DIR)/$(1)/*.$(2)))
hwm-c-objfile-name = $(subst /,-,$(1:%.c=%.o))
hwm-S-objfile-name = $(subst /,-,$(1:%.S=%.o))
hwm-sources-varname = HWM-$(1)-$(2)
hwm-objects-varname = HWM-$(1)-$(2)-objects

define hwm-object-template
$(call hwm-sources-varname,$(1),$(2)) := $(call find-hwm-sources,$(1),$(2))
$(call hwm-objects-varname,$(1),$(2)) := \
  $$(foreach o,$$(value $$(call hwm-sources-varname,$(1),$(2))),\
     $$(call hwm-$(2)-objfile-name,$$(o)))
$$(value $$(call hwm-objects-varname,$(1),$(2))) \
  : hwm-$(1)-%.o : hwm/$(1)/%.$(2) $(if $(subst S,,$(2)),,assym.s)
	$$(CC) $$(if $$(subst S,,$(2)),,-D_ASM -include assym.s) $$(ALL_CFLAGS) $$< -c -o $$@
HWM_ALL_OBJ_$(2) += $$(value $$(call hwm-objects-varname,$(1),$(2)))
endef

HWM_C_SUBDIRS := timer rhymer nickel dimer dcache icache ucache wecache zing
HWM_S_SUBDIRS := base
$(foreach s,$(HWM_C_SUBDIRS),$(eval $(call hwm-object-template,$(s),c)))
$(foreach s,$(HWM_S_SUBDIRS),$(eval $(call hwm-object-template,$(s),S)))

(newlines and backslashes inserted for sanity in word-wrapping; had they actually been there, make probably would have choked.)

Just think how much easier that would have been in a language with real macros. Of course, it's also possible that there's a much simpler way to do what I wanted...

posted by Nate @ 10:23PM