Rewrite the Makefile
authorIvy Foster <iff@escondida.tk>
Fri, 2 Feb 2018 00:56:20 +0000 (18:56 -0600)
committerIvy Foster <iff@escondida.tk>
Fri, 2 Feb 2018 06:34:08 +0000 (00:34 -0600)
Some general patterns for the changes:
- Use user LDFLAGS and CFLAGS
- Generally allow user to pass well-known variables through the
  environment or on the command-line rather than editing the file and
  finding what they're called
- Get rid of non-standard variables like OPTS in favor of additive
  assignmet
- Remove repetitive code (compare %.a definition with previous foo_lib
  recipes)
- Correct build dependencies (e.g., it is frotz_curses.a that requires
  the curses defines.h; frotz itself requires that defines.h only
  indirectly)
- Reduce number of needless variables; it's just as easy to use sed to
  change all occurrences of "frotz" if the name ever changes as it
  would be to change $(NAME)
- Clarify recipes where possible by breaking out conditionals and such
  that can go elsewhere
- Make git usage less brittle by providing fall-backs; this also means
  that releases built from dist tarballs are more clearly marked by
  having GIT_BRANCH and GIT_HASH be "none"
- Remove variable definitions that make automagically handles when not
  passed by user, such as CC

I also removed any mention of the oss and sun audio options, since the
existing checks raised an error if any option other than "ao" or
"none" was passed

Makefile

index 556f2138f9fae61116d4e9fc78df66ed09c03ef7..40b19f4d45c5081a09b66bffbc22fbc472e2d015 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,24 @@
-# Define path for ar
-AR = /usr/bin/ar
-
-# Define path for ranlib
-RANLIB = /usr/bin/ranlib
-
-# Define your C compiler.  I recommend gcc if you have it.
-# MacOS users should use "cc" even though it's really "gcc".
-#
-CC = gcc
+# Versioning
+
+MAJOR=2
+MINOR=44
+VERSION = $(MAJOR).$(MINOR)
+
+# If we're working from git, we have access to proper variables. If
+# not, make it clear that we're working from a release.
+GIT_DIR ?= .git
+ifneq ($(and $(wildcard $(GIT_DIR)),$(shell which git)),)
+       GIT_BRANCH = $(shell git rev-parse --abbref-ref HEAD)
+       GIT_HASH = $(shell git rev-parse HEAD)
+       GIT_HASH_SHORT = $(shell git rev-parse --short HEAD)
+       GIT_TAG = $(shell git describe --abbrev=0 --tags)
+       
+else
+       GIT_BRANCH = none
+       GIT_HASH = none
+       GIT_HASH_SHORT = none
+       GIT_TAG = $(VERSION)
+endif
 
 # Enable compiler warnings. This is an absolute minimum.
 CFLAGS += -Wall -Wextra -std=gnu99
@@ -15,25 +26,52 @@ CFLAGS += -Wall -Wextra -std=gnu99
 # Define your optimization flags.
 #
 # These are good for regular use.
-#OPTS = -O2 -fomit-frame-pointer -falign-functions=2 -falign-loops=2 -falign-jumps=2
+#CFLAGS += -O2 -fomit-frame-pointer -falign-functions=2 -falign-loops=2 -falign-jumps=2
 # These are handy for debugging.
-OPTS = $(CFLAGS) -g
+CFLAGS += -g
 
-# Define where you want Frotz installed (typically /usr/local).
-#
-PREFIX = /usr/local
-MAN_PREFIX = $(PREFIX)
-CONFIG_DIR = /etc
-#CONFIG_DIR = $(PREFIX)/etc
+# Define where you want Frotz installed
+PREFIX ?= /usr/local
+MANDIR ?= $(PREFIX)/share/man
+SYSCONFDIR ?= /etc
+INCLUDEDIR ?= $(PREFIX)/include
+LIBDIR ?= $(PREFIX)/lib
 
-# Pick your sound support.  The most featureful form of sound support is
-# through libao.  Comment all of these out if you don't want sound.
-#
-#SOUND = none
-SOUND = ao
-#SOUND = sun
-#SOUND = oss
+## INCLUDEDIR path for Apple MacOS Sierra 10.12 plus MacPorts
+#INCLUDEDIR ?= /opt/local/include
+## LIBDIR path for Apple MacOS Sierra 10.12 plus MacPorts
+#LIBDIR ?= /opt/local/lib
+
+CFLAGS += -I$(INCLUDEDIR)
+LDFLAGS += -L$(LIBDIR)
 
+RANLIB ?= $(shell which ranlib)
+
+# Choose your sound support
+# OPTIONS: ao, none
+SOUND ?= ao
+
+# Default sample rate for sound effects.
+# All modern sound interfaces can be expected to support 44100 Hz sample
+# rates.  Earlier ones, particularly ones in Sun 4c workstations support
+# only up to 8000 Hz.
+SAMPLERATE ?= 44100
+
+# Audio buffer size in frames
+BUFFSIZE ?= 4096
+
+# Default sample rate converter type
+DEFAULT_CONVERTER ?= SRC_SINC_MEDIUM_QUALITY
+
+ifeq ($(SOUND), ao)
+       CFLAGS += -lao -ldl -lpthread -lm -lsndfile -lvorbisfile -lmodplug -lsamplerate
+else ifeq ($(SOUND), none)
+       CFLAGS += -DNO_SOUND
+else ifndef SOUND
+       CFLAGS += -DNO_SOUND
+else
+       @echo "Invalid sound choice $(SOUND)."
+endif
 
 ##########################################################################
 # The configuration options below are intended mainly for older flavors
@@ -43,37 +81,10 @@ SOUND = ao
 
 # If your machine's version of curses doesn't support color...
 #
-COLOR = yes
-
-# If this matters, you can choose libcurses or libncurses.
-#
-CURSES = -lncurses
-#CURSES = -lcurses
-
-# Uncomment this if your machine's version of install doesn't recognize
-# the -D option.
-#
-#INSTALL_NO_D_FLAG = true
+COLOR ?= yes
 
-# Just in case your operating system keeps its user-added header files
-# somewhere unusual...
-#
-#INCL = -I/usr/local/include
-#INCL = -I/usr/pkg/include
-#INCL = -I/usr/freeware/include
-#INCL = -I/5usr/include
-## INCL path for Apple MacOS Sierra 10.12 plus MacPorts
-INCL = -I/opt/local/include
-
-# Just in case your operating system keeps its user-added libraries
-# somewhere unusual...
-#
-#LIB = -L/usr/local/lib
-#LIB = -L/usr/pkg/lib
-#LIB = -L/usr/freeware/lib
-#LIB = -L/5usr/lib
-## LIB path for Apple MacOS Sierra 10.12 plus MacPorts
-LIB = -L/opt/local/lib
+# If this matters, you can choose -lcurses or -lncurses
+CURSES ?= -lncurses
 
 # Uncomment this if you're compiling Unix Frotz on a machine that lacks 
 # the strrchr() libc library call.  If you don't know what this means,
@@ -87,139 +98,98 @@ LIB = -L/opt/local/lib
 #
 #NO_MEMMOVE = yes
 
-# Default sample rate for sound effects.
-# All modern sound interfaces can be expected to support 44100 Hz sample
-# rates.  Earlier ones, particularly ones in Sun 4c workstations support
-# only up to 8000 Hz.
-SAMPLERATE = 44100
-
-# Audio buffer size in frames
-BUFFSIZE = 4096
-
-# Default sample rate converter type
-DEFAULT_CONVERTER = SRC_SINC_MEDIUM_QUALITY
-
 #########################################################################
 # This section is where Frotz is actually built.
 # Under normal circumstances, nothing in this section should be changed.
 #########################################################################
 
+# Source locations
+
 SRCDIR = src
-VERSION = 2.45pre
-NAME = frotz
-BINNAME = $(NAME)
-DISTFILES = bugtest
-DISTNAME = $(BINNAME)-$(VERSION)
-distdir = $(DISTNAME)
 
 COMMON_DIR = $(SRCDIR)/common
-COMMON_TARGET = $(SRCDIR)/frotz_common.a
 COMMON_OBJECT = $(COMMON_DIR)/buffer.o \
