Add WAY_debug_t_NAME and WAY_debug_t_HC_OPTS
[ghc-hetmet.git] / mk / target.mk
index d4303c7..32eb7e3 100644 (file)
@@ -2,24 +2,24 @@
 #
 #                      target.mk
 #
-#              Standard targets for fptools
+#              Standard targets for GHC
 #
 #################################################################################
 
 #
 # This file contain three groups of target rules:
 #
-# 1.  FPtools targets
+# 1.  GHC targets
 #      depend*
 #      runtests*
 #
 # 2.  GNU standard targets
 #      all*
 #      install* uninstall installcheck installdirs
+#       install-docs*
 #      clean* distclean* mostlyclean* maintainer-clean*
 #      tags*
-#      info dvi ps
-#      dist binary-dist
+#      dvi ps (no info) GHC adds: pdf rtf html chm HxS
 #      check
 #
 # 3. Some of the above targets have a version that
 # 
 #
 
+##################################################################
+# Pre-compute the list of sources so we don't have to do this 
+# multiple times.  See paths.mk.
+
+PRE_SRCS := $(ALL_SRCS)
 
 ##################################################################
-#              FPtools standard targets
+# Include package building machinery
+
+include $(TOP)/mk/package.mk
+
+###################################################################
+# Suffix rules for Haskell, C and literate 
+
+include $(TOP)/mk/suffix.mk
+
+##################################################################
+#              GHC standard targets
 #
 # depend:
 #
 # Compiler produced files that are targets of the source's imports.
 MKDEPENDHS_OBJ_SUFFICES=o
 
-depend :: $(MKDEPENDHS_SRCS) $(MKDEPENDC_SRCS)
+ifneq "$(BootingFromHc)" "YES"
+PKGCONF_DEP = $(STAMP_PKG_CONF)
+endif
+
+depend :: $(MKDEPENDHS_SRCS) $(MKDEPENDC_SRCS) $(PKGCONF_DEP)
        @$(RM) .depend
        @touch .depend
 ifneq "$(DOC_SRCS)" ""
        $(MKDEPENDLIT) -o .depend $(MKDEPENDLIT_OPTS) $(filter %.lit,$(DOC_SRCS))
 endif
 ifneq "$(MKDEPENDC_SRCS)" ""
-       $(MKDEPENDC) -f .depend $(MKDEPENDC_OPTS) -- $(CC_OPTS) -- $(MKDEPENDC_SRCS)
+       $(MKDEPENDC) -f .depend $(MKDEPENDC_OPTS) $(foreach way,$(WAYS),-s $(way)) -- $(CC_OPTS) -- $(MKDEPENDC_SRCS) 
 endif
 ifneq "$(MKDEPENDHS_SRCS)" ""
-       $(MKDEPENDHS) -M -optdep-f -optdep.depend $(foreach way,$(WAYS),-optdep-s -optdep$(way)) $(foreach obj,$(MKDEPENDHS_OBJ_SUFFICES),-optdep-o -optdep$(obj)) $(MKDEPENDHS_OPTS) $(patsubst -odir,,$(HC_OPTS)) $(MKDEPENDHS_SRCS)
+       $(MKDEPENDHS) -M -optdep-f -optdep.depend $(foreach way,$(WAYS),-optdep-s -optdep$(way)) $(foreach obj,$(MKDEPENDHS_OBJ_SUFFICES),-osuf $(obj)) $(MKDEPENDHS_OPTS) $(filter-out -split-objs, $(HC_OPTS)) $(MKDEPENDHS_SRCS)
 endif
 
-# the above patsubst is a hack to remove the '-odir $*' from HC_OPTS
-# which is present when we're splitting objects.  The $* maps to
-# nothing, since this isn't a pattern rule, so we have to get rid of
-# the -odir too to avoid problems.
 
 ##################################################################
 #                      boot
@@ -86,8 +101,12 @@ endif
 #  The boot target, at a minimum generates dependency information
 
 .PHONY: boot
-boot :: depend
 
+ifeq "$(NO_BOOT_TARGET)" "YES"
+boot ::
+else
+boot :: depend
+endif
 
 ##################################################################
 #              GNU Standard targets
@@ -96,9 +115,7 @@ boot :: depend
 # 
 # `all'
 #      Compile the entire program. This should be the default target.
-#      This target need not rebuild any documentation files; Info files
-#      should normally be included in the distribution, and DVI files
-#      should be made only when explicitly asked for.
+#      This target need not rebuild any documentation files
 # 
 # `install'
 #      Compile the program and copy the executables, libraries, and so on
@@ -117,27 +134,6 @@ boot :: depend
 #      will ignore any errors.  This is in case there are systems that
 #      don't have the Unix man page documentation system installed.
 # 
-#      The way to install Info files is to copy them into `$(infodir)'
-#      with $(INSTALL_DATA) (see Command Variables), and then run the
-#      install-info program if it is present.  install-info is a script
-#      that edits the Info `dir' file to add or update the menu entry for
-#      the given Info file; it will be part of the Texinfo package. Here
-#      is a sample rule to install an Info file:
-# 
-#           $(infodir)/foo.info: foo.info # There may be a newer info
-#           file in . than in srcdir.
-#                   -if test -f foo.info; then d=.; \
-#                    else d=$(srcdir); fi; \ $(INSTALL_DATA)
-#                   $$d/foo.info $@; \ # Run install-info only if it
-#           exists.  # Use `if' instead of just prepending `-' to the
-#           # line so we notice real errors from install-info.  # We
-#           use `$(SHELL) -c' because some shells do not # fail
-#           gracefully when there is an unknown command.
-#                   if $(SHELL) -c 'install-info --version' \
-#                      >/dev/null 2>&1; then \ install-info
-#                     --infodir=$(infodir) $$d/foo.info; \ else true;
-#                   fi
-# 
 # `uninstall'
 #      Delete all the installed files that the `install' target would
 #      create (but not the noninstalled files such as `make all' would
@@ -171,7 +167,7 @@ boot :: depend
 #      Delete everything from the current directory that can be
 #      reconstructed with this Makefile.  This typically includes
 #      everything deleted by distclean , plus more: C source files
-#      produced by Bison, tags tables, Info files, and so on.
+#      produced by Bison, tags tables, and so on.
 # 
 #      One exception, however: `make maintainer-clean' should not delete
 #      `configure' even if `configure' can be remade using a rule in the
@@ -182,53 +178,11 @@ boot :: depend
 # `TAGS'
 #      Update a tags table for this program.
 # 
-# `info'
-#      Generate any Info files needed. The best way to write the rules is
-#      as follows:
-# 
-#           info: foo.info
-# 
-#           foo.info: foo.texi chap1.texi chap2.texi
-#                   $(MAKEINFO) $(srcdir)/foo.texi
-# 
-#      You must define the variable MAKEINFO in the Makefile. It should
-#      run the makeinfo program, which is part of the Texinfo
-#      distribution.
-# 
-# `dvi' `ps'
-#      Generate DVI files for all TeXinfo documentation. For example:
-# 
-#           dvi: foo.dvi
-# 
-#           foo.dvi: foo.texi chap1.texi chap2.texi
-#                   $(TEXI2DVI) $(srcdir)/foo.texi
-# 
-#      You must define the variable TEXI2DVI in the Makefile. It should
-#      run the program texi2dvi , which is part of the Texinfo
-#      distribution. Alternatively, write just the dependencies, and
-#      allow GNU Make to provide the command.
-#
-#      ps is a FPtools addition for Postscript files
-# 
-# `dist' `binary-dist'
-#      Create a distribution tar file for this program. The tar file
-#      should be set up so that the file names in the tar file start with
-#      a subdirectory name which is the name of the package it is a
-#      distribution for. This name can include the version number.
-# 
-#      For example, the distribution tar file of GCC version 1.40 unpacks
-#      into a subdirectory named `gcc-1.40'.
-# 
-#      The easiest way to do this is to create a subdirectory
-#      appropriately named, use ln or cp to install the proper files in
-#      it, and then tar that subdirectory.
-# 
-#      The dist target should explicitly depend on all non-source files
-#      that are in the distribution, to make sure they are up to date in
-#      the distribution. See Making Releases.
+# `dvi' `ps' `pdf' `html' `chm' `HxS' `rtf' 
+#      Generate DVI/PS/PDF files for LaTeX/DocBook docs. Not everything is
+#      supported everywhere, but the intention is to standardise on DocBook
+#      producing all formats.
 #
