项目简介
lvgljs 是一个用 JavaScript/React 语法操作 LVGL(轻量级通用图形库)的开源项目。它将 LVGL 的 C 语言 UI 组件封装成了类似 React 的组件化接口,开发者可以用 JSX 编写嵌入式 UI,渲染到 SDL2 模拟器或真实的嵌入式设备上。
技术栈:
- JavaScript 运行时:txiki.js(基于 QuickJS + libuv + curl)
- 图形引擎:LVGL(嵌入式 GUI 库)
- 前端框架:自定义 React Reconciler(virtual DOM → LVGL C 调用)
- 构建工具:CMake(native 层) + esbuild(JS 层)
一、环境准备
1.1 安装系统依赖
bash
sudo apt update
sudo apt install -y \
git \
cmake \
nodejs \
npm \
libsdl2-dev \
libcurl4-openssl-dev \
libffi-dev \
libtool \
autoconf \
automake \
texinfo
各依赖说明:
| 包名 | 用途 |
|---|---|
git |
克隆代码、拉取 git 子模块 |
cmake |
CMake >= 3.16,构建 native 层 |
nodejs / npm |
运行 esbuild、打包 JS bundle |
libsdl2-dev |
SDL2 模拟器显示驱动 |
libcurl4-openssl-dev |
txiki.js HTTP 客户端依赖 |
libffi-dev |
外部 FFI 库(解决 CMake 4.x 兼容问题) |
libtool autoconf automake texinfo |
libffi 源码构建工具链 |
1.2 克隆代码并初始化子模块
bash
git clone https://github.com/lvgl/lv_binding_js.git
cd lv_binding_js
git submodule update --recursive --init
这一步会拉取三个关键子模块:
deps/lvgl--- LVGL 图形库deps/lv_drivers--- LVGL 输入/显示驱动deps/txiki--- JavaScript 运行时
二、修改构建配置(关键步骤)
项目的 Makefile 设计时针对标准 CMake 版本,在Ubuntu26.04系统上,CMake 4.x 环境下需要做两处修改。
打开项目根目录的 Makefile,找到 simulator 目标,将 cmake 命令修改为:
makefile
simulator:
@mkdir -p $(BUILD_SIM)
cmake -B "$(BUILD_SIM)" -DCMAKE_BUILD_TYPE=Simulator -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DUSE_EXTERNAL_FFI=ON "-DCMAKE_C_FLAGS=-Wno-error=discarded-qualifiers -Wno-error=unterminated-string-initialization"
cmake --build $(BUILD_SIM) -j
修改说明:
| 参数 | 原因 |
|---|---|
-DUSE_EXTERNAL_FFI=ON |
CMake 4.x 与 libffi 的 autotools 构建系统不兼容,使用系统已安装的 libffi |
-Wno-error=discarded-qualifiers |
txiki 依赖的 quickjs 代码中有 const 限定符警告被 -Werror 拦截 |
-Wno-error=unterminated-string-initialization |
同上,quickjs 中字符串初始化警告被当作错误 |
三、编译并运行
3.1 一键编译模拟器
bash
make simulator
这一步骤会:
- 创建
build/目录 - 运行 CMake 配置(Simulator 模式会自动链接 SDL2)
- 编译 txiki.js、LVGL、lv_drivers 和项目自身的 C++ 绑定层
编译产物为 build/lvgljs 可执行文件。
3.2 打包 JS Bundle
bash
npm install # 安装前端依赖(首次运行一次即可)
npm run bundle # 用 esbuild 将 .jsx/.tsx 打包成 .js
build.js 会扫描 demo/*/index.jsx 和 test/*/index.jsx,将所有 JSX/TSX 文件打包为可被 txiki.js 执行的纯 JavaScript 文件。
3.3 运行 Demo
bash
# 默认运行 widgets 示例
make demo
# 运行其他 demo
make demo PROJECT=hello_world
make demo PROJECT=calculator

