Hi,

On 2022-10-10 14:35:14 -0700, Andres Freund wrote:
> On 2022-10-05 13:07:10 -0700, Andres Freund wrote:
> > 0004: solaris: Check for -Wl,-E directly instead of checking for gnu LD
> > 
> >   This allows us to get rid of the nontrivial detection of with_gnu_ld,
> >   simplifying meson PGXS compatibility. It's also nice to delete libtool.m4.
> > 
> >   I don't like the SOLARIS_EXPORT_DYNAMIC variable I invented. If somebody 
> > has
> >   a better idea...
> 
> A cleaner approach could be to add a LDFLAGS_BE and emit the -Wl,-E into it
> from both configure and meson, solely based on whether -Wl,-E is supported.  I
> haven't verified cygwin, but on our other platforms that seems to do the right
> thing.

I think that does look better. See the attached 0003.


The attached v3 of this patch has an unchanged 0001 (CRC cflags).

For 0002, I still removed LD from Makefile.global, but instead just hardcoded
ld in the export file generation portion of the backend build - there's no
working alternative linkers, and we already hardcode a bunch of other paths in
mkldexport.

0003 is changed significantly - as proposed in the message quoted above, I
introduced LDFLAGS_EX_BE and moved the detection -Wl,-E (I used
-Wl,--export-dynamic, which we previously only used on FreeBSD) into
configure, getting rid of export_dynamic.

0004, the patch introducing PGXS compat, saw a few changes too:
- I implemented one of the FIXMEs, the correct determination of strip flags
- I moved the bulk of the pgxs compat code to src/makefiles/meson.build - imo
  src/meson.build got bulked up too much with pgxs-emulation code
- some minor cleanups

Greetings,

Andres Freund
>From 6feb84e2f87320f936764aa3d906a8828e080390 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Wed, 5 Oct 2022 12:24:14 -0700
Subject: [PATCH v3 1/4] autoconf: Unify CFLAGS_SSE42 and CFLAGS_ARMV8_CRC32C

Until now we emitted the cflags to build the CRC objects into architecture
specific variables. That doesn't make a whole lot of sense to me - we're never
going to target x86 and arm at the same time, so they don't need to be
separate variables.

It might be better to instead continue to have CFLAGS_SSE42 /
CFLAGS_ARMV8_CRC32C be computed by PGAC_ARMV8_CRC32C_INTRINSICS /
PGAC_SSE42_CRC32_INTRINSICS and then set CFLAGS_CRC based on those. But it
seems unlikely that we'd need other sets of CRC specific flags for those two
architectures at the same time.

Discussion: https://postgr.es/m/20221005200710.luvw5evhwf6cl...@awork3.anarazel.de
---
 src/port/Makefile      | 16 ++++++++--------
 config/c-compiler.m4   |  8 ++++----
 configure              | 19 +++++++++----------
 configure.ac           | 10 +++++-----
 src/Makefile.global.in |  3 +--
 5 files changed, 27 insertions(+), 29 deletions(-)

diff --git a/src/port/Makefile b/src/port/Makefile
index b3754d8940a..711f59e32bd 100644
--- a/src/port/Makefile
+++ b/src/port/Makefile
@@ -88,15 +88,15 @@ libpgport.a: $(OBJS)
 thread.o: CFLAGS+=$(PTHREAD_CFLAGS)
 thread_shlib.o: CFLAGS+=$(PTHREAD_CFLAGS)
 
-# all versions of pg_crc32c_sse42.o need CFLAGS_SSE42
-pg_crc32c_sse42.o: CFLAGS+=$(CFLAGS_SSE42)
-pg_crc32c_sse42_shlib.o: CFLAGS+=$(CFLAGS_SSE42)
-pg_crc32c_sse42_srv.o: CFLAGS+=$(CFLAGS_SSE42)
+# all versions of pg_crc32c_sse42.o need CFLAGS_CRC
+pg_crc32c_sse42.o: CFLAGS+=$(CFLAGS_CRC)
+pg_crc32c_sse42_shlib.o: CFLAGS+=$(CFLAGS_CRC)
+pg_crc32c_sse42_srv.o: CFLAGS+=$(CFLAGS_CRC)
 
-# all versions of pg_crc32c_armv8.o need CFLAGS_ARMV8_CRC32C
-pg_crc32c_armv8.o: CFLAGS+=$(CFLAGS_ARMV8_CRC32C)
-pg_crc32c_armv8_shlib.o: CFLAGS+=$(CFLAGS_ARMV8_CRC32C)
-pg_crc32c_armv8_srv.o: CFLAGS+=$(CFLAGS_ARMV8_CRC32C)
+# all versions of pg_crc32c_armv8.o need CFLAGS_CRC
+pg_crc32c_armv8.o: CFLAGS+=$(CFLAGS_CRC)
+pg_crc32c_armv8_shlib.o: CFLAGS+=$(CFLAGS_CRC)
+pg_crc32c_armv8_srv.o: CFLAGS+=$(CFLAGS_CRC)
 
 #
 # Shared library versions of object files
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 000b075312e..eb8cc8ce170 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -597,7 +597,7 @@ fi])# PGAC_HAVE_GCC__ATOMIC_INT64_CAS
 # the other ones are, on x86-64 platforms)
 #
 # An optional compiler flag can be passed as argument (e.g. -msse4.2). If the
-# intrinsics are supported, sets pgac_sse42_crc32_intrinsics, and CFLAGS_SSE42.
+# intrinsics are supported, sets pgac_sse42_crc32_intrinsics, and CFLAGS_CRC.
 AC_DEFUN([PGAC_SSE42_CRC32_INTRINSICS],
 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_sse42_crc32_intrinsics_$1])])dnl
 AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=$1], [Ac_cachevar],
@@ -613,7 +613,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <nmmintrin.h>],
   [Ac_cachevar=no])
 CFLAGS="$pgac_save_CFLAGS"])
 if test x"$Ac_cachevar" = x"yes"; then
-  CFLAGS_SSE42="$1"
+  CFLAGS_CRC="$1"
   pgac_sse42_crc32_intrinsics=yes
 fi
 undefine([Ac_cachevar])dnl
@@ -629,7 +629,7 @@ undefine([Ac_cachevar])dnl
 #
 # An optional compiler flag can be passed as argument (e.g.
 # -march=armv8-a+crc). If the intrinsics are supported, sets
-# pgac_armv8_crc32c_intrinsics, and CFLAGS_ARMV8_CRC32C.
+# pgac_armv8_crc32c_intrinsics, and CFLAGS_CRC.
 AC_DEFUN([PGAC_ARMV8_CRC32C_INTRINSICS],
 [define([Ac_cachevar], [AS_TR_SH([pgac_cv_armv8_crc32c_intrinsics_$1])])dnl
 AC_CACHE_CHECK([for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=$1], [Ac_cachevar],
@@ -647,7 +647,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <arm_acle.h>],
   [Ac_cachevar=no])
 CFLAGS="$pgac_save_CFLAGS"])
 if test x"$Ac_cachevar" = x"yes"; then
-  CFLAGS_ARMV8_CRC32C="$1"
+  CFLAGS_CRC="$1"
   pgac_armv8_crc32c_intrinsics=yes
 fi
 undefine([Ac_cachevar])dnl
diff --git a/configure b/configure
index e04ee9fb416..e65ac574fb5 100755
--- a/configure
+++ b/configure
@@ -645,8 +645,7 @@ MSGMERGE
 MSGFMT_FLAGS
 MSGFMT
 PG_CRC32C_OBJS
-CFLAGS_ARMV8_CRC32C
-CFLAGS_SSE42
+CFLAGS_CRC
 LIBOBJS
 ZSTD
 LZ4
@@ -17813,7 +17812,7 @@ fi
 #
 # First check if the _mm_crc32_u8 and _mm_crc32_u64 intrinsics can be used
 # with the default compiler flags. If not, check if adding the -msse4.2
-# flag helps. CFLAGS_SSE42 is set to -msse4.2 if that's required.
+# flag helps. CFLAGS_CRC is set to -msse4.2 if that's required.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=" >&5
 $as_echo_n "checking for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=... " >&6; }
 if ${pgac_cv_sse42_crc32_intrinsics_+:} false; then :
@@ -17848,7 +17847,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_sse42_crc32_intrinsics_" >&5
 $as_echo "$pgac_cv_sse42_crc32_intrinsics_" >&6; }
 if test x"$pgac_cv_sse42_crc32_intrinsics_" = x"yes"; then
-  CFLAGS_SSE42=""
+  CFLAGS_CRC=""
   pgac_sse42_crc32_intrinsics=yes
 fi
 
@@ -17887,13 +17886,12 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_sse42_crc32_intrinsics__msse4_2" >&5
 $as_echo "$pgac_cv_sse42_crc32_intrinsics__msse4_2" >&6; }
 if test x"$pgac_cv_sse42_crc32_intrinsics__msse4_2" = x"yes"; then
-  CFLAGS_SSE42="-msse4.2"
+  CFLAGS_CRC="-msse4.2"
   pgac_sse42_crc32_intrinsics=yes
 fi
 
 fi
 
-
 # Are we targeting a processor that supports SSE 4.2? gcc, clang and icc all
 # define __SSE4_2__ in that case.
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -17920,7 +17918,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 #
 # First check if __crc32c* intrinsics can be used with the default compiler
 # flags. If not, check if adding -march=armv8-a+crc flag helps.
-# CFLAGS_ARMV8_CRC32C is set if the extra flag is required.
+# CFLAGS_CRC is set if the extra flag is required.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=" >&5
 $as_echo_n "checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=... " >&6; }
 if ${pgac_cv_armv8_crc32c_intrinsics_+:} false; then :
@@ -17957,7 +17955,7 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_armv8_crc32c_intrinsics_" >&5
 $as_echo "$pgac_cv_armv8_crc32c_intrinsics_" >&6; }
 if test x"$pgac_cv_armv8_crc32c_intrinsics_" = x"yes"; then
-  CFLAGS_ARMV8_CRC32C=""
+  CFLAGS_CRC=""
   pgac_armv8_crc32c_intrinsics=yes
 fi
 
@@ -17998,13 +17996,14 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_armv8_crc32c_intrinsics__march_armv8_apcrc" >&5
 $as_echo "$pgac_cv_armv8_crc32c_intrinsics__march_armv8_apcrc" >&6; }
 if test x"$pgac_cv_armv8_crc32c_intrinsics__march_armv8_apcrc" = x"yes"; then
-  CFLAGS_ARMV8_CRC32C="-march=armv8-a+crc"
+  CFLAGS_CRC="-march=armv8-a+crc"
   pgac_armv8_crc32c_intrinsics=yes
 fi
 
 fi
 
 
+
 # Select CRC-32C implementation.
 #
 # If we are targeting a processor that has Intel SSE 4.2 instructions, we can
@@ -18032,7 +18031,7 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" &&
       USE_SSE42_CRC32C_WITH_RUNTIME_CHECK=1
     else
       # Use ARM CRC Extension if available.
-      if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then
+      if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_CRC" = x""; then
         USE_ARMV8_CRC32C=1
       else
         # ARM CRC Extension, with runtime check?
diff --git a/configure.ac b/configure.ac
index f146c8301ae..219e85441d2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2087,12 +2087,11 @@ fi
 #
 # First check if the _mm_crc32_u8 and _mm_crc32_u64 intrinsics can be used
 # with the default compiler flags. If not, check if adding the -msse4.2
-# flag helps. CFLAGS_SSE42 is set to -msse4.2 if that's required.
+# flag helps. CFLAGS_CRC is set to -msse4.2 if that's required.
 PGAC_SSE42_CRC32_INTRINSICS([])
 if test x"$pgac_sse42_crc32_intrinsics" != x"yes"; then
   PGAC_SSE42_CRC32_INTRINSICS([-msse4.2])
 fi
-AC_SUBST(CFLAGS_SSE42)
 
 # Are we targeting a processor that supports SSE 4.2? gcc, clang and icc all
 # define __SSE4_2__ in that case.
@@ -2106,12 +2105,13 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
 #
 # First check if __crc32c* intrinsics can be used with the default compiler
 # flags. If not, check if adding -march=armv8-a+crc flag helps.
-# CFLAGS_ARMV8_CRC32C is set if the extra flag is required.
+# CFLAGS_CRC is set if the extra flag is required.
 PGAC_ARMV8_CRC32C_INTRINSICS([])
 if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then
   PGAC_ARMV8_CRC32C_INTRINSICS([-march=armv8-a+crc])
 fi
-AC_SUBST(CFLAGS_ARMV8_CRC32C)
+
+AC_SUBST(CFLAGS_CRC)
 
 # Select CRC-32C implementation.
 #
@@ -2140,7 +2140,7 @@ if test x"$USE_SLICING_BY_8_CRC32C" = x"" && test x"$USE_SSE42_CRC32C" = x"" &&
       USE_SSE42_CRC32C_WITH_RUNTIME_CHECK=1
     else
       # Use ARM CRC Extension if available.
-      if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_ARMV8_CRC32C" = x""; then
+      if test x"$pgac_armv8_crc32c_intrinsics" = x"yes" && test x"$CFLAGS_CRC" = x""; then
         USE_ARMV8_CRC32C=1
       else
         # ARM CRC Extension, with runtime check?
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 99889167e18..a5e2f36d217 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -262,8 +262,7 @@ CFLAGS_SL_MODULE = @CFLAGS_SL_MODULE@
 CXXFLAGS_SL_MODULE = @CXXFLAGS_SL_MODULE@
 CFLAGS_UNROLL_LOOPS = @CFLAGS_UNROLL_LOOPS@
 CFLAGS_VECTORIZE = @CFLAGS_VECTORIZE@
-CFLAGS_SSE42 = @CFLAGS_SSE42@
-CFLAGS_ARMV8_CRC32C = @CFLAGS_ARMV8_CRC32C@
+CFLAGS_CRC = @CFLAGS_CRC@
 PERMIT_DECLARATION_AFTER_STATEMENT = @PERMIT_DECLARATION_AFTER_STATEMENT@
 CXXFLAGS = @CXXFLAGS@
 
-- 
2.38.0

>From e110d43824a1044e258feed25a9a6656a06a160c Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Mon, 26 Sep 2022 14:42:01 -0700
Subject: [PATCH v3 2/4] autoconf: Don't AC_SUBST() LD in configure

The only use of $(LD) in Makefiles is for AIX, to generate the export file for
the backend. We only support the system linker on AIX and we already hardcode
the path to a number of other binaries. Removing LD substitution will simplify
the upcoming meson PGXS compatibility.

While at it, add a comment why -r is used.

A subsequent commit will remove the determination of LD from configure as
well.

Discussion: https://postgr.es/m/20221005200710.luvw5evhwf6cl...@awork3.anarazel.de
---
 src/backend/Makefile   | 8 +++++++-
 configure              | 2 --
 configure.ac           | 1 -
 src/Makefile.global.in | 3 ---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/backend/Makefile b/src/backend/Makefile
index 181c217fae4..efd4d30a28d 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -100,8 +100,14 @@ ifeq ($(PORTNAME), aix)
 postgres: $(POSTGRES_IMP)
 	$(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(LDFLAGS) $(LDFLAGS_EX) -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) $(LDREL) $(LDOUT) SUBSYS.o $(call expand_subsys,$^)
+	ld -r -o SUBSYS.o $(call expand_subsys,$^)
 	$(MKLDEXPORT) SUBSYS.o . > $@
 	@rm -f SUBSYS.o
 
diff --git a/configure b/configure
index e65ac574fb5..d87b82dea92 100755
--- a/configure
+++ b/configure
@@ -692,7 +692,6 @@ STRIP_SHARED_LIB
 STRIP_STATIC_LIB
 STRIP
 with_gnu_ld
-LD
 LDFLAGS_SL
 LDFLAGS_EX
 ZSTD_LIBS
@@ -9555,7 +9554,6 @@ with_gnu_ld=$ac_cv_prog_gnu_ld
 
 
 
-
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
diff --git a/configure.ac b/configure.ac
index 219e85441d2..77e5bef9e21 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1129,7 +1129,6 @@ AC_ARG_VAR(LDFLAGS_EX, [extra linker flags for linking executables only])
 AC_ARG_VAR(LDFLAGS_SL, [extra linker flags for linking shared libraries only])
 
 PGAC_PROG_LD
-AC_SUBST(LD)
 AC_SUBST(with_gnu_ld)
 PGAC_CHECK_STRIP
 AC_CHECK_TOOL(AR, ar, ar)
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index a5e2f36d217..8107643578b 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -289,7 +289,6 @@ LDAP_LIBS_FE = @LDAP_LIBS_FE@
 LDAP_LIBS_BE = @LDAP_LIBS_BE@
 UUID_LIBS = @UUID_LIBS@
 LLVM_LIBS=@LLVM_LIBS@
-LD = @LD@
 with_gnu_ld = @with_gnu_ld@
 
 # It's critical that within LDFLAGS, all -L switches pointing to build-tree
@@ -316,8 +315,6 @@ LDFLAGS = $(LDFLAGS_INTERNAL) @LDFLAGS@
 LDFLAGS_EX = @LDFLAGS_EX@
 # LDFLAGS_SL might have already been assigned by calling makefile
 LDFLAGS_SL += @LDFLAGS_SL@
-LDREL = -r
-LDOUT = -o
 WINDRES = @WINDRES@
 X = @EXEEXT@
 
-- 
2.38.0

>From 56ed71091633353d42fb9715c02ee6bdd099cf04 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Wed, 12 Oct 2022 17:14:36 -0700
Subject: [PATCH v3 3/4] autoconf: Move export_dynamic determination to
 configure

Previously export_dynamic was set in src/makefiles/Makefile.$port. For solaris
this required exporting with_gnu_ld. The determination of with_gnu_ld would be
nontrivial to copy for meson PGXS compatibility.  It's also nice to delete
libtool.m4.

This uses -Wl,--export-dynamic on all platforms, previously all platforms but
FreeBSD used -Wl,-E. The likelihood of a name conflict seems lower with the
longer spelling.

Discussion: https://postgr.es/m/20221005200710.luvw5evhwf6cl...@awork3.anarazel.de
---
 config/c-compiler.m4           |  25 ++-
 config/libtool.m4              | 119 --------------
 src/makefiles/Makefile.freebsd |   1 -
 src/makefiles/Makefile.linux   |   1 -
 src/makefiles/Makefile.netbsd  |   1 -
 src/makefiles/Makefile.openbsd |   1 -
 src/makefiles/Makefile.solaris |   4 -
 src/backend/Makefile           |  12 +-
 aclocal.m4                     |   1 -
 configure                      | 275 +++++++++++++--------------------
 configure.ac                   |   8 +-
 src/Makefile.global.in         |   2 +-
 12 files changed, 141 insertions(+), 309 deletions(-)
 delete mode 100644 config/libtool.m4

diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index eb8cc8ce170..768df8b9fed 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -468,29 +468,38 @@ AC_DEFUN([PGAC_PROG_CXX_CFLAGS_OPT],
 
 
 
-# PGAC_PROG_CC_LDFLAGS_OPT
+# PGAC_PROG_CC_LD_VARFLAGS_OPT
 # ------------------------
 # Given a string, check if the compiler supports the string as a
-# command-line option. If it does, add the string to LDFLAGS.
+# command-line option. If it does, add to the given variable.
 # For reasons you'd really rather not know about, this checks whether
 # you can link to a particular function, not just whether you can link.
 # In fact, we must actually check that the resulting program runs :-(
-AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
-[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_ldflags_$1])])dnl
-AC_CACHE_CHECK([whether $CC supports $1], [Ac_cachevar],
+AC_DEFUN([PGAC_PROG_CC_LD_VARFLAGS_OPT],
+[define([Ac_cachevar], [AS_TR_SH([pgac_cv_prog_cc_$1_$2])])dnl
+AC_CACHE_CHECK([whether $CC supports $2, for $1], [Ac_cachevar],
 [pgac_save_LDFLAGS=$LDFLAGS
-LDFLAGS="$pgac_save_LDFLAGS $1"
-AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $2 (); void (*fptr) () = $2;],[])],
+LDFLAGS="$pgac_save_LDFLAGS $2"
+AC_RUN_IFELSE([AC_LANG_PROGRAM([extern void $3 (); void (*fptr) () = $3;],[])],
               [Ac_cachevar=yes],
               [Ac_cachevar=no],
               [Ac_cachevar="assuming no"])
 LDFLAGS="$pgac_save_LDFLAGS"])
 if test x"$Ac_cachevar" = x"yes"; then
-  LDFLAGS="$LDFLAGS $1"
+  $1="${$1} $2"
 fi
 undefine([Ac_cachevar])dnl
+])# PGAC_PROG_CC_LD_VARFLAGS_OPT
+
+# PGAC_PROG_CC_LDFLAGS_OPT
+# ------------------------
+# Convenience wrapper around PGAC_PROG_CC_LD_VARFLAGS_OPT that adds to
+# LDFLAGS.
+AC_DEFUN([PGAC_PROG_CC_LDFLAGS_OPT],
+[PGAC_PROG_CC_LD_VARFLAGS_OPT(LDFLAGS, $1, $2)
 ])# PGAC_PROG_CC_LDFLAGS_OPT
 
+
 # PGAC_HAVE_GCC__SYNC_CHAR_TAS
 # ----------------------------
 # Check if the C compiler understands __sync_lock_test_and_set(char),
diff --git a/config/libtool.m4 b/config/libtool.m4
deleted file mode 100644
index f6e426dbdf1..00000000000
--- a/config/libtool.m4
+++ /dev/null
@@ -1,119 +0,0 @@
-## libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
-## Copyright (C) 1996-1999,2000 Free Software Foundation, Inc.
-## Originally by Gordon Matzigkeit <g...@gnu.ai.mit.edu>, 1996
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2 of the License, or
-## (at your option) any later version.
-##
-## This program is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-##
-## As a special exception to the GNU General Public License, if you
-## distribute this file as part of a program that contains a
-## configuration script generated by Autoconf, you may include it under
-## the same distribution terms that you use for the rest of that program.
-
-# No, PostgreSQL doesn't use libtool (yet), we just borrow stuff from it.
-# This file was taken on 2000-10-20 from the multi-language branch (since
-# that is the branch that PostgreSQL would most likely adopt anyway).
-# --petere
-
-# ... bunch of stuff removed here ...
-
-# PGAC_PROG_LD - find the path to the GNU or non-GNU linker
-AC_DEFUN([PGAC_PROG_LD],
-[AC_ARG_WITH(gnu-ld,
-[  --with-gnu-ld           assume the C compiler uses GNU ld [[default=no]]],
-test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-dnl ###not for PostgreSQL### AC_REQUIRE([AC_CANONICAL_BUILD])dnl
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
-  AC_MSG_CHECKING([for ld used by GCC])
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case "$ac_prog" in
-    # Accept absolute paths.
-changequote(,)dnl
-    [\\/]* | [A-Za-z]:[\\/]*)
-      re_direlt='/[^/][^/]*/\.\./'
-changequote([,])dnl
-      # Canonicalize the path of ld
-      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
-      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
-	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
-      ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
-    ;;
-  *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
-    ;;
-  esac
-elif test "$with_gnu_ld" = yes; then
-  AC_MSG_CHECKING([for GNU ld])
-else
-  AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL(ac_cv_path_LD,
-[if test -z "$LD"; then
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      ac_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
-	test "$with_gnu_ld" != no && break
-      else
-	test "$with_gnu_ld" != yes && break
-      fi
-    fi
-  done
-  IFS="$ac_save_ifs"
-else
-  ac_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$ac_cv_path_LD"
-if test -n "$LD"; then
-  AC_MSG_RESULT($LD)
-else
-  AC_MSG_RESULT(no)
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-PGAC_PROG_LD_GNU
-])
-
-AC_DEFUN([PGAC_PROG_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
-if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
-  ac_cv_prog_gnu_ld=yes
-else
-  ac_cv_prog_gnu_ld=no
-fi])
-with_gnu_ld=$ac_cv_prog_gnu_ld
-])
-
-# ... more stuff removed ...
diff --git a/src/makefiles/Makefile.freebsd b/src/makefiles/Makefile.freebsd
index db74a21568c..8a65d781354 100644
--- a/src/makefiles/Makefile.freebsd
+++ b/src/makefiles/Makefile.freebsd
@@ -1,4 +1,3 @@
-export_dynamic = -Wl,-export-dynamic
 rpath = -Wl,-R'$(rpathdir)'
 
 # extra stuff for $(with_temp_install)
diff --git a/src/makefiles/Makefile.linux b/src/makefiles/Makefile.linux
index 5a9451371ab..16d8249a111 100644
--- a/src/makefiles/Makefile.linux
+++ b/src/makefiles/Makefile.linux
@@ -1,4 +1,3 @@
-export_dynamic = -Wl,-E
 # Use --enable-new-dtags to generate DT_RUNPATH instead of DT_RPATH.
 # This allows LD_LIBRARY_PATH to still work when needed.
 rpath = -Wl,-rpath,'$(rpathdir)',--enable-new-dtags
diff --git a/src/makefiles/Makefile.netbsd b/src/makefiles/Makefile.netbsd
index 4f8e9ec2521..eb86e0b76e4 100644
--- a/src/makefiles/Makefile.netbsd
+++ b/src/makefiles/Makefile.netbsd
@@ -1,4 +1,3 @@
-export_dynamic = -Wl,-E
 rpath = -Wl,-R'$(rpathdir)'
 
 
diff --git a/src/makefiles/Makefile.openbsd b/src/makefiles/Makefile.openbsd
index 4f8e9ec2521..eb86e0b76e4 100644
--- a/src/makefiles/Makefile.openbsd
+++ b/src/makefiles/Makefile.openbsd
@@ -1,4 +1,3 @@
-export_dynamic = -Wl,-E
 rpath = -Wl,-R'$(rpathdir)'
 
 
diff --git a/src/makefiles/Makefile.solaris b/src/makefiles/Makefile.solaris
index 3de73ebc010..e2b386ac127 100644
--- a/src/makefiles/Makefile.solaris
+++ b/src/makefiles/Makefile.solaris
@@ -1,10 +1,6 @@
 # src/makefiles/Makefile.solaris
 rpath = -Wl,-rpath,'$(rpathdir)'
 
-ifeq ($(with_gnu_ld), yes)
-export_dynamic = -Wl,-E
-endif
-
 # Rule for building a shared library from a single .o file
 %.so: %.o
 	$(CC) $(CFLAGS) $< $(LDFLAGS) $(LDFLAGS_SL) -shared -o $@
diff --git a/src/backend/Makefile b/src/backend/Makefile
index efd4d30a28d..c8d1de4f103 100644
--- a/src/backend/Makefile
+++ b/src/backend/Makefile
@@ -55,6 +55,8 @@ ifeq ($(with_systemd),yes)
 LIBS += -lsystemd
 endif
 
+override LDFLAGS := $(LDFLAGS) $(LDFLAGS_EX) $(LDFLAGS_EX_BE)
+
 ##########################################################################
 
 all: submake-libpgport submake-catalog-headers submake-utils-headers postgres $(POSTGRES_IMP)
@@ -64,7 +66,7 @@ ifneq ($(PORTNAME), win32)
 ifneq ($(PORTNAME), aix)
 
 postgres: $(OBJS)
-	$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -o $@
+	$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LIBS) -o $@
 
 endif
 endif
@@ -73,7 +75,7 @@ endif
 ifeq ($(PORTNAME), cygwin)
 
 postgres: $(OBJS)
-	$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) -Wl,--stack,$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@
+	$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) -Wl,--stack,$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@
 
 # libpostgres.a is actually built in the preceding rule, but we need this to
 # ensure it's newer than postgres; see notes in src/backend/parser/Makefile
