You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Enable static DuckDB extensions via Cargo in checkouts (#732)
This PR adds an experimental `bundled-cmake` build path for duckdb-rs
checkouts. It keeps the existing `bundled` feature unchanged, and adds a
higher-priority bundled backend that builds DuckDB through upstream
CMake when `bundled-cmake` is enabled.
Only in-tree static extensions such as `icu` are supported for now, but
there's a path toward future out-of-tree extension support. In fact, I
think using CMake is the only realistic path toward out-of-tree
extensions. Features like `sqlite_scanner` are already part of DuckDB's
checked-in extension configs. Reusing that upstream mechanism is much
more maintainable than inventing a parallel extension build/link system
in Rust. *Let DuckDB build DuckDB.*
*Update: For out-of-tree extensions, see
#734
Although this PR only targets checkout builds, the CMake backend is
structured so that a future crates.io-friendly variant could reuse the
same backend logic after downloading the DuckDB sources (`duckdb.tar.gz`
does not contain the full source tree).
Fixes#461
-`icu` - DuckDB's ICU extension for locale-aware operations.
112
+
-`tpch` - DuckDB's TPC-H benchmark extension.
113
+
-`tpcds` - DuckDB's TPC-DS benchmark extension.
114
+
101
115
### Data integration
102
116
103
-
-`json` - Enables reading and writing JSON files. Requires `bundled`.
104
-
-`parquet` - Enables reading and writing Parquet files. Requires `bundled`.
105
117
-`appender-arrow` - Efficient bulk insertion of Arrow data into DuckDB tables.
106
118
-`polars` - Integration with Polars DataFrames.
107
119
@@ -114,6 +126,7 @@ The `duckdb` crate provides a number of Cargo features that can be enabled to ad
114
126
### Build configuration
115
127
116
128
-`bundled` - Uses a bundled version of DuckDB's source code and compiles it during build. This is the simplest way to get started and avoids needing DuckDB system libraries.
129
+
-`bundled-cmake` - *Experimental*. Builds DuckDB via its upstream CMake build system instead of `cc`. Requires a duckdb-rs checkout (not available from crates.io). See [step 2](#notes-on-building-duckdb-and-libduckdb-sys) below for details.
117
130
-`buildtime_bindgen` - Use bindgen at build time to generate fresh bindings instead of using pre-generated ones.
118
131
-`loadable-extension` - _Experimental_ support for creating loadable DuckDB extensions. Includes procedural macros for extension development.
119
132
@@ -178,7 +191,27 @@ You can adjust this behavior in a number of ways:
178
191
duckdb = { version = "1.10501.0", features = ["bundled"] }
179
192
```
180
193
181
-
2. When linking against a DuckDB library already on the system (so _not_ using any of the `bundled` features), you can set the `DUCKDB_LIB_DIR` environment variable to point to a directory containing the library. You can also set the `DUCKDB_INCLUDE_DIR` variable to point to the directory containing `duckdb.h`.
194
+
2. If you use the `bundled-cmake` feature, `libduckdb-sys` will build DuckDB from the local checkout in `crates/libduckdb-sys/duckdb-sources` using upstream CMake. This keeps plain `bundled` unchanged while allowing CMake-only extensions such as `icu`.
-`bundled-cmake` is *experimental* and requires a git/workspace checkout. It is not available from crates.io because the full `duckdb-sources` tree is not packaged there.
206
+
-`bundled-cmake` implies `bundled` (for conditional-compilation gates) but replaces the `cc` build backend with CMake. Enabling any CMake-only extension feature (e.g. `icu`) automatically activates `bundled-cmake`.
207
+
-`bundled-cmake` always links DuckDB's default static extensions (`core_functions` and `parquet`), so it also implies the `parquet` Cargo feature.
208
+
- Extension autoload/autoinstall are forced on to match the existing `bundled` backend, even though upstream CMake defaults are off.
209
+
- When `ninja` is on `PATH`, the Ninja generator is preferred automatically. Set `CMAKE_GENERATOR` to override.
210
+
- Builds DuckDB in `Release` mode by default, even in Rust debug builds, to avoid DuckDB's much slower debug/sanitizer profile. Set `DUCKDB_CMAKE_BUILD_TYPE` or `CMAKE_BUILD_TYPE` to override. `DUCKDB_CMAKE_BUILD_TYPE` takes precedence.
211
+
-`DUCKDB_EXTENSION_CONFIGS` is not yet supported; the build fails fast rather than producing a broken binary.
212
+
- Use `cargo build -vv -F bundled-cmake` to surface CMake configure/build logs.
213
+
214
+
3. When linking against a DuckDB library already on the system (so _not_ using any of the `bundled` features), you can set the `DUCKDB_LIB_DIR` environment variable to point to a directory containing the library. You can also set the `DUCKDB_INCLUDE_DIR` variable to point to the directory containing `duckdb.h`.
182
215
183
216
Linux example:
184
217
@@ -206,29 +239,31 @@ You can adjust this behavior in a number of ways:
206
239
cargo build --examples
207
240
```
208
241
209
-
3. Setting `DUCKDB_DOWNLOAD_LIB=1` makes the build script download pre-built DuckDB binaries from GitHub Releases. This always links against the dynamic library in the archive (setting `DUCKDB_STATIC` has no effect), and it effectively automates the manual steps above. The archives are cached in `target/duckdb-download/<target>/<version>` and that directory is automatically added to the linker search path. The downloaded version always matches the DuckDB version encoded in the `libduckdb-sys` crate version.
242
+
4. Setting `DUCKDB_DOWNLOAD_LIB=1` makes the build script download pre-built DuckDB binaries from GitHub Releases. This always links against the dynamic library in the archive (setting `DUCKDB_STATIC` has no effect), and it effectively automates the manual steps above. The archives are cached in `target/duckdb-download/<target>/<version>` and that directory is automatically added to the linker search path. The downloaded version always matches the DuckDB version encoded in the `libduckdb-sys` crate version.
210
243
211
244
```shell
212
245
DUCKDB_DOWNLOAD_LIB=1 cargo test
213
246
```
214
247
215
-
4. Installing the DuckDB development packages will usually be all that is required, but
248
+
5. Installing the DuckDB development packages will usually be all that is required, but
216
249
the build helpers for [pkg-config](https://github.com/alexcrichton/pkg-config-rs)
217
250
and [vcpkg](https://github.com/mcgoo/vcpkg-rs) have some additional configuration
218
251
options. The default when using vcpkg is to dynamically link,
219
252
which must be enabled by setting `VCPKGRS_DYNAMIC=1` environment variable before build.
220
253
221
254
When none of the options above are used, the build script falls back to this discovery path and will emit the appropriate `cargo:rustc-link-lib` directives if DuckDB is found on your system.
222
255
223
-
### ICU extension and the bundled feature
256
+
### ICU extension and the bundled features
224
257
225
258
When using the `bundled` feature, the ICU extension is not included due to crates.io's 10MB package size limit. This means some date/time operations (like `now() - interval '1 day'` or `ts::date` casts) will fail. You can load ICU at runtime:
226
259
227
260
```rust,ignore
228
261
conn.execute_batch("INSTALL icu; LOAD icu;")?;
229
262
```
230
263
231
-
Alternatively, link against libduckdb without the `bundled` feature (see build instructions above). The ICU extension will be built-in and pre-loaded in that case.
264
+
Alternatively, link against a system libduckdb that was compiled with ICU (see build instructions above).
265
+
266
+
If you are working from a duckdb-rs checkout, you can also use `bundled-cmake,icu` to compile ICU in through DuckDB's CMake build.
0 commit comments