diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile index d69bd89572a..e80e57e4579 100644 --- a/src/bin/initdb/Makefile +++ b/src/bin/initdb/Makefile @@ -16,13 +16,12 @@ subdir = src/bin/initdb top_builddir = ../../.. include $(top_builddir)/src/Makefile.global -override CPPFLAGS := -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(ICU_CFLAGS) $(CPPFLAGS) - # Note: it's important that we link to encnames.o from libpgcommon, not # from libpq, else we have risks of version skew if we run with a libpq -# shared library from a different PG version. The libpq_pgport macro -# should ensure that that happens. -# +# shared library from a different PG version. Define +# USE_PRIVATE_ENCODING_FUNCS to ensure that that happens. +override CPPFLAGS := -DUSE_PRIVATE_ENCODING_FUNCS -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(ICU_CFLAGS) $(CPPFLAGS) + # We need libpq only because fe_utils does. LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport) $(ICU_LIBS) diff --git a/src/bin/initdb/meson.build b/src/bin/initdb/meson.build index 49743630aad..d477ff1c03e 100644 --- a/src/bin/initdb/meson.build +++ b/src/bin/initdb/meson.build @@ -7,8 +7,6 @@ initdb_sources = files( initdb_sources += timezone_localtime_source -#fixme: reimplement libpq_pgport logic - if host_system == 'windows' initdb_sources += rc_bin_gen.process(win32ver_rc, extra_args: [ '--NAME', 'initdb', @@ -18,6 +16,11 @@ endif initdb = executable('initdb', initdb_sources, include_directories: [timezone_inc], + # Note: it's important that we link to encnames.o from libpgcommon, not + # from libpq, else we have risks of version skew if we run with a libpq + # shared library from a different PG version. Define + # USE_PRIVATE_ENCODING_FUNCS to ensure that that happens. + c_args: ['-DUSE_PRIVATE_ENCODING_FUNCS'], dependencies: [frontend_code, libpq, icu, icu_i18n], kwargs: default_bin_args, ) diff --git a/src/common/Makefile b/src/common/Makefile index cc5c54dcee4..70884be00c3 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -140,6 +140,13 @@ libpgcommon.a: $(OBJS_FRONTEND) rm -f $@ $(AR) $(AROPT) $@ $^ +# +# Files in libpgcommon.a should use/export the "xxx_private" versions +# of pg_char_to_encoding() and friends. +# +$(OBJS_FRONTEND): CPPFLAGS += -DUSE_PRIVATE_ENCODING_FUNCS + + # # Shared library versions of object files # diff --git a/src/common/meson.build b/src/common/meson.build index 3b97497d1a9..ae05ac63cff 100644 --- a/src/common/meson.build +++ b/src/common/meson.build @@ -112,8 +112,8 @@ common_sources_frontend_static += files( 'logging.c', ) -# Build pgport once for backend, once for use in frontend binaries, and once -# for use in shared libraries +# Build pgcommon once for backend, once for use in frontend binaries, and +# once for use in shared libraries # # XXX: in most environments we could probably link_whole pgcommon_shlib # against pgcommon_static, instead of compiling twice. @@ -131,6 +131,9 @@ pgcommon_variants = { '': default_lib_args + { 'sources': common_sources_frontend_static, 'dependencies': [frontend_common_code], + # Files in libpgcommon.a should use/export the "xxx_private" versions + # of pg_char_to_encoding() and friends. + 'c_args': ['-DUSE_PRIVATE_ENCODING_FUNCS'], }, '_shlib': default_lib_args + { 'pic': true, diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h index 25276b199fe..29cd5732f15 100644 --- a/src/include/mb/pg_wchar.h +++ b/src/include/mb/pg_wchar.h @@ -13,6 +13,9 @@ * included by libpq client programs. In particular, a libpq client * should not assume that the encoding IDs used by the version of libpq * it's linked to match up with the IDs declared here. + * To help prevent mistakes, relevant functions that are exported by + * libpq have a physically different name when being referenced + * statically. * *------------------------------------------------------------------------- */ @@ -562,6 +565,23 @@ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second) } +/* + * The functions in this list are exported by libpq, and we need to be sure + * that we know which calls are satisfied by libpq and which are satisfied + * by static linkage to libpgcommon. (This is because we might be using a + * libpq.so that's of a different major version and has encoding IDs that + * differ from the current version's.) The nominal function names are what + * are actually used in and exported by libpq, while the names exported by + * libpgcommon.a and libpgcommon_srv.a end in "_private". + */ +#if defined(USE_PRIVATE_ENCODING_FUNCS) || !defined(FRONTEND) +#define pg_char_to_encoding pg_char_to_encoding_private +#define pg_encoding_to_char pg_encoding_to_char_private +#define pg_valid_server_encoding pg_valid_server_encoding_private +#define pg_valid_server_encoding_id pg_valid_server_encoding_id_private +#define pg_utf_mblen pg_utf_mblen_private +#endif + /* * These functions are considered part of libpq's exported API and * are also declared in libpq-fe.h.