OSDN Git Service

Consolidate fmod() and remainder() source code.
[mingw/mingw-org-wsl.git] / mingwrt / Makefile.in
index 79c829e..6c562e8 100644 (file)
@@ -7,7 +7,7 @@ PACKAGE_TARNAME := @PACKAGE_TARNAME@
 PACKAGE_VERSION := @PACKAGE_VERSION@
 
 # Written by Keith Marshall <keithmarshall@users.sourceforge.net>
-# Copyright (C) 2014, MinGW.org Project
+# Copyright (C) 2014-2020, MinGW.org Project
 #
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
@@ -16,11 +16,11 @@ PACKAGE_VERSION := @PACKAGE_VERSION@
 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
 # and/or sell copies of the Software, and to permit persons to whom the
 # Software is furnished to do so, subject to the following conditions:
-# 
+#
 # The above copyright notice and this permission notice (including the next
 # paragraph) shall be included in all copies or substantial portions of the
 # Software.
-# 
+#
 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -34,9 +34,16 @@ PACKAGE_VERSION := @PACKAGE_VERSION@
 # inadvertent override from any included file.
 #
 all:
-PACKAGE_RELEASE := 
+PACKAGE_RELEASE :=
 PACKAGE_RELEASE_TAG := $(PACKAGE_VERSION)$(PACKAGE_RELEASE:%=-%)-mingw32
-NTDDI_VERSION_SPEC := -D NTDDI_VERSION=0x04000000
+
+# Establish the minimum version of Windows which this build is required
+# to support; note that we fix the default as WinNT4, but we define it in
+# a manner which will allow a command line override, and may be adapted,
+# ultimately, to support a configure time assignment.
+#
+NTDDI_VERSION := NTDDI_WINNT4
+NTDDI_VERSION_SPEC := $(NTDDI_VERSION:%=-D NTDDI_VERSION=%)
 
 # Build paths and macros.
 #
@@ -63,14 +70,16 @@ STRIP = @STRIP@
 NM = @NM@
 
 all: @DEFAULT_MAKECMDGOALS@
-all-mingwrt-stage-1: all-mingwrt-objects all-mingwrt-libs
-all-mingwrt-stage-1-and-2: all-mingwrt-stage-1 all-mingwrt-dll
+all-mingwrt-stage-1-only: _mingw.h w32api.h
+all-mingwrt-stage-1-only: all-mingwrt-objects all-mingwrt-libs
+all-mingwrt-stage-1-and-2: all-mingwrt-stage-1-only all-mingwrt-dll
 all-mingwrt: all-mingwrt-stage-1-and-2
+all-gcc: all-mingwrt-stage-1-only
 
-include_deprecated = @include_deprecated@
-active_goals = $1-$2 $(if $(include_deprecated),$1-deprecated-$2)
+active_goals = $1-$2 $(if @include_deprecated@,$1-deprecated-$2)
+all-deprecated-mingwrt-stage-1-only: all-deprecated-mingwrt
 
-all-stage-1: $(call active_goals,all,mingwrt-stage-1)
+all-stage-1-only: $(call active_goals,all,mingwrt-stage-1-only)
 all-stage-1-and-2: $(call active_goals,all,mingwrt)
 
 # Installation paths and macros.
@@ -93,55 +102,32 @@ man3dir = ${mandir}/man$(man3ext)
 man3ext = 3
 
 INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
+INSTALL_DATA = @INSTALL_DATA@ $1 $2
 
-mkinstalldirs = @MKDIR_P@
+mkinstalldirs = @MKDIR_P@ $(addprefix $1,$2)
+LN_S = @LN_S@
 
-# Keep the configuration in a consistent state.  Note that we assume
-# that configure has been run initially, (otherwise we wouldn't have 
-# a Makefile to begin with); since this also creates config.status,
-# we may normally assume that it is already available ...
+# Include the makefile content which is common to both the mingwrt,
+# and the w32api packages; this may be included within the top level
+# source directory for each package individually, but we must also
+# be prepared to find it in their common parent directory.
 #
-vpath configure ${top_srcdir}
-config.status: configure
-       $(SHELL) config.status --recheck
-
-# ... in which case, updating Makefile should be a simple matter of
-# running config.status ...
-#
-vpath Makefile.in ${top_srcdir}
-requires_existing = $(if $(wildcard $1),$1,$1.missing)
-Makefile: Makefile.in configure $(call requires_existing,config.status)
-       $(SHELL) config.status
-       $(RM) Makefile.stub
-
-.PHONY: config.status.missing
-# ... but, in the event that this may be missing, (e.g. because it
-# has been manually removed, or removed by "make distclean"), suggest
-# running configure, and bail out.
-#
-config.status.missing:
-       $(warning *** cannot execute config.status)
-       $(error please run ${top_srcdir}/configure to regenerate it.)
-
-# If configure itself needs to be updated, we must run autoconf in the
-# top level source directory.
-#
-vpath %.m4 ${top_srcdir}
-vpath configure.ac ${top_srcdir}
-configure: configure.ac aclocal.m4
-       cd ${top_srcdir}; autoconf
+shared_include_file = $1$(if $(wildcard $1/$2),,/..)/$2
+include $(call shared_include_file,${top_srcdir},Makefile.comm)
 
 # Capture dependencies conveyed within source files, ensuring that
 # header files are taken from our working source tree, and not from
