diff mbox series

FAT library support for libatomic, libgfortran, libgomp, libstdc++

Message ID CAGWvny=z4Fcxr6fVivDw2Gw+uJx9i5sy5_WuopCO-3fiMPCWzQ@mail.gmail.com
State New
Headers show
Series FAT library support for libatomic, libgfortran, libgomp, libstdc++ | expand

Commit Message

David Edelsohn June 2, 2020, 6:57 p.m. UTC
[I'll start by repeating what I wrote about a similar libgcc change to
provide background and context.]

When AIX added 64 bit support, it implemented what Apple MacOS Darwin
calls "FAT" libraries for its equivalent functionality -- both 32 bit
and 64 bit objects (or shared objects) are co-located in the same
archive.  GCC on AIX historically has followed the GCC multilib
directory hierarchy approach with separate directories and archives
for each multilib.

We now are working to support GCC on AIX in 64 bit mode.  To retain
the directory hierarchy, it is beneficial to shift (or at least
initially augment) the GCC multilib mechanism with AIX-style "FAT"
libraries.

It is beneficial for the "FAT" libraries to be created consistently
for GCC in both 32 bit mode and 64 bit mode.  When all of the
libraries are converted, the multilib rules will look for 32 bit and
64 bit multilibs in the top-level library.  All target multilibs need
to be enabled at the same time, but the build can start the creation
of the "FAT" libraries without utilizing them.

The goal is to place both 32 bit and 64 bit objects and shared objects
in archives at the top-level, not multilib subdirectories.  The
multilibs are built in subdirectories, but must be combined during the
last parts of the target library build process.  Because of the way
that GCC bootstrap works, the libraries must be combined during the
multiple stages of GCC bootstrap, not solely when installed in the
final destination, so the libraries have to be correct at the end of
each target library build stage, not solely an install recipe.

After trying various options, the best solution seems to be the
inclusion of target-specific Makefile fragments. Directly adding the
rules to the Makefiles conflicts with Automake conditionals syntax.
And Makefile fragments are easily extendible to other targets, such as
Darwin. It avoids regenerating Makefile.in or configure for each
change.

The rhythm of the fragment is the same for each library, but each
library is slightly different: package name versus directory name,
sub-directory, location of version info. I didn't see the benefit of
trying to rationalize all of the GCC target libraries as part of this
effort.

One global issue: I copied empty.mk into each library because Make
needs to include something by default. Alternatively, I can move
empty.mk to the top-level of the source tree and include a common copy
everywhere.

Bootstrapped on powerpc-ibm-aix7.2.0.0 and powerpc64le-unknown-gnu-linux.

Is this okay with each maintainer for the respective target libraries?

Thanks, David

libgomp/
        * Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
        * Makefile.in: Regenerate
        * configure.ac (tmake_file): Substitute.
        * configure: Regenerate.
        * configure.tgt (powerpc-ibm-aix*): Define tmake_file.
        * config/t-aix: New file.
        * empty.mk: New file.

libstdc++-v3/
        * Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
        * Makefile.in: Regenerate.
        * configure.ac (tmake_file): Substitute.
        * configure: Regenerate.
        * configure.host (aix*): Define tmake_file.
        * config/os/aix/t-aix: New file.
        * empty.mk: New file.

libatomic/
        * Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
        * Makefile.in: Regenerate.
        * configure.ac (tmake_file): Substitute.
        * configure: Regenerate.
        * configure.tgt (powerpc-ibm-aix*): Define tmake_file.
        * config/t-aix: New file.
        * empty.mk: New file.

libgfortran/
        * Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
        * Makefile.in: Regenerate.
        * configure.ac (tmake_file): Substitute.
        * configure: Regenerate.
        * configure.host: Add system configury stanza. Define tmake_file.
        * config/t-aix: New file.
        * empty.mk: New file.
From cf96afed42fcda9debb1351e86b511316ee4d781 Mon Sep 17 00:00:00 2001
From: David Edelsohn <dje.gcc@gmail.com>
Date: Fri, 15 May 2020 17:46:08 -0400
Subject: [PATCH] FAT target library support

libgomp/
	* Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
	* Makefile.in: Regenerate
	* configure.ac (tmake_file): Substitute.
	* configure: Regenerate.
	* configure.tgt (powerpc-ibm-aix*): Define tmake_file.
	* config/t-aix: New file.
	* empty.mk: New file.

libstdc++-v3/
	* Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
	* Makefile.in: Regenerate.
	* configure.ac (tmake_file): Substitute.
	* configure: Regenerate.
	* configure.host (aix*): Define tmake_file.
	* config/os/aix/t-aix: New file.
	* empty.mk: New file.

libatomic/
	* Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
	* Makefile.in: Regenerate.
	* configure.ac (tmake_file): Substitute.
	* configure: Regenerate.
	* configure.tgt (powerpc-ibm-aix*): Define tmake_file.
	* config/t-aix: New file.
	* empty.mk: New file.

libgfortran/
	* Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
	* Makefile.in: Regenerate.
	* configure.ac (tmake_file): Substitute.
	* configure: Regenerate.
	* configure.host: Add system configury stanza. Define tmake_file.
	* config/t-aix: New file.
	* empty.mk: New file.
---
 libatomic/Makefile.am              |  2 +
 libatomic/Makefile.in              |  3 +
 libatomic/config/t-aix             | 10 ++++
 libatomic/configure                | 18 +++++-
 libatomic/configure.ac             | 13 +++++
 libatomic/configure.tgt            |  6 ++
 libatomic/empty.mk                 |  2 +
 libgfortran/Makefile.am            |  2 +
 libgfortran/Makefile.in            |  3 +
 libgfortran/config/t-aix           | 10 ++++
 libgfortran/configure              | 17 +++++-
 libgfortran/configure.ac           | 12 ++++
 libgfortran/configure.host         | 18 ++++++
 libgfortran/empty.mk               |  2 +
 libgomp/Makefile.am                |  2 +
 libgomp/Makefile.in                |  9 ++-
 libgomp/config/t-aix               |  9 +++
 libgomp/configure                  | 18 +++++-
 libgomp/configure.ac               | 12 ++++
 libgomp/configure.tgt              |  5 ++
 libgomp/empty.mk                   |  2 +
 libstdc++-v3/Makefile.am           |  2 +
 libstdc++-v3/Makefile.in           |  3 +
 libstdc++-v3/config/os/aix/t-aix   |  9 +++
 libstdc++-v3/configure             | 30 +++++++---
 libstdc++-v3/configure.ac          | 11 ++++
 libstdc++-v3/configure.host        | 16 ++----
 libstdc++-v3/empty.mk              |  2 +
 35 files changed, 409 insertions(+), 75 deletions(-)
 create mode 100644 libatomic/config/t-aix
 create mode 100644 libatomic/empty.mk
 create mode 100644 libgfortran/config/t-aix
 create mode 100644 libgfortran/empty.mk
 create mode 100644 libgomp/config/t-aix
 create mode 100644 libgomp/empty.mk
 create mode 100644 libstdc++-v3/config/os/aix/t-aix
 create mode 100644 libstdc++-v3/empty.mk

Comments

Thomas Koenig June 3, 2020, 7:34 a.m. UTC | #1
Hi David,

> After trying various options, the best solution seems to be the
> inclusion of target-specific Makefile fragments. Directly adding the
> rules to the Makefiles conflicts with Automake conditionals syntax.
> And Makefile fragments are easily extendible to other targets, such as
> Darwin. It avoids regenerating Makefile.in or configure for each
> change.

So, at the moment, this is a no-op for everything but AIX, but some
other architectures might want to make use of it.

Looks like a good approach to me, with just one request: Could you add a
comment to Makefile.am what the line

include $(srcdir)/empty.mk $(tmake_file)

does?

libfortran changes are OK.

Regards

	Thomas
Iain Sandoe June 3, 2020, 7:14 p.m. UTC | #2
Hi David,

thanks for working on this!

David Edelsohn <dje.gcc@gmail.com> wrote:

> [I'll start by repeating what I wrote about a similar libgcc change to
> provide background and context.]
>
> When AIX added 64 bit support, it implemented what Apple MacOS Darwin
> calls "FAT" libraries for its equivalent functionality -- both 32 bit
> and 64 bit objects (or shared objects) are co-located in the same
> archive.  GCC on AIX historically has followed the GCC multilib
> directory hierarchy approach with separate directories and archives
> for each multilib.

End-user builds of GCC on Darwin also currently follow the “GCC multilib”
pattern;  However when and where GCC libraries were installed by Apple
they are already FAT versions (built outside the GCC build system).

… which fortuitously means that a FAT GCC library set is compatible with
the existing system implementations.

Of course that’s an initial reaction - and I/We will need to discuss with the
‘downstreams’ (macports, fink, homebrew) as to whether a switch needs
some transition - or would cause problems.

Given we anticipate a confiuration flag to disable this mode, it seems we
can cover most reasonable concerns.

> libstdc++-v3/
>        * Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
>        * Makefile.in: Regenerate.
>        * configure.ac (tmake_file): Substitute.
>        * configure: Regenerate.
>        * configure.host (aix*): Define tmake_file.
>        * config/os/aix/t-aix: New file.
>        * empty.mk: New file.

