From 407b42b1fbe562dff69820f7456dbb32a8a37d79 Mon Sep 17 00:00:00 2001
From: AIX-dev <postgres-ibm-aix@wwpdl.vnet.ibm.com>
Date: Tue, 16 Sep 2025 08:59:22 -0500
Subject: [PATCH] Changes to add support for AIX.

---
 Makefile                           |  2 -
 configure                          | 37 +++++++++++++++---
 configure.ac                       | 29 +++++++++++++-
 src/Makefile.shlib                 | 29 ++++++++++++++
 src/backend/Makefile               | 20 ++++++++++
 src/backend/port/aix/mkldexport.sh | 61 ++++++++++++++++++++++++++++++
 src/backend/utils/error/elog.c     |  2 +
 src/include/port/aix.h             |  4 ++
 src/include/storage/s_lock.h       | 48 +++--------------------
 src/makefiles/Makefile.aix         | 34 +++++++++++++++++
 src/port/strerror.c                |  2 +
 src/template/aix                   |  7 ++++
 12 files changed, 223 insertions(+), 52 deletions(-)
 create mode 100755 src/backend/port/aix/mkldexport.sh
 create mode 100644 src/include/port/aix.h
 create mode 100644 src/makefiles/Makefile.aix
 create mode 100644 src/template/aix

diff --git a/Makefile b/Makefile
index 8a2ec9396b6..9bc1a4ec17b 100644
--- a/Makefile
+++ b/Makefile
@@ -13,8 +13,6 @@
 
 # AIX make defaults to building *every* target of the first rule.  Start with
 # a single-target, empty rule to make the other targets non-default.
-# (We don't support AIX anymore, but if someone tries to build on AIX anyway,
-# at least they'll get the instructions to run 'configure' first.)
 all:
 
 all check install installdirs installcheck installcheck-parallel uninstall clean distclean maintainer-clean dist distcheck world check-world install-world installcheck-world:
diff --git a/configure b/configure
index 507a2437c33..67cad0f5581 100755
--- a/configure
+++ b/configure
@@ -3022,6 +3022,7 @@ else
 # --with-template not given
 
 case $host_os in
+  aix*) template=aix ;;
   cygwin*|msys*) template=cygwin ;;
   darwin*) template=darwin ;;
 dragonfly*) template=netbsd ;;
@@ -17204,13 +17205,37 @@ _ACEOF
 # wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8 would be too
 # much of a penalty for disk and memory space.
 
-MAX_ALIGNOF=$ac_cv_alignof_double
+echo "Checking for MAX ALIGN - $PORTNAME"
+if test "$PORTNAME" != "aix"; then
+    MAX_ALIGNOF=$ac_cv_alignof_double
 
-if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
-  as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
-fi
-if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF ; then
-  as_fn_error $? "alignment of 'int64_t' is greater than the alignment of 'double'" "$LINENO" 5
+    if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
+      as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
+    fi
+    if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $ac_cv_alignof_long_long_int -gt $MAX_ALIGNOF ; then
+      as_fn_error $? "alignment of 'long long int' is greater than the alignment of 'double'" "$LINENO" 5
+    fi
+else
+# The AIX 'power' alignment rules apply the natural alignment of the "first
+# member" if it is of a floating-point data type (or is an aggregate whose
+# recursively "first" member or element is such a type). The alignment
+# associated with these types for subsequent members use an alignment value
+# where the floating-point data type is considered to have 4-byte alignment.
+# More info
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99557
+#
+# The double is aligned to 4-bytes on AIX in aggregates. But to maintain
+# alignement across platforms the max alignment of long should be considered.
+      echo "MAX ALIGN ac_cv_alignof_long"
+    MAX_ALIGNOF=$ac_cv_alignof_long
+    if test $MAX_ALIGNOF -lt $ac_cv_alignof_double ; then
+      MAX_ALIGNOF=$ac_cv_alignof_double
+      echo "MAX ALIGN ac_cv_alignof_double"
+    fi
+    if test $MAX_ALIGNOF -lt $ac_cv_alignof_int64_t; then
+      MAX_ALIGNOF="$ac_cv_alignof_int64_t"
+      echo "MAX ALIGN ac_cv_alignof_int64_t"
+    fi
 fi
 
 cat >>confdefs.h <<_ACEOF
diff --git a/configure.ac b/configure.ac
index 5f4548adc5c..a25aedacef2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,6 +62,7 @@ PGAC_ARG_REQ(with, template, [NAME], [override operating system template],
 # --with-template not given
 
 case $host_os in
+  aix*) template=aix ;;
   cygwin*|msys*) template=cygwin ;;
   darwin*) template=darwin ;;
 dragonfly*) template=netbsd ;;
@@ -2021,7 +2022,33 @@ AC_CHECK_ALIGNOF(double)
 # wider than 64 bits, as allowing MAXIMUM_ALIGNOF to exceed 8 would be too
 # much of a penalty for disk and memory space.
 
-MAX_ALIGNOF=$ac_cv_alignof_double
+if test "$PORTNAME" != "aix"; then
+    MAX_ALIGNOF=$ac_cv_alignof_double
+
+    if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
+      as_fn_error $? "alignment of 'long' is greater than the alignment of 'double'" "$LINENO" 5
+    fi
+    if test $ac_cv_alignof_int64_t -gt $MAX_ALIGNOF; then
+      as_fn_error $? "alignment of 'long long int' is greater than the alignment of 'double'" "$LINENO" 5
+    fi
+else
+# The AIX 'power' alignment rules apply the natural alignment of the "first
+# member" if it is of a floating-point data type (or is an aggregate whose
+# recursively "first" member or element is such a type). The alignment
+# associated with these types for subsequent members use an alignment value
+# where the floating-point data type is considered to have 4-byte alignment.
+# More info
+# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99557
+# 
+# The double is aligned to 4-bytes on AIX in aggregates. But to maintain
+# alignement across platforms the max alignment of long should be considered.
+    MAX_ALIGNOF=$ac_cv_alignof_long
+    if test $MAX_ALIGNOF -lt $ac_cv_alignof_double ; then
+      MAX_ALIGNOF=$ac_cv_alignof_double
+    fi
+    if test $MAX_ALIGNOF -lt $ac_cv_alignof_int64_t ; then
+      MAX_ALIGNOF="$ac_cv_alignof_int64_t"
+    fi
 
 if test $ac_cv_alignof_long -gt $MAX_ALIGNOF ; then
   AC_MSG_ERROR([alignment of 'long' is greater than the alignment of 'double'])