-# the build-time compiler's installation path.
+# the build-time compiler's installation path.  (Note: we use -MD,
+# and not -MMD in DEPFLAGS; since this package furnishes system
+# headers, we need changes therein to trigger a rebuild).
 #
 sinclude *.d
-DEPFLAGS = -MMD -MP
+DEPFLAGS = -MD -MP
 INCLUDES = -nostdinc -I . -I ${top_srcdir}/include -I ${w32api_srcdir}/include \
   -I ${top_srcdir} -I ${top_srcdir}/profile -iwithprefixbefore include
 
 ALL_CFLAGS = $(CFLAGS) $(DEPFLAGS) $(INCLUDES) $(NTDDI_VERSION_SPEC)
+ALL_CPPFLAGS = $(CPPFLAGS) $(DEPFLAGS) $(INCLUDES) $(NTDDI_VERSION_SPEC)
 
 # The general case, for compiling object files from C source,
 # requires a small adjustment to the default implicit rule.
@@ -202,11 +188,18 @@ $(addsuffix .$(OBJEXT), crt1 dllcrt1): %.$(OBJEXT): %.c
        $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -D__CRTDLL__ -o $@ $<
 
 # ...while, for the current build case, we need an explicit mapping
-# to identify the disparately named source file.
+# to identify the disparately named source file...
 #
 $(addsuffix .$(OBJEXT), crt2 dllcrt2): %2.$(OBJEXT): %1.c
        $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -o $@ $<
 
+# ...and for the pair of default FPU configuration selectors, we
+# need to pass the configuration specification to the compiler, when
+# compiling the common source for each of the two cases.
+#
+CRT_fp8.$(OBJEXT) CRT_fp10.$(OBJEXT): CRT_fp%.$(OBJEXT): CRT_fenv.c
+       $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -D_CRT_FE_DFL_ENV=$* -o $@ $<
+
 # The initialization hook for profiling code is inherited from Cygwin,
 # where it is built as gcrt0.$(OBJEXT); we build it, unmodified, as each
 # of gcrt1.$(OBJEXT) and gcrt2.$(OBJEXT), to satisfy the differing GCC
@@ -230,7 +223,7 @@ $(addsuffix .$(OBJEXT), gcrt0 gcrt1 gcrt2): %.$(OBJEXT): gcrt0.c
 #
 msvcrt_versions := 70 71 80 90 100
 msvcrt_version_script = echo $1 | awk '\
-  { printf "0x%03d0", gensub( "^[^1-9]*([0-9]*).*", "\\\\1", 1 ) \
+  { printf "0x%03d00000", gensub( "^[^1-9]*([0-9]*).*", "\\\\1", 1 ) \
   }'
 
 extra_objects_filter = $(filter %.$(OBJEXT),$1)
@@ -262,20 +255,22 @@ all-deprecated-mingwrt all-deprecated-libmsvcrt: all-libcrtdll
 # definition file, from a common source.
 #
 .SUFFIXES: .def.in .def
-$(addsuffix .def,$(all_msvcrt)): %.def: ${mingwrt_srcdir}/msvcrt.def.in
-       $(CC) -C -E -P -D__FILENAME__=$@ -D__$*__=1 \
+vpath %.def.in ${mingwrt_srcdir}/msvcrt-xref
+$(addsuffix .def,$(all_msvcrt)): %.def: msvcrt.def.in
+       $(CC) -E -P -D__FILENAME__=$@ -D__DLLNAME__=$* \
          -D__MSVCRT_VERSION__=`$(call msvcrt_version_script,$*)` \
          -xc-header $< > $@
 
 # To accommodate the __USE_MINGW_ANSI_STDIO feature, as specified
 # in _mingw.h and stdio.h, while retaining a mechanism for accessing
-# the MSVCRT.DLL functions which it replaces, we augment our import 
+# the MSVCRT.DLL functions which it replaces, we augment our import
 # libraries with extra, alternatively named entry points, each of
 # which implements a vectored jump to the regular entry point for
 # the DLL implementation of its corresponding replaced function.
 #
-msvcrt_repl_prefix = __msvcrt
-msvcrt_repl_funcs = printf fprintf sprintf vprintf vfprintf vsprintf
+msvcrt_repl_prefix := __msvcrt
+msvcrt_repl_funcs := printf fprintf sprintf vprintf vfprintf vsprintf
+msvcrt_repl_funcs += free realloc
 
 # This is kludgey, but dlltool lacks the selectivity to do the job
 # well; (its --ext-prefix-alias option, which is what we would like
@@ -341,7 +336,16 @@ $(foreach name,coldname $(all_moldname),lib$(name).a): lib%.a: %.def
 # Microsoft DLLs, but which nevertheless are easily emulated.
 #
 $(foreach name,coldname $(all_moldname),lib$(name).a): $(addsuffix .$(OBJEXT), \
-  isascii iscsym iscsymf strcasecmp strncasecmp toascii wcscmpi)
+  isascii iscsym iscsymf toascii)
+
+# Selected versions of the oldname libraries also provide a
+# convenient vehicle for delivery of stubs, emulating functions
+# which appear in later MSVCRT versions, and which we also wish
+# to support in conjunction with earlier versions.
+#
+$(foreach name,moldname $(addprefix moldname,70 71),lib$(name).a) \
+$(foreach name,moldname $(addprefix moldname,70 71),lib$(name)d.a): \
+  strnlen.jmpstub.$(OBJEXT) wcsnlen.jmpstub.$(OBJEXT)
 
 coldname.def: %.def: ${mingwrt_srcdir}/moldname.def.in
        $(CC) -C -E -P -D__FILENAME__=$@ -D__CRTDLL__ -xc-header $< > $@
