From 18dd09463342bbc836c7a8dda3a3864ceb083176 Mon Sep 17 00:00:00 2001
From: AIX-dev <postgres-ibm-aix@wwpdl.vnet.ibm.com>
Date: Wed, 15 Oct 2025 09:33:07 -0500
Subject: [PATCH] AIX changes for meson build.

---
 meson.build                                   | 25 +++++++++++--
 src/backend/jit/llvm/meson.build              |  6 ++++
 src/backend/meson.build                       | 36 ++++++++++++++++++-
 .../replication/libpqwalreceiver/meson.build  |  8 ++++-
 src/backend/replication/pgoutput/meson.build  |  6 ++++
 src/backend/snowball/meson.build              |  8 ++++-
 .../utils/mb/conversion_procs/meson.build     |  6 ++++
 src/include/port/aix.h                        | 22 ++++++++++++
 src/interfaces/ecpg/compatlib/meson.build     |  8 ++++-
 src/interfaces/ecpg/ecpglib/meson.build       |  7 +++-
 src/interfaces/ecpg/pgtypeslib/meson.build    |  7 +++-
 src/interfaces/libpq/meson.build              | 14 ++++++--
 src/tools/gen_export.pl                       | 13 +++++--
 13 files changed, 154 insertions(+), 12 deletions(-)

diff --git a/meson.build b/meson.build
index a87eb913fff..27c0f38ebc8 100644
--- a/meson.build
+++ b/meson.build
@@ -198,7 +198,26 @@ endif
 # that purpose.
 portname = host_system
 
-if host_system == 'cygwin'
+if host_system == 'aix'
+  library_path_var = 'LIBPATH'
+
+  export_file_format = 'aix'
+  export_fmt = '-Wl,-bE:@0@'
+  mod_link_args_fmt = ['-Wl,-bI:@0@']
+  mod_link_with_dir = 'libdir'
+  mod_link_with_name = '@0@.imp'
+
+  # M:SRE sets a flag indicating that an object is a shared library. Seems to
+  # work in some circumstances without, but required in others.
+  ldflags_sl += '-Wl,-bM:SRE'
+  ldflags_be += '-Wl,-brtllib'
+
+  # Native memset() is faster, tested on:
+  # - AIX 5.1 and 5.2, XLC 6.0 (IBM's cc)
+  # - AIX 5.3 ML3, gcc 4.0.1
+  #memset_loop_limit = 0
+
+elif host_system == 'cygwin'
   sema_kind = 'unnamed_posix'
   cppflags += '-D_GNU_SOURCE'
   dlsuffix = '.dll'
@@ -1775,7 +1794,9 @@ endforeach
 # would be too much of a penalty for disk and memory space.
 alignof_double = cdata.get('ALIGNOF_DOUBLE')
 if cc.alignment('int64_t', args: test_c_args, prefix: '#include <stdint.h>') > alignof_double
-  error('alignment of int64_t is greater than the alignment of double')
+  if host_system != 'aix'
+    error('alignment of int64_t is greater than the alignment of double')
+  endif
 endif
 cdata.set('MAXIMUM_ALIGNOF', alignof_double)
 
diff --git a/src/backend/jit/llvm/meson.build b/src/backend/jit/llvm/meson.build
index 805fbd69006..f83db9d0d6e 100644
--- a/src/backend/jit/llvm/meson.build
+++ b/src/backend/jit/llvm/meson.build
@@ -29,11 +29,17 @@ if host_system == 'windows'
     '--FILEDESC', 'llvmjit - JIT using LLVM',])
 endif
 
+aix_link_args= []
+if host_machine.system() == 'aix'
+  aix_link_args = ['-Wl,-bI:' + meson.project_build_root() + '/src/backend/postgres.imp']
+endif
+
 llvmjit = shared_module('llvmjit',
   llvmjit_sources,
   kwargs: pg_mod_args + {
     'dependencies': pg_mod_args['dependencies'] + [llvm],
     'cpp_args': pg_mod_args['cpp_args'] + llvm.get_variable(configtool: 'cxxflags').split(),
+    link_args: aix_link_args
   }
 )
 
diff --git a/src/backend/meson.build b/src/backend/meson.build
index b831a541652..47c0eae1309 100644
--- a/src/backend/meson.build
+++ b/src/backend/meson.build
@@ -125,6 +125,40 @@ if host_system == 'windows'
     '--FILEDESC', 'PostgreSQL Server',])
 endif
 
+if host_system == 'aix'
+find_obj_files = find_program('sh', required: true)
+
+cb_o = custom_target(
+   'SUBSYS.o',
+    input: [postgres_lib.extract_all_objects(recursive: true)],
+    output: 'SUBSYS.o',
+   command: ['ld', '-r', '-o', '@OUTPUT@', '@INPUT@'],
+   install: false,
+  )
+postgres_imp = 'postgres.imp'
+
+generate_import_file = custom_target('generate_import_file', output: postgres_imp, command: ['sh', '-c', '../src/backend/port/aix/mkldexport.sh src/backend/SUBSYS.o . > src/backend/postgres.imp'], build_by_default: true, depends: [cb_o])
+
+my_dep = declare_dependency(sources:[generate_import_file])
+#libpq_aix_deps += my_dep
+backend_link_depends += generate_import_file
+
+endif
+
+if host_system == 'aix'
+ postgres = executable('postgres',
+   backend_input,
+   sources: post_export_backend_sources,
+   objects: backend_objs,
+   link_args: backend_link_args + ['-Wl,-bE:src/backend/postgres.imp'],
+   link_with: backend_link_with,
+   link_depends: backend_link_depends,
+   export_dynamic: true,
+   implib: 'postgres',
+   dependencies: backend_build_deps + [my_dep],
+   kwargs: default_bin_args,
+)
+else
 postgres = executable('postgres',
   backend_input,
   sources: post_export_backend_sources,
@@ -137,7 +171,7 @@ postgres = executable('postgres',
   dependencies: backend_build_deps,
   kwargs: default_bin_args,
 )
-
+endif
 backend_targets += postgres
 
 pg_mod_c_args = cflags_mod
diff --git a/src/backend/replication/libpqwalreceiver/meson.build b/src/backend/replication/libpqwalreceiver/meson.build
index 2150f31cfa3..135062244d4 100644
--- a/src/backend/replication/libpqwalreceiver/meson.build
+++ b/src/backend/replication/libpqwalreceiver/meson.build
@@ -10,12 +10,18 @@ if host_system == 'windows'
     '--FILEDESC', 'libpqwalreceiver - receive WAL during streaming replication',])
 endif
 
+aix_link_args= []
+if host_machine.system() == 'aix'
+  aix_link_args = ['-Wl,-bI:' + meson.project_build_root() + '/src/backend/postgres.imp']
+endif
+
 libpqwalreceiver = shared_module('pqwalreceiver',
   libpqwalreceiver_sources,
   kwargs: pg_mod_args + {
     'name_prefix': 'lib',
     'dependencies': pg_mod_args['dependencies'] + [libpq],
-  }
+  },
+  link_args: aix_link_args
 )
 
 backend_targets += libpqwalreceiver
diff --git a/src/backend/replication/pgoutput/meson.build b/src/backend/replication/pgoutput/meson.build
index 14e2f03ada0..9fbd035988b 100644
--- a/src/backend/replication/pgoutput/meson.build
+++ b/src/backend/replication/pgoutput/meson.build
@@ -10,9 +10,15 @@ if host_system == 'windows'
     '--FILEDESC', 'pgoutput - standard logical replication output plugin',])
 endif
 
+aix_link_args= []
+if host_machine.system() == 'aix'
+  aix_link_args = ['-Wl,-bI:' + meson.project_build_root() + '/src/backend/postgres.imp']
+endif
+
 pgoutput = shared_module('pgoutput',
   pgoutput_sources,
   kwargs: pg_mod_args,
+  link_args: aix_link_args
 )
 
 backend_targets += pgoutput
diff --git a/src/backend/snowball/meson.build b/src/backend/snowball/meson.build
index 8e73d9d7368..92b3934bcc6 100644
--- a/src/backend/snowball/meson.build
+++ b/src/backend/snowball/meson.build
@@ -66,12 +66,18 @@ if host_system == 'windows'
     '--FILEDESC', 'snowball - natural language stemmers',])
 endif
 
