Merge branch 'v3' into feat/pgo-v3-split

This commit is contained in:
Jerry Ma
2026-07-16 14:39:30 +08:00
committed by GitHub
10 changed files with 1625 additions and 338 deletions

View File

@@ -10,6 +10,7 @@ Use the repository skills when the task matches them:
- `.github/skills/staticphp-package-maintenance`: add, modify, review, or validate package, artifact, extension, library, target, or tool definitions.
- `.github/skills/staticphp-build-troubleshooting`: diagnose build, download, doctor, shell, terminal, CI, smoke-test, or log failures.
- `.github/skills/staticphp-documentation-sync`: synchronize bilingual documentation (`docs/en/` and `docs/zh/`) when features, commands, configuration, APIs, or behavior change.
## Quick Reference

View File

@@ -0,0 +1,160 @@
---
name: staticphp-documentation-sync
description: Synchronize bilingual documentation when StaticPHP v3 user-facing or developer-facing documentation must change. Use when adding, modifying, deprecating, or removing documented features, CLI commands/options, environment variables, configuration formats, public APIs/extension points, workflows, installation requirements, migration guidance, or user-visible behavior. Do not use solely for internal implementation changes, package/library additions, or build bug fixes unless they change documented behavior or require updating existing docs.
---
# StaticPHP Documentation Sync
## Overview
StaticPHP maintains bilingual documentation under `docs/en/` (English) and `docs/zh/` (Chinese). User-facing or developer-facing documentation changes must be reflected in both languages. Use this skill to identify affected docs, update them in sync, and validate sidebar/config consistency.
## When to Use This Skill
Invoke this skill when the change involves:
- New or modified CLI commands, options, or arguments
- New or changed environment variables
- Package (extension/library/target/tool) additions, removals, or behavioral changes that affect documented support, dependencies, commands, or workflows
- Configuration format changes (YAML fields, artifact definitions, registry)
- Build lifecycle, doctor, or toolchain changes
- API or extension point changes (attributes, hooks, DI, custom artifacts)
- Workflow changes (installation, first build, migration)
- Deprecation or removal of any documented feature
Do not update docs just because code changed. Internal refactors, new libraries used only as dependencies, package build fixes, CI-only changes, and bug fixes that preserve documented behavior usually do not need documentation changes. If existing docs mention the changed behavior, command, package support, dependency, caveat, or workaround, update them.
## Documentation Map
```
docs/
├── en/ # English docs (canonical source)
│ ├── index.md # Home page hero/features
│ ├── guide/ # User-facing guides
│ │ ├── index.md # Overview
│ │ ├── installation.md # Installation instructions
│ │ ├── first-build.md # First build walkthrough
│ │ ├── sapi-reference.md # PHP SAPI options
│ │ ├── cli-reference.md # CLI commands and options
│ │ ├── cli-generator.md # Build command generator
│ │ ├── migrate-from-v2.md # v2 → v3 migration
│ │ ├── extensions.md # Supported extensions list
│ │ ├── extension-notes.md # Per-extension notes
│ │ ├── env-vars.md # Environment variables
│ │ ├── deps-map.md # Dependency map
│ │ └── troubleshooting.md # Troubleshooting guide
│ ├── develop/ # Developer docs
│ │ ├── index.md # Dev overview
│ │ ├── structure.md # Project structure
│ │ ├── registry.md # Registry model
│ │ ├── package-model.md # Package YAML model
│ │ ├── artifact-model.md # Artifact YAML model
│ │ ├── craft-yml.md # craft.yml reference
│ │ ├── build-lifecycle.md # Build stages/lifecycle
│ │ ├── system-build-tools.md # System tool requirements
│ │ ├── doctor-module.md # Doctor module
│ │ ├── php-src-changes.md # PHP source patches
│ │ └── extending/ # Extension authoring
│ │ ├── index.md
│ │ ├── package-classes.md
│ │ ├── annotations.md
│ │ ├── lifecycle-hooks.md
│ │ ├── dependency-injection.md
│ │ └── custom-artifact.md
│ ├── contributing/
│ │ └── index.md
│ └── faq/
│ └── index.md
├── zh/ # Chinese docs (mirrors en/ structure)
│ └── (same structure as en/)
├── .vitepress/
│ ├── sidebar.en.ts # English sidebar config
│ ├── sidebar.zh.ts # Chinese sidebar config
│ └── config.ts # VitePress site config
└── deps-craft-yml.md # Shared craft.yml include used by both languages
```
Other documentation files outside this tree may also matter, especially root-level `ext-support.md`.
**Key rule**: `docs/en/` and `docs/zh/` have identical file trees. Every `.md` file under `en/` must have a corresponding file under `zh/`.
## Workflow
### Step 1: Identify Impact Scope
Map the change to affected documentation:
| Change Type | Likely Affected Docs |
|---|---|
| New/removed CLI command | `guide/cli-reference.md`, `guide/cli-generator.md` |
| New/removed CLI option | `guide/cli-reference.md`, `guide/first-build.md` |
| New env var | `guide/env-vars.md` |
| New/removed documented extension package | `guide/extensions.md`, `guide/extension-notes.md`, `guide/deps-map.md`, root `ext-support.md` |
| Package config field change | `develop/package-model.md`, `develop/artifact-model.md` |
| Build lifecycle change | `develop/build-lifecycle.md` |
| Doctor change | `develop/doctor-module.md`, `develop/system-build-tools.md` |
| New attribute/hook/DI | `develop/extending/annotations.md`, `develop/extending/lifecycle-hooks.md`, `develop/extending/dependency-injection.md` |
| PHP source patch | `develop/php-src-changes.md` |
| Registry change | `develop/registry.md` |
| Install/setup change | `guide/installation.md`, `guide/first-build.md` |
| Deprecation/removal | All docs referencing the feature |
| New doc page | `sidebar.en.ts`, `sidebar.zh.ts` |
### Step 2: Read Current Docs
Before editing, read BOTH the English and Chinese versions of each affected file to understand the current content and existing translation patterns.
```bash
# Example: check both language versions of the CLI reference
cat docs/en/guide/cli-reference.md
cat docs/zh/guide/cli-reference.md
```
### Step 3: Update English Docs First
1. Update `docs/en/` files with accurate, complete English content.
2. Follow existing formatting conventions (headings, code blocks, tables, admonitions).
3. If adding a new page:
- Create the file under `docs/en/<category>/<name>.md`
- Add the corresponding entry in `docs/.vitepress/sidebar.en.ts`
- Ensure the file has proper VitePress frontmatter if needed
### Step 4: Sync Chinese Docs
1. Update `docs/zh/` files to match the English changes.
2. Translate all changed or added prose. Do not leave placeholder text or untranslated English in Chinese docs.
3. Match the structure and formatting of the English version exactly.
4. If a new page was added in English, create the corresponding `docs/zh/` file and update `docs/.vitepress/sidebar.zh.ts`.
5. Treat `docs/deps-craft-yml.md` as a special shared include for both languages. If it needs prose changes, either keep the shared content acceptable for both languages or split the included content before adding language-specific prose.
### Step 5: Validate
Run these checks before considering the task complete:
```bash
# Check that en/ and zh/ have matching file trees
diff <(find docs/en -name '*.md' | sed 's|docs/en/||' | sort) \
<(find docs/zh -name '*.md' | sed 's|docs/zh/||' | sort)
# Check that all sidebar links point to existing files
# (manual check: every 'link' in sidebar.*.ts must resolve to an actual .md file)
# Build docs when Node dependencies are available; this catches many broken links/config issues
npm run docs:build
```
## Translation Guidelines
- **Chinese docs must be complete**: Every section, paragraph, and table in the English docs must have a Chinese equivalent. Never skip sections.
- **Code blocks and command examples**: Keep executable code and commands identical in both languages. Translate surrounding prose; translate comments inside examples only when they are explanatory docs rather than copy-pasteable source/config.
- **Technical terms**: Use consistent translations. Refer to existing Chinese docs for established term translations. When in doubt, prefer the term used elsewhere in `docs/zh/`.
- **Links**: Internal links in Chinese docs should point to `/zh/...` paths (not `/en/...`).
- **YAML frontmatter**: Keep frontmatter identical between languages (layout, etc.) unless the title/tagline field is translated.
## Common Pitfalls
- **Don't update only one language**: This is the most common mistake. Always update both `en/` and `zh/` in the same change.
- **Don't forget sidebar configs**: When adding, renaming, or removing doc pages, update both `sidebar.en.ts` and `sidebar.zh.ts`.
- **Don't forget shared/root docs**: root `ext-support.md` and `docs/deps-craft-yml.md` are also documentation. Update them if relevant.
- **Don't leave TODO markers**: Do not commit TODO translation placeholders unless the user explicitly allows it or the task is blocked; if that happens, call it out in the final response.
- **Don't translate file paths or URLs**: Only translate human-readable content, not paths, URLs, command names, or code identifiers.

