From 2a5e211c2a3df46969bbcf1fb2f6031691a101b1 Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 00:47:45 +0800 Subject: [PATCH 01/11] add .minimum_zig_version --- build.zig.zon | 1 + 1 file changed, 1 insertion(+) diff --git a/build.zig.zon b/build.zig.zon index c46aebe..b4d76da 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,6 +2,7 @@ .name = .rocksdb, .fingerprint = 0xd916a6b24e94f0cf, .version = "9.7.4", + .minimum_zig_version = "0.14.1", .dependencies = .{ .rocksdb = .{ .url = "git+https://github.com/Syndica/rocksdb#3793e721c7795b338d9d7808544b75db6bde3548", From ecfa28eb455d3e07989703a24fd11212d1cc8c5d Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 00:50:05 +0800 Subject: [PATCH 02/11] enable snappy / build it from source --- build.zig | 49 +++++++++++++++++++++++++++++++++++++++++++++---- build.zig.zon | 4 ++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/build.zig b/build.zig index 8122297..41202d6 100644 --- a/build.zig +++ b/build.zig @@ -68,8 +68,18 @@ fn addRocksDB( }), }); - try buildRocksDB(b, static_rocksdb, target); - try buildRocksDB(b, dynamic_rocksdb, target); + const snappy = b.addLibrary(.{ + .name = "snappy", + .linkage = .static, + .root_module = b.createModule(.{ + .target = target, + .optimize = optimize, + .pic = if (force_pic == true) true else null, + }), + }); + + try buildRocksDB(b, static_rocksdb, snappy, target); + try buildRocksDB(b, dynamic_rocksdb, snappy, target); mod.addIncludePath(rocks_dep.path("include")); mod.linkLibrary(static_rocksdb); @@ -81,10 +91,16 @@ fn addRocksDB( fn buildRocksDB( b: *Build, librocksdb: *std.Build.Step.Compile, + libsnappy: *std.Build.Step.Compile, target: std.Build.ResolvedTarget, ) !void { + // Ideally snappy could be an optional dependency, but Zig doesn't support them yet. + // Luckily building this is cheap. + const enable_snappy: bool = true; + const t = target.result; const rocks_dep = b.dependency("rocksdb", .{}); + const snappy_dep = b.dependency("snappy", .{}); librocksdb.linkLibC(); librocksdb.linkLibCpp(); @@ -431,14 +447,39 @@ fn buildRocksDB( "utilities/transactions/lock/range/range_tree/lib/util/dbt.cc", "utilities/transactions/lock/range/range_tree/lib/util/memarena.cc", }, - .flags = &.{ + .flags = @as([]const []const u8, &.{ "-std=c++17", "-faligned-new", "-DHAVE_ALIGNED_NEW", "-DROCKSDB_UBSAN_RUN", - }, + }) ++ @as([]const []const u8, if (enable_snappy) + &.{"-DSNAPPY=1"} + else + &.{}), }); + if (enable_snappy) { + libsnappy.linkLibCpp(); + + libsnappy.addCSourceFiles(.{ + .root = snappy_dep.path("."), + .files = &.{ + "snappy-c.cc", + "snappy-sinksource.cc", + "snappy-stubs-internal.cc", + "snappy.cc", + }, + .flags = &.{ + "-std=c++11", + "-fno-exceptions", + "-fno-rtti", + "-Wno-sign-compare", + }, + }); + + librocksdb.linkLibrary(libsnappy); + } + // platform dependent stuff if (t.cpu.arch == .aarch64) { librocksdb.addCSourceFile(.{ diff --git a/build.zig.zon b/build.zig.zon index b4d76da..3f24e54 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -8,6 +8,10 @@ .url = "git+https://github.com/Syndica/rocksdb#3793e721c7795b338d9d7808544b75db6bde3548", .hash = "N-V-__8AAAKhcQL5PtDzqfPNCjk1LJCK8svO8KtC-f_3bj6z", }, + .snappy = .{ + .url = "git+https://github.com/google/snappy#25e52c58fbf83ee40f4c9284f757f777f691f76f", + .hash = "N-V-__8AADcwMwCa__yeHfNDwYl4KEDbkj-VwAqY844Nblr8", + }, }, .paths = .{ "build.zig", From 18fc4bffd27a81f429c0fb7b0dc635319212c181 Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 00:50:42 +0800 Subject: [PATCH 03/11] expose a read-only open option --- src/database.zig | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/database.zig b/src/database.zig index 6e7c253..ee96083 100644 --- a/src/database.zig +++ b/src/database.zig @@ -47,15 +47,30 @@ pub const DB = struct { cf_options[i] = cf.options.convert(); } var ch = CallHandler.init(err_str); - break :db try ch.handle(rdb.rocksdb_open_column_families( - db_options.convert(), - dir.ptr, - @intCast(cf_names.len), - @ptrCast(cf_names.ptr), - @ptrCast(cf_options.ptr), - @ptrCast(cf_handles.ptr), - @ptrCast(&ch.err_str_in), - ), error.RocksDBOpen); + + const ret = if (db_options.open_read_only) + rdb.rocksdb_open_for_read_only_column_families( + db_options.convert(), + dir.ptr, + @intCast(cf_names.len), + @ptrCast(cf_names.ptr), + @ptrCast(cf_options.ptr), + @ptrCast(cf_handles.ptr), + 0, + @ptrCast(&ch.err_str_in), + ) + else + rdb.rocksdb_open_column_families( + db_options.convert(), + dir.ptr, + @intCast(cf_names.len), + @ptrCast(cf_names.ptr), + @ptrCast(cf_options.ptr), + @ptrCast(cf_handles.ptr), + @ptrCast(&ch.err_str_in), + ); + + break :db try ch.handle(ret, error.RocksDBOpen); }; // organize column family metadata @@ -343,6 +358,8 @@ pub const DBOptions = struct { /// Dynamically changeable through SetDBOptions() API. max_open_files: i32 = -1, + open_read_only: bool = false, + fn convert(do: DBOptions) *rdb.struct_rocksdb_options_t { const ro = rdb.rocksdb_options_create().?; rdb.rocksdb_options_set_create_if_missing(ro, @intFromBool(do.create_if_missing)); From 062c72ba938876b5194b1cb02c7c8fc35b4b871a Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:08:30 +0800 Subject: [PATCH 04/11] fix up tests --- src/database.zig | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/database.zig b/src/database.zig index ee96083..84d3279 100644 --- a/src/database.zig +++ b/src/database.zig @@ -26,6 +26,7 @@ pub const DB = struct { dir: []const u8, db_options: DBOptions, maybe_column_families: ?[]const ColumnFamilyDescription, + for_read_only: bool, err_str: *?Data, ) (Allocator.Error || error{RocksDBOpen})!struct { Self, []const ColumnFamily } { const column_families = if (maybe_column_families) |cfs| @@ -48,7 +49,7 @@ pub const DB = struct { } var ch = CallHandler.init(err_str); - const ret = if (db_options.open_read_only) + const ret = if (for_read_only) rdb.rocksdb_open_for_read_only_column_families( db_options.convert(), dir.ptr, @@ -358,8 +359,6 @@ pub const DBOptions = struct { /// Dynamically changeable through SetDBOptions() API. max_open_files: i32 = -1, - open_read_only: bool = false, - fn convert(do: DBOptions) *rdb.struct_rocksdb_options_t { const ro = rdb.rocksdb_options_create().?; rdb.rocksdb_options_set_create_if_missing(ro, @intFromBool(do.create_if_missing)); @@ -387,6 +386,7 @@ test "DB clean init and deinit" { .create_missing_column_families = true, }, null, + false, &data, ); @@ -571,6 +571,7 @@ fn runTest(err_str: *?Data) !void { .{ .name = "default" }, .{ .name = "another" }, }, + false, err_str, ); defer db.deinit(); @@ -610,6 +611,7 @@ fn runTest(err_str: *?Data) !void { .{ .name = "default" }, .{ .name = "another" }, }, + false, err_str, ); defer db.deinit(); From 1790e2faeb0486fea49b53b0e609a98fb689c784 Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:19:49 +0800 Subject: [PATCH 05/11] use zig 0.14.1 --- .github/workflows/check.yml | 4 ++-- README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 3ecfa06..dbf059b 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -12,7 +12,7 @@ jobs: - name: setup-zig uses: mlugg/setup-zig@v1 with: - version: 0.14.0 + version: 0.14.1 - name: lint run: | @@ -33,7 +33,7 @@ jobs: - name: setup-zig uses: mlugg/setup-zig@v1 with: - version: 0.14.0 + version: 0.14.1 - name: test run: | diff --git a/README.md b/README.md index 04c3784..f975350 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Build and use RocksDB in zig. # Build Dependencies -`rocksdb-zig` is pinned to [Zig `0.13`](https://ziglang.org/download/), so you will need to have it installed. +`rocksdb-zig` is pinned to [Zig `0.14.1`](https://ziglang.org/download/), so you will need to have it installed. # Usage From 9611eba89266c8701d339ee5594717867ba8554b Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:21:42 +0800 Subject: [PATCH 06/11] update setup-zig --- .github/workflows/check.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index dbf059b..68db8e4 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -10,7 +10,7 @@ jobs: uses: actions/checkout@v2 - name: setup-zig - uses: mlugg/setup-zig@v1 + uses: mlugg/setup-zig@v2 with: version: 0.14.1 @@ -31,7 +31,7 @@ jobs: submodules: recursive - name: setup-zig - uses: mlugg/setup-zig@v1 + uses: mlugg/setup-zig@v2 with: version: 0.14.1 From e31027ae340d8adbc4a8b70190fbec32a7ff97d2 Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:46:26 +0800 Subject: [PATCH 07/11] generate and use cmake snappy config --- build.zig | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/build.zig b/build.zig index 41202d6..ada1611 100644 --- a/build.zig +++ b/build.zig @@ -460,6 +460,14 @@ fn buildRocksDB( if (enable_snappy) { libsnappy.linkLibCpp(); + librocksdb.linkLibrary(libsnappy); + + const flags = .{ + "-std=c++11", + "-fno-exceptions", + "-fno-rtti", + "-Wno-sign-compare", + }; libsnappy.addCSourceFiles(.{ .root = snappy_dep.path("."), @@ -469,15 +477,23 @@ fn buildRocksDB( "snappy-stubs-internal.cc", "snappy.cc", }, - .flags = &.{ - "-std=c++11", - "-fno-exceptions", - "-fno-rtti", - "-Wno-sign-compare", - }, + .flags = &flags, }); - librocksdb.linkLibrary(libsnappy); + const build_version = b.addConfigHeader(.{ + .style = .{ .cmake = snappy_dep.path("snappy-stubs-public.h.in") }, + .include_path = "snappy-stubs-public.h", + }, .{ + .PROJECT_VERSION_MAJOR = 1, + .PROJECT_VERSION_MINOR = 2, + .PROJECT_VERSION_PATCH = 2, + .HAVE_SYS_UIO_H_01 = 1, + }); + libsnappy.addCSourceFile(.{ + .file = build_version.getOutput(), + .language = .cpp, + .flags = &flags, + }); } // platform dependent stuff From 480ec1692cc7ab38e7cc86245ad38b30cfaef76f Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:58:35 +0800 Subject: [PATCH 08/11] fix generated header include --- build.zig | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/build.zig b/build.zig index ada1611..b0033e8 100644 --- a/build.zig +++ b/build.zig @@ -489,11 +489,8 @@ fn buildRocksDB( .PROJECT_VERSION_PATCH = 2, .HAVE_SYS_UIO_H_01 = 1, }); - libsnappy.addCSourceFile(.{ - .file = build_version.getOutput(), - .language = .cpp, - .flags = &flags, - }); + + libsnappy.addIncludePath(build_version.getOutput().dirname()); } // platform dependent stuff From 72ce2f9af8fda2b1c93f4e594ceea739938da80b Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Fri, 9 Jan 2026 03:08:38 +0800 Subject: [PATCH 09/11] rocksdb: include snappy.h --- build.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.zig b/build.zig index b0033e8..f41b446 100644 --- a/build.zig +++ b/build.zig @@ -459,8 +459,10 @@ fn buildRocksDB( }); if (enable_snappy) { - libsnappy.linkLibCpp(); librocksdb.linkLibrary(libsnappy); + librocksdb.addIncludePath(snappy_dep.path(".")); + + libsnappy.linkLibCpp(); const flags = .{ "-std=c++11", @@ -491,6 +493,7 @@ fn buildRocksDB( }); libsnappy.addIncludePath(build_version.getOutput().dirname()); + librocksdb.addIncludePath(build_version.getOutput().dirname()); } // platform dependent stuff From e68e6a06798882603f44461850beb52f5dc47557 Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Sat, 10 Jan 2026 02:10:06 +0800 Subject: [PATCH 10/11] make snappy a lazy dep --- build.zig | 76 ++++++++++++++++++++++++++++----------------------- build.zig.zon | 1 + 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/build.zig b/build.zig index f41b446..269835e 100644 --- a/build.zig +++ b/build.zig @@ -3,12 +3,28 @@ const Build = std.Build; const ResolvedTarget = Build.ResolvedTarget; const OptimizeMode = std.builtin.OptimizeMode; -pub fn build(b: *Build) void { +const Options = struct { + enable_snappy: bool, + + fn init(b: *Build) Options { + return .{ + .enable_snappy = b.option( + bool, + "enable_snappy", + "Enables and builds with the Snappy compressor", + ) orelse false, + }; + } +}; + +pub fn build(b: *Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + const options: Options = .init(b); + // RocksDB's translate-c module - const rocksdb_mod = addRocksDB(b, target, optimize); + const rocksdb_mod = try addRocksDB(b, target, optimize, options); const bindings_mod = b.addModule("bindings", .{ .target = target, .optimize = optimize, @@ -32,7 +48,8 @@ fn addRocksDB( b: *Build, target: ResolvedTarget, optimize: OptimizeMode, -) *Build.Module { + options: Options, +) !*Build.Module { const rocks_dep = b.dependency("rocksdb", .{}); const translate_c = b.addTranslateC(.{ @@ -68,7 +85,7 @@ fn addRocksDB( }), }); - const snappy = b.addLibrary(.{ + const maybe_libsnappy = if (options.enable_snappy) b.addLibrary(.{ .name = "snappy", .linkage = .static, .root_module = b.createModule(.{ @@ -76,10 +93,10 @@ fn addRocksDB( .optimize = optimize, .pic = if (force_pic == true) true else null, }), - }); + }) else null; - try buildRocksDB(b, static_rocksdb, snappy, target); - try buildRocksDB(b, dynamic_rocksdb, snappy, target); + try buildRocksDB(b, static_rocksdb, maybe_libsnappy, target); + try buildRocksDB(b, dynamic_rocksdb, maybe_libsnappy, target); mod.addIncludePath(rocks_dep.path("include")); mod.linkLibrary(static_rocksdb); @@ -91,20 +108,25 @@ fn addRocksDB( fn buildRocksDB( b: *Build, librocksdb: *std.Build.Step.Compile, - libsnappy: *std.Build.Step.Compile, + maybe_libsnappy: ?*std.Build.Step.Compile, target: std.Build.ResolvedTarget, ) !void { - // Ideally snappy could be an optional dependency, but Zig doesn't support them yet. - // Luckily building this is cheap. - const enable_snappy: bool = true; - const t = target.result; const rocks_dep = b.dependency("rocksdb", .{}); - const snappy_dep = b.dependency("snappy", .{}); librocksdb.linkLibC(); librocksdb.linkLibCpp(); + var rocksdb_flags: std.ArrayListUnmanaged([]const u8) = .empty; + defer rocksdb_flags.deinit(b.allocator); + try rocksdb_flags.appendSlice(b.allocator, &.{ + "-std=c++17", + "-faligned-new", + "-DHAVE_ALIGNED_NEW", + "-DROCKSDB_UBSAN_RUN", + }); + if (maybe_libsnappy != null) try rocksdb_flags.append(b.allocator, "-DSNAPPY=1"); + librocksdb.addIncludePath(rocks_dep.path("include")); librocksdb.addIncludePath(rocks_dep.path(".")); librocksdb.addCSourceFiles(.{ @@ -447,18 +469,13 @@ fn buildRocksDB( "utilities/transactions/lock/range/range_tree/lib/util/dbt.cc", "utilities/transactions/lock/range/range_tree/lib/util/memarena.cc", }, - .flags = @as([]const []const u8, &.{ - "-std=c++17", - "-faligned-new", - "-DHAVE_ALIGNED_NEW", - "-DROCKSDB_UBSAN_RUN", - }) ++ @as([]const []const u8, if (enable_snappy) - &.{"-DSNAPPY=1"} - else - &.{}), + .flags = rocksdb_flags.items, }); - if (enable_snappy) { + if (maybe_libsnappy) |libsnappy| not_yet_fetched: { + const snappy_dep = b.lazyDependency("snappy", .{}) orelse + break :not_yet_fetched; + librocksdb.linkLibrary(libsnappy); librocksdb.addIncludePath(snappy_dep.path(".")); @@ -500,12 +517,7 @@ fn buildRocksDB( if (t.cpu.arch == .aarch64) { librocksdb.addCSourceFile(.{ .file = rocks_dep.path("util/crc32c_arm64.cc"), - .flags = &.{ - "-std=c++17", - "-faligned-new", - "-DHAVE_ALIGNED_NEW", - "-DROCKSDB_UBSAN_RUN", - }, + .flags = rocksdb_flags.items, }); } @@ -520,11 +532,7 @@ fn buildRocksDB( "env/fs_posix.cc", "env/io_posix.cc", }, - .flags = &.{ - "-std=c++17", - "-faligned-new", - "-DHAVE_ALIGNED_NEW", - }, + .flags = rocksdb_flags.items, }); } else { @panic("TODO: support windows!"); diff --git a/build.zig.zon b/build.zig.zon index 3f24e54..64336a2 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -11,6 +11,7 @@ .snappy = .{ .url = "git+https://github.com/google/snappy#25e52c58fbf83ee40f4c9284f757f777f691f76f", .hash = "N-V-__8AADcwMwCa__yeHfNDwYl4KEDbkj-VwAqY844Nblr8", + .lazy = true, }, }, .paths = .{ From e18cec1e24912a301a1b05a66eb84d67d486247a Mon Sep 17 00:00:00 2001 From: Sobeston <15335529+Sobeston@users.noreply.github.com> Date: Sat, 10 Jan 2026 07:40:29 +0800 Subject: [PATCH 11/11] remove Options struct --- build.zig | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/build.zig b/build.zig index 269835e..9c4a044 100644 --- a/build.zig +++ b/build.zig @@ -3,28 +3,18 @@ const Build = std.Build; const ResolvedTarget = Build.ResolvedTarget; const OptimizeMode = std.builtin.OptimizeMode; -const Options = struct { - enable_snappy: bool, - - fn init(b: *Build) Options { - return .{ - .enable_snappy = b.option( - bool, - "enable_snappy", - "Enables and builds with the Snappy compressor", - ) orelse false, - }; - } -}; - pub fn build(b: *Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const options: Options = .init(b); + const enable_snappy = b.option( + bool, + "enable_snappy", + "Enables and builds with the Snappy compressor", + ) orelse false; // RocksDB's translate-c module - const rocksdb_mod = try addRocksDB(b, target, optimize, options); + const rocksdb_mod = try addRocksDB(b, target, optimize, enable_snappy); const bindings_mod = b.addModule("bindings", .{ .target = target, .optimize = optimize, @@ -48,7 +38,7 @@ fn addRocksDB( b: *Build, target: ResolvedTarget, optimize: OptimizeMode, - options: Options, + enable_snappy: bool, ) !*Build.Module { const rocks_dep = b.dependency("rocksdb", .{}); @@ -85,7 +75,7 @@ fn addRocksDB( }), }); - const maybe_libsnappy = if (options.enable_snappy) b.addLibrary(.{ + const maybe_libsnappy = if (enable_snappy) b.addLibrary(.{ .name = "snappy", .linkage = .static, .root_module = b.createModule(.{