As a “proof of principle, quick hack” I used the following fragment for  
libstdc++
on Darwin; this means that the same fragment would work for X86 and PPC
- and (in principle) would work for as many sub-archs as we elected to build.

My only concern in the short-term is about dependencies; is it defined that
the MULTIBUILDTOP case cannot be active until all the deps are built?

(the libgcc_s case for Darwin which is already FAT is more complex but does
  have rules for the components to be built first).

I haven’t tried to implement the FAT CRTs so far - but I suspect that those  
are
going to use simple linear rules.

thanks
Iain

====

ifeq ($(MULTIBUILDTOP),)
MAJOR=$(firstword $(subst :, ,$(libtool_VERSION)))
OTHER=$(shell for d in $(MULTIDIRS); do echo  
"../$$d/$(PACKAGE)-v3/src/.libs/$(PACKAGE).$(MAJOR).dylib "; done)
all-local:
	lipo -create -output src/.libs/$(PACKAGE).$(MAJOR).f.dylib src/.libs/$(PACKAGE).$(MAJOR).dylib $(OTHER)
	mv src/.libs/$(PACKAGE).$(MAJOR).f.dylib src/.libs/$(PACKAGE).$(MAJOR).dylib
endif
David Edelsohn June 3, 2020, 7:49 p.m. UTC | #3
On Wed, Jun 3, 2020 at 3:14 PM Iain Sandoe <idsandoe@googlemail.com> wrote:
>
> Hi David,
>
> thanks for working on this!
>
> David Edelsohn <dje.gcc@gmail.com> wrote:
>
> > [I'll start by repeating what I wrote about a similar libgcc change to
> > provide background and context.]
> >
> > When AIX added 64 bit support, it implemented what Apple MacOS Darwin
> > calls "FAT" libraries for its equivalent functionality -- both 32 bit
> > and 64 bit objects (or shared objects) are co-located in the same
> > archive.  GCC on AIX historically has followed the GCC multilib
> > directory hierarchy approach with separate directories and archives
> > for each multilib.
>
> End-user builds of GCC on Darwin also currently follow the “GCC multilib”
> pattern;  However when and where GCC libraries were installed by Apple
> they are already FAT versions (built outside the GCC build system).
>
> … which fortuitously means that a FAT GCC library set is compatible with
> the existing system implementations.
>
> Of course that’s an initial reaction - and I/We will need to discuss with the
> ‘downstreams’ (macports, fink, homebrew) as to whether a switch needs
> some transition - or would cause problems.
>
> Given we anticipate a confiuration flag to disable this mode, it seems we
> can cover most reasonable concerns.
>
> > libstdc++-v3/
> >        * Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
> >        * Makefile.in: Regenerate.
> >        * configure.ac (tmake_file): Substitute.
> >        * configure: Regenerate.
> >        * configure.host (aix*): Define tmake_file.
> >        * config/os/aix/t-aix: New file.
> >        * empty.mk: New file.
>
> As a “proof of principle, quick hack” I used the following fragment for
> libstdc++
> on Darwin; this means that the same fragment would work for X86 and PPC
> - and (in principle) would work for as many sub-archs as we elected to build.
>
> My only concern in the short-term is about dependencies; is it defined that
> the MULTIBUILDTOP case cannot be active until all the deps are built?
>
> (the libgcc_s case for Darwin which is already FAT is more complex but does
>   have rules for the components to be built first).

Hi, Ian

Thanks for trying this out and the feedback.

On AIX I can start building the "FAT" libraries without actually
relying upon them for more than the "native" objects.  So I slowly can
create 32/64 bit compatible libraries and then enable the multilib
configuration bits at the end to instruct GCC to look at the same
directory level for both 32 bit and 64 bit objects.  I don't know if
that is viable for Darwin.

And on AIX I cannot transition for some libraries and not others.  In
other words, I can't switch C++ and Fortran, but not Objective-C and
GCCGo.

Thanks, David
Iain Sandoe June 3, 2020, 7:55 p.m. UTC | #4
David Edelsohn <dje.gcc@gmail.com> wrote:

> On Wed, Jun 3, 2020 at 3:14 PM Iain Sandoe <idsandoe@googlemail.com> wrote:

>>> libstdc++-v3/
>>>       * Makefile.am (tmake_file): Build and install AIX-style FAT libraries.
>>>       * Makefile.in: Regenerate.
>>>       * configure.ac (tmake_file): Substitute.
>>>       * configure: Regenerate.
>>>       * configure.host (aix*): Define tmake_file.
>>>       * config/os/aix/t-aix: New file.
>>>       * empty.mk: New file.
>>
>> As a “proof of principle, quick hack” I used the following fragment for
>> libstdc++
>> on Darwin; this means that the same fragment would work for X86 and PPC
>> - and (in principle) would work for as many sub-archs as we elected to  
>> build.
>>
>> My only concern in the short-term is about dependencies; is it defined  
>> that
>> the MULTIBUILDTOP case cannot be active until all the deps are built?
>>
>> (the libgcc_s case for Darwin which is already FAT is more complex but  
>> does
>>  have rules for the components to be built first).
>

