Compare commits

...

259 Commits

Author SHA1 Message Date
crazywhalecc
387b8c9dc5 feat(performance): add performance engineering documentation in English and Chinese 2026-07-15 08:52:51 +08:00
Jerry Ma
c1eefb8399 feat(manifest): implement BuildManifestDumper for generating build manifest (#1210) 2026-07-13 18:53:54 +08:00
crazywhalecc
4d00e338af feat(manifest): implement BuildManifestDumper for generating build manifest 2026-07-13 16:59:19 +08:00
Marc
422323a41d Fable v3 windows (#1207) 2026-07-10 23:25:39 +07:00
Jerry Ma
6144f7affb fix(windows): survive cmd.exe's 8191 character command line limit (#1209) 2026-07-10 21:02:19 +08:00
m-this
6d58d53f7d fix(imagemagick): build the VisualMagick tree under source/ on windows
- C:\im was outside the project so bin/spc reset could not clean it
- with the command line limit fixed a short base path is no longer
  needed; keep SPC_IMAGEMAGICK_BUILD_DIR as an override
2026-07-10 10:52:14 +02:00
m-this
c54fa78ad1 fix(windows): survive cmd.exe's 8191 character command line limit
- with big extension stacks (imagick) the link command lines exceed what
  cmd.exe allows and fail with 'The command line is too long'
- pass the collected LIBS_CLI/LIBS_CGI/LIBS_MICRO lib lists to link.exe
  through @response files, like php-src already does for its object lists
- compile the frankenphp -mthreads shim instead of generating a .bat:
  batch files run through cmd.exe and cap cgo link lines at 8191 chars,
  a real executable gets the full 32K and past that go writes a response
  file by itself; still probe-gated, still a stopgap for golang/go#80290
2026-07-10 08:04:10 +02:00
crazywhalecc
4d6f334cbb Refactor UPX patching logic for phpmicro binary 2026-07-09 16:52:39 +08:00
crazywhalecc
e99423c7d1 Unify GOPATH with go-win custom binary extraction method 2026-07-09 16:20:52 +09:00
crazywhalecc
44daaad548 Resolve xlswriter dllimport issue 2026-07-09 16:20:29 +09:00
crazywhalecc
4dac0d18b4 Fix windows file delete permissions 2026-07-09 16:20:10 +09:00
Jerry Ma
79db27da04 Merge branch 'v3' into fable-v3-windows 2026-07-09 12:31:39 +09:00
crazywhalecc
d04d82a1f1 Fix strawberry-perl detect time 2026-07-09 12:27:41 +09:00
crazywhalecc
dca24585d4 Add frankenphp test label 2026-07-09 11:56:29 +09:00
crazywhalecc
7edd8359d5 Enhance artifact extraction logic to check for existing files and handle hash storage for both file and directory targets 2026-07-09 11:55:54 +09:00
crazywhalecc
be8f239259 Merge remote-tracking branch 'origin/fable-v3-windows' into fable-v3-windows 2026-07-09 11:24:41 +09:00
crazywhalecc
6c7a47c9b5 Trigger full test when containing 'need-full-test' tag 2026-07-09 11:17:10 +09:00
Jerry Ma
859c06a470 Fix the Windows extension test failures on fable-v3-windows (#1208) 2026-07-09 11:09:33 +09:00
crazywhalecc
274706084a Fix frankenphp package path bug 2026-07-09 11:04:00 +09:00
crazywhalecc
0bd94b0ebd Lint 2026-07-09 11:03:39 +09:00
crazywhalecc
150998723d Fix windows captainhook 2026-07-09 11:03:32 +09:00
crazywhalecc
303dca5f59 Remove doctor item 2026-07-09 11:03:15 +09:00
m-this
d7902b9931 feat(tool): bundle python for the meson build
- add a python-win tool package that unzips the official python.org
  nuget package into the pkgroot (venv and ensurepip included)
- meson uses it to build its venv and only falls back to a system
  python, so no manual environment setup is needed
2026-07-08 14:17:36 +02:00
m-this
43b2da0511 fix(libiconv): only put the static lib on the windows link line
- static-libs@windows listed both libiconv.lib (the dll import lib) and
  libiconv_a.lib; the import lib came first, so php.exe ended up
  importing libiconv.dll and the cli smoke test died with
  STATUS_DLL_NOT_FOUND on machines without it
2026-07-08 11:15:11 +02:00
m-this
6dc5c5b770 fix(pgsql): link secur32 and crypt32 on windows
- libpq authenticates through SSPI and the static libcrypto behind it
  reads the system cert store; php.exe failed to link with unresolved
  Cert* and SSPI symbols when the openssl extension is not in the build
2026-07-08 11:15:11 +02:00
m-this
f3afd81c81 fix(php): pass /FORCE:MULTIPLE when linking php-cgi.exe and micro.sfx
- php.exe already links with /FORCE:MULTIPLE for extension-bundled
  duplicate symbols, cgi and micro did not
- imagick's MagickCore defines gettimeofday, also defined in php's
  time.obj, and both links failed with LNK2005
2026-07-08 11:15:11 +02:00
m-this
1dce506222 fix(postgresql): provision meson, ninja and winflexbison on windows
- the meson build assumed meson/ninja/win_flex/win_bison/perl on PATH,
  which only held on machines that had them installed
- add meson, ninja and winflexbison tool packages and declare them via
  tools@windows on postgresql, together with the existing strawberry-perl
- meson no longer ships a Windows MSI, so the wheel is installed offline
  into a venv: postgres re-invokes meson through find_program, which
  needs the real meson.exe launcher pip generates
2026-07-08 11:15:11 +02:00
crazywhalecc
323f21a6f2 Add gdi32.lib 2026-07-08 17:02:32 +09:00
crazywhalecc
ab30c9dc49 fix: update Visual Studio version handling in imagemagick configuration 2026-07-08 16:27:52 +09:00
Jerry Ma
996cca12c0 [v3] - fix(windows): resolve doctor-installed perl and quote perl path (#1174) 2026-07-08 13:59:05 +08:00
crazywhalecc
5451945972 Use escapeshellarg instead 2026-07-08 13:21:52 +08:00
crazywhalecc
fc1673e37f Merge branch 'refs/heads/v3' into pr/win-openssl-perl-path
# Conflicts:
#	src/Package/Library/openssl.php
2026-07-08 13:19:36 +08:00
Marc
f1722a0f3e Merge branch 'v3' into fable-v3-windows 2026-07-08 11:45:02 +07:00
Marc
8034ae37ea v3 weekly build fix (#1203) 2026-07-08 11:40:37 +07:00
Marc
c9f24b980d [v3] Enable SQLite column metadata (#1205) 2026-07-08 11:39:22 +07:00
Jerry Ma
5ffbf2d5fe fix(frankenphp): strip Go's -mthreads so the Windows build survives Clang >= 20 (#1201) 2026-07-08 11:47:02 +08:00
crazywhalecc
facc7bc5a7 test swoole 2026-07-08 11:43:35 +08:00
crazywhalecc
160d7f5537 fix: disable undefined behavior sanitizer in build flags 2026-07-08 11:41:41 +08:00
Jerry Ma
afa5f535e9 Merge branch 'v3' into v3c/fix-builds 2026-07-08 10:06:19 +08:00
Jerry Ma
0dde151632 Merge branch 'v3' into fix/v3-sqlite-column-metadata 2026-07-08 10:00:57 +08:00
Jerry Ma
e906edb332 Test bot separate (#1206) 2026-07-08 10:00:41 +08:00
mathis
83ce54b62b docs(frankenphp): link golang/go#80290 so the -mthreads workaround can be removed later 2026-07-08 03:59:20 +02:00
crazywhalecc
7d6c082c86 random test 2026-07-07 22:38:39 +08:00
crazywhalecc
db4f7c6a0c feat: separate workflow for posting test bot comments 2026-07-07 22:37:23 +08:00
Jan Jakeš
ca0167c83e Enable SQLite column metadata
Build Unix SQLite with SQLITE_ENABLE_COLUMN_METADATA so the metadata APIs are available on macOS and Linux.

Remove the pdo_sqlite configure override that forced PHP to treat sqlite3_column_table_name() as unavailable, and add sanity checks for both SQLite compile options and PDO column metadata.
2026-07-07 16:25:00 +02:00
m-this
5a5c784c4f fix(frankenphp): strip Go's -mthreads so the Windows build survives Clang >= 20
Go passes the MinGW-only -mthreads flag to the C compiler for cgo builds
(golang/go#16932); Clang >= 20 rejects it for the MSVC target, so the final
frankenphp go build fails on current windows-latest (VS 18 / LLVM 20+).

Wrap Clang with a generated .bat that drops the -mthreads token and forwards
the rest, used only when the detected Clang refuses the flag.
2026-07-07 15:30:52 +02:00
crazywhalecc
331da67049 Fix gen-ext-test-matrix AND bug (should be OR) 2026-07-07 15:48:35 +08:00
crazywhalecc
cc448d463b simdjson test 2026-07-07 15:42:34 +08:00
crazywhalecc
dc55881b78 libde265 fix build 2026-07-07 15:21:19 +08:00
crazywhalecc
a59473e4ab ext-test-matrix generation fix 2026-07-07 15:03:31 +08:00
crazywhalecc
c6a227f4de libde265 test 2026-07-07 14:50:32 +08:00
Jerry Ma
392733b7c3 feat(v3): Tool package refactor (#1200) 2026-07-06 21:59:44 +08:00
Jerry Ma
3870269330 feat(docs): add agent guide, build class patterns, log triage, and AI instructions (#1202) 2026-07-06 21:59:26 +08:00
crazywhalecc
03f1313eec chore 2026-07-06 21:20:38 +08:00
crazywhalecc
b9def51f86 Simplify redundant github instruction 2026-07-06 21:20:20 +08:00
crazywhalecc
8533702cf6 oops 2026-07-06 21:19:55 +08:00
crazywhalecc
fe3cd15f81 feat(docs): add agent guide, build class patterns, log triage, and AI instructions 2026-07-06 20:39:44 +08:00
crazywhalecc
dc33b55fd0 Use binary 2026-07-06 20:12:10 +08:00
crazywhalecc
c9401a0b7a Use redirect instead 2026-07-06 19:35:48 +08:00
crazywhalecc
fa040bc346 Fix mingw patch paths 2026-07-06 19:10:10 +08:00
crazywhalecc
ab37b34fb5 fix: improve Windows patching logic and update file paths for xlsxwriter 2026-07-06 16:46:29 +08:00
crazywhalecc
0b02f62b7e feat: add pkg-config tool package config 2026-07-06 15:36:36 +08:00
crazywhalecc
924fac137c docs: fix hosted repo URL in READMEs
- Update static-php-cli-hosted → static-php/hosted in both README.md and README-zh.md
2026-07-06 15:11:07 +08:00
crazywhalecc
d9c41a73da feat: add --installed flag to check-update, improve CLI and InteractiveTerm
- Add --installed option to check-update command to compare against on-disk version (tool packages)
- Support use_installed parameter in ArtifactDownloader::checkUpdate/checkUpdates
- Add -y shorthand for --auto-fix in doctor command
- Hook InteractiveTerm::init() in ConsoleApplication::doRun() to properly inject Symfony input/output
2026-07-06 15:10:52 +08:00
crazywhalecc
dd1e70a394 feat: declare tool dependencies in package configs via tools field
- Add 'tools' field to ConfigValidator for build-time tool declarations
- Move jom and strawberry-perl from depends@windows to tools@windows in openssl.yml
- Move go-xcaddy/go-win from depends to tools in frankenphp.yml
- Register config/pkg/tool/ path in spc.registry.yml
- Use addInstallPackage for upx tool in php.php (ToolPackage instead of library dep)
- Include 'tool' type in DumpCapabilitiesCommand and InstallPackageCommand package lists
2026-07-06 15:10:22 +08:00
crazywhalecc
1bdbdfc08c refactor: move getLibExtra* to Package base, add ToolPackage support to executors and builders
- Move getLibExtraCFlags/getLibExtraCxxFlags/getLibExtraLdFlags/getLibExtraLibs from LibraryPackage to Package base class so ToolPackage can also use them
- Full ToolPackage implementation: getBuildRootPath, getIncludeDir, getLibDir, getBinDir, getToolField with platform suffix support
- Update PackageBuilder to support building ToolPackage (not just LibraryPackage)
- Update PackageInstaller: support ToolPackage in download/extract/install pipeline, auto-install build-time tools, record installed versions
- Allow LibraryPackage|ToolPackage union type in all Executor classes and UnixShell::initializeEnv
2026-07-06 15:10:08 +08:00
crazywhalecc
90846ab149 refactor: restructure tool target configs into tool package system
- Move tool configs from config/pkg/target/ to config/pkg/tool/
- Add ToolVersionRegistry for tracking installed tool versions
- Delete old Target/pkgconfig.php, move to tool config
- Rename: 7za-win, go-win, go-xcaddy, jom, nasm, protoc, strawberry-perl, upx, vswhere, zig, pkg-config
2026-07-06 15:08:43 +08:00
Jerry Ma
8dd7882869 CRLF to LF (#1199) 2026-07-06 14:14:57 +08:00
crazywhalecc
7f6be12bf1 CRLF to LF 2026-07-06 14:02:38 +08:00
Jerry Ma
45b97581d8 feat(zip): add additional dependencies for Windows zip build (#1198) 2026-07-04 15:42:31 +08:00
crazywhalecc
12a5217f17 feat(zip): add additional dependencies for Windows zip build 2026-07-04 14:10:59 +08:00
Jerry Ma
5913cb07fd [v3] implement tool package support with validation and config (#1196) 2026-06-27 20:17:53 +08:00
crazywhalecc
dd69155539 feat(tool): remove deprecated tool package directory from registry configuration 2026-06-27 15:47:46 +08:00
crazywhalecc
a81dd6d5c9 feat(tool): implement tool package support with validation and configuration 2026-06-27 15:39:30 +08:00
Jerry Ma
b4ed673261 feat(windows): replace php-sdk-binary-tools with MSYS2 + 7za-win (#1193) 2026-06-23 14:36:28 +08:00
crazywhalecc
db2d9a909f feat(gmssl): add patch for pbkdf2_hmac_sm3_genkey rename and update build process 2026-06-22 16:44:44 +08:00
crazywhalecc
38e01a9b88 feat(tests): enhance label information for triggering extension build tests 2026-06-22 13:33:25 +08:00
crazywhalecc
2b210f9403 feat(logging): synchronize logger level and debug mode with output verbosity 2026-06-22 13:33:02 +08:00
crazywhalecc
be329c1d56 feat(build): add patch to Makefile for include order to resolve zip.h conflict 2026-06-22 11:14:14 +08:00
Jerry Ma
227b8f0b0a fix(test): fix redundant terminal output during phpunit (#1194) 2026-06-22 08:08:47 +08:00
crazywhalecc
c88041b7e0 feat(build): add UPX as an optional package for compression 2026-06-21 20:08:27 +08:00
crazywhalecc
3bb84f3b94 feat(build): add zlib as a dependency for Windows 2026-06-21 19:35:07 +08:00
crazywhalecc
c31bf73685 feat(build): add bison and re2c to required packages; bypass phpsdk_version check for MSVC + msys2 2026-06-21 19:28:15 +08:00
crazywhalecc
c4d7ca819b fix(openssl): update perl path for Windows compatibility 2026-06-21 19:27:47 +08:00
crazywhalecc
fd8ab71d80 feat(build): use WinCNG as crypto backend for libssh2 windows 2026-06-21 19:27:32 +08:00
crazywhalecc
2a7966aa4b Fix curl zstd build bug 2026-06-21 19:26:55 +08:00
crazywhalecc
ef83ff074e fix(source): use ftp.gnu.org as primary, ftpmirror.gnu.org as fallback
All GNU packages now use ftp.gnu.org (stable canonical server) as the
primary filelist source, with ftpmirror.gnu.org configured as
source-mirror fallback. ftpmirror uses DNS round-robin across many
mirrors of varying reliability; this setup eliminates random CI failures
caused by unreachable mirror nodes while preserving a fallback path.
2026-06-21 17:33:48 +08:00
crazywhalecc
06864fc3f6 feat(windows): replace php-sdk-binary-tools with MSYS2 + 7za-win
- Add msys2-build-essentials target: downloads the MSYS2 nightly sfx,
  extracts it, disables PGP keyring (CI-safe), runs two-pass pacman
  update, and installs autotools build essentials (make, autoconf,
  automake, libtool, pkgconf, perl).
- Add 7za-win target: downloads 7za.exe to PKG_ROOT_PATH\bin.
- Remove php-sdk-binary-tools target and all PHP_SDK_PATH references;
  replace with SPC_MSYS2_PATH throughout Artifact, ArtifactExtractor,
  FileSystem, DefaultShell and MSVCToolchain.
- Replace {php_sdk_path} path placeholder with {spc_msys2_path}.
- WindowsToolCheck: replace checkSDK/installSDK with checkMsys2,
  installMsys2 and check7zaWin/install7zaWin fix items.
- nasm.yml: extract nasm.exe/ndisasm.exe to {pkg_root_path}/bin.
- env.ini: rename PHP_SDK_PATH to SPC_MSYS2_PATH.
- Docs: update Windows migration guide and package-model placeholder docs.
2026-06-21 16:56:40 +08:00
Marc
408d8f755c Remove laravel/prompts from box.json (#1190) 2026-06-16 19:05:39 +07:00
Marc
1f291a9036 Add Visual Studio 2026 support (#1191) 2026-06-16 19:05:09 +07:00
crazywhalecc
127fb1989f Add vs 18 support 2026-06-16 19:21:18 +08:00
Jerry Ma
af771cf2b5 feat: enhance type hints and improve verbosity handling in commands (#1186) 2026-06-16 18:50:18 +08:00
crazywhalecc
5df65d926c Remove laravel/prompts from box.json 2026-06-16 18:49:22 +08:00
Jerry Ma
bdc7bbe1f1 v3: Fix gmssl build (#1188) 2026-06-16 18:45:43 +08:00
Jerry Ma
89dca1f0fb refactor: remove unused symfony/process and unnecessary laravel/prompts (#1187) 2026-06-16 18:15:03 +08:00
crazywhalecc
064a1f05ae Fix phpstan 2026-06-16 15:17:51 +08:00
crazywhalecc
88cb6749b8 Remove laravel/prompts and symfony/process 2026-06-16 15:11:48 +08:00
Jerry Ma
0010e35882 ext: add ext-fastchart and ext-fastjson registry entries (#1165) 2026-06-16 13:57:33 +08:00
crazywhalecc
728c8dd598 Make gmssl standalone 2026-06-16 13:19:03 +08:00
Marc
bf6216e59f Merge branch 'v3' into v3c/ext-fastchart-fastjson 2026-06-14 17:14:37 +07:00
DubbleClick
f66e68754e fable output 2026-06-14 11:51:07 +07:00
Marc
411ad7cc0f Add macports support (#1179) 2026-06-06 21:06:13 +07:00
Kevin Boyd
0761267eb3 Combine the macos tool checks into a single checkBrewOrPorts method 2026-06-04 21:40:01 -07:00
Jerry Ma
072a3b5505 feat: add permissions for id-token and attestations in release build (#1181) 2026-06-04 10:35:38 +08:00
Marc
0e5738b710 toolchain: add SPC_DEFAULT_RANLIB and pin cmake AR/RANLIB (#1163) 2026-06-04 09:25:42 +07:00
crazywhalecc
3ff9426e50 feat: add permissions for id-token and attestations in release build 2026-06-04 09:51:06 +08:00
Kevin Boyd
6057394641 Simplify macports checks 2026-05-31 22:04:44 -07:00
Kevin Boyd
2f4fb9d28f Add a check for macports alongside Brew in toolchainmanager 2026-05-28 22:40:33 -07:00
Kevin Boyd
96ab2de4b1 Add preliminary MacPorts support 2026-05-28 22:38:56 -07:00
Luther Monson
6c59456c02 fix(windows): consolidate to single canonical strawberry-perl path
Per review: spc's pkg config, doctor, and MSVCToolchain all use
PKG_ROOT_PATH\strawberry-perl. The arch-suffixed strawberry-perl-{arch}-win
path was stale and shouldn't be juggled alongside it. Validate against the
one canonical pkg-root path, falling back to WindowsUtil::findCommand.
2026-05-27 22:30:04 -07:00
Luther Monson
0e8a806640 fix(windows): resolve doctor-installed perl and quote perl path
Two related fixes for OpenSSL builds on Windows:

1. spc doctor installs Strawberry Perl under `pkgroot/strawberry-perl/`,
   but the validate() check only looks at the arch-specific native path
   (`strawberry-perl-x86_64-win`). When a user runs `spc doctor` to
   install perl, the subsequent build fails because the doctor's install
   layout isn't on the lookup list. Add it as a fallback before falling
   through to WindowsUtil::findCommand.

2. Wrap the resolved perl path in quote() when building the Configure
   command. WindowsUtil::findCommand can return a path containing spaces
   (e.g. `C:\Program Files\...`), which then splits the cmd.exe
   invocation. Quoting matches how every other interpolated path in this
   command is handled.
2026-05-27 22:07:57 -07:00
crazywhalecc
c641c3b8db Make mongodb standalone 2026-05-25 10:25:47 +08:00
Jerry Ma
48d6e9ebc2 LinuxMuslCheck: pass tool env via setEnv instead of command prefixes (#1170) 2026-05-24 22:59:47 +08:00
Jerry Ma
6cab47db67 deduplicate_flags: keep paired flag+value tokens together (#1168) 2026-05-24 22:57:23 +08:00
Jerry Ma
ec3fd0f4b0 patch: strip trailing U+200E from spc_fix_avx512_cache_before_80400.p… (#1167) 2026-05-24 22:57:01 +08:00
henderkes
e72f9aa623 LinuxMuslCheck: pass tool env via setEnv instead of command prefixes
Build the CC/CXX/AR/LD/RANLIB map once and hand it to shell()->setEnv()
so the configure/make invocations don't have to repeat the same prefix
on every line. For the sudo make-install path the env still needs to
be on the command line (sudo strips the parent env), so the same map
is rendered into $envFlags and prepended there. Also adds RANLIB,
which the upstream Makefile honours.
2026-05-24 21:40:26 +07:00
henderkes
c666cd6cd0 deduplicate_flags: keep paired flag+value tokens together
deduplicate_flags() split flags on whitespace then ran a per-token
unique. For paired flags like `-Xclang -mllvm` or `-framework Cocoa`,
where the value is a separate token, the value token could collide
with an unrelated flag or value and get dropped, corrupting the
command line.

Group known paired flags (-Xclang, -Xpreprocessor, -Xlinker,
-Xassembler, -framework, -arch, -target, -include, -imacros, -isystem,
-isysroot, -iquote, -idirafter, -MT, -MF, -MQ) with their following
token into a single atom before the unique pass.
2026-05-24 21:38:22 +07:00
henderkes
b8dd508148 patch: strip trailing U+200E from spc_fix_avx512_cache_before_80400.patch
The filename had a Left-To-Right Mark (U+200E) appended invisibly, so
the file is unreachable by code that constructs the path from a plain
ASCII string literal. Rename to the visible name.
2026-05-24 21:38:00 +07:00
henderkes
37d8b87c3b oops 2026-05-24 21:11:49 +07:00
Jerry Ma
582a88ef60 artifact: use {pkg_root_path} template in rust and go_win extract (#1164) 2026-05-24 22:04:39 +08:00
Jerry Ma
153003b75c imagemagick: --without-gcc-arch (#1162) 2026-05-24 22:04:02 +08:00
Jerry Ma
899555a964 watcher: drop ldflags from compile-only invocation (#1161) 2026-05-24 22:03:38 +08:00
Jerry Ma
891a222c39 revert useless patch (#1160) 2026-05-24 22:03:11 +08:00
henderkes
39beb68024 artifact: use {pkg_root_path} template in rust and go_win extract
Switch the rust and go_win downloaders from baking PKG_ROOT_PATH into
the extract path at download time to the {pkg_root_path} template,
which ArtifactExtractor resolves at extract time. This keeps the path
stable across runs where pkg_root_path differs between download and
extract (e.g. containerised vs host builds).
2026-05-24 20:56:08 +07:00
henderkes
5172580294 toolchain: add SPC_DEFAULT_RANLIB and pin cmake AR/RANLIB
ClangBrew, ClangNative and GccNative now export SPC_DEFAULT_RANLIB
alongside SPC_DEFAULT_AR. UnixCMakeExecutor honours both when
generating the Linux toolchain file, so cmake uses the toolchain's
ar/ranlib (e.g. zig-ar/zig-ranlib for archives that the system
ranlib does not understand) instead of /usr/bin/ranlib.
2026-05-24 20:55:35 +07:00
henderkes
99e05aa22b ext: add ext-fastchart and ext-fastjson registry entries
Register two iliaal/fastchart and iliaal/fastjson PHP extensions
sourced from ghtar, extracted into php-src/ext/{fastchart,fastjson}.
Both target Linux and Darwin. fastchart depends on freetype and
suggests libpng, libjpeg, libwebp.
2026-05-24 20:55:11 +07:00
henderkes
0807e9e253 watcher: drop ldflags from compile-only invocation
The shell invocation runs `$CXX -c` to compile watcher-c.cpp to a .o,
which never links. Passing linker flags to a compile-only step is
either ignored or, with some flags, an error. Drop them.
2026-05-24 20:54:44 +07:00
henderkes
1a779be028 imagemagick: --without-gcc-arch
ax_gcc_archflag has no Zen cpuid pattern and falls back to
-mtune=amdfam10, which under LLVM+LTO emits SSE4a extrq and SIGILLs on
Intel hosts. Disable the implicit --with-gcc-arch so host CPU features
do not bleed into the built binaries.
2026-05-24 20:54:21 +07:00
henderkes
bdfd3eb269 also revert #1122 2026-05-24 20:41:18 +07:00
Marc
7ae5d742c2 V3 check/4 (#1159) 2026-05-24 20:24:11 +07:00
Marc
95be291a84 Merge branch 'v3' into v3-check/4 2026-05-24 20:24:03 +07:00
Marc
d89add106a V3 check/3 (#1158) 2026-05-24 20:23:44 +07:00
Marc
a36129c6cd V3 check/2 (#1157) 2026-05-24 20:23:32 +07:00
Marc
3f3edd62a1 Update src/Package/Extension/password_argon2.php 2026-05-24 17:57:02 +07:00
crazywhalecc
82b77af317 Chore: extension fixes
clickhouse, mongodb, opcache, password-argon2, pgsql, spx
2026-05-24 18:16:47 +08:00
crazywhalecc
df26b93e58 Remove redundant suffix for getClassesPsr4 function 2026-05-24 18:12:04 +08:00
crazywhalecc
d1b4c05381 Fix curl exe build on windows 2026-05-24 18:11:41 +08:00
crazywhalecc
e1658bc0e6 Chore: gettext-win version, password-argon2 deps 2026-05-24 18:09:51 +08:00
crazywhalecc
5053620b61 feat: auto-load local working directory registry in vendor mode 2026-05-24 18:07:06 +08:00
crazywhalecc
9366cbacd9 Update discord invite link 2026-05-24 18:06:30 +08:00
Jerry Ma
b8ce9f7787 [v3] fix(windows): static builds vswhere.exe -product * (#1149) 2026-05-22 10:20:18 +08:00
Jerry Ma
6772403d81 [v3] fix: use ftpmirror.gnu.org instead of ftp.gnu.org (#1151) 2026-05-21 15:26:58 +08:00
Marc
60a91a82e1 [v3] fix(macos): static build remove -fno-plt from macOS CFLAGS (#1150) 2026-05-21 12:06:18 +07:00
Luther Monson
4a274b69ac fix: use ftpmirror.gnu.org instead of ftp.gnu.org
ftp.gnu.org is unreliable and frequently times out during CI builds.
ftpmirror.gnu.org is GNU's own CDN that auto-redirects to the nearest
mirror. This is the recommended download method per
https://www.gnu.org/prep/ftp.en.html

Also normalizes /pub/gnu/ paths to /gnu/ since ftpmirror only serves
the latter.

Affects: libiconv, gettext, gmp, idn2, libunistring, ncurses, readline
2026-05-20 21:09:34 -07:00
Luther Monson
e4edd0a00f Merge branch 'v3' into fix/macos-fno-plt 2026-05-20 21:05:54 -07:00
Luther Monson
ae26ef3bdb fix(macos): remove -fno-plt from macOS CFLAGS
-fno-plt is an ELF-only flag that has no effect on macOS Mach-O
targets — clang emits "argument unused" when it encounters it.
Libraries like xz that run -Werror sanity checks during configure
promote that warning to a fatal error, breaking the build.
2026-05-20 20:57:12 -07:00
Luther Monson
049ecfe0a5 Merge branch 'v3' into fix/vswhere-products 2026-05-20 20:54:26 -07:00
Jerry Ma
01a4d872ad fix windows test failures: path separators and arch normalization (#1148) 2026-05-21 10:50:33 +08:00
Luther Monson
a9e54bb725 fix(windows): add -products * to vswhere so Build Tools are found
vswhere.exe defaults to searching Community, Professional, and
Enterprise editions only. CI environments typically install the
lightweight Build Tools product which is a separate product type
(Microsoft.VisualStudio.Product.BuildTools). Without -products *
the tool returns no results and the build fails with "Visual Studio
with C++ tools not found".

See: https://github.com/microsoft/vswhere/wiki/Find-MSBuild
2026-05-20 18:36:58 -07:00
Luther Monson
ad9b9ec69f Merge branch 'v3' into v3-fix-windows-test-paths 2026-05-19 23:19:39 -07:00
Marc
8a37303925 Add a Log Filter to Strip Github Tokens (#1147) 2026-05-20 13:19:03 +07:00
Luther Monson
52d234f1f4 fix windows test failures: path separators and arch normalization 2026-05-19 21:59:18 -07:00
Luther Monson
a3c39576df filter secrets at logger callback; register basic-auth encoded blob 2026-05-19 21:23:43 -07:00
Marc
3f7bad75ec Feat/clickhouse (#1137) 2026-05-11 13:28:16 +07:00
crazywhalecc
a3f135d26c Simplify pull request template 2026-05-11 13:59:32 +08:00
Jerry Ma
0732c1f0b0 Merge branch 'v3' into feat/clickhouse 2026-05-11 13:18:16 +08:00
Jerry Ma
9b64ad8299 Add dev:gen-ext-test-matrix command (#1133) 2026-05-11 13:17:57 +08:00
crazywhalecc
4d1ae0093d Bypass curl test on swow loaded time 2026-05-11 11:02:31 +08:00
Jerry Ma
db11d5a420 Update config/pkg/ext/ext-swow.yml 2026-05-11 11:01:43 +08:00
Marc
b20c1fa5c2 Update config/pkg/ext/ext-swow.yml 2026-05-11 09:49:19 +07:00
crazywhalecc
bf38212814 Add isolated extension mark 2026-05-11 10:07:02 +08:00
crazywhalecc
42fdc4eb87 Use PHP 8.5 by default 2026-05-11 09:48:31 +08:00
crazywhalecc
685f5c565f Use PHP 8.5 by default 2026-05-11 09:47:10 +08:00
crazywhalecc
b8ee484e81 Comment upterm session 2026-05-10 16:38:45 +08:00
crazywhalecc
c186038dca Use system cc instead 2026-05-10 16:27:25 +08:00
crazywhalecc
36e738f849 strange there 2026-05-10 16:06:20 +08:00
crazywhalecc
2cc3c8c9af Revert 2026-05-10 15:55:12 +08:00
crazywhalecc
0469b658bf Revert 2026-05-10 15:55:03 +08:00
crazywhalecc
7107566da7 Fix wrongly constructed class 2026-05-10 15:50:21 +08:00
crazywhalecc
02d8f51bb2 Enhance Unix Makefile patch to disable auto-vectorization for zig-cc to prevent minilua segfault 2026-05-10 15:17:51 +08:00
Jerry Ma
21c868463a Update tests.yml 2026-05-10 14:26:38 +08:00
Jerry Ma
079a30c5b1 Add tmate session setup for debugging on failure 2026-05-10 14:12:47 +08:00
crazywhalecc
64d9650f88 Fix compiler extra appending 2026-05-09 17:23:01 +08:00
crazywhalecc
e63d49ec13 Disable pdo pgsql hook for swow temporarily 2026-05-09 16:30:57 +08:00
Jerry Ma
9dbb178bf3 Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-09 16:11:26 +08:00
henderkes
3f48413281 add clickhouse extension by ilia 2026-05-09 15:10:30 +07:00
henderkes
dc6e63e1ba fix logic errors in shared ext patching 2026-05-09 15:09:59 +07:00
crazywhalecc
6ad4b6a4af Add concurrency settings to GitHub Actions workflow 2026-05-09 16:07:22 +08:00
crazywhalecc
270f131f54 Add label event 2026-05-09 16:01:44 +08:00
crazywhalecc
ceade306b8 phpstan fix 2026-05-09 15:55:55 +08:00
crazywhalecc
629b5b6b2d Add test-bot 2026-05-09 15:54:01 +08:00
crazywhalecc
7b79767355 Add retry mechanism to Git clone and GitHub release fetching methods 2026-05-09 14:13:47 +08:00
crazywhalecc
2ed4b10260 Make brotli and zstd as dep 2026-05-09 14:13:09 +08:00
crazywhalecc
184a091fd9 Implicitly define swow dependencies (due to extension generating and windows swow curl bug) 2026-05-09 14:12:50 +08:00
crazywhalecc
e6642459b8 Fix opentelemetry strict flag 2026-05-09 12:16:48 +08:00
crazywhalecc
af3c6a6d08 Move build command here 2026-05-09 11:05:28 +08:00
crazywhalecc
e930873e60 Add tier 2 support for actions runner test 2026-05-09 11:00:26 +08:00
crazywhalecc
cd803c75c5 Add filtering options for extensions, libs, and OS in test matrix generation 2026-05-09 10:44:04 +08:00
crazywhalecc
ad7475246f Merge remote-tracking branch 'origin/v3-docs/readme' into v3-docs/readme 2026-05-09 10:33:10 +08:00
crazywhalecc
b09cc968e6 Add curl execute output log 2026-05-09 10:19:16 +08:00
crazywhalecc
bf308e89a5 Remove duplicate phar patch for micro 2026-05-09 09:49:53 +08:00
crazywhalecc
bf326de985 Fix extracting hosted type for zip archive caused overwriting 2026-05-09 08:17:03 +08:00
crazywhalecc
4f9a555bf3 ds use git (pecl have buggy config.w32) 2026-05-09 08:16:11 +08:00
crazywhalecc
04df87cd5f Make intl use c++17 2026-05-09 08:15:45 +08:00
crazywhalecc
e4201a28ca Add 'imagick' and 'intl' to standalone array 2026-05-08 23:11:48 +08:00
crazywhalecc
1b30c98fbd Make glfw standalone though 2026-05-08 22:51:49 +08:00
crazywhalecc
61747f6f4e Add frameworks for glfw 2026-05-08 22:51:17 +08:00
crazywhalecc
c374163a05 Fix windows mpir build 2026-05-08 22:37:05 +08:00
crazywhalecc
ee21199ebb Remove hosted binary temporarily 2026-05-08 22:33:06 +08:00
crazywhalecc
01607a06c9 Add spx compatible command arg 2026-05-08 22:32:50 +08:00
crazywhalecc
fd4bf90a70 Add standalone list 2026-05-08 22:23:14 +08:00
crazywhalecc
73bf9ff93f Add libzstd.lib for windows builds 2026-05-08 22:13:50 +08:00
crazywhalecc
dcf1c5942c Add macOS test, conflicts 2026-05-08 22:12:06 +08:00
crazywhalecc
4695f846f5 Add macOS test 2026-05-08 21:23:29 +08:00
crazywhalecc
37b5f89ee1 Add extra build flags for specific extensions 2026-05-08 21:07:49 +08:00
crazywhalecc
5e40982e85 Use windows-latest 2026-05-08 20:58:33 +08:00
crazywhalecc
1d1f58f3a1 Disable parallel downloading 2026-05-08 20:55:23 +08:00
crazywhalecc
be039802c0 Add exclude for gen-ext-test-matrix 2026-05-08 20:54:41 +08:00
crazywhalecc
5529e66a61 Add dom deps for xmlreader 2026-05-08 19:33:19 +08:00
crazywhalecc
641ad8becf Add patch for PHP 8.2 compatibility in imap extension 2026-05-08 19:27:11 +08:00
crazywhalecc
a19c4470bb Fix frameworks in unix cmake executor wrongly used by linux 2026-05-08 19:11:31 +08:00
crazywhalecc
143ae4b8c4 Use -i instead of -I (-I used by hardcoded INI) 2026-05-08 19:08:00 +08:00
crazywhalecc
a980b0a1df Use -i instead of -I (-I used by hardcoded INI) 2026-05-08 19:07:39 +08:00
crazywhalecc
a8a851659f Fix memcache build on PHP 8.5 2026-05-08 19:07:06 +08:00
crazywhalecc
6b6025d3f0 Add parallel download 2026-05-08 17:41:12 +08:00
crazywhalecc
4507c8feb4 Fix zig check on fresh installed spc 2026-05-08 16:47:34 +08:00
crazywhalecc
9f80d6b2a8 Add dev:gen-ext-test-matrix command 2026-05-08 15:57:15 +08:00
crazywhalecc
ca8a28a364 Group shell command 2026-05-08 10:06:30 +08:00
crazywhalecc
8e3e790cc3 Add migration guide 2026-05-08 10:06:21 +08:00
crazywhalecc
4218f2905a Add nightly release build 2026-05-07 16:41:43 +08:00
Jerry Ma
4f06548c28 Update deployment workflow and enhance documentation build process (#1131) 2026-05-07 16:30:26 +08:00
crazywhalecc
b92a06a468 Update deployment workflow and enhance documentation build process 2026-05-07 16:05:59 +08:00
Jerry Ma
88d2f0fc52 StaticPHP v3 alpha1 (#980) 2026-05-07 15:53:59 +08:00
crazywhalecc
9d4a8dd7c3 Update README to announce upcoming v3 release and project rename 2026-05-07 15:50:07 +08:00
crazywhalecc
742752fd66 Add discord server 2026-05-07 15:32:09 +08:00
crazywhalecc
e93d103e99 SPC_DEFAULT_LD_FLAGS renamed to SPC_DEFAULT_LDFLAGS 2026-05-07 14:56:07 +08:00
crazywhalecc
9e4a622f42 SPC_DEFAULT_CXX_FLAGS renamed to SPC_DEFAULT_CXXFLAGS 2026-05-07 14:55:45 +08:00
crazywhalecc
506cb15654 SPC_DEFAULT_C_FLAGS renamed to SPC_DEFAULT_CFLAGS 2026-05-07 14:55:05 +08:00
crazywhalecc
43663d2966 Adjust macOS flags 2026-05-07 14:47:42 +08:00
crazywhalecc
0cecda791d Remove debug log for scandirs 2026-05-07 14:40:43 +08:00
crazywhalecc
d3b7c9106f Add ConditionalOn attribute 2026-05-07 14:40:14 +08:00
crazywhalecc
8e46cda227 Use active rdkafka 2026-05-07 14:39:10 +08:00
henderkes
640d973693 add to cxxflags 2026-05-06 14:15:45 +07:00
henderkes
d54e39353d better performance and debugging defaults 2026-05-06 14:13:33 +07:00
henderkes
aecc227b9a suggestions from @crazywhalecc 2026-05-06 14:08:27 +07:00
crazywhalecc
2ae5a876f0 Fix #1129 2026-05-06 14:50:33 +08:00
crazywhalecc
ecf10bec7c Forward-port #1089 2026-05-06 14:43:37 +08:00
henderkes
90d7fe46d7 add ext-gearman 2026-05-06 11:39:08 +07:00
crazywhalecc
8537ad7b19 Fix mongodb 2.3.0 introduced in-tree build bug 2026-04-30 11:18:58 +08:00
crazywhalecc
737728ac24 Make swoole using 6.2.0 2026-04-30 11:16:59 +08:00
crazywhalecc
ffe998697f Improve GitHub source retrieval by using latest release endpoint and enhancing version handling 2026-04-30 11:16:52 +08:00
Jerry Ma
6b53c0afae V3 refactor/forward ports (#1123) 2026-04-30 07:58:08 +08:00
crazywhalecc
c9ce96044d Forward-port #1120 2026-04-29 16:54:20 +08:00
crazywhalecc
2bcf62249f Forward-port #1117 2026-04-29 16:53:43 +08:00
crazywhalecc
2c8c7214f0 Forward-port #1115 2026-04-29 16:52:20 +08:00
crazywhalecc
d745c7d9ec Add maintainer-skip-build option 2026-04-29 16:38:59 +08:00
crazywhalecc
48c3be7e70 Add shared extension output 2026-04-29 16:37:15 +08:00
crazywhalecc
d458f57c84 Forward-port #1110 2026-04-29 16:24:58 +08:00
crazywhalecc
c454a1dc8e Enhance Linux distribution detection and package installation commands (forward-port #1109) 2026-04-29 15:53:52 +08:00
crazywhalecc
9ed2b18d06 Forward-port #1107 2026-04-29 15:44:44 +08:00
crazywhalecc
e70f5252a1 remove workaround for zig < 0.16 (forward-port #1105) 2026-04-29 15:42:07 +08:00
crazywhalecc
d080a86f2b Update OpenSSL source matching patterns to version 3.x 2026-04-29 15:40:49 +08:00
Jerry Ma
55dff48545 V3 docs (#1119) 2026-04-29 15:37:24 +08:00
crazywhalecc
27c364f692 Update CLI documentation for clarity and accuracy 2026-04-29 15:33:06 +08:00
crazywhalecc
a73e6c0e7e Add craft-yml docs 2026-04-29 15:10:00 +08:00
crazywhalecc
02713fafb5 Enhance package management in CraftCommand by merging craft-level packages and shared extensions into build options 2026-04-29 15:09:21 +08:00
crazywhalecc
269cd600f8 Refactor documentation structure and add new artifact model guide 2026-04-29 14:28:17 +08:00
crazywhalecc
3c4f39735e artifact 2026-04-27 10:15:22 +08:00
crazywhalecc
523335fc35 trigger 2026-04-23 15:05:12 +08:00
283 changed files with 9312 additions and 2119 deletions

24
.gitattributes vendored Normal file
View File

@@ -0,0 +1,24 @@
# Force LF line endings for all text files.
# Prevents git from auto-converting LF -> CRLF on Windows checkouts.
* text=auto eol=lf
# Explicit binary files — git won't touch line endings for these
*.phar binary
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.zip binary
*.gz binary
*.tgz binary
*.txz binary
*.xz binary
*.bz2 binary
*.7z binary
*.exe binary
*.dll binary
*.sfx binary
*.so binary
*.a binary
*.o binary

23
.github/copilot-instructions.md vendored Normal file
View 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/`

View File

@@ -1,17 +1,12 @@
## What does this PR do? ## What does this PR do?
<!-- Please describe the changes made in this PR here. -->
## Checklist before merging ## Checklist before merging
> If your PR involves the changes mentioned below and completed the action, please tick the corresponding option. - If you modified `*.php` or `*.yml`, run them locally to ensure your changes are valid:
> If a modification is not involved, please skip it directly.
- If you modified `*.php` or `*.json`, run them locally to ensure your changes are valid:
- [ ] `composer cs-fix` - [ ] `composer cs-fix`
- [ ] `composer analyse` - [ ] `composer analyse`
- [ ] `composer test` - [ ] `composer test`
- [ ] `bin/spc dev:sort-config` - [ ] `bin/spc dev:lint-config`
- If it's an extension or dependency update, please ensure the following:
- [ ] Add your test combination to `src/globals/test-extensions.php`.
- [ ] If adding new or fixing bugs, add commit message containing `extension test` or `test extensions` to trigger full test suite.

View 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.

View 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."

View 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.

View 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.

View 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."

View 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.

View 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
```

View File

@@ -331,5 +331,4 @@ jobs:
with: with:
name: build-meta-${{ inputs.php-version }}-${{ inputs.os }} name: build-meta-${{ inputs.php-version }}-${{ inputs.os }}
path: | path: |
buildroot/build-extensions.json buildroot/build-manifest.json
buildroot/build-libraries.json

View File

@@ -115,5 +115,4 @@ jobs:
with: with:
name: build-meta name: build-meta
path: | path: |
buildroot/build-extensions.json buildroot/build-manifest.json
buildroot/build-libraries.json

View File

@@ -2,13 +2,14 @@ name: "Extension Matrix Tests"
on: on:
workflow_dispatch: workflow_dispatch:
push: pull_request:
types: [opened, synchronize, labeled]
jobs: jobs:
test: test:
name: "${{ matrix.extension }} (PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }})" name: "${{ matrix.extension }} (PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }})"
runs-on: ${{ matrix.operating-system }} runs-on: ${{ matrix.operating-system }}
if: contains(github.event.head_commit.message, 'extension test') || contains(github.event.head_commit.message, 'test extensions') if: contains(github.event.pull_request.labels.*.name, 'need-full-test')
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

View File

@@ -0,0 +1,48 @@
name: Post Test Bot Comment
on:
workflow_run:
workflows: ["v3 Tests"]
types: [completed]
permissions:
pull-requests: write
actions: read
jobs:
post-comment:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Download bot output
id: download
uses: actions/download-artifact@v4
continue-on-error: true
with:
name: bot-output
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Post/Update comment
if: steps.download.outcome == 'success'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
COMMENT_BODY=$(jq -r '.comment_body' bot-output.json)
PR_NUMBER=$(jq -r '.pr_number' bot-output.json)
MARKER="<!-- spc-test-bot -->"
# Find existing bot comment id
EXISTING_ID=$(gh api \
"repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
--jq "[.[] | select(.body | startswith(\"${MARKER}\")) | .id] | first // empty")
if [ -n "$EXISTING_ID" ]; then
gh api --method PATCH \
"repos/${{ github.repository }}/issues/comments/${EXISTING_ID}" \
-f body="$COMMENT_BODY"
else
gh pr comment "$PR_NUMBER" \
--repo "${{ github.repository }}" \
--body "$COMMENT_BODY"
fi

View File

@@ -38,6 +38,9 @@ jobs:
- name: "windows-x64" - name: "windows-x64"
os: "ubuntu-latest" os: "ubuntu-latest"
filename: "spc-windows-x64.exe" filename: "spc-windows-x64.exe"
permissions:
id-token: write
attestations: write
steps: steps:
- name: "Checkout" - name: "Checkout"
uses: "actions/checkout@v5" uses: "actions/checkout@v5"
@@ -105,6 +108,12 @@ jobs:
fi fi
fi fi
- name: "Generate build provenance attestation"
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v4
with:
subject-path: "${{ github.workspace }}/${{ matrix.operating-system.name == 'windows-x64' && 'spc.exe' || 'spc' }}"
- name: "Copy file" - name: "Copy file"
run: | run: |
if [ "${{ matrix.operating-system.name }}" != "windows-x64" ]; then if [ "${{ matrix.operating-system.name }}" != "windows-x64" ]; then
@@ -120,6 +129,18 @@ jobs:
with: with:
files: dist/${{ matrix.operating-system.filename }} files: dist/${{ matrix.operating-system.filename }}
- name: "Deploy to self-hosted OSS (nightly)"
# only run this step if the repository is static-php-cli and is push to v3 branch
if: ${{ github.repository == 'crazywhalecc/static-php-cli' && github.ref == 'refs/heads/v3' }}
uses: static-php/upload-s3-action@v1.0.0
with:
aws_key_id: ${{ secrets.AWS_KEY_ID }}
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws_bucket: ${{ secrets.AWS_BUCKET }}
source_dir: "dist/"
destination_dir: v3/spc-bin/nightly/
endpoint: ${{ secrets.AWS_ENDPOINT }}
- name: "Deploy to self-hosted OSS (latest)" - name: "Deploy to self-hosted OSS (latest)"
# only run this step if the repository is static-php-cli and is release tag # only run this step if the repository is static-php-cli and is release tag
if: ${{ github.repository == 'crazywhalecc/static-php-cli' && startsWith(github.ref, 'refs/tags/') }} if: ${{ github.repository == 'crazywhalecc/static-php-cli' && startsWith(github.ref, 'refs/tags/') }}

View File

@@ -1,9 +1,9 @@
name: Tests name: v3 Tests
on: on:
pull_request: pull_request:
branches: [ "main", "v3" ] branches: [ "v3" ]
types: [ opened, synchronize, reopened ] types: [ opened, synchronize, reopened, labeled, unlabeled ]
paths: paths:
- 'src/**' - 'src/**'
- 'config/**' - 'config/**'
@@ -15,6 +15,10 @@ on:
permissions: read-all permissions: read-all
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -103,114 +107,164 @@ jobs:
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: "Run PHPUnit Tests" - name: "Run PHPUnit Tests"
run: SPC_LIBC=glibc vendor/bin/phpunit tests/ --no-coverage run: vendor/bin/phpunit tests/ --no-coverage
define-matrix: check-gate:
if: false # TODO: enable when refactoring workflows name: "Check: need-test label"
name: "Define Matrix"
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
php: ${{ steps.gendef.outputs.php }} enabled: ${{ steps.gate.outputs.enabled }}
os: ${{ steps.gendef.outputs.os }}
steps: steps:
- name: "Checkout" - name: Check label
uses: actions/checkout@v4 id: gate
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
extensions: curl, openssl, mbstring
- name: Define
id: gendef
run: | run: |
PHP_VERSIONS=$(php src/globals/test-extensions.php php) LABELS='${{ toJSON(github.event.pull_request.labels.*.name) }}'
OS_VERSIONS=$(php src/globals/test-extensions.php os) if echo "$LABELS" | grep -q '"need-test"'; then
echo 'php='"$PHP_VERSIONS" >> "$GITHUB_OUTPUT" echo "enabled=true" >> "$GITHUB_OUTPUT"
echo 'os='"$OS_VERSIONS" >> "$GITHUB_OUTPUT" else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
test-bot:
build: name: "Test Bot: analyze PR"
if: false needs: check-gate
name: "Build PHP Test (PHP ${{ matrix.php }} ${{ matrix.os }})" if: needs.check-gate.outputs.enabled == 'true'
runs-on: ${{ matrix.os }} runs-on: ubuntu-latest
needs: [define-matrix, php-cs-fixer, phpstan, phpunit] permissions:
timeout-minutes: 120 contents: read
strategy: outputs:
matrix: need_test: ${{ steps.bot.outputs.need_test }}
php: ${{ fromJSON(needs.define-matrix.outputs.php) }} gen_matrix_args: ${{ steps.bot.outputs.gen_matrix_args }}
os: ${{ fromJSON(needs.define-matrix.outputs.os) }} gen_matrix_args_tier2: ${{ steps.bot.outputs.gen_matrix_args_tier2 }}
fail-fast: false php_versions: ${{ steps.bot.outputs.php_versions }}
tier2: ${{ steps.bot.outputs.tier2 }}
steps: steps:
- name: "Update runner packages" - uses: actions/checkout@v4
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
run: sudo apt-get update && sudo apt-get install -y ca-certificates
- name: "Checkout" - name: Setup PHP
uses: actions/checkout@v4
- name: "Setup PHP"
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
with: with:
php-version: 8.4 php-version: '8.4'
tools: pecl, composer
extensions: curl, openssl, mbstring extensions: curl, openssl, mbstring
ini-values: memory_limit=-1 ini-values: memory_limit=-1
tools: composer
- name: Install dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-dev
- name: Run dev:test-bot
id: bot
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BOT_JSON=$(php -d opcache.enable_cli=0 bin/spc dev:test-bot \
--pr=${{ github.event.pull_request.number }} \
--repo=${{ github.repository }} 2>/dev/null)
echo "need_test=$(echo "$BOT_JSON" | jq -r '.need_test')" >> "$GITHUB_OUTPUT"
echo "gen_matrix_args=$(echo "$BOT_JSON" | jq -r '.gen_matrix_args')" >> "$GITHUB_OUTPUT"
echo "gen_matrix_args_tier2=$(echo "$BOT_JSON" | jq -r '.gen_matrix_args_tier2')" >> "$GITHUB_OUTPUT"
echo "php_versions=$(echo "$BOT_JSON" | jq -c '.php_versions')" >> "$GITHUB_OUTPUT"
echo "tier2=$(echo "$BOT_JSON" | jq -r '.tier2')" >> "$GITHUB_OUTPUT"
# Save JSON for the comment-posting workflow
jq -n --argjson bot "$BOT_JSON" \
--arg pr '${{ github.event.pull_request.number }}' \
'$bot + {pr_number: $pr}' > bot-output.json
- name: Upload bot output
uses: actions/upload-artifact@v4
with:
name: bot-output
path: bot-output.json
retention-days: 1
gen-matrix:
name: "Generate test matrix"
needs: test-bot
if: needs.test-bot.outputs.need_test == 'true'
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.build.outputs.matrix }}
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
tools: composer
- name: Install dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-dev
- name: Build matrix
id: build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GEN_MATRIX_ARGS: ${{ needs.test-bot.outputs.gen_matrix_args }}
GEN_MATRIX_ARGS_TIER2: ${{ needs.test-bot.outputs.gen_matrix_args_tier2 }}
PHP_VERSIONS: ${{ needs.test-bot.outputs.php_versions }}
TIER2: ${{ needs.test-bot.outputs.tier2 }}
run: |
# Tier1 matrix
MATRIX1=$(bin/spc dev:gen-ext-test-matrix $GEN_MATRIX_ARGS 2>/dev/null)
# Merge Tier2 if requested
if [ "$TIER2" = "true" ] && [ -n "$GEN_MATRIX_ARGS_TIER2" ]; then
MATRIX2=$(bin/spc dev:gen-ext-test-matrix $GEN_MATRIX_ARGS_TIER2 2>/dev/null)
COMBINED=$(jq -n --argjson m1 "$MATRIX1" --argjson m2 "$MATRIX2" '$m1 + $m2')
else
COMBINED=$MATRIX1
fi
# Expand PHP versions: cartesian product of entries × php_versions
FINAL=$(echo "$COMBINED" | jq --argjson versions "$PHP_VERSIONS" \
'[.[] | . as $entry | $versions[] | $entry + {"php-version": .}]')
echo "matrix=$(echo "$FINAL" | jq -c '{"combo": .}')" >> "$GITHUB_OUTPUT"
ext-test:
name: "Ext test: ${{ matrix.combo.extension }} [${{ matrix.combo.sapi }}] (PHP ${{ matrix.combo.php-version }} - ${{ matrix.combo.os }}-${{ matrix.combo.arch }})"
needs: gen-matrix
runs-on: ${{ matrix.combo.runner }}
timeout-minutes: 120
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.gen-matrix.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
tools: composer
env: env:
phpts: nts phpts: nts
- name: "Cache composer packages" - name: Install dependencies
id: composer-cache run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-dev
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
# Cache downloaded source - name: Build
- id: cache-download env:
uses: actions/cache@v4 SPC_USE_SUDO: "yes"
with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
path: downloads
key: php-dependencies-${{ matrix.os }}
- name: "Install Dependencies"
run: composer update -vvv --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-plugins
- name: "Run Build Tests (doctor)"
run: php src/globals/test-extensions.php doctor_cmd ${{ matrix.os }} ${{ matrix.php }}
- name: "Prepare UPX for Windows"
if: ${{ startsWith(matrix.os, 'windows-') }}
run: | run: |
php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }} ./bin/spc doctor --auto-fix
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV ${{ matrix.combo.build-args }} --dl-with-php=${{ matrix.combo.php-version }}
- name: "Prepare UPX for Linux" # - name: Setup upterm session
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
run: |
php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }}
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV
- name: "Run Build Tests (download)"
run: php src/globals/test-extensions.php download_cmd ${{ matrix.os }} ${{ matrix.php }}
- name: "Run Build Tests (build)"
run: php src/globals/test-extensions.php build_cmd ${{ matrix.os }} ${{ matrix.php }}
- name: "Run Build Tests (build - embed for non-windows)"
if: ${{ !startsWith(matrix.os, 'windows-') }}
run: php src/globals/test-extensions.php build_embed_cmd ${{ matrix.os }} ${{ matrix.php }}
- name: "Upload logs"
if: ${{ always() && hashFiles('log/**') != '' }}
uses: actions/upload-artifact@v7
with:
name: build-logs-${{ matrix.os }}-${{ matrix.php }}
path: log
# - name: Setup tmate session
# if: ${{ failure() }} # if: ${{ failure() }}
# uses: mxschmitt/action-tmate@v3 # uses: owenthereal/action-upterm@v1
- name: Upload logs
if: always() && hashFiles('log/**') != ''
uses: actions/upload-artifact@v4
with:
name: logs-${{ matrix.combo.os }}-${{ matrix.combo.arch }}-${{ matrix.combo.sapi }}-${{ matrix.combo.extension }}-php${{ matrix.combo.php-version }}
path: log

View File

@@ -1,8 +1,16 @@
name: Docs Auto Deploy name: Docs build test and auto deploy
on: on:
pull_request:
branches: [ "v3" ]
types: [ opened, synchronize, reopened ]
paths:
- 'config/**.yml'
- 'docs/**'
- 'package.json'
- 'yarn.lock'
- '.github/workflows/vitepress-deploy.yml'
push: push:
branches: branches: [ "v3" ]
- v3
paths: paths:
- 'config/**.yml' - 'config/**.yml'
- 'docs/**' - 'docs/**'
@@ -20,15 +28,8 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- uses: actions/setup-node@v3 - uses: actions/setup-node@v3
with:
cache: yarn
- run: yarn install --frozen-lockfile - run: npm install
- name: "Copy Config Files"
run: |
mkdir -p docs/.vitepress/config
cp -r config/* docs/.vitepress/config/
- name: "Install PHP for official runners" - name: "Install PHP for official runners"
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@@ -55,19 +56,13 @@ jobs:
- name: "Install Locked Dependencies" - name: "Install Locked Dependencies"
run: "composer install --no-interaction --no-progress" run: "composer install --no-interaction --no-progress"
# TODO: Uncomment when v3 gen commands are implemented
# - name: "Generate Extension Support List"
# run: |
# bin/spc dev:gen-ext-docs > docs/en/guide/extensions.md
# bin/spc dev:gen-ext-docs > docs/zh/guide/extensions.md
# bin/spc dev:gen-ext-dep-docs > docs/en/guide/deps-map.md
# bin/spc dev:gen-ext-dep-docs > docs/zh/guide/deps-map.md
- name: Build - name: Build
run: yarn docs:build run: npm run docs:build
# Deploy to GitHub Pages only when the workflow is triggered by a push to the v3 branch
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3 uses: peaceiris/actions-gh-pages@v3
if: github.event_name == 'push' && github.ref == 'refs/heads/v3'
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/.vitepress/dist publish_dir: docs/.vitepress/dist

59
AGENTS.md Normal file
View 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.

View File

@@ -5,9 +5,15 @@
[![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases) [![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases)
[![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml) [![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE) [![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
[![Discord](https://img.shields.io/discord/nrSRbpMJ?label=Discord&logo=discord&style=flat-square)](https://discord.gg/xf6Rd4pEAk)
**StaticPHP** 是一个强大的工具,用于构建可移植的可执行文件,包括 PHP、扩展等。 **StaticPHP** 是一个强大的工具,用于构建可移植的可执行文件,包括 PHP、扩展等。
> [!IMPORTANT]
> 我们正准备发布 **v3** 版本,届时项目名称将从 **static-php-cli** 更改为 **StaticPHP**。
> 此分支对应 v3 版本。v2 版本请查看 [v2 分支](https://github.com/crazywhalecc/static-php-cli/tree/main)。
> 请更新您的参考资料,并关注正式版发布。
## 特性 ## 特性
- :elephant: 支持多个 PHP 版本 - PHP 8.1, 8.2, 8.3, 8.4, 8.5 - :elephant: 支持多个 PHP 版本 - PHP 8.1, 8.2, 8.3, 8.4, 8.5
@@ -35,15 +41,15 @@
```bash ```bash
# For Linux x86_64 # For Linux x86_64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-linux-x86_64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64 # For Linux aarch64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-linux-aarch64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel) # macOS x86_64 (Intel)
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-macos-x86_64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple) # macOS aarch64 (Apple)
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-macos-aarch64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-aarch64
# Windows (x86_64, win10 build 17063 or later, please install VS2022 first) # Windows (x86_64, win10 build 17063 or later, please install VS2022 first)
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/v3/spc-bin/latest/spc-windows-x64.exe curl.exe -fsSL -o spc.exe https://dl.static-php.dev/v3/spc-bin/nightly/spc-windows-x64.exe
``` ```
对于 macOS 和 Linux请先添加可执行权限 对于 macOS 和 Linux请先添加可执行权限
@@ -98,7 +104,7 @@ echo '<?php echo "Hello world!\n";' > a.php
## 直接下载 ## 直接下载
如果你暂时不想构建,或只想先测试,可以从 [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml) 下载示例预编译产物,或从自托管服务器下载。 如果你暂时不想构建,或只想先测试,可以从 [Actions](https://github.com/static-php/hosted/actions/workflows/build-php-bulk.yml) 下载示例预编译产物,或从自托管服务器下载。
我们为每个 PHP 版本提供 2 种扩展集合: 我们为每个 PHP 版本提供 2 种扩展集合:

View File

@@ -5,9 +5,15 @@
[![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases) [![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases)
[![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml) [![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE) [![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
[![Discord](https://img.shields.io/discord/nrSRbpMJ?label=Discord&logo=discord&style=flat-square)](https://discord.gg/xf6Rd4pEAk)
**StaticPHP** is a powerful tool designed for building portable executables including PHP, extensions, and more. **StaticPHP** is a powerful tool designed for building portable executables including PHP, extensions, and more.
> [!IMPORTANT]
> We are preparing to release **v3**, which will include a project rename from **static-php-cli** to **StaticPHP**.
> And this branch is for v3. For v2, please check the [v2 branch](https://github.com/crazywhalecc/static-php-cli/tree/main).
> Please update your references and stay tuned for the official release.
## Features ## Features
- :elephant: Support multiple PHP versions - PHP 8.1, 8.2, 8.3, 8.4, 8.5 - :elephant: Support multiple PHP versions - PHP 8.1, 8.2, 8.3, 8.4, 8.5
@@ -35,15 +41,15 @@
```bash ```bash
# For Linux x86_64 # For Linux x86_64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-linux-x86_64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64 # For Linux aarch64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-linux-aarch64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel) # macOS x86_64 (Intel)
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-macos-x86_64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple) # macOS aarch64 (Apple)
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/latest/spc-macos-aarch64 curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-aarch64
# Windows (x86_64, win10 build 17063 or later, please install VS2022 first) # Windows (x86_64, win10 build 17063 or later, please install VS2022 first)
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/v3/spc-bin/latest/spc-windows-x64.exe curl.exe -fsSL -o spc.exe https://dl.static-php.dev/v3/spc-bin/nightly/spc-windows-x64.exe
``` ```
For macOS and Linux, add execute permission first: For macOS and Linux, add execute permission first:
@@ -98,7 +104,7 @@ see <https://static-php.dev>.
## Direct Download ## Direct Download
If you do not want to build yet or just want to test first, you can download example pre-compiled artifacts from [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml) or from a self-hosted server. If you do not want to build yet or just want to test first, you can download example pre-compiled artifacts from [Actions](https://github.com/static-php/hosted/actions/workflows/build-php-bulk.yml) or from a self-hosted server.
We offer 2 types of extension sets for each PHP version: We offer 2 types of extension sets for each PHP version:

View File

@@ -10,7 +10,6 @@
"config", "config",
"src", "src",
"vendor/psr", "vendor/psr",
"vendor/laravel/prompts",
"vendor/symfony", "vendor/symfony",
"vendor/php-di", "vendor/php-di",
"vendor/zhamao" "vendor/zhamao"

View File

@@ -20,7 +20,7 @@
] ]
}, },
{ {
"action": "bin/spc dev:lint-config --check", "action": "php bin/spc dev:lint-config --check",
"conditions": [ "conditions": [
{ {
"exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\InDirectory", "exec": "\\CaptainHook\\App\\Hook\\Condition\\FileStaged\\InDirectory",

View File

@@ -12,10 +12,8 @@
"php": ">=8.4", "php": ">=8.4",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-zlib": "*", "ext-zlib": "*",
"laravel/prompts": "~0.1",
"php-di/php-di": "^7.1", "php-di/php-di": "^7.1",
"symfony/console": "^5.4 || ^6 || ^7", "symfony/console": "^5.4 || ^6 || ^7",
"symfony/process": "^7.2",
"symfony/yaml": "^7.2", "symfony/yaml": "^7.2",
"zhamao/logger": "^1.1.4" "zhamao/logger": "^1.1.4"
}, },

620
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,12 @@
ncurses: ncurses:
binary: hosted
metadata: metadata:
license-files: license-files:
- COPYING - COPYING
source: source:
type: filelist type: filelist
url: 'https://ftp.gnu.org/pub/gnu/ncurses/' url: 'https://ftp.gnu.org/gnu/ncurses/'
regex: '/href="(?<file>ncurses-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/ncurses/'
regex: '/href="(?<file>ncurses-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>ncurses-(?<version>[^"]+)\.tar\.gz)"/'

View File

@@ -53,8 +53,8 @@ PHP_BUILD_PROVIDER="StaticPHP ${SPC_VERSION}"
SPC_ENABLE_LOG_FILE="yes" SPC_ENABLE_LOG_FILE="yes"
; The LOG DIR for spc logs ; The LOG DIR for spc logs
SPC_LOGS_DIR="${WORKING_DIR}/log" SPC_LOGS_DIR="${WORKING_DIR}/log"
; Preserve old logs when running new builds ; Preserve old logs when running new builds (code checks SPC_PRESERVE_LOG, not SPC_PRESERVE_LOGS)
SPC_PRESERVE_LOGS="no" SPC_PRESERVE_LOG="no"
; EXTENSION_DIR where the built php will look for extension when a .ini instructs to load them ; 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 ; only useful for builds targeting not pure-static linking
@@ -68,8 +68,8 @@ SPC_PRESERVE_LOGS="no"
[windows] [windows]
; build target: win7-static ; build target: win7-static
SPC_TARGET=native-windows SPC_TARGET=native-windows
; php-sdk-binary-tools path ; MSYS2 root directory (msys64 subfolder), used by the Windows toolchain
PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools" SPC_MSYS2_PATH="${PKG_ROOT_PATH}\msys2-build-essentials\msys64"
; upx executable path ; upx executable path
UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe" UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe"
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches ; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
@@ -94,7 +94,7 @@ SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime
; `native-native` - links against system libc dynamically ; `native-native` - links against system libc dynamically
; `native-native-musl` - links against musl libc statically ; `native-native-musl` - links against musl libc statically
; `native-native-musl -dynamic` - links against musl libc dynamically ; `native-native-musl -dynamic` - links against musl libc dynamically
SPC_TARGET=native-native-musl SPC_TARGET=${GNU_ARCH}-linux-musl
; compiler environments (default value is defined by selected toolchain) ; compiler environments (default value is defined by selected toolchain)
CC=${SPC_DEFAULT_CC} CC=${SPC_DEFAULT_CC}
@@ -102,9 +102,9 @@ CXX=${SPC_DEFAULT_CXX}
AR=${SPC_DEFAULT_AR} AR=${SPC_DEFAULT_AR}
LD=${SPC_DEFAULT_LD} LD=${SPC_DEFAULT_LD}
; default compiler flags, used in CMake toolchain file, openssl and pkg-config build ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build
SPC_DEFAULT_C_FLAGS="-fPIC -Os" SPC_DEFAULT_CFLAGS="-fPIC -O3 -pipe -fno-plt -fno-semantic-interposition -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections"
SPC_DEFAULT_CXX_FLAGS="-fPIC -Os" SPC_DEFAULT_CXXFLAGS="${SPC_DEFAULT_CFLAGS}"
SPC_DEFAULT_LD_FLAGS="" SPC_DEFAULT_LDFLAGS="-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -Wl,-z,noexecstack -Wl,--gc-sections"
; upx executable path ; upx executable path
UPX_EXEC=${PKG_ROOT_PATH}/bin/upx UPX_EXEC=${PKG_ROOT_PATH}/bin/upx
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches ; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
@@ -114,15 +114,15 @@ SPC_MICRO_PATCHES=cli_checks,disable_huge_page
; buildconf command ; buildconf command
SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force" SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
; configure command ; configure command
SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --disable-shared --enable-static --disable-all --disable-phpdbg --with-pic" SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --disable-shared --enable-static --disable-all --disable-phpdbg --enable-rtld-now --enable-re2c-cgoto --disable-rpath --with-pic"
; *** default build vars for building php *** ; *** default build vars for building php ***
; embed type for php, static (libphp.a) or shared (libphp.so) ; embed type for php, static (libphp.a) or shared (libphp.so)
SPC_CMD_VAR_PHP_EMBED_TYPE="static" SPC_CMD_VAR_PHP_EMBED_TYPE="static"
; EXTRA_CFLAGS for `configure` and `make` php ; EXTRA_CFLAGS for `configure` and `make` php
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE ${SPC_DEFAULT_C_FLAGS}" SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE -fvisibility=hidden -fvisibility-inlines-hidden ${SPC_DEFAULT_CFLAGS}"
; EXTRA_CXXFLAGS for `configure` and `make` php ; EXTRA_CXXFLAGS for `configure` and `make` php
SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS="-g -fstack-protector-strong -fno-ident -fPIE ${SPC_DEFAULT_CXX_FLAGS}" SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS="-g -fstack-protector-strong -fno-ident -fPIE -fvisibility=hidden -fvisibility-inlines-hidden ${SPC_DEFAULT_CXXFLAGS}"
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so ; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS="" SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
@@ -142,9 +142,9 @@ CXX=${SPC_DEFAULT_CXX}
AR=${SPC_DEFAULT_AR} AR=${SPC_DEFAULT_AR}
LD=${SPC_DEFAULT_LD} LD=${SPC_DEFAULT_LD}
; default compiler flags, used in CMake toolchain file, openssl and pkg-config build ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build
SPC_DEFAULT_C_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os" SPC_DEFAULT_CFLAGS="--target=${MAC_ARCH}-apple-darwin -O3 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections"
SPC_DEFAULT_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os" SPC_DEFAULT_CXXFLAGS="${SPC_DEFAULT_CFLAGS}"
SPC_DEFAULT_LD_FLAGS="" SPC_DEFAULT_LDFLAGS="-Wl,-dead_strip"
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches ; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
SPC_MICRO_PATCHES=cli_checks,macos_iconv SPC_MICRO_PATCHES=cli_checks,macos_iconv
@@ -152,15 +152,15 @@ SPC_MICRO_PATCHES=cli_checks,macos_iconv
; buildconf command ; buildconf command
SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force" SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
; configure command ; configure command
SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-phpdbg" SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --disable-shared --enable-static --disable-all --disable-phpdbg --enable-rtld-now --enable-re2c-cgoto --disable-rpath --with-pic"
; *** default build vars for building php *** ; *** default build vars for building php ***
; embed type for php, static (libphp.a) or shared (libphp.dylib) ; embed type for php, static (libphp.a) or shared (libphp.dylib)
SPC_CMD_VAR_PHP_EMBED_TYPE="static" SPC_CMD_VAR_PHP_EMBED_TYPE="static"
; EXTRA_CFLAGS for `configure` and `make` php ; EXTRA_CFLAGS for `configure` and `make` php
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -Werror=unknown-warning-option ${SPC_DEFAULT_C_FLAGS}" SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -fvisibility=hidden -fvisibility-inlines-hidden -Werror=unknown-warning-option ${SPC_DEFAULT_CFLAGS}"
; EXTRA_CXXFLAGS for `configure` and `make` php ; EXTRA_CXXFLAGS for `configure` and `make` php
SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS="-g -fstack-protector-strong -fno-ident -fpie -Werror=unknown-warning-option ${SPC_DEFAULT_CXX_FLAGS}" SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS="-g -fstack-protector-strong -fno-ident -fpie -fvisibility=hidden -fvisibility-inlines-hidden -Werror=unknown-warning-option ${SPC_DEFAULT_CXXFLAGS}"
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.dylib ; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.dylib
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS="" SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
; minimum compatible macOS version (LLVM vars, availability not guaranteed) ; minimum compatible macOS version (LLVM vars, availability not guaranteed)

View File

@@ -186,6 +186,7 @@ ext-password-argon2:
type: php-extension type: php-extension
depends: depends:
- libargon2 - libargon2
suggests:
- ext-openssl - ext-openssl
php-extension: php-extension:
os: os:
@@ -348,6 +349,7 @@ ext-xmlreader:
type: php-extension type: php-extension
depends: depends:
- ext-xml - ext-xml
- ext-dom
php-extension: php-extension:
arg-type: enable arg-type: enable
build-with-php: true build-with-php: true

View File

@@ -0,0 +1,19 @@
ext-clickhouse:
type: php-extension
artifact:
source:
type: ghtar
repo: iliaal/php_clickhouse
extract: php-src/ext/clickhouse
prefer-stable: true
metadata:
license-files: [LICENSE]
license: PHP-3.01
suggests@unix:
- openssl
lang: cpp
php-extension:
os:
- Linux
- Darwin
arg-type@unix: custom

View File

@@ -2,8 +2,10 @@ ext-ds:
type: php-extension type: php-extension
artifact: artifact:
source: source:
type: pecl type: git
name: ds url: 'https://github.com/php-ds/ext-ds.git'
rev: master
extract: php-src/ext/ds
metadata: metadata:
license-files: [LICENSE] license-files: [LICENSE]
license: MIT license: MIT

View File

@@ -0,0 +1,20 @@
ext-fastchart:
type: php-extension
artifact:
source:
type: ghtar
repo: iliaal/fastchart
extract: php-src/ext/fastchart
prefer-stable: true
metadata:
license-files: [LICENSE]
depends:
- freetype
suggests:
- libpng
- libjpeg
- libwebp
php-extension:
os:
- Linux
- Darwin

View File

@@ -0,0 +1,14 @@
ext-fastjson:
type: php-extension
artifact:
source:
type: ghtar
repo: iliaal/fastjson
extract: php-src/ext/fastjson
prefer-stable: true
metadata:
license-files: [LICENSE]
php-extension:
os:
- Linux
- Darwin

View File

@@ -0,0 +1,16 @@
ext-gearman:
type: php-extension
artifact:
source:
type: pecl
name: gearman
metadata:
license-files: [LICENSE]
license: PHP-3.01
depends:
- libgearman
php-extension:
os:
- Linux
- Darwin
arg-type: '--with-gearman@shared_path_suffix@'

View File

@@ -10,3 +10,5 @@ ext-gmssl:
license: PHP-3.01 license: PHP-3.01
depends: depends:
- gmssl - gmssl
php-extension:
arg-type: with-path

View File

@@ -13,4 +13,5 @@ ext-imagick:
os: os:
- Linux - Linux
- Darwin - Darwin
- Windows
arg-type: custom arg-type: custom

View File

@@ -3,7 +3,7 @@ ext-rdkafka:
artifact: artifact:
source: source:
type: ghtar type: ghtar
repo: arnaud-lb/php-rdkafka repo: php-rdkafka/php-rdkafka
extract: php-src/ext/rdkafka extract: php-src/ext/rdkafka
metadata: metadata:
license-files: [LICENSE] license-files: [LICENSE]

View File

@@ -5,7 +5,6 @@ ext-swoole:
type: ghtar type: ghtar
repo: swoole/swoole-src repo: swoole/swoole-src
extract: php-src/ext/swoole extract: php-src/ext/swoole
match: v6\.+
prefer-stable: true prefer-stable: true
metadata: metadata:
license-files: [LICENSE] license-files: [LICENSE]

View File

@@ -14,5 +14,6 @@ ext-swow:
- curl - curl
- ext-openssl - ext-openssl
- ext-curl - ext-curl
- postgresql
php-extension: php-extension:
arg-type: custom arg-type: custom

View File

@@ -10,6 +10,11 @@ ext-zip:
license: PHP-3.01 license: PHP-3.01
depends: depends:
- libzip - libzip
depends@windows:
- libzip
- zlib
- xz
- bzip2
php-extension: php-extension:
arg-type: custom arg-type: custom
arg-type@windows: enable arg-type@windows: enable

View File

@@ -5,7 +5,6 @@ brotli:
type: ghtagtar type: ghtagtar
repo: google/brotli repo: google/brotli
match: 'v1\.\d.*' match: 'v1\.\d.*'
binary: hosted
metadata: metadata:
license-files: [LICENSE] license-files: [LICENSE]
license: MIT license: MIT

View File

@@ -8,7 +8,6 @@ bzip2:
type: filelist type: filelist
url: 'https://sourceware.org/pub/bzip2/' url: 'https://sourceware.org/pub/bzip2/'
regex: '/href="(?<file>bzip2-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>bzip2-(?<version>[^"]+)\.tar\.gz)"/'
binary: hosted
metadata: metadata:
license-files: ['@/bzip2.txt'] license-files: ['@/bzip2.txt']
license: bzip2-1.0.6 license: bzip2-1.0.6

View File

@@ -4,6 +4,6 @@ gettext-win:
source: source:
type: git type: git
url: 'https://github.com/winlibs/gettext.git' url: 'https://github.com/winlibs/gettext.git'
rev: master rev: '0.18'
static-libs@windows: static-libs@windows:
- libintl_a.lib - libintl_a.lib

View File

@@ -3,7 +3,11 @@ gettext:
artifact: artifact:
source: source:
type: filelist type: filelist
url: 'https://ftp.gnu.org/pub/gnu/gettext/' url: 'https://ftp.gnu.org/gnu/gettext/'
regex: '/href="(?<file>gettext-(?<version>[^"]+)\.tar\.xz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/gettext/'
regex: '/href="(?<file>gettext-(?<version>[^"]+)\.tar\.xz)"/' regex: '/href="(?<file>gettext-(?<version>[^"]+)\.tar\.xz)"/'
metadata: metadata:
license-files: [gettext-runtime/intl/COPYING.LIB] license-files: [gettext-runtime/intl/COPYING.LIB]

View File

@@ -1,6 +1,12 @@
glfw: glfw:
type: library type: library
artifact: glfw artifact: glfw
frameworks:
- Cocoa
- CoreFoundation
- CoreVideo
- IOKit
- QuartzCore
headers: headers:
- GLFW/glfw3.h - GLFW/glfw3.h
- GLFW/glfw3native.h - GLFW/glfw3native.h

View File

@@ -6,8 +6,9 @@ gmp:
url: 'https://ftp.gnu.org/gnu/gmp/' url: 'https://ftp.gnu.org/gnu/gmp/'
regex: '/href="(?<file>gmp-(?<version>[^"]+)\.tar\.xz)"/' regex: '/href="(?<file>gmp-(?<version>[^"]+)\.tar\.xz)"/'
source-mirror: source-mirror:
type: url type: filelist
url: 'https://dl.static-php.dev/static-php-cli/deps/gmp/gmp-6.3.0.tar.xz' url: 'https://ftpmirror.gnu.org/gnu/gmp/'
regex: '/href="(?<file>gmp-(?<version>[^"]+)\.tar\.xz)"/'
metadata: metadata:
license-files: ['@/gmp.txt'] license-files: ['@/gmp.txt']
license: Custom license: Custom

View File

@@ -5,6 +5,10 @@ idn2:
type: filelist type: filelist
url: 'https://ftp.gnu.org/gnu/libidn/' url: 'https://ftp.gnu.org/gnu/libidn/'
regex: '/href="(?<file>libidn2-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>libidn2-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/libidn/'
regex: '/href="(?<file>libidn2-(?<version>[^"]+)\.tar\.gz)"/'
metadata: metadata:
license-files: [COPYING.LESSERv3] license-files: [COPYING.LESSERv3]
license: LGPL-3.0-or-later license: LGPL-3.0-or-later

View File

@@ -16,13 +16,59 @@ imagemagick:
- libtiff - libtiff
- libheif - libheif
- bzip2 - bzip2
depends@windows:
- zlib
suggests: suggests:
- zstd - zstd
- xz - xz
- libzip - libzip
- libxml2 - libxml2
headers@windows:
- imagemagick/MagickWand/MagickWand.h
lang: cpp lang: cpp
pkg-configs: pkg-configs:
- Magick++-7.Q16HDRI - Magick++-7.Q16HDRI
- MagickCore-7.Q16HDRI - MagickCore-7.Q16HDRI
- MagickWand-7.Q16HDRI - MagickWand-7.Q16HDRI
static-libs@windows:
- CORE_RL_MagickWand_.lib
- CORE_RL_MagickCore_.lib
- CORE_RL_coders_.lib
- CORE_RL_filters_.lib
- CORE_RL_aom_.lib
- CORE_RL_brotli_.lib
- CORE_RL_bzip2_.lib
- CORE_RL_cairo_.lib
- CORE_RL_croco_.lib
- CORE_RL_de265_.lib
- CORE_RL_exr_.lib
- CORE_RL_ffi_.lib
- CORE_RL_freetype_.lib
- CORE_RL_fribidi_.lib
- CORE_RL_gdk-pixbuf_.lib
- CORE_RL_glib_.lib
- CORE_RL_harfbuzz_.lib
- CORE_RL_heif_.lib
- CORE_RL_highway_.lib
- CORE_RL_imath_.lib
- CORE_RL_jpeg-turbo-12_.lib
- CORE_RL_jpeg-turbo-16_.lib
- CORE_RL_jpeg-turbo_.lib
- CORE_RL_jpeg-xl_.lib
- CORE_RL_lcms_.lib
- CORE_RL_lqr_.lib
- CORE_RL_lzma_.lib
- CORE_RL_openh264_.lib
- CORE_RL_openjpeg_.lib
- CORE_RL_openjph_.lib
- CORE_RL_pango_.lib
- CORE_RL_pixman_.lib
- CORE_RL_png_.lib
- CORE_RL_raqm_.lib
- CORE_RL_raw_.lib
- CORE_RL_rsvg_.lib
- CORE_RL_tiff_.lib
- CORE_RL_webp_.lib
- CORE_RL_xml_.lib
- CORE_RL_zip_.lib
- CORE_RL_zlib_.lib

View File

@@ -10,7 +10,6 @@ libcares:
type: filelist type: filelist
url: 'https://c-ares.org/download/' url: 'https://c-ares.org/download/'
regex: '/href="\/download\/(?<file>c-ares-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="\/download\/(?<file>c-ares-(?<version>[^"]+)\.tar\.gz)"/'
binary: hosted
metadata: metadata:
license-files: [LICENSE.md] license-files: [LICENSE.md]
headers@unix: headers@unix:

View File

@@ -5,7 +5,6 @@ libedit:
type: filelist type: filelist
url: 'https://thrysoee.dk/editline/' url: 'https://thrysoee.dk/editline/'
regex: '/href="(?<file>libedit-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>libedit-(?<version>[^"]+)\.tar\.gz)"/'
binary: hosted
metadata: metadata:
license-files: [COPYING] license-files: [COPYING]
license: BSD-3-Clause license: BSD-3-Clause

View File

@@ -16,3 +16,4 @@ libevent:
- libevent_core.a - libevent_core.a
- libevent_extra.a - libevent_extra.a
- libevent_openssl.a - libevent_openssl.a
- libevent_pthreads.a

View File

@@ -0,0 +1,23 @@
libgearman:
type: library
artifact:
source:
type: ghrel
repo: gearman/gearmand
match: gearmand-.+\.tar\.gz
prefer-stable: true
metadata:
license-files: [COPYING]
license: BSD-3-Clause
depends:
- libevent
- libuuid
suggests:
- libmemcached
headers@unix:
- libgearman-1.0/gearman.h
lang: cpp
pkg-configs:
- gearmand
static-libs@unix:
- libgearman.a

View File

@@ -9,5 +9,4 @@ libiconv-win:
license-files: [source/COPYING] license-files: [source/COPYING]
license: GPL-3.0-or-later license: GPL-3.0-or-later
static-libs@windows: static-libs@windows:
- libiconv.lib
- libiconv_a.lib - libiconv_a.lib

View File

@@ -5,7 +5,10 @@ libiconv:
type: filelist type: filelist
url: 'https://ftp.gnu.org/gnu/libiconv/' url: 'https://ftp.gnu.org/gnu/libiconv/'
regex: '/href="(?<file>libiconv-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>libiconv-(?<version>[^"]+)\.tar\.gz)"/'
binary: hosted source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/libiconv/'
regex: '/href="(?<file>libiconv-(?<version>[^"]+)\.tar\.gz)"/'
metadata: metadata:
license-files: [COPYING.LIB] license-files: [COPYING.LIB]
license: LGPL-2.0-or-later license: LGPL-2.0-or-later

View File

@@ -6,7 +6,6 @@ libpng:
repo: pnggroup/libpng repo: pnggroup/libpng
match: v1\.6\.\d+ match: v1\.6\.\d+
query: '?per_page=150' query: '?per_page=150'
binary: hosted
metadata: metadata:
license-files: [LICENSE] license-files: [LICENSE]
license: PNG license: PNG

View File

@@ -6,7 +6,6 @@ libsodium:
repo: jedisct1/libsodium repo: jedisct1/libsodium
match: 'libsodium-(?!1\.0\.21)\d+(\.\d+)*\.tar\.gz' match: 'libsodium-(?!1\.0\.21)\d+(\.\d+)*\.tar\.gz'
prefer-stable: true prefer-stable: true
binary: hosted
metadata: metadata:
license-files: [LICENSE] license-files: [LICENSE]
pkg-configs: pkg-configs:

View File

@@ -6,12 +6,13 @@ libssh2:
repo: libssh2/libssh2 repo: libssh2/libssh2
match: libssh2.+\.tar\.gz match: libssh2.+\.tar\.gz
prefer-stable: true prefer-stable: true
binary: hosted
metadata: metadata:
license-files: [COPYING] license-files: [COPYING]
license: BSD-3-Clause license: BSD-3-Clause
depends: depends@unix:
- openssl - openssl
depends@windows:
- zlib
headers: headers:
- libssh2.h - libssh2.h
- libssh2_publickey.h - libssh2_publickey.h

View File

@@ -5,7 +5,10 @@ libunistring:
type: filelist type: filelist
url: 'https://ftp.gnu.org/gnu/libunistring/' url: 'https://ftp.gnu.org/gnu/libunistring/'
regex: '/href="(?<file>libunistring-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>libunistring-(?<version>[^"]+)\.tar\.gz)"/'
binary: hosted source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/libunistring/'
regex: '/href="(?<file>libunistring-(?<version>[^"]+)\.tar\.gz)"/'
metadata: metadata:
license-files: [COPYING.LIB] license-files: [COPYING.LIB]
license: LGPL-3.0-or-later license: LGPL-3.0-or-later

View File

@@ -11,6 +11,10 @@ libzip:
license: BSD-3-Clause license: BSD-3-Clause
depends: depends:
- zlib - zlib
depends@windows:
- zlib
- bzip2
- xz
suggests: suggests:
- bzip2 - bzip2
- xz - xz

View File

@@ -4,13 +4,12 @@ openssl:
source: source:
type: ghrel type: ghrel
repo: openssl/openssl repo: openssl/openssl
match: openssl.+\.tar\.gz match: openssl-3.+\.tar\.gz
prefer-stable: true prefer-stable: true
source-mirror: source-mirror:
type: filelist type: filelist
url: 'https://www.openssl.org/source/' url: 'https://www.openssl.org/source/'
regex: '/href="(?<file>openssl-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>openssl-(?<version>3\.[^"]+)\.tar\.gz)"/'
binary: hosted
metadata: metadata:
license-files: [LICENSE.txt] license-files: [LICENSE.txt]
license: OpenSSL license: OpenSSL
@@ -18,7 +17,6 @@ openssl:
- zlib - zlib
depends@windows: depends@windows:
- zlib - zlib
- jom
headers: headers:
- openssl - openssl
static-libs@unix: static-libs@unix:
@@ -27,3 +25,7 @@ openssl:
static-libs@windows: static-libs@windows:
- libssl.lib - libssl.lib
- libcrypto.lib - libcrypto.lib
tools@windows:
- jom
- nasm
- strawberry-perl

View File

@@ -5,8 +5,6 @@ postgresql:
type: ghtagtar type: ghtagtar
repo: postgres/postgres repo: postgres/postgres
match: REL_18_\d+ match: REL_18_\d+
binary:
windows-x86_64: { type: url, url: 'https://get.enterprisedb.com/postgresql/postgresql-16.8-1-windows-x64-binaries.zip', extract: { lib/libpq.lib: '{build_root_path}/lib/libpq.lib', lib/libpgport.lib: '{build_root_path}/lib/libpgport.lib', lib/libpgcommon.lib: '{build_root_path}/lib/libpgcommon.lib', include/libpq-fe.h: '{build_root_path}/include/libpq-fe.h', include/postgres_ext.h: '{build_root_path}/include/postgres_ext.h', include/pg_config_ext.h: '{build_root_path}/include/pg_config_ext.h', include/libpq/libpq-fs.h: '{build_root_path}/include/libpq/libpq-fs.h' } }
metadata: metadata:
license-files: ['@/postgresql.txt'] license-files: ['@/postgresql.txt']
license: PostgreSQL license: PostgreSQL
@@ -16,6 +14,9 @@ postgresql:
- openssl - openssl
- zlib - zlib
- libedit - libedit
depends@windows:
- openssl
- zlib
suggests@unix: suggests@unix:
- icu - icu
- libxslt - libxslt
@@ -27,3 +28,9 @@ postgresql:
- libpq.lib - libpq.lib
- libpgport.lib - libpgport.lib
- libpgcommon.lib - libpgcommon.lib
tools@windows:
- python-win
- meson
- ninja
- winflexbison
- strawberry-perl

View File

@@ -3,7 +3,11 @@ readline:
artifact: artifact:
source: source:
type: filelist type: filelist
url: 'https://ftp.gnu.org/pub/gnu/readline/' url: 'https://ftp.gnu.org/gnu/readline/'
regex: '/href="(?<file>readline-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/readline/'
regex: '/href="(?<file>readline-(?<version>[^"]+)\.tar\.gz)"/' regex: '/href="(?<file>readline-(?<version>[^"]+)\.tar\.gz)"/'
metadata: metadata:
license-files: [COPYING] license-files: [COPYING]

View File

@@ -6,7 +6,6 @@ xz:
repo: tukaani-project/xz repo: tukaani-project/xz
match: xz.+\.tar\.xz match: xz.+\.tar\.xz
prefer-stable: true prefer-stable: true
binary: hosted
metadata: metadata:
license-files: [COPYING] license-files: [COPYING]
license: 0BSD license: 0BSD

View File

@@ -5,7 +5,6 @@ zlib:
type: ghrel type: ghrel
repo: madler/zlib repo: madler/zlib
match: zlib.+\.tar\.gz match: zlib.+\.tar\.gz
binary: hosted
metadata: metadata:
license-files: ['@/zlib.txt'] license-files: ['@/zlib.txt']
license: Zlib-Custom license: Zlib-Custom

View File

@@ -19,3 +19,4 @@ zstd:
- libzstd.a - libzstd.a
static-libs@windows: static-libs@windows:
- zstd.lib - zstd.lib
- libzstd.lib

View File

@@ -16,6 +16,8 @@ curl:
- zlib - zlib
- libssh2 - libssh2
- nghttp2 - nghttp2
- brotli
- zstd
suggests@unix: suggests@unix:
- libssh2 - libssh2
- brotli - brotli
@@ -27,9 +29,6 @@ curl:
- ldap - ldap
- idn2 - idn2
- krb5 - krb5
suggests@windows:
- brotli
- zstd
frameworks: frameworks:
- CoreFoundation - CoreFoundation
- CoreServices - CoreServices

View File

@@ -10,10 +10,8 @@ frankenphp:
license: MIT license: MIT
depends: depends:
- php-embed - php-embed
- go-xcaddy
depends@windows: depends@windows:
- php-embed - php-embed
- go-win
- pthreads4w - pthreads4w
suggests@unix: suggests@unix:
- brotli - brotli
@@ -24,3 +22,7 @@ frankenphp:
- frankenphp - frankenphp
static-bins@windows: static-bins@windows:
- frankenphp.exe - frankenphp.exe
tools:
- go-xcaddy
tools@windows:
- go-win

View File

@@ -0,0 +1,8 @@
msys2-build-essentials:
type: target
artifact:
binary: custom
env:
SPC_MSYS2_PATH: '{pkg_root_path}/msys2-build-essentials/msys64'
path@windows:
- '{pkg_root_path}/msys2-build-essentials/msys64/usr/bin'

View File

@@ -1,5 +0,0 @@
nasm:
type: target
artifact:
binary:
windows-x86_64: { type: url, url: 'https://dl.static-php.dev/static-php-cli/deps/nasm/nasm-2.16.01-win64.zip', extract: { nasm.exe: '{php_sdk_path}/bin/nasm.exe', ndisasm.exe: '{php_sdk_path}/bin/ndisasm.exe' } }

View File

@@ -1,5 +0,0 @@
php-sdk-binary-tools:
type: target
artifact:
binary:
windows-x86_64: { type: git, rev: master, url: 'https://github.com/php/php-sdk-binary-tools.git', extract: '{php_sdk_path}' }

View File

@@ -1,9 +0,0 @@
pkg-config:
type: target
artifact:
source: 'https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz'
binary:
linux-x86_64: { type: ghrel, repo: static-php/static-php-cli-hosted, match: pkg-config-x86_64-linux-musl-1.2.5.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }
linux-aarch64: { type: ghrel, repo: static-php/static-php-cli-hosted, match: pkg-config-aarch64-linux-musl-1.2.5.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }
macos-x86_64: { type: ghrel, repo: static-php/static-php-cli-hosted, match: pkg-config-x86_64-darwin.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }
macos-aarch64: { type: ghrel, repo: static-php/static-php-cli-hosted, match: pkg-config-aarch64-darwin.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }

View File

@@ -1,4 +0,0 @@
zig:
type: target
artifact:
binary: custom

View File

@@ -0,0 +1,9 @@
7za-win:
type: tool
artifact:
binary:
windows-x86_64: { type: url, url: 'https://dl.static-php.dev/v3/tools/7zip/7za.exe', extract: '{pkg_root_path}/bin/7za.exe' }
tool:
provides:
- 7za.exe
binary-subdir: bin

View File

@@ -1,10 +1,15 @@
go-win: go-win:
type: target type: tool
artifact: artifact:
binary: custom binary: custom
env: env:
GOROOT: '{pkg_root_path}/go-win' GOROOT: '{pkg_root_path}/go-win'
GOBIN: '{pkg_root_path}/go-win/bin' GOBIN: '{pkg_root_path}/go-win/bin'
GOPATH: '{pkg_root_path}/go-win/go' GOPATH: '{pkg_root_path}/go-win/gopath'
path@windows: path@windows:
- '{pkg_root_path}/go-win/bin' - '{pkg_root_path}/go-win/bin'
tool:
provides:
- go.exe
- gofmt.exe
binary-subdir: go-win/bin

View File

@@ -1,5 +1,5 @@
go-xcaddy: go-xcaddy:
type: target type: tool
artifact: artifact:
binary: custom binary: custom
env: env:
@@ -8,5 +8,8 @@ go-xcaddy:
GOPATH: '{pkg_root_path}/go-xcaddy/go' GOPATH: '{pkg_root_path}/go-xcaddy/go'
path@unix: path@unix:
- '{pkg_root_path}/go-xcaddy/bin' - '{pkg_root_path}/go-xcaddy/bin'
static-bins: tool:
- xcaddy provides:
- go
- gofmt
binary-subdir: go-xcaddy/bin

View File

@@ -1,7 +1,11 @@
jom: jom:
type: target type: tool
artifact: artifact:
binary: binary:
windows-x86_64: { type: url, url: 'https://download.qt.io/official_releases/jom/jom.zip', extract: '{pkg_root_path}/jom' } windows-x86_64: { type: url, url: 'https://download.qt.io/official_releases/jom/jom.zip', extract: '{pkg_root_path}/jom' }
path@windows: path@windows:
- '{pkg_root_path}\jom' - '{pkg_root_path}\jom'
tool:
provides:
- jom.exe
binary-subdir: jom

11
config/pkg/tool/meson.yml Normal file
View File

@@ -0,0 +1,11 @@
meson:
type: tool
artifact:
binary:
windows-x86_64: { type: url, url: 'https://github.com/mesonbuild/meson/releases/download/1.11.1/meson-1.11.1-py3-none-any.whl', extract: '{pkg_root_path}/meson/meson-1.11.1-py3-none-any.whl' }
path@windows:
- '{pkg_root_path}\meson'
tool:
provides:
- meson.bat
binary-subdir: meson

10
config/pkg/tool/nasm.yml Normal file
View File

@@ -0,0 +1,10 @@
nasm:
type: tool
artifact:
binary:
windows-x86_64: { type: url, url: 'https://dl.static-php.dev/static-php-cli/deps/nasm/nasm-2.16.01-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

View File

@@ -0,0 +1,9 @@
ninja:
type: tool
artifact:
binary:
windows-x86_64: { type: url, url: 'https://github.com/ninja-build/ninja/releases/download/v1.13.2/ninja-win.zip', extract: { ninja.exe: '{pkg_root_path}/bin/ninja.exe' } }
tool:
provides:
- ninja.exe
binary-subdir: bin

View File

@@ -0,0 +1,13 @@
pkg-config:
type: tool
artifact:
source: 'https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz'
binary:
linux-x86_64: { type: ghrel, repo: static-php/hosted, match: pkg-config-x86_64-linux-musl-1.2.5.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }
linux-aarch64: { type: ghrel, repo: static-php/hosted, match: pkg-config-aarch64-linux-musl-1.2.5.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }
macos-x86_64: { type: ghrel, repo: static-php/hosted, match: pkg-config-x86_64-darwin.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }
macos-aarch64: { type: ghrel, repo: static-php/hosted, match: pkg-config-aarch64-darwin.txz, extract: { bin/pkg-config: '{pkg_root_path}/bin/pkg-config' } }
tool:
provides:
- pkg-config
binary-subdir: bin

View File

@@ -1,8 +1,12 @@
protoc: protoc:
type: target type: tool
artifact: artifact:
binary: binary:
linux-x86_64: { type: ghrel, repo: protocolbuffers/protobuf, match: 'protoc-([0-9.]+)-linux-x86_64\.zip', extract: '{pkg_root_path}/protoc' } linux-x86_64: { type: ghrel, repo: protocolbuffers/protobuf, match: 'protoc-([0-9.]+)-linux-x86_64\.zip', extract: '{pkg_root_path}/protoc' }
linux-aarch64: { type: ghrel, repo: protocolbuffers/protobuf, match: 'protoc-([0-9.]+)-linux-aarch_64\.zip', extract: '{pkg_root_path}/protoc' } linux-aarch64: { type: ghrel, repo: protocolbuffers/protobuf, match: 'protoc-([0-9.]+)-linux-aarch_64\.zip', extract: '{pkg_root_path}/protoc' }
path: path:
- '{pkg_root_path}/protoc/bin' - '{pkg_root_path}/protoc/bin'
tool:
provides:
- protoc
binary-subdir: protoc/bin

View File

@@ -0,0 +1,8 @@
python-win:
type: tool
artifact:
binary: custom
tool:
provides:
- python.exe
binary-subdir: python-win/tools

View File

@@ -1,5 +1,9 @@
strawberry-perl: strawberry-perl:
type: target type: tool
artifact: artifact:
binary: binary:
windows-x86_64: { type: url, url: 'https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip', extract: '{pkg_root_path}/strawberry-perl' } windows-x86_64: { type: url, url: 'https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip', extract: '{pkg_root_path}/strawberry-perl' }
tool:
provides:
- perl.exe
binary-subdir: strawberry-perl/perl/bin

View File

@@ -1,7 +1,13 @@
upx: upx:
type: target type: tool
artifact: artifact:
binary: binary:
linux-x86_64: { type: ghrel, repo: upx/upx, match: upx.+-amd64_linux\.tar\.xz, extract: { upx: '{pkg_root_path}/bin/upx' } } linux-x86_64: { type: ghrel, repo: upx/upx, match: upx.+-amd64_linux\.tar\.xz, extract: { upx: '{pkg_root_path}/bin/upx' } }
linux-aarch64: { type: ghrel, repo: upx/upx, match: upx.+-arm64_linux\.tar\.xz, extract: { upx: '{pkg_root_path}/bin/upx' } } linux-aarch64: { type: ghrel, repo: upx/upx, match: upx.+-arm64_linux\.tar\.xz, extract: { upx: '{pkg_root_path}/bin/upx' } }
windows-x86_64: { type: ghrel, repo: upx/upx, match: upx.+-win64\.zip, extract: { upx.exe: '{pkg_root_path}/bin/upx.exe' } } windows-x86_64: { type: ghrel, repo: upx/upx, match: upx.+-win64\.zip, extract: { upx.exe: '{pkg_root_path}/bin/upx.exe' } }
tool:
provides:
- upx
provides@windows:
- upx.exe
binary-subdir: bin

View File

@@ -1,5 +1,9 @@
vswhere: vswhere:
type: target type: tool
artifact: artifact:
binary: binary:
windows-x86_64: { type: url, url: 'https://github.com/microsoft/vswhere/releases/download/3.1.7/vswhere.exe', extract: '{pkg_root_path}/bin/vswhere.exe' } windows-x86_64: { type: url, url: 'https://github.com/microsoft/vswhere/releases/download/3.1.7/vswhere.exe', extract: '{pkg_root_path}/bin/vswhere.exe' }
tool:
provides:
- vswhere.exe
binary-subdir: bin

View File

@@ -0,0 +1,12 @@
winflexbison:
type: tool
artifact:
binary:
windows-x86_64: { type: url, url: 'https://github.com/lexxmark/winflexbison/releases/download/v2.5.25/win_flex_bison-2.5.25.zip', extract: '{pkg_root_path}/winflexbison' }
path@windows:
- '{pkg_root_path}\winflexbison'
tool:
provides:
- win_flex.exe
- win_bison.exe
binary-subdir: winflexbison

14
config/pkg/tool/zig.yml Normal file
View File

@@ -0,0 +1,14 @@
zig:
type: tool
artifact:
binary: custom
tool:
provides:
- zig
- zig-cc
- zig-c++
- zig-ar
- zig-ld.lld
- zig-ranlib
- zig-objcopy
binary-subdir: zig

View File

@@ -8,6 +8,7 @@ export default {
{ text: 'First Build', link: '/en/guide/first-build' }, { text: 'First Build', link: '/en/guide/first-build' },
{ text: 'PHP SAPI Reference', link: '/en/guide/sapi-reference' }, { text: 'PHP SAPI Reference', link: '/en/guide/sapi-reference' },
{ text: 'CLI Reference', link: '/en/guide/cli-reference' }, { text: 'CLI Reference', link: '/en/guide/cli-reference' },
{ text: 'Migrating from v2', link: '/en/guide/migrate-from-v2' },
], ],
}, },
{ {
@@ -29,46 +30,42 @@ export default {
], ],
'/en/develop/': [ '/en/develop/': [
{ {
text: 'Developer Guide', text: 'Overview',
items: [ items: [
{ text: 'Get Started', link: '/en/develop/' }, { text: 'Get Started', link: '/en/develop/' },
{ text: 'Project Structure', link: '/en/develop/structure' }, { text: 'Project Structure', link: '/en/develop/structure' },
], ],
}, },
{ {
text: 'Concepts', text: 'Configuration Reference',
items: [ items: [
{ text: 'Registry', link: '/en/develop/registry' }, { text: 'Registry', link: '/en/develop/registry' },
{ text: 'Package Model', link: '/en/develop/package-model' }, { text: 'Package Model', link: '/en/develop/package-model' },
{ text: 'Artifact Model', link: '/en/develop/artifact-model' }, { text: 'Artifact Model', link: '/en/develop/artifact-model' },
{ text: 'Build Lifecycle', link: '/en/develop/build-lifecycle' },
],
},
{
text: 'Modules',
items: [
{ text: 'Doctor', link: '/en/develop/doctor-module' },
{ text: 'Source', link: '/en/develop/source-module' },
{ text: 'craft.yml', link: '/en/develop/craft-yml' }, { text: 'craft.yml', link: '/en/develop/craft-yml' },
],
},
{
text: 'Build System',
items: [
{ text: 'Build Lifecycle', link: '/en/develop/build-lifecycle' },
{ text: 'Compilation Tools', link: '/en/develop/system-build-tools' }, { text: 'Compilation Tools', link: '/en/develop/system-build-tools' },
], { text: 'Doctor', link: '/en/develop/doctor-module' },
}, { text: 'Performance Engineering', link: '/en/develop/performance' },
{
text: 'Vendor Mode',
items: [
{ text: 'Introduction', link: '/en/develop/vendor-mode/' },
{ text: 'Writing Package Classes', link: '/en/develop/vendor-mode/package-classes' },
{ text: 'Dependency Injection', link: '/en/develop/vendor-mode/dependency-injection' },
{ text: 'Annotations Reference', link: '/en/develop/vendor-mode/annotations' },
{ text: 'Lifecycle Hooks', link: '/en/develop/vendor-mode/lifecycle-hooks' },
],
},
{
text: 'Miscellaneous',
items: [
{ text: 'PHP Source Modifications', link: '/en/develop/php-src-changes' }, { text: 'PHP Source Modifications', link: '/en/develop/php-src-changes' },
], ],
}, },
{
text: 'Extending StaticPHP',
items: [
{ text: 'Introduction', link: '/en/develop/extending/' },
{ text: 'Writing Package Classes', link: '/en/develop/extending/package-classes' },
{ text: 'Annotations Reference', link: '/en/develop/extending/annotations' },
{ text: 'Lifecycle Hooks', link: '/en/develop/extending/lifecycle-hooks' },
{ text: 'Dependency Injection', link: '/en/develop/extending/dependency-injection' },
{ text: 'Custom Artifact', link: '/en/develop/extending/custom-artifact' },
],
},
], ],
'/en/contributing/': [ '/en/contributing/': [
{ {

View File

@@ -8,6 +8,7 @@ export default {
{ text: '第一次构建', link: '/zh/guide/first-build' }, { text: '第一次构建', link: '/zh/guide/first-build' },
{ text: 'PHP SAPI 构建参考', link: '/zh/guide/sapi-reference' }, { text: 'PHP SAPI 构建参考', link: '/zh/guide/sapi-reference' },
{ text: '命令行参考', link: '/zh/guide/cli-reference' }, { text: '命令行参考', link: '/zh/guide/cli-reference' },
{ text: '从 v2 迁移', link: '/zh/guide/migrate-from-v2' },
], ],
}, },
{ {
@@ -29,46 +30,42 @@ export default {
], ],
'/zh/develop/': [ '/zh/develop/': [
{ {
text: '开发者指南', text: '概览',
items: [ items: [
{ text: '开发简介', link: '/zh/develop/' }, { text: '开发简介', link: '/zh/develop/' },
{ text: '项目结构', link: '/zh/develop/structure' }, { text: '项目结构', link: '/zh/develop/structure' },
], ],
}, },
{ {
text: '核心概念', text: '配置参考',
items: [ items: [
{ text: 'Registry 与插件系统', link: '/zh/develop/registry' }, { text: 'Registry', link: '/zh/develop/registry' },
{ text: 'Package 模型', link: '/zh/develop/package-model' }, { text: 'Package 模型', link: '/zh/develop/package-model' },
{ text: 'Artifact 模型', link: '/zh/develop/artifact-model' }, { text: 'Artifact 模型', link: '/zh/develop/artifact-model' },
{ text: '构建生命周期', link: '/zh/develop/build-lifecycle' },
],
},
{
text: '模块',
items: [
{ text: 'Doctor 环境检查', link: '/zh/develop/doctor-module' },
{ text: '资源模块', link: '/zh/develop/source-module' },
{ text: 'craft.yml 配置', link: '/zh/develop/craft-yml' }, { text: 'craft.yml 配置', link: '/zh/develop/craft-yml' },
],
},
{
text: '构建系统',
items: [
{ text: '构建生命周期', link: '/zh/develop/build-lifecycle' },
{ text: '编译工具', link: '/zh/develop/system-build-tools' }, { text: '编译工具', link: '/zh/develop/system-build-tools' },
], { text: 'Doctor 环境检查', link: '/zh/develop/doctor-module' },
}, { text: '性能工程', link: '/zh/develop/performance' },
{
text: 'Vendor 模式',
items: [
{ text: '简介', link: '/zh/develop/vendor-mode/' },
{ text: '编写 Package 类', link: '/zh/develop/vendor-mode/package-classes' },
{ text: '依赖注入', link: '/zh/develop/vendor-mode/dependency-injection' },
{ text: '注解参考', link: '/zh/develop/vendor-mode/annotations' },
{ text: '生命周期 Hook', link: '/zh/develop/vendor-mode/lifecycle-hooks' },
],
},
{
text: '杂项',
items: [
{ text: '对 PHP 源码的修改', link: '/zh/develop/php-src-changes' }, { text: '对 PHP 源码的修改', link: '/zh/develop/php-src-changes' },
] ],
} },
{
text: '扩展 StaticPHP',
items: [
{ text: '简介', link: '/zh/develop/extending/' },
{ text: '编写 Package 类', link: '/zh/develop/extending/package-classes' },
{ text: '注解参考', link: '/zh/develop/extending/annotations' },
{ text: '生命周期 Hook', link: '/zh/develop/extending/lifecycle-hooks' },
{ text: '依赖注入', link: '/zh/develop/extending/dependency-injection' },
{ text: '自定义 Artifact', link: '/zh/develop/extending/custom-artifact' },
],
},
], ],
'/zh/contributing/': [ '/zh/contributing/': [
{ {

88
docs/deps-craft-yml.md Normal file
View File

@@ -0,0 +1,88 @@
```yaml
# PHP version to build (default: 8.5)
php-version: 8.5
# [REQUIRED] Static PHP extensions to build (list or comma-separated are both accepted)
extensions: bcmath,fileinfo,phar,zlib,sodium,posix,pcntl
# Extra packages to build (list or comma-separated are both accepted)
packages: [ ]
# [REQUIRED] Build SAPIs (list or comma-separated are both accepted)
# Available: cli, micro, fpm, embed, frankenphp, cgi, all
sapi: cli,micro,fpm
# Show full console output (default: false)
debug: false
# Before build, remove all old build files and sources (default: false)
clean-build: false
# Build options (same as `build:php` command options, all options are optional)
build-options:
# Build with all suggested packages (libraries and extensions) as well (default: false)
with-suggests: false
# Build extra shared extensions (comma-separated string)
build-shared: ""
# Build without stripping the binary (default: false)
no-strip: false
# Disable Opcache JIT (default: false)
disable-opcache-jit: false
# Enable thread-safe (ZTS) support (default: false)
enable-zts: false
# Disable smoke test, or for specific SAPIs comma-separated (default: false)
no-smoke-test: false
# PHP configuration options (same as --with-config-file-path)
with-config-file-path: ""
# PHP configuration options (same as --with-config-file-scan-dir)
with-config-file-scan-dir: ""
# Hardcoded INI options for cli and micro SAPI (e.g. "memory_limit=4G", list accepted)
with-hardcoded-ini: [ ]
# Pretend micro SAPI as cli SAPI to avoid some frameworks to limit the usage of micro SAPI
with-micro-fake-cli: false
# Additional patch point injection files (e.g. "path/to/patch.php", list accepted)
with-added-patch: [ ]
# Ignore micro extension tests (if you are using micro SAPI, default: false)
without-micro-ext-test: false
# UPX pack the binary (default: false)
with-upx-pack: false
# Set the micro.exe program icon (only for Windows, default: "")
with-micro-logo: ""
# Set micro SAPI as win32 mode, without this, micro SAPI will be compiled as a console application (only for Windows, default: false)
enable-micro-win32: false
# Path to a folder to be embedded in FrankenPHP (frankenphp SAPI only)
with-frankenphp-app: ""
# Build options for shared extensions (list or comma-separated are both accepted)
shared-extensions: [ ]
# Download options
download-options:
# Number of parallel downloads (default: 1)
parallel: 1
# Retries count for downloading sources (default: 0)
retry: 0
# Prefer source downloads when both source and binary are available (default: false)
prefer-source: false
# Prefer binary downloads when both source and binary are available (default: false)
prefer-binary: false
# Only download source artifacts, skip binary artifacts (default: false)
source-only: false
# Only download binary artifacts, skip source artifacts (default: false)
binary-only: false
# Ignore download cache for specified packages, comma separated (default: false)
ignore-cache: false
# Do not use alternative mirror download sources (default: false)
no-alt: false
# Do not clone shallowly repositories when downloading sources (default: false)
no-shallow-clone: false
# Use custom url for specified sources, format: "{source-name}:{url}" (e.g. "php-src:https://example.com/php-8.4.0.tar.gz")
custom-url: [ ]
# Use custom git repo for specified sources, format: "{source-name}:{branch}:{url}" (e.g. "php-src:master:https://github.com/php/php-src.git")
custom-git: [ ]
# Use custom local source path, format: "{source-name}:{path}" (e.g. "php-src:/path/to/php-src")
custom-local: [ ]
craft-options:
doctor: true
download: true
# Extra environment variables
extra-env:
# e.g. Use github token to avoid rate limit
GITHUB_TOKEN: your-github-token
```

View File

@@ -0,0 +1,451 @@
---
outline: 'deep'
---
# Artifact Model
An **Artifact** is a core concept in the StaticPHP build system. It represents a source archive or pre-built binary required to build a package. Each artifact describes where to download the file, how to extract it, and the resulting path layout. Packages reference one or more artifacts via the `artifact` field to obtain the source code or binaries they need.
## Defining an Artifact
Here is a minimal artifact object that points to a source archive (curl's source code):
```yaml
&:
source:
type: ghrel
repo: curl/curl
match: curl.+\.tar\.xz
prefer-stable: true
```
There are two ways to define an artifact and associate it with a package: **inline** (defined directly inside the package file) or **standalone** (defined in a separate file and referenced by name):
::: code-group
```yaml [Inline Artifact]
# This is a package declaration
curl:
type: target
artifact:
source:
type: ghrel
repo: curl/curl
match: curl.+\.tar\.xz
prefer-stable: true
```
```yaml [Standalone Artifact]
# This is a standalone artifact declaration, typically placed under config/artifact/
curl-src:
source:
type: ghrel
repo: curl/curl
match: curl.+\.tar\.xz
prefer-stable: true
```
```yaml [Package Referencing a Standalone Artifact]
# This is a package declaration
curl:
type: target
artifact: curl-src
```
:::
## Structure
An artifact has three top-level sections: `source`, `binary`, and `metadata`.
- `source` — the source code archive
- `binary` — pre-built binaries for specific platforms
- `metadata` — additional information such as license paths
Both `source` and `binary` accept either an inline source object or a reference to a standalone artifact by name (as shown above).
Full artifact object format:
```yaml
&:
source: {source-object} # (optional)
binary:
windows-x86_64: {source-object} # (optional)
linux-x86_64: {source-object} # (optional)
linux-aarch64: {source-object} # (optional)
macos-x86_64: {source-object} # (optional)
macos-aarch64: {source-object} # (optional)
metadata: # (optional)
license: "" # (optional) SPDX identifier
license-files: ["LICENSE"] # License files from the source directory
source-root: "subdir" # (optional) Use if the actual source root is inside a subdirectory
```
The basic format of a `source-object`:
```yaml
&:
type: "url" # Download type
# ...: Additional keys depend on the type; see below
extract: "path/to/dir" # (optional) Override extract path; default: SOURCE_PATH/{artifact-name}
```
## Metadata
The `metadata` field provides supplementary information about an artifact. It supports three subfields:
### license
- **Type**: `string` (optional)
- **Description**: The open-source license identifier for this package, following the [SPDX License Identifier](https://spdx.org/licenses/) format (e.g. `MIT`, `Apache-2.0`, `GPL-2.0-only`). This is used only for annotation in the license summary of the build output and has no effect on the build process itself.
```yaml
metadata:
license: MIT
```
### license-files
- **Type**: `string[]` (optional)
- **Description**: A list of paths to license files. After a successful build, the framework collects these files and places them in the `license/` directory of the build output. Two path formats are supported:
- **Relative paths** (e.g. `LICENSE`, `COPYING`, `gettext-runtime/intl/COPYING.LIB`): resolved relative to the artifact's source root directory.
- **`@/` prefix** (e.g. `@/bzip2.txt`): references a license file bundled with the framework itself, resolved to `src/globals/licenses/`. This is useful when the upstream source package does not include a license file (or the license text is embedded in other documentation) — in such cases, the license text can be placed in the built-in directory and referenced with `@/`.
The following built-in license files are currently available: `bzip2.txt`, `gmp.txt`, `icu.txt`, `postgresql.txt`, `sqlite.txt`, `zlib.txt`.
```yaml
# Common case: read from the source directory
metadata:
license-files: [LICENSE]
# Multiple license files
metadata:
license-files: [LICENSE, COPYING.LESSER]
# License file inside a subdirectory
metadata:
license-files: [gettext-runtime/intl/COPYING.LIB]
# Use a built-in license file when the source package does not include one
metadata:
license-files: ['@/bzip2.txt']
```
### source-root
- **Type**: `string` (optional)
- **Description**: When the actual source root is located inside a subdirectory of the extracted archive, this field specifies that subdirectory name. The framework will use this path as the working directory during the build instead of the top-level extraction directory.
```yaml
# krb5's actual source root is in the src/ subdirectory after extraction
metadata:
source-root: src
```
## Download Types
Artifacts support a variety of download types. Choose the one that best fits where the package is hosted.
| Type | Description |
|---|---|
| `url` | Download from a fixed URL. Supports `filename` (custom local filename) and `version` (manually set version). |
| `git` | Clone from a Git repository. Supports `rev` (branch/tag/commit), `submodules` (fetch submodules), and `extract`. |
| `ghrel` | Download from GitHub Release Assets by regex match. Requires `repo` (`owner/repo`) and `match` (filename regex). Supports `prefer-stable`. |
| `ghtar` | Download the source tarball from a GitHub Release (`/releases` API), matching by release name with `match`. Supports `prefer-stable`. |
| `ghtagtar` | Download the source tarball from a GitHub Tag (`/tags` API), matching by tag name with `match`. Supports `prefer-stable`. |
| `filelist` | Scrape an HTML page for a file listing, extract the filename and version via `regex`, then download the matched file. Suitable for official download index pages (e.g. ftp.gnu.org, openssl.org). |
| `pecl` | Download a PHP extension from [PECL](https://pecl.php.net) by `name`. Supports `prefer-stable`. |
| `pie` | Download a PHP extension from Packagist via the [PIE](https://github.com/php/pie) spec. Requires `repo` (`vendor/package`). |
| `php-release` | Download official PHP source from php.net. The version is controlled by the `--with-php` build argument. |
| `bitbuckettag` | Download source tarball from the latest Bitbucket tag. Requires `repo` (`workspace/repo`). |
| `local` | Use a pre-existing local directory as the source. Requires `dirname`. Useful for offline or development scenarios. |
| `custom` | Fully custom download logic implemented in a PHP class under `src/Package/Artifact/`. Optionally calls a specific method via `func`. |
## Type Reference
### url
Downloads a file from a fixed URL and extracts it automatically.
- **Class**: `StaticPHP\Artifact\Downloader\Type\Url`
- **Capabilities**: Basic download only; no automatic version update checking
- **Required**: `url` — the download address
- **Optional**:
- `filename` — local filename to save as (defaults to the last path segment of the URL)
- `version` — manually specify a version string (this type cannot auto-detect versions)
- `extract` — override the extraction directory (default: `SOURCE_PATH/{artifact-name}`)
```yaml
# sqlite downloaded from a fixed URL
artifact:
source:
type: url
url: 'https://www.sqlite.org/2024/sqlite-autoconf-3450200.tar.gz'
```
::: tip
Inside an artifact, a bare string starting with `http://` or `https://` is automatically expanded into a `type: url` object, so you can often just write the URL directly:
```yaml
artifact:
source: 'https://www.sqlite.org/2024/sqlite-autoconf-3450200.tar.gz'
```
:::
---
### git
Clones a Git repository as the source. Supports two modes: clone a specific branch/tag/commit (`rev`), or use a regex to match the highest-versioned branch from all remote refs (`regex`).
- **Class**: `StaticPHP\Artifact\Downloader\Type\Git`
- **Capabilities**: Version update checking (`CheckUpdateInterface`)
- **Required**: `url` — repository URL
- **Optional** (at least one of `rev` or `regex` is required):
- `rev` — clone a specific branch, tag, or commit hash
- `regex` — match remote branch names with a PCRE regex; the highest matching version is selected (must include a named capture group `(?P<version>...)`)
- `submodules` — whether to fetch git submodules (boolean)
- `extract` — override the clone target directory
```yaml
# php-glfw cloned from the master branch
artifact:
source:
type: git
url: 'https://github.com/mario-deluna/php-glfw'
rev: master
```
---
### ghrel
Downloads a file from GitHub Release Assets using a regex to match the asset filename. Best suited for repositories that upload pre-compiled packages or source archives as release assets.
- **Class**: `StaticPHP\Artifact\Downloader\Type\GitHubRelease`
- **Capabilities**: Version update checking (`CheckUpdateInterface`), integrity verification (`ValidatorInterface`, SHA256)
- **Required**:
- `repo` — repository path in `owner/repo` format
- `match` — PCRE regex (without delimiters) to match the asset filename, e.g. `openssl.+\.tar\.gz`
- **Optional**:
- `prefer-stable` — skip pre-release versions (default: `true`)
- `query` — query string appended to the API URL (e.g. `?per_page=5`)
- `extract` — override extraction directory
```yaml
# openssl downloaded from GitHub Release Assets
artifact:
source:
type: ghrel
repo: openssl/openssl
match: openssl.+\.tar\.gz
prefer-stable: true
```
---
### ghtar
Downloads the source tarball automatically generated by a GitHub Release (the "Source code" archive on the Release page). Unlike `ghrel` which downloads uploaded assets, `ghtar` uses the auto-generated tarball from the `/releases` API.
- **Class**: `StaticPHP\Artifact\Downloader\Type\GitHubTarball`
- **Capabilities**: Version update checking (`CheckUpdateInterface`)
- **Required**: `repo` — repository path in `owner/repo` format
- **Optional**:
- `prefer-stable` — skip pre-release versions (default: `true`)
- `match` — regex filter applied to `tarball_url` (if omitted, the first result is used)
- `query` — query string appended to the API URL
- `extract` — override extraction directory
```yaml
# librdkafka downloaded via GitHub Release tarball
artifact:
source:
type: ghtar
repo: confluentinc/librdkafka
```
---
### ghtagtar
Downloads a source tarball from a GitHub Tag via the `/tags` API. Functionally identical to `ghtar`, but targets the tags endpoint instead of releases — useful for repositories that tag releases without creating a formal GitHub Release.
- **Class**: `StaticPHP\Artifact\Downloader\Type\GitHubTarball` (shared with `ghtar`)
- **Capabilities**: Version update checking (`CheckUpdateInterface`)
- **Required**: `repo` — repository path in `owner/repo` format
- **Optional**:
- `prefer-stable` — skip pre-release versions (default: `true`)
- `match` — regex filter applied to tag names (if omitted, the latest tag is used)
- `query` — query string appended to the API URL
- `extract` — override extraction directory
```yaml
# brotli: only match v1.x tags
artifact:
source:
type: ghtagtar
repo: google/brotli
match: 'v1\.\d.*'
# libpng: match v1.6.x tags, with pagination
artifact:
source:
type: ghtagtar
repo: pnggroup/libpng
match: v1\.6\.\d+
query: '?per_page=150'
```
---
### filelist
Fetches an HTML page (typically an official download index), extracts filenames and version numbers from the page content using a regex, then automatically selects and downloads the highest stable version. Pre-release versions (those containing keywords like alpha, beta, rc, dev, nightly, or snapshot) are automatically skipped.
**Best for**: projects without GitHub that publish versioned archives on their own FTP or web index, such as `https://ftp.gnu.org/pub/gnu/ncurses/`.
- **Class**: `StaticPHP\Artifact\Downloader\Type\FileList`
- **Capabilities**: Version update checking (`CheckUpdateInterface`)
- **Required**:
- `url` — URL of the HTML page containing the file listing
- `regex` — PCRE regex to extract filenames and versions from the page (must include named capture groups `(?<file>...)` and `(?<version>...)`)
- **Optional**:
- `extract` — override extraction directory
- `download-url` — custom download URL template supporting `{file}` and `{version}` placeholders (by default the filename is appended directly to `url`)
```yaml
# ncurses: scrape latest version from the GNU FTP index
artifact:
source:
type: filelist
url: 'https://ftp.gnu.org/pub/gnu/ncurses/'
regex: '/href="(?<file>ncurses-(?<version>[^"]+)\.tar\.gz)"/'
# openssl: mirror source using filelist
artifact:
source-mirror:
type: filelist
url: 'https://www.openssl.org/source/'
regex: '/href="(?<file>openssl-(?<version>[^"]+)\.tar\.gz)"/'
```
---
### pecl
Downloads a PHP extension source package from [PECL](https://pecl.php.net) using the PECL REST API. The latest stable version is selected automatically.
- **Class**: `StaticPHP\Artifact\Downloader\Type\PECL`
- **Capabilities**: Version update checking (`CheckUpdateInterface`)
- **Required**: `name` — PECL package name (case-insensitive, e.g. `APCu`)
- **Optional**:
- `prefer-stable` — download stable releases only (default: `true`)
- `extract` — override extraction directory (default: `php-src/ext/{name}`)
```yaml
# APCu downloaded from PECL
artifact:
source:
type: pecl
name: APCu
```
---
### pie
Downloads a PHP extension from [Packagist](https://repo.packagist.org) following the [PIE](https://github.com/php/pie) specification. Package metadata is fetched via the Packagist `p2/` API, and the source archive is downloaded from the `dist` field.
- **Class**: `StaticPHP\Artifact\Downloader\Type\PIE`
- **Capabilities**: Version update checking (`CheckUpdateInterface`)
- **Required**: `repo` — Packagist package path in `vendor/package` format
- **Optional**:
- `extract` — override extraction directory
```yaml
# xdebug downloaded from Packagist
artifact:
source:
type: pie
repo: xdebug/xdebug
# php-spx with a custom extraction path
artifact:
source:
type: pie
repo: noisebynorthwest/php-spx
extract: php-src/ext/spx
```
---
### php-release
Downloads the official PHP source from [php.net](https://www.php.net). The version is determined at build time by the `--with-php` argument. SHA256 integrity is verified automatically. Passing `git` as the version will clone the `master` branch of `php/php-src` directly.
- **Class**: `StaticPHP\Artifact\Downloader\Type\PhpRelease`
- **Capabilities**: Version update checking (`CheckUpdateInterface`), integrity verification (`ValidatorInterface`, SHA256)
- **Required**: `domain` — download domain (e.g. `https://www.php.net` or a custom mirror)
- **Optional**:
- `extract` — override extraction directory
```yaml
# php-src with primary and mirror sources
artifact:
source:
type: php-release
domain: 'https://www.php.net'
source-mirror:
type: php-release
domain: 'https://phpmirror.static-php.dev'
```
---
### bitbuckettag
Downloads a source tarball from the latest tag of a Bitbucket repository via the Bitbucket REST API.
- **Class**: `StaticPHP\Artifact\Downloader\Type\BitBucketTag`
- **Capabilities**: Basic download only; no automatic version update checking
- **Required**: `repo` — repository path in `workspace/repo` format
- **Optional**:
- `extract` — override extraction directory
```yaml
artifact:
source:
type: bitbuckettag
repo: snappy-m-o/php-snappy
```
---
### local
Uses a pre-existing local directory as the source without performing any download. Useful for offline environments or local development where the source has already been placed on disk.
- **Class**: `StaticPHP\Artifact\Downloader\Type\LocalDir`
- **Capabilities**: Basic download only; no automatic version update checking
- **Required**: `dirname` — absolute path to the local directory
- **Optional**:
- `extract` — override extraction directory
```yaml
artifact:
source:
type: local
dirname: /path/to/local/source
```
---
### custom
Delegates download logic entirely to a PHP class under `src/Package/Artifact/`. If `func` is not specified, the class's default download method is called.
- **Optional**: `func` — name of the specific method to invoke in the implementation class
```yaml
artifact:
source:
type: custom
```

View File

@@ -4,4 +4,4 @@ aside: false
# craft.yml Configuration # craft.yml Configuration
<!-- TODO: Full reference for craft.yml fields. --> <!--@include: ../../deps-craft-yml.md-->

View File

@@ -0,0 +1,8 @@
# Custom Artifact
<!-- TODO: Guide for implementing a custom artifact download class under src/Package/Artifact/.
Explain when type: custom is appropriate (e.g. proprietary auth, non-standard archives).
Cover: class placement and naming, method signatures (default download method + func dispatch),
accessing source config fields, returning the extracted source path,
registering the class via spc.registry.yml artifact psr-4 mapping.
Provide an annotated code example. -->

View File

@@ -0,0 +1,8 @@
# Extending StaticPHP
<!-- TODO: Introduce the three extension strategies:
1. Contributing to core — edit src/Package/ and config/pkg/ directly.
2. External Registry — point SPC_REGISTRIES at a custom spc.registry.yml.
3. Vendor Mode — package classes + config as a Composer library (composer require).
Explain when to use each approach. Show a minimal end-to-end example:
one Library class, one config YAML, one spc.registry.yml, run spc. -->

View File

@@ -229,7 +229,7 @@ The following path placeholders are supported in string values of the `path`, `e
| `{working_dir}` | Working directory (project root) | | `{working_dir}` | Working directory (project root) |
| `{download_path}` | Download cache directory (`downloads/`) | | `{download_path}` | Download cache directory (`downloads/`) |
| `{source_path}` | Extracted source directory (`source/`) | | `{source_path}` | Extracted source directory (`source/`) |
| `{php_sdk_path}` | Windows PHP SDK directory | | `{spc_msys2_path}` | MSYS2 root directory (`msys64/`) — Windows only |
## target Package Type ## target Package Type

View File

@@ -0,0 +1,301 @@
# Performance Engineering
StaticPHP controls how PHP, its extensions, dependency libraries, and SAPIs are compiled. These choices can affect runtime throughput and latency, startup time, memory use, binary size, portability, and build time. They are related, but they are not the same metric: a smaller binary is not necessarily faster, and a slower build can still produce a faster program.
This page records the current v3 defaults, the optimization work already incorporated into the build, and the areas still being investigated. On Linux, libc and linkage form the first layer: the default fully static musl build and a dynamically linked glibc build have different portability, extension-loading, and performance characteristics. Compiler flags, PGO, and LTO form later layers of the same ongoing work.
This page does not claim that a StaticPHP binary is always faster than another PHP distribution. Results depend on the PHP version, CPU, toolchain, extension set, SAPI, libc, linkage, runtime configuration, and workload.
::: warning Current v3 status
The v3 branch does not currently expose stable `--pgi`, `--pgo`, or `--lto` CLI options. PGO orchestration and broader LTO compatibility remain active areas of investigation. The sections below describe their design, current constraints, and the direction of that work rather than a supported release recipe.
:::
## Linux Linkage and libc
StaticPHP's Linux default optimizes for a self-contained artifact, not for the highest possible score on every server workload. `config/env.ini` selects `${GNU_ARCH}-linux-musl`; with the default Zig toolchain this produces a fully static musl binary.
Current performance investigations distinguish three Linux targets:
| Target | libc and final linkage | Runtime requirements | Shared extensions / FFI | Current role |
|---|---|---|---|---|
| `native-native-musl` | musl, fully static | Linux kernel on a compatible CPU | No | Default portable single-file release |
| `native-native-musl -dynamic` | musl, dynamically linked | Compatible musl loader and libraries | Yes | Isolate static-versus-dynamic effects while keeping musl |
| `native-native-gnu.2.17` | glibc, dynamically linked with a 2.17 baseline | glibc 2.17 or newer | Yes | Broad GNU/Linux compatibility and a glibc performance baseline |
The architecture may replace either `native` component, for example `x86_64-linux-musl`. A `-gnu` target without an explicit version targets the selected/current glibc ABI instead of promising the 2.17 floor.
In this context, “dynamically linked PHP” does not mean every dependency is a system `.so`. StaticPHP still builds most selected third-party libraries and PHP extensions as static archives and links them into the PHP executable. The dynamic part is primarily the libc/runtime loader and any extensions explicitly requested through `--build-shared`. This differs from a conventional distribution PHP in which PHP and many dependencies are separate shared objects.
Likewise, a “static extension” and a “static libc” are independent choices. A glibc-dynamic PHP can contain all PHP extensions statically, while a musl-dynamic PHP can load selected `.so` extensions. Only a fully static musl target prevents runtime loading because no dynamic loader participates in the process.
### What Static versus Dynamic Linking Changes
Static and dynamic linkage mainly change startup work, relocation, symbol resolution, deployment, and library sharing. They do not automatically change PHP VM code generation.
- A fully static process does not start through a runtime dynamic loader or relocate a set of DSOs. This can help very short-lived CLI startup, but PHP initialization, extension startup, script parsing, and Opcache often cost more.
- A dynamic process pays loader and relocation costs at startup. Long-running FPM or FrankenPHP workers amortize this cost over many requests.
- Static linking gives the linker a larger closed world for section garbage collection and, when explicitly enabled, LTO. Static linking alone does not perform cross-object optimization.
- Dynamic glibc allows shared extensions, FFI, NSS integration, and replacement or security updates of runtime libraries without rebuilding PHP. A fully static artifact must be rebuilt to receive libc or embedded-library fixes.
- Shared-library code pages can be reused across different programs. Identical static PHP worker processes still share file-backed executable pages with one another, so “static means every worker duplicates all code in RAM” is not an accurate model.
StaticPHP's [performance testing issue #838](https://github.com/crazywhalecc/static-php-cli/issues/838) recorded one PHP 8.4 test in which static and dynamic builds stayed within about 1% in either direction across repeated runs. This is useful evidence that linkage alone may not dominate steady-state PHP execution, but it is not a universal result. Short CLI programs, many DSOs, different loaders, and I/O-heavy extensions can produce a different outcome.
### musl versus glibc Performance Surfaces
libc differences appear only when a workload reaches libc or behavior implemented around it. Pure PHP code spends much of its time in the Zend VM, Opcache, and Zend Memory Manager. PHP's own [Zend Memory Manager](https://wiki.php.net/internals/zend_mm) handles most request-bound allocations, so a microbenchmark dominated by PHP arrays and opcodes may expose less of the system allocator than a C extension or server runtime does.
| Workload area | Why the libc can matter | Main observed signals |
|---|---|---|
| CPU-bound PHP opcodes | Usually dominated by PHP VM, compiler, CPU target, and Opcache rather than libc | Same PHP/VM/compiler first; then change only libc/linkage |
| Persistent and native allocations | Persistent PHP allocations, C extensions, libraries, and server code can call libc allocation directly | throughput, allocation contention, RSS, fragmentation after a long soak |
| ZTS and FrankenPHP | Thread creation, TLS, mutexes, allocator contention, and per-thread caches differ | scaling by worker/thread count, p95/p99, RSS per thread |
| DNS and name services | Resolver strategy, NSS, `/etc/resolv.conf`, and caching differ | cached and uncached lookup latency, failure/failover latency, query volume |
| Locale, iconv, regex, and stdio | Implementations and supported behavior differ, not merely speed | correctness first, then throughput with production locale/data |
| Very short CLI commands | Loader/relocation and initialization are a larger fraction of total time | cold and warm wall time over many process launches |
| Long-running workers | Startup is amortized; allocator, threading, syscalls, and application behavior become more important | sustained throughput, tail latency, peak/steady RSS |
glibc's allocator provides per-thread caches and multiple arenas whose limits can be tuned; these can improve concurrent allocation throughput at the cost of retained memory. The [glibc allocation tunables](https://sourceware.org/glibc/manual/latest/html_node/Memory-Allocation-Tunables.html) therefore belong in a benchmark record. musl uses a different allocator and prioritizes low baseline overhead, bounded fragmentation, and static-linking suitability; neither design guarantees lower latency or RSS for every PHP application.
Resolver behavior can reverse an apparent “libc performance” result. The [musl functional-differences documentation](https://wiki.musl-libc.org/functional-differences-from-glibc.html) notes that musl queries configured nameservers in parallel, while traditional glibc behavior tries them sequentially. This can improve failover latency but increase DNS traffic. glibc also participates in configurable NSS modules. StaticPHP's DNS comparisons therefore keep resolver, cache state, search domains, and failure conditions consistent instead of treating resolver results as a CPU-only benchmark.
musl uses a much smaller default thread stack than typical glibc configurations. That can reduce reserved address space for thread-heavy programs but can also expose stack assumptions in extensions. It is a deployment and memory characteristic, not proof that one libc executes PHP opcodes faster.
### Current Comparison Model
A direct comparison between the default musl-static binary and a distribution glibc PHP changes libc, linker, compiler, flags, PHP configuration, extensions, dependency versions, and INI at once. It therefore cannot attribute the full difference to libc.
The project uses a controlled matrix with the same StaticPHP commit, PHP source, Zig version, flags, extensions, and SAPI. The three builds are represented by the following commands:
```bash
EXTENSIONS="bcmath,curl,openssl,opcache"
# A: default-style, fully static musl
SPC_TARGET=native-native-musl spc build:php "$EXTENSIONS" --build-cli
# B: dynamically linked musl; requires a musl runtime
SPC_TARGET="native-native-musl -dynamic" spc build:php "$EXTENSIONS" --build-cli
# C: dynamically linked glibc with a defined compatibility floor
SPC_TARGET=native-native-gnu.2.17 spc build:php "$EXTENSIONS" --build-cli
```
Each result is associated with its output, build manifest, `php -i`, and logs. The actual linkage is identified from the binary rather than inferred from its filename:
```bash
file buildroot/bin/php
readelf -l buildroot/bin/php | grep 'Requesting program interpreter'
```
A versus B estimates the linkage effect while holding musl constant. B versus C estimates libc/runtime effects with dynamic linkage on both sides. A distribution PHP remains useful as an external reference, but it is reported separately because its compiler and packaging configuration are different.
The current comparison set covers both no-op startup and real CLI scripts. FPM and FrankenPHP measurements separate worker warmup from sustained throughput and tail latency. libc-sensitive coverage includes allocation-heavy extension work, concurrent requests, DNS cache hit/miss/failure cases, file I/O, and long-running RSS/fragmentation behavior.
### Deployment Characteristics
- **musl static** is the StaticPHP default and represents the portable, self-contained deployment profile without shared extensions or FFI.
- **glibc dynamic** represents integration with a GNU/Linux runtime, including `.so` extensions, FFI, the host name-service stack, and workloads for which glibc produces better measured behavior.
- **musl dynamic** represents a musl-based runtime that still requires shared extensions. It also provides the middle point in the controlled comparison above, while giving up much of the default's single-file portability.
The default is designed to remain predictable and broadly deployable. The fastest target is workload-specific and continues to be evaluated against the actual CPU, PHP version, SAPI, and application behavior.
## Where Optimization Enters the v3 Build
The v3 build passes optimization settings through several layers:
1. `config/env.ini` supplies platform defaults. `config/env.custom.ini` or the process environment can override them.
2. `ToolchainManager` selects Zig on Linux, MSVC on Windows, and system, Homebrew, or MacPorts Clang on macOS by default. It initializes `CC`, `CXX`, `AR`, `RANLIB`, and `LD`.
3. Package executors and `Package::getLibExtra*Flags()` pass the default flags into Autoconf, CMake, and package-specific builds.
4. The PHP target passes its PHP-specific flags to both `./configure` and `make` on Unix. Static extensions compiled as part of php-src see the same compiler environment.
5. The FrankenPHP target links the PHP embed library through CGO. Its `CGO_CFLAGS` and `CGO_LDFLAGS` include the PHP and dependency-library flags, followed by Go and external-linker settings.
6. Deployment extracts separate debug information and strips Unix binaries by default. UPX is optional and affects size and startup behavior, not generated PHP code.
This propagation is intentionally broad, but it is not yet perfectly uniform. Packages with hand-written compiler commands or unusual upstream build systems may ignore part of the global flag set. Extending consistent C, C++, and linker-flag propagation across those adapters remains part of the optimization work.
## Current Default Configuration
The authoritative values are in `config/env.ini`. The following tables explain the current v3 defaults rather than replacing that file.
### Linux Compiler Defaults
These compiler defaults apply to the Linux targets above. The v3 toolchain manager selects Zig unless a maintainer-level `SPC_TOOLCHAIN` override is used.
| Variable | Current default | Purpose |
|---|---|---|
| `SPC_DEFAULT_CFLAGS` | `-fPIC -O3 -pipe -fno-plt -fno-semantic-interposition -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections` | Common C flags for libraries and PHP |
| `SPC_DEFAULT_CXXFLAGS` | `${SPC_DEFAULT_CFLAGS}` | Common C++ flags |
| `SPC_DEFAULT_LDFLAGS` | `-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -Wl,-z,noexecstack -Wl,--gc-sections` | Link hardening, dependency pruning, and unused-section removal |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g -fstack-protector-strong -fno-ident -fPIE -fvisibility=hidden -fvisibility-inlines-hidden ${SPC_DEFAULT_CFLAGS}` | PHP and in-tree extension C flags |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS` | The corresponding C++ form | PHP and in-tree extension C++ flags |
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS` | Empty | Additional PHP program linker flags |
The important performance-related defaults are:
- `-O3` favors runtime speed over compilation time and code size.
- `-fno-semantic-interposition` gives the optimizer more freedom for ELF symbols that cannot be interposed in the final program.
- `-fno-plt` avoids the traditional ELF procedure linkage table sequence where the toolchain can do so.
- `-ffunction-sections -fdata-sections` combined with `--gc-sections` lets the linker remove unused functions and data.
- Frame pointers and `-g` are deliberately retained during compilation for profiling and debugging. The deployed Unix binary is stripped by default, while separate debug information is written under `buildroot/debug/`.
The default PHP configure command also enables `--enable-re2c-cgoto`, disables unused SAPIs and shared PHP libraries, and builds only the requested extensions. These choices reduce unnecessary code; their runtime effect remains workload-dependent.
### macOS
macOS uses the native target and system Clang by default. v3 also supports the newer upstream LLVM distributions from Homebrew and MacPorts through `SPC_USE_LLVM=brew` and `SPC_USE_LLVM=port`. The Homebrew variant selects its `clang`, `clang++`, `llvm-ar`, and `llvm-ranlib` as one coherent toolchain rather than mixing them with the Apple-provided tools.
Homebrew LLVM is one of StaticPHP's current macOS performance paths. Its newer optimizer and code-generation backend can produce faster PHP binaries for some PHP versions and workloads, while also allowing the project to evaluate compiler improvements without waiting for Apple's system Clang release cycle. This is not a guaranteed uplift: PHP VM changes, CPU architecture, extensions, Opcache, and compiler flags can change the result. The project's [performance testing issue #838](https://github.com/crazywhalecc/static-php-cli/issues/838) shows that compiler and optimization-level effects are version- and workload-specific, while the later [v3 toolchain discussion](https://github.com/crazywhalecc/static-php-cli/issues/985#issuecomment-3860775962) records access to an up-to-date compiler as the motivation for the additional macOS LLVM path.
| Variable | Current default | Purpose |
|---|---|---|
| `SPC_DEFAULT_CFLAGS` | `--target=${MAC_ARCH}-apple-darwin -O3 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections` | Target selection, optimization, observability, and section splitting |
| `SPC_DEFAULT_CXXFLAGS` | `${SPC_DEFAULT_CFLAGS}` | Common C++ flags |
| `SPC_DEFAULT_LDFLAGS` | `-Wl,-dead_strip` | Removes unreachable Mach-O code and data |
| PHP extra flags | `-g`, stack protection, PIC/PIE, hidden visibility, and the defaults above | PHP and in-tree extension compilation |
### Windows
Windows uses MSVC and the static CRT patches described in [PHP Source Modifications](./php-src-changes). PHP's release configuration supplies its upstream optimization flags, while StaticPHP rewrites the final CLI, CGI, micro, and embed link rules to include `/LTCG`. Dependency CMake builds commonly use `/MT /Os /Ob1 /DNDEBUG`; individual packages may choose other release flags.
`--no-strip` preserves PDB/debug information while keeping `/O2` optimization in StaticPHP's rewritten build command. This is intentional: debug symbols and disabled optimization are separate concerns.
Windows FrankenPHP uses Clang/LLD for the CGO link. Some Windows libraries explicitly avoid `/GL` because MSVC LTCG objects are not accepted by this link path. `/LTCG` on the final link line therefore does not mean every input participates in whole-program optimization.
## Optimization Dimensions
StaticPHP treats performance as several related metrics rather than one score. Each dimension is affected by a different part of the build:
| Goal | Usually measured as | Main influencing controls |
|---|---|---|
| Request throughput | requests/s at fixed concurrency | SAPI mode, Opcache, worker model, PHP version, compiler and CPU target |
| Tail latency | p50/p95/p99 and error rate | workload, warmup, contention, worker count, JIT/Opcache, memory pressure |
| CLI execution | wall time, CPU time, peak RSS | startup cost, Opcache CLI setting, extension set, PHP/compiler version |
| Binary size | deployed bytes and debug-file bytes | extension set, section GC/dead stripping, symbol stripping, UPX |
| Portability | oldest CPU/OS/libc that runs the binary | `SPC_TARGET`, CPU ISA flags, static versus dynamic libc |
| Build speed | clean build wall time and peak disk/RAM | `SPC_CONCURRENCY`, toolchain, LTO/PGO, number of packages |
Comparable results keep the PHP version, commit, extensions, dependency versions, SAPI, ZTS/NTS mode, INI, target libc, compiler, CPU frequency policy, and workload constant.
## Runtime Optimization Surfaces
### 1. Reproducible Configuration Overrides
`config/env.custom.ini` provides the reproducible override layer while leaving `config/env.ini` as the project baseline. Values replace the complete default string rather than being appended automatically, so performance investigations preserve the baseline and isolate one changed factor.
For example, an x86-64-v3-specific investigation retains the Linux defaults and adds the ISA level:
```ini
[linux]
SPC_DEFAULT_CFLAGS="-fPIC -O3 -pipe -fno-plt -fno-semantic-interposition -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections -march=x86-64-v3"
SPC_DEFAULT_CXXFLAGS="${SPC_DEFAULT_CFLAGS}"
```
This may allow more vector and instruction selection, but the output no longer runs on CPUs below that ISA level. `-march=native` narrows portability further by coupling the result to the build host's CPU class.
PHP-only investigations are represented by `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` and its C++ counterpart rather than the global defaults. Individual-package investigations use snake-case variables such as `libaom_CFLAGS`, `libaom_CXXFLAGS`, and `libaom_LDFLAGS`. Package-specific flags are combined with the defaults when that package uses the common v3 executors.
### 2. Toolchain and PHP-Version Effects
The compiler can matter more than an individual optimization flag. [Issue #838](https://github.com/crazywhalecc/static-php-cli/issues/838) found large GCC-versus-Clang differences for some PHP 8.4 x86-64 tests because PHP's older VM can use GCC global register variables. That result is not universal: architecture, PHP version, VM implementation, and workload all matter, and PHP 8.5 changes the comparison with its newer VM.
Linux v3 defaults to Zig for target flexibility and reproducible libc selection, not because it is guaranteed to produce the fastest binary for every workload. The project's performance work compares this predictable baseline with native toolchains on deployment architectures. `SPC_TOOLCHAIN` remains an internal/maintainer control until a stable user-facing selector is documented.
### 3. SAPI, Thread Safety, and Runtime Settings
- FrankenPHP requires ZTS. CLI, FPM, CGI, micro, and embed remain NTS by default unless the selected SAPI or application requires thread safety.
- Historical tests in issue #838 observed small ZTS/NTS differences in that particular suite; the result remains specific to that workload.
- Including `ext-opcache` only builds the extension. Its performance characteristics also depend on runtime INI, including `opcache.enable_cli` for repeated CLI execution and application-specific JIT settings.
- `--disable-opcache-jit` changes build capability; it is not a substitute for runtime benchmarking. StaticPHP disables the undefined-behavior sanitizer where necessary when Opcache JIT is built on Linux.
- FrankenPHP performance also depends on worker versus classic mode, worker count, application boot behavior, Caddy modules, and Go runtime settings. Compiler flags cannot compensate for an unrepresentative server configuration.
### 4. Speed, Symbols, and Compression
The default Unix deployment extracts debug information, strips the runtime binary, and keeps the debug file separately. `--no-strip` represents the unstripped variant while current v3 keeps optimization enabled.
`--with-upx-pack` is a size optimization for Linux and Windows. It can change startup time, memory mapping, security-tool behavior, and debuggability, so the project treats it as a packaging tradeoff rather than a PHP execution optimization.
## Profile-Guided Optimization (PGO)
PGO builds an instrumented program, runs a representative workload to collect profiles, and recompiles using the observed branch, call, and value frequencies. The compiler can then improve code layout, inlining, and hot/cold decisions beyond static heuristics.
A complete PGO design contains three distinct phases:
1. **Instrumentation** builds the same PHP version, SAPI, extensions, dependencies, and target with profile-generation flags.
2. **Training** covers startup and important production paths at representative traffic mixes and concurrency, including a clean shutdown so raw profiles are flushed.
3. **Profile use** merges the raw profiles with the matching toolchain utility and rebuilds the identical source/configuration with profile-use flags.
Profiles are inputs to the build, not portable benchmark artifacts. Meaningful changes to PHP, extensions, dependencies, compiler version, flags, SAPI linkage, or workload invalidate them. A narrow or stale profile can improve the trained route while making untrained behavior worse.
### StaticPHP PGO Status
The experimental v3 design explores a dedicated PGO context and lifecycle hooks for CLI, CGI, FPM, micro, embed, and FrankenPHP. The concepts under evaluation include:
- instrument and profile-use phases, plus an optional context-sensitive second instrumentation phase;
- per-SAPI raw-profile directories and merged `.profdata` files;
- clean rebuilds when switching the active SAPI profile;
- shutdown patches for php-src and FrankenPHP, because the Go/CGO process does not reliably run the libc `atexit` path that normally flushes profiles;
- LLVM profile tooling and special linker/runtime handling for Zig, Clang, GCC, and FrankenPHP.
This work is not part of the stable v3 feature set. The current v3 tree contains some preparatory compatibility handling—for example, FrankenPHP detects manual `-fprofile*` C flags when using native GCC, suppresses missing-profile errors, and links `libgcov`—but complete training, merging, invalidation, and rebuilding orchestration remains under investigation.
A raw `-fprofile-generate` addition to the global defaults is not equivalent to this orchestration: it also instruments dependency libraries, changes link requirements, increases build and runtime cost, and may fail to flush usable data. For that reason, the current internal variables do not yet constitute a stable release workflow.
### FrankenPHP's Go PGO
[PR #1142](https://github.com/crazywhalecc/static-php-cli/pull/1142) added FrankenPHP's upstream `default.pgo` to the v2 xcaddy build when present. That profile optimizes the Go portion using a profile distributed with FrankenPHP. It does not train php-src, the PHP embed library, extensions, or CGO glue against your application.
A future end-to-end FrankenPHP PGO design may therefore contain two profile sources:
- FrankenPHP's upstream Go profile for the Go/Caddy code;
- application-specific compiler profiles for PHP, static extensions, and CGO-linked C code.
Their ownership and invalidation rules are separate concerns in the current design exploration.
## Link-Time Optimization (LTO)
LTO retains compiler intermediate representation until link time so the optimizer can work across translation units. Full LTO processes the combined program more aggressively; ThinLTO distributes more work and usually reduces memory and build-time cost.
Static linking does not automatically enable LTO. Conversely, adding `-flto` to only the final link is insufficient: relevant objects and archives must be produced with a compatible compiler, LTO mode, archiver, ranlib, and linker plugin.
Unix v3 does not enable LTO by default. Historical work made more archive commands respect the selected `AR`, but the project later removed default LTO work because compatibility fixes across dependency libraries were costly. In [issue #838](https://github.com/crazywhalecc/static-php-cli/issues/838), one test environment observed only about 2% runtime improvement while ThinLTO roughly doubled build time and full LTO increased it by about seven times. These are historical measurements on one setup, not a promised ratio.
Current Unix LTO investigations account for the following constraints:
1. Objects, archives, and the final link need one compatible LLVM/Clang or GCC toolchain family.
2. C, C++, PHP, and linker flags need the same mode, such as `-flto=thin`.
3. Limiting the initial scope to PHP and its in-tree extensions separates core results from dependency-library compatibility.
4. Archive contents and the final link log reveal whether LTO reached the intended objects; build completion alone does not.
5. SAPI and extension smoke tests, clean build time, binary size, throughput, and tail latency together describe the result.
LTO can expose package bugs, unsupported assembly, incompatible archives, symbol-export problems, and Go/CGO linker limitations. It can also increase code size or regress instruction-cache behavior. These compatibility and maintenance costs are why Unix LTO remains opt-in while its benefits continue to be evaluated.
## Performance Evidence and Reproducibility
StaticPHP performance investigations record enough context for another maintainer to reproduce the result:
- StaticPHP commit and registry/package revisions;
- PHP, FrankenPHP, Go, compiler, linker, and profile-tool versions;
- host and target OS, libc, architecture, and exact `SPC_TARGET`;
- CPU model, available instruction set, power/frequency policy, memory, and virtualization;
- complete extension and dependency set, ZTS/NTS, SAPI, static/dynamic linkage, and INI;
- all overridden environment variables and whether the binary was stripped or UPX-packed;
- workload source revision, dataset, route mix, concurrency, duration, warmup, and repetitions;
- median result, variation, p95/p99 where relevant, peak RSS, binary size, and clean build time.
The project alternates a baseline and one changed build on the same machine. Multiple repetitions and confidence intervals carry more weight than a single best run, and benchmark scripts remain part of the result alongside the raw measurements.
## History and Design Lessons
The following merged changes and issue discussions explain why the current defaults and cautions exist. Unmerged implementation work is represented only by its technical concepts elsewhere on this page.
| Record | Outcome and lesson |
|---|---|
| [Issue #385](https://github.com/crazywhalecc/static-php-cli/issues/385), performance degradation | A v2 `--no-strip` path also selected `-O0`, making one reported Laravel test about three times slower. This led to customizable PHP compiler variables and reinforced that debug symbols must not silently disable optimization. Current v3 keeps optimized flags with `--no-strip`. |
| [PR #806](https://github.com/crazywhalecc/static-php-cli/pull/806), Zig toolchain | Added target-flexible Zig support and documented its build/compatibility tradeoffs. Its discussion also contains the static/dynamic within-1% observation and early GCC/Clang/Zig comparisons. Toolchain choice is partly about portability and libc targeting, not only benchmark speed. |
| [Issue #838](https://github.com/crazywhalecc/static-php-cli/issues/838), performance testing | Established reproducible compiler, ZTS/NTS, Opcache, LTO, architecture, and PHP VM comparisons. Its results provide background for the `-O3` defaults but also show why conclusions must remain version- and workload-specific. The issue remains the main historical performance notebook. |
| [Issue #985](https://github.com/crazywhalecc/static-php-cli/issues/985), v3 toolchains | Recorded the decision to prefer predictable defaults while retaining performance-oriented alternatives. On Linux this means Zig alongside native GCC paths; on macOS the discussion also motivated access to a current upstream LLVM instead of being limited to Apple's compiler release cycle. |
| [Issue #862](https://github.com/crazywhalecc/static-php-cli/issues/862), `--pgo=script.php` proposal | Closed after concluding that one universal training script interface was unrealistic. PGO needs SAPI-aware lifecycle orchestration and user-owned representative training. |
| [PR #966](https://github.com/crazywhalecc/static-php-cli/pull/966), flags and stripping | Unified PHP make flags and improved separate debug stripping, helping decouple optimization from symbol handling. |
| [PR #1142](https://github.com/crazywhalecc/static-php-cli/pull/1142), FrankenPHP Go PGO | Added use of FrankenPHP's bundled Go `default.pgo` in the v2 build. This is distinct from application-trained PHP/CGO PGO. |
| [Issue #1088](https://github.com/crazywhalecc/static-php-cli/issues/1088), native intrinsics | Open design request for declaring CPU intrinsic levels across both libraries and PHP/extensions instead of managing every ISA flag manually. |
| [PR #1150](https://github.com/crazywhalecc/static-php-cli/pull/1150), macOS `-fno-plt` | Removed an ELF-only flag from the macOS defaults after it broke dependency configure checks. Optimization flags must be target-format aware. |
Most of this investigation and implementation has been led by [@henderkes](https://github.com/henderkes), with reviews, integration, platform fixes, and testing from the other StaticPHP contributors. The project continues to preserve workloads, raw results, and rationale as this work evolves; an individual compiler flag is only the last line of a much broader performance decision.

View File

@@ -9,7 +9,7 @@ StaticPHP ships with a built-in core registry (`core`) that contains all definit
External Registries can only define new packages that don't already exist in `core`; they cannot override or modify existing definitions in the core registry. Depending on your needs, there are three ways to extend or modify StaticPHP's build capabilities: External Registries can only define new packages that don't already exist in `core`; they cannot override or modify existing definitions in the core registry. Depending on your needs, there are three ways to extend or modify StaticPHP's build capabilities:
- **Modify the `core` registry**: Directly edit files under `src/Package` and `config/pkg/`, suitable when you want to contribute changes back to the StaticPHP mainline. Please read the [Contributing Guide](../contributing/) section on contributing new packages before submitting a PR. - **Modify the `core` registry**: Directly edit files under `src/Package` and `config/pkg/`, suitable when you want to contribute changes back to the StaticPHP mainline. Please read the [Contributing Guide](../contributing/) section on contributing new packages before submitting a PR.
- **Vendor Mode**: Package your custom packages as a standalone sub-registry distributed as a Composer package, suitable for private packages or scenarios where you want to reuse build logic as a library. See [Vendor Mode](./vendor-mode/) for details. - **Vendor Mode**: Package your custom packages as a standalone sub-registry distributed as a Composer package, suitable for private packages or scenarios where you want to reuse build logic as a library. See [Extending StaticPHP](./extending/) for details.
- **External Registry (`SPC_REGISTRIES`)**: Specify one or more external registry file paths via the `SPC_REGISTRIES` environment variable, which StaticPHP loads at startup. Suitable for temporary extensions or scenarios where packaging as a Composer package isn't practical, similar to external source mechanisms in other package managers. - **External Registry (`SPC_REGISTRIES`)**: Specify one or more external registry file paths via the `SPC_REGISTRIES` environment variable, which StaticPHP loads at startup. Suitable for temporary extensions or scenarios where packaging as a Composer package isn't practical, similar to external source mechanisms in other package managers.
## Registry Declaration File ## Registry Declaration File

View File

@@ -1,5 +0,0 @@
# Source Module
<!-- TODO: Migrate and update from v2 source-module.md.
Document v3 source types: url, ghrel, ghtar, ghtagtar, git, pecl (new), filelist, custom.
Per-package YAML source block format. Parallel download (--parallel N). -->

Some files were not shown because too many files have changed in this diff Show More