I have worked on some improvements on how we handle recursive make in
our makefiles.  Most places uses for loops, which has some
disadvantages: parallel make doesn't work across directories, make -k
doesn't work, and make -q doesn't work.  Instead, I went with the
approach that we already use in the src/backend directory, where we call
the subordinate makes as target prerequisites.

Note that because with this, parallel make really works, the rule
dependencies must be correct.  This has always been the case, but now it
really shows up.  A frequent issue is that this sort of thing no longer
works:

all: submake-libpgport zic

zic: $(ZICOBJS)

because this relies on the "all" target to execute its prerequisites in
order.  Instead, you need to write it like this:

all: zic

zic: $(ZICOBJS) | submake-libpgport

(The bar is necessary so that zic isn't considered constantly out of
date because it depends on a phony target.)

This patch requires GNU make 3.80, because of the above "|" feature and
the $(eval) function.  Version 3.80 is dated October 2002, so it should
be no problem, but I do occasionally read of make 3.79 around here;
maybe it's time to get rid of that.  I did put in a check that makes the
build fail right away if a wrong version of make is used.

diff --git a/GNUmakefile.in b/GNUmakefile.in
index 57f5813..9d4c4ce 100644
--- a/GNUmakefile.in
+++ b/GNUmakefile.in
@@ -8,57 +8,39 @@ subdir =
 top_builddir = .
 include $(top_builddir)/src/Makefile.global
 
+$(call recurse,all install,src config)
+
 all:
-	$(MAKE) -C src all
-	$(MAKE) -C config all
-	@echo "All of PostgreSQL successfully made. Ready to install."
+	+...@echo "All of PostgreSQL successfully made. Ready to install."
 
 docs:
 	$(MAKE) -C doc all
 
-world:
-	$(MAKE) -C doc all
-	$(MAKE) -C src all
-	$(MAKE) -C config all
-	$(MAKE) -C contrib all
-	@echo "PostgreSQL, contrib, and documentation successfully made. Ready to install."
+$(call recurse,world,contrib,all)
+world: all docs
+	+...@echo "PostgreSQL, contrib, and documentation successfully made. Ready to install."
 
 html man:
 	$(MAKE) -C doc $@
 
 install:
-	$(MAKE) -C src $@
-	$(MAKE) -C config $@
-	@echo "PostgreSQL installation complete."
+	+...@echo "PostgreSQL installation complete."
 
 install-docs:
 	$(MAKE) -C doc install
 
-install-world:
-	$(MAKE) -C doc install
-	$(MAKE) -C src install
-	$(MAKE) -C config install
-	$(MAKE) -C contrib install
-	@echo "PostgreSQL, contrib, and documentation installation complete."
+$(call recurse,install-world,contrib,install)
+install-world: install install-docs
+	+...@echo "PostgreSQL, contrib, and documentation installation complete."
 
-installdirs uninstall coverage:
-	$(MAKE) -C doc $@
-	$(MAKE) -C src $@
-	$(MAKE) -C config $@
+$(call recurse,installdirs uninstall coverage,doc src config)
 
-distprep:
-	$(MAKE) -C doc $@
-	$(MAKE) -C src $@
-	$(MAKE) -C config $@
-	$(MAKE) -C contrib $@
+$(call recurse,distprep,doc src config contrib)
 
 # clean, distclean, etc should apply to contrib too, even though
 # it's not built by default
+$(call recurse,clean,doc contrib src config)
 clean:
-	$(MAKE) -C doc $@
-	$(MAKE) -C contrib $@
-	$(MAKE) -C src $@
-	$(MAKE) -C config $@
 # Garbage from autoconf:
 	@rm -rf autom4te.cache/
 
@@ -78,11 +60,7 @@ check: all
 check installcheck installcheck-parallel:
 	$(MAKE) -C src/test $@
 
-installcheck-world:
-	$(MAKE) -C src/test installcheck
-	$(MAKE) -C src/pl installcheck
-	$(MAKE) -C src/interfaces/ecpg installcheck
-	$(MAKE) -C contrib installcheck
+$(call recurse,installcheck-world,src/test src/interfaces/ecpg contrib,installcheck)
 
 GNUmakefile: GNUmakefile.in $(top_builddir)/config.status
 	./config.status $@
@@ -143,4 +121,4 @@ distcheck: dist
 	rm -rf $(distdir) $(dummy)
 	@echo "Distribution integrity checks out."
 
