From e3d1e4a4ef68d50fd1ae9a31e0f7eed96b387972 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Fri, 23 Sep 2022 12:19:17 -0700
Subject: [PATCH v15 11/14] meson: Add support for building with precompiled
 headers

This substantially speeds up building for windows. A cross build with mingw
goes from

real	0m29.884s
user	15m41.900s
sys	1m58.257s

to

real	0m13.196s
user	6m52.330s
sys	1m15.140s

The wins on windows are similar-ish (but I don't have a system at hand just
now for actual numbers).
---
 src/include/meson.build           | 1 +
 src/include/pch/c_pch.h           | 1 +
 src/include/pch/meson.build       | 4 ++++
 src/include/pch/postgres_fe_pch.h | 1 +
 src/include/pch/postgres_pch.h    | 1 +
 src/common/meson.build            | 2 ++
 src/port/meson.build              | 2 ++
 src/backend/meson.build           | 5 +++++
 src/backend/snowball/meson.build  | 1 +
 src/fe_utils/meson.build          | 1 +
 src/bin/pg_dump/meson.build       | 1 +
 src/bin/pg_upgrade/meson.build    | 1 +
 src/bin/psql/meson.build          | 1 +
 src/interfaces/libpq/meson.build  | 1 +
 src/pl/plperl/meson.build         | 1 +
 src/pl/plpgsql/src/meson.build    | 1 +
 src/pl/plpython/meson.build       | 1 +
 src/pl/tcl/meson.build            | 1 +
 contrib/bloom/meson.build         | 1 +
 contrib/btree_gist/meson.build    | 1 +
 contrib/hstore/meson.build        | 1 +
 contrib/pg_trgm/meson.build       | 1 +
 contrib/pgcrypto/meson.build      | 1 +
 contrib/pgstattuple/meson.build   | 1 +
 contrib/sepgsql/meson.build       | 1 +
 contrib/xml2/meson.build          | 1 +
 .cirrus.yml                       | 4 ++--
 meson.build                       | 8 ++++++++
 28 files changed, 45 insertions(+), 2 deletions(-)
 create mode 100644 src/include/pch/c_pch.h
 create mode 100644 src/include/pch/meson.build
 create mode 100644 src/include/pch/postgres_fe_pch.h
 create mode 100644 src/include/pch/postgres_pch.h

diff --git a/src/include/meson.build b/src/include/meson.build
index e5390df0584..28ed9011c70 100644
--- a/src/include/meson.build
+++ b/src/include/meson.build
@@ -110,6 +110,7 @@ install_headers(
 
 subdir('catalog')
 subdir('nodes')
+subdir('pch')
 subdir('storage')
 subdir('utils')
 
diff --git a/src/include/pch/c_pch.h b/src/include/pch/c_pch.h
new file mode 100644
index 00000000000..f40c757ca62
--- /dev/null
+++ b/src/include/pch/c_pch.h
@@ -0,0 +1 @@
+#include "c.h"
diff --git a/src/include/pch/meson.build b/src/include/pch/meson.build
new file mode 100644
index 00000000000..2bcec49c3a2
--- /dev/null
+++ b/src/include/pch/meson.build
@@ -0,0 +1,4 @@
+# See https://github.com/mesonbuild/meson/issues/10338
+pch_c_h = meson.source_root() / meson.current_source_dir() / 'c_pch.h'
+pch_postgres_h = meson.source_root() / meson.current_source_dir() / 'postgres_pch.h'
+pch_postgres_fe_h = meson.source_root() / meson.current_source_dir() / 'postgres_fe_pch.h'
diff --git a/src/include/pch/postgres_fe_pch.h b/src/include/pch/postgres_fe_pch.h
new file mode 100644
index 00000000000..f3ea20912d3
--- /dev/null
+++ b/src/include/pch/postgres_fe_pch.h
@@ -0,0 +1 @@
+#include "postgres_fe.h"
diff --git a/src/include/pch/postgres_pch.h b/src/include/pch/postgres_pch.h
new file mode 100644
index 00000000000..71b2f35f76b
--- /dev/null
+++ b/src/include/pch/postgres_pch.h
@@ -0,0 +1 @@
+#include "postgres.h"
diff --git a/src/common/meson.build b/src/common/meson.build
index 23842e1ffef..1c9b8a3a018 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -147,6 +147,7 @@ foreach name, opts : pgcommon_variants
     endif
     c_args = opts.get('c_args', []) + common_cflags[cflagname]
     cflag_libs += static_library('libpgcommon@0@_@1@'.format(name, cflagname),
+      c_pch: pch_c_h,
       include_directories: include_directories('.'),
       kwargs: opts + {
         'sources': sources,
@@ -159,6 +160,7 @@ foreach name, opts : pgcommon_variants
 
   lib = static_library('libpgcommon@0@'.format(name),
       link_with: cflag_libs,
+      c_pch: pch_c_h,
       include_directories: include_directories('.'),
       kwargs: opts + {
         'dependencies': opts['dependencies'] + [ssl],
diff --git a/src/port/meson.build b/src/port/meson.build
index ced2e014db8..c2222696f1b 100644
--- a/src/port/meson.build
+++ b/src/port/meson.build
@@ -161,6 +161,7 @@ foreach name, opts : pgport_variants
     c_args = opts.get('c_args', []) + pgport_cflags[cflagname]
     cflag_libs += static_library('libpgport@0@_@1@'.format(name, cflagname),
       sources,
+      c_pch: pch_c_h,
       kwargs: opts + {
         'c_args': c_args,
         'build_by_default': false,
@@ -172,6 +173,7 @@ foreach name, opts : pgport_variants
   lib = static_library('libpgport@0@'.format(name),
       pgport_sources,
       link_with: cflag_libs,
+      c_pch: pch_c_h,
       kwargs: opts + {
         'dependencies': opts['dependencies'] + [ssl],
       }
diff --git a/src/backend/meson.build b/src/backend/meson.build
index 1cb4cd3431f..a535543ee9e 100644
--- a/src/backend/meson.build
+++ b/src/backend/meson.build
@@ -62,6 +62,7 @@ postgres_lib = static_library('postgres_lib',
   backend_sources + timezone_sources + generated_backend_sources,
   link_whole: backend_link_with,
   dependencies: backend_build_deps,
+  c_pch: pch_postgres_h,
   kwargs: internal_lib_args,
 )
 
@@ -81,6 +82,10 @@ if cc.get_id() == 'msvc'
 
   backend_link_args += '/DEF:@0@'.format(postgres_def.full_path())
   backend_link_depends += postgres_def
+  # Due to the way msvc and meson's precompiled headers implementation
+  # interact, we need to have symbols from the full library available. Could
+  # be restricted to b_pch=true.
+  backend_link_with += postgres_lib
 
 elif host_system == 'aix'
   # The '.' argument leads mkldexport.sh to emit "#! .", which refers to the
diff --git a/src/backend/snowball/meson.build b/src/backend/snowball/meson.build
index 974401d187e..72959fa29d6 100644
--- a/src/backend/snowball/meson.build
+++ b/src/backend/snowball/meson.build
@@ -66,6 +66,7 @@ endif
 
 dict_snowball = shared_module('dict_snowball',
   dict_snowball_sources,
+  c_pch: pch_postgres_h,
   kwargs: pg_mod_args + {
     'include_directories': [stemmer_inc],
   }
diff --git a/src/fe_utils/meson.build b/src/fe_utils/meson.build
index b6bf8e1ca21..f1ba5ac8c14 100644
--- a/src/fe_utils/meson.build
+++ b/src/fe_utils/meson.build
@@ -23,6 +23,7 @@ fe_utils_sources += psqlscan
 
 fe_utils = static_library('libpgfeutils',
   fe_utils_sources + generated_headers,
+  c_pch: pch_postgres_fe_h,
   include_directories: [postgres_inc, libpq_inc],
   dependencies: frontend_common_code,
   kwargs: default_lib_args,
diff --git a/src/bin/pg_dump/meson.build b/src/bin/pg_dump/meson.build
index 3527a25c288..e66f632b54e 100644
--- a/src/bin/pg_dump/meson.build
+++ b/src/bin/pg_dump/meson.build
@@ -13,6 +13,7 @@ pg_dump_common_sources = files(
 
 pg_dump_common = static_library('libpgdump_common',
   pg_dump_common_sources,
+  c_pch: pch_postgres_fe_h,
   dependencies: [frontend_code, libpq, zlib],
   kwargs: internal_lib_args,
 )
diff --git a/src/bin/pg_upgrade/meson.build b/src/bin/pg_upgrade/meson.build
index a7b927a45c7..212bc9ce6ef 100644
--- a/src/bin/pg_upgrade/meson.build
+++ b/src/bin/pg_upgrade/meson.build
@@ -24,6 +24,7 @@ endif
 
 pg_upgrade = executable('pg_upgrade',
   pg_upgrade_sources,
+  c_pch: pch_postgres_fe_h,
   dependencies: [frontend_code, libpq],
   kwargs: default_bin_args,
 )
diff --git a/src/bin/psql/meson.build b/src/bin/psql/meson.build
index 3474389d3b6..8ec07260d1b 100644
--- a/src/bin/psql/meson.build
+++ b/src/bin/psql/meson.build
@@ -46,6 +46,7 @@ endif
 
 psql = executable('psql',
   psql_sources,
+  c_pch: pch_postgres_fe_h,
   include_directories: include_directories('.'),
   dependencies: [frontend_code, libpq, readline],
   kwargs: default_bin_args,
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index 2c9edeaa088..72102521edc 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -49,6 +49,7 @@ libpq_st = static_library('libpq',
   pic: true,
   include_directories: [libpq_inc, postgres_inc],
   c_args: ['-DSO_MAJOR_VERSION=5'],
+  c_pch: pch_postgres_fe_h,
   dependencies: libpq_deps,
   kwargs: default_lib_args,
 )
diff --git a/src/pl/plperl/meson.build b/src/pl/plperl/meson.build
index 535660085dd..cd3894e6a73 100644
--- a/src/pl/plperl/meson.build
+++ b/src/pl/plperl/meson.build
@@ -45,6 +45,7 @@ endif
 
 plperl = shared_module('plperl',
   plperl_sources,
+  c_pch: pch_postgres_h,
   include_directories: [plperl_inc, postgres_inc],
   kwargs: pg_mod_args + {
     'dependencies': [perl_dep, pg_mod_args['dependencies']],
diff --git a/src/pl/plpgsql/src/meson.build b/src/pl/plpgsql/src/meson.build
index c46c0a1da2a..27b2f5ef529 100644
--- a/src/pl/plpgsql/src/meson.build
+++ b/src/pl/plpgsql/src/meson.build
@@ -48,6 +48,7 @@ endif
 
 plpgsql = shared_module('plpgsql',
   plpgsql_sources,
+  c_pch: pch_postgres_h,
   include_directories: include_directories('.'),
   kwargs: pg_mod_args,
 )
diff --git a/src/pl/plpython/meson.build b/src/pl/plpython/meson.build
index 40888386b5f..7bd683580e8 100644
--- a/src/pl/plpython/meson.build
+++ b/src/pl/plpython/meson.build
@@ -36,6 +36,7 @@ endif
 
 plpython = shared_module('plpython3',
   plpython_sources,
+  c_pch: pch_postgres_h,
   include_directories: [plpython_inc, postgres_inc],
   kwargs: pg_mod_args + {
     'dependencies': [python3_dep, pg_mod_args['dependencies']],
diff --git a/src/pl/tcl/meson.build b/src/pl/tcl/meson.build
index f09bb14c950..7a708776c99 100644
--- a/src/pl/tcl/meson.build
+++ b/src/pl/tcl/meson.build
@@ -22,6 +22,7 @@ endif
 
 pltcl = shared_module('pltcl',
   pltcl_sources,
+  c_pch: pch_postgres_h,
   include_directories: [include_directories('.'), postgres_inc],
   kwargs: pg_mod_args + {
     'dependencies': [tcl_dep, pg_mod_args['dependencies']],
diff --git a/contrib/bloom/meson.build b/contrib/bloom/meson.build
index 16f3b83e4d2..163a93c98fb 100644
--- a/contrib/bloom/meson.build
+++ b/contrib/bloom/meson.build
@@ -15,6 +15,7 @@ endif
 
 bloom = shared_module('bloom',
   bloom_sources,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args,
 )
 contrib_targets += bloom
diff --git a/contrib/btree_gist/meson.build b/contrib/btree_gist/meson.build
index e98c91dacc8..bfb7865d213 100644
--- a/contrib/btree_gist/meson.build
+++ b/contrib/btree_gist/meson.build
@@ -33,6 +33,7 @@ endif
 
 btree_gist = shared_module('btree_gist',
   btree_gist_sources,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args,
 )
 contrib_targets += btree_gist
diff --git a/contrib/hstore/meson.build b/contrib/hstore/meson.build
index 2bb26bb772b..a2a4ec36cb0 100644
--- a/contrib/hstore/meson.build
+++ b/contrib/hstore/meson.build
@@ -18,6 +18,7 @@ endif
 
 hstore = shared_module('hstore',
   hstore_sources,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args,
 )
 contrib_targets += hstore
diff --git a/contrib/pg_trgm/meson.build b/contrib/pg_trgm/meson.build
index c8c7c07b308..839d6c4a7f6 100644
--- a/contrib/pg_trgm/meson.build
+++ b/contrib/pg_trgm/meson.build
@@ -13,6 +13,7 @@ endif
 
 pg_trgm = shared_module('pg_trgm',
   pg_trgm_sources,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pg_trgm
diff --git a/contrib/pgcrypto/meson.build b/contrib/pgcrypto/meson.build
index 7fc7bbc7ca1..cc782578b49 100644
--- a/contrib/pgcrypto/meson.build
+++ b/contrib/pgcrypto/meson.build
@@ -78,6 +78,7 @@ endif
 pgcrypto = shared_module('pgcrypto',
   pgcrypto_sources,
   link_with: pgcrypto_link_with,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args + {
     'dependencies': [pgcrypto_deps, contrib_mod_args['dependencies']]
   },
diff --git a/contrib/pgstattuple/meson.build b/contrib/pgstattuple/meson.build
index 05e4cd46a5c..42d0b0e6ce9 100644
--- a/contrib/pgstattuple/meson.build
+++ b/contrib/pgstattuple/meson.build
@@ -12,6 +12,7 @@ endif
 
 pgstattuple = shared_module('pgstattuple',
   pgstattuple_sources,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args,
 )
 contrib_targets += pgstattuple
diff --git a/contrib/sepgsql/meson.build b/contrib/sepgsql/meson.build
index 8bef239e3c2..1ac0fa388ab 100644
--- a/contrib/sepgsql/meson.build
+++ b/contrib/sepgsql/meson.build
@@ -22,6 +22,7 @@ endif
 
 sepgsql = shared_module('sepgsql',
   sepgsql_sources,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args + {
     'dependencies': [selinux, contrib_mod_args['dependencies']],
   }
diff --git a/contrib/xml2/meson.build b/contrib/xml2/meson.build
index 89b0d677516..92ab3368428 100644
--- a/contrib/xml2/meson.build
+++ b/contrib/xml2/meson.build
@@ -15,6 +15,7 @@ endif
 
 xml2 = shared_module('pgxml',
   xml2_sources,
+  c_pch: pch_postgres_h,
   kwargs: contrib_mod_args + {
     'dependencies': [libxml, libxslt, contrib_mod_args['dependencies']],
   },
diff --git a/.cirrus.yml b/.cirrus.yml
index 965483550d1..a0e7acf5ec9 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -602,7 +602,7 @@ task:
   # Use /DEBUG:FASTLINK to avoid high memory usage during linking
   configure_script: |
     vcvarsall x64
-    meson setup --backend ninja --buildtype debug -Dc_link_args=/DEBUG:FASTLINK -Dcassert=true -Dssl=openssl -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=c:/windows/system32/tar.exe -DPG_TEST_EXTRA="%PG_TEST_EXTRA%" build
+    meson setup --backend ninja --buildtype debug -Dc_link_args=/DEBUG:FASTLINK -Dcassert=true -Db_pch=true -Dssl=openssl -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=c:/windows/system32/tar.exe -DPG_TEST_EXTRA="%PG_TEST_EXTRA%" build
 
   build_script: |
     vcvarsall x64
@@ -630,7 +630,7 @@ task:
 
   configure_script: |
     vcvarsall x64
-    meson setup --buildtype debug --backend vs -Dcassert=true -Dssl=openssl -Dlz4=enabled -Dzlib=enabled -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=c:/windows/system32/tar.exe -DPG_TEST_EXTRA="%PG_TEST_EXTRA%" build
+    meson setup --buildtype debug --backend vs -Dcassert=true -Db_pch=true -Dssl=openssl -Dlz4=enabled -Dzlib=enabled -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=c:/windows/system32/tar.exe -DPG_TEST_EXTRA="%PG_TEST_EXTRA%" build
 
   build_script: |
     vcvarsall x64
diff --git a/meson.build b/meson.build
index 2b0cbb9a5a7..6ee9bbb3f46 100644
--- a/meson.build
+++ b/meson.build
@@ -15,6 +15,7 @@ project('postgresql',
   meson_version: '>=0.54',
   default_options: [
     'warning_level=1', #-Wall equivalent
+    'b_pch=false',
     'buildtype=release',
   ]
 )
@@ -1767,6 +1768,13 @@ if cc.get_id() == 'msvc'
     '/wd4267', # conversion from 'size_t' to 'type', possible loss of data
   ]
 
+  # Dirty hack to disable warnings due to some files defining
+  # UMDF_USING_NTSTATUS before including postgres.h. We need a better fix, but
+  # for now this allows us to see "real" warnings.
+  if get_option('b_pch')
+    cflags_warn += '/wd4005' # macro redefinition
+  endif
+
   cppflags += [
     '/DWIN32',
     '/DWINDOWS',
-- 
2.37.3.542.gdd3f6c4cae

