3.6 KiB
3.6 KiB
Code Style
这个文档记录 agent 修改 Tianole 代码时必须遵守的代码组织和风格规则。
总原则
- 参考 Linux 的工程风格,但不机械照抄 Linux 的历史实现。
- 简化实现可以接受,写死架构边界、设备假设、内存布局和调用路径不接受。
- 文件按职责拆分,不按行数拆分。
- 入口文件只编排流程,不承载具体功能细节。
Include 风格
- 公共头文件使用
<...>,例如<tianole/boot_info.h>。 - 同目录私有头文件使用
"...",例如"file.h"。 - 不使用
../foo.h这类相对 include。 - 如果一个头文件需要跨目录使用,先判断它是否应该成为公共接口。
include/tianole/放尽量架构无关的共享接口。arch/<arch>/include/放架构公开接口。
文件组织
- 长文件不是问题,职责混乱才是问题。
- 一个文件可以较长,但必须代表一个清晰子系统、算法或驱动边界。
- 不为了降低行数拆出
utils.c、helpers.c这类无边界文件。 - 按职责、生命周期、所有权和调用边界拆分。
kernel/main.c、boot/main.c这类入口文件应保持短,只串联阶段。mm/是顶层内存管理子系统目录,不放在kernel/mm/下。- 顶层目录参考
docs/agents/linux-layout.md;可以预留目录,但不要放临时代码。
命名
- 内部 C API 不加
tianole_前缀。 - 架构目录内部不要重复架构名前缀;例如
arch/x86/kernel/内使用gdt_init(),不要写成x86_gdt_init()。 - 跨通用层暴露的架构入口使用
arch_前缀,例如arch_traps_init()。 - 描述硬件规格的文档文字可以写
x86_64,但代码文件名和内部符号不需要反复带x86。 - 避免
temp、tmp这类临时语义进入函数名、类型名和长期变量名。 - 一次性局部变量也应尽量使用具体含义命名。
- 名字应表达长期职责,不表达当前实现的临时状态。
注释
- 注释优先解释硬件约束、ABI 决策、内存所有权、并发语义和不明显的不变量。
- 不写重复描述简单代码行为的注释。
- 如果代码依赖硬件手册、启动协议、调用顺序或特殊寄存器状态,应写明约束。
- 如果一个实现是临时简化,应写清楚后续替换边界,而不是写成永久接口。
C 格式
- 使用
.clang-format作为当前格式化规则。 - 使用 tab 缩进。
- 函数左花括号另起一行。
if/for/while左花括号留在行尾。- 文本文件使用 LF 行尾。
构建文件
- 根
Makefile只做总控和通用规则。 - 架构配置放在
arch/<arch>/Makefile。 - 目录自己的源文件列表放在对应目录的
Makefile。 - 顶层子系统目录可以有自己的
Makefile,例如mm/Makefile。 - 不新增独立
mk/目录,除非后续有明确且无法避免的理由。
脚本组织
scripts/check.sh是本地和 CI 共用的检查入口,只做编排。- 可独立执行的检查放在
scripts/checks/。 - 多个检查共享的函数放在
scripts/lib/。 - 不把所有检查逻辑持续堆进
scripts/check.sh。 - 项目结构规则放在
scripts/checks/structure.sh,优先用宿主 Linux/LLVM 工具实现底层扫描,把 Tianole 自己的目录和 include 约束固化在脚本里。 - 启动阶段内核自测集中放在
kernel/selftest/,不要散落在具体实现目录里。
验证
- 新增或大改 C/H 文件后运行
clang-format。 - 提交前至少运行
scripts/check.sh。 - 如果只是文档修改,至少运行
git diff --check。