返回资讯中心
外部精选
软件工程
#开发者实时流

zebkit 将 Chromium 引擎封装为可链接的库

来源标题:Zebkit – Chromium's engine as a library you link, not a runtime you live in

zebkit 把 Blink、V8、PDFium、FFmpeg 等 Chromium 核心组件打包成一个可直接链接进应用的库,不含 Chrome 浏览器或 Electron 运行时。它提供统一的 C API 以及 Rust、Python、JavaScript 绑定,支持 Linux、macOS 和 Windows,开发者只需几行代码即可集成。发布包内含库文件、头文件和 zebkit-run、zebkit-js、zebkit-mcp 等工具。

Hacker News 最新Riiiiichard2026/11/9 · 今天30 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

把 Chromium 当作库来用——轻量、快速、随处可用,而且集成简单。一套 API 覆盖 Linux、macOS 和 Windows,几行代码就能接入。

zebkit 把 Chromium 的引擎打包成一个可链接进你自己应用的库:Blink、包含全部 JIT 层级的 V8、PDFium、FFmpeg,以及构成 Chrome 的其余组件,但既没有 Chrome 浏览器的那部分,也没有 Electron 的运行时。你的应用仍然属于你,可以用 C、C++、Rust、Python 或 JavaScript 编写,拥有自己的窗口和工具包。需要显示网页的地方,就加一个 zebkit 视图;需要 PDF、媒体、压缩或加密时,就调用 zebkit 的 API:可以直接用 C,也可以通过 Rust、Python 和 JavaScript 的绑定(zebkit-js,以及在应用自身页面里的 zebkit.*)。

获取引擎 一个包就是一个目录,里面包含库、helper、引擎数据和 include/。你可以解压某个 release 的归档(GitHub releases 里的 zebkit-<version>-<target>.tar.xz),也可以自己构建: mise run r # dist/release(Linux)、dist/release-macos(macOS)、dist/release-windows;首次构建需要数小时 每个归档里还带有工具,针对所在系统与库一起构建,解压后即可直接运行:zebkit-run、zebkit-js 和 zebkit-mcp(Windows 上是 .exe,同样受沙箱保护)。

在安装了完整 Xcode 的 Apple silicon Mac 上,scripts/dist.sh release 会在本地把引擎构建到 dist/release。然后运行 scripts/example.sh macos-basic,即可构建并启动 C 嵌入示例,位于 dist/example/Zebkit Embedded Browser.app。

构建 Chromium 的源码树大约需要 30 GB(docs/BUILD.md)。下文中的 $PKG 指包目录。

zebkit 是一个库:你的程序保留自己的 main() 并调用它。下面这个例子把 PDF 的第一页渲染成 PNG 并读取其文本,PDFium 和图像编码器都在 zebkit 内部,无需安装其他东西: #include <stdio.h> #include <zebkit/pdf.h> #include <zebkit/services.h> /* 你的程序,你的 main():zebkit 只是它调用的一个库。 */ int main(int argc, char **argv) { char *error = NULL; zebkit_pdf pdf = zebkit_pdf_open_file(argv[1], NULL, &error); if (!pdf) { fprintf(stderr, "%s\n", error); return 1; / 第一页渲染为 PNG,尺寸放大一倍。 */ zebkit_pdf_render_options options = {.scale = 2, .background = 0xffffffff}; int width, height; uint8_t *rgba = zebkit_pdf_render(pdf, 0, &options, &width, &height, &error); size_t size; uint8_t png = zebkit_image_encode(ZEBKIT_IMAGE_PNG, rgba, width, height, 0, &size, &error); fwrite(png, 1, size, fopen("page1.png", "wb")); / 以及它的文本。 */ char text = zebkit_pdf_text(pdf, 0, &error); printf("%d pages; page 1 says: %.80s\n", zebkit_pdf_page_count(pdf), text); zebkit_free(text), zebkit_free(png), zebkit_free(rgba); zebkit_pdf_close(pdf); return 0; cc thumb.c -I$PKG/include -L$PKG -l:libzebkit.so.1 -Wl,-rpath,$PKG -o thumb # Linux cc thumb.c -I$PKG/include -F$PKG -framework Zebkit -Wl,-rpath,$PKG -o thumb # macOS ./thumb report.pdf # 2 pages; page 1 says: Quarterly report ... PDF API、压缩、加密、URL、图像编解码器、ICU 以及引擎内部的库(zebkit_vendor_,其中包含 FFmpeg 的库)都不需要引擎主循环(docs/API.md);只有通过引擎网络栈发起的 HTTP 和网页才需要。