-.PHONY: dist distdir distcheck docs install-docs
+.PHONY: dist distdir distcheck docs install-docs world install-world installcheck-world
diff --git a/contrib/Makefile b/contrib/Makefile
index b777325..e1f2a84 100644
--- a/contrib/Makefile
+++ b/contrib/Makefile
@@ -63,14 +63,4 @@ endif
 #		start-scripts	\ (does not have a makefile)
 
 
-all install installdirs uninstall distprep clean distclean maintainer-clean:
-	@for dir in $(SUBDIRS); do \
-		$(MAKE) -C $$dir $@ || exit; \
-	done
-
-# We'd like check operations to run all the subtests before failing.
-check installcheck:
-	@CHECKERR=0; for dir in $(SUBDIRS); do \
-		$(MAKE) -C $$dir $@ || CHECKERR=$$?; \
-	done; \
-	exit $$CHECKERR
+$(recurse)
diff --git a/contrib/dblink/Makefile b/contrib/dblink/Makefile
index 148961e..cc59128 100644
--- a/contrib/dblink/Makefile
+++ b/contrib/dblink/Makefile
@@ -4,6 +4,7 @@ MODULE_big = dblink
 PG_CPPFLAGS = -I$(libpq_srcdir)
 OBJS	= dblink.o
 SHLIB_LINK = $(libpq)
+SHLIB_PREREQS = submake-libpq
 
 DATA_built = dblink.sql 
 DATA = uninstall_dblink.sql 
diff --git a/src/Makefile b/src/Makefile
index 0e1e431..0d4a6ee 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -12,20 +12,21 @@ subdir = src
 top_builddir = ..
 include Makefile.global
 
+SUBDIRS = \
+	port \
+	timezone \
+	backend \
+	backend/utils/mb/conversion_procs \
+	backend/snowball \
+	include \
+	interfaces \
+	backend/replication/libpqwalreceiver \
+	bin \
+	pl \
+	makefiles \
+	test/regress
 
-all install installdirs uninstall distprep:
-	$(MAKE) -C port $@
-	$(MAKE) -C timezone $@
-	$(MAKE) -C backend $@
-	$(MAKE) -C backend/utils/mb/conversion_procs $@
-	$(MAKE) -C backend/snowball $@
-	$(MAKE) -C include $@
-	$(MAKE) -C interfaces $@
-	$(MAKE) -C backend/replication/libpqwalreceiver $@
-	$(MAKE) -C bin $@
-	$(MAKE) -C pl $@
-	$(MAKE) -C makefiles $@
-	$(MAKE) -C test/regress $@
+$(recurse)
 
 install: install-local
 
@@ -46,31 +47,11 @@ uninstall-local:
 	rm -f $(addprefix '$(DESTDIR)$(pgxsdir)/$(subdir)'/, Makefile.global Makefile.port Makefile.shlib nls-global.mk)
 
 clean:
-	$(MAKE) -C port $@
-	$(MAKE) -C timezone $@
-	$(MAKE) -C backend $@
-	$(MAKE) -C backend/snowball $@
-	$(MAKE) -C include $@
-	$(MAKE) -C interfaces $@
-	$(MAKE) -C backend/replication/libpqwalreceiver $@
-	$(MAKE) -C bin $@
-	$(MAKE) -C pl $@
-	$(MAKE) -C makefiles $@
 	$(MAKE) -C test $@
 	$(MAKE) -C tutorial NO_PGXS=1 $@
 	$(MAKE) -C test/thread $@
 
 distclean maintainer-clean:
-	$(MAKE) -C port $@
-	$(MAKE) -C timezone $@
-	$(MAKE) -C backend $@
-	$(MAKE) -C backend/snowball $@
-	$(MAKE) -C include $@
-	$(MAKE) -C interfaces $@
-	$(MAKE) -C backend/replication/libpqwalreceiver $@
-	$(MAKE) -C bin $@
-	$(MAKE) -C pl $@
-	$(MAKE) -C makefiles $@
 	$(MAKE) -C test $@
 	$(MAKE) -C tutorial NO_PGXS=1 $@
 	$(MAKE) -C test/thread $@
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 5d30845..b6f922e 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -18,7 +18,9 @@
 #
 # Meta configuration
 
-.PHONY: all install install-strip installdirs uninstall clean distclean maintainer-clean distprep check installcheck maintainer-check coverage html man installcheck-parallel world install-world installcheck-world
+standard_targets = all install installdirs uninstall distprep clean distclean maintainer-clean coverage check installcheck
+
+.PHONY: $(standard_targets) install-strip maintainer-check html man installcheck-parallel
 
 # make `all' the default target
 all:
