From 103760b2d065081447efd27f4ecc20c5dbb7abcf Mon Sep 17 00:00:00 2001 From: Sriram RK Date: Fri, 6 Dec 2024 10:36:29 -0600 Subject: [PATCH] AIX support --- Makefile | 2 - configure | 35 +++++++++-- doc/src/sgml/dfunc.sgml | 19 ++++++ 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 | 10 ++-- src/makefiles/Makefile.aix | 39 +++++++++++++ src/port/strerror.c | 2 + src/template/aix | 7 +++ src/test/regress/expected/jsonb_jsonpath.out | 6 +- << IGNORE: known issue resolved in af21152268317323480 src/test/regress/sql/jsonb_jsonpath.sql | 4 ++ << IGNORE: known issue resolved in af21152268317323480 14 files changed, 225 insertions(+), 15 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 8a2ec9396b..9bc1a4ec17 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 3a577e463b..0f400c4e84 100755 --- a/configure +++ b/configure @@ -2985,6 +2985,7 @@ else # --with-template not given case $host_os in + aix*) template=aix ;; cygwin*|msys*) template=cygwin ;; darwin*) template=darwin ;; dragonfly*) template=netbsd ;; @@ -16769,13 +16770,35 @@ _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 +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 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 +# AIX alignment info: We assume long's alignment is at least as strong as char, short, or +# int; but we must check long long (if it is being used for int64) and double. +# +# 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. +# +# 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 x"$HAVE_LONG_LONG_INT_64" = xyes && test $MAX_ALIGNOF -lt $ac_cv_alignof_long_long_int ; then + MAX_ALIGNOF="$ac_cv_alignof_long_long_int" + fi -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 cat >>confdefs.h <<_ACEOF diff --git a/doc/src/sgml/dfunc.sgml b/doc/src/sgml/dfunc.sgml index b94aefcd0c..554f9fac4c 100644 --- a/doc/src/sgml/dfunc.sgml +++ b/doc/src/sgml/dfunc.sgml @@ -202,4 +202,23 @@ gcc -G -o foo.so foo.o server expects to find the shared library files. + + diff --git a/src/Makefile.shlib b/src/Makefile.shlib index fa81f6ffdd..13ea84ac18 100644 --- a/src/Makefile.shlib +++ b/src/Makefile.shlib @@ -106,6 +106,20 @@ ifdef SO_MAJOR_VERSION override CPPFLAGS += -DSO_MAJOR_VERSION=$(SO_MAJOR_VERSION) endif +ifeq ($(PORTNAME), aix) + LINK.shared = $(COMPILER) + ifdef SO_MAJOR_VERSION + shlib = lib$(NAME)$(DLSUFFIX).$(SO_MAJOR_VERSION) + endif + haslibarule = yes + # $(exports_file) is also usable as an import file + exports_file = lib$(NAME).exp + BUILD.exports = ( echo '\#! $(shlib)'; $(AWK) '/^[^\#]/ {printf "%s\n",$$1}' $< ) > $@ + ifneq (,$(SHLIB_EXPORTS)) + LINK.shared += -Wl,-bE:$(exports_file) + endif +endif + ifeq ($(PORTNAME), darwin) ifdef soname # linkable library @@ -254,6 +268,14 @@ $(stlib): $(OBJS) | $(SHLIB_PREREQS) touch $@ endif #haslibarule +# AIX wraps both shared libraries and static library, which can be used both +# for static and shared linking +ifeq ($(PORTNAME), aix) +$(stlib): $(shlib) + rm -f $(stlib) + $(AR) $(AROPT) $(stlib) $(shlib) +endif # aix + ifeq (,$(filter cygwin win32,$(PORTNAME))) # Normal case @@ -267,8 +289,11 @@ ifneq ($(shlib), $(shlib_major)) endif # Make sure we have a link to a name without any version numbers ifneq ($(shlib), $(shlib_bare)) +# except on AIX, where that's not a thing +ifneq ($(PORTNAME), aix) rm -f $(shlib_bare) $(LN_S) $(shlib) $(shlib_bare) +endif # aix endif # shlib_bare endif # shlib_major @@ -376,6 +401,9 @@ install-lib-static: $(stlib) installdirs-lib install-lib-shared: $(shlib) installdirs-lib ifdef soname +# we don't install $(shlib) on AIX +# (see http://archives.postgresql.org/message-id/52EF20B2E3209443BC37736D00C3C1380A6E79FE@EXADV1.host.magwien.gv.at) +ifneq ($(PORTNAME), aix) $(INSTALL_SHLIB) $< '$(DESTDIR)$(libdir)/$(shlib)' ifneq ($(PORTNAME), cygwin) ifneq ($(PORTNAME), win32) @@ -391,6 +419,7 @@ ifneq ($(shlib), $(shlib_bare)) endif endif # not win32 endif # not cygwin +endif # not aix ifneq (,$(findstring $(PORTNAME),win32 cygwin)) $(INSTALL_SHLIB) $< '$(DESTDIR)$(bindir)/$(shlib)' endif diff --git a/src/backend/Makefile b/src/backend/Makefile index 84302cc6da..a37f6198ed 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -62,12 +62,14 @@ all: submake-libpgport submake-catalog-headers submake-utils-headers postgres $( ifneq ($(PORTNAME), cygwin) ifneq ($(PORTNAME), win32) +ifneq ($(PORTNAME), aix) postgres: $(OBJS) $(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LIBS) -o $@ endif endif +endif ifeq ($(PORTNAME), cygwin) @@ -94,6 +96,24 @@ libpostgres.a: postgres endif # win32 +ifeq ($(PORTNAME), aix) + +postgres: $(POSTGRES_IMP) + $(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(LDFLAGS) -Wl,-bE:$(top_builddir)/src/backend/$(POSTGRES_IMP) $(LIBS) -Wl,-brtllib -o $@ + +# Linking to a single .o with -r is a lot faster than building a .a or passing +# all objects to MKLDEXPORT. +# +# It looks alluring to use $(CC) -r instead of ld -r, but that doesn't +# trivially work with gcc, due to gcc specific static libraries linked in with +# -r. +$(POSTGRES_IMP): $(OBJS) + ld -r -o SUBSYS.o $(call expand_subsys,$^) + $(MKLDEXPORT) SUBSYS.o . > $@ + @rm -f SUBSYS.o + +endif # aix + $(top_builddir)/src/port/libpgport_srv.a: | submake-libpgport diff --git a/src/backend/port/aix/mkldexport.sh b/src/backend/port/aix/mkldexport.sh new file mode 100755 index 0000000000..adf3793e86 --- /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/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 8acca3e0a0..54c3446c66 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -904,7 +904,9 @@ errcode_for_file_access(void) /* Wrong object type or state */ case ENOTDIR: /* Not a directory */ case EISDIR: /* Is a directory */ +#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */ case ENOTEMPTY: /* Directory not empty */ +#endif edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE; break; diff --git a/src/include/port/aix.h b/src/include/port/aix.h new file mode 100644 index 0000000000..7d08480c8c --- /dev/null +++ b/src/include/port/aix.h @@ -0,0 +1,4 @@ +/* + * src/include/port/aix.h + */ + diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index e94ed5f48b..17a2ee0973 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -415,17 +415,15 @@ tas(volatile slock_t *lock) __asm__ __volatile__( " lwarx %0,0,%3,1 \n" " cmpwi %0,0 \n" -" bne 1f \n" +" bne $+16 \n" /* branch to li %1,1 */ " addi %0,%0,1 \n" " stwcx. %0,0,%3 \n" -" beq 2f \n" -"1: \n" +" beq $+12 \n" /* branch to lwsync */ " li %1,1 \n" -" b 3f \n" -"2: \n" +" b $+12 \n" /* branch to end of asm sequence */ " lwsync \n" " li %1,0 \n" -"3: \n" + : "=&b"(_t), "=r"(_res), "+m"(*lock) : "r"(lock) : "memory", "cc"); diff --git a/src/makefiles/Makefile.aix b/src/makefiles/Makefile.aix new file mode 100644 index 0000000000..dd16a7a037 --- /dev/null +++ b/src/makefiles/Makefile.aix @@ -0,0 +1,39 @@ +# MAKE_EXPORTS is required for svr4 loaders that want a file of +# symbol names to tell them what to export/import. +MAKE_EXPORTS= true + +# -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 + +# when building with gcc, need to make sure that libgcc can be found +ifeq ($(GCC), yes) +libpath := $(libpath):$(dir $(shell gcc -print-libgcc-file-name)) +endif + +rpath = -Wl,-blibpath:'$(rpathdir)$(libpath)' + +LDFLAGS_SL += -Wl,-bnoentry -Wl,-H512 -Wl,-bM:SRE + +# 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/port/strerror.c b/src/port/strerror.c index 4918ba821c..1070a49802 100644 --- a/src/port/strerror.c +++ b/src/port/strerror.c @@ -214,8 +214,10 @@ get_errno_symbol(int errnum) return "ENOTCONN"; case ENOTDIR: return "ENOTDIR"; +#if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */ case ENOTEMPTY: return "ENOTEMPTY"; +#endif case ENOTSOCK: return "ENOTSOCK"; #ifdef ENOTSUP diff --git a/src/template/aix b/src/template/aix new file mode 100644 index 0000000000..48a3ce55cf --- /dev/null +++ b/src/template/aix @@ -0,0 +1,7 @@ +# src/template/aix + +# Extra CFLAGS for code that will go into a shared library +CFLAGS_SL="" + +# Native memset() is faster. +MEMSET_LOOP_LIMIT=0 diff --git a/src/test/regress/expected/jsonb_jsonpath.out b/src/test/regress/expected/jsonb_jsonpath.out index acdf7e436f..4bcd4e91a2 100644 --- a/src/test/regress/expected/jsonb_jsonpath.out +++ b/src/test/regress/expected/jsonb_jsonpath.out @@ -2684,12 +2684,16 @@ select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()'); "12:34:56+05:30" (1 row) +-- this timetz usage will absorb the UTC offset of the current timezone setting +begin; +set local timezone = 'UTC-10'; select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()'); jsonb_path_query_tz --------------------- - "12:34:56-07:00" + "12:34:56+10:00" (1 row) +rollback; select jsonb_path_query('"12:34:56"', '$.time().string()'); jsonb_path_query ------------------ diff --git a/src/test/regress/sql/jsonb_jsonpath.sql b/src/test/regress/sql/jsonb_jsonpath.sql index da3f7969ca..3e8929a526 100644 --- a/src/test/regress/sql/jsonb_jsonpath.sql +++ b/src/test/regress/sql/jsonb_jsonpath.sql @@ -607,7 +607,11 @@ select jsonb_path_query_tz('"2023-08-15 12:34:56"', '$.timestamp_tz().string()') select jsonb_path_query('"2023-08-15 12:34:56 +5:30"', '$.timestamp_tz().string()'); select jsonb_path_query('"2023-08-15 12:34:56"', '$.timestamp().string()'); select jsonb_path_query('"12:34:56 +5:30"', '$.time_tz().string()'); +-- this timetz usage will absorb the UTC offset of the current timezone setting +begin; +set local timezone = 'UTC-10'; select jsonb_path_query_tz('"12:34:56"', '$.time_tz().string()'); +rollback; select jsonb_path_query('"12:34:56"', '$.time().string()'); select jsonb_path_query('"2023-08-15"', '$.date().string()'); -- 2.41.0