Zig-rocksdb 支持靜態鏈接以及示例介紹
得益於 Zig 與 C 的無縫交互加上構建系統的逐漸完善,我們可以相對教簡單的將一個 C 項目包裝成一個 Zig 綁定庫。以下是 zig-rocksdb[1] 支持靜態鏈接 librocksdb 的構建方式:
fn buildStaticRocksdb(
b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
strip_lib: bool,
) !?*Step.Compile {
const is_darwin = target.result.isDarwin();
const is_linux = target.result.os.tag == .linux;
const rocksdb_dep = b.lazyDependency("rocksdb", .{
.target = target,
.optimize = optimize,
}) orelse return null;
const lib = b.addStaticLibrary(.{
.name = "rocksdb",
.target = target,
.optimize = optimize,
.link_libc = true,
.strip = if (strip_lib) true else false,
});
lib.root_module.sanitize_c = false;
if (optimize != .Debug) {
lib.defineCMacro("NDEBUG", "1");
}
lib.defineCMacro("ROCKSDB_PLATFORM_POSIX", null);
lib.defineCMacro("ROCKSDB_LIB_IO_POSIX", null);
lib.defineCMacro("ROCKSDB_SUPPORT_THREAD_LOCAL", null);
if (is_darwin) {
lib.defineCMacro("OS_MACOSX", null);
} else if (is_linux) {
lib.defineCMacro("OS_LINUX", null);
}
lib.linkLibCpp();
lib.addIncludePath(rocksdb_dep.path("include"));
lib.addIncludePath(rocksdb_dep.path("."));
const cflags = &.{
"-std=c++17",
"-Wsign-compare",
"-Wshadow",
"-Wno-unused-parameter",
"-Wno-unused-variable",
"-Woverloaded-virtual",
"-Wnon-virtual-dtor",
"-Wno-missing-field-initializers",
"-Wno-strict-aliasing",
"-Wno-invalid-offsetof",
};
const src_file = b.path("sys/rocksdb_lib_sources.txt").getPath2(b, null);
var f = try std.fs.openFileAbsolute(src_file, .{});
const body = try f.readToEndAlloc(b.allocator, 1024_1000);
var it = std.mem.splitScalar(u8, body, '\n');
while (it.next()) |src| {
// We have a pre-generated a version of build_version.cc in the local directory
if (std.mem.eql(u8, "util/build_version.cc", src) or src.len == 0) {
continue;
}
lib.addCSourceFile(.{
.file = rocksdb_dep.path(src),
.flags = cflags,
});
}
lib.addCSourceFile(.{
.file = b.path("sys/build_version.cc"),
.flags = cflags,
});
b.installArtifact(lib);
lib.installHeadersDirectory(rocksdb_dep.path("include/rocksdb"), "rocksdb", .{});
return lib;
}
核心幾點:
-
通過
lazyDependency
進行惰性加載 rocksdb 源碼 -
defineCMacro
定義 librocksdb 中需要用的到宏 -
找到所需 C 文件,調用
addCSourceFile
添加到靜態 lib 中,對於 rocksdb 還比較簡單,就是在 src.mk[2] 中,其他的 C 項目獲取可能要複雜一些 -
最後調用
installHeadersDirectory
將相關頭文件放知道構建產物中,這樣上層 module 就可以直接cImport
的頭文件,不需要在指定 includePath
使用也很簡單,首先下載:
zig fetch --save=rocksdb https://github.com/jiacai2050/zig-rocksdb/archive/refs/tags/v0.1.0.zip
之後在 build.zig 中的 exe 引用即可
const dep_rocksdb = b.dependency("rocksdb", .{});
exe.root_module.addImport("rocksdb", dep_rocksdb.module("rocksdb"));
exe.linkLibC();
這是進行讀寫的示例代碼:
const std = @import("std");
const rocksdb = @import("rocksdb");
pub fn main() !void {
const allocator = std.heap.page_allocator;
var db = try rocksdb.Database(.Single).open(
allocator,
"/tmp/zig-rocksdb-basic",
.{
.create_if_missing = true,
},
);
defer db.deinit();
const key = "hello";
try db.put(key, "world", .{});
const value = try db.get(key, .{});
if (value) |v| {
defer rocksdb.free(v);
std.debug.print("{s} = {s}\n", .{ key, v });
}
}
參考資料
[1]
zig-rocksdb: https://github.com/jiacai2050/zig-rocksdb/
[2]
src.mk: https://github.com/jiacai2050/rocksdb/blob/9ad772e652bb3172ed8821ebacf40757bfbb7da1/src.mk#L2
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/CJovB-KcLyl-brwHAjmvqA