meson: Add _static and _shared suffixes to the library names

Started by Nazir Bilal Yavuz5 months ago12 messages
#1Nazir Bilal Yavuz
byavuz81@gmail.com
1 attachment(s)

Hi,

Windows CI images are updated ~15 hours ago [1]https://cirrus-ci.com/task/5683237017616384 and Windows CI task
started to fail with [2]https://cirrus-ci.com/task/5906793164963840:

```
FAILED: [code=2] src/interfaces/libpq/libpq.a.p/meson_pch-c.obj
src/interfaces/libpq/libpq.a.p/postgres_fe_pch.pch

"cl" "-Isrc/interfaces/libpq\libpq.a.p" "-Isrc/interfaces/libpq"
"-I..\src\interfaces\libpq" "-Isrc\port" "-I..\src\port"
"-Isrc\include" "-I..\src\include" "-Ic:\openssl\1.1\include"
"-I..\src\include\port\win32" "-I..\src\include\port\win32_msvc"
"-IC:/cirrus/src/include/pch" "/nologo" "/showIncludes" "/utf-8" "/W2"
"/Od" "/Zi" "/Zc:preprocessor" "/DWIN32" "/DWINDOWS" "/D__WINDOWS__"
"/D__WIN32__" "/D_CRT_SECURE_NO_DEPRECATE"
"/D_CRT_NONSTDC_NO_DEPRECATE" "/wd4018" "/wd4244" "/wd4273" "/wd4101"
"/wd4102" "/wd4090" "/wd4267" "/Ycpostgres_fe_pch.h"
"/Fpsrc/interfaces/libpq\libpq.a.p\postgres_fe_pch.pch"
"/Fosrc/interfaces/libpq\libpq.a.p\meson_pch-c.obj" "/MDd" "/nologo"
"/showIncludes" "/utf-8" "/W2" "/Od" "/Zi" "/Zc:preprocessor"
"/DWIN32" "/DWINDOWS" "/D__WINDOWS__" "/D__WIN32__"
"/D_CRT_SECURE_NO_DEPRECATE" "/D_CRT_NONSTDC_NO_DEPRECATE" "/wd4018"
"/wd4244" "/wd4273" "/wd4101" "/wd4102" "/wd4090" "/wd4267"
"-DSO_MAJOR_VERSION=5" "/FS"
"/FdC:\cirrus\build\src/interfaces/libpq\libpq.pdb" "/c"
src/interfaces/libpq/libpq.a.p/meson_pch-c.c

src/interfaces/libpq/libpq.a.p/meson_pch-c.c: fatal error C1052:
program database file,
'C:\cirrus\build\src\interfaces\libpq\libpq.pdb', was generated by the
linker with /DEBUG:fastlink; compiler cannot update such PDB files;
please delete it or use /Fd to specify a different PDB filename
```

After talking with Andres, we realized that the problem is caused by
static and shared libraries having the same name, so they overwrite
each other's debug file. This was not seen before, our guess is that
the ninja version is upgraded on the Windows CI image from 1.11.1 to
1.13.0 and new ninja optimized the build. Older ninja was building two
libraries concurrently and that hid the problem but the new ninja
optimized/changed the build, so these two libraries weren't built
concurrently and caused the failure.

The solution is changing the libraries' names [3]https://cirrus-ci.com/task/5204554066690048. Changing
conflicting libraries' names is actually enough but I wanted to add
_static and _shared suffixes to all of the libraries' names as I think
this is more future proof.

Any feedback would be appreciated.

Note: Since there is no new commit after the Windows CI image update
[1]: https://cirrus-ci.com/task/5683237017616384
first commit will trigger this problem.

[1]: https://cirrus-ci.com/task/5683237017616384
[2]: https://cirrus-ci.com/task/5906793164963840
[3]: https://cirrus-ci.com/task/5204554066690048

--
Regards,
Nazir Bilal Yavuz
Microsoft

Attachments:

v1-0001-meson-Add-_static-and-_shared-suffixes-to-the-lib.patchtext/x-patch; charset=US-ASCII; name=v1-0001-meson-Add-_static-and-_shared-suffixes-to-the-lib.patchDownload
From 3e177cb280d0e643f6cce785d6048c5e2dd11d5c Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <byavuz81@gmail.com>
Date: Tue, 12 Aug 2025 17:53:50 +0300
Subject: [PATCH v1] meson: Add _static and _shared suffixes to the library
 names

Otherwise static and shared libraries overwrite each other's debug file.

Suggested-by: Andres Freund <andres@anarazel.de>
Author: Nazir Bilal Yavuz <byavuz81@gmail.com>
---
 src/backend/bootstrap/meson.build          | 2 +-
 src/backend/meson.build                    | 2 +-
 src/backend/nodes/meson.build              | 2 +-
 src/backend/parser/meson.build             | 2 +-
 src/backend/replication/meson.build        | 2 +-
 src/backend/utils/activity/meson.build     | 2 +-
 src/backend/utils/adt/meson.build          | 2 +-
 src/backend/utils/misc/meson.build         | 2 +-
 src/common/meson.build                     | 6 +++---
 src/port/meson.build                       | 4 ++--
 src/fe_utils/meson.build                   | 2 +-
 src/bin/pg_basebackup/meson.build          | 2 +-
 src/bin/pg_dump/meson.build                | 2 +-
 src/bin/scripts/meson.build                | 2 +-
 src/interfaces/libpq/meson.build           | 4 ++--
 src/interfaces/ecpg/compatlib/meson.build  | 4 ++--
 src/interfaces/ecpg/ecpglib/meson.build    | 4 ++--
 src/interfaces/ecpg/pgtypeslib/meson.build | 4 ++--
 src/interfaces/libpq-oauth/meson.build     | 2 +-
 19 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/src/backend/bootstrap/meson.build b/src/backend/bootstrap/meson.build
index 29726c1ab4f..4264d09113c 100644
--- a/src/backend/bootstrap/meson.build
+++ b/src/backend/bootstrap/meson.build
@@ -21,7 +21,7 @@ bootparse = custom_target('bootparse',
 generated_sources += bootparse.to_list()
 boot_parser_sources += bootparse
 
-boot_parser = static_library('boot_parser',
+boot_parser = static_library('boot_parser_static',
   boot_parser_sources,
   dependencies: [backend_code],
   include_directories: include_directories('.'),
diff --git a/src/backend/meson.build b/src/backend/meson.build
index b831a541652..e6e2f93179c 100644
--- a/src/backend/meson.build
+++ b/src/backend/meson.build
@@ -62,7 +62,7 @@ backend_link_depends = []
 # Can't name the static library 'postgres', because msbuild ends up with a
 # conflict for the .pdb file otherwise.
 
-postgres_lib = static_library('postgres_lib',
+postgres_lib = static_library('postgres_lib_static',
   backend_sources + timezone_sources + generated_backend_sources,
   link_whole: backend_link_with,
   dependencies: backend_build_deps,
diff --git a/src/backend/nodes/meson.build b/src/backend/nodes/meson.build
index 9a1c1b7b987..1ee286ea17b 100644
--- a/src/backend/nodes/meson.build
+++ b/src/backend/nodes/meson.build
@@ -23,7 +23,7 @@ nodefunc_sources = files(
   'outfuncs.c',
   'readfuncs.c',
 )
-nodefuncs = static_library('nodefuncs',
+nodefuncs = static_library('nodefuncs_static',
   nodefunc_sources,
   dependencies: [backend_code],
   include_directories: include_directories('../../include/nodes'),
diff --git a/src/backend/parser/meson.build b/src/backend/parser/meson.build
index 874aa749aa6..f5c07ff8dcf 100644
--- a/src/backend/parser/meson.build
+++ b/src/backend/parser/meson.build
@@ -42,7 +42,7 @@ backend_parser = custom_target('gram',
 generated_sources += backend_parser.to_list()
 parser_sources += backend_parser
 
-parser = static_library('parser',
+parser = static_library('parser_static',
   parser_sources,
   dependencies: [backend_code],
   include_directories: include_directories('.'),
diff --git a/src/backend/replication/meson.build b/src/backend/replication/meson.build
index b0601498865..ad278e78e3b 100644
--- a/src/backend/replication/meson.build
+++ b/src/backend/replication/meson.build
@@ -42,7 +42,7 @@ syncrep_gram = custom_target('syncrep_gram',
 generated_sources += syncrep_gram.to_list()
 repl_parser_sources += syncrep_gram
 
-repl_parser = static_library('repl_parser',
+repl_parser = static_library('repl_parser_static',
   repl_parser_sources,
   dependencies: [backend_code],
   include_directories: include_directories('.'),
diff --git a/src/backend/utils/activity/meson.build b/src/backend/utils/activity/meson.build
index d8e56b49c24..1bb0320a0b2 100644
--- a/src/backend/utils/activity/meson.build
+++ b/src/backend/utils/activity/meson.build
@@ -27,7 +27,7 @@ waitevent_sources = files(
   'wait_event_funcs.c',
 )
 
-wait_event = static_library('wait_event_names',
+wait_event = static_library('wait_event_names_static',
   waitevent_sources,
   dependencies: [backend_code],
   include_directories: include_directories('../../../include/utils'),
diff --git a/src/backend/utils/adt/meson.build b/src/backend/utils/adt/meson.build
index ed9bbd7b926..238ce24a7f8 100644
--- a/src/backend/utils/adt/meson.build
+++ b/src/backend/utils/adt/meson.build
@@ -130,7 +130,7 @@ jsonpath_gram = custom_target('jsonpath_parse',
 generated_sources += jsonpath_gram.to_list()
 
 # so we don't need to add . as an include dir for the whole backend
-backend_link_with += static_library('jsonpath',
+backend_link_with += static_library('jsonpath_static',
   jsonpath_scan, jsonpath_gram,
   dependencies: [backend_code],
   include_directories: include_directories('.'),
diff --git a/src/backend/utils/misc/meson.build b/src/backend/utils/misc/meson.build
index 9e389a00d05..af01d4852a8 100644
--- a/src/backend/utils/misc/meson.build
+++ b/src/backend/utils/misc/meson.build
@@ -27,7 +27,7 @@ guc_scan = custom_target('guc_scan',
 generated_sources += guc_scan
 
 # so we don't need to add . as an include dir for the whole backend
-backend_link_with += static_library('guc-file',
+backend_link_with += static_library('guc-file_static',
   guc_scan,
   dependencies: [backend_code],
   include_directories: include_directories('.'),
diff --git a/src/common/meson.build b/src/common/meson.build
index 1540ba67cca..7ce71bbf934 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -167,7 +167,7 @@ foreach name, opts : pgcommon_variants
       continue
     endif
     c_args = opts.get('c_args', []) + common_cflags[cflagname]
-    cflag_libs += static_library('libpgcommon@0@_@1@'.format(name, cflagname),
+    cflag_libs += static_library('libpgcommon@0@_@1@_static'.format(name, cflagname),
       c_pch: pch_c_h,
       kwargs: opts + {
         'include_directories': [
@@ -182,7 +182,7 @@ foreach name, opts : pgcommon_variants
     )
   endforeach
 
-  lib = static_library('libpgcommon@0@'.format(name),
+  lib = static_library('libpgcommon@0@_static'.format(name),
       link_with: cflag_libs,
       link_whole: cflag_libs,
       c_pch: pch_c_h,
@@ -201,7 +201,7 @@ common_srv = pgcommon['_srv']
 common_shlib = pgcommon['_shlib']
 common_static = pgcommon['']
 
-common_excluded_shlib = static_library('libpgcommon_excluded_shlib',
+common_excluded_shlib = static_library('libpgcommon_excluded_shlib_static',
   sources: common_sources_excluded_shlib,
   dependencies: [frontend_common_code],
   build_by_default: false,
diff --git a/src/port/meson.build b/src/port/meson.build
index fc7b059fee5..382e6d3078a 100644
--- a/src/port/meson.build
+++ b/src/port/meson.build
@@ -175,7 +175,7 @@ foreach name, opts : pgport_variants
       continue
     endif
     c_args = opts.get('c_args', []) + pgport_cflags[cflagname]
-    cflag_libs += static_library('libpgport@0@_@1@'.format(name, cflagname),
+    cflag_libs += static_library('libpgport@0@_@1@_static'.format(name, cflagname),
       sources,
       c_pch: pch_c_h,
       kwargs: opts + {
@@ -186,7 +186,7 @@ foreach name, opts : pgport_variants
     )
   endforeach
 
-  lib = static_library('libpgport@0@'.format(name),
+  lib = static_library('libpgport@0@_static'.format(name),
       pgport_sources,
       link_with: cflag_libs,
       link_whole: cflag_libs,
diff --git a/src/fe_utils/meson.build b/src/fe_utils/meson.build
index 5a9ddb73463..999dc469896 100644
--- a/src/fe_utils/meson.build
+++ b/src/fe_utils/meson.build
@@ -28,7 +28,7 @@ psqlscan = custom_target('psqlscan',
 generated_sources += psqlscan
 fe_utils_sources += psqlscan
 
-fe_utils = static_library('libpgfeutils',
+fe_utils = static_library('libpgfeutils_static',
   fe_utils_sources,
   c_pch: pch_postgres_fe_h,
   include_directories: [postgres_inc, libpq_inc],
diff --git a/src/bin/pg_basebackup/meson.build b/src/bin/pg_basebackup/meson.build
index 3a7fc10eab0..8cd2186ad2f 100644
--- a/src/bin/pg_basebackup/meson.build
+++ b/src/bin/pg_basebackup/meson.build
@@ -8,7 +8,7 @@ common_sources = files(
 )
 
 pg_basebackup_deps = [frontend_code, libpq, lz4, zlib, zstd]
-pg_basebackup_common = static_library('libpg_basebackup_common',
+pg_basebackup_common = static_library('libpg_basebackup_common_static',
   common_sources,
   dependencies: pg_basebackup_deps,
   kwargs: internal_lib_args,
diff --git a/src/bin/pg_dump/meson.build b/src/bin/pg_dump/meson.build
index a2233b0a1b4..c58fd370f21 100644
--- a/src/bin/pg_dump/meson.build
+++ b/src/bin/pg_dump/meson.build
@@ -19,7 +19,7 @@ pg_dump_common_sources = files(
   'pg_backup_utils.c',
 )
 
-pg_dump_common = static_library('libpgdump_common',
+pg_dump_common = static_library('libpgdump_common_static',
   pg_dump_common_sources,
   c_pch: pch_postgres_fe_h,
   dependencies: [frontend_code, libpq, lz4, zlib, zstd],
diff --git a/src/bin/scripts/meson.build b/src/bin/scripts/meson.build
index 80df7c33257..ff5b815baff 100644
--- a/src/bin/scripts/meson.build
+++ b/src/bin/scripts/meson.build
@@ -1,6 +1,6 @@
 # Copyright (c) 2022-2025, PostgreSQL Global Development Group
 
-scripts_common = static_library('libscripts_common',
+scripts_common = static_library('libscripts_common_static',
   files('common.c'),
   dependencies: [frontend_code, libpq],
   kwargs: internal_lib_args,
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index a74e885b169..52e157b48e8 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -57,7 +57,7 @@ libpq_so_c_args = ['-DUSE_DYNAMIC_OAUTH']
 # We could try to avoid building the source files twice, but it probably adds
 # more complexity than its worth (reusing object files requires also linking
 # to the library on windows or breaks precompiled headers).
-libpq_st = static_library('libpq',
+libpq_st = static_library('libpq_static',
   libpq_sources,
   include_directories: [libpq_inc],
   c_args: libpq_c_args,
@@ -66,7 +66,7 @@ libpq_st = static_library('libpq',
   kwargs: default_lib_args,
 )
 
-libpq_so = shared_library('libpq',
+libpq_so = shared_library('libpq_shared',
   libpq_sources + libpq_so_sources,
   include_directories: [libpq_inc, postgres_inc],
   c_args: libpq_c_args + libpq_so_c_args,
diff --git a/src/interfaces/ecpg/compatlib/meson.build b/src/interfaces/ecpg/compatlib/meson.build
index 56e0a21651b..4e5ad5e3f5b 100644
--- a/src/interfaces/ecpg/compatlib/meson.build
+++ b/src/interfaces/ecpg/compatlib/meson.build
@@ -16,7 +16,7 @@ if host_system == 'windows'
 endif
 
 # see src/interfaces/libpq/meson.build
-ecpg_compat_st = static_library('libecpg_compat',
+ecpg_compat_st = static_library('libecpg_compat_static',
   ecpg_compat_sources,
   include_directories: ecpg_compat_inc,
   c_args: ecpg_compat_c_args,
@@ -26,7 +26,7 @@ ecpg_compat_st = static_library('libecpg_compat',
 )
 ecpg_targets += ecpg_compat_st
 
-ecpg_compat_so = shared_library('libecpg_compat',
+ecpg_compat_so = shared_library('libecpg_compat_shared',
   ecpg_compat_sources + ecpg_compat_so_sources,
   include_directories: ecpg_compat_inc,
   c_args: ecpg_compat_c_args,
diff --git a/src/interfaces/ecpg/ecpglib/meson.build b/src/interfaces/ecpg/ecpglib/meson.build
index 8f478c6a73e..df0aebe2d1c 100644
--- a/src/interfaces/ecpg/ecpglib/meson.build
+++ b/src/interfaces/ecpg/ecpglib/meson.build
@@ -25,7 +25,7 @@ if host_system == 'windows'
 endif
 
 # see src/interfaces/libpq/meson.build
-ecpglib_st = static_library('libecpg',
+ecpglib_st = static_library('libecpg_static',
   ecpglib_sources,
   include_directories: ecpglib_inc,
   c_args: ecpglib_c_args,
@@ -36,7 +36,7 @@ ecpglib_st = static_library('libecpg',
 )
 ecpg_targets += ecpglib_st
 
-ecpglib_so = shared_library('libecpg',
+ecpglib_so = shared_library('libecpg_shared',
   ecpglib_sources + ecpglib_so_sources,
   include_directories: ecpglib_inc,
   c_args: ecpglib_c_args,
diff --git a/src/interfaces/ecpg/pgtypeslib/meson.build b/src/interfaces/ecpg/pgtypeslib/meson.build
index 02301ec9acb..7b660932526 100644
--- a/src/interfaces/ecpg/pgtypeslib/meson.build
+++ b/src/interfaces/ecpg/pgtypeslib/meson.build
@@ -21,7 +21,7 @@ if host_system == 'windows'
 endif
 
 # see src/interfaces/libpq/meson.build
-ecpg_pgtypes_st = static_library('libpgtypes',
+ecpg_pgtypes_st = static_library('libpgtypes_static',
   ecpg_pgtypes_sources,
   include_directories: ecpg_pgtypes_inc,
   c_args: ecpg_pgtypes_c_args,
@@ -31,7 +31,7 @@ ecpg_pgtypes_st = static_library('libpgtypes',
 )
 ecpg_targets += ecpg_pgtypes_st
 
-ecpg_pgtypes_so = shared_library('libpgtypes',
+ecpg_pgtypes_so = shared_library('libpgtypes_shared',
   ecpg_pgtypes_sources + ecpg_pgtypes_so_sources,
   include_directories: ecpg_pgtypes_inc,
   c_args: ecpg_pgtypes_c_args,
diff --git a/src/interfaces/libpq-oauth/meson.build b/src/interfaces/libpq-oauth/meson.build
index df064c59a40..0b986b4355b 100644
--- a/src/interfaces/libpq-oauth/meson.build
+++ b/src/interfaces/libpq-oauth/meson.build
@@ -21,7 +21,7 @@ export_file = custom_target('libpq-oauth.exports',
 # port needs to be in include path due to pthread-win32.h
 libpq_oauth_inc = include_directories('.', '../libpq', '../../port')
 
-libpq_oauth_st = static_library('libpq-oauth',
+libpq_oauth_st = static_library('libpq-oauth_static',
   libpq_oauth_sources,
   include_directories: [libpq_oauth_inc, postgres_inc],
   c_pch: pch_postgres_fe_h,
-- 
2.50.1

#2Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Nazir Bilal Yavuz (#1)
Re: meson: Add _static and _shared suffixes to the library names

On Tue, Aug 12, 2025 at 8:46 AM Nazir Bilal Yavuz <byavuz81@gmail.com> wrote:

The solution is changing the libraries' names [3]. Changing
conflicting libraries' names is actually enough but I wanted to add
_static and _shared suffixes to all of the libraries' names as I think
this is more future proof.

Any feedback would be appreciated.

Just as a kneejerk reaction, I think it'd be really strange if the
Meson version of libpq-oauth.a was named libpq-oauth_static.a on disk,
and clients had to figure out which build system was used in order to
link. (Especially since the original name doesn't actually conflict
with libpq-oauth-19.so.)

-libpq_so = shared_library('libpq',
+libpq_so = shared_library('libpq_shared',

This, in particular, can't happen; it's akin to an SONAME bump.

Is there a way to work around this problem in a way that affects Windows only?

--Jacob

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jacob Champion (#2)
Re: meson: Add _static and _shared suffixes to the library names

Jacob Champion <jacob.champion@enterprisedb.com> writes:

On Tue, Aug 12, 2025 at 8:46 AM Nazir Bilal Yavuz <byavuz81@gmail.com> wrote:

The solution is changing the libraries' names [3]. Changing
conflicting libraries' names is actually enough but I wanted to add
_static and _shared suffixes to all of the libraries' names as I think
this is more future proof.

Any feedback would be appreciated.

Just as a kneejerk reaction, I think it'd be really strange if the
Meson version of libpq-oauth.a was named libpq-oauth_static.a on disk,
and clients had to figure out which build system was used in order to
link.

This proposal seems utterly unacceptable from a client compatibility
standpoint. Sure, we could get away with renaming purely internal
things like boot_parser, but libpq? It won't do for the ecpg
libraries either.

Is there a way to work around this problem in a way that affects Windows only?

Even on Windows, the proposal is unacceptable. The build products
have to remain the same as what they've been for decades. If meson
is unable to build them, we can't use meson. But I imagine there is
something you can do to persuade the newer version to do what it was
doing before.

regards, tom lane

#4Jacob Champion
jacob.champion@enterprisedb.com
In reply to: Tom Lane (#3)
Re: meson: Add _static and _shared suffixes to the library names

On Tue, Aug 12, 2025 at 9:27 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Is there a way to work around this problem in a way that affects Windows only?

Even on Windows, the proposal is unacceptable.

Sure, but I'm hoping that there's some Windows-specific Meson
twiddling that can be done to disambiguate the debug files on disk.

--Jacob

#5Peter Eisentraut
peter@eisentraut.org
In reply to: Jacob Champion (#4)
Re: meson: Add _static and _shared suffixes to the library names

On 12.08.25 18:37, Jacob Champion wrote:

On Tue, Aug 12, 2025 at 9:27 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Is there a way to work around this problem in a way that affects Windows only?

Even on Windows, the proposal is unacceptable.

Sure, but I'm hoping that there's some Windows-specific Meson
twiddling that can be done to disambiguate the debug files on disk.

Here is an older discussion that also involved having concurrent
shared_library() and static_library() on Windows, and the general
sentiment there appeared to be that this should (be made to) work:
https://github.com/mesonbuild/meson/issues/459

So I don't know what changed now, but I think we should think about in
terms of what changed rather than fixing our code.

#6Nazir Bilal Yavuz
byavuz81@gmail.com
In reply to: Peter Eisentraut (#5)
2 attachment(s)
Re: meson: Add _static and _shared suffixes to the library names

Hi,

Thank you all for sharing your thoughts and I am sorry for the first
proposal. It is a mistake on my part, I should have thought more.

On Tue, 12 Aug 2025 at 21:47, Peter Eisentraut <peter@eisentraut.org> wrote:

On 12.08.25 18:37, Jacob Champion wrote:

On Tue, Aug 12, 2025 at 9:27 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Is there a way to work around this problem in a way that affects Windows only?

Even on Windows, the proposal is unacceptable.

Sure, but I'm hoping that there's some Windows-specific Meson
twiddling that can be done to disambiguate the debug files on disk.

Here is an older discussion that also involved having concurrent
shared_library() and static_library() on Windows, and the general
sentiment there appeared to be that this should (be made to) work:
https://github.com/mesonbuild/meson/issues/459

I think the problem in the link you shared is different, we have
problems with Windows debug files (*.pdb files) but they have problems
with the library files themselves. Our problem is that the latest
built library tries to overwrite the early built library's .pdb file
and the build fails. So, my guess is that the libraries are in
different paths but their .pdb files are still in the same path. I did
a quick check and found that we have only one .pdb file after the
build, which I think confirms my guess. After the #1 fix applied, we
have two .pdb files; one .pdb file for each library type.

So I don't know what changed now, but I think we should think about in
terms of what changed rather than fixing our code.

I think we had this problem for a long time but the new ninja version
showed that problem.

I found two ways to fix that problem, both approaches fix the problem
by themselves:

1- Setting different names for .pdb files for shared libraries only on
the Windows OS. I think that is the correct fix, it just adds _shared
suffix to .pdb files of shared libraries on the Windows OS.

2- Using '/DEBUG:FULL' instead of '/DEBUG:FASTLINK' in the Windows CI
task but this causes more memory to be used. It seems that the error
appears only when the '/DEBUG:FASTLINK' is set. '/DEBUG:FULL' is a
default option, so we may decide to not add it at all. I explicitly
added it as I found this easier to understand. This approach fixes the
build but I think it is not the correct fix, we will have one .pdb
file after this fix; not one for each library type.

Here is how the directories look like after the fixes are applied:

$ dir C:\cirrus\build\src\interfaces\libpq ->

master with old ninja (master with new ninja fails):

Directory of C:\cirrus\build\src\interfaces\libpq

08/13/2025 05:47 AM <DIR> .
08/13/2025 05:47 AM <DIR> ..
08/13/2025 05:47 AM 4,483 exports.def
08/13/2025 05:47 AM 973,700 libpq.a
08/13/2025 05:47 AM <DIR> libpq.a.p
08/13/2025 05:47 AM 450,560 libpq.dll
08/13/2025 05:47 AM <DIR> libpq.dll.p
08/13/2025 05:47 AM 41,952 libpq.lib
08/13/2025 05:47 AM 1,413,120 libpq.pdb
08/13/2025 05:47 AM 700,416
lnk{6BBDFFB2-4393-4C5B-AE04-F33F1E9BBA12}.tmp
08/13/2025 05:47 AM <DIR> test
6 File(s) 3,584,231 bytes
5 Dir(s) 22,671,282,176 bytes free
--------------------------------------------------
#1 fix with new ninja:

Directory of C:\cirrus\build\src\interfaces\libpq

08/13/2025 05:55 AM <DIR> .
08/13/2025 05:53 AM <DIR> ..
08/13/2025 05:53 AM 4,483 exports.def
08/13/2025 05:55 AM 973,700 libpq.a
08/13/2025 05:54 AM <DIR> libpq.a.p
08/13/2025 05:53 AM 450,560 libpq.dll
08/13/2025 05:53 AM <DIR> libpq.dll.p
08/13/2025 05:53 AM 41,952 libpq.lib
08/13/2025 05:54 AM 700,416 libpq.pdb
08/13/2025 05:53 AM 1,413,120 libpq_shared.pdb
08/13/2025 05:55 AM <DIR> test
6 File(s) 3,584,231 bytes
5 Dir(s) 22,891,589,632 bytes free
----------------------------------------
#1 fix with old ninja:

Directory of C:\cirrus\build\src\interfaces\libpq

08/13/2025 06:19 AM <DIR> .
08/13/2025 06:19 AM <DIR> ..
08/13/2025 06:19 AM 4,483 exports.def
08/13/2025 06:19 AM 973,700 libpq.a
08/13/2025 06:19 AM <DIR> libpq.a.p
08/13/2025 06:19 AM 450,560 libpq.dll
08/13/2025 06:19 AM <DIR> libpq.dll.p
08/13/2025 06:19 AM 41,952 libpq.lib
08/13/2025 06:19 AM 700,416 libpq.pdb
08/13/2025 06:19 AM 1,413,120 libpq_shared.pdb
08/13/2025 06:19 AM <DIR> test
6 File(s) 3,584,231 bytes
5 Dir(s) 22,671,474,688 bytes free

--------------------------------------------------
#2 fix with new ninja:

Directory of C:\cirrus\build\src\interfaces\libpq

08/13/2025 06:04 AM <DIR> .
08/13/2025 06:02 AM <DIR> ..
08/13/2025 06:02 AM 4,483 exports.def
08/13/2025 06:04 AM 973,700 libpq.a
08/13/2025 06:03 AM <DIR> libpq.a.p
08/13/2025 06:02 AM 450,560 libpq.dll
08/13/2025 06:02 AM <DIR> libpq.dll.p
08/13/2025 06:02 AM 41,952 libpq.lib
08/13/2025 06:03 AM 1,961,984 libpq.pdb
08/13/2025 06:04 AM <DIR> test
5 File(s) 3,432,679 bytes
5 Dir(s) 22,859,337,728 bytes free
----------------------------------------
#2 fix with old ninja:

Directory of C:\cirrus\build\src\interfaces\libpq

08/13/2025 06:07 AM <DIR> .
08/13/2025 06:07 AM <DIR> ..
08/13/2025 06:07 AM 4,483 exports.def
08/13/2025 06:07 AM 973,700 libpq.a
08/13/2025 06:07 AM <DIR> libpq.a.p
08/13/2025 06:07 AM 450,560 libpq.dll
08/13/2025 06:07 AM <DIR> libpq.dll.p
08/13/2025 06:07 AM 41,952 libpq.lib
08/13/2025 06:07 AM 1,961,984 libpq.pdb
08/13/2025 06:07 AM <DIR> test
5 File(s) 3,432,679 bytes
5 Dir(s) 22,639,058,944 bytes free

- We have one .pdb file and one .tmp file on the master. I think this
.tmp file is a corrupted .pdb file
- #1 fix has correct .pdb files on both ninja versions.
- We have only one .pdb file with the #2 fix on both ninja versions,
there should be one for each library type.

--
Regards,
Nazir Bilal Yavuz
Microsoft

Attachments:

v2-0001-meson-windows-Add-_shared-suffix-to-the-.pdb-file.patchtext/x-patch; charset=US-ASCII; name=v2-0001-meson-windows-Add-_shared-suffix-to-the-.pdb-file.patchDownload
From 1db1c13d6cb6149ee529d1a9bcc2282a0728ed2e Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <byavuz81@gmail.com>
Date: Tue, 12 Aug 2025 20:46:57 +0300
Subject: [PATCH v2 1/2] meson: windows: Add _shared suffix to the .pdb files
 of shared libraries

Otherwise static and shared libraries overwrite each other's .pdb
(debug) files.

Suggested-by: Andres Freund <andres@anarazel.de>
Author: Nazir Bilal Yavuz <byavuz81@gmail.com>
Reviewed-by: Jacob Champion <jacob.champion@enterprisedb.com>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAN55FZ1RuBhJmPWs3Oi%3D9UoezDfrtO-VaU67db5%2B0_uy19uF%2BA%40mail.gmail.com
---
 src/interfaces/libpq/meson.build           | 9 ++++++++-
 src/interfaces/ecpg/compatlib/meson.build  | 9 ++++++++-
 src/interfaces/ecpg/ecpglib/meson.build    | 9 ++++++++-
 src/interfaces/ecpg/pgtypeslib/meson.build | 9 ++++++++-
 4 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index a74e885b169..d0203901fa7 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -66,6 +66,13 @@ libpq_st = static_library('libpq',
   kwargs: default_lib_args,
 )
 
+# Change shared library's .pdb name so it won't conflict with static library's
+# .pdb file
+libpq_pdb_args = []
+if host_system == 'windows'
+  libpq_pdb_args = ['/PDB:' + meson.current_build_dir() / 'libpq_shared.pdb']
+endif
+
 libpq_so = shared_library('libpq',
   libpq_sources + libpq_so_sources,
   include_directories: [libpq_inc, postgres_inc],
@@ -76,7 +83,7 @@ libpq_so = shared_library('libpq',
   darwin_versions: ['5', '5.' + pg_version_major.to_string()],
   dependencies: [frontend_shlib_code, libpq_deps],
   link_depends: export_file,
-  link_args: export_fmt.format(export_file.full_path()),
+  link_args: [export_fmt.format(export_file.full_path())] + libpq_pdb_args,
   kwargs: default_lib_args,
 )
 
diff --git a/src/interfaces/ecpg/compatlib/meson.build b/src/interfaces/ecpg/compatlib/meson.build
index 56e0a21651b..42bc87869ff 100644
--- a/src/interfaces/ecpg/compatlib/meson.build
+++ b/src/interfaces/ecpg/compatlib/meson.build
@@ -26,6 +26,13 @@ ecpg_compat_st = static_library('libecpg_compat',
 )
 ecpg_targets += ecpg_compat_st
 
+# Change shared library's .pdb name so it won't conflict with static library's
+# .pdb file
+ecpg_compat_pdb_args = []
+if host_system == 'windows'
+  ecpg_compat_pdb_args = ['/PDB:' + meson.current_build_dir() / 'libecpg_compat_shared.pdb']
+endif
+
 ecpg_compat_so = shared_library('libecpg_compat',
   ecpg_compat_sources + ecpg_compat_so_sources,
   include_directories: ecpg_compat_inc,
@@ -35,7 +42,7 @@ ecpg_compat_so = shared_library('libecpg_compat',
   soversion: host_system != 'windows' ? '3' : '',
   darwin_versions: ['3', '3.' + pg_version_major.to_string()],
   version: '3.' + pg_version_major.to_string(),
-  link_args: export_fmt.format(export_file.full_path()),
+  link_args: [export_fmt.format(export_file.full_path())] + ecpg_compat_pdb_args,
   link_depends: export_file,
   kwargs: default_lib_args,
 )
diff --git a/src/interfaces/ecpg/ecpglib/meson.build b/src/interfaces/ecpg/ecpglib/meson.build
index 8f478c6a73e..1d090489a69 100644
--- a/src/interfaces/ecpg/ecpglib/meson.build
+++ b/src/interfaces/ecpg/ecpglib/meson.build
@@ -36,6 +36,13 @@ ecpglib_st = static_library('libecpg',
 )
 ecpg_targets += ecpglib_st
 
+# Change shared library's .pdb name so it won't conflict with static library's
+# .pdb file
+ecpglib_pdb_args = []
+if host_system == 'windows'
+  ecpglib_pdb_args = ['/PDB:' + meson.current_build_dir() / 'libecpg_shared.pdb']
+endif
+
 ecpglib_so = shared_library('libecpg',
   ecpglib_sources + ecpglib_so_sources,
   include_directories: ecpglib_inc,
@@ -46,7 +53,7 @@ ecpglib_so = shared_library('libecpg',
   soversion: host_system != 'windows' ? '6' : '',
   darwin_versions: ['6', '6.' + pg_version_major.to_string()],
   version: '6.' + pg_version_major.to_string(),
-  link_args: export_fmt.format(export_file.full_path()),
+  link_args: [export_fmt.format(export_file.full_path())] + ecpglib_pdb_args,
   link_depends: export_file,
   kwargs: default_lib_args,
 )
diff --git a/src/interfaces/ecpg/pgtypeslib/meson.build b/src/interfaces/ecpg/pgtypeslib/meson.build
index 02301ec9acb..80a1f0db28e 100644
--- a/src/interfaces/ecpg/pgtypeslib/meson.build
+++ b/src/interfaces/ecpg/pgtypeslib/meson.build
@@ -31,6 +31,13 @@ ecpg_pgtypes_st = static_library('libpgtypes',
 )
 ecpg_targets += ecpg_pgtypes_st
 
+# Change shared library's .pdb name so it won't conflict with static library's
+# .pdb file
+ecpg_pgtypes_pdb_args = []
+if host_system == 'windows'
+  ecpg_pgtypes_pdb_args = ['/PDB:' + meson.current_build_dir() / 'libpgtypes_shared.pdb']
+endif
+
 ecpg_pgtypes_so = shared_library('libpgtypes',
   ecpg_pgtypes_sources + ecpg_pgtypes_so_sources,
   include_directories: ecpg_pgtypes_inc,
@@ -40,7 +47,7 @@ ecpg_pgtypes_so = shared_library('libpgtypes',
   version: '3.' + pg_version_major.to_string(),
   soversion: host_system != 'windows' ? '3' : '',
   darwin_versions: ['3', '3.' + pg_version_major.to_string()],
-  link_args: export_fmt.format(export_file.full_path()),
+  link_args: [export_fmt.format(export_file.full_path())] + ecpg_pgtypes_pdb_args,
   link_depends: export_file,
   kwargs: default_lib_args,
 )
-- 
2.50.1

v2-0002-ci-windows-Use-DEBUG-FULL-instead-of-DEBUG-FASTLI.patchtext/x-patch; charset=US-ASCII; name=v2-0002-ci-windows-Use-DEBUG-FULL-instead-of-DEBUG-FASTLI.patchDownload
From 45d25df523f1dd642d1877354755e905392e9359 Mon Sep 17 00:00:00 2001
From: Nazir Bilal Yavuz <byavuz81@gmail.com>
Date: Tue, 12 Aug 2025 19:41:59 +0300
Subject: [PATCH v2 2/2] ci: windows: Use DEBUG:FULL instead of DEBUG:FASTLINK
 while building Postgres

DEBUG:FASTLINK causes the .pdb files of shared and static libraries that
have the same names to conflict. So, use DEBUG:FULL altough it uses more
memory.

Suggested-by: Andres Freund <andres@anarazel.de>
Author: Nazir Bilal Yavuz <byavuz81@gmail.com>
Reviewed-by: Jacob Champion <jacob.champion@enterprisedb.com>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAN55FZ1RuBhJmPWs3Oi%3D9UoezDfrtO-VaU67db5%2B0_uy19uF%2BA%40mail.gmail.com
---
 .cirrus.tasks.yml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.cirrus.tasks.yml b/.cirrus.tasks.yml
index 1a366975d82..b8661dcce8c 100644
--- a/.cirrus.tasks.yml
+++ b/.cirrus.tasks.yml
@@ -730,10 +730,9 @@ task:
     echo 127.0.0.3 pg-loadbalancetest >> c:\Windows\System32\Drivers\etc\hosts
     type c:\Windows\System32\Drivers\etc\hosts
 
-  # 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 -Dinjection_points=true -Db_pch=true -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=%TAR% build
+    meson setup --backend ninja --buildtype debug -Dc_link_args=/DEBUG:FULL -Dcassert=true -Dinjection_points=true -Db_pch=true -Dextra_lib_dirs=c:\openssl\1.1\lib -Dextra_include_dirs=c:\openssl\1.1\include -DTAR=%TAR% build
 
   build_script: |
     vcvarsall x64
-- 
2.50.1

#7Wolfgang Walther
walther@technowledgy.de
In reply to: Nazir Bilal Yavuz (#6)
Re: meson: Add _static and _shared suffixes to the library names

Nazir Bilal Yavuz:

1- Setting different names for .pdb files for shared libraries only on
the Windows OS. I think that is the correct fix, it just adds _shared
suffix to .pdb files of shared libraries on the Windows OS.

How about renaming the .pdb files, but instead of adding _shared, rename
both .pdb files to libpq.a.pdb and libpq.dll.pdb?

I think that would be much clearer than libpq.pdb and libpq_shared.pdb.

Best,

Wolfgang

#8Nazir Bilal Yavuz
byavuz81@gmail.com
In reply to: Wolfgang Walther (#7)
Re: meson: Add _static and _shared suffixes to the library names

Hi,

Thank you for looking into this!

On Wed, 13 Aug 2025 at 10:50, Wolfgang Walther <walther@technowledgy.de> wrote:

Nazir Bilal Yavuz:

1- Setting different names for .pdb files for shared libraries only on
the Windows OS. I think that is the correct fix, it just adds _shared
suffix to .pdb files of shared libraries on the Windows OS.

How about renaming the .pdb files, but instead of adding _shared, rename
both .pdb files to libpq.a.pdb and libpq.dll.pdb?

I think that would be much clearer than libpq.pdb and libpq_shared.pdb.

That works for me. I think the only downside is that there are 22
static_library() and 4 shared_library() calls inside the meson build.
So we need to copy this logic [1]${name}_pdb_args = [] if host_system == 'windows' ${name}_pdb_args = ['/PDB:' + meson.current_build_dir() / '${name}.pdb'] endif 22 times more if we want to rename
static libraries' .pdb files.

[1]: ${name}_pdb_args = [] if host_system == 'windows' ${name}_pdb_args = ['/PDB:' + meson.current_build_dir() / '${name}.pdb'] endif
${name}_pdb_args = []
if host_system == 'windows'
${name}_pdb_args = ['/PDB:' + meson.current_build_dir() / '${name}.pdb']
endif

--
Regards,
Nazir Bilal Yavuz
Microsoft

#9Andres Freund
andres@anarazel.de
In reply to: Nazir Bilal Yavuz (#6)
Re: meson: Add _static and _shared suffixes to the library names

Hi,

On 2025-08-13 09:36:23 +0300, Nazir Bilal Yavuz wrote:

Thank you all for sharing your thoughts and I am sorry for the first
proposal. It is a mistake on my part, I should have thought more.

That's just iterative development, don't worry about it.

On Tue, 12 Aug 2025 at 21:47, Peter Eisentraut <peter@eisentraut.org> wrote:

On 12.08.25 18:37, Jacob Champion wrote:

On Tue, Aug 12, 2025 at 9:27 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

Is there a way to work around this problem in a way that affects Windows only?

Even on Windows, the proposal is unacceptable.

Sure, but I'm hoping that there's some Windows-specific Meson
twiddling that can be done to disambiguate the debug files on disk.

Here is an older discussion that also involved having concurrent
shared_library() and static_library() on Windows, and the general
sentiment there appeared to be that this should (be made to) work:
https://github.com/mesonbuild/meson/issues/459

I think the problem in the link you shared is different, we have
problems with Windows debug files (*.pdb files) but they have problems
with the library files themselves. Our problem is that the latest
built library tries to overwrite the early built library's .pdb file
and the build fails. So, my guess is that the libraries are in
different paths but their .pdb files are still in the same path. I did
a quick check and found that we have only one .pdb file after the
build, which I think confirms my guess. After the #1 fix applied, we
have two .pdb files; one .pdb file for each library type.

Yea.

So I don't know what changed now, but I think we should think about in
terms of what changed rather than fixing our code.

I think we had this problem for a long time but the new ninja version
showed that problem.

Right - I'm fairly sure that if you built sequentially with an older ninja
you'd also see the issue.

I found two ways to fix that problem, both approaches fix the problem
by themselves:

1- Setting different names for .pdb files for shared libraries only on
the Windows OS. I think that is the correct fix, it just adds _shared
suffix to .pdb files of shared libraries on the Windows OS.

I don't think it is right to do this "below" meson - presumably this means
that meson install won't work correctly, as it doesn't know about the changed
pdb file names.

2- Using '/DEBUG:FULL' instead of '/DEBUG:FASTLINK' in the Windows CI
task but this causes more memory to be used. It seems that the error
appears only when the '/DEBUG:FASTLINK' is set. '/DEBUG:FULL' is a
default option, so we may decide to not add it at all. I explicitly
added it as I found this easier to understand. This approach fixes the
build but I think it is not the correct fix, we will have one .pdb
file after this fix; not one for each library type.

I think it's an acceptable fix for now. I added /DEBUG:FASTLINK to the CI
task when it was using windows containers, as we'd run out of memory
occasionally. But since we aren't using those anymore, I think the best way to
make CI work again is to simply stop using /DEBUG:FASTLINK.

Separately I think we should report this as a bug to meson. Could you perhaps
create a minimal reproducer of the issue and report it?

Greetings,

Andres Freund

#10Andres Freund
andres@anarazel.de
In reply to: Andres Freund (#9)
Re: meson: Add _static and _shared suffixes to the library names

Hi,

On 2025-08-13 10:24:07 -0400, Andres Freund wrote:

2- Using '/DEBUG:FULL' instead of '/DEBUG:FASTLINK' in the Windows CI
task but this causes more memory to be used. It seems that the error
appears only when the '/DEBUG:FASTLINK' is set. '/DEBUG:FULL' is a
default option, so we may decide to not add it at all. I explicitly
added it as I found this easier to understand. This approach fixes the
build but I think it is not the correct fix, we will have one .pdb
file after this fix; not one for each library type.

I think it's an acceptable fix for now. I added /DEBUG:FASTLINK to the CI
task when it was using windows containers, as we'd run out of memory
occasionally. But since we aren't using those anymore, I think the best way to
make CI work again is to simply stop using /DEBUG:FASTLINK.

I'll push it this way once the test completes that way in my repo. I want to
get cfbot green again. If we want to do it differently than in Bilal's
v2-0002-ci-windows-Use-DEBUG-FULL-instead-of-DEBUG-FASTLI.patch

I however removed DEBUG:FULL, I don't see a point of explicitly specifying the
default value.

Greetings,

Andres Freund

#11Nazir Bilal Yavuz
byavuz81@gmail.com
In reply to: Andres Freund (#10)
Re: meson: Add _static and _shared suffixes to the library names

Hi,

On Wed, 13 Aug 2025 at 23:03, Andres Freund <andres@anarazel.de> wrote:

Hi,

On 2025-08-13 10:24:07 -0400, Andres Freund wrote:

2- Using '/DEBUG:FULL' instead of '/DEBUG:FASTLINK' in the Windows CI
task but this causes more memory to be used. It seems that the error
appears only when the '/DEBUG:FASTLINK' is set. '/DEBUG:FULL' is a
default option, so we may decide to not add it at all. I explicitly
added it as I found this easier to understand. This approach fixes the
build but I think it is not the correct fix, we will have one .pdb
file after this fix; not one for each library type.

I think it's an acceptable fix for now. I added /DEBUG:FASTLINK to the CI
task when it was using windows containers, as we'd run out of memory
occasionally. But since we aren't using those anymore, I think the best way to
make CI work again is to simply stop using /DEBUG:FASTLINK.

I'll push it this way once the test completes that way in my repo. I want to
get cfbot green again. If we want to do it differently than in Bilal's
v2-0002-ci-windows-Use-DEBUG-FULL-instead-of-DEBUG-FASTLI.patch

Thank you!

Separately I think we should report this as a bug to meson. Could you perhaps
create a minimal reproducer of the issue and report it?

Yes, I will share the issue link for tracking when I report it.

--
Regards,
Nazir Bilal Yavuz
Microsoft

#12Nazir Bilal Yavuz
byavuz81@gmail.com
In reply to: Nazir Bilal Yavuz (#11)
Re: meson: Add _static and _shared suffixes to the library names

Hi,

On Thu, 14 Aug 2025 at 10:37, Nazir Bilal Yavuz <byavuz81@gmail.com> wrote:

On Wed, 13 Aug 2025 at 23:03, Andres Freund <andres@anarazel.de> wrote:

v2-0002-ci-windows-Use-DEBUG-FULL-instead-of-DEBUG-FASTLI.patch

Separately I think we should report this as a bug to meson. Could you perhaps
create a minimal reproducer of the issue and report it?

Yes, I will share the issue link for tracking when I report it.

Here is the link: https://github.com/mesonbuild/meson/issues/14925

--
Regards,
Nazir Bilal Yavuz
Microsoft