View File

@@ -27,9 +27,14 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v3
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: yarn
- run: npm install
- name: Install documentation dependencies
run: yarn install --frozen-lockfile
- name: "Install PHP for official runners"
uses: shivammathur/setup-php@v2
@@ -57,7 +62,7 @@ jobs:
run: "composer install --no-interaction --no-progress"
- name: Build
run: npm run docs:build
run: yarn docs:build
# Deploy to GitHub Pages only when the workflow is triggered by a push to the v3 branch
- name: Deploy to GitHub Pages

1
.gitignore vendored
View File

@@ -52,6 +52,7 @@ packlib_files.txt
/node_modules/
/docs/.vitepress/dist/
/docs/.vitepress/cache/
/docs/.vitepress/.temp/
/docs/.vitepress/ext-data.json
/docs/.vitepress/deps-data.json
package-lock.json

View File

@@ -10,6 +10,7 @@ Detailed task workflows live in `.github/skills`. Use them when the task matches
- `.github/skills/staticphp-package-maintenance`: add, modify, review, or validate package, artifact, extension, library, target, or tool definitions.
- `.github/skills/staticphp-build-troubleshooting`: diagnose build, download, doctor, shell, terminal, CI, smoke-test, or log failures.
- `.github/skills/staticphp-documentation-sync`: synchronize bilingual documentation (`docs/en/` and `docs/zh/`) when features, commands, configuration, APIs, or behavior change.
If your agent does not automatically discover skills from `.github/skills`, read the matching `SKILL.md` manually before working on that task.