@@ -540,6 +542,47 @@ install-strip:
 
 ##########################################################################
 #
+# Recursive make support
+# ----------------------
+# Instead of recursing through subdirectories with a for loop or
+# repeated $(MAKE) -C whatever calls, this is a little smarter: it
+# allows parallel make across directories and lets make -k and -q work
+# correctly.
+
+# This function is only for internal use below.  It should be called
+# with $(eval).  It will set up a target so that it recurses into
+# subdirectories.
+# $1: target name, e.g., all
+# $2: list of subdirs
+# $3: target to run in subdir, usually same as $1
+define _create_recursive_target
+.PHONY: $(patsubst %,$(1)-%-recursive,$(2))
+$(1): $(patsubst %,$(1)-%-recursive,$(2))
+$(2:%=$(1)-%-recursive):
+	$$(MAKE) -C $$(patsubst $(1)-%-recursive,%,$$@) $(3)
+endef
+# Note that the use of $$ on the last line above is important; we want
+# those variables/functions to be evaluated when the rule is run, not
+# when the $(eval) is run to create the rule.  In the case of
+# $$(MAKE), this is necessary to get make -q working.
+
+# Call this function in a makefile.  In the normal case it doesn't
+# need any arguments.
+# $1: targets to make recursive (defaults to list of standard targets)
+# $2: list of subdirs (defaults to SUBDIRS variable)
+# $3: target to run in subdir (defaults to $1)
+recurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(eval $(call _create_recursive_target,$(target),$(if $2,$2,$(SUBDIRS)),$(if $3,$3,$(target)))))
+
+# We need the $(eval) function, which is available in GNU make 3.80.
+# That also happens to be the version where the .VARIABLES variable
+# was introduced, so this is a simple check.
+ifndef .VARIABLES
+$(error GNU make 3.80 or newer is required)
+endif
+
+
+##########################################################################
+#
 # Automatic dependency generation
 # -------------------------------
 # When we configure with --enable-depend then we override the default
@@ -640,7 +683,6 @@ lcov.info: $(gcda_files)
 	$(GCOV) -b -f -p -o . $(GCOVFLAGS) $*.c >$*.c.gcov.out
 
 coverage: $(gcda_files:.gcda=.c.gcov) lcov.info
-	$(if $(SUBDIRS),for dir in $(SUBDIRS); do $(MAKE) -C $$dir coverage || exit; done)
 
 .PHONY: coverage-html
 coverage-html: coverage
diff --git a/src/Makefile.shlib b/src/Makefile.shlib
index 3e5387f..b6dea47 100644
--- a/src/Makefile.shlib
+++ b/src/Makefile.shlib
@@ -22,6 +22,7 @@
 # OBJS                  List of object files to include in library
 # SHLIB_LINK            If shared library relies on other libraries,
 #                       additional stuff to put in its link command
+# SHLIB_PREREQS         Order-only prerequisites for library build target
 # SHLIB_EXPORTS         (optional) Name of file containing list of symbols to
 #                       export, in the format "function_name  number"
 #
@@ -340,7 +341,7 @@ all-static-lib: $(stlib)
 all-shared-lib: $(shlib)
 
 ifndef haslibarule
-$(stlib): $(OBJS)
+$(stlib): $(OBJS) | $(SHLIB_PREREQS)
 	$(LINK.static) $@ $^
 	$(RANLIB) $@
 endif #haslibarule
@@ -351,7 +352,7 @@ ifeq (,$(filter cygwin win32,$(PORTNAME)))
 ifneq ($(PORTNAME), aix)
 
 # Normal case
-$(shlib): $(OBJS)
+$(shlib): $(OBJS) | $(SHLIB_PREREQS)
 	$(LINK.shared) -o $@ $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK)
 ifdef shlib_major
 # If we're using major and minor versions, then make a symlink to major-version-only.
@@ -382,7 +383,7 @@ endif
 else # PORTNAME == aix
 
 # AIX case
-$(shlib) $(stlib): $(OBJS)
+$(shlib) $(stlib): $(OBJS) | $(SHLIB_PREREQS)
 	$(LINK.static) $(stlib) $^
 	$(RANLIB) $(stlib)
 	$(MKLDEXPORT) $(stlib) >$(exports_file)
@@ -408,10 +409,10 @@ else
 DLL_DEFFILE = lib$(NAME)dll.def
 endif
 