-               $(COMMON_DIR)/err.o \
-               $(COMMON_DIR)/fastmem.o \
-               $(COMMON_DIR)/files.o \
-               $(COMMON_DIR)/hotkey.o \
-               $(COMMON_DIR)/input.o \
-               $(COMMON_DIR)/main.o \
-               $(COMMON_DIR)/math.o \
-               $(COMMON_DIR)/object.o \
-               $(COMMON_DIR)/process.o \
-               $(COMMON_DIR)/quetzal.o \
-               $(COMMON_DIR)/random.o \
-               $(COMMON_DIR)/redirect.o \
-               $(COMMON_DIR)/screen.o \
-               $(COMMON_DIR)/sound.o \
-               $(COMMON_DIR)/stream.o \
-               $(COMMON_DIR)/table.o \
-               $(COMMON_DIR)/text.o \
-               $(COMMON_DIR)/variable.o
+       $(COMMON_DIR)/err.o \
+       $(COMMON_DIR)/fastmem.o \
+       $(COMMON_DIR)/files.o \
+       $(COMMON_DIR)/hotkey.o \
+       $(COMMON_DIR)/input.o \
+       $(COMMON_DIR)/main.o \
+       $(COMMON_DIR)/math.o \
+       $(COMMON_DIR)/object.o \
+       $(COMMON_DIR)/process.o \
+       $(COMMON_DIR)/quetzal.o \
+       $(COMMON_DIR)/random.o \
+       $(COMMON_DIR)/redirect.o \
+       $(COMMON_DIR)/screen.o \
+       $(COMMON_DIR)/sound.o \
+       $(COMMON_DIR)/stream.o \
+       $(COMMON_DIR)/table.o \
+       $(COMMON_DIR)/text.o \
+       $(COMMON_DIR)/variable.o
 
 CURSES_DIR = $(SRCDIR)/curses
-CURSES_TARGET = $(SRCDIR)/frotz_curses.a
 CURSES_OBJECT = $(CURSES_DIR)/ux_init.o \
-               $(CURSES_DIR)/ux_input.o \
-               $(CURSES_DIR)/ux_pic.o \
-               $(CURSES_DIR)/ux_screen.o \
-               $(CURSES_DIR)/ux_text.o \
-               $(CURSES_DIR)/ux_blorb.o \
-               $(CURSES_DIR)/ux_audio.o \
-               $(CURSES_DIR)/ux_resource.o \
-               $(CURSES_DIR)/ux_audio_none.o \
-               $(CURSES_DIR)/ux_locks.o
+       $(CURSES_DIR)/ux_input.o \
+       $(CURSES_DIR)/ux_pic.o \
+       $(CURSES_DIR)/ux_screen.o \
+       $(CURSES_DIR)/ux_text.o \
+       $(CURSES_DIR)/ux_blorb.o \
+       $(CURSES_DIR)/ux_audio.o \
+       $(CURSES_DIR)/ux_resource.o \
+       $(CURSES_DIR)/ux_audio_none.o \
+       $(CURSES_DIR)/ux_locks.o
 
 DUMB_DIR = $(SRCDIR)/dumb
-DUMB_TARGET = $(SRCDIR)/frotz_dumb.a
-DUMB_OBJECT =  $(DUMB_DIR)/dumb_init.o \
-               $(DUMB_DIR)/dumb_input.o \
-               $(DUMB_DIR)/dumb_output.o \
-               $(DUMB_DIR)/dumb_pic.o \
-               $(DUMB_DIR)/dumb_blorb.o
+DUMB_OBJECT = $(DUMB_DIR)/dumb_init.o \
+       $(DUMB_DIR)/dumb_input.o \
+       $(DUMB_DIR)/dumb_output.o \
+       $(DUMB_DIR)/dumb_pic.o \
+       $(DUMB_DIR)/dumb_blorb.o
 
 BLORB_DIR = $(SRCDIR)/blorb
-BLORB_TARGET =  $(SRCDIR)/blorblib.a
 BLORB_OBJECT =  $(BLORB_DIR)/blorblib.o
 
-TARGETS = $(COMMON_TARGET) $(CURSES_TARGET) $(BLORB_TARGET)
+# Main programs
 
-FLAGS = $(OPTS) $(INCL)
+frotz: $(SRCDIR)/frotz_common.a $(SRCDIR)/frotz_curses.a $(SRCDIR)/blorblib.a
+       $(CC) $(CFLAGS) $(CURSES) $(LDFLAGS) $^ -o $@$(EXTENSION)
 
-SOUND_LIB = -lao -ldl -lpthread -lm -lsndfile -lvorbisfile -lmodplug -lsamplerate
+dfrotz:  $(SRCDIR)/frotz_common.a $(SRCDIR)/frotz_dumb.a $(SRCDIR)/blorblib.a
+       $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@$(EXTENSION)
 
-#########################################################################
-#########################################################################
-# Targets
-#
+all: frotz dfrotz
 
-.PHONY: all help dist clean distclean install install_dumb uninstall uninstall_dumb
+# Libs
 
