diff --git a/configure b/configure
index 542bf7355fda821066fcb4ca03162f374391ab93..62e835ae415e5c9dcde9ecc05cb8221ee76c144d 100755
--- a/configure
+++ b/configure
@@ -627,6 +627,7 @@ ac_includes_default="\
 
 ac_subst_vars='LTLIBOBJS
 vpath_build
+PG_SYSROOT
 PG_VERSION_NUM
 PROVE
 OSX
@@ -15908,6 +15909,15 @@ _ACEOF
 
 
 
+# If we are inserting PG_SYSROOT into CPPFLAGS, do so symbolically not
+# literally, so that it's possible to override it at build time using
+# a command like "make ... PG_SYSROOT=path".  This has to be done after
+# we've finished all configure checks that depend on CPPFLAGS.
+if test x"$PG_SYSROOT" != x; then
+  CPPFLAGS=`echo "$CPPFLAGS" | sed -e "s| $PG_SYSROOT | \\\$(PG_SYSROOT) |"`
+fi
+
+
 
 # Begin output steps
 
diff --git a/configure.in b/configure.in
index 44e345666aedd84109212d5f53b8ad7c7a55e2ff..c958f4c678dcd69e0adda2e722e8681a032e7228 100644
--- a/configure.in
+++ b/configure.in
@@ -2181,6 +2181,15 @@ $AWK '{printf "%d%02d%02d", $1, $2, (NF >= 3) ? $3 : 0}'`"]
 AC_DEFINE_UNQUOTED(PG_VERSION_NUM, $PG_VERSION_NUM, [PostgreSQL version as a number])
 AC_SUBST(PG_VERSION_NUM)
 
+# If we are inserting PG_SYSROOT into CPPFLAGS, do so symbolically not
+# literally, so that it's possible to override it at build time using
+# a command like "make ... PG_SYSROOT=path".  This has to be done after
+# we've finished all configure checks that depend on CPPFLAGS.
+if test x"$PG_SYSROOT" != x; then
+  CPPFLAGS=`echo "$CPPFLAGS" | sed -e "s| $PG_SYSROOT | \\\$(PG_SYSROOT) |"`
+fi
+AC_SUBST(PG_SYSROOT)
+
 
 # Begin output steps
 
diff --git a/doc/src/sgml/installation.sgml b/doc/src/sgml/installation.sgml
index a724a938fb827ebe0f90df14500b946f383b1380..32978dc91893ce070fea6943b2b7ee22e0dfe8f7 100644
--- a/doc/src/sgml/installation.sgml
+++ b/doc/src/sgml/installation.sgml
@@ -2570,6 +2570,57 @@ PHSS_30849  s700_800 u2comp/be/plugin library Patch
    </para>
   </sect2>
 
+  <sect2 id="installation-notes-macos">
+   <title>macOS</title>
+
+   <indexterm zone="installation-notes-macos">
+    <primary>macOS</primary>
+    <secondary>installation on</secondary>
+   </indexterm>
+
+   <para>
+    On recent <productname>macOS</productname> releases, it's necessary to
+    embed the <quote>sysroot</quote> path in the include switches used to
+    find some system header files.  This results in the outputs of
+    the <application>configure</application> script varying depending on
+    which SDK version was used during <application>configure</application>.
+    That shouldn't pose any problem in simple scenarios, but if you are
+    trying to do something like building an extension on a different machine
+    than the server code was built on, you may need to force use of a
+    different sysroot path.  To do that, set <varname>PG_SYSROOT</varname>,
+    for example
+<programlisting>
+make PG_SYSROOT=<replaceable>/desired/path</replaceable> all
+</programlisting>
+    To find out the appropriate path on your machine, run
+<programlisting>
+xcodebuild -version -sdk macosx Path
+</programlisting>
+    Note that building an extension using a different sysroot version than
+    was used to build the core server is not really recommended; in the
+    worst case it could result in hard-to-debug ABI inconsistencies.
+   </para>
+
+   <para>
+    You can also select a non-default sysroot path when configuring, by
+    specifying <varname>PG_SYSROOT</varname>
+    to <application>configure</application>:
+<programlisting>
+./configure ... PG_SYSROOT=<replaceable>/desired/path</replaceable>
+</programlisting>
+   </para>
+
+   <para>
+    <productname>macOS</productname>'s <quote>System Integrity
+    Protection</quote> (SIP) feature breaks <literal>make check</literal>,
+    because it prevents passing the needed setting
+    of <literal>DYLD_LIBRARY_PATH</literal> down to the executables being
+    tested.  You can work around that by doing <literal>make
+    install</literal> before <literal>make check</literal>.
+    Most Postgres developers just turn off SIP, though.
+   </para>
+  </sect2>
+
   <sect2 id="installation-notes-mingw">
    <title>MinGW/Native Windows</title>
 
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 5d6a2ceaa9295ebbc3819fd2961c1ffa907127d2..3902d16d98a55bd0151151db380aae3058c00456 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -225,6 +225,7 @@ PTHREAD_LIBS		= @PTHREAD_LIBS@
 
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+PG_SYSROOT = @PG_SYSROOT@
 
 ifdef PGXS
 override CPPFLAGS := -I$(includedir_server) -I$(includedir_internal) $(CPPFLAGS)
diff --git a/src/template/darwin b/src/template/darwin
index 159d8bb12750f698bd48e6f0ae0a53f958aca3b9..c05adca0bfbec7bba7a6551d4edf0ea0bf932d49 100644
--- a/src/template/darwin
+++ b/src/template/darwin
@@ -3,14 +3,15 @@
 # Note: Darwin is the original code name for macOS, also known as OS X.
 # We still use "darwin" as the port name, partly because config.guess does.
 
-# Some configure tests require explicit knowledge of where the Xcode "sysroot"
-# is.  We try to avoid having this leak into configure's results, though.
+# Select where system include files should be sought.
 if test x"$PG_SYSROOT" = x"" ; then
   PG_SYSROOT=`xcodebuild -version -sdk macosx Path 2>/dev/null`
 fi
 # Old xcodebuild versions may produce garbage, so validate the result.
 if test x"$PG_SYSROOT" != x"" ; then
-  if test \! -d "$PG_SYSROOT" ; then
+  if test -d "$PG_SYSROOT" ; then
+    CPPFLAGS="-isysroot $PG_SYSROOT $CPPFLAGS"
+  else
     PG_SYSROOT=""
   fi
 fi