feat(docs): update package model documentation to include new package types and clarify definitions

This commit is contained in:
crazywhalecc
2026-07-14 23:03:15 +08:00
parent abc6e3695f
commit 01a0b26a2a
2 changed files with 116 additions and 39 deletions

View File

@@ -1,20 +1,18 @@
# Package 模型
<!-- TODO: 统一 Package 模型说明library / php-extension / target 类型。
config/pkg/ 下 per-package YAML 格式、depends 字段、平台覆盖(@windows / @unix 写法)。
artifact.source 和 artifact.binary 字段。附注释的 library 和 extension YAML 示例。 -->
## Package 定义
Package 是 StaticPHP 构建系统中的核心概念,代表一个可构建/可安装的单元,如 PHP 扩展、库、构建目标等。
每个 Package 包含构建信息、依赖关系、构建逻辑等,构成了 StaticPHP 的构建模型。Package 的定义主要通过 YAML/JSON 配置文件来实现。`core` 注册表的包配置文件位于 `config/pkg/` 目录下,对应的构建类位于 `src/Package/` 目录
每个 Package 包含构建信息、依赖关系、构建逻辑等,构成了 StaticPHP 的构建模型。Package 的定义主要通过 YAML/JSON 配置文件来实现。`core` Registry 的 Package 配置位于 `config/pkg/` 目录下,可选 recipe class 位于 `src/Package/` 对应的子目录
Package 主要分为种类型:
Package 分为种类型:
- **php-extension**PHP 扩展包,包含 PHP 扩展的构建信息和构建逻辑。
- **library**库包,包含构建工具链、依赖库等的构建信息和构建逻辑
- **library**依赖库 Package通常安装到 `buildroot/`,供其他 Package 编译和链接
- **target**:构建目标包,代表最终的构建产物,如 PHP 二进制、curl 二进制等,继承自 `library` 包类型。
- **virtual-target**:虚构建目标包,代表一个抽象的构建目标,不直接对应构建产物,主要用于依赖管理和构建调度。
- **tool**:宿主机侧构建工具 Package单独安装在 `pkgroot/` 下,不作为链接期库依赖处理。
```yaml
{pkg-name}:
@@ -24,7 +22,7 @@ Package 主要分为四种类型:
## Artifact 定义
Artifact 是独立于 Package 的定义,它包含构建包的源码归档文件或预构建的二进制文件。每个 Artifact 定义了下载 URL、解压方式、构建产物的文件路径等信息。Package 可以通过 `artifact` 字段引用一个或多个 Artifact获取构建所需的源码或二进制文件。
Artifact 是独立于 Package 的定义,它包含构建包的源码归档文件或预构建的二进制文件。每个 Artifact 定义了下载 URL、解压方式、构建产物的文件路径等信息。一个 Package 可以通过 `artifact` 字段引用一个 Artifact,以获取构建所需的源码或二进制文件。
简单来说,默认情况下,一个 Package 对应一个 Artifact如果多个 Package 共用一份源码时,可以定义一个 Artifact 供多个 Package 引用。Artifact 的定义位于 `config/artifact/` 目录下,对应的自定义下载/解压逻辑类位于 `src/Package/Artifact/` 目录下对于虚拟目标、PHP 内置扩展等特殊包类型Package 也可以不设置 Artifact 字段。
@@ -43,7 +41,7 @@ example-library-package:
## php-extension 包类型
php-extension 一个包代表一个 PHP 扩展,它的配置文件位于 `config/pkg/ext/` 目录下,构建类继承自 `PhpExtensionPackage`,位于 `src/Package/Extension/` 目录下。PHP 扩展包的配置文件包含扩展名称、版本、依赖关系、构建选项等信息
php-extension Package 代表一个 PHP 扩展,它的配置文件位于 `config/pkg/ext/` 目录下。可选的 recipe class 通常放在 `src/Package/Extension/`,通过 `#[Extension]` 注册,并从 callback context 接收对应的 `PhpExtensionPackage`。当前 core recipe 支持继承 `PhpExtensionPackage`,但并不要求继承
```yaml
ext-lz4:
@@ -60,7 +58,7 @@ ext-lz4:
depends:
- liblz4
php-extension:
arg-type@unix: '--enable-lz4=@shared_suffix@ --with-lz4-includedir=@build_root_path@'
arg-type@unix: '--enable-lz4@shared_suffix@ --with-lz4-includedir=@build_root_path@'
arg-type@windows: '--enable-lz4'
```
@@ -75,15 +73,17 @@ ext-{ext-name}: # 包名必须以 ext- 前缀开头
lang: c # 可选扩展的实现语言c / c++ 等)
frameworks: [] # 可选相关macOS框架依赖列表
artifact: '{artifact-name}' # 可选;字符串时引用同名 Artifact 定义,
artifact: '{artifact-name}' # 可选;字符串时引用指定名称的 Artifact 定义,
# 对象时为内联 Artifact内置扩展无需此字段
# depends / suggests 支持 @windows / @unix / @linux / @macos 后缀
# depends / suggests / tools 支持 @windows / @unix / @linux / @macos 后缀
depends: [] # 可选硬依赖列表库名直接写PHP 扩展需加 ext- 前缀)
depends@unix: [] # 可选,仅 Unix 平台生效的硬依赖
depends@windows: [] # 可选,仅 Windows 平台生效的硬依赖
suggests: [] # 可选,可选依赖列表(格式同 depends
suggests@unix: []
tools: [] # 可选,宿主机侧构建工具依赖,单独解析
tools@windows: [] # 可选,特定平台的工具依赖
# ── php-extension 专属字段(嵌套在 php-extension: 对象中)─────────────────
php-extension:
@@ -101,7 +101,7 @@ ext-{ext-name}: # 包名必须以 ext- 前缀开头
# @shared_suffix@ → 共享构建时展开为 =shared静态构建时为空
# @shared_path_suffix@ → 共享构建时展开为 =shared,{buildroot},静态构建时为 ={buildroot}
arg-type: enable
arg-type@unix: '--enable-{extname}=@shared_suffix@'
arg-type@unix: '--enable-my-extension@shared_suffix@'
arg-type@windows: with-path
zend-extension: false # 可选true 表示这是 Zend 扩展(如 opcache、xdebug
@@ -120,7 +120,7 @@ ext-{ext-name}: # 包名必须以 ext- 前缀开头
## library 包类型
library 包代表一个需要从源码编译的依赖库(如 openssl、zlib 等),其配置文件位于 `config/pkg/lib/` 目录下,构建类继承自 `LibraryPackage`位于 `src/Package/Library/` 目录下
library Package 代表 openssl、zlib 等依赖库,可以从源码或预构建二进制安装。其配置文件位于 `config/pkg/lib/` 目录下。可选的 recipe class 通常放在 `src/Package/Library/`通过 `#[Library]` 注册,并从 callback context 接收 `LibraryPackage`;不要求继承该类
以 openssl 为例:
@@ -160,20 +160,25 @@ openssl:
# ── 通用字段 ─────────────────────────────────────────────────────────────
description: '...' # 可选,人类可读的包描述
license: MIT # 可选,SPDX 许可证标识符(用于许可证导出)
license: # 可选,从源码构建后复制的许可证内容
type: file # type 可为 file 或 text也可填写多个条目的列表
path: LICENSE
lang: c # 可选库的实现语言c / c++ 等)
frameworks: [] # 可选,相关框架标签列表
artifact: '{artifact-name}' # 必填;字符串时引用同名 Artifact 定义,对象时为内联 Artifact
artifact: '{artifact-name}' # 必填;字符串时引用指定名称的 Artifact 定义,对象时为内联 Artifact
# depends / suggests 支持 @windows / @unix / @linux / @macos 后缀
# depends / suggests / tools 支持 @windows / @unix / @linux / @macos 后缀
depends: [] # 可选,硬依赖列表(库名或 ext- 前缀的 PHP 扩展名)
depends@unix: []
depends@windows: []
suggests: [] # 可选,可选依赖列表(格式同 depends
tools: [] # 可选,仅构建时需要的 ToolPackage 名称
tools@windows: []
# ── library / target 专属字段 ────────────────────────────────────────────
# 以下字段用于构建完成后验证产物是否已正确安装,支持 @unix / @windows / @linux / @macos 后缀
# 以下字段用于构建完成后验证产物是否已正确安装headers、static-libs、static-bins
# 支持 @unix / @windows / @linux / @macos 后缀
# 验证 buildroot/include/ 下是否存在指定头文件或目录
# 相对路径基于 buildroot/include/,绝对路径直接使用
@@ -225,17 +230,49 @@ openssl:
| `{source_path}` | 解压源码目录(`source/` |
| `{spc_msys2_path}` | MSYS2 根目录(`msys64/`)——仅 Windows |
## tool 包类型
`tool` Package 表示构建其他 Package 时需要的可执行工具,而不是链接进最终 target 的库。Tool Package 可以使用预构建二进制,也可以从源码构建,默认安装在 `pkgroot/` 下的共享 `bin/` 或配置的子目录。其他 Package 通过顶层 `tools` 字段请求这些工具;该依赖集合与 `depends``suggests` 分开解析。
```yaml
nasm:
type: tool
artifact:
binary:
windows-x86_64:
type: url
url: 'https://example.com/nasm-win64.zip'
extract:
nasm.exe: '{pkg_root_path}/bin/nasm.exe'
ndisasm.exe: '{pkg_root_path}/bin/ndisasm.exe'
tool:
provides: [nasm.exe, ndisasm.exe]
binary-subdir: bin
min-version: '2.16'
```
嵌套的 `tool` 对象支持:
| 字段 | 是否必填 | 含义 |
|---|---|---|
| `provides` | 是 | 用于判断工具是否已经安装的可执行文件名 |
| `binary-subdir` | 否 | `install-root` 下存放可执行文件的目录;默认就是安装根目录 |
| `install-root` | 否 | 安装根目录;默认为 `PKG_ROOT_PATH`,支持路径占位符 |
| `min-version` | 否 | 由 `ToolPackage` 暴露的最低版本元数据installer 当前不会强制校验 |
`tool` 内的字段可以使用 `@windows``@unix``@linux``@macos` 后缀。例如,`provides@windows` 可以列出 `.exe` 名称,`provides@unix` 列出 Unix 名称。
## target 包类型
`target` 代表一个最终的构建产物,它继承于 `library`,所以包含 `library` 的所有定义字段。`target` 包的配置文件位于 `config/pkg/target/` 目录下,构建类继承自 `TargetPackage`,位于 `src/Package/Target/` 目录下
`target` Package 代表一个最终的构建产物,它继承于 `library`,所以包含 `library` 的所有定义字段。配置文件位于 `config/pkg/target/`。可选的 recipe class 通常放在 `src/Package/Target/`,通过 `#[Target]` 注册,并接收 `TargetPackage`;是否继承 `TargetPackage` 是可选的
`library` 的唯一区别是,`target` 包可以注册成为构建目标,且自动注册构建命令 `spc build:{target-name}`
## virtual-target 包类型
`target` 不同的是`virtual-target` 可以不包含 `artifact`,即不直接对应一个可构建的实体,而是一个抽象的构建目标,主要用于依赖管理和构建调度。`virtual-target` 的配置文件位于 `config/pkg/target/` 目录下,构建类继承自 `TargetPackage`,位于 `src/Package/Target/` 目录下。它的定义与 `target` 基本相同,但 `artifact` 字段可选且通常不设置。`virtual-target` 主要用于以下场景:
`target` 不同,`virtual-target` 可以省略 `artifact`,即不直接对应一个可构建的实体,而是用于依赖管理和构建调度的抽象构建目标。它与 `target` 使用相同的配置目录、可选 recipe class 目录和 `#[Target]` 注册方式。其余定义基本相同,但 `artifact` 字段可选且通常不设置。`virtual-target` 主要用于以下场景:
- 定义一个抽象的构建目标,供其他包依赖,但不直接对应一个可构建的实体。
- 作为多个 `target` 包的公共依赖,简化依赖关系管理。
典型例子 PHP 包的 `php-cli``php-fpm` 构建目标,他们没有独立源码,依赖 `php-src`,通过构建调度决定最终构建成 CLI 还是 FPM 二进制。
典型例子是 `php-cli``php-fpm` 构建目标。它们没有独立源码,依赖 Artifact 为 `php-src``php` target构建调度决定最终成 CLI 还是 FPM 二进制。