-$(NAME): $(COMMON_DIR)/git_hash.h $(COMMON_DIR)/defines.h $(CURSES_DIR)/defines.h $(COMMON_TARGET) $(CURSES_TARGET) $(BLORB_TARGET)
-       @echo Linking $(NAME)...
-ifeq ($(SOUND), ao)
-       $(CC) -o $(BINNAME)$(EXTENSION) $(TARGETS) $(LIB) $(CURSES) $(SOUND_LIB)
-else ifeq ($(SOUND), none)
-       $(CC) -o $(BINNAME)$(EXTENSION) $(TARGETS) $(LIB) $(CURSES) -DNO_SOUND
-else ifndef SOUND
-       $(CC) -o $(BINNAME)$(EXTENSION) $(TARGETS) $(LIB) $(CURSES) -DNO_SOUND
-else
-       @echo "Invalid sound choice $(SOUND)."
-endif
-
-dumb:          d$(NAME)
-d$(NAME):      $(COMMON_DIR)/git_hash.h $(COMMON_DIR)/defines.h $(COMMON_TARGET) $(DUMB_TARGET) $(BLORB_TARGET)
-       @echo Linking d$(NAME)...
-       $(CC) -o d$(BINNAME)$(EXTENSION) $(COMMON_TARGET) $(DUMB_TARGET) $(BLORB_TARGET) $(LIB)
-
-all:   $(NAME) d$(NAME)
-
-
-.SUFFIXES:
-.SUFFIXES: .c .o .h
+%.a:
+       $(AR) rc $@ $^
+       $(RANLIB) $@
 
-$(COMMON_OBJECT): %.o: %.c
-       #$(CC) $(OPTS) -o $@ -c $<
-       $(CC) $(OPTS) $(INCL) -o $@ -c $<
+%.o: %.c
+       $(CC) $(CFLAGS) -fPIC -fpic -o $@ -c $<
 
-$(BLORB_OBJECT): %.o: %.c
-       $(CC) $(CFLAGS) $(OPTS) -o $@ -c $<
+common_lib: $(SRCDIR)/frotz_common.a
+$(SRCDIR)/frotz_common.a: $(COMMON_DIR)/git_hash.h $(COMMON_DIR)/defines.h $(COMMON_OBJECT)
+curses_lib: $(SRCDIR)/frotz_curses.a
+$(SRCDIR)/frotz_curses.a: $(CURSES_DIR)/defines.h $(CURSES_OBJECT)
 
-$(DUMB_OBJECT): %.o: %.c
-       $(CC) $(CFLAGS) $(OPTS) -o $@ -c $<
+dumb_lib:      $(SRCDIR)/frotz_dumb.a
+$(SRCDIR)/frotz_dumb.a: $(DUMB_OBJECT)
 
-$(CURSES_OBJECT): %.o: %.c
-       #$(CC) $(OPTS) -o $@ -c $<
-       $(CC) $(OPTS) $(INCL) -o $@ -c $<
+blorb_lib:     $(SRCDIR)/blorblib.a
+$(SRCDIR)/blorblib.a: $(BLORB_OBJECT)
 
+# Defines
 
-####################################
-# Get the defines set up just right
-#
 $(COMMON_DIR)/defines.h:
        @echo "Generating $@"
        @echo "#define VERSION \"$(VERSION)\"" > $@
 
 $(CURSES_DIR)/defines.h:
        @echo "Generating $@"
-       @echo "#define CONFIG_DIR \"$(CONFIG_DIR)\"" >> $@
+       @echo "#define CONFIG_DIR \"$(SYSCONFDIR)\"" >> $@
        @echo "#define SOUND \"$(SOUND)\"" >> $@
        @echo "#define SAMPLERATE $(SAMPLERATE)" >> $@
        @echo "#define BUFFSIZE $(BUFFSIZE)" >> $@
@@ -241,131 +211,59 @@ ifdef NO_MEMMOVE
        @echo "#define NO_MEMMOVE" >> $@
 endif
 
-
-# If we're building from a Git repository, fetch the commit tag and put 
-#   it into $(COMMON_DIR)/git_hash.h.
-# If not, that should mean that we're building from a tarball.  In that 
-#  case, $(COMMON_DIR)/git_hash.h should already be there.
-#
 hash: $(COMMON_DIR)/git_hash.h
 $(COMMON_DIR)/git_hash.h:
-ifneq ($(and $(wildcard .git),$(shell which git)),)
        @echo "Creating $(COMMON_DIR)/git_hash.h"
-       @echo "#define GIT_HASH \"$$(git rev-parse HEAD)\"" > $(COMMON_DIR)/git_hash.h
-       @echo "#define GIT_HASH_SHORT \"$$(git rev-parse HEAD|head -c7 -)\"" >> $(COMMON_DIR)/git_hash.h
-       @echo "#define GIT_TAG \"$$(git describe --tags)\"" >> $(COMMON_DIR)/git_hash.h
-       @echo "#define GIT_BRANCH \"$$(git rev-parse --abbrev-ref HEAD)\"" >> $(COMMON_DIR)/git_hash.h
-else
-       $(error $(COMMON_DIR)/git_hash.h is missing!.)
-endif
+       @echo "#define GIT_BRANCH \"$(GIT_BRANCH)\"" > $(COMMON_DIR)/git_hash.h
+       @echo "#define GIT_HASH \"$(GIT_HASH)\"" >> $(COMMON_DIR)/git_hash.h
+       @echo "#define GIT_HASH_SHORT \"$(GIT_HASH_SHORT)\"" >> $(COMMON_DIR)/git_hash.h
+       @echo "#define GIT_TAG \"$(GIT_TAG)\"" >> $(COMMON_DIR)/git_hash.h
 
+# Administrative stuff
 
-########################################################################
-# If you're going to make this target manually, you'd better know which
-# config target to make first.
-#
-common_lib:    $(COMMON_TARGET)
-$(COMMON_TARGET): $(COMMON_OBJECT)
-       @echo
-       @echo "Archiving common code..."
-       $(AR) rc $(COMMON_TARGET) $(COMMON_OBJECT)
-       $(RANLIB) $(COMMON_TARGET)
-       @echo
-
-curses_lib:    $(CURSES_TARGET)
-$(CURSES_TARGET): $(CURSES_OBJECT)
-       @echo
-       @echo "Archiving curses interface code..."
-       $(AR) rc $(CURSES_TARGET) $(CURSES_OBJECT)
-       $(RANLIB) $(CURSES_TARGET)
-       @echo
-
-dumb_lib:      $(DUMB_TARGET)
-$(DUMB_TARGET): $(DUMB_OBJECT)
-       @echo
-       @echo "Archiving dumb interface code..."
-       $(AR) rc $(DUMB_TARGET) $(DUMB_OBJECT)
-       $(RANLIB) $(DUMB_TARGET)
-       @echo
-
-blorb_lib:     $(BLORB_TARGET)
-$(BLORB_TARGET): $(BLORB_OBJECT)
-       @echo
-       @echo "Archiving Blorb file handling code..."
-       $(AR) rc $(BLORB_TARGET) $(BLORB_OBJECT)
-       $(RANLIB) $(BLORB_TARGET)
-       @echo
-
-install: $(NAME)
-ifeq ($(INSTALL_NO_D_FLAG), true)
-       @install -d $(DESTDIR)$(PREFIX)/bin -m 755 $(BINNAME)$(EXTENSION) "$(DESTDIR)$(PREFIX)/bin/$(BINNAME)$(EXTENSION)"
-       @install -d $(DESTDIR)$(MAN_PREFIX)/man/man6 -m 644 doc/$(NAME).6 "$(DESTDIR)$(MAN_PREFIX)/man/man6/$(NAME).6"
-else
-       @install -D -m 755 $(BINNAME)$(EXTENSION) "$(DESTDIR)$(PREFIX)/bin/$(BINNAME)$(EXTENSION)"
-       @install -D -m 644 doc/$(NAME).6 "$(DESTDIR)$(MAN_PREFIX)/man/man6/$(NAME).6"
-endif
+install: frotz
+       install -d "$(DESTDIR)$(PREFIX)/bin" "$(DESTDIR)$(MANDIR)/man6"
+       install "frotz$(EXTENSION)" "$(DESTDIR)$(PREFIX)/bin/"
+       install -m 644 doc/frotz.6 "$(DESTDIR)$(MANDIR)/man6/"
 
 uninstall:
-       @rm -f "$(DESTDIR)$(PREFIX)/bin/$(NAME)"
-       @rm -f "$(DESTDIR)$(MAN_PREFIX)/man/man6/$(NAME).6"
-
-install_dumb: d$(NAME)
-ifeq ($(INSTALL_NO_D_FLAG), true)
-       @install -d $(DESTDIR)$(PREFIX)/bin -m 755 d$(BINNAME)$(EXTENSION) "$(DESTDIR)$(PREFIX)/bin/d$(BINNAME)$(EXTENSION)"
-       @install -d $(DESTDIR)$(MAN_PREFIX)/man/man6 -m 644 doc/d$(NAME).6 "$(DESTDIR)$(MAN_PREFIX)/man/man6/d$(NAME).6"
-else
-       @install -D -m 755 d$(BINNAME)$(EXTENSION) "$(DESTDIR)$(PREFIX)/bin/d$(BINNAME)$(EXTENSION)"
-       @install -D -m 644 doc/d$(NAME).6 "$(DESTDIR)$(MAN_PREFIX)/man/man6/d$(NAME).6"
-endif
-
-uninstall_dumb:
-       @rm -f "$(DESTDIR)$(PREFIX)/bin/d$(NAME)"
-       @rm -f "$(DESTDIR)$(MAN_PREFIX)/man/man6/d$(NAME).6"
-
-dist: distclean hash
-       mkdir $(distdir)
-       @for file in `ls`; do \
-               if test $$file != $(distdir); then \
-                       cp -Rp $$file $(distdir)/$$file; \
-               fi; \
-       done
-       find $(distdir) -type l -exec rm -f {} \;
-       tar chof $(distdir).tar $(distdir)
-       gzip -f --best $(distdir).tar
-       rm -rf $(distdir)
-       @echo
-       @echo "$(distdir).tar.gz created"
-       @echo
-
+       rm -f "$(DESTDIR)$(PREFIX)/bin/frotz"
+       rm -f "$(DESTDIR)$(MANDIR)/man6/frotz.6"
+
+install_dfrotz install_dumb: dfrotz
+       install -d "$(DESTDIR)$(PREFIX)/bin" "$(DESTDIR)$(MANDIR)/man6"
+       install "dfrotz$(EXTENSION)" "$(DESTDIR)$(PREFIX)/bin/"
+       install -m 644 doc/dfrotz.6 "$(DESTDIR)$(MANDIR)/man6/"
+
+uninstall_dfrotz uninstall_dumb:
+       rm -f "$(DESTDIR)$(PREFIX)/bin/dfrotz"
+       rm -f "$(DESTDIR)$(MANDIR)/man6/dfrotz.6"
+
+dist: frotz-$(GIT_TAG).tar.gz
+frotz-$(GIT_TAG).tar.gz:
+       git archive --format=tar.gz -o "frotz-$(GIT_TAG).tar.gz" "$(GIT_TAG)"
+       
 clean:
-       rm -f $(SRCDIR)/*.h $(SRCDIR)/*.a
-       rm -f $(COMMON_DIR)/defines.h
-ifneq ($(and $(wildcard .git),$(shell which git)),)
-       rm -f $(COMMON_DIR)/git_hash.h
-endif
-       rm -f $(CURSES_DIR)/defines.h
-       find . -name *.o -exec rm -f {} \;
-       find . -name *.O -exec rm -f {} \;
-
-distclean: clean
-       rm -f $(BINNAME)$(EXTENSION) d$(BINNAME)$(EXTENSION) s$(BINNAME)
-       find . -iname *.exe -exec rm -f {} \;
-       find . -iname *.bak -exec rm -f {} \;
-       find . -iname *.lib -exec rm -f {} \;
-       rm -f *core $(SRCDIR)/*core
-       -rm -rf $(distdir)
-       -rm -f $(distdir).tar $(distdir).tar.gz
+       rm -f $(SRCDIR)/*.h $(SRCDIR)/*.a $(COMMON_DIR)/defines.h \
+               $(COMMON_DIR)/git_hash.h $(CURSES_DIR)/defines.h \
+               frotz*.tar.gz
+       find . -iname *.o -delete
 
 help:
-       @echo
        @echo "Targets:"
-       @echo "    frotz"
-       @echo "    dfrotz"
+       @echo "    frotz: the standard edition"
+       @echo "    dfrotz: for dumb terminals and wrapper scripts"
        @echo "    install"
        @echo "    uninstall"
        @echo "    install_dfrotz"
        @echo "    uninstall_dfrotz"
        @echo "    clean"
-       @echo "    distclean"
-       @echo "    dist"
-       @echo
+       @echo "    dist: create a source tarball of the latest tagged release"
+
+.SUFFIXES:
+.SUFFIXES: .c .o .h
+
+.PHONY: all clean dist dumb hash help \
+       blorb_lib common_lib curses_lib dumb_lib \
+       install install_dfrotz install_dumb \
+       uninstall uninstall_dfrotz uninstall_dumb