-#      binary-dist is an FPtools addition for binary distributions
-# 
 # `check'
 #      Perform self-tests (if any). The user must build the program
 #      before running the tests, but need not install the program; you
@@ -248,7 +202,7 @@ boot :: depend
 #      directories where files are installed, and their parent
 #      directories. There is a script called `mkinstalldirs' which is
 #      convenient for this; find it in the Texinfo package.
-#      (FPTOOLS: we use a close relative of the suggested script, situated
+#      (GHC: we use a close relative of the suggested script, situated
 #       in glafp-utils/mkdirhier -- SOF)
 
 
@@ -279,8 +233,14 @@ boot :: depend
 ifneq "$(HS_PROG)" ""
 all :: $(HS_PROG)
 
-$(HS_PROG) :: $(HS_OBJS)
-       $(HC) -o $@ $(HC_OPTS) $(LD_OPTS) $(HS_OBJS) $(LIBS)
+ifneq "$(BootingFromHc)" "YES"
+$(HS_PROG) :: $(OBJS)
+       $(HC) -o $@ $(HC_OPTS) $(LD_OPTS) $(OBJS)
+else
+# see bootstrap.mk
+$(HS_PROG) :: $(OBJS)
+       $(CC) -o $@ $(HC_BOOT_CC_OPTS) $(HC_BOOT_LD_OPTS) $(OBJS) $(HC_BOOT_LIBS)
+endif
 endif
 
 #----------------------------------------
@@ -293,19 +253,33 @@ $(C_PROG) :: $(C_OBJS)
        $(CC) -o $@ $(CC_OPTS) $(LD_OPTS) $(C_OBJS) $(LIBS)
 endif
 
-
 #----------------------------------------
 #      Libraries/archives
+#
+# Build $(LIBRARY) from $(LIBOBJS)+$(STUBOBJS)
+#
+# Inputs:
+#   $(LIBOBJS)
+#   $(STUBOBJS)
+#
+# Outputs:
+#   Rule to build $(LIBRARY)
 
 ifneq "$(LIBRARY)" ""
 all :: $(LIBRARY)
 
-
+ifneq "$(way)" "i"
 define BUILD_LIB
 $(RM) $@
-$(AR) $(AR_OPTS) $@ $(LIBOBJS)
+$(AR) $(AR_OPTS) $@ $(STUBOBJS) $(LIBOBJS)
 $(RANLIB) $@
 endef
+else
+define BUILD_LIB
+$(RM) $@
+al -out:$@ $(STUBOBJS) $(LIBOBJS)
+endef
+endif
 
 #
 # For Haskell object files, we might have chosen to split
@@ -314,20 +288,206 @@ endef
 # whether HS_SRCS is empty or not.
 #
 
+# can't split objs in way 'u', so we disable it here
+ifeq "$(way)" "u"
+SplitObjs = NO
+endif
+
 ifneq "$(HS_SRCS)" ""
-ifneq "$(filter -split-objs,$(HC_OPTS))" ""
+ifeq "$(SplitObjs)" "YES"
+
+SRC_HC_OPTS += -split-objs
+
+# We generate the archive into a temporary file libfoo.a.tmp, then
+# rename it at the end.  This avoids the problem that ar may sometimes
+# fail, leaving a partially built archive behind.
+ifeq "$(ArSupportsInput)" ""
 define BUILD_LIB
-$(RM) $@
-TMPDIR=$(TMPDIR); export TMPDIR; find $(patsubst %.$(way_)o,%,$(LIBOBJS)) -name '*.$(way_)o' -print | xargs ar q $@
+$(RM) $@ $@.tmp
+(echo $(STUBOBJS) $(C_OBJS) $(GC_C_OBJS); $(FIND) $(patsubst %.$(way_)o,%_split,$(HS_OBJS)) -name '*.$(way_)o' -print) | xargs $(AR) $@
+$(RANLIB) $@
+endef
+else
+define BUILD_LIB
+$(RM) $@ $@.tmp
+echo $(STUBOBJS) > $@.list
+echo $(C_OBJS) >> $@.list
+echo $(GC_C_OBJS) >> $@.list
+$(FIND) $(patsubst %.$(way_)o,%_split,$(HS_OBJS)) -name '*.$(way_)o' -print >> $@.list
+$(AR) $(AR_OPTS) $@ $(ArSupportsInput) $@.list
+$(RM) $@.list
 $(RANLIB) $@
 endef
-endif # $(filter...
 endif
 
