Skip to content

odbc: build the ODBC shim as a Windows DLL (Windows port, phase 2) - #10

Merged
lemenkov merged 1 commit into
masterfrom
windows-odbc-shim
Jul 25, 2026
Merged

odbc: build the ODBC shim as a Windows DLL (Windows port, phase 2)#10
lemenkov merged 1 commit into
masterfrom
windows-odbc-shim

Conversation

@lemenkov

Copy link
Copy Markdown
Owner

Phase 2 of the Windows port: re-enable src/odbc on Windows (Phase 1 #8 gated it off) and get it compiling and exporting as seerodbc.dll under MinGW-w64. Builds on #8 and the iconv fix #9.

The good news

The *W path needed no work — it already uses sizeof(SQLWCHAR) + UTF-16 throughout, which matches Windows' 2-byte SQLWCHAR. So the scary "UTF-16 vs UTF-32" landmine was a non-issue, and this is mostly headers, a few libc shims, and the PE export mechanism.

Changes

  • src/odbc/odbc_platform.h (new) — pulls <windows.h> before the native ODBC headers (which use HWND/DWORD/GUID without defining them). Included ahead of <sql*.h> in odbc_internal.h, convert.h, unicode.c (convert.c gets it transitively).
  • src/common/compat.{c,h} — three more portable libc replacements the Windows CRT lacks: seer_strndup (exec.c, sqlprep.c), seer_strcasestr (catalog.c), seer_getline (odbcini.c). Used on every platform (one code path).
  • odbcini.cseer_getline, and "r" instead of "re" (no O_CLOEXEC on Windows).
  • src/common/log.h — check seer_log's format against the gnu_printf archetype on MinGW. The bare printf archetype there means msvcrt (no %z/%ll), so -Wformat wrongly rejected our %zu; we already build with __USE_MINGW_ANSI_STDIO, so gnu_printf is the matching, warning-clean choice. (Also silences the pre-existing tns %z warnings.)
  • src/odbc/seerodbc.def (new) + meson — the PE equivalent of seerodbc.map/.exp. GNU ld applies version scripts only to ELF, so PE restricts exports via a .def. Verified the DLL exports exactly the 64 SQL* entry points and nothing else (no core/OpenSSL leakage). Names are undecorated so a future 32-bit __stdcall build still exports plain SQLConnect, not _SQLConnect@N.
  • tests/meson.build — skip test_odbcini on Windows for now (the reader builds; only the test's mkdtemp/setenv harness isn't ported, and file-based odbc.ini matters less where DSNs live in the registry — both land with the later registry/DSN phase).

Verification

  • Fedora mingw-w64 cross-toolchain (new local loop): full tree (core + shim) builds warning-clean; the DLL's export table matches seerodbc.def exactly (64 SQL*, nothing else).
  • Native Linux: offline 9/0/4, live 11g integration OK under ASan/UBSan — the portable compat replacements are behavior-identical.
  • The MinGW compile of the shim is validated by the Build + unit (Windows/MinGW) CI job here.

Next (Phase 3)

Loads under the MS Driver Manager + live query; InitOnceExecuteOnce; and the registry/DSN work (SQLGetPrivateProfileString) — which is also when test_odbcini gets its Windows port.

🤖 Generated with Claude Code

Phase 2 of the Windows port: re-enable src/odbc on Windows (Phase 1 had
gated it off) and get it compiling and exporting as seerodbc.dll under
MinGW-w64. The *W path needed no work - it already uses sizeof(SQLWCHAR)
+ UTF-16 throughout, which matches Windows' 2-byte SQLWCHAR - so this is
mostly headers, a few more libc shims, and the PE export mechanism.

  * src/odbc/odbc_platform.h (new): pulls <windows.h> before the native
    ODBC headers, which use HWND/DWORD/GUID/... without defining them.
    Included ahead of <sql*.h> in odbc_internal.h, convert.h and
    unicode.c (convert.c gets it transitively via convert.h).
  * src/common/compat.{c,h}: three more portable libc replacements the
    Windows CRT lacks - seer_strndup (exec.c, sqlprep.c), seer_strcasestr
    (catalog.c) and seer_getline (odbcini.c) - used on every platform.
  * odbcini.c: seer_getline for getline, and "r" instead of "re" (no
    O_CLOEXEC concept on Windows).
  * src/common/log.h: check seer_log's format string against the
    gnu_printf archetype on MinGW. The bare "printf" archetype there means
    msvcrt, which lacks %z/%ll, so -Wformat wrongly rejected our %zu (and
    miscounted trailing args); we already build with __USE_MINGW_ANSI_STDIO,
    so gnu_printf is the matching, warning-clean choice.
  * src/odbc/seerodbc.def (new) + meson: the PE equivalent of
    seerodbc.map / seerodbc.exp. GNU ld honours version scripts only for
    ELF, so PE restricts exports via a .def. Verified: the DLL exports
    exactly the 64 SQL* entry points and nothing else (no core/OpenSSL
    leakage). Names are undecorated so a future 32-bit __stdcall build
    still exports plain SQLConnect, not _SQLConnect@N.
  * tests/meson.build: skip test_odbcini on Windows for now - the reader
    builds there, but the test's harness (mkdtemp/setenv/POSIX temp paths)
    is not yet ported, and file-based odbc.ini matters less where DSNs
    live in the registry; both land with the later registry/DSN phase.

Validated on the Fedora mingw-w64 cross-toolchain: full tree (core +
shim) builds warning-clean and the DLL's export table matches the .def.
No behaviour change on POSIX: native Linux offline 9/0/4 and live 11g
integration pass under ASan/UBSan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
@lemenkov
lemenkov merged commit c9c680c into master Jul 25, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant