mirror of
https://github.com/postgres/postgres.git
synced 2026-07-13 11:50:50 -04:00
The additional packaging footprint of the OAuth Curl dependency, as well
as the existence of libcurl in the address space even if OAuth isn't
ever used by a client, has raised some concerns. Split off this
dependency into a separate loadable module called libpq-oauth.
When configured using --with-libcurl, libpq.so searches for this new
module via dlopen(). End users may choose not to install the libpq-oauth
module, in which case the default flow is disabled.
For static applications using libpq.a, the libpq-oauth staticlib is a
mandatory link-time dependency for --with-libcurl builds. libpq.pc has
been updated accordingly.
The default flow relies on some libpq internals. Some of these can be
safely duplicated (such as the SIGPIPE handlers), but others need to be
shared between libpq and libpq-oauth for thread-safety. To avoid
exporting these internals to all libpq clients forever, these
dependencies are instead injected from the libpq side via an
initialization function. This also lets libpq communicate the offsets of
PGconn struct members to libpq-oauth, so that we can function without
crashing if the module on the search path came from a different build of
Postgres. (A minor-version upgrade could swap the libpq-oauth module out
from under a long-running libpq client before it does its first load of
the OAuth flow.)
This ABI is considered "private". The module has no SONAME or version
symlinks, and it's named libpq-oauth-<major>.so to avoid mixing and
matching across Postgres versions. (Future improvements may promote this
"OAuth flow plugin" to a first-class concept, at which point we would
need a public API to replace this anyway.)
Additionally, NLS support for error messages in b3f0be788a was
incomplete, because the new error macros weren't being scanned by
xgettext. Fix that now.
Per request from Tom Lane and Bruce Momjian. Based on an initial patch
by Daniel Gustafsson, who also contributed docs changes. The "bare"
dlopen() concept came from Thomas Munro. Many people reviewed the design
and implementation; thank you!
Co-authored-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Andres Freund <andres@anarazel.de>
Reviewed-by: Christoph Berg <myon@debian.org>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Jelte Fennema-Nio <postgres@jeltef.nl>
Reviewed-by: Peter Eisentraut <peter@eisentraut.org>
Reviewed-by: Wolfgang Walther <walther@technowledgy.de>
Discussion: https://postgr.es/m/641687.1742360249%40sss.pgh.pa.us
274 lines
7 KiB
Meson
274 lines
7 KiB
Meson
# Copyright (c) 2022-2025, PostgreSQL Global Development Group
|
|
|
|
### Compute pgxs_data, used in src/meson.build to generate Makefile.global
|
|
### etc, that's complete enough for PGXS to work.
|
|
|
|
|
|
# Emulation of PGAC_CHECK_STRIP
|
|
strip_bin = find_program(get_option('STRIP'), required: false, native: true)
|
|
strip_cmd = strip_bin.found() ? [strip_bin.path()] : [':']
|
|
|
|
working_strip = false
|
|
if strip_bin.found()
|
|
strip_version = run_command(strip_bin, '-V', check: false)
|
|
|
|
if strip_version.returncode() == 0 and (
|
|
strip_version.stdout().contains('GNU strip') or
|
|
strip_version.stderr().contains('GNU strip'))
|
|
working_strip = true
|
|
strip_static_cmd = strip_cmd + ['--strip-unneeded']
|
|
strip_shared_cmd = strip_cmd + ['--strip-unneeded']
|
|
elif host_system == 'darwin'
|
|
working_strip = true
|
|
strip_static_cmd = strip_cmd + ['-x']
|
|
strip_shared_cmd = strip_cmd + ['-x']
|
|
endif
|
|
endif
|
|
|
|
if not working_strip
|
|
strip_cmd = [':']
|
|
strip_static_cmd = [':']
|
|
strip_shared_cmd = [':']
|
|
endif
|
|
|
|
|
|
pgxs_kv = {
|
|
'PACKAGE_URL': pg_url,
|
|
'PACKAGE_VERSION': pg_version,
|
|
'PG_MAJORVERSION': pg_version_major,
|
|
'PG_VERSION_NUM': pg_version_num,
|
|
'configure_input': 'meson',
|
|
|
|
'vpath_build': 'yes',
|
|
'autodepend': cc.get_argument_syntax() == 'gcc' ? 'yes' : 'no',
|
|
|
|
'host_cpu': host_cpu,
|
|
'host': '@0@-@1@'.format(host_cpu, host_system),
|
|
'host_os': host_system,
|
|
'build_os': build_machine.system(),
|
|
'PORTNAME': portname,
|
|
'PG_SYSROOT': pg_sysroot,
|
|
|
|
'abs_top_builddir': meson.build_root(),
|
|
'abs_top_srcdir': meson.source_root(),
|
|
|
|
'enable_rpath': get_option('rpath') ? 'yes' : 'no',
|
|
'enable_nls': libintl.found() ? 'yes' : 'no',
|
|
'enable_injection_points': get_option('injection_points') ? 'yes' : 'no',
|
|
'enable_tap_tests': tap_tests_enabled ? 'yes' : 'no',
|
|
'enable_debug': get_option('debug') ? 'yes' : 'no',
|
|
'enable_coverage': 'no',
|
|
'enable_dtrace': dtrace.found() ? 'yes' : 'no',
|
|
|
|
'DLSUFFIX': dlsuffix,
|
|
'EXEEXT': exesuffix,
|
|
|
|
'SUN_STUDIO_CC': 'no', # not supported so far
|
|
|
|
# want the chosen option, rather than the library
|
|
'with_ssl' : ssl_library,
|
|
'with_uuid': uuidopt,
|
|
|
|
'default_port': get_option('pgport'),
|
|
'with_system_tzdata': get_option('system_tzdata'),
|
|
|
|
'with_krb_srvnam': get_option('krb_srvnam'),
|
|
'krb_srvtab': krb_srvtab,
|
|
|
|
'STRIP': ' '.join(strip_cmd),
|
|
'STRIP_STATIC_LIB': ' '.join(strip_static_cmd),
|
|
'STRIP_SHARED_LIB': ' '.join(strip_shared_cmd),
|
|
|
|
# these seem to be standard these days
|
|
'MKDIR_P': 'mkdir -p',
|
|
'LN_S': 'ln -s',
|
|
# Just always use the install_sh fallback that autoconf uses. Unlikely to
|
|
# matter performance-wise for extensions. If it turns out to do, we can
|
|
'install_bin': '$(SHELL) $(top_srcdir)/config/install-sh -c',
|
|
|
|
'CC': var_cc,
|
|
'CPP': var_cpp,
|
|
'GCC': cc.get_argument_syntax() == 'gcc' ? 'yes' : 'no',
|
|
|
|
'CPPFLAGS': var_cppflags,
|
|
'CFLAGS': var_cflags,
|
|
'CXXFLAGS': var_cxxflags,
|
|
'CFLAGS_SL': var_cflags_sl,
|
|
'CFLAGS_SL_MODULE': ' '.join(cflags_mod),
|
|
'CXXFLAGS_SL_MODULE': ' '.join(cxxflags_mod),
|
|
'PERMIT_DECLARATION_AFTER_STATEMENT':
|
|
' '.join(cflags_no_decl_after_statement),
|
|
'PERMIT_MISSING_VARIABLE_DECLARATIONS':
|
|
' '.join(cflags_no_missing_var_decls),
|
|
|
|
'CFLAGS_CRC': ' '.join(cflags_crc),
|
|
'CFLAGS_UNROLL_LOOPS': ' '.join(unroll_loops_cflags),
|
|
'CFLAGS_VECTORIZE': ' '.join(vectorize_cflags),
|
|
|
|
'LDFLAGS': var_ldflags,
|
|
'LDFLAGS_EX': var_ldflags_ex,
|
|
'LDFLAGS_EX_BE':
|
|
' '.join(cc.get_supported_link_arguments('-Wl,--export-dynamic')),
|
|
'LDFLAGS_SL': var_ldflags_sl,
|
|
|
|
# TODO: requires bitcode generation to be implemented for meson
|
|
'BITCODE_CFLAGS': '',
|
|
'BITCODE_CXXFLAGS': '',
|
|
|
|
'BISONFLAGS': ' '.join(bison_flags),
|
|
'FLEXFLAGS': ' '.join(flex_flags),
|
|
|
|
'LIBS': var_libs,
|
|
}
|
|
|
|
if llvm.found()
|
|
pgxs_kv += {
|
|
'CLANG': clang.path(),
|
|
'CXX': ' '.join(cpp.cmd_array()),
|
|
'LLVM_BINPATH': llvm_binpath,
|
|
}
|
|
else
|
|
pgxs_kv += {
|
|
'CLANG': '',
|
|
'CXX': '',
|
|
'LLVM_BINPATH': '',
|
|
}
|
|
endif
|
|
|
|
pgxs_bins = {
|
|
'AR':
|
|
find_program(['ar'], native: true, required: false),
|
|
'AWK':
|
|
find_program(['gawk', 'mawk', 'nawk', 'awk'], native: true, required: false),
|
|
'BISON': bison,
|
|
'FLEX': flex,
|
|
'GZIP': gzip,
|
|
'LZ4': program_lz4,
|
|
'OPENSSL': openssl,
|
|
'PERL': perl,
|
|
'PROVE': prove,
|
|
'PYTHON': python,
|
|
'TAR': tar,
|
|
'ZSTD': program_zstd,
|
|
'DTRACE': dtrace,
|
|
}
|
|
|
|
pgxs_empty = [
|
|
'ICU_CFLAGS', # needs to be added, included by public server headers
|
|
|
|
# hard to see why we'd need either?
|
|
'ZIC',
|
|
'TCLSH',
|
|
|
|
# docs don't seem to be supported by pgxs
|
|
'XMLLINT',
|
|
'XSLTPROC',
|
|
'DBTOEPUB',
|
|
'FOP',
|
|
|
|
# supporting coverage for pgxs-in-meson build doesn't seem worth it
|
|
'GENHTML',
|
|
'LCOV',
|
|
'GCOV',
|
|
'MSGFMT_FLAGS',
|
|
|
|
# translation doesn't appear to be supported by pgxs
|
|
'MSGFMT',
|
|
'XGETTEXT',
|
|
'MSGMERGE',
|
|
'WANTED_LANGUAGES',
|
|
|
|
# Not needed because we don't build the server / PLs with the generated makefile
|
|
'LIBOBJS', 'PG_CRC32C_OBJS', 'TAS',
|
|
'PG_TEST_EXTRA',
|
|
'DTRACEFLAGS', # only server has dtrace probes
|
|
|
|
'perl_archlibexp', 'perl_embed_ccflags', 'perl_embed_ldflags', 'perl_includespec', 'perl_privlibexp',
|
|
'python_additional_libs', 'python_includespec', 'python_libdir', 'python_libspec', 'python_majorversion', 'python_version',
|
|
|
|
# possible that some of these are referenced explicitly in pgxs makefiles?
|
|
# For now not worth it.
|
|
'TCL_INCLUDE_SPEC', 'TCL_LIBS', 'TCL_LIB_SPEC', 'TCL_SHARED_BUILD',
|
|
|
|
'LLVM_CFLAGS', 'LLVM_CPPFLAGS', 'LLVM_CXXFLAGS', 'LLVM_LIBS',
|
|
|
|
'LDAP_LIBS_BE', 'LDAP_LIBS_FE',
|
|
|
|
'UUID_LIBS',
|
|
|
|
'PTHREAD_CFLAGS', 'PTHREAD_LIBS',
|
|
|
|
'ICU_LIBS',
|
|
|
|
'LIBNUMA_CFLAGS', 'LIBNUMA_LIBS',
|
|
|
|
'LIBURING_CFLAGS', 'LIBURING_LIBS',
|
|
|
|
'LIBCURL_CPPFLAGS', 'LIBCURL_LDFLAGS', 'LIBCURL_LDLIBS',
|
|
]
|
|
|
|
if host_system == 'windows' and cc.get_argument_syntax() != 'msvc'
|
|
pgxs_bins += {'WINDRES': windres}
|
|
else
|
|
pgxs_empty += 'WINDRES'
|
|
endif
|
|
|
|
pgxs_dirs = {
|
|
'prefix': get_option('prefix'),
|
|
|
|
'bindir': '${exec_prefix}' / get_option('bindir'),
|
|
'datarootdir': '${prefix}' / get_option('datadir'),
|
|
'datadir': '${datarootdir}',
|
|
'docdir': '${prefix}' / dir_doc,
|
|
'exec_prefix': '${prefix}',
|
|
'htmldir': '${docdir}',
|
|
'includedir': '${prefix}' / get_option('includedir'),
|
|
'libdir': '${exec_prefix}' / get_option('libdir'),
|
|
'localedir': '${prefix}' / get_option('localedir'),
|
|
'mandir': '${prefix}' / get_option('mandir'),
|
|
'sysconfdir': '${prefix}' / get_option('sysconfdir'),
|
|
}
|
|
|
|
pgxs_deps = {
|
|
'bonjour': bonjour,
|
|
'bsd_auth': bsd_auth,
|
|
'gssapi': gssapi,
|
|
'icu': icu,
|
|
'ldap': ldap,
|
|
'libcurl': libcurl,
|
|
'libnuma': libnuma,
|
|
'liburing': liburing,
|
|
'libxml': libxml,
|
|
'libxslt': libxslt,
|
|
'llvm': llvm,
|
|
'lz4': lz4,
|
|
'nls': libintl,
|
|
'pam': pam,
|
|
'perl': perl_dep,
|
|
'python': python3_dep,
|
|
'readline': readline,
|
|
'selinux': selinux,
|
|
'systemd': systemd,
|
|
'tcl': tcl_dep,
|
|
'zlib': zlib,
|
|
'zstd': zstd,
|
|
}
|
|
|
|
|
|
pgxs_cdata = configuration_data(pgxs_kv)
|
|
|
|
foreach b, p : pgxs_bins
|
|
pgxs_cdata.set(b, p.found() ? p.path() : '')
|
|
endforeach
|
|
|
|
foreach pe : pgxs_empty
|
|
pgxs_cdata.set(pe, '')
|
|
endforeach
|
|
|
|
foreach d, p : pgxs_dirs
|
|
pgxs_cdata.set(d, p)
|
|
endforeach
|
|
|
|
foreach d, v : pgxs_deps
|
|
pgxs_cdata.set('with_@0@'.format(d), v.found() ? 'yes' : 'no')
|
|
endforeach
|