拓冰建站拓冰建站
首页 / 资讯中心 / 正文

SerenityOS 移植 SRB2(Sonic Robo Blast 2)的补丁工程:从 libgme 头文件到 i_system.c 的实战解析

SerenityOS 移植 SRB2Sonic Robo Blast 2的补丁工程从 libgme 头文件到 i_system.c 的实战解析【免费下载链接】serenityThe Serenity Operating System 项目地址: https://gitcode.com/GitHub_Trending/se/serenity本文以 SerenityOS 仓库中 SRB2 移植补丁说明文档 为主体结合 SRB2 移植脚本 与三份补丁的完整 diff系统讲解一款基于 Doom 引擎的开源 3D 索尼克游戏是如何被移植到 SerenityOS 的。读完本文你将理解 SerenityOS Ports 补丁机制的工作原理、三份补丁各自修复的构建问题头文件搜索路径、控制台变量校验、系统层 API 兼容以及如何借助dev开发模式维护和重新生成这些补丁。背景SRB2 移植到 SerenityOS 的整体方案SRB2Sonic Robo Blast 2是一款基于 Doom 引擎的开源 3D 索尼克同人游戏。SerenityOS 通过 Ports 体系将其引入系统SRB2 移植目录 的完整结构非常精简Ports/SRB2/ ├── package.sh # 移植脚本版本、依赖、构建配置、安装步骤 └── patches/ ├── 0001-Fix-libgme-include.patch ├── 0002-Disable-Console-Variables-value-checker-sad-path.patch ├── 0003-i_system.c-hacks.patch └── ReadMe.md # 三份补丁的说明文档从 package.sh 可以确认移植的版本信息与依赖关系版本SRB22.2.15version2.2.15短版本号short_version2215依赖端口curl、glu、libpng、SDL2、SDL2_mixer——游戏图形/音频依赖 SDL2 生态其中 SDL2_mixer 移植 又进一步依赖libmodplug、libmpg123、libvorbis、timidity等音频解码库构建系统CMake通过configure()以-B build指定构建目录并传入CMAKE_TOOLCHAIN_FILE指向 SerenityOS 的交叉编译工具链关键配置项SRB2_CONFIG_EXECINFOOFF禁用 execinfo避免依赖 SerenityOS 暂不提供的 API、SRB2_SDL2_EXE_NAMEsrb2、SRB2_CONFIG_ASSET_DIRECTORY指向构建目录下的资产路径安装位置/usr/local/games/SRB2并在系统应用菜单中注册为 “Sonic Robo Blast 2”分类Games启动命令为/usr/local/games/SRB2/srb2。值得注意的一个细节是install()中的特殊处理安装时通过run_nocd touch ${PORT_BUILD_DIR}/patch.pk3手工创建一个空的patch.pk3文件。脚本注释解释了原因——该文件虽然在 2.2.12/2.2.13 之后源码中已不再引用但安装流程仍需要它这是移植过程中处理上游资产依赖变更的一个典型小技巧。SerenityOS Ports 补丁机制patches/*.patch如何生效在深入三份补丁之前先理解补丁是如何被应用的。SerenityOS 的 Ports 框架核心是 .port_include.sh其中patch_internal()函数负责补丁应用if [ -d ${PORT_META_DIR}/patches ]; then for filepath in ${PORT_META_DIR}/patches/*.patch; do filename$(basename $filepath) if [ -f $workdir/.${filename}_applied ]; then continue fi if [ -e ${workdir}/.git ]; then run git am --keep-cr --keep-non-patch ${filepath} else run patch -p$patchlevel $filepath run touch .${filename}_applied fi done fi这里有几个关键机制值得展开按文件名排序顺序应用*.patch通配符按字典序匹配因此补丁以0001-、0002-、0003-前缀编号保证应用顺序确定且可复现幂等保护每个补丁应用成功后会在workdir下创建一个以补丁名命名的.xxx_applied标记文件下次构建时检测到标记文件存在就跳过避免重复打补丁导致失败两种应用方式若源码目录是 git 仓库则用git am保留提交元数据否则用patch -p1patchlevel默认值为 1对应a/、b/前缀剥离。三份补丁的提交信息都来自作者 RefragR3FR4GYTgmail.com日期为 2024 年 2 月 4 日采用标准的 git format-patch 格式包含完整 diff 和提交说明。补丁 0001修复 libgme 头文件搜索路径第一份补丁 0001-Fix-libgme-include.patch 解决的是一个非常经典的 CMake 构建问题头文件找不到。问题现象原文档说明SRB2 的某个构建目标需要gme.h头文件libgme即 Game Music Emu 库用于播放游戏音乐格式但 CMake 构建时无法自动找到它。补丁内容补丁对上游CMakeLists.txt只做了一行插入include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) include_directories(${CMAKE_BINARY_DIR}/_deps/libgme-src)这一行的含义SRB2 通过 CMake 的 FetchContent 机制_deps目录正是 FetchContent 下载依赖的默认落地位置拉取 libgme 源码但上游CMakeLists.txt没有把 libgme 的源码根目录加入全局头文件搜索路径导致引用#include gme.h的编译单元报“找不到头文件”。补丁通过include_directories()显式补上${CMAKE_BINARY_DIR}/_deps/libgme-src让预处理器能在构建产物目录下的依赖源码中找到gme.h。这个补丁本身不修改任何业务逻辑属于纯粹的构建基础设施修复——对于移植场景这类“帮 CMake 一把”的补丁非常常见因为交叉编译环境下依赖的安装位置与上游开发环境往往不一致。补丁 0002禁用控制台变量取值校验的“坏路径”第二份补丁 0002-Disable-Console-Variables-value-checker-sad-path.patch 修改的是src/command.c中的Setvalue()静态函数——这是 SRB2 控制台系统处理consvar_t控制台变量赋值校验的核心逻辑。问题现象原文档说明控制台变量的取值校验器即使在默认变量值下也表现异常禁用其错误路径后问题解决游戏运行不受影响。补丁内容补丁删除了两处代码。第一处在整数型变量的范围检查段if (v INT32_MIN) goto badinput;原逻辑当解析出的整数值等于INT32_MIN32 位有符号整数最小值时跳转到badinput错误标签拒绝赋值。补丁删除了这一判断——推测在 SerenityOS 的 C 库/平台组合下某些默认控制台变量值的数值转换结果恰好落入INT32_MIN边界被误判为非法输入。第二处删除了字符串枚举型变量匹配失败后的兜底逻辑- // ...or not. - goto badinput; found:原逻辑如果字符串值与变量允许的枚举取值列表逐一比对后均不匹配就goto badinput报错。补丁删除了这个兜底跳转让不匹配的值也能继续走found:之后的正常赋值流程。源码级解读从 补丁上下文 可以看到Setvalue()的完整结构函数先解析字符串通过MINVAL/MAXVAL宏展开做数值范围钳制override/overrideval用于处理越界覆盖再对枚举型变量遍历possible values表查找匹配项。补丁删掉的正是这条“sad path”错误路径——作者评估后认为该路径在 SerenityOS 上误伤正常流程且禁用后游戏功能不受影响因此选择直接移除而非修复其根因。这是移植工作中“以可构建、可运行为优先”的务实取舍。补丁 0003i_system.c 系统层兼容性 hack第三份补丁 0003-i_system.c-hacks.patch 修改src/sdl/i_system.c这是 SRB2 中与操作系统平台打交道最深的文件负责系统初始化、内存信息查询、鼠标串口初始化等。补丁内容补丁分两部分共 3 行插入、3 行删除第一部分删除三个平台专属头文件的#include#include sys/statvfs.h #include sys/param.h -#include sys/mount.h /*For meminfo*/ #include sys/types.h #ifdef FREEBSD #include kvm.h #endif -#include nlist.h -#include sys/sysctl.h被删的三个头文件sys/mount.h、nlist.h、sys/sysctl.h在 FreeBSD 分支下被包含用于磁盘挂载信息与内核内存信息查询。SerenityOS 的 C 库LibC尚未提供这些 BSD 专属接口导致编译直接失败。删除后相关功能代码会被条件编译逻辑跳过i_system.c中对不同系统用#ifdef分支选择实现因此不影响构建。第二部分将I_StartupMouse2()中通过串口ioctl设置 DTR/RTS 信号控制鼠标供电的代码块用#if 0包裹} #if 0 if (dtr ! -1 || rts ! -1) { INT32 c; ioctl(fdmouse2, TIOCMSET, c); } #endif } mouse2_started 1;这段代码在初始化第二个鼠标时通过ioctl(fdmouse2, TIOCMSET, c)操作调制解调器控制信号TIOCM_DTR/TIOCM_RTS。SerenityOS 的串口驱动/终端层未实现该 ioctl 语义编译或运行时可能出错。补丁用#if 0直接禁用正如原文档所说“这些代码看起来影响不大游戏依然能正常运行”。完整移植流水线从package.sh到运行综合 Ports README 与 .port_include.shSRB2 的完整安装流程是installdepends → fetch → patch → configure → build → install。在已经构建好 SerenityOS 交叉编译环境的前提下cd Ports/SRB2 ./package.sh执行过程的核心步骤与三份补丁的介入点installdepends按依赖数组自动安装curl、glu、libpng、SDL2、SDL2_mixer依赖以--auto模式标记安装记录在installed.dbfetch下载两个归档文件——上游源码SRB2_release_2.2.15.tar.gz带 SHA256 校验与官方完整资产包SRB2-v2215-Full.zip包含游戏贴图、音效等数据文件校验通过后解压到workdirSRB2-SRB2_release_2.2.15patch依次应用patches/下三份补丁每份应用后打.xxx_applied标记0001 修复 CMake 头文件搜索、0002 修复控制台变量校验、0003 修复系统层 API 兼容三者共同保证后续 configure/build 能顺利通过configure运行cmake -B build传入 SerenityOS 工具链文件与上述配置项buildcmake --build build产出srb2可执行文件installtouch patch.pk3后cmake --install到/usr/local/games/SRB2同时注册启动器与图标。维护补丁利用dev模式重新生成补丁不是一成不变的。当 SRB2 上游发布新版本、或需要针对 SerenityOS 做更多适配时Ports 框架提供了./package.sh dev开发模式.port_include.sh 中的do_dev()函数进入一个基于 git 的workdir其“干净基线”是打过补丁的版本可作为远程仓库进行提交、回退等常规 git 操作退出 dev shell 后脚本比较refs/tags/patched与当前 HEAD若存在差异自动用git format-patch --no-numbered --zero-commit --no-signature --full-index refs/tags/source重新生成patches/*.patch最后调用do_generate_patch_readme()从每个补丁的git mailinfo提取 Subject 与提交正文自动重建patches/ReadMe.md——这正是本仓库中 ReadMe.md 的生成方式。因此本仓库的 ReadMe 文档结构与补丁是一一对应的每个## 补丁文件名小节下的第一行是 git 提交标题随后是提交正文。理解这一点后维护者新增或修改补丁时只需保持 git 提交规范ReadMe 可随时自动化重建。总结三份补丁背后的移植方法论补丁涉及文件问题类型修复策略0001CMakeLists.txt依赖头文件搜索路径缺失显式include_directories补路径0002src/command.c控制台变量校验逻辑误判删除错误路径分支0003src/sdl/i_system.c平台专属头文件与 ioctl 不可用删除 include #if 0禁用这三份补丁浓缩了把上游游戏移植到 SerenityOS 的三类典型工作为构建系统补齐交叉编译环境缺失的路径信息、禁用在新平台上误伤正常流程的校验逻辑、屏蔽依赖 SerenityOS 尚未实现的系统 API 的代码段。它们都不改动游戏的核心玩法逻辑以最小侵入换取“能构建、能运行”体现了 SerenityOS Ports 生态“务实移植、渐进适配”的工程风格。若要深入源码细节可继续研读 SRB2 补丁目录、移植脚本 以及 Ports 框架核心 .port_include.sh。【免费下载链接】serenityThe Serenity Operating System 项目地址: https://gitcode.com/GitHub_Trending/se/serenity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门