@@ -86,7 +88,7 @@ ifeq ($(PORTNAME), win32)
 LIBS += -lsecur32
 
 postgres: $(OBJS) $(WIN32RES)
-	$(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(WIN32RES) $(LDFLAGS) $(LDFLAGS_EX) -Wl,--stack=$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@$(X)
+	$(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(WIN32RES) $(LDFLAGS) -Wl,--stack=$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(LIBS) -o $@$(X)
 
 # libpostgres.a is actually built in the preceding rule, but we need this to
 # ensure it's newer than postgres; see notes in src/backend/parser/Makefile
@@ -98,7 +100,7 @@ endif # win32
 ifeq ($(PORTNAME), aix)
 
 postgres: $(POSTGRES_IMP)
-	$(CC) $(CFLAGS) $(call expand_subsys,$(OBJS)) $(LDFLAGS) $(LDFLAGS_EX) -Wl,-bE:$(top_builddir)/src/backend/$(POSTGRES_IMP) $(LIBS) -Wl,-brtllib -o $@
+	$(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.
@@ -320,4 +322,4 @@ maintainer-clean: distclean
 # are up to date.  It saves the time of doing all the submakes.
 .PHONY: quick
 quick: $(OBJS)
-	$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LDFLAGS_EX) $(export_dynamic) $(LIBS) -o postgres
+	$(CC) $(CFLAGS) $(call expand_subsys,$^) $(LDFLAGS) $(LIBS) -o postgres
diff --git a/aclocal.m4 b/aclocal.m4
index 1c19c60c596..d05f8f9e3a8 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -4,7 +4,6 @@ m4_include([config/c-compiler.m4])
 m4_include([config/c-library.m4])
 m4_include([config/check_decls.m4])
 m4_include([config/general.m4])
-m4_include([config/libtool.m4])
 m4_include([config/llvm.m4])
 m4_include([config/perl.m4])
 m4_include([config/pkg.m4])
diff --git a/configure b/configure
index d87b82dea92..f0faa1c2e87 100755
--- a/configure
+++ b/configure
@@ -629,6 +629,7 @@ ac_subst_vars='LTLIBOBJS
 vpath_build
 PG_SYSROOT
 PG_VERSION_NUM
+LDFLAGS_EX_BE
 PROVE
 DBTOEPUB
 FOP
@@ -691,7 +692,6 @@ AR
 STRIP_SHARED_LIB
 STRIP_STATIC_LIB
 STRIP
-with_gnu_ld
 LDFLAGS_SL
 LDFLAGS_EX
 ZSTD_LIBS
@@ -870,7 +870,6 @@ with_system_tzdata
 with_zlib
 with_lz4
 with_zstd
-with_gnu_ld
 with_ssl
 with_openssl
 enable_largefile
@@ -1581,7 +1580,6 @@ Optional Packages:
   --without-zlib          do not use Zlib
   --with-lz4              build with LZ4 support
   --with-zstd             build with ZSTD support
-  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-ssl=LIB          use LIB for SSL/TLS support (openssl)
   --with-openssl          obsolete spelling of --with-ssl=openssl
 
@@ -9455,105 +9453,6 @@ LDFLAGS="$LDFLAGS $LIBDIRS"
 
 
 
-# Check whether --with-gnu-ld was given.
-if test "${with_gnu_ld+set}" = set; then :
-  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
-else
-  with_gnu_ld=no
-fi
-
-ac_prog=ld
-if test "$GCC" = yes; then
-  # Check if gcc -print-prog-name=ld gives a path.
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5
-$as_echo_n "checking for ld used by GCC... " >&6; }
-  case $host in
-  *-*-mingw*)
-    # gcc leaves a trailing carriage return which upsets mingw
-    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
-  *)
-    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
-  esac
-  case "$ac_prog" in
-    # Accept absolute paths.
-    [\\/]* | [A-Za-z]:[\\/]*)
-      re_direlt='/[^/][^/]*/\.\./'
-      # Canonicalize the path of ld
-      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
-      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
-	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
-      done
-      test -z "$LD" && LD="$ac_prog"
-      ;;
-  "")
-    # If it fails, then pretend we aren't using GCC.
-    ac_prog=ld
-    ;;
-  *)
-    # If it is relative, then search for the first ld in PATH.
-    with_gnu_ld=unknown
-    ;;
-  esac
-elif test "$with_gnu_ld" = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
-$as_echo_n "checking for GNU ld... " >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
-$as_echo_n "checking for non-GNU ld... " >&6; }
-fi
-if ${ac_cv_path_LD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$LD"; then
-  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
-  for ac_dir in $PATH; do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
-      ac_cv_path_LD="$ac_dir/$ac_prog"
-      # Check to see if the program is GNU ld.  I'd rather use --version,
-      # but apparently some GNU ld's only accept -v.
-      # Break only if it was the GNU/non-GNU ld that we prefer.
-      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
-	test "$with_gnu_ld" != no && break
-      else
-	test "$with_gnu_ld" != yes && break
-      fi
-    fi
-  done
-  IFS="$ac_save_ifs"
-else
-  ac_cv_path_LD="$LD" # Let the user override the test with a path.
-fi
-fi
-
-LD="$ac_cv_path_LD"
-if test -n "$LD"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
-$as_echo "$LD" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
-$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if ${ac_cv_prog_gnu_ld+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
-if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
-  ac_cv_prog_gnu_ld=yes
-else
-  ac_cv_prog_gnu_ld=no
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gnu_ld" >&5
-$as_echo "$ac_cv_prog_gnu_ld" >&6; }
-with_gnu_ld=$ac_cv_prog_gnu_ld
-
-
-
-
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
@@ -19069,19 +18968,19 @@ else
 fi
 
 if test "$PORTNAME" = "darwin"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,-dead_strip_dylibs" >&5
-$as_echo_n "checking whether $CC supports -Wl,-dead_strip_dylibs... " >&6; }
-if ${pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl, for LDFLAGS" >&5
+$as_echo_n "checking whether $CC supports -Wl, for LDFLAGS... " >&6; }
+if ${pgac_cv_prog_cc_LDFLAGS__Wl+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   pgac_save_LDFLAGS=$LDFLAGS
-LDFLAGS="$pgac_save_LDFLAGS -Wl,-dead_strip_dylibs"
+LDFLAGS="$pgac_save_LDFLAGS -Wl"
 if test "$cross_compiling" = yes; then :
-  pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs="assuming no"
+  pgac_cv_prog_cc_LDFLAGS__Wl="assuming no"
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-extern void $link_test_func (); void (*fptr) () = $link_test_func;
+extern void -dead_strip_dylibs (); void (*fptr) () = -dead_strip_dylibs;
 int
 main ()
 {
@@ -19091,9 +18990,9 @@ main ()
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-  pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs=yes
+  pgac_cv_prog_cc_LDFLAGS__Wl=yes
 else
-  pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs=no
+  pgac_cv_prog_cc_LDFLAGS__Wl=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
@@ -19101,22 +19000,107 @@ fi
 
 LDFLAGS="$pgac_save_LDFLAGS"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs" >&5
-$as_echo "$pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs" >&6; }
-if test x"$pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs" = x"yes"; then
-  LDFLAGS="$LDFLAGS -Wl,-dead_strip_dylibs"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS__Wl" >&5
+$as_echo "$pgac_cv_prog_cc_LDFLAGS__Wl" >&6; }
+if test x"$pgac_cv_prog_cc_LDFLAGS__Wl" = x"yes"; then
+  LDFLAGS="${LDFLAGS} -Wl"
 fi
 
+
 elif test "$PORTNAME" = "openbsd"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,-Bdynamic" >&5
-$as_echo_n "checking whether $CC supports -Wl,-Bdynamic... " >&6; }
-if ${pgac_cv_prog_cc_ldflags__Wl__Bdynamic+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl, for LDFLAGS" >&5
+$as_echo_n "checking whether $CC supports -Wl, for LDFLAGS... " >&6; }
+if ${pgac_cv_prog_cc_LDFLAGS__Wl+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   pgac_save_LDFLAGS=$LDFLAGS
-LDFLAGS="$pgac_save_LDFLAGS -Wl,-Bdynamic"
+LDFLAGS="$pgac_save_LDFLAGS -Wl"
 if test "$cross_compiling" = yes; then :
-  pgac_cv_prog_cc_ldflags__Wl__Bdynamic="assuming no"
+  pgac_cv_prog_cc_LDFLAGS__Wl="assuming no"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+extern void -Bdynamic (); void (*fptr) () = -Bdynamic;
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  pgac_cv_prog_cc_LDFLAGS__Wl=yes
+else
+  pgac_cv_prog_cc_LDFLAGS__Wl=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+LDFLAGS="$pgac_save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS__Wl" >&5
+$as_echo "$pgac_cv_prog_cc_LDFLAGS__Wl" >&6; }
+if test x"$pgac_cv_prog_cc_LDFLAGS__Wl" = x"yes"; then
+  LDFLAGS="${LDFLAGS} -Wl"
+fi
+
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl, for LDFLAGS" >&5
+$as_echo_n "checking whether $CC supports -Wl, for LDFLAGS... " >&6; }
+if ${pgac_cv_prog_cc_LDFLAGS__Wl+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  pgac_save_LDFLAGS=$LDFLAGS
+LDFLAGS="$pgac_save_LDFLAGS -Wl"
+if test "$cross_compiling" = yes; then :
+  pgac_cv_prog_cc_LDFLAGS__Wl="assuming no"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+extern void --as-needed (); void (*fptr) () = --as-needed;
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  pgac_cv_prog_cc_LDFLAGS__Wl=yes
+else
+  pgac_cv_prog_cc_LDFLAGS__Wl=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+LDFLAGS="$pgac_save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS__Wl" >&5
+$as_echo "$pgac_cv_prog_cc_LDFLAGS__Wl" >&6; }
+if test x"$pgac_cv_prog_cc_LDFLAGS__Wl" = x"yes"; then
+  LDFLAGS="${LDFLAGS} -Wl"
+fi
+
+
+fi
+
+# For linkers that understand --export-dynamic, add that to the LDFLAGS_EX_BE
+# (backend specific ldflags). One some platforms this will always fail (e.g.,
+# windows), but on others it depends on the choice of linker (e.g., solaris).
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,--export-dynamic, for LDFLAGS_EX_BE" >&5
+$as_echo_n "checking whether $CC supports -Wl,--export-dynamic, for LDFLAGS_EX_BE... " >&6; }
+if ${pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  pgac_save_LDFLAGS=$LDFLAGS
+LDFLAGS="$pgac_save_LDFLAGS -Wl,--export-dynamic"
+if test "$cross_compiling" = yes; then :
+  pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic="assuming no"
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -19130,9 +19114,9 @@ main ()
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-  pgac_cv_prog_cc_ldflags__Wl__Bdynamic=yes
+  pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic=yes
 else
-  pgac_cv_prog_cc_ldflags__Wl__Bdynamic=no
+  pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
@@ -19140,52 +19124,13 @@ fi
 
 LDFLAGS="$pgac_save_LDFLAGS"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_ldflags__Wl__Bdynamic" >&5
-$as_echo "$pgac_cv_prog_cc_ldflags__Wl__Bdynamic" >&6; }
-if test x"$pgac_cv_prog_cc_ldflags__Wl__Bdynamic" = x"yes"; then
-  LDFLAGS="$LDFLAGS -Wl,-Bdynamic"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic" >&5
+$as_echo "$pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic" >&6; }
+if test x"$pgac_cv_prog_cc_LDFLAGS_EX_BE__Wl___export_dynamic" = x"yes"; then
+  LDFLAGS_EX_BE="${LDFLAGS_EX_BE} -Wl,--export-dynamic"
 fi
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,--as-needed" >&5
-$as_echo_n "checking whether $CC supports -Wl,--as-needed... " >&6; }
-if ${pgac_cv_prog_cc_ldflags__Wl___as_needed+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  pgac_save_LDFLAGS=$LDFLAGS
-LDFLAGS="$pgac_save_LDFLAGS -Wl,--as-needed"
-if test "$cross_compiling" = yes; then :
-  pgac_cv_prog_cc_ldflags__Wl___as_needed="assuming no"
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-extern void $link_test_func (); void (*fptr) () = $link_test_func;
-int
-main ()
-{
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  pgac_cv_prog_cc_ldflags__Wl___as_needed=yes
-else
-  pgac_cv_prog_cc_ldflags__Wl___as_needed=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-LDFLAGS="$pgac_save_LDFLAGS"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_cc_ldflags__Wl___as_needed" >&5
-$as_echo "$pgac_cv_prog_cc_ldflags__Wl___as_needed" >&6; }
-if test x"$pgac_cv_prog_cc_ldflags__Wl___as_needed" = x"yes"; then
-  LDFLAGS="$LDFLAGS -Wl,--as-needed"
-fi
-
-fi
 
 # Create compiler version string
 if test x"$GCC" = x"yes" ; then
@@ -19872,7 +19817,7 @@ PostgreSQL config.status 16devel
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C)  Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
diff --git a/configure.ac b/configure.ac
index 77e5bef9e21..723fb736038 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1128,8 +1128,6 @@ LDFLAGS="$LDFLAGS $LIBDIRS"
 AC_ARG_VAR(LDFLAGS_EX, [extra linker flags for linking executables only])
 AC_ARG_VAR(LDFLAGS_SL, [extra linker flags for linking shared libraries only])
 
-PGAC_PROG_LD
-AC_SUBST(with_gnu_ld)
 PGAC_CHECK_STRIP
 AC_CHECK_TOOL(AR, ar, ar)
 if test "$PORTNAME" = "win32"; then
@@ -2368,6 +2366,12 @@ else
   PGAC_PROG_CC_LDFLAGS_OPT([-Wl,--as-needed], $link_test_func)
 fi
 
+# For linkers that understand --export-dynamic, add that to the LDFLAGS_EX_BE
+# (backend specific ldflags). One some platforms this will always fail (e.g.,
+# windows), but on others it depends on the choice of linker (e.g., solaris).
+PGAC_PROG_CC_LD_VARFLAGS_OPT(LDFLAGS_EX_BE, [-Wl,--export-dynamic], $link_test_func)
+AC_SUBST(LDFLAGS_EX_BE)
+
 # Create compiler version string
 if test x"$GCC" = x"yes" ; then
   cc_string=`${CC} --version | sed q`
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 8107643578b..0d3c3e117fd 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -289,7 +289,6 @@ LDAP_LIBS_FE = @LDAP_LIBS_FE@
 LDAP_LIBS_BE = @LDAP_LIBS_BE@
 UUID_LIBS = @UUID_LIBS@
 LLVM_LIBS=@LLVM_LIBS@
-with_gnu_ld = @with_gnu_ld@
 
 # It's critical that within LDFLAGS, all -L switches pointing to build-tree
 # directories come before any -L switches pointing to external directories.
@@ -313,6 +312,7 @@ endif
 LDFLAGS = $(LDFLAGS_INTERNAL) @LDFLAGS@
 
 LDFLAGS_EX = @LDFLAGS_EX@
+LDFLAGS_EX_BE = @LDFLAGS_EX_BE@
 # LDFLAGS_SL might have already been assigned by calling makefile
 LDFLAGS_SL += @LDFLAGS_SL@
 WINDRES = @WINDRES@
-- 
2.38.0

>From f672bd8765a45e6bcaca9400ddec3afcc471d854 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Wed, 24 Aug 2022 20:27:17 -0700
Subject: [PATCH v3 4/4] meson: Add PGXS compatibility

This works for some extensions on some operating systems, but could use plenty
of cleanups.

Discussion: https://postgr.es/m/20221005200710.luvw5evhwf6cl...@awork3.anarazel.de
---
 src/makefiles/meson.build | 257 ++++++++++++++++++++++++++++++++++++++
 meson_options.txt         |   3 +
 src/meson.build           |  37 ++++++
 3 files changed, 297 insertions(+)
 create mode 100644 src/makefiles/meson.build

diff --git a/src/makefiles/meson.build b/src/makefiles/meson.build
new file mode 100644
index 00000000000..a2c494fdccc
--- /dev/null
+++ b/src/makefiles/meson.build
@@ -0,0 +1,257 @@
+### Compute pgxs_data, used in src/meson.build to generate Makefile.global
+### etc, that's complete enough for PGXS to work.
+
+
+# Emulation of PGAC_CHECK_STRIP
+strip_bin = find_program(get_option('STRIP'), required: false, native: true)
+strip_cmd = strip_bin.found() ? [strip_bin.path()] : [':']
+
+working_strip = false
+if strip_bin.found()
+  strip_version = run_command(strip_bin, '-V', check: false)
+
+  if strip_version.returncode() == 0 and (
+      strip_version.stdout().contains('GNU strip') or
+      strip_version.stderr().contains('GNU strip'))
+    working_strip = true
+    strip_static_cmd = strip_cmd + ['-x']
+    strip_shared_cmd = strip_cmd + ['--strip-unneeded']
+  elif host_system == 'darwin'
+    working_strip = true
+    strip_static_cmd = strip_cmd + ['-x']
+    strip_shared_cmd = strip_cmd + ['-x']
+  endif
+endif
+
+if not working_strip
+  strip_cmd = [':']
+  strip_static_cmd = [':']
+  strip_shared_cmd = [':']
+endif
+
+
+pgxs_kv = {
+  'PACKAGE_URL': pg_url,
+  'PACKAGE_VERSION': pg_version,
+  'PG_MAJORVERSION': pg_version_major,
+  'PG_VERSION_NUM': pg_version_num,
+  'configure_input': 'meson',
+
+  'vpath_build': 'yes',
+  'autodepend': cc.get_argument_syntax() == 'gcc' ? 'yes' : 'no',
+
+  'host_cpu': host_cpu,
+  'host': '@0@-@1@'.format(host_cpu, host_system),
+  'host_os': host_system,
+  'build_os': build_machine.system(),
+  'PORTNAME': portname,
+  'PG_SYSROOT': pg_sysroot,
+
+  'abs_top_builddir': meson.build_root(),
+  'abs_top_srcdir': meson.source_root(),
+
+  'enable_thread_safety': 'yes',
+  'enable_rpath': 'yes',
+  'enable_nls': libintl.found() ? 'yes' : 'no',
+  'enable_tap_tests': tap_tests_enabled ? 'yes' : 'no',
+  'enable_debug': get_option('debug') ? 'yes' : 'no',
+  'enable_coverage': 'no',
+  'enable_dtrace': dtrace.found() ? 'yes' : 'no',
+
+  'DLSUFFIX': dlsuffix,
+  'EXEEXT': exesuffix,
+
+  'SUN_STUDIO_CC': 'no', # not supported so far
+
+  # want the chosen option, rather than the library
+  'with_ssl' : get_option('ssl'),
+  'with_uuid': uuidopt,
+
+  'default_port': get_option('pgport'),
+  'with_system_tzdata': get_option('system_tzdata'),
+
+  'with_krb_srvnam': get_option('krb_srvnam'),
+  'krb_srvtab': krb_srvtab,
+
+  'STRIP': ' '.join(strip_cmd),
+  'STRIP_STATIC_LIB': ' '.join(strip_static_cmd),
+  'STRIP_SHARED_LIB': ' '.join(strip_shared_cmd),
+
+  # Just always use the install_sh fallback that autoconf uses. Unlikely to
+  # matter performance-wise for extensions. If it turns out to do, we can
+  # improve that later.
+  'MKDIR_P': ' '.join([install_sh.path(), '-d']),
+
+  'CC': var_cc,
+  'CPP': var_cpp,
+  'GCC': cc.get_argument_syntax() == 'gcc' ? 'yes' : 'no',
+
+  'CPPFLAGS': var_cppflags,
+  'CFLAGS': var_cflags,
+  'CXXFLAGS': var_cxxflags,
+  'CFLAGS_SL': var_cflags_sl,
+  'CFLAGS_SL_MODULE': ' '.join(cflags_mod),
+  'CXXFLAGS_SL_MODULE': ' '.join(cxxflags_mod),
+
+  'CFLAGS_CRC': ' '.join(cflags_crc),
+  'CFLAGS_UNROLL_LOOPS': ' '.join(unroll_loops_cflags),
+  'CFLAGS_VECTORIZE': ' '.join(vectorize_cflags),
+
+  'LDFLAGS': var_ldflags,
+  'LDFLAGS_EX': var_ldflags_ex,
+  'LDFLAGS_EX_BE': ' '.join(cc.get_supported_link_arguments('-Wl,--export-dynamic')),
+  'LDFLAGS_SL': var_ldflags_sl,
+
+  # TODO: requires bitcode generation to be implemented for meson
+  'BITCODE_CFLAGS': '',
+  'BITCODE_CXXFLAGS': '',
+
+  'BISONFLAGS': ' '.join(bison_flags),
+  'FLEXFLAGS': ' '.join(flex_flags),
+
+  'LIBS': var_libs,
+}
+
+if llvm.found()
+  pgxs_kv += {
+    'CLANG': clang.path(),
+    'CXX': ' '.join(cpp.cmd_array()),
+    'LLVM_BINPATH': llvm_binpath,
+  }
+else
+  pgxs_kv += {
+    'CLANG': '',
+    'CXX': '',
+    'LLVM_BINPATH': '',
+  }
+endif
+
+pgxs_bins = {
+  'BISON': bison,
+  'FLEX': flex,
+  'GZIP': gzip,
+  'LZ4': program_lz4,
+  'PERL': perl,
+  'PROVE': prove,
+  'PYTHON': python,
+  'TAR': tar,
+  'ZSTD': program_zstd,
+  'DTRACE': dtrace,
+  'install_bin': install_sh,
+}
+
+pgxs_empty = [
+  'PERMIT_DECLARATION_AFTER_STATEMENT',
+  'ICU_CFLAGS', # needs to be added, included by public server headers
+
+  # probably need most of these?
+  'LN_S',
+  'AR',
+  'AWK',
+
+  # hard to see why we'd need either?
+  'ZIC',
+  'TCLSH',
+
+  # docs don't seem to be supported by pgxs
+  'XMLLINT',
+  'XSLTPROC',
+  'DBTOEPUB',
+  'FOP',
+
+  # supporting coverage for pgxs-in-meson build doesn't seem worth it
+  'GENHTML',
+  'LCOV',
+  'GCOV',
+  'MSGFMT_FLAGS',
+
+  # translation doesn't appear to be supported by pgxs
+  'MSGFMT',
+  'XGETTEXT',
+  'MSGMERGE',
+  'WANTED_LANGUAGES',
+
+  # Not needed because we don't build the server / PLs with the generated makefile
+  'LIBOBJS', 'PG_CRC32C_OBJS', 'TAS',
+  'DTRACEFLAGS', # only server has dtrace probes
+
+  'perl_archlibexp', 'perl_embed_ccflags', 'perl_embed_ldflags', 'perl_includespec', 'perl_privlibexp',
+  'python_additional_libs', 'python_includespec', 'python_libdir', 'python_libspec', 'python_majorversion', 'python_version',
+
+  # possible that some of these are referenced explicitly in pgxs makefiles?
+  # For now not worth it.
+  'TCL_INCLUDE_SPEC', 'TCL_LIBS', 'TCL_LIB_SPEC', 'TCL_SHARED_BUILD',
+
+  'LLVM_CFLAGS', 'LLVM_CPPFLAGS', 'LLVM_CXXFLAGS', 'LLVM_LIBS',
+
+  'LDAP_LIBS_BE', 'LDAP_LIBS_FE',
+
+  'UUID_LIBS',
+
+  'PTHREAD_CFLAGS', 'PTHREAD_LIBS',
+
+  'ICU_LIBS',
+]
+
+if host_system == 'windows' and cc.get_argument_syntax() != 'msvc'
+  pgxs_bins += {'WINDRES': windres}
+else
+  pgxs_empty += 'WINDRES'
+endif
+
+pgxs_dirs = {
+  'prefix': get_option('prefix'),
+
+  'bindir': '${exec_prefix}' / get_option('bindir'),
+  'datarootdir': '${prefix}' / get_option('datadir'),
+  'datadir': '${datarootdir}',
+  'docdir': '${prefix}' / dir_doc,
+  'exec_prefix': '${prefix}',
+  'htmldir': '${prefix}' / dir_doc_html, #?
+  'includedir': '${prefix}' / get_option('includedir'),
+  'libdir': '${exec_prefix}' / get_option('libdir'),
+  'localedir': '${prefix}' / get_option('localedir'),
+  'mandir': '${prefix}' / get_option('mandir'),
+  'sysconfdir': '${prefix}' / get_option('sysconfdir'),
+}
+
+pgxs_deps = {
+  'bonjour': bonjour,
+  'bsd_auth': bsd_auth,
+  'gssapi': gssapi,
+  'icu': icu,
+  'ldap': ldap,
+  'libxml': libxml,
+  'libxslt': libxslt,
+  'llvm': llvm,
+  'lz4': lz4,
+  'nls': libintl,
+  'pam': pam,
+  'perl': perl_dep,
+  'python': python3_dep,
+  'readline': readline,
+  'selinux': selinux,
+  'systemd': systemd,
+  'tcl': tcl_dep,
+  'zlib': zlib,
+  'zstd': zstd,
+}
+
+
+pgxs_cdata = configuration_data(pgxs_kv)
+
+foreach b, p : pgxs_bins
+  pgxs_cdata.set(b, p.found() ? p.path() : '')
+endforeach
+
+foreach pe : pgxs_empty
+  pgxs_cdata.set(pe, '')
+endforeach
+
+foreach d, p : pgxs_dirs
+  pgxs_cdata.set(d, p)
+endforeach
+
+foreach d, v : pgxs_deps
+  pgxs_cdata.set('with_@0@'.format(d), v.found() ? 'yes' : 'no')
+endforeach
diff --git a/meson_options.txt b/meson_options.txt
index b629cd8d689..c69fe5691b4 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -169,6 +169,9 @@ option('PYTHON', type : 'array', value: ['python3', 'python'],
 option('SED', type : 'string', value: 'gsed',
   description: 'path to sed binary')
 
+option('STRIP', type : 'string', value: 'strip',
+  description: 'path to strip binary, used for PGXS emulation')
+
 option('TAR', type : 'string', value: 'tar',
   description: 'path to tar binary')
 
diff --git a/src/meson.build b/src/meson.build
index b515af15bfa..654c0edfc3c 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -10,3 +10,40 @@ subdir('bin')
 subdir('pl')
 
 subdir('interfaces')
+
+
+### Generate a Makefile.global that's complete enough for PGXS to work.
+#
+# This is somewhat ugly, but allows extensions to use a single buildsystem
+# across all the supported postgres versions. Once all supported PG versions
+# support meson, we can remove all of this.
+#
+# XXX: Should we make this optional?
+
+# pgxs_cdata is built in makefiles/meson.build, but some of the generated
+# files are output into src/
+subdir('makefiles')
+
+makefile_global = configure_file(
+  input: 'Makefile.global.in',
+  output: 'Makefile.global',
+  configuration: pgxs_cdata,
+  install: true,
+  install_dir: dir_pgxs / 'src',
+)
+configure_files += makefile_global
+
+makefile_port = configure_file(
+  input: 'makefiles' / 'Makefile.@0@'.format(portname),
+  output: 'Makefile.port',
+  copy: true,
+  install_dir: dir_pgxs / 'src')
+configure_files += makefile_port
+
+install_data(
+  'Makefile.shlib', 'nls-global.mk',
+  install_dir: dir_pgxs / 'src')
+
+install_data(
+  'makefiles/pgxs.mk',
+  install_dir: dir_pgxs / 'src' / 'makefiles')
-- 
2.38.0

Reply via email to