From 779129f32124314ef8a3672be9f3ba1b5d29295b Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Tue, 30 Aug 2022 13:33:00 -0700
Subject: [PATCH v13 19/20] 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 3f5e9883c0c..36d06c7ca6b 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 8c6f685cb32..2747026c729 100644
--- a/src/backend/snowball/meson.build
+++ b/src/backend/snowball/meson.build
@@ -60,6 +60,7 @@ stemmer_inc = include_directories('../../include/snowball')
 
 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 02f030e0ccf..372ab47ab92 100644
--- a/src/bin/pg_upgrade/meson.build
+++ b/src/bin/pg_upgrade/meson.build
@@ -18,6 +18,7 @@ pg_upgrade_sources = files(
 
 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 73b733dd50b..9866737c913 100644
--- a/src/pl/plperl/meson.build
+++ b/src/pl/plperl/meson.build
@@ -38,6 +38,7 @@ endforeach
 plperl_inc = include_directories('.')
 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 dd499fdd151..eb0ddaac376 100644
--- a/src/pl/plpgsql/src/meson.build
+++ b/src/pl/plpgsql/src/meson.build
@@ -42,6 +42,7 @@ plpgsql_sources += pl_unreserved
 
 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 366b3b171ac..5cecd9aeb0c 100644
--- a/src/pl/plpython/meson.build
+++ b/src/pl/plpython/meson.build
@@ -30,6 +30,7 @@ plpython_inc = include_directories('.')
 
 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 9b6addd7fd5..9d31074f0eb 100644
--- a/src/pl/tcl/meson.build
+++ b/src/pl/tcl/meson.build
@@ -16,6 +16,7 @@ pltcl_sources += custom_target('pltclerrcodes.h',
 
 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 1fe7632bdbe..3d9fe8bf930 100644
--- a/contrib/bloom/meson.build
+++ b/contrib/bloom/meson.build
@@ -9,6 +9,7 @@ bloom_sources = files(
 
 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 c0a8d238540..4aefe475573 100644
--- a/contrib/btree_gist/meson.build
+++ b/contrib/btree_gist/meson.build
@@ -27,6 +27,7 @@ btree_gist_sources = files(
 
 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 07c59f40a97..d472c2591d8 100644
--- a/contrib/hstore/meson.build
+++ b/contrib/hstore/meson.build
@@ -10,6 +10,7 @@ hstore = shared_module('hstore',
     'hstore_op.c',
     'hstore_subs.c',
   ),
+  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 a90628d23c6..6e9d5cabdbb 100644
--- a/contrib/pg_trgm/meson.build
+++ b/contrib/pg_trgm/meson.build
@@ -5,6 +5,7 @@ pg_trgm = shared_module('pg_trgm',
     'trgm_op.c',
     'trgm_regexp.c',
   ),
+  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 fe0851bf8e8..8e08b2f5ae9 100644
--- a/contrib/pgcrypto/meson.build
+++ b/contrib/pgcrypto/meson.build
@@ -72,6 +72,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 8e828692d5c..65318f27e11 100644
--- a/contrib/pgstattuple/meson.build
+++ b/contrib/pgstattuple/meson.build
@@ -4,6 +4,7 @@ pgstattuple = shared_module('pgstattuple',
     'pgstatindex.c',
     'pgstattuple.c',
   ),
+  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 60a95e17c2f..fd88b14a3c5 100644
--- a/contrib/sepgsql/meson.build
+++ b/contrib/sepgsql/meson.build
@@ -16,6 +16,7 @@ sepgsql_sources = files(
 
 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 9c0b56f01f6..8b041b4d4cb 100644
--- a/contrib/xml2/meson.build
+++ b/contrib/xml2/meson.build
@@ -7,6 +7,7 @@ xml2 = shared_module('pgxml',
     'xpath.c',
     'xslt_proc.c',
   ),
+  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 5a7a93baf4c..cdd2f238c78 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1174,7 +1174,7 @@ task:
 
   configure_script:
     - vcvarsall x64
-    - meson setup --buildtype debug --backend ninja  -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 build
+    - meson setup --buildtype debug --backend ninja  -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 build
 
   build_script:
     - vcvarsall x64
@@ -1201,7 +1201,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 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 build
 
   build_script:
     - vcvarsall x64
diff --git a/meson.build b/meson.build
index a56af6ccb0e..c4d3ce83954 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',
   ]
 )
@@ -1769,6 +1770,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

