2. 开发环境搭建:基于PC的模拟器环境搭建(VS Code + SDL + CMake)

说实话,很多初学者一上来就买开发板,结果折腾半天连灯都没点亮,信心直接归零。

我个人习惯是:先在PC上跑模拟器。等界面逻辑调通了,再往板子上烧。这样调试快,成本低,心态也稳。

这一章,我们就来搭一套基于 VS Code + SDL + CMake 的 LVGL 模拟器环境。最后跑通一个 Hello World,让你亲眼看到 LVGL 跑起来的样子。

本章目标:在 Windows / Linux / macOS 上,用 VS Code 打开一个 LVGL 模拟器工程,编译运行,看到屏幕中央显示 "Hello LVGL!"。

2.1 环境全景图

先别急着装软件。我们看看整个模拟器是怎么工作的。

LVGL 模拟器环境架构图 LVGL 模拟器环境架构图 你的 LVGL 应用代码 LVGL 图形库 SDL 显示/输入驱动 操作系统 (Win/Linux/macOS) CMake 负责构建 VS Code 负责编辑 SDL 模拟硬件显示 你只需要写应用代码 底层全部由模拟器封装

你看,从上到下就四层。你只需要关心最上面那层——写你的界面代码。剩下的,CMake 帮你编译,SDL 帮你画到屏幕上。

2.2 安装必备工具

不同操作系统,安装方式略有差异。我列个表,你照着来就行。

工具 Windows Linux (Ubuntu/Debian) macOS
VS Code 官网下载 .exe 安装 sudo snap install code 官网下载 .dmg 安装
Git 官网下载 .exe 安装 sudo apt install git brew install git
CMake 官网下载 .msi 安装 sudo apt install cmake brew install cmake
SDL2 下载开发库 .zip 解压 sudo apt install libsdl2-dev brew install sdl2
编译器 MinGW-w64 或 MSVC sudo apt install build-essential xcode-select --install

我的建议:Windows 用户直接用 MSVC(Visual Studio Build Tools)最省心。MinGW 有时候路径问题会让人抓狂。我在项目里吃过这个亏,折腾了一下午才发现是路径斜杠写反了。

2.3 获取 LVGL 模拟器工程

LVGL 官方提供了一个现成的模拟器模板,我们直接拿来用。

# 打开终端,进入你想放工程的目录
cd ~/projects

# 克隆官方模拟器仓库
git clone --recursive https://github.com/lvgl/lv_port_pc_eclipse.git

# 注意 --recursive 参数,它会同时拉取 LVGL 核心库
# 如果忘记加,可以进入目录后执行:
# git submodule update --init --recursive

克隆完成后,目录结构是这样的:

lv_port_pc_eclipse/
├── CMakeLists.txt          # 构建配置文件
├── main/
│   ├── main.c              # 主程序入口
│   ├── main.h
│   ├── lv_conf.h           # LVGL 配置文件
│   └── ...
├── lvgl/                   # LVGL 核心库(子模块)
├── lv_drivers/             # SDL 驱动(子模块)
└── README.md

嗯,这里要注意:lv_conf.h 是 LVGL 的配置总开关。很多功能默认是关闭的,比如动画、字体、文件系统。你需要什么,就在里面打开对应的宏。

2.4 用 VS Code 打开工程

这一步很简单,但有个小坑。

  1. 打开 VS Code
  2. 点击 File → Open Folder,选择 lv_port_pc_eclipse 目录
  3. 安装必要插件:C/C++(微软官方)、CMake Tools
  4. 按 Ctrl+Shift+P,输入 CMake: Configure,选择编译器

我曾经遇到过:Windows 下 CMake 找不到 SDL2 的路径。原因是 SDL2 的 .dll 和 .lib 文件没有放在系统 PATH 里。解决办法:在 CMakeLists.txt 中手动指定 SDL2_DIR 路径,或者把 SDL2 的 bin 目录加到环境变量。

2.5 编写 Hello World

打开 main/main.c,把内容替换成下面这段:

#include "lvgl.h"
#include "lv_drivers/display/sdl.h"
#include "lv_drivers/indev/sdl_mouse.h"

int main(void)
{
    /* 1. 初始化 LVGL */
    lv_init();

    /* 2. 初始化 SDL 显示驱动 */
    sdl_init();

    /* 3. 注册显示设备 */
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.flush_cb = sdl_display_flush;
    lv_disp_drv_register(&disp_drv);

    /* 4. 注册输入设备(鼠标) */
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = sdl_mouse_read;
    lv_indev_drv_register(&indev_drv);

    /* 5. 创建 Hello World 标签 */
    lv_obj_t *label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello LVGL!");
    lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

    /* 6. 主循环 */
    while(1)
    {
        lv_task_handler();
        lv_tick_inc(5);
        SDL_Delay(5);
    }

    return 0;
}

这段代码干了六件事:

  • 初始化 LVGL 核心
  • 初始化 SDL 窗口(模拟屏幕)
  • 把 LVGL 的绘图命令和 SDL 窗口绑定
  • 把鼠标事件传给 LVGL
  • 在屏幕中央创建一个标签,写上 "Hello LVGL!"
  • 进入主循环,不断处理 LVGL 任务

这里有个细节:lv_tick_inc(5) 告诉 LVGL 过去了 5 毫秒。LVGL 内部靠这个时间戳驱动动画和任务。如果你发现动画不动,八成是忘了调这个函数。

2.6 编译与运行

在 VS Code 底部状态栏,点击 Build 按钮(或者按 F7)。

编译成功后,终端会生成一个可执行文件。在 VS Code 终端里运行它:

# 在 build 目录下
./lv_sim

你会看到一个 SDL 窗口弹出来,中间显示 "Hello LVGL!"。

如果窗口是黑的,或者报错,别慌。检查以下几点:

现象 可能原因 解决办法
窗口黑屏 SDL 初始化失败 检查 SDL2 是否安装正确,.dll 是否在可执行文件旁边
编译报错找不到 lvgl.h 子模块未拉取 执行 git submodule update --init --recursive
窗口一闪而过 主循环退出 检查 while(1) 循环是否被 break 或 return 打断
文字显示乱码 字体未启用 在 lv_conf.h 中打开 LV_FONT_MONTSERRAT_24 等宏

2.7 验证成功

当你看到这个窗口时,恭喜你——环境搭建成功了。

Hello World 运行效果 LVGL Simulator Hello LVGL!

说白了,你现在已经拥有了一个 LVGL 的「虚拟开发板」。后续所有界面实验,都可以在这个模拟器上完成。

记住这个感觉:从零到跑通第一个程序,你只用了不到 10 分钟。这就是模拟器开发的优势——没有硬件等待,没有烧录烦恼,专注在界面本身。

2.8 避坑指南

最后,分享几个我踩过的坑:

  • 路径不要有中文:CMake 对中文路径支持很差,尤其是 Windows。工程目录最好全英文。
  • SDL2 版本要匹配:LVGL 官方模拟器用的是 SDL2,不是 SDL1。别下错了。
  • VS Code 终端乱码:Windows 下如果终端输出乱码,把 VS Code 终端编码改成 UTF-8。在设置里搜 "terminal.integrated.defaultProfile.windows" 选 PowerShell 或 cmd,然后加参数 -NoExit -Command "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8"。
  • CMake 缓存问题:如果改了 CMakeLists.txt 但编译没反应,手动删除 build 目录重新配置。