# Makefile # # Build scripts. # # Copyright (C) 2003, 2004 # Andy Goth # # Adapted from the Makefile in xpyre , and # distantly related to Peter Miller 's Makefiles at # . # # Caution: reading this file will give you scary nightmares. # # This code is available under the GNU General Public License; see COPYING. include global.mk SHELL := /bin/sh SUFFIXES := all: all-targets # TODO: different INCPATH, CFLAGS, etc. for source files in different modules. # I guess I can do this by replace the %-style generic targets near the end of # the file with autogenerated targets for source files in each module. INCPATH += $(patsubst %,-I%,$(MODULES)) MODFILES := $(patsubst %,%/module.mk,$(MODULES)) PROGRAMS := ARLIBS := SHLIBS := TARGETS := CLEANTARGETS := clean RANLIB := ranlib # This is here for the sake of the dependency include, below. ifeq ($(MAKECMDGOALS),) MAKECMDGOALS := all endif # Hide commands? ifeq ($(HUSH),1) override HUSH := @ else override HUSH := endif # Use debugging flags and libraries? ifeq ($(DEBUG),1) CFLAGS += -g3 -ggdb LIBS += -lefence else override DEBUG := endif # Include module descriptions. include.mk: Makefile global.mk $(MODFILES) @echo "* GEN $@" $(HUSH)(echo '# This file is automatically generated by make.';\ echo '# Do not edit; changes will be lost, and you will be sorry.';\ for mod in $(MODULES); do\ echo;\ echo "DIR := $$mod";\ echo "include $$mod/module.mk";\ done;\ echo;\ echo "-include auto.mk") > $@ -include include.mk # This must be done after including module definitions. all-programs: $(PROGRAMS) all-arlibs: $(ARLIBS) all-shlibs: $(SHLIBS) all-targets: all-programs all-arlibs all-shlibs $(TARGETS) # Generate nifty automatic stuff. auto.mk: Makefile global.mk $(MODFILES) @echo "* GEN $@" $(HUSH)(echo '# This file is automatically generated by make.';\ echo '# Do not edit; changes will be lost, and you will be sorry.') > $@ $(if $(PROGRAMS),$(HUSH)(for prog in $(PROGRAMS); do\ echo;\ echo "# Program: $$prog.";\ echo 'OBJ-'$$prog' := $$(foreach sfx,c cc s,$$(patsubst\ %.$$(sfx),%.o,$$(filter %.$$(sfx),$$(SRC-'$$prog'))))';\ echo 'DEP-'$$prog' := $$(foreach sfx,c cc,$$(patsubst\ %.$$(sfx),%.d,$$(filter %.$$(sfx),$$(SRC-'$$prog'))))';\ echo 'SRC += $$(SRC-'$$prog')';\ echo 'OBJ += $$(OBJ-'$$prog')';\ echo 'DEP += $$(DEP-'$$prog')';\ echo $$prog': $$(OBJ-'$$prog') $$(LLIBS-'$$prog')';\ echo -e '\t@echo "* LD $$@"';\ echo -e '\t$$(HUSH)$$(CC) $$(LDFLAGS) $$(LIBPATH) -o $$@ $$(LIBS)'\ '$$(OBJ-'$$prog') $$(LLIBS-'$$prog') $$(LIBS-'$$prog')';\ done) >> $@) $(if $(ARLIBS),$(HUSH)(for arlib in $(ARLIBS); do\ echo;\ echo "# Static library: $$arlib.";\ echo 'OBJ-'$$arlib' := $$(foreach sfx,c cc s,$$(patsubst\ %.$$(sfx),%.o,$$(filter %.$$(sfx),$$(SRC-'$$arlib'))))';\ echo 'DEP-'$$arlib' := $$(foreach sfx,c cc,$$(patsubst\ %.$$(sfx),%.d,$$(filter %.$$(sfx),$$(SRC-'$$arlib'))))';\ echo 'SRC += $$(SRC-'$$arlib')';\ echo 'OBJ += $$(OBJ-'$$arlib')';\ echo 'DEP += $$(DEP-'$$arlib')';\ echo $$arlib': $$(OBJ-'$$arlib') $$(LLIBS-'$$arlib')';\ echo -e '\t@echo "* AR $$@"';\ echo -e '\t$$(HUSH)$$(AR) cr $$@ $$^ $$(LIBS-'$$arlib')'\ '$$(LLIBS-'$$arlib')';\ echo -e '\t$$(HUSH)$$(RANLIB) $$@';\ done) >> $@) $(if $(SHLIBS),$(HUSH)(for shlib in $(SHLIBS); do\ echo;\ echo "# Shared library: $$shlib.";\ echo 'OBJ-'$$shlib' := $$(foreach sfx,c cc s,$$(patsubst\ %.$$(sfx),%.o,$$(filter %.$$(sfx),$$(SRC-'$$shlib'))))';\ echo 'DEP-'$$shlib' := $$(foreach sfx,c cc,$$(patsubst\ %.$$(sfx),%.d,$$(filter %.$$(sfx),$$(SRC-'$$shlib'))))';\ echo 'SRC += $$(SRC-'$$shlib')';\ echo 'OBJ += $$(OBJ-'$$shlib')';\ echo 'DEP += $$(DEP-'$$shlib')';\ echo $$shlib': $$(OBJ-'$$shlib') $$(LLIBS-'$$shlib')';\ echo -e '\t@echo "* LD $$@"';\ echo -e '\t$$(HUSH)$$(CC) $$(LDFLAGS) -shared -fPIC $$(LIBPATH)'\ '-o $$@ $$^ $$(LIBS-'$$shlib') $$(LLIBS-'$$shlib') $$(LIBS)';\ done) >> $@) $(HUSH)(echo;\ echo '# Include dependencies.';\ echo 'ifneq ($$(filter-out $$(CLEANTARGETS),$$(MAKECMDGOALS)),)';\ echo '-include $$(DEP)';\ echo 'endif';\ echo;\ echo '# Installation.';\ echo -n 'install:';\ for module in $(MODULES); do\ echo -n ' install-'$$module;\ done;\ echo) >> $@ # Generate dependency files from source. %.d: %.c Makefile global.mk $(MODFILES) @echo "* DEP $<" $(HUSH)(dir=$$(echo "$(dir $@)" | sed 's+^\./++');\ for dep in $$(echo -n "$@ $$dir";\ $(CC) $(CFLAGS) $(CPPFLAGS) $(INCPATH) -MM -MG -o - $<); do\ if test "$$dep" == \\; then\ continue;\ elif test ! -f "$$dep" -a ! "$${dep:0:$${#dir}}" == "$$dir"; then\ echo -n "$$dir";\ fi;\ echo -n "$$dep ";\ done;\ echo) > $@ %.d: %.cc Makefile global.mk $(MODFILES) @echo "* DEP $<" $(HUSH)(dir=$$(echo "$(dir $@)" | sed 's+^\./++');\ for dep in $$(echo -n "$@ $$dir";\ $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(INCPATH) -MM -MG -o - $<); do\ if test "$$dep" == \\; then\ continue;\ elif test ! -f "$$dep" -a ! "$${dep:0:$${#dir}}" == "$$dir"; then\ echo -n "$$dir";\ fi;\ echo -n "$$dep ";\ done;\ echo) > $@ # Generate object files from source. %.o: %.c %.d @echo "* CC $<" $(HUSH)$(CC) $(CFLAGS) $(CPPFLAGS) $(INCPATH) -c -o $@ $< %.o: %.cc %.d @echo "* C++ $<" $(HUSH)$(CXX) $(CFLAGS) $(CPPFLAGS) $(INCPATH) -c -o $@ $< %.o: %.s %.d @echo "* AS $<" $(HUSH)$(AS) -o $@ $< # Remove generated files. GENERATED += $(TARGETS) $(PROGRAMS) $(ARLIBS) $(SHLIBS)\ $(OBJ) include.mk auto.mk clean-obj: @echo "* RM compiled files" $(HUSH)-$(RM) -f $(GENERATED) # Remove generated dependency files. clean: clean-obj @echo "* RM dependency files" $(HUSH)-$(RM) -f $(DEP) # Dummy target for generating dependencies. depend: $(DEP) @true # Tell make about special (non-file) targets. .PHONY: all all-programs all-arlibs all-shlibs clean depend install # vim: set ts=4 sw=4 tw=80 noet: