mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-07 00:35:41 +08:00
feat(docs): add agent guide, build class patterns, log triage, and AI instructions (#1202)
This commit is contained in:
23
.github/copilot-instructions.md
vendored
Normal file
23
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# StaticPHP v3 Copilot Instructions
|
||||
|
||||
> The canonical agent instructions live in [AGENTS.md](./AGENTS.md). This file provides the essential summary for GitHub Copilot; read `AGENTS.md` for the complete project map, working rules, and validation steps.
|
||||
|
||||
StaticPHP is a PHP CLI application for building static PHP binaries, PHP SAPIs, extensions, libraries, and helper tools. Prefer the v3 architecture under `src/StaticPHP`, `src/Package`, `config/pkg`, and `config/artifact`.
|
||||
|
||||
## Skills
|
||||
|
||||
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.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
- **Entrypoint**: `php bin/spc`
|
||||
- **Config lint**: `php bin/spc dev:lint-config`
|
||||
- **CS fix**: `composer cs-fix`
|
||||
- **Tests**: `composer test`
|
||||
- **Static analysis**: `composer analyse`
|
||||
- **Extension packages**: `config/pkg/ext/ext-*.yml`, prefix with `ext-` in dependencies
|
||||
- **Platform suffixes**: `@unix`, `@linux`, `@macos`, `@windows` — prefer these over runtime conditionals
|
||||
- **Do NOT edit generated dirs**: `buildroot/`, `source/`, `downloads/`, `pkgroot/`
|
||||
56
.github/skills/staticphp-build-troubleshooting/SKILL.md
vendored
Normal file
56
.github/skills/staticphp-build-troubleshooting/SKILL.md
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
name: staticphp-build-troubleshooting
|
||||
description: Diagnose StaticPHP v3 failures. Use when investigating build, compile, linker, download, doctor, environment, CI, smoke-test, terminal output, spc.output.log, spc.shell.log, config.log, CMake logs, or user-provided error snippets from StaticPHP commands.
|
||||
---
|
||||
|
||||
# StaticPHP Build Troubleshooting
|
||||
|
||||
## Overview
|
||||
|
||||
Use this skill to triage StaticPHP failures from the outside in: command and environment first, SPC module/stage metadata next, shell/config logs last. The goal is to isolate the failing package, stage, command, and root cause before editing code.
|
||||
|
||||
## First Pass
|
||||
|
||||
1. Capture the exact command, OS, architecture, PHP version, extensions/libs/targets, and whether the run used `-v`, `-vv`, or `-vvv`.
|
||||
2. Read the final terminal error first. StaticPHP prints module error info, failed package, failed stage, failed command, log paths, and extra log files when available.
|
||||
3. If log files exist, inspect them in this order:
|
||||
- `log/spc.output.log`: user-facing SPC messages and exception summary.
|
||||
- `log/spc.shell.log`: executed commands, working directories, env, stdout/stderr.
|
||||
- Extra logs named in the exception output: `php-src.config.log`, `lib.<pkg>.console.log`, `lib.<pkg>.cmake-error.log`, `lib.<pkg>.cmake-configure.log`, `lib.<pkg>.cmake-output.log`.
|
||||
4. Read `references/log-triage.md` for pattern matching, likely causes, and next checks.
|
||||
|
||||
## Diagnosis Rules
|
||||
|
||||
- Do not start by changing shared core code. Most failures are package metadata, environment, upstream source, dependency order, or platform flags.
|
||||
- Prefer evidence from the last failing command over earlier warnings.
|
||||
- When logs are long, search backward for `Command exited`, `error:`, `undefined reference`, `not found`, `No package`, `CMake Error`, `configure: error`, `fatal error`, `Failed module`, and `Failed stage`.
|
||||
- Use `config.log` and CMake logs for configure detection failures; use `spc.shell.log` for the actual command and env.
|
||||
- Be careful with rebuild suggestions. `spc reset --with-download --yes` is destructive to caches; ask before clearing caches unless the user explicitly asked.
|
||||
|
||||
## Repro Commands
|
||||
|
||||
Use focused commands when reproducing:
|
||||
|
||||
```bash
|
||||
php bin/spc doctor -vvv
|
||||
php bin/spc download --for-extensions="curl,openssl" --with-php=8.5 --parallel=4 --retry=3 -vvv
|
||||
php bin/spc build:libs "openssl" -vvv
|
||||
php bin/spc build:php "bcmath,openssl,curl" --build-cli -vvv
|
||||
php bin/spc dev:lint-config
|
||||
```
|
||||
|
||||
Choose the smallest command that still reaches the failing package.
|
||||
|
||||
## Fix Direction
|
||||
|
||||
After finding the failing package/stage:
|
||||
|
||||
- Package YAML issue: use `$staticphp-package-maintenance`, then edit `config/pkg/*` or `config/artifact/*`.
|
||||
- Build command or patch issue: inspect the package class under `src/Package/*`.
|
||||
- Environment issue: check `doctor`, toolchain classes, and `config/pkg/tool/*`.
|
||||
- Upstream download issue: check artifact type, regex, GitHub rate limiting, mirror behavior, and `GITHUB_TOKEN`.
|
||||
- Core exception/logging issue: inspect `src/StaticPHP/Exception`, `src/StaticPHP/Runtime/Shell`, or executor classes only after package-level causes are ruled out.
|
||||
|
||||
## Resources
|
||||
|
||||
- `references/log-triage.md`: log files, failure categories, search patterns, and likely fixes.
|
||||
4
.github/skills/staticphp-build-troubleshooting/agents/openai.yaml
vendored
Normal file
4
.github/skills/staticphp-build-troubleshooting/agents/openai.yaml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "StaticPHP Build Troubleshooting"
|
||||
short_description: "Diagnose StaticPHP build and log failures."
|
||||
default_prompt: "Use $staticphp-build-troubleshooting to investigate a StaticPHP build, download, doctor, or log failure."
|
||||
209
.github/skills/staticphp-build-troubleshooting/references/log-triage.md
vendored
Normal file
209
.github/skills/staticphp-build-troubleshooting/references/log-triage.md
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
# StaticPHP Log Triage
|
||||
|
||||
## Contents
|
||||
|
||||
- Log files
|
||||
- Terminal summary
|
||||
- Search strategy
|
||||
- Failure categories
|
||||
- Rebuild hygiene
|
||||
- Reporting checklist
|
||||
|
||||
## Log Files
|
||||
|
||||
Default log directory is `log/`, controlled by `SPC_LOGS_DIR`. The important files are:
|
||||
|
||||
- `spc.output.log`: StaticPHP console/logger output and exception summaries.
|
||||
- `spc.shell.log`: command execution log with command, caller, inline env, working directory, stdout, stderr, and exit code.
|
||||
- `php-src.config.log`: copied when PHP source configure fails.
|
||||
- `lib.<pkg>.console.log`: copied Autoconf `config.log` for a library when available.
|
||||
- `lib.<pkg>.cmake-configure.log`: copied CMake 3.26+ configure log.
|
||||
- `lib.<pkg>.cmake-error.log`: copied CMake error log.
|
||||
- `lib.<pkg>.cmake-output.log`: copied CMake output log.
|
||||
|
||||
Logs are created when `SPC_ENABLE_LOG_FILE` is true. Old `*.log` files are cleaned unless `SPC_PRESERVE_LOG` is set to a truthy value. The code in `src/bootstrap.php` reads `SPC_PRESERVE_LOG` (no trailing S).
|
||||
|
||||
## Terminal Summary
|
||||
|
||||
StaticPHP exceptions often print:
|
||||
|
||||
- Exception category: build, download, environment, execution, file system, patch, validation, wrong usage, registry, internal.
|
||||
- Failed module: package name, type, and sometimes class/file/line.
|
||||
- Failed stage: call chain such as `build` or `build -> configure`.
|
||||
- Failed command: the command that returned non-zero.
|
||||
- Command working directory and inline env.
|
||||
- Paths to `spc.output.log`, `spc.shell.log`, and extra logs.
|
||||
|
||||
Use this summary to choose the first files to read. If a package and stage are present, start with that package's YAML and class after reading the relevant log tail.
|
||||
|
||||
## Search Strategy
|
||||
|
||||
For long logs, search from the end first.
|
||||
|
||||
Useful patterns:
|
||||
|
||||
```text
|
||||
Failed module:
|
||||
Failed stage:
|
||||
Failed command:
|
||||
Command exited with non-zero code
|
||||
configure: error
|
||||
CMake Error
|
||||
undefined reference
|
||||
cannot find -l
|
||||
fatal error:
|
||||
No package
|
||||
Package .* not found
|
||||
Could NOT find
|
||||
is not a valid
|
||||
permission denied
|
||||
curl: (
|
||||
HTTP/2 403
|
||||
rate limit
|
||||
```
|
||||
|
||||
In `spc.shell.log`, each command block begins with `>>>>>>>>>>>>>>>>>>>>>>>>>>`, then prints the command, caller, env, and working dir. The last failed block is usually the highest-value evidence.
|
||||
|
||||
## Failure Categories
|
||||
|
||||
### Download Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- `Download failed`
|
||||
- `curl: (56)`, `curl: (22)`, HTTP 403/404/429
|
||||
- GitHub API calls in verbose logs
|
||||
- Asset regex did not match a release asset
|
||||
|
||||
Likely checks:
|
||||
|
||||
- If GitHub rate limited, ask user to set `GITHUB_TOKEN`.
|
||||
- Verify artifact source type and regex in `config/pkg/*` or `config/artifact/*`.
|
||||
- Use `--dl-retry`, `--dl-parallel`, `--ignore-cache`, `--no-alt`, or custom source options only as repro aids.
|
||||
- Prefer fixing stale URLs/regexes over adding workarounds.
|
||||
|
||||
### Doctor or Environment Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- `Environment check failed`
|
||||
- missing `make`, `cmake`, `autoconf`, `pkg-config`, compiler, Perl, Visual Studio, MSYS2, Zig, etc.
|
||||
- `Some check items can not be fixed`
|
||||
|
||||
Likely checks:
|
||||
|
||||
- Run `php bin/spc doctor -vvv`.
|
||||
- Inspect `src/StaticPHP/Doctor/Item/*` for the check and fix behavior.
|
||||
- Inspect `config/pkg/tool/*` for installable helper tools.
|
||||
- On Windows, some dependencies cannot be auto-installed.
|
||||
|
||||
### Configure Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- `configure: error`
|
||||
- Autoconf failure before compilation
|
||||
- extra `config.log` listed
|
||||
|
||||
Likely checks:
|
||||
|
||||
- Read copied `php-src.config.log` or `lib.<pkg>.console.log`.
|
||||
- Look for the first compiler/linker probe that failed.
|
||||
- Check `headers`, `static-libs`, `pkg-configs`, dependency order, and `initializeEnv($pkg)` behavior.
|
||||
- For extensions, check `php-extension.arg-type` and `#[CustomPhpConfigureArg]`.
|
||||
|
||||
### CMake Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- `CMake Error`
|
||||
- `Could NOT find`
|
||||
- missing target, package config, or static library
|
||||
|
||||
Likely checks:
|
||||
|
||||
- Read `lib.<pkg>.cmake-error.log` and `lib.<pkg>.cmake-configure.log`.
|
||||
- Inspect `UnixCMakeExecutor`/`WindowsCMakeExecutor` usage in the package class.
|
||||
- Check CMake options, toolchain root path, `pkg-configs`, and transitive dependency libraries.
|
||||
|
||||
### Compile Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- compiler `fatal error: header.h: No such file or directory`
|
||||
- syntax/type errors from upstream source
|
||||
- incompatible PHP API or platform macros
|
||||
|
||||
Likely checks:
|
||||
|
||||
- Identify the source file and include path from `spc.shell.log`.
|
||||
- Verify dependency headers are installed in `buildroot/include`.
|
||||
- Check PHP version compatibility and existing patches in `src/globals/patch`.
|
||||
- Prefer targeted patches or compile flags in the package class over broad toolchain changes.
|
||||
|
||||
### Link Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- `undefined reference`
|
||||
- `cannot find -lfoo`
|
||||
- duplicate symbols
|
||||
- Windows unresolved external symbol or missing `.lib`
|
||||
|
||||
Likely checks:
|
||||
|
||||
- Verify `static-libs`, dependency order, and `getStaticLibFiles()` usage.
|
||||
- Inspect `SPC_EXTRA_LIBS`, `Libs.private` in `.pc` files, and package-specific pkg-config patching.
|
||||
- On Windows, confirm `.lib` names and required system libraries.
|
||||
- For OpenSSL/curl-like packages, search existing linker flag hooks before adding a new one.
|
||||
|
||||
### Smoke Test or Validation Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- `Validation failed`
|
||||
- `php --ri` failure
|
||||
- extension not loaded after build
|
||||
- micro/embed runtime smoke test fails
|
||||
|
||||
Likely checks:
|
||||
|
||||
- Check extension `display-name`; empty string skips `php --ri`.
|
||||
- Confirm static vs shared build settings.
|
||||
- Confirm the extension is included in the final SAPI target and not only built as a dependency.
|
||||
- Inspect `src/globals/ext-tests/*` and common tests for expected runtime behavior.
|
||||
|
||||
### Registry or Config Failure
|
||||
|
||||
Signs:
|
||||
|
||||
- `Registry error`
|
||||
- unknown package, invalid field, invalid platform suffix, type mismatch
|
||||
- package referenced by attribute but missing config
|
||||
|
||||
Likely checks:
|
||||
|
||||
- Run `php bin/spc dev:lint-config`.
|
||||
- Inspect `ConfigValidator` tests for accepted fields and error expectations.
|
||||
- Confirm attribute type matches YAML `type`.
|
||||
- Confirm hooks reference existing package names and stages for the current platform.
|
||||
|
||||
## Rebuild Hygiene
|
||||
|
||||
Use the smallest cleanup that can invalidate the suspected stale state:
|
||||
|
||||
- Redownload one artifact: `--ignore-cache="artifact-name"`.
|
||||
- Skip downloads to test local source/build logic: `--no-download`.
|
||||
- Prefer source when debugging build logic: `--dl-prefer-source`.
|
||||
- Clear build products only when necessary. `spc reset --with-download --yes` removes caches and should not be suggested casually.
|
||||
|
||||
## Reporting Checklist
|
||||
|
||||
When preparing an issue or PR explanation, include:
|
||||
|
||||
- Exact `php bin/spc ...` command.
|
||||
- OS, architecture, PHP version option, and relevant env vars.
|
||||
- Failed package and stage.
|
||||
- Last failed command and exit code.
|
||||
- Tail of `spc.output.log`, relevant command block from `spc.shell.log`, and any extra config/CMake log.
|
||||
- Whether the failure reproduces after a focused clean or cache refresh.
|
||||
55
.github/skills/staticphp-package-maintenance/SKILL.md
vendored
Normal file
55
.github/skills/staticphp-package-maintenance/SKILL.md
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
name: staticphp-package-maintenance
|
||||
description: Maintain StaticPHP v3 packages and artifacts. Use when adding, modifying, reviewing, or validating config under config/pkg or config/artifact; package classes under src/Package; extension/library/target/tool dependencies; PHP configure args; build hooks; package metadata; or related tests and docs.
|
||||
---
|
||||
|
||||
# StaticPHP Package Maintenance
|
||||
|
||||
## Overview
|
||||
|
||||
Use this skill to make focused package changes without re-reading the entire repository. StaticPHP v3 separates declarative package/artifact YAML from package-specific PHP build logic; prefer config-only edits unless current patterns require a class.
|
||||
|
||||
## Quick Workflow
|
||||
|
||||
1. Identify the package kind and exact name.
|
||||
- Extension: `config/pkg/ext/ext-name.yml`, class `src/Package/Extension/name.php`.
|
||||
- Library: `config/pkg/lib/name.yml`, class `src/Package/Library/name.php`.
|
||||
- Target or virtual target: `config/pkg/target/name.yml`, class `src/Package/Target/name.php`.
|
||||
- Tool: `config/pkg/tool/name.yml`, class `src/Package/Tool/name.php`.
|
||||
- Shared/custom artifact: `config/artifact/name.yml`, class `src/Package/Artifact/name.php`.
|
||||
|
||||
2. Search for the closest existing package before designing anything new.
|
||||
- Similar build system: `rg "#\\[BuildFor|UnixCMakeExecutor|UnixAutoconfExecutor|WindowsCMakeExecutor" src/Package`.
|
||||
- Similar config fields: `rg "static-libs|pkg-configs|arg-type|depends@" config/pkg`.
|
||||
- Similar download type: `rg "type: ghrel|type: pecl|type: pie|type: git|binary: hosted" config`.
|
||||
|
||||
3. Read `references/package-reference.md` when changing YAML fields, artifact definitions, package naming, dependencies, platform suffixes, or validation expectations.
|
||||
|
||||
4. Read `references/build-class-patterns.md` when PHP build logic, attributes, lifecycle hooks, custom configure args, source patching, or executor usage is needed.
|
||||
|
||||
5. Validate narrowly, then broadly if risk warrants it.
|
||||
- Config lint: `php bin/spc dev:lint-config`
|
||||
- Focused tests: `vendor/bin/phpunit tests/StaticPHP/Config tests/StaticPHP/Registry tests/StaticPHP/Util/DependencyResolverTest.php --no-coverage`
|
||||
- Full project checks: `composer test`, `composer analyse`
|
||||
|
||||
## Editing Rules
|
||||
|
||||
- Treat `config/pkg/*` and `config/artifact/*` as the source of package truth; package classes augment behavior.
|
||||
- Use platform suffix fields for declarative OS differences: `@unix`, `@linux`, `@macos`, `@windows`.
|
||||
- Add a PHP class only for custom build stages, validation, hook behavior, patches, or custom configure arguments.
|
||||
- Keep extension dependencies prefixed with `ext-`; libraries, tools, and targets use their package names.
|
||||
- Prefer existing helpers such as `UnixAutoconfExecutor`, `UnixCMakeExecutor`, `WindowsCMakeExecutor`, `shell()`, `cmd()`, and `FileSystem`.
|
||||
- Do not modify build outputs (`buildroot/`, `source/`, `downloads/`, `pkgroot/`) to fix package definitions.
|
||||
- If upstream metadata changes, update license metadata and smoke-test/display names when relevant.
|
||||
|
||||
## Common Task Paths
|
||||
|
||||
- Add a new PECL extension: define `config/pkg/ext/ext-name.yml` with `type: php-extension`, `artifact.source.type: pecl`, dependencies, and `php-extension.arg-type`; add a class only if configure args, patches, or hooks are non-standard.
|
||||
- Add a library: define `config/pkg/lib/name.yml` with artifact, dependencies, and install verification fields (`headers`, `static-libs`, `pkg-configs`, `static-bins`); add build class methods by OS.
|
||||
- Fix an existing package build: start from the failing package config/class, then inspect dependencies and hooks targeting that package before changing shared core code.
|
||||
- Update a version source: prefer artifact fields that support update checking (`ghrel`, `ghtar`, `ghtagtar`, `git` with regex, `filelist`, `pecl`, `pie`) over hard-coded URLs when upstream supports it.
|
||||
|
||||
## Resources
|
||||
|
||||
- `references/package-reference.md`: YAML package/artifact model, naming, fields, validation, and commands.
|
||||
- `references/build-class-patterns.md`: PHP package attributes, stages, hooks, executors, and class patterns.
|
||||
4
.github/skills/staticphp-package-maintenance/agents/openai.yaml
vendored
Normal file
4
.github/skills/staticphp-package-maintenance/agents/openai.yaml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
interface:
|
||||
display_name: "StaticPHP Package Maintenance"
|
||||
short_description: "Add, update, and validate StaticPHP v3 package definitions."
|
||||
default_prompt: "Use $staticphp-package-maintenance to add, modify, or review StaticPHP package and artifact definitions."
|
||||
143
.github/skills/staticphp-package-maintenance/references/build-class-patterns.md
vendored
Normal file
143
.github/skills/staticphp-package-maintenance/references/build-class-patterns.md
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
# StaticPHP Build Class Patterns
|
||||
|
||||
## Contents
|
||||
|
||||
- When a class is needed
|
||||
- Package attributes
|
||||
- Stage and hook behavior
|
||||
- Executor choices
|
||||
- Common patterns
|
||||
- Failure-safe edits
|
||||
|
||||
## When a Class Is Needed
|
||||
|
||||
Do not add a PHP package class for simple metadata. Use YAML alone when StaticPHP can infer the configure args, dependencies, and verification.
|
||||
|
||||
Add or update a class when the package needs:
|
||||
|
||||
- OS-specific build commands.
|
||||
- Custom validation before building.
|
||||
- Custom PHP configure arguments.
|
||||
- Patches or file edits before build.
|
||||
- Hooks into another package's stage.
|
||||
- Custom source/binary download or extraction logic.
|
||||
- Package info shown by dev tooling.
|
||||
|
||||
Package classes live in `src/Package/*` and are discovered through PSR-4 plus attributes. Config must exist first; `PackageLoader` throws if an attribute references an undefined package.
|
||||
|
||||
## Package Attributes
|
||||
|
||||
Class-level package attributes:
|
||||
|
||||
- `#[Extension('curl')]` maps to package `ext-curl` if the prefix is omitted.
|
||||
- `#[Library('openssl')]`
|
||||
- `#[Target('php')]`
|
||||
- `#[Tool('zig')]`
|
||||
|
||||
Method-level attributes:
|
||||
|
||||
- `#[BuildFor('Linux'|'Darwin'|'Windows')]`: registers the `build` stage for that OS.
|
||||
- `#[Stage('name')]`: registers a named stage; defaults to the method name when omitted.
|
||||
- `#[BeforeStage('package', 'stage', 'only-when-package-resolved')]`: hook before a target package stage.
|
||||
- `#[AfterStage('package', 'stage', 'only-when-package-resolved')]`: hook after a target package stage.
|
||||
- `#[PatchBeforeBuild]`: runs once before package build unless `.spc-patched` exists; return `true` to write that marker.
|
||||
- `#[CustomPhpConfigureArg('Linux')]`: supplies custom extension configure args.
|
||||
- `#[Validate]`: validates environment/source assumptions.
|
||||
- `#[Info]`: returns package information for tooling.
|
||||
- `#[InitPackage]`: runs while loading a package class.
|
||||
- `#[ResolveBuild]`: target package callback for resolving build dependencies.
|
||||
- `#[ConditionalOn(SomeClass::class)]`: conditionally enables before/after hooks only when DI has the class.
|
||||
|
||||
## Stage and Hook Behavior
|
||||
|
||||
`PackageBuilder::buildPackage()` does:
|
||||
|
||||
1. Ensure build directories exist.
|
||||
2. Skip if already installed unless forced.
|
||||
3. Ensure source exists for non-virtual packages.
|
||||
4. Emit `PatchBeforeBuild` callbacks.
|
||||
5. Run the `build` stage.
|
||||
6. Install license data.
|
||||
7. Record tool package versions where relevant.
|
||||
|
||||
`Package::runStage()` wraps a stage with:
|
||||
|
||||
1. `BeforeStage` callbacks.
|
||||
2. The stage method itself.
|
||||
3. `AfterStage` callbacks.
|
||||
|
||||
SPC exceptions bind package and stage metadata. Preserve that behavior by throwing existing `SPCException` subclasses instead of raw exceptions when adding new failure paths.
|
||||
|
||||
## Executor Choices
|
||||
|
||||
Use existing executors where possible:
|
||||
|
||||
- `UnixAutoconfExecutor`: for Unix packages using `./configure && make && make install`. It injects default static flags and copies `config.log` into SPC logs on failure.
|
||||
- `UnixCMakeExecutor`: for Unix CMake packages. It writes toolchain settings and copies CMake configure/error/output logs on failure.
|
||||
- `WindowsCMakeExecutor`: for Windows CMake packages.
|
||||
- `shell()->cd(...)->initializeEnv($pkg)`: for custom Unix command chains.
|
||||
- `cmd()->cd(...)`: for Windows command chains.
|
||||
|
||||
Prefer `FileSystem` helpers for file edits and copies so behavior stays consistent.
|
||||
|
||||
## Common Patterns
|
||||
|
||||
Minimal library class:
|
||||
|
||||
```php
|
||||
#[Library('example')]
|
||||
class example
|
||||
{
|
||||
#[BuildFor('Linux')]
|
||||
public function build(LibraryPackage $pkg): void
|
||||
{
|
||||
(new UnixAutoconfExecutor($pkg))
|
||||
->configure()
|
||||
->make();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Extension hook into PHP build:
|
||||
|
||||
```php
|
||||
#[Extension('curl')]
|
||||
class curl
|
||||
{
|
||||
#[BeforeStage('php', [php::class, 'makeForWindows'], 'ext-curl')]
|
||||
public function patchBeforePhpBuild(): void
|
||||
{
|
||||
// Adjust env, generated build files, or linker flags.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Validation:
|
||||
|
||||
```php
|
||||
#[Validate]
|
||||
public function validate(): void
|
||||
{
|
||||
if (SystemTarget::getTargetOS() === 'Windows' && WindowsUtil::findCommand('perl.exe') === null) {
|
||||
throw new EnvironmentException('You need to install perl first!');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Custom configure args should be used when YAML `arg-type` is `custom` or when args need package/install context:
|
||||
|
||||
```php
|
||||
#[CustomPhpConfigureArg('Linux')]
|
||||
public function configureArg(PhpExtensionPackage $ext): string
|
||||
{
|
||||
return '--with-example=' . $ext->getBuildRootPath();
|
||||
}
|
||||
```
|
||||
|
||||
## Failure-Safe Edits
|
||||
|
||||
- Make hooks conditional with the third `BeforeStage`/`AfterStage` argument when a dependency must be resolved before the hook should run.
|
||||
- Keep platform-specific code under matching `#[BuildFor]` methods rather than branching heavily inside one method.
|
||||
- If a patch changes upstream source, place patch files in `src/globals/patch/` and describe them with `#[PatchDescription]` where appropriate.
|
||||
- If a class only mutates environment variables for another package, search for existing hooks first to avoid duplicate linker flags.
|
||||
- After adding attributes, run registry/config tests because invalid stages and unknown packages are caught during loading.
|
||||
157
.github/skills/staticphp-package-maintenance/references/package-reference.md
vendored
Normal file
157
.github/skills/staticphp-package-maintenance/references/package-reference.md
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
# StaticPHP Package Reference
|
||||
|
||||
## Contents
|
||||
|
||||
- Package locations
|
||||
- Package types
|
||||
- Artifact model
|
||||
- Common YAML fields
|
||||
- PHP extension fields
|
||||
- Platform suffixes
|
||||
- Validation and tests
|
||||
|
||||
## Package Locations
|
||||
|
||||
StaticPHP v3 keeps package metadata in YAML and behavior in PHP classes.
|
||||
|
||||
| Kind | YAML | PHP class namespace | Typical attribute |
|
||||
|---|---|---|---|
|
||||
| PHP extension | `config/pkg/ext/ext-name.yml` | `Package\Extension` | `#[Extension('name')]` |
|
||||
| Library | `config/pkg/lib/name.yml` | `Package\Library` | `#[Library('name')]` |
|
||||
| Target | `config/pkg/target/name.yml` | `Package\Target` | `#[Target('name')]` |
|
||||
| Virtual target | `config/pkg/target/name.yml` | `Package\Target` | `#[Target('name')]` |
|
||||
| Tool | `config/pkg/tool/name.yml` | `Package\Tool` | `#[Tool('name')]` |
|
||||
| Custom artifact | `config/artifact/name.yml` | `Package\Artifact` | artifact attributes |
|
||||
|
||||
Prefer one package per YAML file unless an existing file groups related definitions. Match nearby naming and ordering.
|
||||
|
||||
## Package Types
|
||||
|
||||
`php-extension` packages describe PHP extensions. Config package names must use the `ext-` prefix. Dependencies on extensions also use `ext-`.
|
||||
|
||||
`library` packages describe buildable dependency libraries. They usually define source artifacts plus verification fields such as headers, static libraries, pkg-config files, or binaries.
|
||||
|
||||
`target` packages represent final build outputs and inherit the library-style fields. StaticPHP automatically exposes build commands for targets.
|
||||
|
||||
`virtual-target` packages are abstract dependency/build scheduling nodes. They may omit `artifact`.
|
||||
|
||||
`tool` packages are helper programs or toolchains installed into `pkgroot/` or used by builds.
|
||||
|
||||
## Artifact Model
|
||||
|
||||
Artifacts define downloadable source archives or prebuilt binaries. Use inline artifacts for simple one-package sources and `config/artifact/*.yml` for shared, complex, or custom artifacts.
|
||||
|
||||
Top-level artifact sections:
|
||||
|
||||
- `source`: source archive, git checkout, PECL/PIE package, local directory, or custom source.
|
||||
- `binary`: prebuilt binary by platform, or aliases such as `hosted`/`custom`.
|
||||
- `metadata`: `license`, `license-files`, and `source-root`.
|
||||
|
||||
Common source types:
|
||||
|
||||
- `url`: fixed URL; supports `filename`, `version`, and `extract`.
|
||||
- `git`: repository source; use `rev` for a fixed branch/tag/commit or `regex` with named `version` capture for update checks.
|
||||
- `ghrel`: GitHub release asset by regex filename match.
|
||||
- `ghtar`: generated GitHub release tarball.
|
||||
- `ghtagtar`: generated GitHub tag tarball.
|
||||
- `filelist`: scrape a download index and extract version/filename with regex.
|
||||
- `pecl`: PECL extension by name.
|
||||
- `pie`: Packagist PIE extension by `vendor/package`.
|
||||
- `php-release`: official PHP source selected by build PHP version.
|
||||
- `local`: local source directory for development/offline use.
|
||||
- `custom`: PHP artifact class handles source or binary logic.
|
||||
|
||||
Use `metadata.source-root` when the actual build directory is inside an extracted subdirectory.
|
||||
|
||||
Use `metadata.license-files` for source licenses. `@/file.txt` points to bundled license files in `src/globals/licenses/`.
|
||||
|
||||
## Common YAML Fields
|
||||
|
||||
Shared fields:
|
||||
|
||||
- `type`: required package type.
|
||||
- `description`: optional human-readable package description.
|
||||
- `license`: package-level license annotation where applicable.
|
||||
- `lang`: implementation language such as `c` or `c++`.
|
||||
- `frameworks`: macOS framework tags.
|
||||
- `artifact`: string reference or inline artifact object. Required for `library` and `target`; optional for built-in extensions and virtual targets.
|
||||
- `depends`: hard dependencies.
|
||||
- `suggests`: optional dependencies.
|
||||
|
||||
Library, target, and tool verification/installation fields:
|
||||
|
||||
- `headers`: expected files/directories under `buildroot/include`.
|
||||
- `static-libs`: expected static libraries under `buildroot/lib`.
|
||||
- `pkg-configs`: expected `.pc` files under `buildroot/lib/pkgconfig`.
|
||||
- `static-bins`: expected executables under `buildroot/bin`.
|
||||
- `path`: directories appended to PATH after install.
|
||||
- `env`: environment variables set after install.
|
||||
- `append-env`: values appended to existing environment variables.
|
||||
|
||||
Path placeholders in `path`, `env`, and `append-env`:
|
||||
|
||||
- `{build_root_path}`: `buildroot/`
|
||||
- `{pkg_root_path}`: `pkgroot/`
|
||||
- `{working_dir}`: repository or working directory
|
||||
- `{download_path}`: `downloads/`
|
||||
- `{source_path}`: `source/`
|
||||
- `{spc_msys2_path}`: MSYS2 root on Windows
|
||||
|
||||
## PHP Extension Fields
|
||||
|
||||
Extension-specific fields live under `php-extension`.
|
||||
|
||||
- `arg-type`: configure argument behavior. Built-ins include `enable`, `enable-path`, `with`, `with-path`, `custom`, and `none`. Full strings are allowed.
|
||||
- `zend-extension`: true for Zend extensions such as opcache/xdebug.
|
||||
- `build-shared`: whether shared builds are allowed.
|
||||
- `build-static`: whether static builds are allowed.
|
||||
- `build-with-php`: true when built inside the PHP source tree.
|
||||
- `display-name`: value used for `php --ri` smoke tests and license display; empty string skips the `--ri` check.
|
||||
- `os`: allowed OS families: `Linux`, `Darwin`, `Windows`.
|
||||
|
||||
Configure string placeholders:
|
||||
|
||||
- `@build_root_path@`: absolute buildroot path.
|
||||
- `@shared_suffix@`: `=shared` in shared builds, empty in static builds.
|
||||
- `@shared_path_suffix@`: `=shared,{buildroot}` in shared builds, `={buildroot}` in static builds.
|
||||
|
||||
## Platform Suffixes
|
||||
|
||||
Many fields support platform suffixes:
|
||||
|
||||
- `@unix`: Linux and macOS.
|
||||
- `@linux`: Linux only.
|
||||
- `@macos`: macOS only.
|
||||
- `@windows`: Windows only.
|
||||
|
||||
For Linux, specific fields override generic fields in this order: `field@linux`, then `field@unix`, then `field`.
|
||||
|
||||
Use suffixes for declarative differences in dependencies, headers, libraries, pkg-configs, extension args, and suggestions.
|
||||
|
||||
## Validation and Tests
|
||||
|
||||
Run config validation for most package edits:
|
||||
|
||||
```bash
|
||||
php bin/spc dev:lint-config
|
||||
```
|
||||
|
||||
Run focused tests after config or registry changes:
|
||||
|
||||
```bash
|
||||
vendor/bin/phpunit tests/StaticPHP/Config tests/StaticPHP/Registry tests/StaticPHP/Util/DependencyResolverTest.php --no-coverage
|
||||
```
|
||||
|
||||
Run broader checks for framework or class changes:
|
||||
|
||||
```bash
|
||||
composer test
|
||||
composer analyse
|
||||
```
|
||||
|
||||
Build commands are expensive. Use them for user-provided repros, package-specific fixes, or when validation cannot prove the behavior:
|
||||
|
||||
```bash
|
||||
php bin/spc build:libs "openssl,curl" -vvv
|
||||
php bin/spc build:php "bcmath,openssl,curl" --build-cli -vvv
|
||||
```
|
||||
59
AGENTS.md
Normal file
59
AGENTS.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# StaticPHP v3 Agent Guide
|
||||
|
||||
StaticPHP is a PHP CLI application for building static PHP binaries, PHP SAPIs, extensions, libraries, helper tools, and project bundles. Prefer the v3 architecture under `src/StaticPHP`, `src/Package`, `config/pkg`, and `config/artifact`.
|
||||
|
||||
This file is the shared entry point for coding agents such as Codex, OpenCode, Claude-compatible agents, and GitHub Copilot agents. GitHub Copilot also has `.github/copilot-instructions.md`.
|
||||
|
||||
## Skills
|
||||
|
||||
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.
|
||||
|
||||
If your agent does not automatically discover skills from `.github/skills`, read the matching `SKILL.md` manually before working on that task.
|
||||
|
||||
## Project Map
|
||||
|
||||
- `bin/spc`: primary CLI entrypoint.
|
||||
- `composer.json`: PHP 8.4+, Symfony Console, DI, YAML, logger; useful scripts are `composer test`, `composer analyse`, `composer lint-config`, and `composer cs-fix`.
|
||||
- `spc.registry.yml`: built-in `core` registry.
|
||||
- `config/pkg/ext`: PHP extension package YAML, usually named `ext-*.yml`.
|
||||
- `config/pkg/lib`: library package YAML.
|
||||
- `config/pkg/target`: final build target and virtual target YAML.
|
||||
- `config/pkg/tool`: helper tool package YAML.
|
||||
- `config/artifact`: standalone artifact YAML for shared or complex sources/binaries.
|
||||
- `log/`: build and shell execution logs (`spc.output.log`, `spc.shell.log`, and per-package CMake/config logs); controlled by `SPC_LOGS_DIR` and `SPC_ENABLE_LOG_FILE`.
|
||||
- `src/StaticPHP`: framework core: registry loading, config validation, dependency resolution, package install/build pipeline, doctor, toolchains, runtime shell/executors, exceptions.
|
||||
- `src/Package`: package-specific build logic registered by PHP attributes.
|
||||
- `src/globals`: constants, helper functions, patches, smoke tests, bundled license text.
|
||||
- `tests`: PHPUnit tests for config, registry, artifacts, dependency resolver, DI, commands, and utilities.
|
||||
- `docs/en/develop` and `docs/zh/develop`: developer documentation. Some pages may be TODO; verify against source when behavior matters.
|
||||
|
||||
## Working Rules
|
||||
|
||||
- Keep changes scoped to the requested package, artifact, command, docs, or tests.
|
||||
- Prefer existing package patterns over new abstractions. Search for a similar package first.
|
||||
- Use structured YAML config; do not encode dependency logic in PHP when config fields are enough.
|
||||
- Match package names exactly: extension packages use `ext-` in config and dependencies; `#[Extension('curl')]` expands to `ext-curl`.
|
||||
- Use platform suffixes such as `@unix`, `@linux`, `@macos`, and `@windows` instead of runtime conditionals when the difference is declarative.
|
||||
- Add or update PHP package classes only when build commands, validation, custom configure args, hooks, or source patching are required.
|
||||
- Do not edit generated build directories (`buildroot/`, `source/`, `downloads/`, `pkgroot/`) as a fix.
|
||||
|
||||
## Validation
|
||||
|
||||
For config or package changes, run CS checks first:
|
||||
|
||||
```bash
|
||||
bin/spc dev:lint-config
|
||||
composer cs-fix
|
||||
```
|
||||
|
||||
For broader PHP code changes, also run:
|
||||
|
||||
```bash
|
||||
composer test
|
||||
composer analyse
|
||||
```
|
||||
|
||||
Use build commands only when needed for the task or when the user provided a repro, because full static builds can be slow and platform-sensitive.
|
||||
@@ -53,8 +53,8 @@ PHP_BUILD_PROVIDER="StaticPHP ${SPC_VERSION}"
|
||||
SPC_ENABLE_LOG_FILE="yes"
|
||||
; The LOG DIR for spc logs
|
||||
SPC_LOGS_DIR="${WORKING_DIR}/log"
|
||||
; Preserve old logs when running new builds
|
||||
SPC_PRESERVE_LOGS="no"
|
||||
; Preserve old logs when running new builds (code checks SPC_PRESERVE_LOG, not SPC_PRESERVE_LOGS)
|
||||
SPC_PRESERVE_LOG="no"
|
||||
|
||||
; EXTENSION_DIR where the built php will look for extension when a .ini instructs to load them
|
||||
; only useful for builds targeting not pure-static linking
|
||||
|
||||
Reference in New Issue
Block a user