Files
TransPyC/wiki/12-project.md
2026-07-18 19:25:40 +08:00

6.6 KiB
Raw Blame History

12 - 项目配置与构建

Viper 项目使用 project.json 配置文件管理编译和链接参数。

project.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_64ELF 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 使用自定义链接脚本控制内存布局:

ENTRY(_start)

SECTIONS
{
    . = 0x100000;  /* 加载地址 */

    .text : {
        *(.text.startup)
        *(.text*)
    }

    .rodata : {
        *(.rodata*)
    }

    .data : {
        *(.data*)
    }

    .bss : {
        *(.bss*)
        *(COMMON)
    }
}

编译命令

TransPyC 编译器的基本用法(注:适用于单个文件,而不适用于工程):

python TransPyC.py -f InputFile -o OutputFile [options]

命令行参数

参数 说明
-f 输入文件路径
-o 输出文件路径
-wh 头文件列表
-debug 调试输出文件
-cc 编译命令
-cflags 编译标志
-run 编译后运行
-args 运行参数
-h 辅助文件C 或 Python

工程编译使用:

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