| From: | expl0it3r(at)my-gate(dot)net |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Static libpq and ecpglib clash with PThreads4W on Windows |
| Date: | 2026-10-11 16:44:05 |
| Message-ID: | a004d8e3d6d95a560d402afeada99510@my-gate.net |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Hi,
Linking the static libpq on Windows into an application that also uses a
"real" pthreads library like PThreads4W fails with duplicate symbols:
pthreadVC3d.lib(pthread.o) : error LNK2005: pthread_self already
defined in pq.lib(pthread-win32.c.obj)
pthreadVC3d.lib(pthread.o) : error LNK2005: pthread_mutex_init already
defined in pq.lib(pthread-win32.c.obj)
...
libpq and ecpglib each bring a small pthread emulation on Windows
(src/port/pthread-win32.h with src/interfaces/libpq/pthread-win32.c, and
ecpg-pthread-win32.h with the definitions in ecpglib/misc.c), and the
functions are named exactly like the official pthread ones. The static
PThreads4W library is a single object file, so there's no way around it
on the application side.
Depending on the link order, the two emulations also run into each
other. On master, the following program fails to link against the static
libecpg.a, libpq.a and PThreads4W:
#include <stdio.h>
#include <pthread.h>
#include <libpq-fe.h>
extern void *ECPGget_sqlca(void);
int main(void)
{
PGconn *conn = PQconnectdb("host=localhost port=1
connect_timeout=1");
printf("%p %p\n", ECPGget_sqlca(), (void *) pthread_self().p);
PQfinish(conn);
return 0;
}
libpq.a(pthread-win32.c.obj) : error LNK2005: pthread_mutex_init
already defined in libecpg.a(misc.c.obj)
libpq.a(pthread-win32.c.obj) : error LNK2005: pthread_mutex_lock
already defined in libecpg.a(misc.c.obj)
libpq.a(pthread-win32.c.obj) : error LNK2005: pthread_mutex_unlock
already defined in libecpg.a(misc.c.obj)
I ran into this through vcpkg, where pdal on the static Windows triplets
pulls in libpq together with mbedtls built with pthreads. I've patched
the vcpkg version, so the static Windows triplets no longer fail on CI
[1].
The attached patch renames the functions with macros in the two
emulation headers to pq_pthread_* and ecpg_pthread_*. The headers are
included by the definitions and by every caller, and none of the
functions are in exports.txt, so the call sites and the DLL ABI stay the
same. The "Cleaning up threading code" thread [2] discussed essentially
the same fix for the emulations, but it seems that it hasn't been
implemented yet.
Tested with MSVC 2026 and meson on Windows: a full build, the ecpg suite
(66 subtests including the thread tests), and the program above linking
and running against the static libpq, ecpglib and PThreads4W, which
fails on master.
[1] https://github.com/microsoft/vcpkg/pull/54377
[2]
https://postgr.es/m/CA+hUKG+XpCcqoNe3-3oUzuGUeRoxAKqGnEAedvOhotsNCxuS+Q@mail.gmail.com
Kind regards,
Lukas
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0001-Rename-the-Windows-pthread-emulation-functions-in.patch | text/x-diff | 2.6 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Tom Lane | 2026-10-11 18:05:21 | Re: GIN (JSONPath) checks equality only on the first node of each operand |
| Previous Message | Chinmay Kanchi | 2026-10-11 02:04:42 | GIN (JSONPath) checks equality only on the first node of each operand |