@@ -349,12 +353,13 @@ coldname.def: %.def: ${mingwrt_srcdir}/moldname.def.in
 $(addsuffix .def,$(all_moldname)): %.def: ${mingwrt_srcdir}/moldname.def.in
        $(CC) -C -E -P -D__FILENAME__=$@ -xc-header $< > $@
 
-all-mingwrt-libs install-mingwrt-libs: libmingw32.a libmingwex.a
+vpath %.sx ${mingwrt_srcdir}
+all-mingwrt-libs install-mingwrt-libs: libmingw32.a libmingwex.a libmemalign.a
 libmingw32.a: $(addsuffix .$(OBJEXT), CRTinit CRTglob setargv \
   CRTfmode cpu_features CRT_fp10 txtmode main dllmain gccmain crtst \
   tlsmcrt tlsmthread tlssup tlsthrd pseudo-reloc pseudo-reloc-list)
 
-libmingw32.a libmingwex.a libm.a libmingwthrd.a libgmon.a:
+libmingw32.a libmingwex.a libmemalign.a libm.a libmingwthrd.a libgmon.a:
        $(AR) $(ARFLAGS) $@ $?
 
 # Complex math objects, to be included in libmingwex.a
@@ -414,15 +419,16 @@ libmingwex.a: $(addsuffix .$(OBJEXT), cosf cosl acosf acosl sinf sinl asinf \
   nearbyint nearbyintf nearbyintl nextafterf nextafterl nexttoward nexttowardf \
   powf powl powi powif powil remainder remainderf remainderl remquo remquof \
   remquol rint rintf rintl round roundf roundl scalbn scalbnf scalbnl signbit \
-  signbitf signbitl sqrtf sqrtl tgamma tgammaf tgammal trunc truncf truncl)
+  signbitf signbitl sqrtf sqrtl tgamma tgammaf tgammal trunc truncf truncl \
+  x87cvt x87cvtf x87log x87log1p x87pow x87remquo)
 
 # Replacement I/O functions in libmingwex.a, providing better POSIX
 # compatibility than their Microsoft equivalents.
 #
 vpath %.c ${mingwrt_srcdir}/mingwex/stdio
-libmingwex.a: $(addsuffix .$(OBJEXT), btowc fprintf fseeko64 lseek64 \
-  pformat printf snprintf snwprintf sprintf vfprintf vfscanf vfwscanf vprintf \
-  vscanf vsnprintf vsnwprintf vsprintf vsscanf vswscanf vwscanf)
+libmingwex.a: $(addsuffix .$(OBJEXT), btowc fprintf fseeki64 ftelli64 \
+  fwrite ofmtctl pformat printf snprintf sprintf vfprintf vfscanf vfwscanf \
+  vprintf vscanf vsnprintf vsprintf vsscanf vswscanf vwscanf)
 
 # pformat.$(OBJEXT) needs an explicit build rule, since we need to
 # specify an additional header file path.
@@ -439,22 +445,46 @@ libmingwex.a: $(addsuffix fmt.$(OBJEXT),varo crto geto seto crtn getn setn)
 $(addsuffix fmt.$(OBJEXT),varo crto geto seto crtn getn setn): %.$(OBJEXT): ofmt.c
        $(CC) -c $(ALL_CFLAGS) -D__$*__ -fno-align-functions -o $@ $<
 
-# Some additional miscellaneous functions, in libmingwex.a
+# Functions comprising the MinGW aligned heap management API:
 #
-#libmingwex.a: $(addsuffix .$(OBJEXT), glob membarrier)
-libmingwex.a: $(addsuffix .$(OBJEXT), mingw-aligned-malloc mingw-fseek glob)
-libmingwex.a: $(addsuffix .$(OBJEXT), getopt basename dirname ftruncate usleep)
-libmingwex.a: $(addsuffix .$(OBJEXT), mkstemp mkdtemp cryptnam)
+LIBMINGWEX_MEMALIGN := memalign-lwm memalign-base aligned-malloc
+LIBMINGWEX_MEMALIGN += aligned-realloc memalign-realloc realloc free
 
-libmingwex.a: $(addsuffix .$(OBJEXT), tdelete tfind tsearch twalk)
+LIBMINGWEX_MEMALIGN_OBJECTS = $(addsuffix .$(OBJEXT),$(LIBMINGWEX_MEMALIGN))
 
-libmingwex.a: gettimeofday.$(OBJEXT)
-libmingwex.a: $(addsuffix .$(OBJEXT), dirent wdirent dlfcn)
+$(LIBMINGWEX_MEMALIGN_OBJECTS): %.$(OBJEXT): memalign.c
+       $(CC) -c $(CFLAGS) -D__mingw_$(subst -,_,$*)_case $< -o $@
 