diff --git a/src/backend/port/aix/mkldexport.sh b/src/backend/port/aix/mkldexport.sh
new file mode 100755
index 00000000000..adf3793e868
--- /dev/null
+++ b/src/backend/port/aix/mkldexport.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+#
+# mkldexport
+#      create an AIX exports file from an object file
+#
+# src/backend/port/aix/mkldexport.sh
+#
+# Usage:
+#      mkldexport objectfile [location]
+# where
+#      objectfile is the current location of the object file.
+#      location is the eventual (installed) location of the
+#              object file (if different from the current
+#              working directory).
+#
+# [This file comes from the Postgres 4.2 distribution. - ay 7/95]
+#
+# Header: /usr/local/devel/postgres/src/tools/mkldexport/RCS/mkldexport.sh,v 1.2 1994/03/13 04:59:12 aoki Exp
+#
+
+# setting this to nm -B might be better
+# ... due to changes in AIX 4.x ...
+# ... let us search in different directories - Gerhard Reithofer
+if [ -x /usr/ucb/nm ]
+then NM=/usr/ucb/nm
+elif [ -x /usr/bin/nm ]
+then NM=/usr/bin/nm
+elif [ -x /usr/ccs/bin/nm ]
+then NM=/usr/ccs/bin/nm
+elif [ -x /usr/usg/bin/nm ]
+then NM=/usr/usg/bin/nm
+else echo "Fatal error: cannot find `nm' ... please check your installation."
+     exit 1
+fi
+
+CMDNAME=`basename $0`
+if [ -z "$1" ]; then
+       echo "Usage: $CMDNAME object [location]"
+       exit 1
+fi
+OBJNAME=`basename $1`
+if [ "`basename $OBJNAME`" != "`basename $OBJNAME .o`" ]; then
+       OBJNAME=`basename $OBJNAME .o`.so
+fi
+if [ -z "$2" ]; then
+       echo '#!'
+else
+       if [ "$2" = "." ]; then
+               # for the base executable (AIX 4.2 and up)
+               echo '#! .'
+       else
+               echo '#!' $2
+       fi
+fi
+$NM -BCg $1 | \
+       egrep ' [TDB] ' | \
+       sed -e 's/.* //' | \
+       egrep -v '\$' | \
+       sed -e 's/^[.]//' | \
+       sort | \
+       uniq
diff --git a/src/include/port/aix.h b/src/include/port/aix.h
new file mode 100644
index 00000000000..7d08480c8c0
--- /dev/null
+++ b/src/include/port/aix.h
@@ -0,0 +1,4 @@
+/*
+ * src/include/port/aix.h
+ */
+
diff --git a/src/makefiles/Makefile.aix b/src/makefiles/Makefile.aix
new file mode 100644
index 00000000000..4c4de8b0be7
--- /dev/null
+++ b/src/makefiles/Makefile.aix
@@ -0,0 +1,34 @@
+# -blibpath:
+# The path to be inserted into the default path (Index 0 path) field of the
+# loader section. When this flag is presented, the -L paths will not be stored. 
+# AIX uses a stricter, more explicit approach. The runtime linker expects to
+# tell it exactly where to look using -blibpath.
+# -blibpath must contain ALL directories where we should look for libraries
+libpath := $(shell echo $(subst -L,:,$(filter -L/%,$(LDFLAGS))) | sed -e's/ //g'):/usr/lib:/lib
+
+# AIX uses a stricter, more explicit approach. The runtime linker expects 
+# to tell it exactly where to look using -blibpath.
+rpath = -Wl,-blibpath:'$(rpathdir)$(libpath)'
+
+# gcc needs to know it's building a shared lib, otherwise it'll not emit
+# correct code / link to the right support libraries
+ifeq ($(GCC), yes)
+LDFLAGS_SL += -shared
+endif
+
+# env var name to use in place of LD_LIBRARY_PATH
+ld_library_path_var = LIBPATH
+
+POSTGRES_IMP= postgres.imp
+
+ifdef PGXS
+BE_DLLLIBS= -Wl,-bI:$(pkglibdir)/$(POSTGRES_IMP)
+else
+BE_DLLLIBS= -Wl,-bI:$(top_builddir)/src/backend/$(POSTGRES_IMP)
+endif
+
+MKLDEXPORT_DIR=src/backend/port/aix
+MKLDEXPORT=$(top_srcdir)/$(MKLDEXPORT_DIR)/mkldexport.sh
+
+%$(DLSUFFIX): %.o
+	$(CC) $(CFLAGS) $*.o $(LDFLAGS) $(LDFLAGS_SL) -o $@ $(BE_DLLLIBS)
diff --git a/src/template/aix b/src/template/aix
new file mode 100644
index 00000000000..bfc193348f4
--- /dev/null
+++ b/src/template/aix
@@ -0,0 +1,7 @@
+# This file is referred for specific flags wrt to AIX build process like
+# cflags.
+# src/template/aix
+
+# Extra CFLAGS for code that will go into a shared library
+# With optimization, the MemSet() and MemSetAlign() perform better.
+CFLAGS_SL=" -O2 "
-- 
2.41.0