View File

@@ -45,7 +45,7 @@
<label :for="'build_' + item">{{ item }}</label>
</div>
</div>
<div v-if="selectedSystem === 'windows' && (checkedTargets.includes('fpm') || checkedTargets.includes('embed') || checkedTargets.includes('frankenphp'))" class="warning custom-block">
<div v-if="selectedSystem === 'windows' && checkedTargets.includes('fpm')" class="warning custom-block">
<p class="custom-block-title">WARNING</p>
<p>{{ I18N[lang].windowsSAPIUnavailable }}</p>
</div>
@@ -157,7 +157,7 @@
<div class="warning custom-block">
<p class="custom-block-title">WARNING</p>
<p>{{ I18N[lang].windowsDownSPCWarning }}</p>
<a href="https://dl.static-php.dev/v3/spc-bin/latest/spc-windows-x86_64.exe" target="_blank">https://dl.static-php.dev/v3/spc-bin/latest/spc-windows-x86_64.exe</a>
<a href="https://dl.static-php.dev/v3/spc-bin/nightly/spc-windows-x86_64.exe" target="_blank">https://dl.static-php.dev/v3/spc-bin/nightly/spc-windows-x86_64.exe</a>
</div>
</div>
</div>
@@ -278,7 +278,7 @@ const spcCommand = computed(() => {
const spcDownloadCommand = computed(() => {
const os = selectedSystem.value === 'macos' ? 'macos' : 'linux';
const arch = selectedArch.value;
return `curl -#fSL https://dl.static-php.dev/v3/spc-bin/latest/spc-${os}-${arch} -o spc && chmod +x spc`;
return `curl -#fSL https://dl.static-php.dev/v3/spc-bin/nightly/spc-${os}-${arch} -o spc && chmod +x spc`;
});
const doctorCommandString = computed(() => `${spcCommand.value} doctor --auto-fix`);
@@ -425,7 +425,7 @@ const I18N: Record<string, Record<string, string>> = {
downloadPhpVersion: '下载 PHP 版本',
downloadSPCBinaryCommand: '下载 spc 二进制命令',
selectedSystem: '选择操作系统',
windowsSAPIUnavailable: 'Windows 目前不支持 fpm、embed、frankenphp 构建!',
windowsSAPIUnavailable: 'Windows 目前不支持 fpm 构建!',
useUPX: '是否开启 UPX 压缩(减小二进制体积)',
windowsDownSPCWarning: 'Windows 下请手动下载 spc.exe 二进制文件!',
usePreBuilt: '如果可能,使用预编译的依赖库(减少编译时间)',
@@ -459,7 +459,7 @@ const I18N: Record<string, Record<string, string>> = {
downloadPhpVersion: 'PHP version',
downloadSPCBinaryCommand: 'Download spc binary',
selectedSystem: 'Select OS',
windowsSAPIUnavailable: 'Windows does not support fpm, embed and frankenphp build!',
windowsSAPIUnavailable: 'Windows does not support fpm build!',
useUPX: 'Enable UPX compression (reduce binary size)',
windowsDownSPCWarning: 'Please download the spc.exe binary manually on Windows!',
usePreBuilt: 'Use pre-built dependencies where available (reduce compile time)',

View File

@@ -4,14 +4,15 @@
A Package is the core concept in StaticPHP's build system, representing a buildable/installable unit such as a PHP extension, library, or build target.
Each Package contains build information, dependencies, and build logic, forming StaticPHP's build model. Package definitions are primarily implemented through YAML/JSON configuration files. The package configuration files for the `core` registry are located in the `config/pkg/` directory, and the corresponding build classes are in the `src/Package/` directory.
Each Package contains build information, dependencies, and build logic, forming StaticPHP's build model. Package definitions are primarily implemented through YAML/JSON configuration files. The package configuration files for the `core` registry are located in the `config/pkg/` directory, and optional recipe classes are in the corresponding subdirectories of `src/Package/`.
Packages are primarily divided into four types:
Packages are divided into five types:
- **php-extension**: A PHP extension package containing build information and logic for a PHP extension.
- **library**: A library package containing build information and logic for build tools, dependency libraries, etc.
- **library**: A dependency library package, usually installed into `buildroot/` for other packages to compile and link against.
- **target**: A build target package representing the final build artifact, such as a PHP binary or curl binary. Inherits from the `library` package type.
- **virtual-target**: A virtual build target package representing an abstract build target that doesn't directly correspond to a build artifact, primarily used for dependency management and build scheduling.
- **tool**: A host-side build tool package, installed separately under `pkgroot/` and not treated as a link-time library dependency.
```yaml
{pkg-name}:
@@ -21,7 +22,7 @@ Packages are primarily divided into four types:
## Artifact Definition
An Artifact is a definition independent of Packages. It contains the source archive file or pre-built binary for building packages. Each Artifact defines download URLs, extraction methods, and build artifact file paths. Packages can reference one or more Artifacts via the `artifact` field to obtain the source or binaries needed for building.
An Artifact is a definition independent of Packages. It contains the source archive file or pre-built binary for building packages. Each Artifact defines download URLs, extraction methods, and build artifact file paths. A Package can reference one Artifact via the `artifact` field to obtain the source or binary needed for building.
In simple terms, by default one Package corresponds to one Artifact; if multiple Packages share the same source, you can define a single Artifact for multiple Packages to reference. Artifact definitions are located in the `config/artifact/` directory, and the corresponding custom download/extract logic classes are in the `src/Package/Artifact/` directory. For special package types like virtual targets and PHP built-in extensions, a Package may also omit the Artifact field entirely.
@@ -40,7 +41,7 @@ For more on Artifact definitions, see the [Artifact Model](./artifact-model) cha
## php-extension Package Type
A php-extension package represents a PHP extension. Its configuration file is located in the `config/pkg/ext/` directory, and its build class inherits from `PhpExtensionPackage` in the `src/Package/Extension/` directory. PHP extension package configurations include extension name, version, dependencies, build options, and more.
A php-extension package represents a PHP extension. Its configuration file is located in the `config/pkg/ext/` directory. Optional recipe classes are normally placed in `src/Package/Extension/`, registered with `#[Extension]`, and receive the corresponding `PhpExtensionPackage` through callback context. Inheriting from `PhpExtensionPackage` is supported but is not required by the current core recipes.
```yaml
ext-lz4:
@@ -57,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'
```
@@ -72,16 +73,18 @@ ext-{ext-name}: # Package name must start with ext- prefix
lang: c # Optional, implementation language of the extension (c / c++ etc.)
frameworks: [] # Optional, list of related macOS framework dependencies
artifact: '{artifact-name}' # Optional; when a string, references an Artifact definition
# with the same name; when an object, is an inline Artifact
artifact: '{artifact-name}' # Optional; when a string, references the named Artifact definition;
# when an object, it is an inline Artifact
# (built-in extensions don't need this field)
# depends / suggests support @windows / @unix / @linux / @macos suffixes
# depends / suggests / tools support @windows / @unix / @linux / @macos suffixes
depends: [] # Optional, hard dependency list (library names as-is, PHP extensions need ext- prefix)
depends@unix: [] # Optional, hard dependencies only effective on Unix platforms
depends@windows: [] # Optional, hard dependencies only effective on Windows platforms
suggests: [] # Optional, optional dependency list (same format as depends)
suggests@unix: []
tools: [] # Optional, host-side build tool dependencies; resolved separately
tools@windows: [] # Optional, platform-specific tool dependencies
# ── php-extension Specific Fields (nested under php-extension: object) ────
php-extension:
@@ -100,7 +103,7 @@ ext-{ext-name}: # Package name must start with ext- prefix
# @shared_path_suffix@ → Expands to =shared,{buildroot} in shared builds,
# expands to ={buildroot} in static builds
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 # Optional, true indicates this is a Zend extension (e.g., opcache, xdebug)
@@ -121,7 +124,7 @@ ext-{ext-name}: # Package name must start with ext- prefix
## library Package Type
A library package represents a dependency library that needs to be compiled from source (such as openssl, zlib, etc.). Its configuration file is located in the `config/pkg/lib/` directory, and its build class inherits from `LibraryPackage` in the `src/Package/Library/` directory.
A library package represents a dependency library, such as openssl or zlib, installed from source or a pre-built binary. Its configuration file is located in the `config/pkg/lib/` directory. Optional recipe classes are normally placed in `src/Package/Library/`, registered with `#[Library]`, and receive a `LibraryPackage` through callback context; they do not need to inherit from it.
Taking openssl as an example:
@@ -161,22 +164,27 @@ Allowed fields for `library`:
# ── Common Fields ─────────────────────────────────────────────────────────
description: '..' # Optional, human-readable package description
license: MIT # Optional, SPDX license identifier (for license export)
license: # Optional, license material copied after a source build
type: file # type is file or text; a list of entries is also accepted
path: LICENSE
lang: c # Optional, implementation language of the library (c / c++ etc.)
frameworks: [] # Optional, list of related framework tags
artifact: '{artifact-name}' # Required; when a string, references an Artifact definition
# with the same name; when an object, is an inline Artifact
artifact: '{artifact-name}' # Required; when a string, references the named Artifact definition;
# when an object, it is an inline Artifact
# depends / suggests support @windows / @unix / @linux / @macos suffixes
# depends / suggests / tools support @windows / @unix / @linux / @macos suffixes
depends: [] # Optional, hard dependency list (library names or PHP extension names with ext- prefix)
depends@unix: []
depends@windows: []
suggests: [] # Optional, optional dependency list (same format as depends)
tools: [] # Optional, ToolPackage names required only while building
tools@windows: []
# ── library / target Specific Fields ───────────────────────────────────────
# The following fields are used to verify that artifacts have been correctly
# installed after the build. They support @unix / @windows / @linux / @macos suffixes.
# installed after the build. headers, static-libs, and static-bins support
# @unix / @windows / @linux / @macos suffixes.
# Verify that specified header files or directories exist under buildroot/include/
# Relative paths are based on buildroot/include/, absolute paths are used directly
@@ -231,17 +239,49 @@ The following path placeholders are supported in string values of the `path`, `e
| `{source_path}` | Extracted source directory (`source/`) |
| `{spc_msys2_path}` | MSYS2 root directory (`msys64/`) — Windows only |
## tool Package Type
A `tool` package represents an executable needed while building another package, rather than a library linked into the final target. Tool packages may use a pre-built binary or build from source, and install under `pkgroot/` by default, using either a shared `bin/` directory or a configured subdirectory. Packages request them through the top-level `tools` field; this dependency set is resolved independently of `depends` and `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'
```
The nested `tool` object supports:
| Field | Required | Meaning |
|---|---|---|
| `provides` | Yes | Executable filenames used to decide whether the tool is installed |
| `binary-subdir` | No | Directory below `install-root` containing the executables; defaults to the install root |
| `install-root` | No | Installation root; defaults to `PKG_ROOT_PATH` and supports path placeholders |
| `min-version` | No | Declared minimum version metadata exposed by `ToolPackage`; the installer does not currently enforce it |
Fields inside `tool` may use `@windows`, `@unix`, `@linux`, and `@macos` suffixes. For example, `provides@windows` can list `.exe` names while `provides@unix` lists Unix names.
## target Package Type
A `target` package represents a final build artifact. It inherits from `library`, so it includes all definition fields of `library`. The configuration file for `target` packages is located in the `config/pkg/target/` directory, and its build class inherits from `TargetPackage` in the `src/Package/Target/` directory.
A `target` package represents a final build artifact. It inherits from `library`, so it includes all definition fields of `library`. Its configuration file is located in `config/pkg/target/`. Optional recipe classes are normally placed in `src/Package/Target/`, registered with `#[Target]`, and receive a `TargetPackage`; inheriting from `TargetPackage` is optional.
The only difference from `library` is that a `target` package can be registered as a build target and automatically registers the build command `spc build:{target-name}`.
## virtual-target Package Type
Unlike `target`, a `virtual-target` may not include an `artifact`, meaning it doesn't directly correspond to a buildable entity but is instead an abstract build target, primarily used for dependency management and build scheduling. The configuration file for `virtual-target` is located in the `config/pkg/target/` directory, and its build class inherits from `TargetPackage` in the `src/Package/Target/` directory. Its definition is essentially the same as `target`, but the `artifact` field is optional and typically not set. `virtual-target` is primarily used in the following scenarios:
Unlike `target`, a `virtual-target` may omit `artifact`, meaning it doesn't directly correspond to a buildable entity but is instead an abstract build target, primarily used for dependency management and build scheduling. Its configuration and optional recipe classes use the same directories and `#[Target]` registration mechanism as `target`. Its definition is otherwise essentially the same, but the `artifact` field is optional and typically not set. `virtual-target` is primarily used in the following scenarios:
- Defining an abstract build target for other packages to depend on, without directly corresponding to a buildable entity.
- Serving as a common dependency for multiple `target` packages, simplifying dependency management.
A typical example is the `php-cli`, `php-fpm` build targets for PHP. They have no independent source code and depend on `php-src`, with the final build outcome (CLI or FPM binary) determined through build scheduling.
Typical examples are the `php-cli` and `php-fpm` build targets. They have no independent source and depend on the `php` target, whose Artifact is `php-src`; build scheduling determines whether the CLI or FPM binary is produced.

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 二进制。

View File

@@ -2,12 +2,12 @@
"scripts": {
"docs:dev": "node docs/.vitepress/gen-meta.js && vitepress dev docs",
"docs:gen-meta": "node docs/.vitepress/gen-meta.js",
"docs:build": "npm run docs:gen-meta && vitepress build docs",
"docs:build": "node docs/.vitepress/gen-meta.js && vitepress build docs",
"docs:preview": "vitepress preview docs"
},
"devDependencies": {
"mermaid": "^11.0.0",
"vitepress": "^2.0.0-alpha.5",
"vitepress": "2.0.0-alpha.18",
"vue": "^3.2.47"
}
}

1620
yarn.lock

File diff suppressed because it is too large Load Diff