Files
TransPyC/wiki/12-project.md
T

274 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 12 - 项目配置与构建
Viper 项目使用 `project.vpj` 配置文件管理编译和链接参数(Python 单文件模式仍接受 `project.json`)。
## project.vpj 结构
```json
{
"name": "Kernel",
"version": "1.0.0",
"source_dir": "./Kernel",
"build_dir": "./.tpv_build",
"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,
"sha1_slice_level": 1,
"target": "llvm",
"strict_mode": true
}
}
```
## 配置项说明
### 基本信息字段
| 字段 | 类型 | 说明 |
|------|------|------|
| `name` | string | 项目名称 |
| `version` | string | 项目版本 |
| `source_dir` | string | 源代码目录(相对于 project.vpj 所在目录) |
| `build_dir` | string | 构建目录(默认 `./.tpv_build`);`temp`/`output` 均由它派生 |
### 编译器配置
| 字段 | 类型 | 说明 |
|------|------|------|
| `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`;TransPyV 宿主工程为 `clang++`) |
| `linker.flags` | string[] | 链接器标志 |
| `linker.static_libs` | string[] | 静态库/目标文件列表(`.a`/`.obj`) |
| `linker.dynamic_libs` | string[] | 动态库列表(`.dll`/`.so`) |
| `linker.output` | string | 输出文件名 |
支持 DSO(动态共享对象)构建:开启后产物为 `*_dso.ll`。
常用 `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**——由各工程 `project.vpj` 自行指定(TransPyV 自身为 `x86_64-pc-windows-gnu`;ViperOS 内核为 `x86_64-none-elf`)。`target.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.sha1_slice_level` | int | SHA1 切片存储级别(默认 1;≥1 时产物按 `{temp}/{sha1[0:2]}/` 子目录存放) |
| `options.target` | string | 编译目标(目前仅支持 `llvm`) |
| `options.strict_mode` | bool | 严格模式 |
## 切片优化级别
| 级别 | 名称 | 说明 |
|------|------|------|
| `0` | `no_optimize` | 无优化 |
| `1` | `conservative` | 保守优化 |
| `2` | `moderate` | 适度优化 |
| `3` | `aggressive` | 激进优化(默认) |
| `s` | `size` | 体积优化 |
## 项目结构示例
### 内核项目
```
VKernel/
├── project.vpj # 项目配置
├── linker.ld # 链接脚本
├── Kernel/ # 源代码目录
│ ├── main.vp # 内核入口
│ ├── bootinfo.vp
│ ├── intr/
│ │ ├── gdt.vp
│ │ ├── idt.vp
│ │ └── syscall.vp
│ ├── drivers/
│ │ ├── serial/
│ │ ├── video/
│ │ ├── storage/
│ │ └── ...
│ └── ...
├── .tpv_build/ # 构建目录(build_dir,自动生成)
│ ├── temp/ # 临时文件
│ │ ├── <sha1[0:2]>/ # SHA1 切片子目录(sha1_slice_level ≥ 1)
│ │ │ ├── <SHA1>.vpi # 签名存根
│ │ │ ├── <SHA1>.stub.ll # LLVM IR 声明
│ │ │ ├── <SHA1>.text.ll # 含代码的 .ll
│ │ │ └── <SHA1>.deps.txt # 依赖信息
│ │ └── _sha1_map.txt # SHA1→源文件路径映射(仅人类可读)
│ └── output/ # 输出文件
│ ├── kernel.bin # 内核二进制
│ ├── *.deps.txt # 依赖信息
│ └── linker.ld # 生成的链接脚本
```
### 应用项目
```
HelloWorld/
├── project.vpj # 项目配置
├── linker.ld # 链接脚本
├── main.vp # 应用入口
└── .tpv_build/ # 构建目录(自动生成)
├── temp/ # 临时文件
└── output/ # 输出文件
└── helloworld.elf # ELF 可执行文件
```
### 库项目
```
SerialLogger/
├── project.vpj # 项目配置
├── linker.ld # 链接脚本
├── serial_logger.vp # 库源码
└── .tpv_build/ # 构建目录(自动生成)
├── 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) |
工程编译使用(`--project` 指定工程文件):
```bash
python Projectrans.py --project project.vpj
```
即可
## 构建流程(真实骨架)
工程构建的实际流水线:
- **Phase 1(声明阶段)**:扫描入口与依赖并建依赖图 → 1a 结构体注册 → 1b 生成 `.vpi` 并翻译生成 stub
- **Phase 2(翻译与链接)**
- **Phase A-pre-vpi / Phase A-pre**:加载 `.vpi`,预翻译准备
- **Phase A**:主循环多遍收敛翻译,`.stub.ll`/`.text.ll` 在此写盘
- **Phase B**:`llc` 并行编译 `.ll` → `.o`
- **Phase B+**:缺失 includes 按需编译
- **Phase C**:链接(`linker.cmd` 决定链接器)
## 增量编译
TransPyC 支持基于 SHA1 的增量编译,与两阶段编译模型紧密耦合:
### 阶段一增量
- 每个源文件按内容计算 SHA1 哈希(16 个十六进制字符,即 64 位截断)
- 如果 `<SHA1>.vpi` 和 `<SHA1>.stub.ll` 已存在,则跳过生成(缓存命中)
- 只有源文件内容变化导致 SHA1 变化时才重新生成声明接口
- SHA1 → 源文件路径映射在内存 `Sha1Store` 中多遍收敛构建;`temp/_sha1_map.txt`(格式 `<sha1>:<relative_path>`)仅人类可读
### 阶段二增量
- 阶段二(Phase A 主循环)在内存 `Sha1Store`/`StubMergerStore` 中多遍收敛构建并复用映射,不依赖 `_sha1_map.txt`
- 旧产物清理使用 `--clear-cache`
- 共享符号表为内存 `StubMergerStore`,按需加载避免每个文件重复加载
### SHA1 命名空间与增量编译的协同
SHA1 同时服务于命名空间隔离和增量编译:
- **命名空间**:非 `t.CExport` 函数和结构体使用 SHA1 前缀,消除符号冲突
- **增量编译**:SHA1 不变则缓存命中,SHA1 变化则重新生成
详见 [01-overview.md 中 SHA1 命名空间机制](01-overview.md#sha1-命名空间机制)。