From b69cab3e83cce4732a0539fb6aea929e7fb04cdf Mon Sep 17 00:00:00 2001 From: Evert Lammerts Date: Fri, 8 May 2026 10:06:53 +0200 Subject: [PATCH 1/2] Export all symbols --- CMakeLists.txt | 31 ------------------------------- src/duckdb_py/duckdb_python.cpp | 16 +++++----------- 2 files changed, 5 insertions(+), 42 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02a059c7..88dc2e36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,37 +81,6 @@ pybind11_add_module( target_link_libraries(_duckdb PRIVATE _duckdb_dependencies) duckdb_link_extensions(_duckdb) -# ──────────────────────────────────────────── -# Controlling symbol export -# -# We want to export exactly two symbols: - PyInit__duckdb: this allows CPython -# to load the module - duckdb_adbc_init: the DuckDB ADBC driver -# -# The export of symbols on OSX and Linux is controlled by: - Visibility -# annotations in the code (for this lib we use the PYBIND11_EXPORT macro) - -# Telling the linker which symbols we want exported, which we do below -# -# For Windows, we rely on just the visbility annotations. -# ──────────────────────────────────────────── -set_target_properties( - _duckdb - PROPERTIES CXX_VISIBILITY_PRESET hidden - C_VISIBILITY_PRESET hidden - VISIBILITY_INLINES_HIDDEN ON) - -if(APPLE) - target_link_options( - _duckdb PRIVATE "LINKER:-exported_symbol,_duckdb_adbc_init" - "LINKER:-exported_symbol,_PyInit__duckdb") -elseif(UNIX AND NOT APPLE) - target_link_options( - _duckdb PRIVATE "LINKER:--export-dynamic-symbol=duckdb_adbc_init" - "LINKER:--export-dynamic-symbol=PyInit__duckdb") -elseif(WIN32) - target_link_options(_duckdb PRIVATE "/EXPORT:duckdb_adbc_init" - "/EXPORT:PyInit__duckdb") -endif() - # ──────────────────────────────────────────── # Put the object file in the correct place # ──────────────────────────────────────────── diff --git a/src/duckdb_py/duckdb_python.cpp b/src/duckdb_py/duckdb_python.cpp index eea21519..d950960d 100644 --- a/src/duckdb_py/duckdb_python.cpp +++ b/src/duckdb_py/duckdb_python.cpp @@ -1051,22 +1051,16 @@ static void RegisterExpectedResultType(py::handle &m) { } // ###################################################################### -// Symbol exports +// Force inclusion of symbols that are not referenced by any code in the +// Python module but must be present in the shared object. // -// We want to limit the symbols we export to only the absolute minimum. -// This means we compile with -fvisibility=hidden to hide all symbols, -// and then explicitly export only the symbols we want. +// duckdb_adbc_init: entrypoint for the ADBC driver. Not called from Python +// code, but loaded by adbc_driver_manager via dlsym/GetProcAddress. // -// Right now we export two symbols only: -// - duckdb_adbc_init: the entrypoint for our ADBC driver -// - PyInit__duckdb: the entrypoint for the python extension -// -// All symbols that need exporting must be added to both the list below -// AND to CMakeLists.txt. +// Without this, the linker may strip these as dead code. extern "C" { PYBIND11_EXPORT void *_force_symbol_inclusion() { static void *symbols[] = { - // Add functions to export here (void *)&duckdb_adbc_init, }; return symbols; From 21c351b9f9dd280255509f5d5ab6244a9b4ad00b Mon Sep 17 00:00:00 2001 From: Evert Lammerts Date: Fri, 8 May 2026 16:50:47 +0200 Subject: [PATCH 2/2] add DUCKDB_STATIC_BUILD to compile defs --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88dc2e36..0c063bdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,11 @@ target_include_directories( INTERFACE $ ) +# We link duckdb_static. Without this define, duckdb.h marks C API symbols +# __declspec(dllimport) on Windows, producing unresolvable __imp_* references at +# link time. No-op on non-Windows. +target_compile_definitions(_duckdb_dependencies INTERFACE DUCKDB_STATIC_BUILD) + # ──────────────────────────────────────────── # Descend into the real DuckDB‑Python sources # ────────────────────────────────────────────