253 lines
6.6 KiB
Markdown
253 lines
6.6 KiB
Markdown
# 12 - 项目配置与构建
|
||
|
||
Viper 项目使用 `project.json` 配置文件管理编译和链接参数。
|
||
|
||
## project.json 结构
|
||
|
||
```json
|
||
{
|
||
"name": "Kernel",
|
||
"version": "1.0.0",
|
||
"source_dir": "./Kernel",
|
||
"temp_dir": "./temp",
|
||
"output_dir": "./output",
|
||
"compiler": {
|
||
"cmd": "llc",
|
||
"flags": ["-filetype=obj", "-mtriple=x86_64-none-elf", "-relocation-model=static", "-O2"]
|
||
},
|
||
"linker": {
|
||
"cmd": "ld.lld.exe",
|
||
"flags": [
|
||
"-m", "elf_x86_64",
|
||
"-T", "linker.ld",
|
||
"--oformat", "elf64-x86-64",
|
||
"--strip-all"
|
||
],
|
||
"output": "kernel.bin"
|
||
},
|
||
"includes": ["../../includes"],
|
||
"target": {
|
||
"triple": "x86_64-none-elf",
|
||
"datalayout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||
},
|
||
"options": {
|
||
"slice_level": 3,
|
||
"target": "llvm",
|
||
"strict_mode": true
|
||
}
|
||
}
|
||
```
|
||
|
||
## 配置项说明
|
||
|
||
### 基本信息字段
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `name` | string | 项目名称 |
|
||
| `version` | string | 项目版本 |
|
||
| `source_dir` | string | 源代码目录(相对于 project.json 所在目录) |
|
||
| `temp_dir` | string | 临时文件目录(存放 .pyi 存根等) |
|
||
| `output_dir` | string | 输出文件目录 |
|
||
|
||
### 编译器配置
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `compiler.cmd` | string | 编译器命令(通常为 `llc`) |
|
||
| `compiler.flags` | string[] | 编译器标志 |
|
||
|
||
常用 `llc` 标志:
|
||
- `-filetype=obj`:输出目标文件
|
||
- `-mtriple=x86_64-none-elf`:目标三元组
|
||
- `-relocation-model=static`:静态重定位
|
||
- `-O2`:优化级别
|
||
|
||
### 链接器配置
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `linker.cmd` | string | 链接器命令(通常为 `ld.lld.exe`) |
|
||
| `linker.flags` | string[] | 链接器标志 |
|
||
| `linker.output` | string | 输出文件名 |
|
||
|
||
常用 `ld.lld` 标志:
|
||
- `-m elf_x86_64`:ELF x86_64 格式
|
||
- `-T linker.ld`:链接脚本
|
||
- `--oformat elf64-x86-64`:输出 ELF 格式
|
||
- `--oformat binary`:输出原始二进制(用于内核)
|
||
- `--strip-all`:去除所有符号信息
|
||
|
||
### 目标平台配置
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `target.triple` | string | LLVM 目标三元组 |
|
||
| `target.datalayout` | string | LLVM 数据布局字符串 |
|
||
|
||
默认值:
|
||
- triple: `x86_64-none-elf`
|
||
- datalayout: `e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128`
|
||
|
||
### 包含路径
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `includes` | string[] | 模块搜索路径列表 |
|
||
|
||
### 编译选项
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `options.slice_level` | int | 切片优化级别(0-3) |
|
||
| `options.target` | string | 编译目标(目前仅支持 `llvm`) |
|
||
| `options.strict_mode` | bool | 严格模式 |
|
||
|
||
## 切片优化级别
|
||
|
||
| 级别 | 名称 | 说明 |
|
||
|------|------|------|
|
||
| `0` | `no_optimize` | 无优化 |
|
||
| `1` | `conservative` | 保守优化 |
|
||
| `2` | `moderate` | 适度优化 |
|
||
| `3` | `aggressive` | 激进优化(默认) |
|
||
| `s` | `size` | 体积优化 |
|
||
|
||
## 项目结构示例
|
||
|
||
### 内核项目
|
||
|
||
```
|
||
VKernel/
|
||
├── project.json # 项目配置
|
||
├── linker.ld # 链接脚本
|
||
├── Kernel/ # 源代码目录
|
||
│ ├── main.py # 内核入口
|
||
│ ├── bootinfo.py
|
||
│ ├── intr/
|
||
│ │ ├── gdt.py
|
||
│ │ ├── idt.py
|
||
│ │ └── syscall.py
|
||
│ ├── drivers/
|
||
│ │ ├── serial/
|
||
│ │ ├── video/
|
||
│ │ ├── storage/
|
||
│ │ └── ...
|
||
│ └── ...
|
||
├── temp/ # 临时文件(自动生成)
|
||
│ ├── <SHA1>.pyi # 签名存根(阶段一生成)
|
||
│ ├── <SHA1>.stub.ll # LLVM IR 声明(阶段一生成)
|
||
│ └── _sha1_map.txt # SHA1→源文件路径映射
|
||
└── output/ # 输出文件(自动生成)
|
||
├── kernel.bin # 内核二进制
|
||
├── *.deps.json # 依赖信息
|
||
└── linker.ld # 生成的链接脚本
|
||
```
|
||
|
||
### 应用项目
|
||
|
||
```
|
||
HelloWorld/
|
||
├── project.json # 项目配置
|
||
├── linker.ld # 链接脚本
|
||
├── main.py # 应用入口
|
||
├── temp/ # 临时文件
|
||
└── output/ # 输出文件
|
||
└── helloworld.elf # ELF 可执行文件
|
||
```
|
||
|
||
### 库项目
|
||
|
||
```
|
||
SerialLogger/
|
||
├── project.json # 项目配置
|
||
├── linker.ld # 链接脚本
|
||
├── serial_logger.py # 库源码
|
||
├── temp/ # 临时文件
|
||
└── output/ # 输出文件
|
||
```
|
||
|
||
## 链接脚本
|
||
|
||
ViperOS 使用自定义链接脚本控制内存布局:
|
||
|
||
```ld
|
||
ENTRY(_start)
|
||
|
||
SECTIONS
|
||
{
|
||
. = 0x100000; /* 加载地址 */
|
||
|
||
.text : {
|
||
*(.text.startup)
|
||
*(.text*)
|
||
}
|
||
|
||
.rodata : {
|
||
*(.rodata*)
|
||
}
|
||
|
||
.data : {
|
||
*(.data*)
|
||
}
|
||
|
||
.bss : {
|
||
*(.bss*)
|
||
*(COMMON)
|
||
}
|
||
}
|
||
```
|
||
|
||
## 编译命令
|
||
|
||
TransPyC 编译器的基本用法(注:适用于单个文件,而不适用于工程):
|
||
|
||
```bash
|
||
python TransPyC.py -f InputFile -o OutputFile [options]
|
||
```
|
||
|
||
### 命令行参数
|
||
|
||
| 参数 | 说明 |
|
||
|------|------|
|
||
| `-f` | 输入文件路径 |
|
||
| `-o` | 输出文件路径 |
|
||
| `-wh` | 头文件列表 |
|
||
| `-debug` | 调试输出文件 |
|
||
| `-cc` | 编译命令 |
|
||
| `-cflags` | 编译标志 |
|
||
| `-run` | 编译后运行 |
|
||
| `-args` | 运行参数 |
|
||
| `-h` | 辅助文件(C 或 Python) |
|
||
|
||
工程编译使用:
|
||
```bash
|
||
python Projectrans.py xxx.json
|
||
```
|
||
即可
|
||
|
||
## 增量编译
|
||
|
||
TransPyC 支持基于 SHA1 的增量编译,与两阶段编译模型紧密耦合:
|
||
|
||
### 阶段一增量
|
||
|
||
- 每个源文件按内容计算 SHA1 哈希(16位)
|
||
- 如果 `<SHA1>.pyi` 和 `<SHA1>.stub.ll` 已存在,则跳过生成(缓存命中)
|
||
- 只有源文件内容变化导致 SHA1 变化时才重新生成声明接口
|
||
- `temp/_sha1_map.txt` 记录 SHA1 → 源文件路径的映射,格式为 `<sha1>:<relative_path>`
|
||
|
||
### 阶段二增量
|
||
|
||
- 阶段二加载 `temp/_sha1_map.txt` 重建 SHA1 映射
|
||
- 过滤掉不在当前 SHA1 映射中的旧 `.pyi` 和 `.stub.ll` 文件
|
||
- 共享符号表一次性构建,避免每个文件重复加载
|
||
|
||
### SHA1 命名空间与增量编译的协同
|
||
|
||
SHA1 同时服务于命名空间隔离和增量编译:
|
||
- **命名空间**:非 `t.CExport` 函数和结构体使用 SHA1 前缀,消除符号冲突
|
||
- **增量编译**:SHA1 不变则缓存命中,SHA1 变化则重新生成
|
||
|
||
详见 [01-overview.md 中 SHA1 命名空间机制](01-overview.md#sha1-命名空间机制)。
|