diff --git a/meson.build b/meson.build
index 253994931e8..c709643fe5e 100644
--- a/meson.build
+++ b/meson.build
@@ -2619,17 +2619,29 @@ backend_common_code = declare_dependency(
 
 subdir('src/common')
 
-frontend_shlib_code = declare_dependency(
-  compile_args: ['-DFRONTEND'],
-  include_directories: [postgres_inc],
+# all shared libraries should depend on shlib_code
+shlib_code = declare_dependency(
   link_args: ldflags_sl,
-  link_with: [pgport_shlib, common_shlib],
+)
+
+# all static libraries not part of the backend should depend on this
+frontend_stlib_code = declare_dependency(
+  include_directories: [postgres_inc],
+  link_with: [common_static, pgport_static],
   sources: generated_headers,
   dependencies: [os_deps, libintl],
 )
 
+# all shared libraries not part of the backend should depend on this
+frontend_shlib_code = declare_dependency(
+  include_directories: [postgres_inc],
+  link_with: [common_shlib, pgport_shlib],
+  sources: generated_headers,
+  dependencies: [shlib_code, os_deps, libintl],
+)
+
+# Dependencies both for static and shared libpq
 libpq_deps += [
-  frontend_shlib_code,
   thread_dep,
 
   gssapi,
@@ -2642,6 +2654,7 @@ subdir('src/interfaces/libpq')
 # fe_utils depends on libpq
 subdir('src/fe_utils')
 
+# for frontend binaries
 frontend_code = declare_dependency(
   include_directories: [postgres_inc],
   link_with: [fe_utils, common_static, pgport_static],
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index bc047e00d62..34cb58c2617 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -39,26 +39,33 @@ export_file = custom_target('libpq.exports',
 
 # port needs to be in include path due to pthread-win32.h
 libpq_inc = include_directories('.', '../../port')
+libpq_c_args = ['-DSO_MAJOR_VERSION=5']
 
+# Not using both_libraries() here as
+# 1) resource files should only be in the shared library
+# 2) we want the .pc file to include a dependency to {pgport,common}_static for
+#    libpq_st, and {pgport,common}_shlib for libpq_sh
+#
+# We could try to avoid building the source files twice, but it probably adds
+# more complexity than its worth (AIX doesn't support link_whole yet, reusing
+# object files requires also linking to the library on windows or breaks
+# precompiled headers).
 libpq_st = static_library('libpq',
   libpq_sources,
-  pic: true,
-  include_directories: [libpq_inc, postgres_inc],
-  c_args: ['-DSO_MAJOR_VERSION=5'],
-  dependencies: libpq_deps,
+  include_directories: [libpq_inc],
+  c_args: libpq_c_args,
+  dependencies: [frontend_stlib_code, libpq_deps],
   kwargs: default_lib_args,
 )
 
-# not using both_libraries here, causes problems with precompiled headers and
-# resource files with msbuild
 libpq_so = shared_library('libpq',
-  dependencies: libpq_deps,
+  libpq_sources,
   include_directories: [libpq_inc, postgres_inc],
-  c_args: ['-DSO_MAJOR_VERSION=5'],
-  link_whole: libpq_st,
+  c_args: libpq_c_args,
   version: '5.' + pg_version_major.to_string(),
   soversion: host_system != 'windows' ? '5' : '',
   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()),
   kwargs: default_lib_args,
@@ -70,10 +77,11 @@ libpq = declare_dependency(
 )
 
 pkgconfig.generate(
-  libpq_so,
   name: 'libpq',
   description: 'PostgreSQL libpq library',
   url: pg_url,
+  libraries: libpq,
+  libraries_private: [frontend_stlib_code, libpq_deps],
 )
 
 install_headers(