-$(LIBRARY) :: $(LIBOBJS)
+# Extra stuff for compiling Haskell files with $(SplitObjs):
+
+#
+# If (Haskell) object files are split, cleaning up 
+# consist of descending into the directories where
+# the myriads of object files have been put.
+#
+
+extraclean ::
+       $(FIND) $(patsubst %.$(way_)o,%_split,$(HS_OBJS)) -name '*.$(way_)o' -print -o -name ld.script -print | xargs $(RM) __rm_food
+       -rmdir $(patsubst %.$(way_)o,%_split,$(HS_OBJS)) > /dev/null 2>&1
+
+endif # $(SplitObjs)
+endif # $(HS_SRCS)
+
+#
+# Remove local symbols from library objects if requested.
+#
+
+ifeq "$(StripLibraries)" "YES"
+ifeq "$(SplitObjs)" "YES"
+SRC_HC_POST_OPTS += \
+  for i in $(basename $@)_split/*.$(way_)o; do \
+       $(LD) -r $(LD_X) -o $$i.tmp $$i; \
+       $(MV) $$i.tmp $$i; \
+  done
+else
+SRC_HC_POST_OPTS += \
+  $(LD) -r $(LD_X) -o $@.tmp $@; $(MV) $@.tmp $@
+endif # SplitObjs
+endif # StripLibraries
+
+# Note: $(STUBOBJS) isn't depended on here, but included when building the lib.
+#       (i.e., the assumption is that $(STUBOBJS) are created as a side-effect
+#       of building $(LIBOBJS)).
+$(LIBRARY) : $(LIBOBJS)
        $(BUILD_LIB)
+endif # LIBRARY = ""
+
+#----------------------------------------
+#      Building Win32 DLLs
+#
+
+ifeq "$(DLLized)" "YES"
+SRC_CC_OPTS += -DDLLized
+
+ifneq "$(PACKAGE)" ""
+
+SRC_BLD_DLL_OPTS += --export-all --output-def=HS$(PACKAGE)$(_cbits)$(_way).def DllVersionInfo.$(way_)o
+
+ifneq "$(PACKAGE) $(IS_CBITS_LIB)" "std YES"
+ifneq "$(PACKAGE)" "rts"
+SRC_BLD_DLL_OPTS += -lHSstd_cbits_imp -L$(GHC_LIB_DIR)/std/cbits
+SRC_BLD_DLL_OPTS += -lHSrts_$(way_)imp -L$(GHC_RTS_DIR)
+ifneq "$(PACKAGE)" "std"
+  ifeq "$(IS_CBITS_LIB)" ""
+  SRC_BLD_DLL_OPTS += -lHSstd_$(way_)imp -L$(GHC_LIB_DIR)/std 
+  endif
+endif
+endif
+endif
+
+SRC_BLD_DLL_OPTS += -lgmp -L. -L$(GHC_RTS_DIR)/gmp
+ifeq "$(IS_CBITS_LIB)" ""
+SRC_BLD_DLL_OPTS += $(patsubst %,-lHS%_$(way_)imp, $(PACKAGE_DEPS))
+SRC_BLD_DLL_OPTS += $(patsubst %,-L../%, $(PACKAGE_DEPS))
+endif
+ifneq "$(HAS_CBITS)" ""
+SRC_BLD_DLL_OPTS += -lHS$(PACKAGE)_cbits_imp -Lcbits
+endif
+SRC_BLD_DLL_OPTS += -lwsock32 -lwinmm
+
+endif # PACKAGE != ""
+
+SplitObjs = NO 
+
+ifneq "$(LIBRARY)" ""
+
+all :: DllVersionInfo.$(way_)o
+
+ifeq "$(DLL_NAME)" ""
+DLL_NAME = $(patsubst %.a,%.dll,$(subst lib,,$(LIBRARY)))
+endif
+
+ifneq "$(DLL_NAME)" ""
+DLL_NAME := $(DLL_PEN)/$(DLL_NAME)
+endif
+
+all :: $(DLL_NAME)
+
+ifeq "$(DLL_IMPLIB_NAME)" ""
+DLL_IMPLIB_NAME = $(patsubst %.a,%_imp.a,$(LIBRARY))
 endif
 
+$(DLL_NAME) :: $(LIBRARY)
+       $(BLD_DLL) --output-lib $(DLL_IMPLIB_NAME) -o $(DLL_NAME) $(LIBRARY) $(BLD_DLL_OPTS)
+endif # LIBRARY != ""
+
+endif # DLLized
+
+#
+# Version information is baked into a DLL by having the DLL include DllVersionInfo.o.
+# The version info contains two user tweakables: DLL_VERSION and DLL_VERSION_NAME.
+# (both are given sensible defaults though.)
+#
+# Note: this will not work as expected with Cygwin B20.1; you need a more recent
+#       version of binutils (to pick up windres bugfixes.)
+
+ifndef DLL_VERSION
+DLL_VERSION=$(ProjectVersion)
+endif
+
+ifndef DLL_VERSION_NAME
+DLL_VERSION_NAME="http://www.haskell.org/ghc"
+endif
+
+ifndef DLL_DESCRIPTION
+DLL_DESCRIPTION="A GHC-compiled DLL"
+endif
+
+ifndef EXE_VERSION
+EXE_VERSION=$(ProjectVersion)
+endif
+
+ifndef EXE_VERSION_NAME
+EXE_VERSION_NAME="http://www.haskell.org/ghc"
+endif
+
+ifndef EXE_DESCRIPTION
+EXE_DESCRIPTION="A GHC-compiled binary"
+endif
+
+#
+# Little bit of lo-fi mangling to get at the right set of settings depending
+# on whether we're generating the VERSIONINFO for a DLL or EXE
+# 
+DLL_OR_EXE=$(subst VersionInfo.$(way_)rc,,$@)
+VERSION_FT=$(subst Dll, 0x2L, $(subst Exe, 0x1L, $(DLL_OR_EXE)))
+VERSION_RES_NAME=$(subst Exe,$(EXE_VERSION_NAME), $(subst Dll, $(DLL_VERSION_NAME),$(DLL_OR_EXE)))
+VERSION_RES=$(subst Exe,$(EXE_VERSION), $(subst Dll, $(DLL_VERSION),$(DLL_OR_EXE)))
+VERSION_DESC=$(subst Exe,$(EXE_DESCRIPTION), $(subst Dll, $(DLL_DESCRIPTION),$(DLL_OR_EXE)))
+
+DllVersionInfo.$(way_)rc ExeVersionInfo.$(way_)rc:
+       $(RM) DllVersionInfo.$(way_)rc
+       echo "1 VERSIONINFO"                > $@
+       echo "FILEVERSION 1,0,0,1"         >> $@
+       echo "PRODUCTVERSION 1,0,0,1"      >> $@
+       echo "FILEFLAGSMASK 0x3fL"         >> $@
+       echo "FILEOS 0x4L"                 >> $@
+       echo "FILETYPE $(VERSION_FT)"      >> $@
+       echo "FILESUBTYPE 0x0L"            >> $@
+       echo "BEGIN"                       >> $@
+       echo " BLOCK \"StringFileInfo\""   >> $@
+       echo " BEGIN"                      >> $@
+       echo "  BLOCK \"040904B0\""        >> $@
+       echo "  BEGIN"                     >> $@
+       echo "   VALUE \"CompanyName\", \"$(VERSION_RES_NAME)\\0\"" >> $@
+       echo "   VALUE \"FileVersion\", \"$(VERSION_RES)\\0\"" >> $@
+       echo "   VALUE \"ProductVersion\", \"$(VERSION_RES)\\0\"" >> $@
+       echo "   VALUE \"FileDescription\", \"$(VERSION_DESC)\\0\"" >> $@
+       echo "  END" >> $@
+       echo " END" >> $@
+       echo " BLOCK \"VarFileInfo\""  >> $@
+       echo " BEGIN" >> $@
+       echo "  VALUE \"Translation\", 0x0409, 1200" >> $@
+       echo " END" >> $@
+       echo "END" >> $@
+
 #----------------------------------------
 #      Script programs
 
@@ -376,22 +536,12 @@ endif
 
 all :: $(SCRIPT_PROG)
 
-#
-# #! support under cygwin32 is not quite there yet, 
-# so we rely on the eval `trick' instead. On all other
-# platforms, we prepend #!$(INTERP)  -- SOF 6/97
-# 
-
-$(SCRIPT_PROG) :: $(SCRIPT_OBJS)
+$(SCRIPT_PROG) : $(SCRIPT_OBJS)
        $(RM) $@
        @echo Creating $@...
 ifeq "$(INTERP)" "perl"
-ifneq "$(BIN_DIST)" "1"
        echo "#! "$(PERL) > $@
 else
-       @touch $@
-endif
-else
 ifneq "$(INTERP)" ""
        @echo "#!"$(INTERP) > $@
 else
@@ -401,22 +551,77 @@ endif
 ifneq "$(SCRIPT_PREFIX_FILES)" ""
        @cat $(SCRIPT_PREFIX_FILES) >> $@
 endif
+ifneq "$(SCRIPT_SUBST)" ""
        @eval $(SCRIPT_SUBST) 
+endif
        @cat $(SCRIPT_OBJS) >> $@
        @chmod a+x $@
        @echo Done.
 endif
 
-# links to script programs: we sometimes install a script as
-# <name>-<version> with a link from <name> to the real script.
+# ---------------------------------------------------------------------------
+# Symbolic links
+
+# links to programs: we sometimes install a program as
+# <name>-<version> with a link from <name> to the real program.
 
-ifneq "$(SCRIPT_LINK)" ""
-all :: $(SCRIPT_LINK)
+ifneq "$(LINK)" ""
 
-$(SCRIPT_LINK) : $(SCRIPT_PROG)
-       $(LN_S) $(SCRIPT_PROG) $(SCRIPT_LINK)
+all :: $(LINK)
+
+CLEAN_FILES += $(LINK)
+
+ifeq "$(LINK_TARGET)" ""
+ifneq "$(SCRIPT_PROG)" ""
+LINK_TARGET = $(SCRIPT_PROG)
+else
+ifneq "$(HS_PROG)" ""
+LINK_TARGET = $(HS_PROG)
+else
+ifneq "$(C_PROG)" ""
+LINK_TARGET = $(C_PROG)
+else
+LINK_TARGET = dunno
+endif
+endif
+endif
 endif
 
+#
+# Don't want to overwrite $(LINK)s that aren't symbolic
+# links. Testing for symbolic links is problematic to do in
+# a portable fashion using a /bin/sh test, so we simply rely
+# on perl.
+#
+$(LINK) : $(LINK_TARGET)
+       @if ( $(PERL) -e '$$fn="$(LINK)"; exit ((! -f $$fn || -l $$fn) ? 0 : 1);' ); then \
+          echo "Creating a symbolic link from $(LINK_TARGET) to $(LINK)"; \
+          $(RM) $(LINK); \
+          $(LN_S) $(LINK_TARGET) $(LINK); \
+        else \
+          echo "Creating a symbolic link from $(LINK_TARGET) to $(LINK) failed: \`$(LINK)' already exists"; \
+          echo "Perhaps remove \`$(LINK)' manually?"; \
+          exit 1; \
+        fi;
+
+
+#
+# install links to script drivers.
+#
+install ::
+       @$(INSTALL_DIR) $(bindir)
+       @if ( $(PERL) -e '$$fn="$(bindir)/$(LINK)"; exit ((! -f $$fn || -l $$fn) ? 0 : 1);' ); then \
+          echo "Creating a symbolic link from $(LINK_TARGET) to $(LINK) in $(bindir)"; \
+          $(RM) $(bindir)/$(LINK); \
+          $(LN_S) $(LINK_TARGET) $(bindir)/$(LINK); \
+        else \
+          echo "Creating a symbolic link from $(LINK_TARGET) to $(LINK) in $(bindir) failed: \`$(bindir)/$(LINK)' already exists"; \
+          echo "Perhaps remove \`$(bindir)/$(LINK)' manually?"; \
+          exit 1; \
+        fi;
+
+endif # LINK 
+
 
 ###########################################
 #
@@ -427,11 +632,13 @@ endif
 # For each of these variables that is defined, you
 # get one install rule
 #
-#      INSTALL_PROGS     executable programs in $(bindir)
-#      INSTALL_SCRIPTS   executable scripts in $(bindir)
-#      INSTALL_LIBS      platform-dependent libraries in $(libdir) (ranlib'ed)
-#      INSTALL_LIBEXECS  platform-dependent execs in $(libdir)
-#      INSTALL_DATAS     platform-independent files in $(datadir)
+#      INSTALL_PROGS        executable programs in $(bindir)
+#      INSTALL_SCRIPTS      executable scripts in $(bindir)
+#      INSTALL_LIBS         platform-dependent libraries in $(libdir) (ranlib'ed)
+#      INSTALL_LIB_SCRIPTS  platform-dependent scripts   in $(libdir)
+#      INSTALL_LIBEXECS     platform-dependent execs in $(libdir)
+#      INSTALL_DATAS        platform-independent files in $(datadir)
+#      INSTALL_IFACES       platform-dependent interface files in $(ifacedir)
 #
 # If the installation directory variable is undefined, the install rule simply
 # emits a suitable error message.
@@ -440,7 +647,7 @@ endif
 # friends can be overridden from their original settings in mk/config.mk.in
 # || mk/build.mk
 #
-.PHONY: install installdirs install-strip install-dirs uninstall install-docs show-install
+.PHONY: install install-docs installdirs install-strip install-dirs uninstall install-docs show-install
 
 show-install :
        @echo "bindir = $(bindir)"
@@ -463,11 +670,38 @@ install-dirs ::
 # within the various install targets instead.
 #install:: install-dirs
 
-ifneq "$(INSTALL_PROGS)" ""
+#
+# Setting user/group ownership for the installed entities
+#
+ifneq "$(INSTALL_OWNER)" ""
+SRC_INSTALL_OPTS += -o $(INSTALL_OWNER)
+endif
+ifneq "$(INSTALL_GROUP)" ""
+SRC_INSTALL_OPTS += -g $(INSTALL_GROUP)
+endif
+
+
+ifneq "$(strip $(INSTALL_PROGS))" ""
+
+#
+# Here's an interesting one - when using the win32 version
+# of install (provided via the cygwin toolkit), we have to
+# supply the .exe suffix, *if* there's no other suffix.
+#
+# The rule below does this by ferreting out the suffix of each
+# entry in the INSTALL_PROGS list. If there's no suffix, use
+# $(exeext).
+# 
+INSTALL_PROGS := $(foreach p, $(INSTALL_PROGS), $(addsuffix $(if $(suffix $(p)),,$(exeext)), $(basename $(p))))
+
 install:: $(INSTALL_PROGS)
        @$(INSTALL_DIR) $(bindir)
-       for i in $(INSTALL_PROGS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_BIN_OPTS) $$i$(exeext) $(bindir); \
+       @for i in $(INSTALL_PROGS); do \
+                   echo $(INSTALL_PROGRAM) $(INSTALL_BIN_OPTS) $$i $(bindir); \
+                   $(INSTALL_PROGRAM) $(INSTALL_BIN_OPTS) $$i $(bindir) ;  \
+                    if test "$(darwin_TARGET_OS)" = "1"; then \
+                      sh $(FPTOOLS_TOP)/mk/fix_install_names.sh $(libdir) $(bindir)/$$i ; \
+                    fi ; \
        done
 endif
 
@@ -475,94 +709,31 @@ endif
 # Just like INSTALL_PROGS, but prefix with install sites bin/lib/data and
 # install without stripping.
 #
-ifneq "$(INSTALL_SCRIPTS)" ""
+ifneq "$(strip $(INSTALL_SCRIPTS))" ""
 install:: $(INSTALL_SCRIPTS)
        @$(INSTALL_DIR) $(bindir)
-ifeq "$(INTERP)" "perl"
-ifneq "$(BIN_DIST)" "1"
-       @for i in $(INSTALL_SCRIPTS); do \
-          $(RM) $$i.tmp; \
-          echo "#! $(PERL)" > $$i.tmp ; \
-          echo '$$'"bindir='$(bindir)';"                            >> $$i.tmp ; \
-          echo '$$'"libdir='$(libdir)';"                            >> $$i.tmp ; \
-          echo '$$'"libexecdir='$(libexecdir)';"                    >> $$i.tmp ; \
-          echo '$$'"datadir='$(datadir)';"                          >> $$i.tmp ; \
-          cat  $$i                                                >> $$i.tmp ; \
-          echo $(INSTALL_PROGRAM) $(filter-out -s,$(INSTALL_BIN_OPTS)) $$i.tmp $(bindir)/$$i ;    \
-          $(INSTALL_PROGRAM) $(filter-out -s,$(INSTALL_BIN_OPTS)) $$i.tmp $(bindir)/$$i ; \
-          $(RM) $$i.tmp; \
-       done
-else
        for i in $(INSTALL_SCRIPTS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(bindir); \
+               $(INSTALL_SCRIPT) $(INSTALL_OPTS) $$i $(bindir); \
        done
 endif
-else
-       for i in $(INSTALL_SCRIPTS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(bindir); \
-       done
-endif
-endif
 
-ifneq "$(INSTALL_LIB_SCRIPTS)" ""
+ifneq "$(strip $(INSTALL_LIB_SCRIPTS))" ""
 install:: $(INSTALL_LIB_SCRIPTS)
        @$(INSTALL_DIR) $(libdir)
-ifeq "$(INTERP)" "perl"
-ifneq "$(BIN_DIST)" "1"
-       @for i in $(INSTALL_LIB_SCRIPTS); do \
-          $(RM) $$i.tmp; \
-          echo "#! $(PERL)" > $$i.tmp ; \
-          echo '$$'"bindir='$(bindir)';"                            >> $$i.tmp ; \
-          echo '$$'"libdir='$(libdir)';"                            >> $$i.tmp ; \
-          echo '$$'"libexecdir='$(libexecdir)';"                    >> $$i.tmp ; \
-          echo '$$'"datadir='$(datadir)';"                          >> $$i.tmp ; \
-          cat  $$i                                                >> $$i.tmp ; \
-          echo $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(libdir) ;    \
-          $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i.tmp $(libdir)/$$i ; \
-          $(RM) $$i.tmp; \
-       done
-else
        for i in $(INSTALL_LIB_SCRIPTS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(libdir); \
+               $(INSTALL_SCRIPT) $(INSTALL_OPTS) $$i $(libdir); \
        done
 endif
-else
-       for i in $(INSTALL_LIB_SCRIPTS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(libdir); \
-       done
-endif
-endif
 
-ifneq "$(INSTALL_LIBEXEC_SCRIPTS)" ""
+ifneq "$(strip $(INSTALL_LIBEXEC_SCRIPTS))" ""
 install:: $(INSTALL_LIBEXEC_SCRIPTS)
        @$(INSTALL_DIR) $(libexecdir)
-ifeq "$(INTERP)" "perl"
-ifneq "$(BIN_DIST)" "1"
-       @for i in $(INSTALL_LIBEXEC_SCRIPTS); do \
-          $(RM) $$i.tmp; \
-          echo "#! $(PERL)" > $$i.tmp ; \
-          echo '$$'"bindir='$(bindir)';"                            >> $$i.tmp ; \
-          echo '$$'"libdir='$(libdir)';"                            >> $$i.tmp ; \
-          echo '$$'"libexecdir='$(libexecdir)';"                    >> $$i.tmp ; \
-          echo '$$'"datadir='$(datadir)';"                          >> $$i.tmp ; \
-          cat  $$i                                                >> $$i.tmp ; \
-          echo $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(libexecdir) ;    \
-          $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i.tmp $(libexecdir)/$$i ; \
-          $(RM) $$i.tmp; \
-       done
-else
-       for i in $(INSTALL_LIBEXEC_SCRIPTS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(libexecdir); \
-       done
-endif
-else
        for i in $(INSTALL_LIBEXEC_SCRIPTS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_OPTS) $$i $(libexecdir); \
+               $(INSTALL_SCRIPT) $(INSTALL_OPTS) $$i $(libexecdir); \
        done
 endif
-endif
 
-ifneq "$(INSTALL_LIBS)" ""
+ifneq "$(strip $(INSTALL_LIBS))" ""
 install:: $(INSTALL_LIBS)
        @$(INSTALL_DIR) $(libdir)
        for i in $(INSTALL_LIBS); do \
@@ -570,21 +741,37 @@ install:: $(INSTALL_LIBS)
                  *.a) \
                    $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(libdir); \
                    $(RANLIB) $(libdir)/`basename $$i` ;; \
+                 *.dll) \
+                   $(INSTALL_DATA) -s $(INSTALL_OPTS) $$i $(libdir) ;; \
+                 *.so) \
+                   $(INSTALL_SHLIB) $(INSTALL_OPTS) $$i $(libdir) ;; \
+                 *.dylib) \
+                   $(INSTALL_SHLIB) $(INSTALL_OPTS) $$i $(libdir); \
+                   install_name_tool -id $(libdir)/`basename $$i` $(libdir)/`basename $$i` ;; \
                  *) \
                    $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(libdir); \
                esac; \
        done
 endif
 
-ifneq "$(INSTALL_LIBEXECS)" ""
+ifneq "$(strip $(INSTALL_LIBEXECS))" ""
+#
+# See above comment next to defn of INSTALL_PROGS for what
+# the purpose of this one-liner is.
+# 
+INSTALL_LIBEXECS := $(foreach p, $(INSTALL_LIBEXECS), $(addsuffix $(subst _,,$(subst __,$(exeext),_$(suffix $(p))_)), $(basename $(p))))
+
 install:: $(INSTALL_LIBEXECS)
        @$(INSTALL_DIR) $(libexecdir)
        -for i in $(INSTALL_LIBEXECS); do \
-               $(INSTALL_PROGRAM) $(INSTALL_BIN_OPTS) $$i$(exeext) $(libexecdir); \
+               $(INSTALL_PROGRAM) $(INSTALL_BIN_OPTS) $$i $(libexecdir); \
+                if test "$(darwin_TARGET_OS)" = "1"; then \
+                        sh $(FPTOOLS_TOP)/mk/fix_install_names.sh $(libdir) $(libexecdir)/`basename $$i` ; \
+                fi ; \
        done
 endif
 
-ifneq "$(INSTALL_DATAS)" ""
+ifneq "$(strip $(INSTALL_DATAS))" ""
 install:: $(INSTALL_DATAS)
        @$(INSTALL_DIR) $(datadir)
        for i in $(INSTALL_DATAS); do \
@@ -592,34 +779,92 @@ install:: $(INSTALL_DATAS)
        done
 endif
 
+ifneq "$(strip $(INSTALL_IFACES))" ""
+install:: $(INSTALL_IFACES)
+       @$(INSTALL_DIR) $(ifacedir)
+       for i in $(INSTALL_IFACES); do \
+               $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(ifacedir); \
+       done
+endif
+
+ifneq "$(strip $(INSTALL_IFACES_WITH_DIRS))" ""
+install:: $(INSTALL_IFACES_WITH_DIRS)
+       @$(INSTALL_DIR) $(ifacedir)
+       for i in $(INSTALL_IFACES_WITH_DIRS); do \
+               $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(ifacedir)/`dirname $$i`; \
+       done
+endif
+
+ifneq "$(strip $(INSTALL_INCLUDES))" ""
+install:: $(INSTALL_INCLUDES)
+       @$(INSTALL_DIR) $(includedir)
+       for i in $(INSTALL_INCLUDES); do \
+               $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(includedir); \
+       done
+endif
+
+ifneq "$(strip $(INSTALL_DOCS))" ""
+ifneq "$(XMLDocWays)" ""
+install-docs:: $(INSTALL_DOCS)
+       @$(INSTALL_DIR) $(datadir)      
+       for i in $(INSTALL_DOCS); do \
+               $(INSTALL_DATA) $(INSTALL_OPTS) $$i $(datadir); \
+       done
+endif
+endif
+
+# TODO: The following could be an entry for an Obfuscated Makefile Contest...
+ifneq "$(strip $(INSTALL_XML_DOC))" ""
+ifneq "$(XMLDocWays)" ""
+install-docs:: $(foreach i,$(XMLDocWays),$(INSTALL_XML_DOC)$(patsubst %.html-no-chunks,%.html,$(patsubst %.html,%/index.html,.$(i))))
+       @$(INSTALL_DIR) $(datadir)      
+       @for i in $(XMLDocWays); do \
+               if [ $$i = "html" ]; then \
+                       $(INSTALL_DIR) $(datadir)/html; \
+                       $(INSTALL_DIR) $(datadir)/html/$(INSTALL_XML_DOC); \
+                       echo "( cd $(INSTALL_XML_DOC) && $(CP) * $(datadir)/html/$(INSTALL_XML_DOC) )" ; \
+                       ( cd $(INSTALL_XML_DOC) && $(CP) * $(datadir)/html/$(INSTALL_XML_DOC) ) ; \
+               else \
+                       $(INSTALL_DIR) $(datadir)/doc; \
+                       echo $(INSTALL_DATA) $(INSTALL_OPTS) $(INSTALL_XML_DOC)`echo .$$i | sed s/\.html-no-chunks/.html/` $(datadir)/doc; \
+                       $(INSTALL_DATA) $(INSTALL_OPTS) $(INSTALL_XML_DOC)`echo .$$i | sed s/\.html-no-chunks/.html/` $(datadir)/doc; \
+               fi; \
+               if [ $$i = "html-no-chunks" ]; then \
+                       echo $(CP) $(FPTOOLS_CSS_ABS) $(datadir)/doc; \
+                       $(CP) $(FPTOOLS_CSS_ABS) $(datadir)/doc; \
+               fi \
+       done
+endif
+endif
+
 #
 # Use with care..
 #
 uninstall:: 
-ifeq ($(INSTALL_PROGS),)
-       @for i in $(INSTALL_PROGS) ; do                         \
+       @for i in $(INSTALL_PROGS) "" ; do                      \
+         if test "$$i"; then                                   \
                echo rm -f $(bindir)/`basename $$i`;            \
                rm -f $(bindir)/`basename $$i`;                 \
+         fi;                                                   \
        done
-endif
-ifeq ($(INSTALL_LIBS),)
-       @for i in $(INSTALL_LIBS); do                           \
+       @for i in $(INSTALL_LIBS) ""; do                        \
+         if test "$$i"; then                                   \
                echo rm -f $(libdir)/`basename $$i`;            \
                rm -f $(libdir)/`basename $$i`;                 \
+         fi;                                                   \
        done
-endif
-ifeq ($(INSTALL_LIBEXECS),)
-       @for i in $(INSTALL_LIBEXECS); do                       \
+       @for i in $(INSTALL_LIBEXECS) ""; do                    \
+         if test "$$i"; then                                   \
                echo rm -f $(libexecdir)/`basename $$i`;        \
                rm -f $(libexecdir)/`basename $$i`;             \
+         fi;                                                   \
        done
-endif
-ifeq ($(INSTALL_DATAS),)
-       @for i in $(INSTALL_DATAS); do                          \
+       @for i in $(INSTALL_DATAS) ""; do                       \
+         if test "$$i"; then                                   \
                echo rm -f $(datadir)/`basename $$i`;           \
                rm -f $(datadir)/`basename $$i`;                \
+         fi;                                                   \
        done
-endif
 
 #
 # install-strip is from the GNU Makefile standard.
@@ -629,162 +874,11 @@ install-strip::
        @$(MAKE) EXTRA_INSTALL_OPTS='-s' install                                        
 endif
 
+##############################################################################
 #
-# install links to script drivers.
-#
-ifneq "$(SCRIPT_LINK)" ""
-install ::
-       $(LN_S) $(SCRIPT_PROG) $(bindir)/$(SCRIPT_LINK)
-endif
-
-###########################################
-#
-#      Targets: dist binary-dist
-#
-###########################################
-
-
-#
-# dist-pre is a canned rule the toplevel of your source tree
-# would use as follows, 
-#
-#  dist :: dist-pre
-#
-# it performs two tasks, first creating the distribution directory
-# tree and it then decorates the new tree with symbolic links pointing
-# to the symbolic links in the build tree.
-#
-# The dist-pre relies on (at least) the `find' in GNU findutils
-# (only tested with version 4.1). All non-GNU `find's I have
-# laid on my hands locally, has a restrictive treatment of {} in
-# -exec commands, i.e.,
-#
-#   find . -print echo a{} \;
-#   
-# does not expand the {}, it has to be a separate argument (i.e. `a {}').
-# GNU find is (IMHO) more sensible here, expanding any {} it comes across
-# inside an -exec, whether it is a separate arg or part of a word:
+#      Targets: check tags show
 #
-#  $ touch yes
-#  $ find --version
-#    GNU find version 4.1
-#  $ find yes -exec echo oh,{}! \;
-#    oh,yes!
-#
-# Of course, the above is not impossible to achieve with other finds,
-# just that GNU find does the Patently Right Thing here :)
-#
-# ====> if you're using these dist rules, get hold of GNU findutils.
-#
-#  --SOF 2/97
-#
-.PHONY: dist dist-pre dist-post
-
-#
-# The dist rules leaves out CVS, SRC (from mkshadowdir) and tests
-# directories when creating shadow source distrib tree
-#
-dist-pre::
-       -rm -rf $(SRC_DIST_DIR)
-       -rm -f $(SRC_DIST_NAME).tar.gz
-       (cd $(FPTOOLS_TOP_ABS); find $(SRC_DIST_DIRS) -type d \( -name CVS -prune -o -name SRC -prune -o -name tests -prune -o -exec $(MKDIRHIER) $(SRC_DIST_DIR)/{} \; \) ; )
-       (cd $(FPTOOLS_TOP_ABS); find $(SRC_DIST_DIRS) -name CVS -prune -o -name SRC -prune -o -name tests -prune -o -name "*~" -prune -o -name ".cvsignore" -prune -o -name "\#*" -prune -o -name ".\#*" -prune -o -type l -exec $(LN_S) $(FPTOOLS_TOP_ABS)/{} $(SRC_DIST_DIR)/{} \; )
-
-#
-# After having created a shadow distribution tree and copied/linked
-# all the necessary files to it, `dist-post' makes sure the permissions
-# are set right and then package up the tree. Empty directories are also removed.
-#
-# For now, we make the packaging a separate rule, so as to allow
-# the inspection of the dist tree before eventually packaging it up.
-#
-dist-post::
-       @echo Deleting the following empty directories..
-       ( cd $(SRC_DIST_DIR) ; cd .. ; find $(SRC_DIST_NAME) -type d -exec sh -c 'test x`ls $$0 | wc -l | sed -e "s/ //g"` = x0' {} \; -print -exec rm -rf {} \; -prune )
-       ( cd $(SRC_DIST_DIR) ; cd .. ; chmod -R a+rw $(SRC_DIST_NAME) ) 
-
-dist-package::
-       cd $(SRC_DIST_DIR); cd ..; $(TAR) chzf $(SRC_DIST_NAME).tar.gz $(SRC_DIST_NAME)
-
-#
-
-
-# The default dist rule:
-#
-# copy/link the contents of $(SRC_DIST_FILES) into the
-# shadow distribution tree. SRC_DIST_FILES contain the
-# build-generated files that you want to include in
-# a source distribution.
-#
-#
-ifneq "$(SRC_DIST_FILES)" ""
-dist::
-       @for i in $(SRC_DIST_FILES); do                  \
-         if (test -f "$$i"); then                       \
-           echo $(LN_S) `pwd`/$$i $(SRC_DIST_DIR)/$$i ; \
-           $(LN_S) `pwd`/$$i $(SRC_DIST_DIR)/$$i ;      \
-         fi;                                            \
-       done;
-endif
-
-#
-# binary-dist creates a binary bundle, set BIN_DIST_NAME
-# to package name and do `make binary-dist' (normally this
-# just a thing you would do from the toplevel of fptools or)
-# from the top of a project.
-#
-.PHONY: binary-dist-pre binary-dist binary-pack
-
-binary-dist-pre::
-       -rm -rf $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)
-       -rm -f $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME).tar.gz
-       @for i in $(BIN_DIST_DIRS); do                   \
-         if test -d "$$i"; then                         \
-          echo $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion); \
-          $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion); \
-          echo $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion); \
-          $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion); \
-          echo $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share/$(ProjectNameShort)-$(ProjectVersion); \
-          $(MKDIRHIER) $(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share/$(ProjectNameShort)-$(ProjectVersion); \
-          echo $(MAKE) -C $$i $(MFLAGS) install BIN_DIST=1 BIN_DIST_NAME=$(BIN_DIST_NAME) \
-                       prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \
-                       exec_prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \
-                       bindir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion) \
-                       libdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion) \
-                       libexecdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion) \
-                       datadir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share/$(ProjectNameShort)-$(ProjectVersion) ; \
-          $(MAKE) -C $$i $(MFLAGS) install BIN_DIST=1 BIN_DIST_NAME=$(BIN_DIST_NAME) \
-                       prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \
-                       exec_prefix=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME) \
-                       bindir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/bin/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion) \
-                       libdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion) \
-                       libexecdir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/lib/$(TARGETPLATFORM)/$(ProjectNameShort)-$(ProjectVersion) \
-                       datadir=$(BIN_DIST_TMPDIR)/$(BIN_DIST_NAME)/share/$(ProjectNameShort)-$(ProjectVersion) ; \
-         fi; \
-       done
-
-#
-# Do this separately for now
-# 
-binary-pack::
-       ( cd $(BIN_DIST_TMPDIR); $(TAR) chzf $(BIN_DIST_NAME).tar.gz $(BIN_DIST_NAME); rm -rf $(BIN_DIST_NAME) )
-
-ifneq "$(way)" ""
-package-way-dist::
-       ( cd $(BIN_DIST_TMPDIR); find $(BIN_DIST_NAME)/ \( -name "*$(_way).a" -o -name "*.$(way_)hi" \) -print | xargs tar cvf $(BIN_DIST_TMPDIR)/ghc-$(ProjectVersion)-$(way)-$(TARGETPLATFORM).tar )
-       gzip $(BIN_DIST_TMPDIR)/ghc-$(ProjectVersion)-$(way)-$(TARGETPLATFORM).tar
-endif
-
-ifneq "$(way)" ""
-remove-way-dist::
-       ( cd $(BIN_DIST_TMPDIR); find $(BIN_DIST_NAME)/ \( -name "*$(_way).a" -o -name "*.$(way_)hi" \) -print -exec rm -f {} \; )
-endif
-
-###########################################
-#
-#      Targets: check tags show info
-#
-###########################################
+##############################################################################
 
 #------------------------------------------------------------
 #                      Check
@@ -808,7 +902,7 @@ tags TAGS:: $(TAGS_HS_SRCS) $(TAGS_C_SRCS)
        @$(RM) TAGS
        @touch TAGS
 ifneq "$(TAGS_HS_SRCS)" ""
-       $(HSTAGS) $(HSTAGS_OPTS) -- $(TAGS_HS_SRCS)
+       $(HSTAGS) $(HSTAGS_OPTS) $(TAGS_HS_SRCS)
 endif
 ifneq "$(TAGS_C_SRCS)" ""
        etags -a $(TAGS_C_SRCS)
@@ -822,109 +916,90 @@ endif
 #
 
 show:
-       @echo '$(VALUE)=$($(VALUE))'
+       @echo '$(VALUE)="$($(VALUE))"'
 
-#--------------------------------------------------------------------------
-# SGML Documentation
+################################################################################
 #
-.PHONY: dvi ps html info txt
-
-ifneq "$(SGML_DOC)" ""
-
-# multi-file SGML document: main document name is specified in $(SGML_DOC),
-# sub-documents (.sgml files) listed in $(SGML_SRCS).
+#                      DocBook XML Documentation
+#
+################################################################################
 
-$(SGML_DOC).sgml : $(SGML_SRCS)
-       cat $(SGML_SRCS) > $(SGML_DOC).sgml
+.PHONY: html html-no-chunks chm HxS fo dvi ps pdf
 
-SGML_DVI  = $(SGML_DOC).dvi
-SGML_PS   = $(SGML_DOC).ps
-SGML_INFO = $(SGML_DOC).info
-SGML_HTML = $(SGML_DOC).html
-SGML_TEXT = $(SGML_DOC).txt
+ifneq "$(XML_DOC)" ""
 
-else # no SGML_DOC
+all :: $(XMLDocWays)
 
-VSGML_SRCS = $(wildcard *.vsgml)
+# multi-file XML document: main document name is specified in $(XML_DOC),
+# sub-documents (.xml files) listed in $(XML_SRCS).
 
-ifneq "$(VSGML_SRCS)" ""
-SGML_SRCS  = $(addsuffix .sgml, $(basename $(VSGML_SRCS)))
-else
-SGML_SRCS  = $(wildcard *.sgml)
+ifeq "$(XML_SRCS)" ""
+XML_SRCS = $(wildcard *.xml)
 endif
 
-SGML_DVI  = $(addsuffix  .dvi, $(basename $(SGML_SRCS)))
-SGML_PS   = $(addsuffix   .ps, $(basename $(SGML_SRCS)))
-SGML_INFO = $(addsuffix .info, $(basename $(SGML_SRCS)))
-SGML_HTML = $(addsuffix .html, $(basename $(SGML_SRCS)))
-SGML_TEXT = $(addsuffix  .txt, $(basename $(SGML_SRCS)))
-
-endif # SGML_DOC
-
-dvi  :: $(SGML_DVI)
-info :: $(SGML_INFO)
-html :: $(SGML_HTML)
-txt  :: $(SGML_TXT)
-ps   :: $(SGML_PS)
-
-CLEAN_FILES += $(SGML_TEXT) $(SGML_HTML) $(SGML_PS) $(SGML_DVI)
+XML_HTML           = $(addsuffix /index.html,$(basename $(XML_DOC)))
+XML_HTML_NO_CHUNKS = $(addsuffix .html,$(XML_DOC))
+XML_CHM            = $(addsuffix .chm,$(XML_DOC))
+XML_HxS            = $(addsuffix .HxS,$(XML_DOC))
+XML_FO             = $(addsuffix .fo,$(XML_DOC))
+XML_DVI            = $(addsuffix .dvi,$(XML_DOC))
+XML_PS             = $(addsuffix .ps,$(XML_DOC))
+XML_PDF            = $(addsuffix .pdf,$(XML_DOC))
+
+$(XML_HTML) $(XML_NO_CHUNKS_HTML) $(XML_FO) $(XML_DVI) $(XML_PS) $(XML_PDF) :: $(XML_SRCS)
+
+html           :: $(XML_HTML)
+html-no-chunks :: $(XML_HTML_NO_CHUNKS)
+chm            :: $(XML_CHM)
+HxS            :: $(XML_HxS)
+fo             :: $(XML_FO)
+dvi            :: $(XML_DVI)
+ps             :: $(XML_PS)
+pdf            :: $(XML_PDF)
+
+CLEAN_FILES += $(XML_HTML_NO_CHUNKS) $(XML_FO) $(XML_DVI) $(XML_PS) $(XML_PDF)
+
+extraclean ::
+       $(RM) -rf $(XML_DOC).out $(FPTOOLS_CSS) $(basename $(XML_DOC)) $(basename $(XML_DOC))-htmlhelp
+
+validate ::
+       $(XMLLINT) --valid --noout $(XMLLINT_OPTS) $(XML_DOC).xml
+endif
 
-###########################################
+##############################################################################
 #
 #      Targets: clean
 #
-###########################################
-
-.PHONY: realclean mostlyclean clean distclean maintainer-clean
+##############################################################################
 
-# realclean is just a synonym for maintainer-clean
-realclean: maintainer-clean
+# we have to be careful about recursion here; since all the clean
+# targets are recursive, we don't want to make eg. distclean depend on
+# clean because that would result in far too many recursive calls.
 
+.PHONY: mostlyclean clean distclean maintainer-clean
 
-ifneq "$(MOSTLY_CLEAN_FILES)" ""
 mostlyclean::
        rm -f $(MOSTLY_CLEAN_FILES)
-endif
-
-ifneq "$(CLEAN_FILES)" ""
-clean:: mostlyclean
-       rm -f $(CLEAN_FILES)
-endif
 
+# extraclean is used for adding actions to the clean target.
+extraclean::
 
-ifneq "$(DIST_CLEAN_FILES)" ""
-distclean:: mostlyclean clean
-       rm -f $(DIST_CLEAN_FILES)
-endif
+clean:: extraclean
+       rm -f $(MOSTLY_CLEAN_FILES) $(CLEAN_FILES)
 
+distclean:: extraclean
+       rm -f $(MOSTLY_CLEAN_FILES) $(CLEAN_FILES) $(DIST_CLEAN_FILES)
 
-ifneq "$(MAINTAINER_CLEAN_FILES)" ""
-maintainer-clean:: mostlyclean clean distclean
+maintainer-clean:: extraclean
        @echo 'This command is intended for maintainers to use; it'
        @echo 'deletes files that may need special tools to rebuild.'
-       rm -f $(MAINTAINER_CLEAN_FILES)
-endif
-
-#
-# If (Haskell) object files are split, cleaning up 
-# consist of descending into the directories where
-# the myriads of object files have been put.
-#
-
-ifneq "$(HS_OBJS)" ""
-ifneq "$(filter -split-objs,$(HC_OPTS))" ""
-clean ::
-       find $(patsubst %.$(way_)o,%,$(HS_OBJS)) -name '*.$(way_)o' -print | xargs $(RM) __rm_food
-       -rmdir $(patsubst %.$(way_)o,%,$(HS_OBJS))
-endif
-endif
-
+       rm -f $(MOSTLY_CLEAN_FILES) $(CLEAN_FILES) $(DIST_CLEAN_FILES) $(MAINTAINER_CLEAN_FILES)
 
-#################################################################################
+################################################################################
 #
 #                      Way management
 #
-#################################################################################
+################################################################################
 
 # Here is the ingenious jiggery pokery that allows you to build multiple versions
 # of a program in a single build tree.
@@ -934,6 +1009,11 @@ endif
 # Expects:     $(WAYS)                 the possible "way" strings to one of 
 #                                      which $(way) will be set
 
+ifneq "$(way)" ""
+ifeq "$(findstring $(way), $(WAYS))" ""
+$(error Unknown way $(way))
+endif
+endif
 
 # So how does $(way) ever get set to anything?  Answer, we recursively
 # invoke make, setting $(way) on the command line.
@@ -979,11 +1059,58 @@ $(LIB_WAY_TARGETS) :
 
 endif  # if way
 
+# -------------------------------------------------------------------------
+# Object and interface files have suffixes tagged with their ways
+
+ifneq "$(way)" ""
+SRC_HC_OPTS += -hisuf $(way_)hi -hcsuf $(way_)hc -osuf $(way_)o
+endif
+
+# -------------------------------------------------------------------------
+# Rules to invoke the current target recursively for each way
+
+ifneq "$(strip $(WAYS))" ""
+ifeq "$(way)" ""
+
+# NB: the targets exclude 
+#      boot runtests
+# since these are way-independent
+all docs TAGS clean distclean mostlyclean maintainer-clean install ::
+       @echo "------------------------------------------------------------------------"
+       @echo "== Recursively making \`$@' for ways: $(WAYS) ..."
+       @echo "PWD = $(shell pwd)"
+       @echo "------------------------------------------------------------------------"
+# Don't rely on -e working, instead we check exit return codes from sub-makes.
+       case '${MFLAGS}' in *-[ik]*) x_on_err=0;; *-r*[ik]*) x_on_err=0;; *) x_on_err=1;; esac; \
+       for i in $(WAYS) ; do \
+         echo "------------------------------------------------------------------------"; \
+         echo "== $(MAKE) way=$$i $@;"; \
+         echo "PWD = $(shell pwd)"; \
+         echo "------------------------------------------------------------------------"; \
+         $(MAKE) way=$$i --no-print-directory $(MFLAGS) $@ ; \
+         if [ $$? -eq 0 ] ; then true; else exit $$x_on_err; fi; \
+       done
+       @echo "------------------------------------------------------------------------"
+       @echo "== Finished recursively making \`$@' for ways: $(WAYS) ..."
+       @echo "PWD = $(shell pwd)"
+       @echo "------------------------------------------------------------------------"
+
+endif
+endif
+
 
 ##################################################################
 #
 #              Recursive stuff
 #
+# This was once at the top of the file, allegedly because it was
+# needed for some targets, e.g. when building DLLs in libraries.  But
+# since this reason is a little short on information, and I'm having
+# trouble with subdirectory builds happening before the current
+# directory when building hslibs (bad interaction with including
+# _hsc.o files in the cbits lib) so I'm moving the recursive makes to
+# the end --SDM 12/12/2001
+#
 ##################################################################
 
 # Here are the diabolically clever rules that
@@ -993,7 +1120,7 @@ endif      # if way
 #
 # (b) when SUBDIRS is empty,
 #     for each "multi-way-target" <t>
-#     calls "make -way=w <t>" for each w in $(WAYS)
+#     calls "make way=w <t>" for each w in $(WAYS)
 #
 #     This has the effect of making the standard target
 #     in each of the specified ways (as well as in the normal way
@@ -1016,41 +1143,58 @@ endif   # if way
 # the --no-print-directory flag which is passed to recursive
 # invocations of make.
 #
-# NOTE: Truly weird use of exit below to stop the for loop dead in
-# its tracks should any of the sub-makes fail. By my reckoning, 
-#  "cmd || exit $?" should be equivalent to "cmd"
-
 ifeq "$(way)" ""
 ifneq "$(SUBDIRS)" ""
 
-all docs runtests boot TAGS clean veryclean maintainer-clean install info ::
+# we override the 'boot', 'all' and 'install' targets in the top
+# level Makefile. Some of the sub-projects also set 'boot' to empty.
+
+ifeq "$(NO_ALL_TARGET)" "YES"
+ALL_TARGET     =
+else
+ALL_TARGET     = all
+endif
+
+ifeq "$(NO_BOOT_TARGET)" "YES"
+BOOT_TARGET    =
+else
+BOOT_TARGET    = boot
+endif
+
+ifeq "$(NO_INSTALL_TARGET)" "YES"
+INSTALL_TARGET =
+INSTALL_DOCS_TARGET =
+else
+INSTALL_TARGET = install
+INSTALL_DOCS_TARGET = install-docs
+endif
+
+$(ALL_TARGET) docs runtests $(BOOT_TARGET) TAGS clean distclean mostlyclean maintainer-clean $(INSTALL_TARGET) $(INSTALL_DOCS_TARGET) html chm HxS ps dvi txt::
        @echo "------------------------------------------------------------------------"
-       @echo "===fptools== Recursively making \`$@' in $(SUBDIRS) ..."
+       @echo "== Recursively making \`$@' in $(SUBDIRS) ..."
        @echo "PWD = $(shell pwd)"
        @echo "------------------------------------------------------------------------"
 # Don't rely on -e working, instead we check exit return codes from sub-makes.
        @case '${MFLAGS}' in *-[ik]*) x_on_err=0;; *-r*[ik]*) x_on_err=0;; *) x_on_err=1;; esac; \
+       if [ $$x_on_err -eq 0 ]; \
+           then echo "Won't exit on error due to MFLAGS: ${MFLAGS}"; \
+       fi; \
        for i in $(SUBDIRS); do \
          echo "------------------------------------------------------------------------"; \
-         echo "==fptools== $(MAKE) $@ $(MFLAGS);"; \
+         echo "== $(MAKE) $@ $(MFLAGS);"; \
          echo " in $(shell pwd)/$$i"; \
          echo "------------------------------------------------------------------------"; \
          $(MAKE) --no-print-directory -C $$i $(MFLAGS) $@; \
-         if [ $$? -eq 0 -o $$x_on_err -eq 0 ] ;  then true; else exit 1; fi; \
+         if [ $$? -eq 0 -o $$x_on_err -eq 0 ]; \
+             then echo "Finished making $@ in $$i": $$?; \
+             else echo "Failed making $@ in $$i": $$?; exit 1; \
+         fi; \
        done
        @echo "------------------------------------------------------------------------"
-       @echo "===fptools== Finished making \`$@' in $(SUBDIRS) ..."
+       @echo "== Finished making \`$@' in $(SUBDIRS) ..."
        @echo "PWD = $(shell pwd)"
        @echo "------------------------------------------------------------------------"
 
-dist ::
-# Don't rely on -e working, instead we check exit return codes from sub-makes.
-       @case '${MFLAGS}' in *-[ik]*) x_on_err=0;; *-r*[ik]*) x_on_err=0;; *) x_on_err=1;; esac; \
-       for i in $(SUBDIRS) ; do \
-         $(MKDIRHIER_PREFIX)mkdirhier $(SRC_DIST_DIR)/$$i; \
-         $(MAKE) -C $$i $(MFLAGS) $@ SRC_DIST_DIR=$(SRC_DIST_DIR)/$$i; \
-         if [ $$? -eq 0 ] ;  then true; else exit $$x_on_err; fi; \
-       done
 endif
 endif
 
@@ -1063,32 +1207,16 @@ $(SUBDIRS) ::
          $(MAKE) -C $@ $(MFLAGS)
 endif
 
-ifneq "$(WAYS)" ""
-ifeq "$(way)" ""
+# -----------------------------------------------------------------------------
+# Further cleaning
 
-# NB: the targets exclude 
-#      boot info TAGS runtests
-# since these are way-independent
-all docs TAGS clean veryclean maintainer-clean install ::
-       @echo "------------------------------------------------------------------------"
-       @echo "===fptools== Recursively making \`$@' for ways: $(WAYS) ..."
-       @echo "PWD = $(shell pwd)"
-       @echo "------------------------------------------------------------------------"
-# Don't rely on -e working, instead we check exit return codes from sub-makes.
-       @case '${MFLAGS}' in *-[ik]*) x_on_err=0;; *-r*[ik]*) x_on_err=0;; *) x_on_err=1;; esac; \
-       for i in $(WAYS) ; do \
-         echo "------------------------------------------------------------------------"; \
-         echo "==fptools== $(MAKE) way=$$i $@;"; \
-         echo "PWD = $(shell pwd)"; \
-         echo "------------------------------------------------------------------------"; \
-         $(MAKE) way=$$i --no-print-directory $(MFLAGS) $@ ; \
-         if [ $$? -eq 0 ] ; then true; else exit $$x_on_err; fi; \
-       done
-       @echo "------------------------------------------------------------------------"
-       @echo "===fptools== Finished recursively making \`$@' for ways: $(WAYS) ..."
-       @echo "PWD = $(shell pwd)"
-       @echo "------------------------------------------------------------------------"
+# Sometimes we want to clean things only after the recursve cleaning
+# has heppened (eg. if the files we're about to remove would affect
+# the recursive traversal).
 
-endif
-endif
+distclean::
+       rm -f $(LATE_DIST_CLEAN_FILES)
+
+maintainer-clean::
+       rm -f $(LATE_DIST_CLEAN_FILES)