也可以手动指定路径:
bash
./build/lvgljs run demo/widgets/index.js
3.4 热重载开发模式
同时打开两个终端窗口:
bash
# 终端 1:监视 JSX 文件变化,自动重新打包
npm run bundle:watch
# 终端 2:监视编译产物变化,自动重新运行
npm run sim:watch -- demo/widgets/index.js
四、项目结构一览
lvgljs/
├── CMakeLists.txt # C++ 构建配置
├── Makefile # 便捷构建入口
├── build.js # esbuild JS 打包脚本
├── package.json # npm 依赖配置
│
├── src/
│ ├── engine/ # C++ 应用入口
│ │ ├── engine.cpp # main():初始化 txiki.js + 暴露 lvgljs 对象
│ │ └── hal/
│ │ ├── simulator/ # SDL2 模拟器 HAL
│ │ └── device/ # 嵌入式 framebuffer HAL
│ │
│ └── render/
│ ├── native/ # C++ LVGL 绑定层
│ │ ├── bootstrap/ # 初始化所有组件/事件绑定
│ │ └── components/ # 各个 LVGL 组件的 C++ 包装
│ └── react/ # JavaScript UI 框架
│ ├── core/ # Reconciler、样式、动画、主题
│ └── components/ # Button、Text、View 等 React 组件
│
├── deps/
│ ├── lvgl/ # LVGL 图形库(子模块)
│ ├── lv_drivers/ # LVGL 驱动(子模块)
│ └── txiki/ # txiki.js 运行时(子模块)
│
├── demo/
│ ├── widgets/ # 组件展示 demo
│ ├── hello_world/ # 入门 hello world
│ └── calculator/ # 计算器 demo
│
└── doc/ # 详细文档
├── build/ # 构建指南
├── component/ # 各组件 API 文档
└── style/ # CSS 样式文档
五、编写自己的 UI
项目提供了类似 React 的组件化接口。使用前确保 npm run bundle 已执行过(或者开 bundle:watch),然后编写 JSX 文件:
tsx
import { Button, Render, Text, View } from "lvgljs-ui";
import React from "react";
function App() {
return (
<View style={{ "background-color": "#1a1a2e", "flex-direction": "column", "align-items": "center", "justify-content": "center" }}>
<Text style={{ color: "#ffffff", "font-size": 24 }}>
Hello lvgljs!
</Text>
<Button style={{ "margin-top": 20, "background-color": "#e94560" }}>
<Text>Click Me</Text>
</Button>
</View>
);
}
Render.render(<App />);
将文件放到 demo/myapp/index.jsx,运行:
bash
npm run bundle
./build/lvgljs run demo/myapp/index.js
六、可能遇到的问题
| 问题 | 解决方案 |
|---|---|
Could NOT find CURL |
sudo apt install libcurl4-openssl-dev |
Could NOT find SDL2 |
sudo apt install libsdl2-dev |
LIBTOOL is undefined |
sudo apt install libtool autoconf automake |
makeinfo: command not found |
sudo apt install texinfo |
quickjs ... discarded-qualifiers |
Makefile cmake 命令加 -DCMAKE_C_FLAGS=-Wno-error=discarded-qualifiers |
unterminated-string-initialization |
同上,加 -Wno-error=unterminated-string-initialization |
libffi configure failed |
cmake 命令加 -DUSE_EXTERNAL_FFI=ON + sudo apt install libffi-dev |
七、总结
整个流程可以归纳为 4 条命令:
bash
# 1. 安装依赖(一次性)
sudo apt install git cmake nodejs npm libsdl2-dev libcurl4-openssl-dev \
libffi-dev libtool autoconf automake texinfo
# 2. 拉取代码和子模块,网络不好的话自己想办法
git clone https://github.com/lvgl/lv_binding_js.git && cd lv_binding_js
git submodule update --recursive --init
# 3. 安装 JS 依赖
npm install
# 4. 编译 + 打包 + 运行
make simulator && npm run bundle && make demo
修改 Makefile 这一步只在 CMake 4.x + Ubuntu 最新版系统上需要。如果是较老版本的 CMake(3.16~3.28),项目原生的 Makefile 应该是可以直接使用的,make setup && make simulator 即可成功编译。