> On AIX I can start building the "FAT" libraries without actually
> relying upon them for more than the "native" objects.  So I slowly can
> create 32/64 bit compatible libraries and then enable the multilib
> configuration bits at the end to instruct GCC to look at the same
> directory level for both 32 bit and 64 bit objects.  I don't know if
> that is viable for Darwin.

probably, since the linker is happy to consume either - so long as the
search paths are there for the multi-lib style ld64 will use the first lib
it finds with a viable slice.

> And on AIX I cannot transition for some libraries and not others.  In
> other words, I can't switch C++ and Fortran, but not Objective-C and
> GCCGo.

That would seem unwise for Darwin too - even if it would work - it would
create confusion.
Iain
diff mbox series

Patch

diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am
index 133fbbca77e..9dd1db73589 100644
--- a/libatomic/Makefile.am
+++ b/libatomic/Makefile.am
@@ -153,4 +153,6 @@  libatomic_convenience_la_LIBADD = $(libatomic_la_LIBADD)
 all-multi: $(libatomic_la_LIBADD)
 	$(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 include $(top_srcdir)/../multilib.am
diff --git a/libatomic/Makefile.in b/libatomic/Makefile.in
index a51807e95c9..febaf98b1fb 100644
--- a/libatomic/Makefile.in
+++ b/libatomic/Makefile.in
@@ -376,6 +376,7 @@  target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
+tmake_file = @tmake_file@
 toolexecdir = @toolexecdir@
 toolexeclibdir = @toolexeclibdir@
 top_build_prefix = @top_build_prefix@
@@ -862,6 +863,8 @@  vpath % $(strip $(search_path))
 all-multi: $(libatomic_la_LIBADD)
 	$(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 # GNU Make needs to see an explicit $(MAKE) variable in the command it
 # runs to enable its job server during parallel builds.  Hence the
 # comments below.
diff --git a/libatomic/config/t-aix b/libatomic/config/t-aix
new file mode 100644
index 00000000000..53c2d83242f
--- /dev/null
+++ b/libatomic/config/t-aix
@@ -0,0 +1,10 @@ 
+ifeq ($(MULTIBUILDTOP),)
+BITS=$(shell if test -z "`ar -X64 t .libs/$(PACKAGE).a`" ; then \
+    echo '64'; else echo '32'; fi)
+#MAJOR=$(firstword $(subst :, ,$(libtool_VERSION)))
+MAJOR=1
+all-local:
+	ar -X$(BITS) rc .libs/$(PACKAGE).a ../ppc$(BITS)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR)
+	ar -X$(BITS) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(BITS)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR)
+endif
+
diff --git a/libatomic/configure b/libatomic/configure
index b441636c85b..2acaffe441a 100755
--- a/libatomic/configure
+++ b/libatomic/configure
@@ -643,6 +643,7 @@  ARCH_AARCH64_LINUX_FALSE
 ARCH_AARCH64_LINUX_TRUE
 HAVE_IFUNC_FALSE
 HAVE_IFUNC_TRUE
+tmake_file
 SIZES
 XLDFLAGS
 XCFLAGS
@@ -11387,7 +11388,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11390 "configure"
+#line 11391 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11493,7 +11494,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11496 "configure"
+#line 11497 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15668,6 +15669,19 @@  XCFLAGS="$XCFLAGS $XPCFLAGS"
 
 
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+
+
+
  if test x$libat_cv_have_ifunc = xyes; then
   HAVE_IFUNC_TRUE=
   HAVE_IFUNC_FALSE='#'
diff --git a/libatomic/configure.ac b/libatomic/configure.ac
index 7ac8911c342..d74bd7c4c18 100644
--- a/libatomic/configure.ac
+++ b/libatomic/configure.ac
@@ -268,6 +268,19 @@  AC_SUBST(XLDFLAGS)
 AC_SUBST(LIBS)
 AC_SUBST(SIZES)
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+AC_SUBST(tmake_file)
+
+
 AM_CONDITIONAL(HAVE_IFUNC, test x$libat_cv_have_ifunc = xyes)
 AM_CONDITIONAL(ARCH_AARCH64_LINUX,
 	       [expr "$config_path" : ".* linux/aarch64 .*" > /dev/null])
diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt
index 5dd0926d207..efb3b1efb68 100644
--- a/libatomic/configure.tgt
+++ b/libatomic/configure.tgt
@@ -117,6 +117,7 @@  if test -d ${srcdir}/config/$ARCH ; then
   config_path="$ARCH"
 fi
 