网页需要引擎运行起来。这时由引擎来跑主循环:程序用 zebkit_main() 启动它,并在其回调中工作。自带主循环的程序(GTK、Qt、AppKit、winit)则用 zebkit_init() 启动引擎,并调用 zebkit_pump()(examples/native-host)。 #include <stdio.h> #include <zebkit/zebkit.h> static void printed(zebkit_view *view, const char *json, const char *error, void *data) { printf("%s\n", json ? json : error); zebkit_quit(); static void loaded(zebkit_view *view, zebkit_load_event event, const char *url, void *data) { if (event == ZEBKIT_LOAD_FINISHED) zebkit_view_evaluate(view, "document.title", printed, NULL); static void ready(void *data) { zebkit_view *view = zebkit_view_new("https://example.com/", 1024, 768); zebkit_view_on_load(view, loaded, NULL); int main(int argc, char **argv) { return zebkit_main(argc, argv, ready, NULL); cc app.c -I$PKG/include -L$PKG -l:libzebkit.so.1 -Wl,-rpath,$PKG -o app # Linux cc app.c -I$PKG/include -F$PKG -framework Zebkit -Wl,-rpath,$PKG -o app # macOS clang-cl /MT app.c /I%PKG%\include %PKG%\zebkit.dll.lib %PKG%\zebkit_sandbox.lib # Windows ./app --remote-debugging-port=9222 # 带 CDP,可供 Puppeteer 和 Playwright 使用 在 Windows 上,可执行文件会参与 Chromium 的沙箱:它链接 zebkit_sandbox.lib,并在 main() 最开始调用 zebkit_win_startup()(docs/WINDOWS.md)。

如果没有非特权用户命名空间,引擎会拒绝启动并说明原因:安装它的 helper,或者在自用的容器里加上 --no-sandbox(docs/SANDBOX.md)。

应用通过自定义 scheme 提供自己的页面,并给页面授予可调用的函数;除非明确授权,页面里不会有任何 zebkit 的东西。 /* 页面调用 zebkit.app.greet("Ada")。 */ static void greet(zebkit_view *view, const char *origin, const char *args_json, zebkit_call *call, void data) { char answer[256]; snprintf(answer, sizeof answer, "{"hello": %s}", args_json); zebkit_call_resolve(call, answer); / app://main/... 来自 ./ui,以范围请求支持媒体。真实的处理器会拒绝 ".."。 */ static void serve(zebkit_request *request, void *data) { char path[1024]; snprintf(path, sizeof path, "ui%s", zebkit_request_url(request) + sizeof "app://main" - 1); zebkit_request_respond_file(request, path, NULL); static void closed(zebkit_view *view, void *data) { zebkit_quit(); } static void ready(void *data) { zebkit_view *view = zebkit_view_new("app://main/index.html", 1024, 768); zebkit_view_grant(view, "app://main", ZEBKIT_ALLOW_APP | ZEBKIT_ALLOW_PDF, NULL); zebkit_view_bind(view, "greet", greet, NULL); zebkit_view_on_close(view, closed, NULL); int main(int argc, char **argv) { zebkit_scheme_register("app", ZEBKIT_SCHEME_STANDARD | ZEBKIT_SCHEME_SECURE | ZEBKIT_SCHEME_FETCH); zebkit_scheme_handle("app", serve, NULL); return zebkit_main(argc, argv, ready, NULL);

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →