Hi,

On 2022-12-01 08:43:19 +0100, Peter Eisentraut wrote:
> On 13.10.22 07:23, Andres Freund wrote:
> > > > 0005: meson: Add PGXS compatibility
> > > > 
> > > >     The actual meson PGXS compatibility. Plenty more replacements to 
> > > > do, but
> > > >     suffices to build common extensions on a few platforms.
> > > > 
> > > >     What level of completeness do we want to require here?
> > > 
> > > I have tried this with a few extensions.  Seems to work alright.  I don't
> > > think we need to overthink this.  The way it's set up, if someone needs
> > > additional variables set, they can easily be added.
> > 
> > Yea, I am happy enough with it now that the bulk is out of src/meson.build 
> > and
> > strip isn't set to an outright wrong value.
> 
> How are you planning to proceed with this?  I thought it was ready, but it
> hasn't moved in a while.

I basically was hoping for a review of the prerequisite patches I posted at
[1], particularly 0003 (different approach than before, comparatively large).

Here's an updated version of the patches. There was a stupid copy-paste bug in
the prior version of the 0003 / export_dynamic patch.

I'll push 0001, 0002 shortly. I don't think 0002 is the most elegant approach,
but it's not awful. I'd still like some review for 0003, but will try to push
it in a few days if that's not forthcoming.

Greetings,

Andres Freund