-libmingwex.a: $(addsuffix .$(OBJEXT), fwide mbrtowc mbsinit wcrtomb wcstof \
-  wcstold wctob wmemchr wmemcmp wmemcpy wmemmove wmemset)
+libmingwex.a: $(LIBMINGWEX_MEMALIGN_OBJECTS)
+
+# Some additional miscellaneous functions, in libmingwex.a
+#
+libmingwex.a: $(addsuffix .$(OBJEXT), ftruncate getdelim gettimeofday)
+libmingwex.a: $(addsuffix .$(OBJEXT), glob getopt basename dirname nsleep)
+libmingwex.a: $(addsuffix .$(OBJEXT), clockapi clockres clockset clocktime)
+libmingwex.a: $(addsuffix .$(OBJEXT), insque remque tdelete tfind tsearch twalk)
+libmingwex.a: $(addsuffix .$(OBJEXT), dirent wdirent dlfcn strerror_r strtok_r)
+libmingwex.a: $(addsuffix .$(OBJEXT), mkstemp mkdtemp memcrypt cryptnam setenv)
+
+vpath %.s ${mingwrt_srcdir}/mingwex
+vpath %.sx ${mingwrt_srcdir}/mingwex
+libmingwex.a: $(addsuffix .$(OBJEXT), codeset mbrconv mbrscan mbrlen)
+libmingwex.a: $(addsuffix .$(OBJEXT), mbrtowc mbsrtowcs strnlen wcharmap)
+libmingwex.a: $(addsuffix .$(OBJEXT), wcrtomb wcsrtombs wcsnlen wcstod wcstof)
+libmingwex.a: $(addsuffix .$(OBJEXT), wcstofp wcstold wctob wctrans wctype)
+libmingwex.a: $(addsuffix .$(OBJEXT), wmemchr wmemcmp wmemcpy wmemmove wmemset)
+
+# The wcsnlen() function, enumerated above, is an adaptation of strnlen();
+# we need a specific rule to compile it, from shared source.
+#
+wcsnlen.$(OBJEXT): strnlen.sx
+       $(COMPILE.sx) -D_UNICODE $^ -o $@
 
-libmingwex.a: $(addsuffix .$(OBJEXT), wctrans wctype)
+# Similarly, the wcstod(), wcstof(), and wcstold() functions are
+# compiled from the common wcstofp.c source file.
+#
+$(addsuffix .$(OBJEXT), wcstod wcstof wcstold): %.$(OBJEXT): wcstofp.c
+       $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -D FUNCTION=$* -o $@ $<
 
 # For the math sources, we support the convention that a single
 # quux_generic.c source file will produce three objects: quux.o,
@@ -475,6 +505,34 @@ $(addsuffix .$(OBJEXT), % %f %l): %_generic.c
 $(addsuffix .$(OBJEXT), llround llroundf llroundl): %.$(OBJEXT): lround_generic.c
        $(CC) -c -D FUNCTION=$* $(CPPFLAGS) $(ALL_CFLAGS) -o $@ $<
 
+# Similarly, we may need to compile quux.o, quuxf.o, and quuxl.o
+# variants from a common quux_generic.sx assembly language file.
+#
+vpath %.sx ${mingwrt_srcdir}/mingwex/math
+$(addsuffix .$(OBJEXT), % %f %l): %_generic.sx
+       $(COMPILE.sx) -D_$*_source -o $*.$(OBJEXT) $<
+       $(COMPILE.sx) -D_$*f_source -o $*f.$(OBJEXT) $<
+       $(COMPILE.sx) -D_$*l_source -o $*l.$(OBJEXT) $<
+
+# Assembly language sources for all fmod() and remainder() object
+# code variants originate from one fmod_generic.sx.in template.
+#
+vpath fmod_generic.sx.in ${srcdir}/mingwex/math
+fmod_generic.sx remainder_generic.sx: %_generic.sx: fmod_generic.sx.in
+       sed '$($*_generic_subst)' $< > $@
+
+# fmod() variants, and remainder() variants, require differing
+# template substitutions.
+#
+fmod_generic_subst = s:%name%:$*:;s:%fprem%:fprem:
+remainder_generic_subst = s:%name%:$*:;s:%fprem%:fprem1:
+
+# Several generically implemented functions also require separate
+# assembly of associated generic back-end support routines.
+#
+x87%.$(OBJEXT): %_generic.sx
+       $(COMPILE.sx) -o $@ $<
+
 # Historically, MinGW.org's libm.a has been a dummy, delivering
 # nothing of value; FIXME: IMO, this sucks; it should deliver the
 # non-MSVCRT.DLL math functions, as noted above.
@@ -482,7 +540,7 @@ $(addsuffix .$(OBJEXT), llround llroundf llroundl): %.$(OBJEXT): lround_generic.
 all-mingwrt-libs install-mingwrt-libs: libm.a
 libm.a: libm_dummy.$(OBJEXT)
 libm_dummy.c: Makefile
-       echo "static int __mingw_libm_dummy;" > $@
+       echo "int __mingw_libm_dummy;" > $@
 
 # The mingwrt headers define a number of functions which are normally
 # expected to be compiled as inline code.  Each such function must also
@@ -490,7 +548,6 @@ libm_dummy.c: Makefile
 # entry points as stubs in libmingwex.a, via the following rules:
 #
 sinclude Makefile.stub
-vpath jmpstub.sx ${mingwrt_srcdir}/mingwex
 libstub_refnames = grep -lr '__$1.*FUNCTION *=' ${mingwrt_srcdir}
 jmpstub_prerequisites := $(shell $(call libstub_refnames,JMPSTUB)/include)
 libimpl_prerequisites := $(shell $(call libstub_refnames,LIBIMPL)/include)
@@ -511,11 +568,13 @@ jmpstub_awk_script = test -z "$1" || awk '\
     fmt = "\nlib%s.a: %s\n%s: jmpstub.sx\n\t$$(COMPILE.sx) %s -o $$@ $$^\n"; \
   } \
   /__JMPSTUB(__)? *[(].*FUNCTION/ { \
-    LIB = "mingwex"; \
     FUNCTION = gensub( ".*[ ,(:]FUNCTION *= *"symbol".*", "\\1", 1 ); \
+    LIB = match( $$0, ".*[ ,(:]LIB *= *"symbol, altlib ) ? altlib[1] : "mingwex"; \
     OBJNAME = gensub( "_*(.*)_*", "\\1", 1, FUNCTION )".jmpstub.$$(OBJEXT)"; \
     OBJNAME_CFLAGS = "-D FUNCTION="FUNCTION; \
-    if( match( $$0, ".*[ ,(:]REMAPPED *= *"symbol, alias ) ) \
+    if( match( $$0, ".*[ ,(:]DLLENTRY *= *"symbol, alias ) ) \
+      OBJNAME_CFLAGS = OBJNAME_CFLAGS" -D DLLENTRY="alias[1]; \
+    else if( match( $$0, ".*[ ,(:]REMAPPED *= *"symbol, alias ) ) \
       OBJNAME_CFLAGS = OBJNAME_CFLAGS" -D REMAPPED="alias[1]; \
     printf fmt, LIB, OBJNAME, OBJNAME, OBJNAME_CFLAGS; \
   } \
@@ -532,8 +591,8 @@ libimpl_awk_script = test -z "$1" || awk '\
     fmt = "\nlib%s.a: %s\n%s.libimpl: %s\n"; \
   } \
   /__LIBIMPL(__)? *[(].*FUNCTION/ { \
-    LIB = "mingwex"; \
     FUNCTION = gensub( ".*[ ,(:]FUNCTION *= *"symbol".*", "\\1", 1 ); \
+    LIB = match( $$0, ".*[ ,(:]LIB *= *"symbol, altlib ) ? altlib[1] : "mingwex"; \
     OBJNAME = gensub( "_*(.*)_*", "\\1", 1, FUNCTION )".libimpl.$$(OBJEXT)"; \
     printf fmt, LIB, OBJNAME, FUNCTION, FILENAME; \
   } \
@@ -555,7 +614,8 @@ libimpl_sed_script = sed \
   -e 's/__LIBIMPL.*ALIAS *= *$1[ ,)].*)/__attribute__((__alias__("$1")))/' \
   -e '/__CRT_ALIAS  *__LIBIMPL.*FUNCTION *= *$1[ ,)].*)/d'
 
-LIBIMPL_CFLAGS = $(CFLAGS) $(INCLUDES) -fno-align-functions
+LIBIMPL_CFLAGS = $(CFLAGS) $(INCLUDES) $(LIBIMPL_EXTRA_CFLAGS)
+LIBIMPL_EXTRA_CFLAGS = -fno-align-functions -Wno-deprecated-declarations
 
 # LIBIMPL dependencies are tracked using zero sized name.libimpl
 # files; the intermediate C files are generated as a side effect
@@ -603,6 +663,67 @@ all-mingwrt-libs install-mingwrt-libs: libgmon.a
 libgmon.a: $(addsuffix .$(OBJEXT), gmon mcount profil)
 
 
+# Optional DLL Generation Rules
+# -----------------------------
+#
+# The following rules are provided to accommodate optional delivery
+# of certain of the static libraries, generated as components of this
+# package, in the alternative form of DLLs, each with an accompanying
+# import library.  Each such DLL should be versioned, ideally with an
+# explicitly specified version number, but we provide this fall back
+# as a catch-all default for any which is not so specified; (all such
+# version specifications should be in the "current:revision:age" form,
+# conforming to the GNU-libtool convention).
+#
+DLLVERSION = "0:0:0"
+
+# DLLVERSION must be specified for each DLL file itself, and also for
+# the associated installation and distribution rules; the appropriate
+# dependencies may be specified by use of this function macro:
+#
+optional_dll = mingwrt-$1-optdist install-$1-optional-dll $2
+
+# Generally, we should prefer to have explicit version specifications,
+# relating individually to each DLL; these are specified in VERSION.m4,
+# and propagated here via configure time substitution.
+#
+$(call optional_dll,libmingwex,@MAP_LIBMINGWEX_A_DLLVERSION@)
+
+# For convenience, we implement the DLL build rule in the form of a
+# generic pattern rule, invoked in the form of a request to build any
+# version-agnostic import library; the versioned DLL is then built as
+# a side effect of building the import library.
+#
+# Note that, in addition to the obvious dependency on the originating
+# static library, we also make this depend on configure; this ensures
+# that DLL version changes, specified in VERSION.m4, are propagated.
+#
+# Further note that we use an alternatively named reference link to
+# the originating static library, as code source for the DLL, rather
+# than the original name; this is to work around a limitation of the
+# handling of --whole-archive, by GNU-ld, which suppresses creation
+# of an exports table, in the event that the same static library is
+# named among GCC's implicit default libraries, after reverting to
+# --no-whole-archive operation.
+#
+%.dll.a: %.a configure
+       $(RM) $@; $(LN_S) -f $< tmp$<
+       $(CC) $(call a2dll,tmp$<,$(call dllname,$*)) -L. -Wl,--out-implib=$@
+       $(RM) tmp$<
+
+dllname = $1-$(dllsuffix).dll $(LIBGCC_LINK_OPTION)
+a2dll = -shared -o $2 -Wl,--whole-archive $1 -Wl,--no-whole-archive
+dllsuffix = `echo $(DLLVERSION) | awk -F: '{printf "%d",$$1-$$3}'`
+
+all-optional-dlls: all-mingwrt-optional-dlls
+all-mingwrt-optional-dlls: libmingwex.dll.a
+
+# In most optional DLL build cases, we should avoid creating any
+# unnecessary dependency on (known to be broken) -shared-libgcc
+#
+libmingwex.dll.a: LIBGCC_LINK_OPTION = -static-libgcc
+
+
 # Installation Rules
 # ------------------
 #
@@ -619,7 +740,7 @@ bindir docdir includedir libdir mandir htmldir pdfdir:
        @test -z "$(strip ${DESTDIR})" || case $($@) in ${DESTDIR}?:*) \
          $(MAKE) --no-print-directory reject=$@ DESTDIR-UNSUPPORTED;; \
          esac