+tmake_file=
 # Other system configury
 case "${target}" in
   aarch64*-*-linux*)
@@ -134,6 +135,11 @@  case "${target}" in
 	config_path="${config_path} s390 posix"
 	;;
 
+  powerpc*-*-aix*)
+	config_path="${config_path} posix"
+	tmake_file="t-aix"
+	;;
+
   *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu \
   | *-*-netbsd* | *-*-freebsd* | *-*-openbsd* | *-*-dragonfly* \
   | *-*-solaris2* | *-*-sysv4* | *-*-irix6* | *-*-osf* | *-*-hpux11* \
diff --git a/libatomic/empty.mk b/libatomic/empty.mk
new file mode 100644
index 00000000000..7b1d97b8b04
--- /dev/null
+++ b/libatomic/empty.mk
@@ -0,0 +1,2 @@ 
+# Empty.  This file exists to suppress errors in the parent Makefile
+# when a variable (e.g. LIB2ADD) is empty.
diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am
index a8a2191acc3..dd3c469765d 100644
--- a/libgfortran/Makefile.am
+++ b/libgfortran/Makefile.am
@@ -1236,4 +1236,6 @@  endif
 
 EXTRA_DIST = $(m4_files)
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 include $(top_srcdir)/../multilib.am
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index 312a682b45d..c1003e685b8 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -707,6 +707,7 @@  target_noncanonical = @target_noncanonical@
 target_os = @target_os@
 target_subdir = @target_subdir@
 target_vendor = @target_vendor@
+tmake_file = @tmake_file@
 toolexecdir = @toolexecdir@
 toolexeclibdir = @toolexeclibdir@
 top_build_prefix = @top_build_prefix@
@@ -7190,6 +7191,8 @@  fpu-target.inc: fpu-target.h $(srcdir)/libgfortran.h
 @MAINTAINER_MODE_TRUE@$(gfor_misc_specifics): m4/misc_specifics.m4 m4/head.m4
 @MAINTAINER_MODE_TRUE@	$(M4) -Dfile=$@ -I$(srcdir)/m4 misc_specifics.m4 > $@
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 # GNU Make needs to see an explicit $(MAKE) variable in the command it
 # runs to enable its job server during parallel builds.  Hence the
 # comments below.
diff --git a/libgfortran/config/t-aix b/libgfortran/config/t-aix
new file mode 100644
index 00000000000..7046aeeacc3
--- /dev/null
+++ b/libgfortran/config/t-aix
@@ -0,0 +1,10 @@ 
+ifeq ($(MULTIBUILDTOP),)
+BITS=$(shell if test -z "`ar -X64 t .libs/$(PACKAGE).a`" ; then \
+    echo '64'; else echo '32'; fi)
+#MAJOR=$(firstword $(subst :, ,$(libtool_VERSION)))
+MAJOR=5
+all-local:
+	ar -X$(BITS) rc .libs/$(PACKAGE).a ../ppc$(BITS)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR)
+	ar -X$(BITS) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(BITS)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR)
+endif
+
diff --git a/libgfortran/configure b/libgfortran/configure
index 195f8bbce4c..854656960c4 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -639,6 +639,7 @@  LIBOBJS
 get_gcc_base_ver
 HAVE_AVX128_FALSE
 HAVE_AVX128_TRUE
+tmake_file
 IEEE_FLAGS
 IEEE_SUPPORT
 IEEE_SUPPORT_FALSE
@@ -12723,7 +12724,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12726 "configure"
+#line 12727 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12829,7 +12830,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12832 "configure"
+#line 12833 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -26533,6 +26534,18 @@  fi
 IEEE_FLAGS="${ieee_flags}"
 
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+
+
 
 # Check for POSIX getpwuid_r
 #
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 711dc60ff78..4109d0fefae 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -601,6 +601,18 @@  AC_SUBST(IEEE_SUPPORT)
 IEEE_FLAGS="${ieee_flags}"
 AC_SUBST(IEEE_FLAGS)
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+AC_SUBST(tmake_file)
+
 
 # Check for POSIX getpwuid_r 
 #
diff --git a/libgfortran/configure.host b/libgfortran/configure.host
index 5824f253e2f..e9d92c9d34d 100644
--- a/libgfortran/configure.host
+++ b/libgfortran/configure.host
@@ -15,6 +15,9 @@ 
 # It sets the following shell variables:
 #
 #   fpu_host            FPU-specific code file, defaults to fpu-generic.
+#   tmake_file		A list of machine-description-specific
+#			makefile fragments.
+
 
 
 # DEFAULTS
@@ -57,3 +60,18 @@  case "${host_cpu}" in
   sh*)
     ieee_flags="-mieee" ;;
 esac
+
+tmake_file=
+# Other system configury
+case "${target}" in
+
+  *-*-aix*)
+	# Create AIX-style "FAT" libraries.
+	tmake_file="t-aix"
+	;;
+
+  *)
+	;;
+
+esac
+
diff --git a/libgfortran/empty.mk b/libgfortran/empty.mk
new file mode 100644
index 00000000000..7b1d97b8b04
--- /dev/null
+++ b/libgfortran/empty.mk
@@ -0,0 +1,2 @@ 
+# Empty.  This file exists to suppress errors in the parent Makefile
+# when a variable (e.g. LIB2ADD) is empty.
diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index b84156291e8..e9c2f226a31 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -141,4 +141,6 @@  stamp-build-info: libgomp.texi
 CLEANFILES = $(STAMP_GENINSRC) $(STAMP_BUILD_INFO)
 MAINTAINERCLEANFILES = $(srcdir)/libgomp.info
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 include $(top_srcdir)/../multilib.am
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index 5ff2ac14db9..e12b821653b 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -16,7 +16,7 @@ 
 
 # Plugins for offload execution, Makefile.am fragment.
 #
-# Copyright (C) 2014-2019 Free Software Foundation, Inc.
+# Copyright (C) 2014-2020 Free Software Foundation, Inc.
 #
 # Contributed by Mentor Embedded.
 #
@@ -530,6 +530,7 @@  target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
+tmake_file = @tmake_file@
 toolexecdir = @toolexecdir@
 toolexeclibdir = @toolexeclibdir@
 top_build_prefix = @top_build_prefix@
@@ -573,8 +574,8 @@  libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c \
 	affinity.c target.c splay-tree.c libgomp-plugin.c \
 	oacc-parallel.c oacc-host.c oacc-init.c oacc-mem.c \
 	oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
-	affinity-fmt.c teams.c allocator.c oacc-profiling.c oacc-target.c \
-	$(am__append_4)
+	affinity-fmt.c teams.c allocator.c oacc-profiling.c \
+	oacc-target.c $(am__append_4)
 
 # Nvidia PTX OpenACC plugin.
 @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION)
@@ -1438,6 +1439,8 @@  stamp-build-info: libgomp.texi
 	$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) -o libgomp.info $(srcdir)/libgomp.texi
 	@touch $@
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 # GNU Make needs to see an explicit $(MAKE) variable in the command it
 # runs to enable its job server during parallel builds.  Hence the
 # comments below.
diff --git a/libgomp/config/t-aix b/libgomp/config/t-aix
new file mode 100644
index 00000000000..5d0b7e0f9ae
--- /dev/null
+++ b/libgomp/config/t-aix
@@ -0,0 +1,9 @@ 
+ifeq ($(MULTIBUILDTOP),)
+BITS=$(shell if test -z "`ar -X64 t .libs/$(PACKAGE).a`" ; then \
+    echo '64'; else echo '32'; fi)
+MAJOR=$(firstword $(subst :, ,$(libtool_VERSION)))
+all-local:
+	ar -X$(BITS) rc .libs/$(PACKAGE).a ../ppc$(BITS)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR)
+	ar -X$(BITS) rc ../pthread/$(PACKAGE)/.libs/$(PACKAGE).a ../pthread/ppc$(BITS)/$(PACKAGE)/.libs/$(PACKAGE).so.$(MAJOR)
+endif
+
diff --git a/libgomp/configure b/libgomp/configure
index 9ffa66c18d9..fd65828136d 100755
--- a/libgomp/configure
+++ b/libgomp/configure
@@ -650,6 +650,7 @@  OMP_LOCK_SIZE
 USE_FORTRAN_FALSE
 USE_FORTRAN_TRUE
 link_gomp
+tmake_file
 XLDFLAGS
 XCFLAGS
 config_path
@@ -11432,7 +11433,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11435 "configure"
+#line 11436 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11538,7 +11539,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11541 "configure"
+#line 11542 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -16747,6 +16748,7 @@  fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CET support" >&5
 $as_echo_n "checking for CET support... " >&6; }
 
+# NB: Avoid nested save_CFLAGS and save_LDFLAGS.
 case "$host" in
   i[34567]86-*-linux* | x86_64-*-linux*)
     case "$enable_cet" in
@@ -16822,6 +16824,18 @@  FCFLAGS="$FCFLAGS $CET_FLAGS"
 
 
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+
+
 # Cleanup and exit.
 CFLAGS="$save_CFLAGS"
 cat >confcache <<\_ACEOF
diff --git a/libgomp/configure.ac b/libgomp/configure.ac
index ef5d293c31e..201d26fff7a 100644
--- a/libgomp/configure.ac
+++ b/libgomp/configure.ac
@@ -348,6 +348,18 @@  AC_SUBST(config_path)
 AC_SUBST(XCFLAGS)
 AC_SUBST(XLDFLAGS)
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+AC_SUBST(tmake_file)
+
 # Cleanup and exit.
 CFLAGS="$save_CFLAGS"
 AC_CACHE_SAVE
diff --git a/libgomp/configure.tgt b/libgomp/configure.tgt
index 4790a31e394..1863287fa0d 100644
--- a/libgomp/configure.tgt
+++ b/libgomp/configure.tgt
@@ -9,6 +9,8 @@ 
 #			config subdirectory of the source tree.
 #  XCFLAGS		Add extra compile flags to use.
 #  XLDFLAGS		Add extra link flags to use.
+#  tmake_file		A list of machine-description-specific
+#			makefile fragments.
 
 # Optimize TLS usage by avoiding the overhead of dynamic allocation.
 if test $gcc_cv_have_tls = yes ; then
@@ -30,6 +32,7 @@  if test $gcc_cv_have_tls = yes ; then
   esac
 fi
 
+tmake_file=
 # Since we require POSIX threads, assume a POSIX system by default.
 config_path="posix"
 
@@ -154,6 +157,8 @@  case "${target}" in
 	XLDFLAGS="${XLDFLAGS} -lpthread"
 	# AIX needs -frandom-seed for bootstrap compare.
 	XCFLAGS="${XCFLAGS} -frandom-seed=\$@"
+	# Create AIX-style "FAT" libraries.
+	tmake_file="t-aix"
 	;;
 
   nvptx*-*-*)
diff --git a/libgomp/empty.mk b/libgomp/empty.mk
new file mode 100644
index 00000000000..7b1d97b8b04
--- /dev/null
+++ b/libgomp/empty.mk
@@ -0,0 +1,2 @@ 
+# Empty.  This file exists to suppress errors in the parent Makefile
+# when a variable (e.g. LIB2ADD) is empty.
diff --git a/libstdc++-v3/Makefile.am b/libstdc++-v3/Makefile.am
index da021ec7074..58237a8aa6e 100644
--- a/libstdc++-v3/Makefile.am
+++ b/libstdc++-v3/Makefile.am
@@ -173,4 +173,6 @@  AM_MAKEFLAGS = \
 # Subdir rules rely on $(FLAGS_TO_PASS)
 FLAGS_TO_PASS = $(AM_MAKEFLAGS)
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 include $(top_srcdir)/../multilib.am
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index 8f11aaf2810..8df1eadcdd8 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -377,6 +377,7 @@  target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
 thread_header = @thread_header@
+tmake_file = @tmake_file@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
@@ -817,6 +818,8 @@  install-dvi:
 # automake-generated TAGS rule. Make a simple one here.
 TAGS: tags-recursive $(LISP)
 
+include $(srcdir)/empty.mk $(tmake_file)
+
 # GNU Make needs to see an explicit $(MAKE) variable in the command it
 # runs to enable its job server during parallel builds.  Hence the
 # comments below.
diff --git a/libstdc++-v3/config/os/aix/t-aix b/libstdc++-v3/config/os/aix/t-aix
new file mode 100644
index 00000000000..a588746dd99
--- /dev/null
+++ b/libstdc++-v3/config/os/aix/t-aix
@@ -0,0 +1,9 @@ 
+ifeq ($(MULTIBUILDTOP),)
+BITS=$(shell if test -z "`ar -X64 t src/.libs/$(PACKAGE).a`" ; then \
+    echo '64'; else echo '32'; fi)
+MAJOR=$(firstword $(subst :, ,$(libtool_VERSION)))
+all-local:
+	ar -X$(BITS) rc src/.libs/$(PACKAGE).a ../ppc$(BITS)/$(PACKAGE)-v3/src/.libs/$(PACKAGE).so.$(MAJOR)
+	ar -X$(BITS) rc ../pthread/$(PACKAGE)-v3/src/.libs/$(PACKAGE).a ../pthread/ppc$(BITS)/$(PACKAGE)-v3/src/.libs/$(PACKAGE).so.$(MAJOR)
+endif
+
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 4ef678e001e..dd54bd406a9 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -643,6 +643,7 @@  glibcxx_toolexecdir
 gxx_include_dir
 glibcxx_prefixdir
 EXTRA_CFLAGS
+tmake_file
 CPU_OPT_BITS_RANDOM
 CPU_OPT_EXT_RANDOM
 ERROR_CONSTANTS_SRCDIR