+aix_link_args= []
+if host_machine.system() == 'aix'
+  aix_link_args = ['-Wl,-bI:' + meson.project_build_root() + '/src/backend/postgres.imp']
+endif
+
 dict_snowball = shared_module('dict_snowball',
   dict_snowball_sources,
   c_pch: pch_postgres_h,
   kwargs: pg_mod_args + {
     'include_directories': [stemmer_inc],
-  }
+  },
+  link_args: aix_link_args
 )
 
 snowball_create = custom_target('snowball_create',
diff --git a/src/backend/utils/mb/conversion_procs/meson.build b/src/backend/utils/mb/conversion_procs/meson.build
index 0e8273e0b61..a76c4993055 100644
--- a/src/backend/utils/mb/conversion_procs/meson.build
+++ b/src/backend/utils/mb/conversion_procs/meson.build
@@ -38,8 +38,14 @@ foreach encoding, sources : encodings
       '--NAME', encoding])
   endif
 
+  aix_link_args= []
+  if host_machine.system() == 'aix'
+    aix_link_args = ['-Wl,-bI:' + meson.project_build_root() + '/src/backend/postgres.imp']
+  endif
+
   backend_targets += shared_module(encoding,
     source_files,
     kwargs: pg_mod_args,
+    link_args: aix_link_args
   )
 endforeach
diff --git a/src/include/port/aix.h b/src/include/port/aix.h
index 7d08480c8c0..450e68da657 100644
--- a/src/include/port/aix.h
+++ b/src/include/port/aix.h
@@ -2,3 +2,25 @@
  * src/include/port/aix.h
  */
 
+/* These changes are required for the meson changes as the autoconf is not run
+ * and corresponding  key feature macros are defined here.
+ */
+ 
+#ifdef _AIX
+#ifndef PGDLLIMPORT
+#define PGDLLIMPORT
+#endif  /* PGDLLIMPORT */
+typedef float float4;
+typedef double float8;
+
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+#define pg_noreturn _Noreturn
+#elif defined(__GNUC__)
+#define pg_noreturn __attribute__((noreturn))
+#else
+#define pg_noreturn
+#endif
+
+#include <stdbool.h>
+
+#endif  /*_AIX */
diff --git a/src/interfaces/ecpg/compatlib/meson.build b/src/interfaces/ecpg/compatlib/meson.build
index 56e0a21651b..d199002f7ed 100644
--- a/src/interfaces/ecpg/compatlib/meson.build
+++ b/src/interfaces/ecpg/compatlib/meson.build
@@ -15,8 +15,14 @@ if host_system == 'windows'
     '--FILEDESC', 'ECPG compat - compatibility library for ECPG',])
 endif
 
+libname = 'libecpg_compat'
+if host_machine.system() == 'aix'
+  libname += '_static'
+endif
+
+
 # see src/interfaces/libpq/meson.build
-ecpg_compat_st = static_library('libecpg_compat',
+ecpg_compat_st = static_library(libname,
   ecpg_compat_sources,
   include_directories: ecpg_compat_inc,
   c_args: ecpg_compat_c_args,
diff --git a/src/interfaces/ecpg/ecpglib/meson.build b/src/interfaces/ecpg/ecpglib/meson.build
index 8f478c6a73e..448a0038a71 100644
--- a/src/interfaces/ecpg/ecpglib/meson.build
+++ b/src/interfaces/ecpg/ecpglib/meson.build
@@ -24,8 +24,13 @@ if host_system == 'windows'
     '--FILEDESC', 'ECPG - embedded SQL in C',])
 endif
 
+libname = 'libecpg'
+if host_machine.system() == 'aix'
+  libname += '_static'
+endif
+
 # see src/interfaces/libpq/meson.build
-ecpglib_st = static_library('libecpg',
+ecpglib_st = static_library(libname,
   ecpglib_sources,
   include_directories: ecpglib_inc,
   c_args: ecpglib_c_args,
diff --git a/src/interfaces/ecpg/pgtypeslib/meson.build b/src/interfaces/ecpg/pgtypeslib/meson.build
index 02301ec9acb..6421930dc05 100644
--- a/src/interfaces/ecpg/pgtypeslib/meson.build
+++ b/src/interfaces/ecpg/pgtypeslib/meson.build
@@ -20,8 +20,13 @@ if host_system == 'windows'
     '--FILEDESC', 'pgtypes - library for data type mapping',])
 endif
 
+libname = 'libpgtypes'
+if host_machine.system() == 'aix'
+  libname += '_static'
+endif
+
 # see src/interfaces/libpq/meson.build
-ecpg_pgtypes_st = static_library('libpgtypes',
+ecpg_pgtypes_st = static_library(libname,
   ecpg_pgtypes_sources,
   include_directories: ecpg_pgtypes_inc,
   c_args: ecpg_pgtypes_c_args,
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index a74e885b169..3e96d3f073e 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -49,6 +49,11 @@ libpq_c_args = ['-DSO_MAJOR_VERSION=5']
 # The OAuth implementation differs depending on the type of library being built.
 libpq_so_c_args = ['-DUSE_DYNAMIC_OAUTH']
 
+libname = 'libpq'
+if host_machine.system() == 'aix'
+  libname += '_static'
+endif
+
 # Not using both_libraries() here as
 # 1) resource files should only be in the shared library
 # 2) we want the .pc file to include a dependency to {pgport,common}_static for
@@ -57,7 +62,7 @@ libpq_so_c_args = ['-DUSE_DYNAMIC_OAUTH']
 # We could try to avoid building the source files twice, but it probably adds
 # more complexity than its worth (reusing object files requires also linking
 # to the library on windows or breaks precompiled headers).
-libpq_st = static_library('libpq',
+libpq_st = static_library(libname,
   libpq_sources,
   include_directories: [libpq_inc],
   c_args: libpq_c_args,
@@ -66,6 +71,11 @@ libpq_st = static_library('libpq',
   kwargs: default_lib_args,
 )
 
+aix_link_args = []
+if host_machine.system() == 'aix'
+  aix_link_args = ['-Wl,-bI:' + export_file.full_path()]
+endif
+
 libpq_so = shared_library('libpq',
   libpq_sources + libpq_so_sources,
   include_directories: [libpq_inc, postgres_inc],
@@ -76,7 +86,7 @@ libpq_so = shared_library('libpq',
   darwin_versions: ['5', '5.' + pg_version_major.to_string()],
   dependencies: [frontend_shlib_code, libpq_deps],
   link_depends: export_file,
-  link_args: export_fmt.format(export_file.full_path()),
+  link_args: [export_fmt.format(export_file.full_path()), aix_link_args],
   kwargs: default_lib_args,
 )
 
diff --git a/src/tools/gen_export.pl b/src/tools/gen_export.pl
index 86a7742b369..19c8b60560f 100644
--- a/src/tools/gen_export.pl
+++ b/src/tools/gen_export.pl
@@ -18,9 +18,10 @@ GetOptions(
 
 if (not(   $format eq 'darwin'
 		or $format eq 'gnu'
-		or $format eq 'win'))
+		or $format eq 'win'
+        or $format eq 'aix'))
 {
-	die "$0: $format is not yet handled (only darwin, gnu, win are)\n";
+	die "$0: $format is not yet handled (only darwin, gnu, win, aix are)\n";
 }
 
 open(my $input_handle, '<', $input)
@@ -46,6 +47,10 @@ elsif ($format eq 'win')
 	}
 	print $output_handle "EXPORTS\n";
 }
+elsif ($format eq 'aix')
+{
+	print $output_handle "#!\n";
+}
 
 while (<$input_handle>)
 {
@@ -63,6 +68,10 @@ while (<$input_handle>)
 		{
 			print $output_handle "    $1;\n";
 		}
+        elsif ($format eq 'aix')
+        {
+            print $output_handle "$1\n";
+        }
 		elsif ($format eq 'win')
 		{
 			print $output_handle "$1 @ $2\n";
-- 
2.41.0