[1] 
https://www.postgresql.org/message-id/20221013051648.ufz7ud2b5tioctyt%40awork3.anarazel.de
>From 53b4063ff6230963ee60122d47b154f91990d097 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Wed, 5 Oct 2022 12:24:14 -0700
Subject: [PATCH v4 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.

This simplifies the upcoming meson PGXS compatibility.

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

diff --git a/configure.ac b/configure.ac
index f76b7ee31fc..6e7c8e09411 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2091,12 +2091,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.
@@ -2110,12 +2109,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.
 #
@@ -2144,7 +2144,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/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/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/configure b/configure
index 3966368b8d9..f62fbc5d0f5 100755
--- a/configure
+++ b/configure
@@ -645,8 +645,7 @@ MSGMERGE
 MSGFMT_FLAGS
 MSGFMT
 PG_CRC32C_OBJS
-CFLAGS_ARMV8_CRC32C
-CFLAGS_SSE42
+CFLAGS_CRC
 LIBOBJS
 OPENSSL
 ZSTD
@@ -17957,7 +17956,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 :
@@ -17992,7 +17991,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
 
@@ -18031,13 +18030,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
@@ -18064,7 +18062,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 :
@@ -18101,7 +18099,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
 
@@ -18142,13 +18140,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
@@ -18176,7 +18175,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 84e72e99278..346b73260fc 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 8c8206c33e937a36749f88c2d7a9f1037cfa7899 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Mon, 26 Sep 2022 14:42:01 -0700
Subject: [PATCH v4 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
---
 configure.ac           | 1 -
 src/backend/Makefile   | 8 +++++++-
 configure              | 2 --
 src/Makefile.global.in | 3 ---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/configure.ac b/configure.ac
index 6e7c8e09411..61e6da6eb37 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1132,7 +1132,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/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 f62fbc5d0f5..4b24e36a93b 100755
--- a/configure
+++ b/configure
@@ -693,7 +693,6 @@ STRIP_SHARED_LIB
 STRIP_STATIC_LIB
 STRIP
 with_gnu_ld
-LD
 LDFLAGS_SL
 LDFLAGS_EX
 ZSTD_LIBS
@@ -9645,7 +9644,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/src/Makefile.global.in b/src/Makefile.global.in
index 346b73260fc..6ee0f513018 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 d50c8452ddf47c08e65e81e2974d78b0cf8485f2 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Wed, 12 Oct 2022 17:14:36 -0700
Subject: [PATCH v4 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
---
 configure.ac                   |   8 +-
 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 +-
 configure                      | 209 ++++++++++++---------------------
 aclocal.m4                     |   1 -
 src/Makefile.global.in         |   2 +-
 12 files changed, 108 insertions(+), 276 deletions(-)
 delete mode 100644 config/libtool.m4

diff --git a/configure.ac b/configure.ac
index 61e6da6eb37..0df13e5439f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1131,8 +1131,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
@@ -2372,6 +2370,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/config/c-compiler.m4 b/config/c-compiler.m4
index eb8cc8ce170..5be8f0f08dc 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/configure b/configure
index 4b24e36a93b..650755a6b1a 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
@@ -692,7 +693,6 @@ AR
 STRIP_SHARED_LIB
 STRIP_STATIC_LIB
 STRIP
-with_gnu_ld
 LDFLAGS_SL
 LDFLAGS_EX
 ZSTD_LIBS
@@ -871,7 +871,6 @@ with_system_tzdata
 with_zlib
 with_lz4
 with_zstd
-with_gnu_ld
 with_ssl
 with_openssl
 enable_largefile
@@ -1582,7 +1581,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
 
@@ -9545,105 +9543,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
@@ -19213,15 +19112,15 @@ 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,-dead_strip_dylibs, for LDFLAGS" >&5
+$as_echo_n "checking whether $CC supports -Wl,-dead_strip_dylibs, for LDFLAGS... " >&6; }
+if ${pgac_cv_prog_cc_LDFLAGS__Wl__dead_strip_dylibs+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   pgac_save_LDFLAGS=$LDFLAGS
 LDFLAGS="$pgac_save_LDFLAGS -Wl,-dead_strip_dylibs"
 if test "$cross_compiling" = yes; then :
-  pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs="assuming no"
+  pgac_cv_prog_cc_LDFLAGS__Wl__dead_strip_dylibs="assuming no"
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -19235,9 +19134,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__dead_strip_dylibs=yes
 else
-  pgac_cv_prog_cc_ldflags__Wl__dead_strip_dylibs=no
+  pgac_cv_prog_cc_LDFLAGS__Wl__dead_strip_dylibs=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
@@ -19245,22 +19144,23 @@ 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__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"
 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,-Bdynamic, for LDFLAGS" >&5
+$as_echo_n "checking whether $CC supports -Wl,-Bdynamic, for LDFLAGS... " >&6; }
+if ${pgac_cv_prog_cc_LDFLAGS__Wl__Bdynamic+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   pgac_save_LDFLAGS=$LDFLAGS
 LDFLAGS="$pgac_save_LDFLAGS -Wl,-Bdynamic"
 if test "$cross_compiling" = yes; then :
-  pgac_cv_prog_cc_ldflags__Wl__Bdynamic="assuming no"
+  pgac_cv_prog_cc_LDFLAGS__Wl__Bdynamic="assuming no"
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -19274,9 +19174,9 @@ main ()
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-  pgac_cv_prog_cc_ldflags__Wl__Bdynamic=yes
+  pgac_cv_prog_cc_LDFLAGS__Wl__Bdynamic=yes
 else
-  pgac_cv_prog_cc_ldflags__Wl__Bdynamic=no
+  pgac_cv_prog_cc_LDFLAGS__Wl__Bdynamic=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
   conftest.$ac_objext conftest.beam conftest.$ac_ext
@@ -19284,22 +19184,23 @@ 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__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"
 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 "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wl,--as-needed, for LDFLAGS" >&5
+$as_echo_n "checking whether $CC supports -Wl,--as-needed, for LDFLAGS... " >&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"
+  pgac_cv_prog_cc_LDFLAGS__Wl___as_needed="assuming no"
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -19313,9 +19214,9 @@ main ()
 }
 _ACEOF
 if ac_fn_c_try_run "$LINENO"; then :
-  pgac_cv_prog_cc_ldflags__Wl___as_needed=yes
+  pgac_cv_prog_cc_LDFLAGS__Wl___as_needed=yes
 else
-  pgac_cv_prog_cc_ldflags__Wl___as_needed=no
+  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
@@ -19323,14 +19224,58 @@ 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"
+{ $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
 
+# 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.  */
+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_EX_BE__Wl___export_dynamic=yes
+else
+  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
+fi
+
+LDFLAGS="$pgac_save_LDFLAGS"
+fi
+{ $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
+
+
+
 # Create compiler version string
 if test x"$GCC" = x"yes" ; then
   cc_string=`${CC} --version | sed q`
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/src/Makefile.global.in b/src/Makefile.global.in
index 6ee0f513018..fb3e197fc06 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 2fde18729ff57efbd0704aa6f1df37226a792cd7 Mon Sep 17 00:00:00 2001
From: Andres Freund <and...@anarazel.de>
Date: Wed, 24 Aug 2022 20:27:17 -0700
Subject: [PATCH v4 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
---
 meson.build               |   8 +-
 meson_options.txt         |   3 +
 src/makefiles/meson.build | 260 ++++++++++++++++++++++++++++++++++++++
 src/include/meson.build   |  10 +-
 src/common/meson.build    |   4 +-
 src/meson.build           |  37 ++++++
 6 files changed, 311 insertions(+), 11 deletions(-)
 create mode 100644 src/makefiles/meson.build

diff --git a/meson.build b/meson.build
index 725e10d815c..c0c83212521 100644
--- a/meson.build
+++ b/meson.build
@@ -333,9 +333,6 @@ program_zstd = find_program(get_option('ZSTD'), native: true, required: false)
 dtrace = find_program(get_option('DTRACE'), native: true, required: get_option('dtrace'))
 missing = find_program('config/missing', native: true)
 
-# used by PGXS
-install_sh = find_program('config/install-sh', native: true)
-
 bison_flags = []
 if bison.found()
   bison_version_c = run_command(bison, '--version', check: true)
@@ -1737,11 +1734,10 @@ endif
 
 # A few places with imported code get a pass on -Wdeclaration-after-statement, remember
 # the result for them
+cflags_no_decl_after_statement = []
 if cc.has_argument('-Wdeclaration-after-statement')
   cflags_warn += '-Wdeclaration-after-statement'
-  using_declaration_after_statement_warning = true
-else
-  using_declaration_after_statement_warning = false
+  cflags_no_decl_after_statement += '-Wno-declaration-after-statement'
 endif
 
 
diff --git a/meson_options.txt b/meson_options.txt
index c7ea57994dc..2c871969f52 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -172,6 +172,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/makefiles/meson.build b/src/makefiles/meson.build
new file mode 100644
index 00000000000..3bcb0dc0304
--- /dev/null
+++ b/src/makefiles/meson.build
@@ -0,0 +1,260 @@
+### 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),
+
+  # these seem to be standard these days
+  'MKDIR_P': 'mkdir -p',
+  'LN_S': 'ln -s',
+  # 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
+  'install_bin': '$(SHELL) $(top_srcdir)/config/install-sh -c',
+
+  '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),
+  'PERMIT_DECLARATION_AFTER_STATEMENT':
+    ' '.join(cflags_no_decl_after_statement),
+
+  '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 = {
+  'AR':
+    find_program(['ar'], native: true, required: false),
+  'AWK':
+    find_program(['gawk', 'mawk', 'nawk', 'awk'], native: true, required: false),
+  'BISON': bison,
+  'FLEX': flex,
+  'GZIP': gzip,
+  'LZ4': program_lz4,
+  'OPENSSL': openssl,
+  'PERL': perl,
+  'PROVE': prove,
+  'PYTHON': python,
+  'TAR': tar,
+  'ZSTD': program_zstd,
+  'DTRACE': dtrace,
+}
+
+pgxs_empty = [
+  'ICU_CFLAGS', # needs to be added, included by public server headers
+
+  # 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': '${docdir}',
+  '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/src/include/meson.build b/src/include/meson.build
index 35c06c4856a..0b15919bb87 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -49,8 +49,14 @@ else
   var_cxxflags = ''
 endif
 var_cppflags = ' '.join(cppflags)
-var_cflags_sl = '-fPIC' #FIXME
-var_ldflags = ' '.join(ldflags + get_option('c_link_args'))
+var_cflags_sl = ' '.join(cc.get_supported_arguments('-fPIC'))
+# explicitly add -Wl,--as-needed, normally added by meson, but we want it for
+# PGXS compatibility
+var_ldflags = ' '.join(
+  ldflags
+  + cc.get_supported_link_arguments('-Wl,--as-needed')
+  + get_option('c_link_args')
+)
 var_ldflags_sl = ''.join(ldflags_sl)
 var_ldflags_ex = '' # FIXME
 # FIXME - some extensions might directly use symbols from one of libs. If
diff --git a/src/common/meson.build b/src/common/meson.build
index 1c9b8a3a018..f69d75e9c6e 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -64,9 +64,7 @@ ryu_sources = files(
 )
 ryu_cflags = []
 
-if using_declaration_after_statement_warning
-  ryu_cflags += ['-Wno-declaration-after-statement']
-endif
+ryu_cflags += cflags_no_decl_after_statement
 
 config_info_sources = files('config_info.c',)
 config_info_cflags = [
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