@@ -12059,7 +12060,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12062 "configure"
+#line 12063 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12165,7 +12166,7 @@  else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 12168 "configure"
+#line 12169 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15857,7 +15858,7 @@  $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
   # Fake what AC_TRY_COMPILE does.
 
     cat > conftest.$ac_ext << EOF
-#line 15860 "configure"
+#line 15861 "configure"
 int main()
 {
   typedef bool atomic_type;
@@ -15892,7 +15893,7 @@  $as_echo "$glibcxx_cv_atomic_bool" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15895 "configure"
+#line 15896 "configure"
 int main()
 {
   typedef short atomic_type;
@@ -15927,7 +15928,7 @@  $as_echo "$glibcxx_cv_atomic_short" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15930 "configure"
+#line 15931 "configure"
 int main()
 {
   // NB: _Atomic_word not necessarily int.
@@ -15963,7 +15964,7 @@  $as_echo "$glibcxx_cv_atomic_int" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 15966 "configure"
+#line 15967 "configure"
 int main()
 {
   typedef long long atomic_type;
@@ -16116,7 +16117,7 @@  $as_echo "mutex" >&6; }
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 16119 "configure"
+#line 16120 "configure"
 int main()
 {
   _Decimal32 d1;
@@ -16158,7 +16159,7 @@  ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
   # unnecessary for this test.
 
     cat > conftest.$ac_ext << EOF
-#line 16161 "configure"
+#line 16162 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -16192,7 +16193,7 @@  $as_echo "$enable_int128" >&6; }
     rm -f conftest*
 
     cat > conftest.$ac_ext << EOF
-#line 16195 "configure"
+#line 16196 "configure"
 template<typename T1, typename T2>
   struct same
   { typedef T2 type; };
@@ -77719,6 +77720,17 @@  CPU_OPT_BITS_RANDOM=config/${cpu_opt_bits_random}
 
 
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+
 
 # Add CET specific flags if Intel CET is enabled.
  # Check whether --enable-cet was given.
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index 699e55fd829..ffd0079613f 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -528,6 +528,17 @@  AC_SUBST(ERROR_CONSTANTS_SRCDIR)
 AC_SUBST(CPU_OPT_EXT_RANDOM)
 AC_SUBST(CPU_OPT_BITS_RANDOM)
 
+# Conditionalize the makefile for this target machine.
+tmake_file_=
+for f in ${tmake_file}
+do
+	if test -f ${srcdir}/config/$f
+	then
+		tmake_file_="${tmake_file_} \$(srcdir)/config/$f"
+	fi
+done
+tmake_file="${tmake_file_}"
+AC_SUBST(tmake_file)
 
 # Add CET specific flags if Intel CET is enabled.
 GCC_CET_FLAGS(CET_FLAGS)
diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
index 898db37d9a2..8d1b60804f3 100644
--- a/libstdc++-v3/configure.host
+++ b/libstdc++-v3/configure.host
@@ -70,6 +70,9 @@ 
 #                          additional symbols to export from the shared
 #                          library, when symbol versioning is in use
 #
+#   tmake_file		   A list of machine-description-specific
+#			   makefile fragments.
+#
 #
 # If the defaults will not work for your platform, you need only change the
 # variables that won't work, i.e., you do not need to explicitly set a
@@ -91,6 +94,7 @@  try_cpu=generic
 abi_baseline_subdir_switch=--print-multi-directory
 abi_tweaks_dir="cpu/generic"
 error_constants_dir="os/generic"
+tmake_file=
 
 # HOST-SPECIFIC OVERRIDES
 # Set any CPU-dependent bits.
@@ -206,17 +210,7 @@  case "${host_os}" in
     # Newer versions of AIX only support PowerPC architecture, so use
     # atomic instructions directly.
     os_include_dir="os/aix"
-    ;;
-  aix4.[3456789]*)
-    # We set os_include_dir to os/aix only on AIX 4.3 and newer, but
-    # os/aix/atomicity.h works on earlier versions of AIX 4.*, so we
-    # explicitly duplicate the directory for 4.[<3].
-    os_include_dir="os/aix"
-    atomicity_dir="os/aix"
-    ;;
-  aix4.*)
-    os_include_dir="os/generic"
-    atomicity_dir="os/aix"
+    tmake_file="os/aix/t-aix"
     ;;
   aix*)
     os_include_dir="os/generic"
diff --git a/libstdc++-v3/empty.mk b/libstdc++-v3/empty.mk
new file mode 100644
index 00000000000..7b1d97b8b04
--- /dev/null
+++ b/libstdc++-v3/empty.mk
@@ -0,0 +1,2 @@ 
+# Empty.  This file exists to suppress errors in the parent Makefile
+# when a variable (e.g. LIB2ADD) is empty.