# 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-命名空间机制)。