-$(shlib): $(OBJS) $(DLL_DEFFILE)
+$(shlib): $(OBJS) $(DLL_DEFFILE) | $(SHLIB_PREREQS)
 	$(DLLWRAP) -o $@ --dllname $(shlib) $(DLLWRAP_FLAGS) --def $(DLL_DEFFILE) $(OBJS) $(LDFLAGS) $(LDFLAGS_SL) $(SHLIB_LINK)
 
-$(stlib): $(shlib) $(DLL_DEFFILE)
+$(stlib): $(shlib) $(DLL_DEFFILE) | $(SHLIB_PREREQS)
 	$(DLLTOOL) --dllname $(shlib) $(DLLTOOL_LIBFLAGS) --def $(DLL_DEFFILE) --output-lib $@
 
 endif # PORTNAME == cygwin || PORTNAME == win32
diff --git a/src/backend/Makefile b/src/backend/Makefile
index bed086c..dad1aca 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -124,6 +124,8 @@ submake-schemapg:
 
 catalog/schemapg.h: submake-schemapg
 
+$(top_builddir)/src/port/libpgport_srv.a: submake-libpgport
+
 
 # The postgres.o target is needed by the rule in Makefile.global that
 # creates the exports file when MAKE_EXPORTS = true.
diff --git a/src/backend/common.mk b/src/backend/common.mk
index 5ba8822..4e0a5da 100644
--- a/src/backend/common.mk
+++ b/src/backend/common.mk
@@ -34,15 +34,13 @@ objfiles.txt: Makefile $(SUBDIROBJS) $(OBJS)
 expand_subsys = $(foreach file,$(1),$(if $(filter %/objfiles.txt,$(file)),$(patsubst ../../src/backend/%,%,$(addprefix $(top_builddir)/,$(shell cat $(file)))),$(file)))
 
 # Parallel make trickery
-$(SUBDIROBJS): $(SUBDIRS:%=%-recursive) ;
+$(SUBDIROBJS): | $(SUBDIRS:%=%-recursive) ;
 
 .PHONY: $(SUBDIRS:%=%-recursive)
 $(SUBDIRS:%=%-recursive):
 	$(MAKE) -C $(subst -recursive,,$@) all
 
+$(call recurse,clean)
 clean: clean-local
 clean-local:
-ifdef SUBDIRS
-	for dir in $(SUBDIRS); do $(MAKE) -C $$dir clean || exit; done
-endif
 	rm -f $(subsysfilename) $(OBJS)
diff --git a/src/backend/replication/libpqwalreceiver/Makefile b/src/backend/replication/libpqwalreceiver/Makefile
index c310b3b..774adaa 100644
--- a/src/backend/replication/libpqwalreceiver/Makefile
+++ b/src/backend/replication/libpqwalreceiver/Makefile
@@ -16,9 +16,10 @@ override CPPFLAGS := -I$(srcdir) -I$(libpq_srcdir) $(CPPFLAGS)
 
 OBJS = libpqwalreceiver.o
 SHLIB_LINK = $(libpq)
+SHLIB_PREREQS = submake-libpq
 NAME = libpqwalreceiver
 
-all: submake-libpq all-shared-lib
+all: all-shared-lib
 
 include $(top_srcdir)/src/Makefile.shlib
 
diff --git a/src/backend/utils/mb/conversion_procs/Makefile b/src/backend/utils/mb/conversion_procs/Makefile
index 3cdc457..0848d96 100644
--- a/src/backend/utils/mb/conversion_procs/Makefile
+++ b/src/backend/utils/mb/conversion_procs/Makefile
@@ -26,6 +26,8 @@ SUBDIRS = \
 	utf8_and_sjis utf8_and_win utf8_and_uhc \
 	utf8_and_euc2004 utf8_and_sjis2004 euc2004_sjis2004
 
+$(recurse)
+
 # conversion_name source_encoding destination_encoding function object
 CONVERSIONS = \
 		ascii_to_mic	SQL_ASCII MULE_INTERNAL ascii_to_mic ascii_and_mic \
@@ -162,7 +164,6 @@ CONVERSIONS = \
 		shift_jis_2004_to_euc_jis_2004 SHIFT_JIS_2004 EUC_JIS_2004 shift_jis_2004_to_euc_jis_2004 euc2004_sjis2004
 
 all: $(SQLSCRIPT)
-	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@ || exit; done
 
 $(SQLSCRIPT): Makefile
 ifeq ($(enable_shared), yes)
@@ -205,15 +206,12 @@ $(REGRESSION_SCRIPT): Makefile
 
 install: $(SQLSCRIPT) installdirs
 	$(INSTALL_DATA) $(SQLSCRIPT) '$(DESTDIR)$(datadir)'
-	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@ || exit; done
 
 installdirs:
 	$(MKDIR_P) '$(DESTDIR)$(datadir)' '$(DESTDIR)$(pkglibdir)'
 
 uninstall:
 	rm -f '$(DESTDIR)$(datadir)/$(SQLSCRIPT)'
-	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@ || exit; done
 
 clean distclean maintainer-clean:
 	rm -f $(SQLSCRIPT)
-	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@ || exit; done
diff --git a/src/bin/Makefile b/src/bin/Makefile
index 63b32e4..c81b665 100644
--- a/src/bin/Makefile
+++ b/src/bin/Makefile
@@ -19,5 +19,4 @@ ifeq ($(PORTNAME), win32)
 SUBDIRS+=pgevent
 endif
 
-all install installdirs uninstall distprep clean distclean maintainer-clean:
-	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@ || exit; done
+$(recurse)
diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile
index 99c8b1b..903fbc1 100644
--- a/src/bin/initdb/Makefile
+++ b/src/bin/initdb/Makefile
@@ -20,9 +20,9 @@ override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
 
 OBJS=	initdb.o encnames.o pqsignal.o $(WIN32RES)
 
-all: submake-libpgport initdb
+all: initdb
 
-initdb: $(OBJS)
+initdb: $(OBJS) | submake-libpgport
 	$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 # We used to pull in all of libpq to get encnames and pqsignal, but that
diff --git a/src/bin/pg_config/Makefile b/src/bin/pg_config/Makefile
index 732144d..c7e5a02 100644
--- a/src/bin/pg_config/Makefile
+++ b/src/bin/pg_config/Makefile
@@ -31,9 +31,9 @@ override CPPFLAGS += -DVAL_LDFLAGS_EX="\"$(LDFLAGS_EX)\""
 override CPPFLAGS += -DVAL_LDFLAGS_SL="\"$(LDFLAGS_SL)\""
 override CPPFLAGS += -DVAL_LIBS="\"$(LIBS)\""
 
-all: submake-libpgport pg_config
+all: pg_config
 
-pg_config: $(OBJS)
+pg_config: $(OBJS) | submake-libpgport
 	$(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 install: all installdirs
diff --git a/src/bin/pg_controldata/Makefile b/src/bin/pg_controldata/Makefile
index bcdf741..180c5eb 100644
--- a/src/bin/pg_controldata/Makefile
+++ b/src/bin/pg_controldata/Makefile
@@ -17,9 +17,9 @@ include $(top_builddir)/src/Makefile.global
 
 OBJS= pg_controldata.o pg_crc.o $(WIN32RES)
 
-all: submake-libpgport pg_controldata
+all: pg_controldata
 
-pg_controldata: $(OBJS)
+pg_controldata: $(OBJS) | submake-libpgport
 	$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 pg_crc.c: $(top_srcdir)/src/backend/utils/hash/pg_crc.c
diff --git a/src/bin/pg_ctl/Makefile b/src/bin/pg_ctl/Makefile
index 0d49509..992799c 100644
--- a/src/bin/pg_ctl/Makefile
+++ b/src/bin/pg_ctl/Makefile
@@ -20,9 +20,9 @@ override CPPFLAGS := -DDEF_PGPORT=$(DEF_PGPORT) -I$(libpq_srcdir) $(CPPFLAGS)
 
 OBJS=	pg_ctl.o $(WIN32RES)
 
-all: submake-libpq submake-libpgport pg_ctl
+all: pg_ctl
 
-pg_ctl: $(OBJS) $(libpq_builddir)/libpq.a
+pg_ctl: $(OBJS) | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 install: all installdirs
diff --git a/src/bin/pg_dump/Makefile b/src/bin/pg_dump/Makefile
index f4c716e..0367466 100644
--- a/src/bin/pg_dump/Makefile
+++ b/src/bin/pg_dump/Makefile
@@ -27,15 +27,15 @@ KEYWRDOBJS = keywords.o kwlookup.o
 kwlookup.c: % : $(top_srcdir)/src/backend/parser/%
 	rm -f $@ && $(LN_S) $< .
 
-all: submake-libpq submake-libpgport pg_dump pg_restore pg_dumpall
+all: pg_dump pg_restore pg_dumpall
 
-pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) $(libpq_builddir)/libpq.a 
+pg_dump: pg_dump.o common.o pg_dump_sort.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) pg_dump.o common.o pg_dump_sort.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
-pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) $(libpq_builddir)/libpq.a
+pg_restore: pg_restore.o $(OBJS) $(KEYWRDOBJS) | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) pg_restore.o $(KEYWRDOBJS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
-pg_dumpall: pg_dumpall.o dumputils.o $(KEYWRDOBJS) $(libpq_builddir)/libpq.a
+pg_dumpall: pg_dumpall.o dumputils.o $(KEYWRDOBJS) | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(KEYWRDOBJS) $(WIN32RES) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 install: all installdirs
diff --git a/src/bin/pg_resetxlog/Makefile b/src/bin/pg_resetxlog/Makefile
index 67ba562..ad56a11 100644
--- a/src/bin/pg_resetxlog/Makefile
+++ b/src/bin/pg_resetxlog/Makefile
@@ -17,9 +17,9 @@ include $(top_builddir)/src/Makefile.global
 
 OBJS= pg_resetxlog.o pg_crc.o $(WIN32RES)
 
-all: submake-libpgport pg_resetxlog
+all: pg_resetxlog
 
-pg_resetxlog: $(OBJS)
+pg_resetxlog: $(OBJS) | submake-libpgport
 	$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 pg_crc.c: $(top_srcdir)/src/backend/utils/hash/pg_crc.c
diff --git a/src/bin/psql/Makefile b/src/bin/psql/Makefile
index 9e1c3cd..a30c668 100644
--- a/src/bin/psql/Makefile
+++ b/src/bin/psql/Makefile
@@ -29,9 +29,9 @@ OBJS=	command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
 FLEXFLAGS = -Cfe
 
 
-all: submake-libpq submake-libpgport psql
+all: psql
 
-psql: $(OBJS) $(libpq_builddir)/libpq.a
+psql: $(OBJS) | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) $(OBJS) $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 help.o: sql_help.h
diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile
index 4248f3b..d0b0c1c 100644
--- a/src/bin/scripts/Makefile
+++ b/src/bin/scripts/Makefile
@@ -20,20 +20,20 @@ PROGRAMS = createdb createlang createuser dropdb droplang dropuser clusterdb vac
 
 override CPPFLAGS := -I$(top_srcdir)/src/bin/pg_dump -I$(top_srcdir)/src/bin/psql -I$(libpq_srcdir) $(CPPFLAGS)
 
-all: submake-libpq $(PROGRAMS)
+all: $(PROGRAMS)
 
 %: %.o $(WIN32RES)
 	$(CC) $(CFLAGS) $^ $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
-createdb: createdb.o common.o dumputils.o kwlookup.o keywords.o
-createlang: createlang.o common.o print.o mbprint.o
-createuser: createuser.o common.o dumputils.o kwlookup.o keywords.o
-dropdb: dropdb.o common.o dumputils.o kwlookup.o keywords.o
-droplang: droplang.o common.o print.o mbprint.o
-dropuser: dropuser.o common.o dumputils.o kwlookup.o keywords.o
-clusterdb: clusterdb.o common.o dumputils.o kwlookup.o keywords.o
-vacuumdb: vacuumdb.o common.o
-reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o
+createdb: createdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
+createlang: createlang.o common.o print.o mbprint.o | submake-libpq
+createuser: createuser.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
+dropdb: dropdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
+droplang: droplang.o common.o print.o mbprint.o | submake-libpq
+dropuser: dropuser.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
+clusterdb: clusterdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
+vacuumdb: vacuumdb.o common.o | submake-libpq
+reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
 
 dumputils.c keywords.c: % : $(top_srcdir)/src/bin/pg_dump/%
 	rm -f $@ && $(LN_S) $< .
diff --git a/src/interfaces/Makefile b/src/interfaces/Makefile
index f208a28..2c034bc 100644
--- a/src/interfaces/Makefile
+++ b/src/interfaces/Makefile
@@ -14,5 +14,4 @@ include $(top_builddir)/src/Makefile.global
 
 SUBDIRS = libpq ecpg
 
-all install installdirs uninstall distprep clean distclean maintainer-clean:
-	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@ || exit; done
+$(recurse)
diff --git a/src/interfaces/ecpg/Makefile b/src/interfaces/ecpg/Makefile
index 71bfff6..d955cee 100644
--- a/src/interfaces/ecpg/Makefile
+++ b/src/interfaces/ecpg/Makefile
@@ -2,19 +2,13 @@ subdir = src/interfaces/ecpg
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-all install installdirs uninstall distprep:
-	$(MAKE) -C include $@
-	$(MAKE) -C pgtypeslib $@
-	$(MAKE) -C ecpglib $@
-	$(MAKE) -C compatlib $@
-	$(MAKE) -C preproc $@
+SUBDIRS = include pgtypeslib ecpglib compatlib preproc
+
+$(recurse)
+
+all-compatlib-recursive: all-ecpglib-recursive
 
 clean distclean maintainer-clean:
-	$(MAKE) -C include $@
-	$(MAKE) -C pgtypeslib $@
-	$(MAKE) -C ecpglib $@
-	$(MAKE) -C compatlib $@
-	$(MAKE) -C preproc $@
 	$(MAKE) -C test clean
 
 check checktcp installcheck: all
diff --git a/src/interfaces/ecpg/compatlib/Makefile b/src/interfaces/ecpg/compatlib/Makefile
index d211b7d..eb9a76a 100644
--- a/src/interfaces/ecpg/compatlib/Makefile
+++ b/src/interfaces/ecpg/compatlib/Makefile
@@ -23,6 +23,7 @@ override CFLAGS += $(PTHREAD_CFLAGS)
 
 SHLIB_LINK = -L../ecpglib -lecpg -L../pgtypeslib -lpgtypes $(libpq) \
 	$(filter -lintl -lm, $(LIBS)) $(PTHREAD_LIBS)
+SHLIB_PREREQS = submake-ecpglib submake-pgtypeslib
 
 SHLIB_EXPORTS = exports.txt
 
@@ -33,6 +34,14 @@ OBJS= informix.o $(filter snprintf.o, $(LIBOBJS))
 
 all: all-lib
 
+.PHONY: submake-ecpglib submake-pgtypeslib
+
+submake-ecpglib:
+	$(MAKE) -C $(top_builddir)/src/interfaces/ecpg/ecpglib all
+
+submake-pgtypeslib:
+	$(MAKE) -C $(top_builddir)/src/interfaces/ecpg/pgtypeslib all
+
 # Shared library stuff
 include $(top_srcdir)/src/Makefile.shlib
 
diff --git a/src/interfaces/ecpg/ecpglib/Makefile b/src/interfaces/ecpg/ecpglib/Makefile
index 7d134ac..9a29d15 100644
--- a/src/interfaces/ecpg/ecpglib/Makefile
+++ b/src/interfaces/ecpg/ecpglib/Makefile
@@ -34,6 +34,7 @@ OBJS += thread.o
 endif
 
 SHLIB_LINK = -L../pgtypeslib -lpgtypes $(libpq) $(filter -lintl -lm, $(LIBS)) $(PTHREAD_LIBS)
+SHLIB_PREREQS = submake-libpq submake-pgtypeslib
 
 SHLIB_EXPORTS = exports.txt
 
@@ -42,12 +43,10 @@ ifeq ($(PORTNAME), win32)
 SHLIB_LINK += -lshfolder
 endif
 
-all: libpq pgtypeslib all-lib
+all: all-lib
 
-libpq:
-	$(MAKE) -C $(top_builddir)/src/interfaces/libpq all
-
-pgtypeslib:
+.PHONY: submake-pgtypeslib
+submake-pgtypeslib:
 	$(MAKE) -C $(top_builddir)/src/interfaces/ecpg/pgtypeslib all
 
 # Shared library stuff
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index 8978eeb..e8a6916 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -30,11 +30,14 @@ OBJS=	preproc.o type.o ecpg.o output.o parser.o \
 	keywords.o c_keywords.o ecpg_keywords.o kwlookup.o ../ecpglib/typename.o descriptor.o variable.o \
 	$(WIN32RES)
 
-all: submake-libpgport ecpg
+all: ecpg
 
-ecpg: $(OBJS)
+ecpg: $(OBJS) | submake-libpgport
 	$(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) $^ $(LIBS) $(PTHREAD_LIBS) -o $...@$(X)
 
+../ecpglib/typename.o: ../ecpglib/typename.c
+	$(MAKE) -C $(dir $@) $(notdir $@)
+
 # pgc is compiled as part of preproc
 preproc.o: pgc.c
 
diff --git a/src/pl/Makefile b/src/pl/Makefile
index c625c0d..ef630fe 100644
--- a/src/pl/Makefile
+++ b/src/pl/Makefile
@@ -26,12 +26,4 @@ ifeq ($(with_tcl), yes)
 SUBDIRS += tcl
 endif
 
