From ec15e1cd0d0db16a421306f884b685fb8f0d22f2 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Wed, 18 May 2022 09:44:53 -0700 Subject: [PATCH v10 12/16] meson: prereq: Can we get away with not export-all'ing libraries? By using explicit export annotations in shared libraries we avoid the need to generate export files on windows. And it reduces the number of exported symbols, which is good too. See also https://www.postgresql.org/message-id/20220111025328.iq5g6uck53j5qtin%40alap3.anarazel.de currently stuck on https://www.postgresql.org/message-id/20220111025328.iq5g6uck53j5qtin%40alap3.anarazel.de --- src/include/c.h | 12 +++++- src/include/fmgr.h | 6 ++- src/include/jit/jit.h | 2 +- src/include/pg_config.h.in | 3 ++ src/include/replication/output_plugin.h | 2 + src/pl/plpython/plpy_elog.h | 8 ++-- src/pl/plpython/plpy_typeio.h | 18 ++++---- src/pl/plpython/plpy_util.h | 8 ++-- contrib/basic_archive/basic_archive.c | 4 +- contrib/hstore/hstore.h | 16 +++---- contrib/ltree/ltree.h | 40 +++++++++--------- src/test/modules/test_shm_mq/test_shm_mq.h | 2 +- src/test/modules/worker_spi/worker_spi.c | 2 +- configure | 49 ++++++++++++++++++++++ configure.ac | 10 +++++ src/Makefile.global.in | 1 + src/Makefile.shlib | 12 ++++++ src/tools/msvc/Solution.pm | 1 + 18 files changed, 144 insertions(+), 52 deletions(-) diff --git a/src/include/c.h b/src/include/c.h index 863a16c6a6c..ad86da1b90c 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -1339,8 +1339,18 @@ extern unsigned long long strtoull(const char *str, char **endptr, int base); /* * Use "extern PGDLLIMPORT ..." to declare variables that are defined * in the core backend and need to be accessible by loadable modules. - * No special marking is required on most ports. */ + +/* + * If the platform knows __attribute__((visibility("*"))), i.e. gcc like + * compilers, we use that. + */ +#if !defined(PGDLLIMPORT) && defined(HAVE_VISIBILITY_ATTRIBUTE) +#define PGDLLIMPORT __attribute__((visibility("default"))) +#define PGDLLEXPORT __attribute__((visibility("default"))) +#endif + +/* No special marking is required on most ports. */ #ifndef PGDLLIMPORT #define PGDLLIMPORT #endif diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 5314b737052..210f9835004 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -413,7 +413,7 @@ typedef const Pg_finfo_record *(*PGFInfoFunction) (void); * info function, since authors shouldn't need to be explicitly aware of it. */ #define PG_FUNCTION_INFO_V1(funcname) \ -extern Datum funcname(PG_FUNCTION_ARGS); \ +extern PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS); \ extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \ const Pg_finfo_record * \ CppConcat(pg_finfo_,funcname) (void) \ @@ -424,6 +424,10 @@ CppConcat(pg_finfo_,funcname) (void) \ extern int no_such_variable +extern PGDLLEXPORT void _PG_init(void); +extern PGDLLEXPORT void _PG_fini(void); + + /*------------------------------------------------------------------------- * Support for verifying backend compatibility of loaded modules * diff --git a/src/include/jit/jit.h b/src/include/jit/jit.h index d1940332094..600ddfc7539 100644 --- a/src/include/jit/jit.h +++ b/src/include/jit/jit.h @@ -63,7 +63,7 @@ typedef struct JitContext typedef struct JitProviderCallbacks JitProviderCallbacks; -extern void _PG_jit_provider_init(JitProviderCallbacks *cb); +extern PGDLLEXPORT void _PG_jit_provider_init(JitProviderCallbacks *cb); typedef void (*JitProviderInit) (JitProviderCallbacks *cb); typedef void (*JitProviderResetAfterErrorCB) (void); typedef void (*JitProviderReleaseContextCB) (JitContext *context); diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 7133c3dc66b..529fb84a86c 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -700,6 +700,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UUID_UUID_H +/* Define to 1 if your compiler knows the visibility("hidden") attribute. */ +#undef HAVE_VISIBILITY_ATTRIBUTE + /* Define to 1 if you have the `wcstombs_l' function. */ #undef HAVE_WCSTOMBS_L diff --git a/src/include/replication/output_plugin.h b/src/include/replication/output_plugin.h index 539dc8e6974..b7d28d7045c 100644 --- a/src/include/replication/output_plugin.h +++ b/src/include/replication/output_plugin.h @@ -35,6 +35,8 @@ typedef struct OutputPluginOptions */ typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb); +extern PGDLLEXPORT void _PG_output_plugin_init(struct OutputPluginCallbacks *cb); + /* * Callback that gets called in a user-defined plugin. ctx->private_data can * be set to some private data. diff --git a/src/pl/plpython/plpy_elog.h b/src/pl/plpython/plpy_elog.h index e02ef4ffe9f..aeade82ce10 100644 --- a/src/pl/plpython/plpy_elog.h +++ b/src/pl/plpython/plpy_elog.h @@ -34,13 +34,13 @@ extern PyObject *PLy_exc_spi_error; } while(0) #endif /* HAVE__BUILTIN_CONSTANT_P */ -extern void PLy_elog_impl(int elevel, const char *fmt,...) pg_attribute_printf(2, 3); +extern PGDLLEXPORT void PLy_elog_impl(int elevel, const char *fmt,...) pg_attribute_printf(2, 3); -extern void PLy_exception_set(PyObject *exc, const char *fmt,...) pg_attribute_printf(2, 3); +extern PGDLLEXPORT void PLy_exception_set(PyObject *exc, const char *fmt,...) pg_attribute_printf(2, 3); -extern void PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural, +extern PGDLLEXPORT void PLy_exception_set_plural(PyObject *exc, const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(2, 5) pg_attribute_printf(3, 5); -extern void PLy_exception_set_with_details(PyObject *excclass, ErrorData *edata); +extern PGDLLEXPORT void PLy_exception_set_with_details(PyObject *excclass, ErrorData *edata); #endif /* PLPY_ELOG_H */ diff --git a/src/pl/plpython/plpy_typeio.h b/src/pl/plpython/plpy_typeio.h index d11e6ae1b89..87e3b2c464e 100644 --- a/src/pl/plpython/plpy_typeio.h +++ b/src/pl/plpython/plpy_typeio.h @@ -147,29 +147,29 @@ struct PLyObToDatum }; -extern PyObject *PLy_input_convert(PLyDatumToOb *arg, Datum val); -extern Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, +extern PGDLLEXPORT PyObject *PLy_input_convert(PLyDatumToOb *arg, Datum val); +extern PGDLLEXPORT Datum PLy_output_convert(PLyObToDatum *arg, PyObject *val, bool *isnull); -extern PyObject *PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, +extern PGDLLEXPORT PyObject *PLy_input_from_tuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc, bool include_generated); -extern void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, +extern PGDLLEXPORT void PLy_input_setup_func(PLyDatumToOb *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, struct PLyProcedure *proc); -extern void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, +extern PGDLLEXPORT void PLy_output_setup_func(PLyObToDatum *arg, MemoryContext arg_mcxt, Oid typeOid, int32 typmod, struct PLyProcedure *proc); -extern void PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, +extern PGDLLEXPORT void PLy_input_setup_tuple(PLyDatumToOb *arg, TupleDesc desc, struct PLyProcedure *proc); -extern void PLy_output_setup_tuple(PLyObToDatum *arg, TupleDesc desc, +extern PGDLLEXPORT void PLy_output_setup_tuple(PLyObToDatum *arg, TupleDesc desc, struct PLyProcedure *proc); -extern void PLy_output_setup_record(PLyObToDatum *arg, TupleDesc desc, +extern PGDLLEXPORT void PLy_output_setup_record(PLyObToDatum *arg, TupleDesc desc, struct PLyProcedure *proc); /* conversion from Python objects to C strings --- exported for transforms */ -extern char *PLyObject_AsString(PyObject *plrv); +extern PGDLLEXPORT char *PLyObject_AsString(PyObject *plrv); #endif /* PLPY_TYPEIO_H */ diff --git a/src/pl/plpython/plpy_util.h b/src/pl/plpython/plpy_util.h index 7c6577925ea..6f491b0f95b 100644 --- a/src/pl/plpython/plpy_util.h +++ b/src/pl/plpython/plpy_util.h @@ -8,10 +8,10 @@ #include "plpython.h" -extern PyObject *PLyUnicode_Bytes(PyObject *unicode); -extern char *PLyUnicode_AsString(PyObject *unicode); +extern PGDLLEXPORT PyObject *PLyUnicode_Bytes(PyObject *unicode); +extern PGDLLEXPORT char *PLyUnicode_AsString(PyObject *unicode); -extern PyObject *PLyUnicode_FromString(const char *s); -extern PyObject *PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size); +extern PGDLLEXPORT PyObject *PLyUnicode_FromString(const char *s); +extern PGDLLEXPORT PyObject *PLyUnicode_FromStringAndSize(const char *s, Py_ssize_t size); #endif /* PLPY_UTIL_H */ diff --git a/contrib/basic_archive/basic_archive.c b/contrib/basic_archive/basic_archive.c index 6b550fc55f7..9816a1f72fb 100644 --- a/contrib/basic_archive/basic_archive.c +++ b/contrib/basic_archive/basic_archive.c @@ -40,8 +40,8 @@ PG_MODULE_MAGIC; -void _PG_init(void); -void _PG_archive_module_init(ArchiveModuleCallbacks *cb); +PGDLLEXPORT void _PG_init(void); +PGDLLEXPORT void _PG_archive_module_init(ArchiveModuleCallbacks *cb); static char *archive_directory = NULL; static MemoryContext basic_archive_context; diff --git a/contrib/hstore/hstore.h b/contrib/hstore/hstore.h index bf4a565ed9b..625134c9f69 100644 --- a/contrib/hstore/hstore.h +++ b/contrib/hstore/hstore.h @@ -147,7 +147,7 @@ typedef struct } while (0) /* DatumGetHStoreP includes support for reading old-format hstore values */ -extern HStore *hstoreUpgrade(Datum orig); +extern PGDLLEXPORT HStore *hstoreUpgrade(Datum orig); #define DatumGetHStoreP(d) hstoreUpgrade(d) @@ -168,14 +168,14 @@ typedef struct bool needfree; /* need to pfree the value? */ } Pairs; -extern int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen); -extern HStore *hstorePairs(Pairs *pairs, int32 pcount, int32 buflen); +extern PGDLLEXPORT int hstoreUniquePairs(Pairs *a, int32 l, int32 *buflen); +extern PGDLLEXPORT HStore *hstorePairs(Pairs *pairs, int32 pcount, int32 buflen); -extern size_t hstoreCheckKeyLen(size_t len); -extern size_t hstoreCheckValLen(size_t len); +extern PGDLLEXPORT size_t hstoreCheckKeyLen(size_t len); +extern PGDLLEXPORT size_t hstoreCheckValLen(size_t len); -extern int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen); -extern Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs); +extern PGDLLEXPORT int hstoreFindKey(HStore *hs, int *lowbound, char *key, int keylen); +extern PGDLLEXPORT Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs); #define HStoreContainsStrategyNumber 7 #define HStoreExistsStrategyNumber 9 @@ -194,7 +194,7 @@ extern Pairs *hstoreArrayToPairs(ArrayType *a, int *npairs); #if HSTORE_POLLUTE_NAMESPACE #define HSTORE_POLLUTE(newname_,oldname_) \ PG_FUNCTION_INFO_V1(oldname_); \ - Datum newname_(PG_FUNCTION_ARGS); \ + extern PGDLLEXPORT Datum newname_(PG_FUNCTION_ARGS); \ Datum oldname_(PG_FUNCTION_ARGS) { return newname_(fcinfo); } \ extern int no_such_variable #else diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h index 564e4fa81b8..85199ba15d1 100644 --- a/contrib/ltree/ltree.h +++ b/contrib/ltree/ltree.h @@ -176,30 +176,30 @@ typedef struct /* use in array iterator */ -Datum ltree_isparent(PG_FUNCTION_ARGS); -Datum ltree_risparent(PG_FUNCTION_ARGS); -Datum ltq_regex(PG_FUNCTION_ARGS); -Datum ltq_rregex(PG_FUNCTION_ARGS); -Datum lt_q_regex(PG_FUNCTION_ARGS); -Datum lt_q_rregex(PG_FUNCTION_ARGS); -Datum ltxtq_exec(PG_FUNCTION_ARGS); -Datum ltxtq_rexec(PG_FUNCTION_ARGS); -Datum _ltq_regex(PG_FUNCTION_ARGS); -Datum _ltq_rregex(PG_FUNCTION_ARGS); -Datum _lt_q_regex(PG_FUNCTION_ARGS); -Datum _lt_q_rregex(PG_FUNCTION_ARGS); -Datum _ltxtq_exec(PG_FUNCTION_ARGS); -Datum _ltxtq_rexec(PG_FUNCTION_ARGS); -Datum _ltree_isparent(PG_FUNCTION_ARGS); -Datum _ltree_risparent(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltree_isparent(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltree_risparent(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltq_regex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltq_rregex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum lt_q_regex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum lt_q_rregex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltxtq_exec(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltxtq_rexec(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _ltq_regex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _ltq_rregex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _lt_q_regex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _lt_q_rregex(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _ltxtq_exec(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _ltxtq_rexec(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _ltree_isparent(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum _ltree_risparent(PG_FUNCTION_ARGS); /* Concatenation functions */ -Datum ltree_addltree(PG_FUNCTION_ARGS); -Datum ltree_addtext(PG_FUNCTION_ARGS); -Datum ltree_textadd(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltree_addltree(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltree_addtext(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltree_textadd(PG_FUNCTION_ARGS); /* Util function */ -Datum ltree_in(PG_FUNCTION_ARGS); +PGDLLEXPORT Datum ltree_in(PG_FUNCTION_ARGS); bool ltree_execute(ITEM *curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM *val)); diff --git a/src/test/modules/test_shm_mq/test_shm_mq.h b/src/test/modules/test_shm_mq/test_shm_mq.h index 0310caf50bd..8f97be78d3e 100644 --- a/src/test/modules/test_shm_mq/test_shm_mq.h +++ b/src/test/modules/test_shm_mq/test_shm_mq.h @@ -40,6 +40,6 @@ extern void test_shm_mq_setup(int64 queue_size, int32 nworkers, shm_mq_handle **input); /* Main entrypoint for a worker. */ -extern void test_shm_mq_main(Datum) pg_attribute_noreturn(); +extern PGDLLEXPORT void test_shm_mq_main(Datum) pg_attribute_noreturn(); #endif diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c index 5b541ec47f1..c4c9b4f48db 100644 --- a/src/test/modules/worker_spi/worker_spi.c +++ b/src/test/modules/worker_spi/worker_spi.c @@ -47,7 +47,7 @@ PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(worker_spi_launch); void _PG_init(void); -void worker_spi_main(Datum) pg_attribute_noreturn(); +PGDLLEXPORT void worker_spi_main(Datum) pg_attribute_noreturn(); /* GUC variables */ static int worker_spi_naptime = 10; diff --git a/configure b/configure index 1e63c6862bc..ae0aa991407 100755 --- a/configure +++ b/configure @@ -741,6 +741,7 @@ CPP CFLAGS_SL BITCODE_CXXFLAGS BITCODE_CFLAGS +CFLAGS_SL_MOD CFLAGS_VECTORIZE CFLAGS_UNROLL_LOOPS PERMIT_DECLARATION_AFTER_STATEMENT @@ -6485,6 +6486,54 @@ fi if test -n "$NOT_THE_CFLAGS"; then CFLAGS="$CFLAGS -Wno-stringop-truncation" fi + + # If the compiler knows how to hide symbols, use that. But only for shared libraries, + # for postgres itself that'd be too verbose for now. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -fvisibility=hidden, for CFLAGS_SL_MOD" >&5 +$as_echo_n "checking whether ${CC} supports -fvisibility=hidden, for CFLAGS_SL_MOD... " >&6; } +if ${pgac_cv_prog_CC_cflags__fvisibility_hidden+:} false; then : + $as_echo_n "(cached) " >&6 +else + pgac_save_CFLAGS=$CFLAGS +pgac_save_CC=$CC +CC=${CC} +CFLAGS="${CFLAGS_SL_MOD} -fvisibility=hidden" +ac_save_c_werror_flag=$ac_c_werror_flag +ac_c_werror_flag=yes +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + pgac_cv_prog_CC_cflags__fvisibility_hidden=yes +else + pgac_cv_prog_CC_cflags__fvisibility_hidden=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_c_werror_flag=$ac_save_c_werror_flag +CFLAGS="$pgac_save_CFLAGS" +CC="$pgac_save_CC" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__fvisibility_hidden" >&5 +$as_echo "$pgac_cv_prog_CC_cflags__fvisibility_hidden" >&6; } +if test x"$pgac_cv_prog_CC_cflags__fvisibility_hidden" = x"yes"; then + CFLAGS_SL_MOD="${CFLAGS_SL_MOD} -fvisibility=hidden" +fi + + + if test "$pgac_cv_prog_CC_cflags__fvisibility_hidden" = yes; then + +$as_echo "#define HAVE_VISIBILITY_ATTRIBUTE 1" >>confdefs.h + + fi + elif test "$ICC" = yes; then # Intel's compiler has a bug/misoptimization in checking for # division by NAN (NaN == 0), -mp1 fixes it, so add it to the CFLAGS. diff --git a/configure.ac b/configure.ac index 71191f14ad7..459ae04b446 100644 --- a/configure.ac +++ b/configure.ac @@ -555,6 +555,15 @@ if test "$GCC" = yes -a "$ICC" = no; then if test -n "$NOT_THE_CFLAGS"; then CFLAGS="$CFLAGS -Wno-stringop-truncation" fi + + # If the compiler knows how to hide symbols, use that. But only for shared libraries, + # for postgres itself that'd be too verbose for now. + PGAC_PROG_CC_VAR_OPT(CFLAGS_SL_MOD, [-fvisibility=hidden]) + if test "$pgac_cv_prog_CC_cflags__fvisibility_hidden" = yes; then + AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE, 1, + [Define to 1 if your compiler knows the visibility("hidden") attribute.]) + fi + elif test "$ICC" = yes; then # Intel's compiler has a bug/misoptimization in checking for # division by NAN (NaN == 0), -mp1 fixes it, so add it to the CFLAGS. @@ -573,6 +582,7 @@ fi AC_SUBST(CFLAGS_UNROLL_LOOPS) AC_SUBST(CFLAGS_VECTORIZE) +AC_SUBST(CFLAGS_SL_MOD) # Determine flags used to emit bitcode for JIT inlining. # 1. We must duplicate any behaviour-changing compiler flags used above, diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 138d66ac006..7f1b2c52bf8 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -258,6 +258,7 @@ SUN_STUDIO_CC = @SUN_STUDIO_CC@ CXX = @CXX@ CFLAGS = @CFLAGS@ CFLAGS_SL = @CFLAGS_SL@ +CFLAGS_SL_MOD = @CFLAGS_SL_MOD@ CFLAGS_UNROLL_LOOPS = @CFLAGS_UNROLL_LOOPS@ CFLAGS_VECTORIZE = @CFLAGS_VECTORIZE@ CFLAGS_SSE42 = @CFLAGS_SSE42@ diff --git a/src/Makefile.shlib b/src/Makefile.shlib index 6df96c634b6..5160d5c71df 100644 --- a/src/Makefile.shlib +++ b/src/Makefile.shlib @@ -218,6 +218,18 @@ ifeq ($(PORTNAME), win32) endif +# If the shared library doesn't have an export file, mark all symbols not +# explicitly exported using PGDLLEXPORT as hidden. We can't pass these flags +# when building a library with explicit exports, as the symbols would be +# hidden before the linker script / exported symbol list takes effect. +# +# XXX: This probably isn't the best location, but not clear instead? +ifeq ($(SHLIB_EXPORTS),) + LDFLAGS += $(CFLAGS_SL_MOD) + override CFLAGS += $(CFLAGS_SL_MOD) + override CXXFLAGS += $(CFLAGS_SL_MOD) +endif + ## ## BUILD diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm index c80441c7c8f..1e125aef942 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -429,6 +429,7 @@ sub GenerateFiles HAVE_WINLDAP_H => undef, HAVE_WCSTOMBS_L => 1, HAVE_WCTYPE_H => 1, + HAVE_VISIBILITY_ATTRIBUTE => undef, HAVE_WRITEV => undef, HAVE_X509_GET_SIGNATURE_NID => 1, HAVE_X86_64_POPCNTQ => undef, -- 2.37.0.3.g30cc8d0f14