-       $(mkinstalldirs) $($@)
+       $(call mkinstalldirs,,$($@))
 
 # Note: we MUST use a recursive make invocation here, as the
 # "error" function within the accompanying diagnostics would be
@@ -644,11 +765,17 @@ MSG_DESTDIR_TRANSFORM = ${DESTDIR}$(shell echo $1 | sed 's/^.://')
 
 # Install everything.
 #
-install: install-mingwrt
+install: inst@DEFAULT_MAKECMDGOALS@
 install-stage-1-only: install-headers install-libdir-objects install-libs
 install-stage-1-and-2: install-stage-1-only install-bin
 install-gcc: install-stage-1-only
 
+install-strip: install-strip-mingwrt
+install-strip-%:
+       $(MAKE) --no-print-directory \
+         STRIP_DATA='cd ${libdir}; $(STRIP) --strip-unneeded $$1' \
+         STRIP_DLL='cd ${bindir}; $(STRIP) $$1' install-$*
+
 # Install licence files.
 #
 install-license: install-mingwrt-license
@@ -665,22 +792,29 @@ mingwrt-license-files: COPYING CYGWIN_LICENSE DISCLAIMER
 #
 install-mingwrt-license install-w32api-license: install-%: docdir %-files
 %-license-files:
-       $(mkinstalldirs) ${docdir}/$*/$(PACKAGE_VERSION)
-       $(INSTALL_DATA) $^ ${docdir}/$*/$(PACKAGE_VERSION)
+       $(call mkinstalldirs,,${docdir}/$*/$(PACKAGE_VERSION))
+       $(call INSTALL_DATA,$^,${docdir}/$*/$(PACKAGE_VERSION))
 
 # Install headers associated with the MinGW runtime libraries.
 #
 includedirs: mingwrt-includedirs
 install-headers install-mingwrt: install-mingwrt-headers
 
-${includedir}/sys: includedir
-mingwrt-includedirs: ${includedir}/sys
-       $(mkinstalldirs) $^
+mingwrt-includedirs: includedir $(eval mingwrt_include_subdirs=sys parts)
+       $(call mkinstalldirs,${includedir}/,$(mingwrt_include_subdirs))
+
+SUB_HEADERS_PRESENT = echo $1/include/$2/*.h | grep -v '[*]' > /dev/null
+INSTALL_SUB_HEADERS = $(call INSTALL_DATA,$1/include/$2/*.h,${includedir}/$2)
 
-install-mingwrt-headers: mingwrt-includedirs
-       $(INSTALL_DATA) ${mingwrt_srcdir}/include/*.h ${includedir}
-       $(INSTALL_DATA) ${mingwrt_srcdir}/include/sys/*.h ${includedir}/sys
-       $(INSTALL_DATA) ${mingwrt_srcdir}/profile/*.h ${includedir}
+install-mingwrt-headers: _mingw.h mingwrt-includedirs
+       $(call INSTALL_DATA,_mingw.h,${includedir})
+       $(call INSTALL_DATA,${mingwrt_srcdir}/include/*.h,${includedir})
+       for dir in $(mingwrt_include_subdirs); do \
+         if $(call SUB_HEADERS_PRESENT,${mingwrt_srcdir},$$dir); then \
+           $(call INSTALL_SUB_HEADERS,${mingwrt_srcdir},$$dir); \
+           fi; \
+         done
+       $(call INSTALL_DATA,${mingwrt_srcdir}/profile/*.h,${includedir})
 
 # Install libraries, and supporting free standing object files.
 #
@@ -692,56 +826,115 @@ install-mingwrt-libdir-objects: libdir $(call active_goals,install,crt-objects)
 
 install-crt-objects install-deprecated-crt-objects \
 install-mingwrt-libs install-deprecated-mingwrt-libs:
-       $(INSTALL_DATA) $^ ${libdir}
+       $(call INSTALL_DATA,$^,${libdir})
+       $(if $(STRIP_DATA),$(call STRIP_DATA,$^))
+
 
 # Install DLLs.
 #
 install-mingwrt: install-mingwrt-dll
-install-bin install-dll: install-mingwrt-dll 
+install-bin install-dll: install-mingwrt-dll
 install-mingwrt-bin install-w32api-bin: install-%-bin: install-%-dll
 install-mingwrt-dll install-w32api-dll: install-%-dll: bindir install-%-dll-files
 install-%-dll-files:
-       $(INSTALL_DATA) $^ ${bindir}
+       $(call INSTALL_DATA,$^,${bindir})
+       $(if $(STRIP_DLL),$(call STRIP_DLL,$^))
+
+install-optional-dlls: install-mingwrt-optional-dlls
+install-mingwrt-optional-dlls: install-libmingwex-optional-dll
+install-%-optional-dll: %.dll.a bindir libdir
+       $(call INSTALL_DATA,$<,${libdir})
+       $(call INSTALL_DATA,$(call dllname,$*),${bindir})
+       $(if $(STRIP_DLL),$(call STRIP_DLL,$(call dllname,$*)))
+       $(if $(STRIP_DATA),$(call STRIP_DATA,$<))
+
 
 # Install manpages.
 #
-install-man install-manpages: install-mingwrt-manpages
-format_manpage = sed "s/%PAGEREF%/`echo $1 | tr a-z A-Z` $2/"
-
 vpath %.man ${mingwrt_srcdir}/man
-basename.$(man3ext) dirname.$(man3ext): %.$(man3ext): dirname.man
-       $(call format_manpage,$*,$(man3ext)) $< > $@
+manpages = $(basename $(notdir $(wildcard $1/man/*.$2.man)))
+mancopy = $(call manpage_ref,$1,$2.man)$(eval $1: %: %.$0-recursive)
+manpage_ref = $(eval $1: export reference_manpage = $2)
 
-mingwrt-man$(man3ext): basename.$(man3ext) dirname.$(man3ext)
+install-man install-manpages: install-mingwrt-manpages
+mingwrt-man$(man3ext): $(call manpages,${mingwrt_srcdir},$(man3ext))
+install-mingwrt-manpages: mandir mingwrt-man$(man3ext)
 
-install-mingwrt-manpages: mandir mingwrt-man3
 mingwrt-man%:
-       $(mkinstalldirs) ${man$*dir}
-       $(INSTALL_DATA) $^ ${man$*dir}
+       $(call mkinstalldirs,,${man$*dir})
+       $(call INSTALL_DATA,$^,${man$*dir})
        $(RM) $^
 
+%: %.man
+       $(call format_manpage,$(basename $*),$(suffix $*),$<) $< > $@
+
+format_manpage = sed \
+  -e "s/%PAGEREF%/`echo $1 | tr a-z A-Z` $(2:.%=%) `date -r $3 +%d-%b-%Y`/"
+
+manpage_copy = $(eval $1$3: $2.$3)$(call mancopy,$2.$3,$4)
+$(call manpage_copy,mingwrt-man,basename,$(man3ext),dirname.$(man3ext))
+$(call manpage_copy,mingwrt-man,getdelim,$(man3ext),getline.$(man3ext))
+
+%.mancopy-recursive:
+       $(MAKE) --no-print-directory $*.mancopy
+
+%.mancopy: $(reference_manpage)
+       $(call format_manpage,$(basename $*),$(suffix $*),$<) $< > $*
+
+
+# Undo Installation
+# -----------------
+#
+uninstall: uninstall-mingwrt
+uninstall-bin uninstall-dll uninstall-mingwrt: uninstall-mingwrt-dll
+uninstall-optional-dlls uninstall-mingwrt: uninstall-mingwrt-optional-dlls
+uninstall-mingwrt: uninstall-mingwrt-headers uninstall-mingwrt-libdir-libs
+uninstall-mingwrt: uninstall-mingwrt-libdir-objects
+
+REMOVE_HEADERS = cd $1 && $(RM) $(notdir $(wildcard $2))
+
+uninstall-mingwrt-headers:
+       $(call REMOVE_HEADERS,${includedir},${mingwrt_srcdir}/include/*.h)
+       for dir in $(mingwrt_include_subdirs); do \
+         files=`cd ${mingwrt_srcdir}/include/$$dir && echo *.h`; \
+         (cd ${includedir}/$$dir && $(RM) $$files); \
+         done
+       $(call REMOVE_HEADERS,${includedir},${mingwrt_srcdir}/profile/*.h)
+
+uninstall-mingwrt-dll uninstall-mingwrt-optional-dlls \
+uninstall-mingwrt-libdir-objects uninstall-mingwrt-libdir-libs: un%:
+       $(MAKE) --no-print-directory mkinstalldirs= \
+         INSTALL_DATA='cd $$2 && $(RM) $$1' $*
+
+
+# Test Suite
+# ----------
+#
+.PHONY: check-recursive
+check test tests: check-recursive
+check-recursive:
+       $(MAKE) -C tests $@
+
 
 # Distribution
 # ------------
 #
 .PHONY: dist
-dist: devdist dlldist licdist mandist srcdist
+dist: devdist dlldist licdist mandist optdist srcdist
        $(RM) -r dist/mingwrt dist/w32api
 
 mingwrt-dist-staged w32api-dist-staged: %-dist-staged:
        $(RM) -r dist/$*
-       $(MAKE) --no-print-directory prefix=`pwd`/dist/$* install-$*
+       $(MAKE) --no-print-directory prefix=`pwd`/dist/$* install-strip-$*
 
 devdist: mingwrt-devdist
 mingwrt_devdist_objects = dist/mingwrt/lib/*.$(OBJEXT)
 mingwrt-devdist w32api-devdist: %-devdist: %-dist-staged
-       $(STRIP) -g $($*_devdist_objects) dist/$*/lib/*.a
        cd dist/$* && tar chf - --hard-dereference include lib | \
          xz -c > ../$*-$(PACKAGE_RELEASE_TAG)-dev.tar.xz
 
 dlldist: mingwrt-dlldist
 mingwrt-dlldist: %-dlldist: %-dist-staged
-       $(STRIP) dist/$*/bin/*.dll
        cd dist/$* && tar chf - --hard-dereference bin | \
          xz -c > ../$*-$(PACKAGE_RELEASE_TAG)-dll.tar.xz
 
@@ -761,6 +954,18 @@ mingwrt-mandist: %-mandist:
          xz -c > ../dist/$*-$(PACKAGE_RELEASE_TAG)-man.tar.xz
        $(RM) -r tmp
 
+optdist: mingwrt-optdist
+mingwrt-optdist: mingwrt-libmingwex-optdist
+
+mingwrt-%-optdist:
+       $(RM) -r tmp
+       $(MAKE) --no-print-directory prefix=`pwd`/tmp install-strip-$*-optional-dll
+       cd tmp && tar chf - --hard-dereference bin | \
+         xz -c > ../dist/$*-$(PACKAGE_RELEASE_TAG)-dll-$(dllsuffix).tar.xz
+       cd tmp && tar chf - --hard-dereference lib | \
+         xz -c > ../dist/$*-$(PACKAGE_RELEASE_TAG)-dev.tar.xz
+       $(RM) -r tmp
+
 srcdist: mingwrt-srcdist
 mingwrt-srcdist: mingwrt-srcdist-dir mingwrt-srcdist-files
        cd dist && tar chf - $(PACKAGE_TARNAME)-$(PACKAGE_VERSION) | \
@@ -769,19 +974,27 @@ mingwrt-srcdist: mingwrt-srcdist-dir mingwrt-srcdist-files
 
 mingwrt-srcdist-dir:
        $(RM) -r dist/$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)
-       $(mkinstalldirs) dist/$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)
+       $(call mkinstalldirs,,dist/$(PACKAGE_TARNAME)-$(PACKAGE_VERSION))
+
+mingwrt-srcdist-files: mingwrt-srcdist-common-files
+mingwrt-srcdist-files: mingwrt-srcdist-testsuite-files
+mingwrt-srcdist-files: mingwrt-srcdist-package-files
 
-mingwrt-srcdist-files:
+mingwrt-srcdist-package-files:
        (cd ${mingwrt_srcdir} && tar chf - --hard-dereference $(notdir $^)) | \
          (cd dist/$(PACKAGE_TARNAME)-$(PACKAGE_VERSION) && tar xf -)
 
-mingwrt-srcdist-files: $(wildcard ${mingwrt_srcdir}/*.[chs]) \
+mingwrt-srcdist-package-files: $(wildcard ${mingwrt_srcdir}/*.[chs]) \
   $(addprefix ${mingwrt_srcdir}/,ChangeLog CONTRIBUTORS DISCLAIMER README) \
   $(wildcard ${mingwrt_srcdir}/*.def.in) $(wildcard ${mingwrt_srcdir}/config*) \
-  $(addprefix ${mingwrt_srcdir}/,aclocal.m4 install-sh Makefile.in TODO) \
-  $(addprefix ${mingwrt_srcdir}/,include man mingwex profile) \
-  $(addprefix ${mingwrt_srcdir}/,crtdll.def) \
-  $(wildcard ${mingwrt_srcdir}/*.txt)
+  $(addprefix ${mingwrt_srcdir}/,include man mingwex msvcrt-xref profile) \
+  $(addprefix ${mingwrt_srcdir}/,TODO Makefile.in crtdll.def) \
+  $(wildcard $(addprefix ${mingwrt_srcdir}/,*.sx *.txt))
+
+mingwrt-srcdist-testsuite-files: $(wildcard ${mingwrt_srcdir}/tests/*.at)
+mingwrt-srcdist-testsuite-files: $(wildcard ${mingwrt_srcdir}/tests/*.in)
+       (cd ${mingwrt_srcdir} && tar chf - $(addprefix tests/,$(notdir $^))) | \
+         (cd dist/$(PACKAGE_TARNAME)-$(PACKAGE_VERSION) && tar xf -)
 
 install-html install-pdf: install-%: %dir mingwrt-man$(man3ext)
        $(MAKE) --no-print-directory install-$*-files
@@ -794,7 +1007,7 @@ install-html-files install-pdf-files: install-%-files: \
        chmod 644 ${htmldir}/$(notdir $@)
 
 %.$(man3ext).pdf: %.$(man3ext)
-       man -t $< | ps2pdf - > ${pdfdir}/$(notdir $@)
+       man -t $(dir $<)$< | ps2pdf - > ${pdfdir}/$(notdir $@)
        chmod 644 ${pdfdir}/$(notdir $@)
 
 html-docdist pdf-docdist: %-docdist:
@@ -816,7 +1029,7 @@ mostlyclean-local:
        $(RM) *.d *.$(OBJEXT) Makefile.stub *.libimpl
 
 distclean-local: clean-local
-       $(RM) config.log config.status libm_dummy.c
+       $(RM) config.log config.status libm_dummy.c _mingw.h w32api.h
 
 maintainer-clean-warning:
        $(warning $(MAKE) $(@:%-warning=%))