-all install installdirs uninstall distprep clean distclean maintainer-clean:
-	@for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@ || exit; done
-
-# We'd like check operations to run all the subtests before failing.
-check installcheck:
-	@CHECKERR=0; for dir in $(SUBDIRS); do \
-		$(MAKE) -C $$dir $@ || CHECKERR=$$?; \
-	done; \
-	exit $$CHECKERR
+$(recurse)
diff --git a/src/test/regress/GNUmakefile b/src/test/regress/GNUmakefile
index b2b5b16..0755304 100644
--- a/src/test/regress/GNUmakefile
+++ b/src/test/regress/GNUmakefile
@@ -50,9 +50,9 @@ EXTRADEFS = '-DHOST_TUPLE="$(host_tuple)"' \
 
 # Build regression test driver
 
-all: submake-libpgport pg_regress$(X)
+all: pg_regress$(X)
 
-pg_regress$(X): pg_regress.o pg_regress_main.o
+pg_regress$(X): pg_regress.o pg_regress_main.o | submake-libpgport
 	$(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@
 
 # dependencies ensure that path changes propagate
@@ -131,8 +131,6 @@ $(top_builddir)/contrib/dummy_seclabel/dummy_seclabel$(DLSUFFIX): $(top_builddir
 
 # Tablespace setup
 
-all: tablespace-setup
-
 .PHONY: tablespace-setup
 tablespace-setup:
 	rm -rf ./testtablespace
@@ -145,13 +143,13 @@ tablespace-setup:
 
 pg_regress_call = ./pg_regress --inputdir=$(srcdir) --dlpath=. --multibyte=$(MULTIBYTE) $(NOLOCALE)
 
-check: all
+check: all tablespace-setup
 	$(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) $(TEMP_CONF)
 
-installcheck: all
+installcheck: all tablespace-setup
 	$(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule
 
-installcheck-parallel: all
+installcheck-parallel: all tablespace-setup
 	$(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT)
 
 standbycheck: all
@@ -163,10 +161,10 @@ runcheck: check
 runtest: installcheck
 runtest-parallel: installcheck-parallel
 
-bigtest: all
+bigtest: all tablespace-setup
 	$(pg_regress_call) --psqldir=$(PSQLDIR) --schedule=$(srcdir)/serial_schedule numeric_big 
 
-bigcheck: all
+bigcheck: all tablespace-setup
 	$(pg_regress_call) --temp-install=./tmp_check --top-builddir=$(top_builddir) --schedule=$(srcdir)/parallel_schedule $(MAXCONNOPT) numeric_big
 
 
diff --git a/src/timezone/Makefile b/src/timezone/Makefile
index a20ddb0..2cecaec 100644
--- a/src/timezone/Makefile
+++ b/src/timezone/Makefile
@@ -35,7 +35,7 @@ endif
 include $(top_srcdir)/src/backend/common.mk
 
 ifeq (,$(with_system_tzdata))
-all: submake-libpgport zic
+all: zic
 endif
 
 # We could do this test in the action section:
@@ -46,7 +46,7 @@ ifeq (,$(ZIC))
 ZIC= ./zic
 endif
 
-zic: $(ZICOBJS)
+zic: $(ZICOBJS) | submake-libpgport
 	$(CC) $(CFLAGS) $(ZICOBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 install: all installdirs
diff --git a/src/tools/findoidjoins/Makefile b/src/tools/findoidjoins/Makefile
index db3c8f9..ac9f480 100644
--- a/src/tools/findoidjoins/Makefile
+++ b/src/tools/findoidjoins/Makefile
@@ -16,9 +16,9 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
 
 OBJS= findoidjoins.o
 
-all: submake-libpq submake-libpgport findoidjoins
+all: findoidjoins
 
-findoidjoins: findoidjoins.o $(libpq_builddir)/libpq.a
+findoidjoins: findoidjoins.o | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) findoidjoins.o $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 clean distclean maintainer-clean:
diff --git a/src/tools/fsync/Makefile b/src/tools/fsync/Makefile
index b0fd13b..d9412e1 100644
--- a/src/tools/fsync/Makefile
+++ b/src/tools/fsync/Makefile
@@ -16,9 +16,9 @@ override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
 
 OBJS= test_fsync.o
 
-all: submake-libpq submake-libpgport test_fsync
+all: test_fsync
 
-test_fsync: test_fsync.o $(libpq_builddir)/libpq.a
+test_fsync: test_fsync.o $(libpq_builddir)/libpq.a | submake-libpq submake-libpgport
 	$(CC) $(CFLAGS) test_fsync.o $(libpq_pgport) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $...@$(X)
 
 clean distclean maintainer-clean:
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to