Compare commits

...

307 Commits

Author SHA1 Message Date
Marc
bf6216e59f Merge branch 'v3' into v3c/ext-fastchart-fastjson 2026-06-14 17:14:37 +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
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
crazywhalecc
c8dbd19ba2 Update latest docs 2026-04-23 14:11:44 +08:00
crazywhalecc
860ff38dae Update latest docs 2026-04-23 14:09:20 +08:00
Jerry Ma
3583cbe119 [v3] docs update: guide part (#1112) 2026-04-20 14:38:21 +08:00
crazywhalecc
13e2d0c969 Test deploy 2026-04-20 14:36:18 +08:00
crazywhalecc
8ff90dbb7d Add tag-based trigger 2026-04-20 14:27:35 +08:00
crazywhalecc
ecaebe0054 Add v2 version warning message 2026-04-20 14:19:39 +08:00
crazywhalecc
4a9087c35c Add netlify config 2026-04-20 14:08:52 +08:00
crazywhalecc
4abbc1c9ac Add gen-meta node option 2026-04-20 13:57:17 +08:00
crazywhalecc
c39155898a Add deps-map component and related command 2026-04-20 11:30:40 +08:00
crazywhalecc
05900c2d6c Remove patch point 2026-04-20 11:29:16 +08:00
crazywhalecc
69d4c16fcb Remove v2 docs 2026-04-19 18:08:35 +08:00
crazywhalecc
2045055591 Add GUIDE section for v3 docs 2026-04-19 18:01:56 +08:00
crazywhalecc
a348e838d7 Temp 2026-04-19 11:49:55 +08:00
crazywhalecc
a175c5862d Update index 2026-04-16 14:40:45 +08:00
crazywhalecc
e3b07d701e Remove unused fail download elements 2026-04-16 14:32:29 +08:00
crazywhalecc
3ff0742ff1 Enhance error handling in artifact downloading process 2026-04-16 14:08:06 +08:00
crazywhalecc
182f4ee0d0 Too new, too new 2026-04-13 12:56:02 +08:00
crazywhalecc
e22e615ba4 Upgrade actions/upload-artifact to v8 in build and test workflows 2026-04-13 12:27:52 +08:00
crazywhalecc
4413529d83 Update to v5 2026-04-13 11:30:03 +08:00
crazywhalecc
8e970f37dc Use versioned spc-bin and latest spc-bin 2026-04-13 11:26:11 +08:00
crazywhalecc
764894e930 Use dev:info instead of dev:extensions 2026-04-13 11:19:54 +08:00
crazywhalecc
f6f7b629e3 Disable v2 workflows temporarily 2026-04-13 11:17:55 +08:00
crazywhalecc
165372d17b Add OS support for Linux and Darwin in memcache and memcached configurations 2026-04-13 11:04:43 +08:00
crazywhalecc
7b66a88af1 Add dump-extensions command 2026-04-13 10:47:34 +08:00
crazywhalecc
3816b94a9b Update README.md 2026-04-13 10:21:10 +08:00
Jerry Ma
79d0cd4d19 Update src/Package/Extension/swow.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-13 08:24:04 +08:00
Jerry Ma
d37e23218b Update src/Package/Artifact/attr.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-13 08:23:33 +08:00
Jerry Ma
9fc2b64b6b Update src/Package/Library/gettext.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-13 08:21:04 +08:00
Jerry Ma
e8b8abea47 [3.0] Add frankenphp single executable build for Windows (#1099) 2026-04-13 00:35:55 +08:00
crazywhalecc
5d76e0b6cb phpstan 2026-04-12 23:20:38 +08:00
crazywhalecc
8cc5c82595 Add frankenphp build 2026-04-12 23:17:50 +08:00
crazywhalecc
4ddc137eae Add clang finder for Windows 2026-04-12 23:17:33 +08:00
crazywhalecc
f8ed1aa86e Fix unpassed env for windows cmd 2026-04-12 23:17:16 +08:00
crazywhalecc
f4918ba92c Add pthreadVC3.lib for frankenphp 2026-04-12 23:13:30 +08:00
crazywhalecc
ffc677e4b3 chore 2026-04-12 23:13:07 +08:00
crazywhalecc
0dbbf7abb2 Allow all packages has output 2026-04-12 23:12:26 +08:00
crazywhalecc
be034b756b Allow detect static-bins for windows 2026-04-12 23:12:11 +08:00
crazywhalecc
60d206cac0 Add go-win 2026-04-12 23:11:53 +08:00
Jerry Ma
2e2548d3de V3 refactor/forward port decimal (#1098) 2026-04-12 16:45:01 +08:00
crazywhalecc
75a7b21a6f Add patch to ensure ext/json MINIT runs before ext/decimal on Windows static builds 2026-04-12 16:05:20 +08:00
crazywhalecc
24231f793a Enhance debug flag handling in Makefile for release builds 2026-04-12 16:05:06 +08:00
crazywhalecc
d2f007d4c4 Forward-port #1095 2026-04-12 14:17:53 +08:00
Jerry Ma
c505430187 [3.0] Remove v2 code from v3 branch (#1096) 2026-04-12 13:42:44 +08:00
crazywhalecc
cc713069c2 Remove unnecessary TODO mark 2026-04-12 13:36:12 +08:00
crazywhalecc
6ee4759444 PhPStAN fIX 2026-04-12 13:32:43 +08:00
crazywhalecc
f327dda615 Update composer 2026-04-12 13:29:16 +08:00
crazywhalecc
4671be623b Add v3 artifact test 2026-04-12 13:29:06 +08:00
crazywhalecc
661b0fe887 Remove v2 from v3 branch 2026-04-12 13:19:59 +08:00
Jerry Ma
564e204111 V3 refactor/craft (#1091) 2026-04-12 13:02:32 +08:00
crazywhalecc
bca1fb5410 Remove TODO.md 2026-04-12 13:01:34 +08:00
crazywhalecc
e7bf945b96 Forward-port #1094 2026-04-12 12:51:16 +08:00
crazywhalecc
8ee9d134b3 Add craft command 2026-04-12 01:12:53 +08:00
crazywhalecc
6976e9db96 Allow callback for removeDir 2026-04-12 01:12:32 +08:00
crazywhalecc
39a975dc90 Just skip sleep 2026-04-12 01:12:17 +08:00
crazywhalecc
4f1ed70c96 Move out callback 2026-04-12 01:11:59 +08:00
crazywhalecc
626bdc3509 Allow fallback to builder options 2026-04-12 01:11:48 +08:00
Jerry Ma
ec399052ed [3.0] Refactor windows extensions (#1073) 2026-04-11 15:01:25 +08:00
crazywhalecc
ae7552f5a2 Forward-port #1087 2026-04-11 00:45:31 +08:00
crazywhalecc
25891a8648 Add ext-mongodb for Windows 2026-04-11 00:39:30 +08:00
crazywhalecc
e83a997d0c Add ext-zstd for Windows 2026-04-10 21:09:46 +08:00
crazywhalecc
58eb769ddf Forward-port #1086 2026-04-10 20:37:40 +08:00
crazywhalecc
e33aff18cc Forward-port #1082 2026-04-10 20:37:25 +08:00
crazywhalecc
9fb1dcbe93 Merge branch 'main' into v3-refactor/win-exts 2026-04-10 16:27:16 +08:00
crazywhalecc
869c9a06e3 Add ext-maxminddb and libmaxminddb support on Windows 2026-04-10 16:25:24 +08:00
crazywhalecc
4ba565b461 Add ext-uv and libuv support on Windows 2026-04-10 16:15:13 +08:00
crazywhalecc
6ef012e204 Add ext-uv and libuv support on Windows 2026-04-10 16:15:07 +08:00
Jerry Ma
6e354b4c6a fix: icu-static-win, ext-swoole, krb5, sqlsrv with grpc (#1087) 2026-04-10 16:14:02 +08:00
crazywhalecc
864fa9d0eb Fix #1083 2026-04-10 16:09:35 +08:00
crazywhalecc
db8520d8f0 Change config 2026-04-10 15:56:39 +08:00
crazywhalecc
3808457b52 Add lz4 and ext-lz4 for Windows 2026-04-10 15:51:18 +08:00
crazywhalecc
d29bd12bcc Remove old support config 2026-04-10 15:36:21 +08:00
crazywhalecc
f46240b55e Remove old support config 2026-04-10 15:35:22 +08:00
crazywhalecc
35b23a532f Add ext-snappy and snappy support on Windows 2026-04-10 15:34:55 +08:00
crazywhalecc
323f1ec00e Use correct ext-xz arg-type 2026-04-10 15:33:52 +08:00
crazywhalecc
6b29d92579 Disable ext-snmp, ext-ldap on Windows 2026-04-10 15:33:31 +08:00
crazywhalecc
1320a74460 Add ext-trader 2026-04-10 15:32:50 +08:00
crazywhalecc
4c07bcc95f Allow xz build statically 2026-04-10 15:05:15 +08:00
crazywhalecc
a27f5cc8be Oops 2026-04-10 14:26:03 +08:00
crazywhalecc
26a14bccbe Disable iouring on glibc build 2026-04-10 14:21:06 +08:00
crazywhalecc
cf48d131b3 Use direct link to official release instead of mirror 2026-04-10 13:52:21 +08:00
crazywhalecc
544fd15c0b test tmate 2026-04-10 13:26:14 +08:00
crazywhalecc
b04b079267 test 2026-04-10 13:22:06 +08:00
crazywhalecc
da49c056c9 test 2026-04-10 12:49:10 +08:00
crazywhalecc
7fc5dd428d Fix krb5 CI build by the way 2026-04-10 12:24:25 +08:00
crazywhalecc
6b62255091 test 2026-04-10 12:21:21 +08:00
crazywhalecc
9d777ca650 fix(icu_static_win): update paths for ICU static libraries and includes 2026-04-09 23:37:36 +08:00
crazywhalecc
7e2cfe2950 Merge remote-tracking branch 'origin/v3-refactor/win-exts' into v3-refactor/win-exts 2026-04-09 19:11:32 +08:00
Marc
20f95efcba fix(xlswriter): fix macOS build with modern Clang (C23) (#1086) 2026-04-09 14:30:42 +07:00
crazywhalecc
1d0ccdec45 Refactor micro:combine command on v3 2026-04-09 15:16:44 +08:00
Marc
fb7730989c Apply suggestions from code review
Co-authored-by: Marc <m@pyc.ac>
2026-04-09 14:00:10 +07:00
Kévin Dunglas
4d2036f20e fix(xlswriter): use -std=gnu17 to fix K&R declarations rejected by C23
The bundled minizip in xlswriter has K&R C function declarations in
multiple files (mztools.c, ioapi.c). Apple Clang (Xcode 16+) defaults
to C23, which removed K&R from the standard, causing hard build errors.

Instead of patching individual files, downgrade the C standard to gnu17
for the whole build when xlswriter is enabled. This covers all K&R
occurrences in the bundled code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 08:49:49 +02:00
crazywhalecc
cd14f6253b Add ext-zip for Windows 2026-04-09 12:25:12 +08:00
crazywhalecc
28e102100f Refactor support for sysv extensions and tidy for Windows 2026-04-09 12:17:00 +08:00
crazywhalecc
e25d95c26b Add ext-soap for Windows 2026-04-09 12:16:30 +08:00
crazywhalecc
b45e64ec16 Add ext-swow for Windows 2026-04-09 12:15:56 +08:00
crazywhalecc
1a027003b1 Add libxslt for Windows 2026-04-09 12:15:45 +08:00
crazywhalecc
6ed35eaa85 Add tidy for Windows 2026-04-09 12:15:30 +08:00
crazywhalecc
f1bd64ec06 Add tidy for Windows 2026-04-09 12:15:24 +08:00
crazywhalecc
2256f47aed Add ext-readline for windows 2026-04-09 10:51:12 +08:00
crazywhalecc
631549073a Add wineditline 2026-04-09 10:50:59 +08:00
crazywhalecc
3805c06caa Limit posix to unix-only 2026-04-09 10:41:10 +08:00
crazywhalecc
402e105b6b Add ext-pgsql, ext-pdo_pgsql 2026-04-09 10:40:55 +08:00
crazywhalecc
39f6a628da Limit password-argon2, pcntl to unix only 2026-04-09 10:40:34 +08:00
crazywhalecc
6630fbdce8 Fix sqlsrv build configuration for Windows by removing /sdl, /W4, and /WX flags 2026-04-09 10:40:03 +08:00
crazywhalecc
4d73af45c2 Add ext-odbc, ext-pdo_odbc for windows 2026-04-09 10:19:53 +08:00
crazywhalecc
ee2e887625 Add ext-gd, ext-iconv, ext-intl for windows 2026-04-09 10:19:12 +08:00
crazywhalecc
1bee20ac61 Add Windows build configuration support for opcache extension 2026-04-09 10:07:21 +08:00
crazywhalecc
9b8e0c794a Update getBinaryExtractConfig to handle 'hosted' cache extraction path 2026-04-09 10:07:09 +08:00
Kévin Dunglas
105f0328e6 fix(xlswriter): convert K&R function declaration to ANSI C in bundled minizip
The bundled minizip in xlswriter (pinned at libxlsxwriter RELEASE_1.0.0)
uses a K&R-style function declaration in mztools.c. Modern Clang on macOS
(defaulting to C23) rejects this as a hard syntax error since K&R
declarations were removed from the C23 standard.

The upstream libxlsxwriter has already fixed this on their main branch.
This patch applies the same fix during the build process.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 21:33:59 +02:00
crazywhalecc
2f260e4d09 Add moveFileOrDir method to handle cross-device file and directory moves 2026-04-08 22:14:55 +08:00
crazywhalecc
9182cf1e34 Add ext-glfw support for Windows 2026-04-08 22:14:37 +08:00
crazywhalecc
c207269998 Add php extension OS support checks to PackageInstaller 2026-04-08 22:13:59 +08:00
crazywhalecc
097af804a7 Add OS support checks to PhpExtensionPackage 2026-04-08 22:13:44 +08:00
crazywhalecc
a5a3a990bf Use legacy --enable-micro-win32 way to workaround 2026-04-08 22:13:21 +08:00
crazywhalecc
2bc0d05242 Add ext-gettext for Windows 2026-04-08 22:12:36 +08:00
crazywhalecc
d7ee946864 Add mpir for windows gmp support 2026-04-08 22:12:13 +08:00
crazywhalecc
9a0d239b58 Add gettext-win 2026-04-08 22:11:45 +08:00
crazywhalecc
ad631f9b6e Add pdo_sqlsrv, libyaml patches from v2 2026-04-08 14:49:38 +08:00
crazywhalecc
a3624b1510 Forward-port #1078, add sqlsrv and pdo_sqlsrv extension support for win 2026-04-08 11:22:45 +08:00
crazywhalecc
2a80d5a05d Merge branch 'main' into v3-refactor/win-exts 2026-04-08 11:17:40 +08:00
crazywhalecc
ee854eed41 Refactor extension configuration and improve Windows build support 2026-04-08 11:08:05 +08:00
crazywhalecc
921870eaea Update composer.lock 2026-04-08 10:08:24 +08:00
crazywhalecc
76fc5abfe7 Apply v2 patch for xlswriter 2026-04-08 10:04:07 +08:00
crazywhalecc
30c9a3f7a3 phpstan 2026-04-07 17:11:27 +08:00
crazywhalecc
baa21d6e94 Implement caching for config file parsing to improve performance 2026-04-07 17:10:33 +08:00
crazywhalecc
8e91e02806 Add suggestion for ext-yaml to improve YAML config file parsing 2026-04-07 17:09:05 +08:00
crazywhalecc
8fa27ae59c Enhance spc-debug script to support Xdebug profiling mode 2026-04-07 17:04:08 +08:00
crazywhalecc
028aa45c17 Merge remote-tracking branch 'origin/v3-refactor/win-exts' into v3-refactor/win-exts
# Conflicts:
#	src/Package/Target/php/windows.php
2026-04-06 13:16:55 +08:00
crazywhalecc
85b9f5e055 Refactor package resolution to filter only available build artifacts 2026-04-06 13:15:25 +08:00
crazywhalecc
f8d24e2b3a Refactor package resolution to filter only available build artifacts 2026-04-06 13:13:45 +08:00
crazywhalecc
991da260ba Enhance CMake configuration with dynamic linker flags for target packages 2026-04-06 13:06:25 +08:00
Jerry Ma
d411fac9a1 add framework coreservices to watcher library (#1082) 2026-04-04 20:05:47 +08:00
henderkes
ddb9e3e7e4 add framework coreservices to watcher library 2026-04-04 18:18:22 +07:00
Marc
fef361225a Fix file paths for SQLSRV (#1081) 2026-04-04 18:11:38 +07:00
crazywhalecc
0b2b1d51e1 Fix file paths for SQLSRV 2026-04-04 18:39:28 +08:00
Jerry Ma
820d77b8b2 [v2] Fix bunch of build bugs for Windows (#1078) 2026-04-03 19:58:57 +08:00
Jerry Ma
cd3eb3d41d Update src/globals/ext-tests/openssl.php 2026-04-03 19:53:23 +08:00
crazywhalecc
e5e6e26f67 Add cli, cgi, micro output 2026-04-03 17:42:30 +08:00
crazywhalecc
c671cfd13b Add cli, cgi, micro output 2026-04-03 16:33:57 +08:00
crazywhalecc
51b8a0cab5 Fix upx packing for win 2026-04-03 16:26:20 +08:00
crazywhalecc
fb8f8d4ef8 Correct openssl test script condition 2026-04-03 15:49:02 +08:00
crazywhalecc
1a476d0e80 Fix xcopy command in FileSystem.php by removing the 'v' flag 2026-04-03 15:34:56 +08:00
crazywhalecc
e5ad72214c Add brotli to curl (just workaround for transitive deps) 2026-04-03 14:18:13 +08:00
crazywhalecc
c339b900f8 Disable simd for libjpeg 2026-04-03 11:33:55 +08:00
crazywhalecc
852a0437bd Disable openssl for ngtcp2 temporarily 2026-04-03 11:03:22 +08:00
crazywhalecc
3ded9881e1 Disable openssl for ngtcp2 temporarily 2026-04-03 09:55:46 +08:00
crazywhalecc
08a6bf38a4 Remove zstd suggested libs for v2 (implemented on v3)
Anyway we don't support zstd windows build before
2026-04-02 18:04:03 +08:00
crazywhalecc
cae668a947 Remove zstd suggested libs for v2 (implemented on v3)
Anyway we don't support zstd windows build before
2026-04-02 17:59:15 +08:00
crazywhalecc
e592488d7a Add test 2026-04-02 16:34:51 +08:00
crazywhalecc
a7184d0411 Fix sqlsrv redundant cflags when building PHP 2026-04-02 16:32:43 +08:00
733 changed files with 14019 additions and 38507 deletions

View File

@@ -1,17 +1,12 @@
## What does this PR do?
<!-- Please describe the changes made in this PR here. -->
## Checklist before merging
> If your PR involves the changes mentioned below and completed the action, please tick the corresponding option.
> 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:
- If you modified `*.php` or `*.yml`, run them locally to ensure your changes are valid:
- [ ] `composer cs-fix`
- [ ] `composer analyse`
- [ ] `composer test`
- [ ] `bin/spc dev:sort-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.
- [ ] `bin/spc dev:lint-config`

View File

@@ -276,7 +276,7 @@ jobs:
# Upload debug logs
- if: ${{ inputs.debug && failure() }}
name: "Upload build logs on failure"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: spc-logs-${{ inputs.php-version }}-${{ inputs.os }}
path: log/*.log
@@ -284,7 +284,7 @@ jobs:
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
name: "Upload PHP cli SAPI"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: php-cli-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/bin/php
@@ -292,7 +292,7 @@ jobs:
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
name: "Upload PHP micro SAPI"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: php-micro-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/bin/micro.sfx
@@ -300,7 +300,7 @@ jobs:
# Upload fpm executable
- if: ${{ inputs.build-fpm == true }}
name: "Upload PHP fpm SAPI"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: php-fpm-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/bin/php-fpm
@@ -308,7 +308,7 @@ jobs:
# Upload frankenphp executable
- if: ${{ inputs['build-frankenphp'] == true }}
name: "Upload FrankenPHP SAPI"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: php-frankenphp-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/bin/frankenphp
@@ -316,17 +316,17 @@ jobs:
# Upload extensions metadata
- if: ${{ inputs['shared-extensions'] != '' }}
name: "Upload shared extensions"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: php-shared-ext-${{ inputs.php-version }}-${{ inputs.os }}
path: |
buildroot/modules/*.so
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
name: "Upload License Files"
with:
name: license-files-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/license/
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
name: "Upload Build Metadata"
with:
name: build-meta-${{ inputs.php-version }}-${{ inputs.os }}

View File

@@ -94,24 +94,24 @@ jobs:
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: php-${{ inputs.version }}
path: buildroot/bin/php.exe
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: micro-${{ inputs.version }}
path: buildroot/bin/micro.sfx
# Upload extensions metadata
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: build-meta
path: |

View File

@@ -2,9 +2,9 @@ name: Build SPC Binary
on:
push:
branches: [ "main" ]
branches: [ "main", "v3" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "v3" ]
paths:
- '.github/workflows/release-build.yml'
release:
@@ -38,9 +38,12 @@ jobs:
- name: "windows-x64"
os: "ubuntu-latest"
filename: "spc-windows-x64.exe"
permissions:
id-token: write
attestations: write
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
uses: "actions/checkout@v5"
- if: inputs.debug == true
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
@@ -60,7 +63,7 @@ jobs:
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: "Cache Composer dependencies"
uses: "actions/cache@v4"
uses: "actions/cache@v5"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-${{ env.PHP_VERSION }}-locked-composer-${{ hashFiles('**/composer.lock') }}"
@@ -101,10 +104,16 @@ jobs:
tar -czf ${{ matrix.operating-system.filename }} spc
# validate spc binary
if [ "${{ matrix.operating-system.name }}" == "linux-x86_64" ]; then
./spc dev:extensions
./spc dev:info php
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"
run: |
if [ "${{ matrix.operating-system.name }}" != "windows-x64" ]; then
@@ -120,20 +129,44 @@ jobs:
with:
files: dist/${{ matrix.operating-system.filename }}
- name: "Deploy to self-hosted OSS"
# only run this step if the repository is static-php-cli and the branch is main
if: github.repository == 'crazywhalecc/static-php-cli' && github.ref == 'refs/heads/main'
- 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: static-php-cli/spc-bin/nightly/
destination_dir: v3/spc-bin/nightly/
endpoint: ${{ secrets.AWS_ENDPOINT }}
- name: "Deploy to self-hosted OSS (latest)"
# 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/') }}
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/latest/
endpoint: ${{ secrets.AWS_ENDPOINT }}
- name: "Deploy to self-hosted OSS (versioned)"
# 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/') }}
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/${{ github.ref_name }}/
endpoint: ${{ secrets.AWS_ENDPOINT }}
- name: "Upload Artifact"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
path: spc${{ env.SUFFIX }}
name: spc-${{ matrix.operating-system.name }}${{ env.SUFFIX }}
@@ -156,10 +189,10 @@ jobs:
os: "windows-latest"
steps:
- name: "Checkout"
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: "Download Artifact"
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
env:
SUFFIX: ${{ matrix.operating-system.name == 'windows-x64' && '.exe' || '' }}
with:
@@ -172,4 +205,4 @@ jobs:
- name: "Run SPC Tests"
env:
SUFFIX: ${{ matrix.operating-system.name == 'windows-x64' && '.exe' || '' }}
run: ./spc${{ env.SUFFIX }} dev:extensions
run: ./spc${{ env.SUFFIX }} dev:info php

View File

@@ -1,9 +1,9 @@
name: Tests
name: v3 Tests
on:
pull_request:
branches: [ "main", "v3" ]
types: [ opened, synchronize, reopened ]
branches: [ "v3" ]
types: [ opened, synchronize, reopened, labeled, unlabeled ]
paths:
- 'src/**'
- 'config/**'
@@ -15,6 +15,10 @@ on:
permissions: read-all
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -103,112 +107,171 @@ jobs:
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: "Run PHPUnit Tests"
run: SPC_LIBC=glibc vendor/bin/phpunit tests/ --no-coverage
run: vendor/bin/phpunit tests/ --no-coverage
define-matrix:
name: "Define Matrix"
check-gate:
name: "Check: need-test label"
runs-on: ubuntu-latest
outputs:
php: ${{ steps.gendef.outputs.php }}
os: ${{ steps.gendef.outputs.os }}
enabled: ${{ steps.gate.outputs.enabled }}
steps:
- name: "Checkout"
uses: actions/checkout@v4
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
extensions: curl, openssl, mbstring
- name: Define
id: gendef
- name: Check label
id: gate
run: |
PHP_VERSIONS=$(php src/globals/test-extensions.php php)
OS_VERSIONS=$(php src/globals/test-extensions.php os)
echo 'php='"$PHP_VERSIONS" >> "$GITHUB_OUTPUT"
echo 'os='"$OS_VERSIONS" >> "$GITHUB_OUTPUT"
LABELS='${{ toJSON(github.event.pull_request.labels.*.name) }}'
if echo "$LABELS" | grep -q '"need-test"'; then
echo "enabled=true" >> "$GITHUB_OUTPUT"
else
echo "enabled=false" >> "$GITHUB_OUTPUT"
fi
build:
name: "Build PHP Test (PHP ${{ matrix.php }} ${{ matrix.os }})"
runs-on: ${{ matrix.os }}
needs: [define-matrix, php-cs-fixer, phpstan, phpunit]
timeout-minutes: 120
strategy:
matrix:
php: ${{ fromJSON(needs.define-matrix.outputs.php) }}
os: ${{ fromJSON(needs.define-matrix.outputs.os) }}
fail-fast: false
test-bot:
name: "Test Bot: analyze PR"
needs: check-gate
if: needs.check-gate.outputs.enabled == 'true'
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
outputs:
need_test: ${{ steps.bot.outputs.need_test }}
gen_matrix_args: ${{ steps.bot.outputs.gen_matrix_args }}
gen_matrix_args_tier2: ${{ steps.bot.outputs.gen_matrix_args_tier2 }}
php_versions: ${{ steps.bot.outputs.php_versions }}
tier2: ${{ steps.bot.outputs.tier2 }}
steps:
- name: "Update runner packages"
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
run: sudo apt-get update && sudo apt-get install -y ca-certificates
- uses: actions/checkout@v4
- name: "Checkout"
uses: actions/checkout@v4
- name: "Setup PHP"
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.4
tools: pecl, composer
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: 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"
COMMENT_BODY=$(echo "$BOT_JSON" | jq -r '.comment_body')
MARKER="<!-- spc-test-bot -->"
# Find existing bot comment id
EXISTING_ID=$(gh api \
repos/${{ github.repository }}/issues/${{ github.event.pull_request.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 ${{ github.event.pull_request.number }} \
--repo ${{ github.repository }} \
--body "$COMMENT_BODY"
fi
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 }} (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:
phpts: nts
- name: "Cache composer packages"
id: composer-cache
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-dev
# Cache downloaded source
- id: cache-download
uses: actions/cache@v4
with:
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-') }}
- name: Build
env:
SPC_USE_SUDO: "yes"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }}
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV
./bin/spc doctor --auto-fix
${{ matrix.combo.build-args }} --dl-with-php=${{ matrix.combo.php-version }}
- name: "Prepare UPX for Linux"
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: Setup upterm session
# if: ${{ failure() }}
# uses: owenthereal/action-upterm@v1
- 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/**') != '' }}
- name: Upload logs
if: always() && hashFiles('log/**') != ''
uses: actions/upload-artifact@v4
with:
name: build-logs-${{ matrix.os }}-${{ matrix.php }}
name: logs-${{ matrix.combo.os }}-${{ matrix.combo.arch }}-${{ matrix.combo.extension }}-php${{ matrix.combo.php-version }}
path: log
# - name: Setup tmate session
# if: ${{ failure() }}
# uses: mxschmitt/action-tmate@v3

View File

@@ -1,71 +1,68 @@
name: Docs Auto Deploy
on:
push:
branches:
- main
paths:
- 'config/**.json'
- 'docs/**'
- 'package.json'
- 'yarn.lock'
- '.github/workflows/vitepress-deploy.yml'
jobs:
build:
name: Deploy docs
runs-on: ubuntu-latest
if: github.repository == 'crazywhalecc/static-php-cli'
steps:
- name: Checkout master
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
cache: yarn
- run: yarn install --frozen-lockfile
- name: "Copy Config Files"
run: |
mkdir -p docs/.vitepress/config
cp -r config/* docs/.vitepress/config/
- name: "Install PHP for official runners"
uses: shivammathur/setup-php@v2
with:
coverage: none
tools: composer:v2
php-version: 8.4
ini-values: memory_limit=-1
extensions: curl, openssl, mbstring
- name: "Get Composer Cache Directory"
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: "Cache Composer dependencies"
uses: "actions/cache@v4"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-8.2-locked-composer-${{ hashFiles('**/composer.lock') }}"
restore-keys: |
php-8.2-locked-composer
- name: "Install Locked Dependencies"
run: "composer install --no-interaction --no-progress"
- name: "Generate Extension Support List"
run: |
bin/spc dev:gen-ext-docs > docs/extensions.md
bin/spc dev:gen-ext-dep-docs > docs/deps-map-ext.md
bin/spc dev:gen-lib-dep-docs > docs/deps-map-lib.md
- name: Build
run: yarn docs:build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/.vitepress/dist
name: Docs build test and auto deploy
on:
pull_request:
branches: [ "v3" ]
types: [ opened, synchronize, reopened ]
paths:
- 'config/**.yml'
- 'docs/**'
- 'package.json'
- 'yarn.lock'
- '.github/workflows/vitepress-deploy.yml'
push:
branches: [ "v3" ]
paths:
- 'config/**.yml'
- 'docs/**'
- 'package.json'
- 'yarn.lock'
- '.github/workflows/vitepress-deploy.yml'
jobs:
build:
name: Deploy docs
runs-on: ubuntu-latest
if: github.repository == 'crazywhalecc/static-php-cli'
steps:
- name: Checkout
uses: actions/checkout@v4
- uses: actions/setup-node@v3
- run: npm install
- name: "Install PHP for official runners"
uses: shivammathur/setup-php@v2
with:
coverage: none
tools: composer:v2
php-version: 8.4
ini-values: memory_limit=-1
extensions: curl, openssl, mbstring
- name: "Get Composer Cache Directory"
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: "Cache Composer dependencies"
uses: "actions/cache@v4"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-8.2-locked-composer-${{ hashFiles('**/composer.lock') }}"
restore-keys: |
php-8.2-locked-composer
- name: "Install Locked Dependencies"
run: "composer install --no-interaction --no-progress"
- name: 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
uses: peaceiris/actions-gh-pages@v3
if: github.event_name == 'push' && github.ref == 'refs/heads/v3'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: docs/.vitepress/dist

5
.gitignore vendored
View File

@@ -52,6 +52,8 @@ packlib_files.txt
/node_modules/
/docs/.vitepress/dist/
/docs/.vitepress/cache/
/docs/.vitepress/ext-data.json
/docs/.vitepress/deps-data.json
package-lock.json
pnpm-lock.yaml
@@ -67,3 +69,6 @@ spc.exe
# dumped files from StaticPHP v3
/dump-*.json
# config parse cache
/.spc.cache.php

View File

@@ -1,172 +1,156 @@
# StaticPHP
[![English readme](https://img.shields.io/badge/README-English%20%F0%9F%87%AC%F0%9F%87%A7-moccasin?style=flat-square)](README.md)
[![Chinese readme](https://img.shields.io/badge/README-%E4%B8%AD%E6%96%87%20%F0%9F%87%A8%F0%9F%87%B3-moccasin?style=flat-square)](README-zh.md)
[![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)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
**StaticPHP** 是一个用于构建静态编译可执行文件(包括 PHP、扩展等的强大工具。
## 特性
- :elephant: **支持多 PHP 版本** - 支持 PHP 8.1, 8.2, 8.3, 8.4, 8.5
- :handbag: **单文件 PHP 可执行文件** - 构建零依赖的独立 PHP
- :hamburger: **phpmicro 集成** - 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自解压可执行文件(将 PHP 二进制文件和源代码合并为一个文件)
- :pill: **智能环境检查器** - 自动构建环境检查器,具备自动修复功能
- :zap: **跨平台支持** - 支持 Linux、macOS、FreeBSD 和 Windows
- :wrench: **可配置补丁** - 可自定义的源代码补丁系统
- :books: **智能依赖管理** - 自动处理构建依赖
- 📦 **自包含工具** - 提供使用 [box](https://github.com/box-project/box) 构建的 `spc` 可执行文件
- :fire: **广泛的扩展支持** - 支持 75+ 流行 [扩展](https://static-php.dev/zh/guide/extensions.html)
- :floppy_disk: **UPX 压缩** - 减小二进制文件大小 30-50%(仅 Linux/Windows
**单文件独立 php-cli**
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
**使用 phpmicro 将 PHP 代码与 PHP 解释器结合:**
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
## 快速开始
### 1. 下载 spc 二进制文件
```bash
# Linux x86_64
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
# Linux aarch64
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
# Windows (x86_64, win10 build 17063 或更高版本,请先安装 VS2022)
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
```
对于 macOS 和 Linux请先添加执行权限
```bash
chmod +x ./spc
```
### 2. 构建静态 PHP
首先,创建一个 `craft.yml` 文件,并从 [扩展列表](https://static-php.dev/zh/guide/extensions.html) 或 [命令生成器](https://static-php.dev/zh/guide/cli-generator.html) 中指定要包含的扩展:
```yml
# PHP 版本支持8.1, 8.2, 8.3, 8.4, 8.5
php-version: 8.4
# 在此处放置您的扩展列表
extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
sapi:
- cli
- micro
- fpm
download-options:
prefer-pre-built: true
```
运行命令:
```bash
./spc craft
# 输出完整控制台日志
./spc craft --debug
```
### 3. 静态 PHP 使用
现在您可以将 StaticPHP 构建的二进制文件复制到另一台机器上,无需依赖即可运行:
```
# php-cli
buildroot/bin/php -v
# phpmicro
echo '<?php echo "Hello world!\n";' > a.php
./spc micro:combine a.php -O my-app
./my-app
# php-fpm
buildroot/bin/php-fpm -v
```
## 文档
当前 README 包含基本用法。有关 StaticPHP 的所有功能,
请访问 <https://static-php.dev>。
## 直接下载
如果您不想构建或想先测试,可以从 [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml) 下载示例预编译工件,或从自托管服务器下载。
以下是几个具有不同扩展组合的预编译静态 PHP 二进制文件,
您可以根据需要直接下载。
| 组合名称 | 扩展数量 | 系统 | 备注 |
|----------------------------------------------------------------------|----------------------------------------------------------------------------|--------------|--------------------|
| [common](https://dl.static-php.dev/static-php-cli/common/) | [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) | Linux, macOS | 二进制文件大小约为 7.5MB |
| [bulk](https://dl.static-php.dev/static-php-cli/bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | 二进制文件大小约为 25MB |
| [gnu-bulk](https://dl.static-php.dev/static-php-cli/gnu-bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | 使用 glibc 的 bulk 组合 |
| [minimal](https://dl.static-php.dev/static-php-cli/minimal/) | [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) | Linux, macOS | 二进制文件大小约为 3MB |
| [spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/) | [5](https://dl.static-php.dev/static-php-cli/windows/spc-min/README.txt) | Windows | 二进制文件大小约为 3MB |
| [spc-max](https://dl.static-php.dev/static-php-cli/windows/spc-max/) | [40+](https://dl.static-php.dev/static-php-cli/windows/spc-max/README.txt) | Windows | 二进制文件大小约为 8.5MB |
> Linux 和 Windows 支持对二进制文件进行 UPX 压缩,可以将二进制文件大小减少 30% 到 50%。
> macOS 不支持 UPX 压缩,因此 mac 的预构建二进制文件大小较大
### 在线构建(使用 GitHub Actions
上方直接下载的二进制不能满足需求时,可使用 GitHub Action 可以轻松构建静态编译的 PHP
同时自行定义要编译的扩展
1. Fork 本项目
2. 进入项目的 Actions 并选择 `CI`
3. 选择 `Run workflow`,填入您要编译的 PHP 版本、目标类型和扩展列表。(扩展用逗号分隔,例如 `bcmath,curl,mbstring`
4. 等待一段时间后,进入相应的任务并获取 `Artifacts`
如果您启用 `debug`,构建时将输出所有日志,包括编译日志,以便故障排除。
## 贡献
如果您需要的扩展缺失,可以创建 issue。
如果您熟悉本项目,也欢迎发起 pull request
如果您想贡献文档,请直接编辑 `docs/` 目录。
现在有一个 [static-php](https://github.com/static-php) 组织,用于存储与项目相关的仓库
## 赞助本项目
您可以从 [GitHub Sponsor](https://github.com/crazywhalecc) 赞助我或我的项目。您捐赠的一部分将用于维护 **static-php.dev** 服务器。
**特别感谢以下赞助商**
<a href="https://beyondco.de/"><img src="/docs/public/images/beyondcode-seeklogo.png" width="300" alt="Beyond Code Logo" /></a>
<a href="https://nativephp.com/"><img src="/docs/public/images/nativephp-logo.svg" width="300" alt="NativePHP Logo" /></a>
## 开源许可证
本项目本身基于 MIT 许可证,
一些新添加的扩展和依赖可能来自其他项目,
这些代码文件的头部也会给出额外的许可证和作者说明。
这些是类似的项目:
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
本项目使用了 [dixyes/lwmbs](https://github.com/dixyes/lwmbs) 的一些代码,例如 Windows 静态构建目标和 libiconv 支持。
lwmbs 基于 [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2) 许可证。
由于本项目的特殊性,
项目编译过程中会使用许多其他开源项目,如 curl 和 protobuf
它们都有自己的开源许可证。
请在编译后使用 `bin/spc dump-license` 命令导出项目中使用的开源许可证,
并遵守相应项目的 LICENSE。
# StaticPHP
[![Chinese readme](https://img.shields.io/badge/README-%E4%B8%AD%E6%96%87%20%F0%9F%87%A8%F0%9F%87%B3-moccasin?style=flat-square)](README-zh.md)
[![English readme](https://img.shields.io/badge/README-English%20%F0%9F%87%AC%F0%9F%87%A7-moccasin?style=flat-square)](README.md)
[![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)
[![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、扩展等。
> [!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
- :handbag: 构建零依赖的单文件 PHP 可执行程序
- :hamburger: 构建 **[phpmicro](https://github.com/static-php/phpmicro)** 自解压可执行文件(将 PHP 二进制和源码合并为单个文件)
- :pill: 自动构建环境检查器,支持自动修复
- :zap: 支持 `Linux``macOS``Windows`
- :wrench: 通过 vendor 模式和自定义注册表实现便捷扩展
- :books: 智能依赖管理
- 📦 自包含 `spc` 可执行文件,便于自安装
- :fire: 支持 100+ 热门 [PHP 扩展](https://static-php.dev/en/guide/extensions.html)
- :floppy_disk: 支持 UPX 压缩(二进制体积可缩小 30-50%
**单文件独立 php-cli**
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
**使用 phpmicro 将 PHP 代码与 PHP 解释器结合:**
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
## 快速开始
### 1. 下载 spc 二进制
```bash
# For Linux x86_64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
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)
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/v3/spc-bin/nightly/spc-windows-x64.exe
```
对于 macOS 和 Linux请先添加可执行权限
```bash
chmod +x ./spc
```
### 2. 构建静态 PHP
首先,创建 `craft.yml` 文件,并从 [扩展列表](https://static-php.dev/en/guide/extensions.html) 或 [命令生成器](https://static-php.dev/en/guide/cli-generator.html) 指定要包含的扩展:
```yml
# PHP version support: 8.1, 8.2, 8.3, 8.4, 8.5
php-version: 8.5
# Put your extension list here
extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
sapi:
- cli
- micro
download-options:
parallel: 10
```
运行命令:
```bash
./spc craft
# 输出完整控制台日志
./spc craft -vvv
```
### 3. 静态 PHP 使用
现在你可以将 StaticPHP 构建的二进制复制到另一台机器并在无依赖环境下运行:
```
# php-cli
buildroot/bin/php -v
# phpmicro
echo '<?php echo "Hello world!\n";' > a.php
./spc micro:combine a.php -O my-app
./my-app
```
## 文档
当前 README 包含基础用法。有关 StaticPHP 的完整功能集,
请访问 <https://static-php.dev>。
## 直接下载
如果你暂时不想构建,或只想先测试,可以从 [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml) 下载示例预编译产物,或从自托管服务器下载。
我们为每个 PHP 版本提供 2 种扩展集合:
- **gigantic**:尽可能包含更多扩展,二进制大小约 100-150MB。
- **base**:仅包含 StaticPHP 自身使用的少量扩展,二进制大小约 10MB。
> WIP
### 在线构建(使用 GitHub Actions
当上方直接下载的二进制无法满足你的需求时,
你可以使用 GitHub Actions 轻松构建静态编译的 PHP
并同时自定义要编译的扩展列表
1. Fork 此仓库。
2. 进入项目的 Actions 并选择 `CI`
3. 选择 `Run workflow`,填写你要编译的 PHP 版本、目标类型和扩展列表。(扩展用逗号分隔,例如 `bcmath,curl,mbstring`
4. 等待工作流执行完成后,进入对应运行记录并下载 `Artifacts`
如果你启用 `debug`,构建时将输出所有日志,包括编译日志,便于排查问题
> 我们也计划在未来提供可复用的 GitHub Actions 工作流,
> 这样你无需 fork 本项目,也能在自己的仓库中轻松构建 static PHP
## 贡献
如果你需要的扩展缺失,可以创建 issue。
如果你熟悉本项目,也欢迎发起 pull request。
如果你想贡献文档,请直接编辑 `docs/`
## 赞助本项目
你可以通过 [GitHub Sponsor](https://github.com/crazywhalecc) 赞助我或我的项目。你捐赠的一部分将用于维护 **static-php.dev** 服务器
**特别感谢以下赞助商:**
<a href="https://beyondco.de/"><img src="/docs/public/images/beyondcode-seeklogo.png" width="300" alt="Beyond Code Logo" /></a>
<a href="https://nativephp.com/"><img src="/docs/public/images/nativephp-logo.svg" width="300" alt="NativePHP Logo" /></a>
## 开源许可证
本项目本身采用 MIT 许可证。
一些新添加的扩展和依赖可能来自其他项目。
这些源码文件头部也可能包含额外的 LICENSE 和 AUTHOR 信息。
请在编译后使用 `bin/spc dump-license` 命令导出项目中使用的开源许可证,
并遵守对应项目的 LICENSE。

View File

@@ -5,20 +5,26 @@
[![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)
[![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.
> [!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
- :elephant: Support multiple PHP versions - PHP 8.1, 8.2, 8.3, 8.4, 8.5
- :handbag: Build single-file PHP executable with zero dependencies
- :hamburger:Build **[phpmicro](https://github.com/dixyes/phpmicro)** self-extracting executables (combines PHP binary and source code into one file)
- :hamburger: Build **[phpmicro](https://github.com/static-php/phpmicro)** self-extracting executables (combines PHP binary and source code into one file)
- :pill: Automatic build environment checker with auto-fix capabilities
- :zap: `Linux`, `macOS`, `FreeBSD`, `Windows` support
- :wrench: Configurable source code patching
- :zap: `Linux`, `macOS`, `Windows` support
- :wrench: Easy to extend with vendor mode and custom registries
- :books: Intelligent dependency management
- 📦 Self-contained `spc` executable (built with [box](https://github.com/box-project/box))
- :fire: Support 100+ popular [extensions](https://static-php.dev/en/guide/extensions.html)
- 📦 Self-contained `spc` executable for easy self-installation
- :fire: Support 100+ popular [PHP extensions](https://static-php.dev/en/guide/extensions.html)
- :floppy_disk: UPX compression support (reduces binary size by 30-50%)
**Single-file standalone php-cli:**
@@ -35,15 +41,15 @@
```bash
# For Linux x86_64
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
curl -fsSL -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/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)
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/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:
@@ -58,15 +64,14 @@ First, create a `craft.yml` file and specify which extensions you want to includ
```yml
# PHP version support: 8.1, 8.2, 8.3, 8.4, 8.5
php-version: 8.4
php-version: 8.5
# Put your extension list here
extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
sapi:
- cli
- micro
- fpm
download-options:
prefer-pre-built: true
parallel: 10
```
Run command:
@@ -75,7 +80,7 @@ Run command:
./spc craft
# Output full console log
./spc craft --debug
./spc craft -vvv
```
### 3. Static PHP usage
@@ -90,48 +95,40 @@ buildroot/bin/php -v
echo '<?php echo "Hello world!\n";' > a.php
./spc micro:combine a.php -O my-app
./my-app
# php-fpm
buildroot/bin/php-fpm -v
```
## Documentation
The current README contains basic usage. For all the features of StaticPHP,
see <https://static-php.dev> .
The current README contains basic usage. For the complete feature set of StaticPHP,
see <https://static-php.dev>.
## Direct Download
If you don't want to build or want to test first, you can download example pre-compiled artifact from [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml), or from 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/static-php-cli-hosted/actions/workflows/build-php-bulk.yml) or from a self-hosted server.
Below are several precompiled static-php binaries with different extension combinations,
which can be downloaded directly according to your needs.
We offer 2 types of extension sets for each PHP version:
| Combination | Extension Count | OS | Comment |
|----------------------------------------------------------------------|----------------------------------------------------------------------------|--------------|--------------------------------|
| [common](https://dl.static-php.dev/static-php-cli/common/) | [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) | Linux, macOS | The binary size is about 7.5MB |
| [bulk](https://dl.static-php.dev/static-php-cli/bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | The binary size is about 25MB |
| [gnu-bulk](https://dl.static-php.dev/static-php-cli/gnu-bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | Using shared glibc |
| [minimal](https://dl.static-php.dev/static-php-cli/minimal/) | [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) | Linux, macOS | The binary size is about 3MB |
| [spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/) | [5](https://dl.static-php.dev/static-php-cli/windows/spc-min/README.txt) | Windows | The binary size is about 3MB |
| [spc-max](https://dl.static-php.dev/static-php-cli/windows/spc-max/) | [40+](https://dl.static-php.dev/static-php-cli/windows/spc-max/README.txt) | Windows | The binary size is about 8.5MB |
- **gigantic**: Includes as many extensions as possible, the binary size is about 100-150MB.
- **base**: Only includes a few extensions used by StaticPHP itself, the binary size is about 10MB.
> Linux and Windows supports UPX compression for binaries, which can reduce the size of the binary by 30% to 50%.
> macOS does not support UPX compression, so the size of the pre-built binaries for mac is larger.
> WIP
### Build Online (using GitHub Actions)
When the above direct download binaries cannot meet your needs,
you can use GitHub Action to easily build a statically compiled PHP,
and at the same time define the extensions to be compiled by yourself.
When the direct-download binaries above cannot meet your needs,
you can use GitHub Actions to easily build a statically compiled PHP
while defining your own extension list.
1. Fork me.
1. Fork this repository.
2. Go to the Actions of the project and select `CI`.
3. Select `Run workflow`, fill in the PHP version you want to compile, the target type, and the list of extensions. (extensions comma separated, e.g. `bcmath,curl,mbstring`)
4. After waiting for about a period of time, enter the corresponding task and get `Artifacts`.
4. After waiting for the workflow to finish, open the corresponding run and download `Artifacts`.
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
> We are also planning to provide a reusable GitHub Actions workflow in the future,
> so that you can easily build static PHP in your own repository, without forking this project.
## Contribution
If the extension you need is missing, you can create an issue.
@@ -139,8 +136,6 @@ If you are familiar with this project, you are also welcome to initiate a pull r
If you want to contribute documentation, please just edit in `docs/`.
Now there is a [static-php](https://github.com/static-php) organization, which is used to store the repo related to the project.
## Sponsor this project
You can sponsor me or my project from [GitHub Sponsor](https://github.com/crazywhalecc). A portion of your donation will be used to maintain the **static-php.dev** server.
@@ -153,21 +148,9 @@ You can sponsor me or my project from [GitHub Sponsor](https://github.com/crazyw
## Open-Source License
This project itself is based on MIT License,
some newly added extensions and dependencies may originate from the the other projects,
and the headers of these code files will also be given additional instructions LICENSE and AUTHOR.
These are similar projects:
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
The project uses some code from [dixyes/lwmbs](https://github.com/dixyes/lwmbs), such as windows static build target and libiconv support.
lwmbs is licensed under the [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2).
Due to the special nature of this project,
many other open source projects such as curl and protobuf will be used during the project compilation process,
and they all have their own open source licenses.
This project itself is licensed under MIT.
Some newly added extensions and dependencies may originate from other projects.
The headers of those source files may also include additional LICENSE and AUTHOR information.
Please use the `bin/spc dump-license` command to export the open source licenses used in the project after compilation,
and comply with the corresponding project's LICENSE.

View File

@@ -122,7 +122,7 @@ COPY ./composer.* /app/
ADD ./bin /app/bin
RUN composer install --no-dev
ADD ./config /app/config
ADD ./spc.registry.json /app/spc.registry.json
ADD ./spc.registry.yml /app/spc.registry.yml
RUN bin/spc doctor --auto-fix
RUN bin/spc install-pkg upx

View File

@@ -1,4 +1,12 @@
#!/usr/bin/env bash
# Use SPC_XDEBUG=profile to enable Xdebug profiling mode, which will generate profiling files in /tmp.
# Otherwise, it will enable Xdebug debugging mode, which allows you to connect a debugger to port 9003.
if [ "$SPC_XDEBUG" = "profile" ]; then
XDEBUG_PREFIX="-d xdebug.mode=profile -d xdebug.start_with_request=yes -d xdebug.output_dir=/tmp -d xdebug.output_name=spc-profile.%t.%p.%r"
else
XDEBUG_PREFIX="-d xdebug.mode=debug -d xdebug.client_host=127.0.0.1 -d xdebug.client_port=9003 -d xdebug.start_with_request=yes"
fi
# This script runs the 'spc' command with Xdebug enabled for debugging purposes.
php -d xdebug.mode=debug -d xdebug.client_host=127.0.0.1 -d xdebug.client_port=9003 -d xdebug.start_with_request=yes "$(dirname "$0")/../bin/spc" "$@"
php $XDEBUG_PREFIX "$(dirname "$0")/../bin/spc" "$@"

View File

@@ -1,236 +0,0 @@
#!/usr/bin/env bash
set -e
# This file is using docker to run commands
SPC_DOCKER_VERSION=v6
# Detect docker can run
if ! which docker >/dev/null; then
echo "Docker is not installed, please install docker first !"
exit 1
fi
DOCKER_EXECUTABLE="docker"
# shellcheck disable=SC2046
if [ $(id -u) -ne 0 ]; then
if ! docker info > /dev/null 2>&1; then
if [ "$SPC_USE_SUDO" != "yes" ] && [ "$SPC_DOCKER_DEBUG" != "yes" ]; then
echo "Docker command requires sudo"
# shellcheck disable=SC2039
echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
exit 1
fi
DOCKER_EXECUTABLE="sudo docker"
fi
fi
# Convert uname to gnu arch
CURRENT_ARCH=$(uname -m)
if [ "$CURRENT_ARCH" = "arm64" ]; then
CURRENT_ARCH=aarch64
fi
if [ -z "$SPC_USE_ARCH" ]; then
SPC_USE_ARCH=$CURRENT_ARCH
fi
# parse SPC_USE_ARCH
case $SPC_USE_ARCH in
x86_64|amd64)
SPC_USE_ARCH=x86_64
SPC_USE_ARCH_DOCKER=amd64
if [ "$CURRENT_ARCH" != "x86_64" ]; then
PLATFORM_ARG="--platform linux/amd64"
fi
;;
aarch64|arm64)
SPC_USE_ARCH=aarch64
SPC_USE_ARCH_DOCKER=arm64
if [ "$CURRENT_ARCH" != "aarch64" ]; then
PLATFORM_ARG="--platform linux/arm64"
fi
;;
*)
echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
exit 1
;;
esac
# detect if we need to use qemu-static
if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then
if [ "$(uname -s)" = "Linux" ]; then
echo "* Using different arch needs to setup qemu-static for docker !"
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static --reset -p yes > /dev/null
fi
fi
# Detect docker env is setup
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION; then
echo "Docker container does not exist. Building docker image ..."
$DOCKER_EXECUTABLE buildx build $PLATFORM_ARG -t cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
FROM centos:7
RUN sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo && \
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
RUN yum clean all && \
yum makecache && \
yum update -y && \
localedef -c -i en_US -f UTF-8 en_US.UTF-8
RUN yum install -y centos-release-scl
RUN if [ "$SPC_USE_ARCH" = "aarch64" ]; then \
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo ; \
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl.repo ; \
else \
sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo ; \
fi
RUN sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo && \
sed -i 's|http://|https://|g' /etc/yum.repos.d/*.repo
RUN yum update -y && \
yum install -y devtoolset-10-gcc-* devtoolset-10-libatomic-devel
RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc
RUN source /etc/bashrc
RUN yum install -y which
RUN curl -o cmake.tgz -#fSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$SPC_USE_ARCH.tar.gz && \
mkdir /cmake && \
tar -xzf cmake.tgz -C /cmake --strip-components 1
WORKDIR /app
COPY ./composer.* /app/
ADD ./bin/setup-runtime /app/bin/setup-runtime
ADD ./bin/spc /app/bin/spc
RUN /app/bin/setup-runtime
ADD ./src /app/src
RUN /app/bin/php /app/bin/composer install --no-dev
ENV SPC_LIBC=glibc
ENV PATH="/app/bin:/cmake/bin:/opt/rh/devtoolset-10/root/usr/bin:\$PATH"
ADD ./config /app/config
RUN CC=gcc bin/spc doctor --auto-fix --debug
RUN bin/spc install-pkg upx
RUN if [ -f /app/buildroot/bin/re2c ]; then \
cp /app/buildroot/bin/re2c /usr/local/bin/re2c ;\
fi
RUN curl -o make.tgz -fsSL https://ftp.gnu.org/gnu/make/make-4.4.tar.gz && \
tar -zxvf make.tgz && \
cd make-4.4 && \
./configure && \
make && \
make install && \
ln -sf /usr/local/bin/make /usr/bin/make
RUN curl -o automake.tgz -fsSL https://ftp.gnu.org/gnu/automake/automake-1.17.tar.xz && \
tar -xvf automake.tgz && \
cd automake-1.17 && \
./configure && \
make && \
make install && \
ln -sf /usr/local/bin/automake /usr/bin/automake
RUN mv /app/pkgroot/\$(uname -m)-linux /app/pkgroot-private
ADD bin/docker-entrypoint.sh /bin/docker-entrypoint.sh
RUN chmod +x /bin/docker-entrypoint.sh
ENTRYPOINT ["/bin/docker-entrypoint.sh"]
EOF
fi
# Check if in ci (local terminal can execute with -it)
if [ -t 0 ]; then
INTERACT=-it
else
INTERACT=''
fi
# Mounting volumes
MOUNT_LIST=""
# shellcheck disable=SC2089
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/config:/app/config"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/src:/app/src"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/buildroot:/app/buildroot"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/source:/app/source"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/dist:/app/dist"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/downloads:/app/downloads"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/log:/app/log"
if [ -f "$(pwd)/craft.yml" ]; then
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/craft.yml:/app/craft.yml"
fi
# Apply env in temp env file
echo 'SPC_DEFAULT_C_FLAGS=-fPIC' > /tmp/spc-gnu-docker.env
echo 'SPC_LIBC=glibc' >> /tmp/spc-gnu-docker.env
# Environment variable passthrough
ENV_LIST=""
ENV_LIST="$ENV_LIST -e SPC_FIX_DEPLOY_ROOT="$(pwd)""
if [ ! -z "$GITHUB_TOKEN" ]; then
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
fi
# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
FRANKENPHP_APP_PATH=""
NEW_ARGS=()
while [ $# -gt 0 ]; do
case "$1" in
--with-frankenphp-app=*)
FRANKENPHP_APP_PATH="${1#*=}"
NEW_ARGS+=("--with-frankenphp-app=/app/app")
shift
;;
--with-frankenphp-app)
if [ -n "${2:-}" ]; then
FRANKENPHP_APP_PATH="$2"
NEW_ARGS+=("--with-frankenphp-app=/app/app")
shift 2
else
NEW_ARGS+=("$1")
shift
fi
;;
*)
NEW_ARGS+=("$1")
shift
;;
esac
done
# Normalize the path and add mount if provided
if [ -n "$FRANKENPHP_APP_PATH" ]; then
# expand ~ to $HOME
if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
fi
# make absolute if relative
case "$FRANKENPHP_APP_PATH" in
/*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
*) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
esac
MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
fi
# Run docker
# shellcheck disable=SC2068
# shellcheck disable=SC2086
# shellcheck disable=SC2090
if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
echo "* Debug mode enabled, run docker in interactive mode."
echo "* You can use 'exit' to exit the docker container."
echo "* You can use 'bin/spc' like normal builds."
echo "*"
echo "* Mounted directories:"
echo "* ./config: $(pwd)/config"
echo "* ./src: $(pwd)/src"
echo "* ./buildroot: $(pwd)/buildroot"
echo "* ./source: $(pwd)/source"
echo "* ./dist: $(pwd)/dist"
echo "* ./downloads: $(pwd)/downloads"
echo "* ./pkgroot: $(pwd)/pkgroot"
echo "*"
set -ex
$DOCKER_EXECUTABLE run $PLATFORM_ARG --privileged --rm -it $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
else
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
fi

View File

@@ -29,7 +29,6 @@
},
"autoload": {
"psr-4": {
"SPC\\": "src/SPC",
"StaticPHP\\": "src/StaticPHP",
"Package\\": "src/Package"
},
@@ -49,7 +48,7 @@
"scripts": {
"analyse": "phpstan analyse --memory-limit 300M",
"cs-fix": "php-cs-fixer fix",
"lint-config": "bin/spc dev:lint-config",
"lint-config": "php bin/spc dev:lint-config",
"test": "vendor/bin/phpunit tests/ --no-coverage",
"build:phar": "vendor/bin/box compile"
},
@@ -63,6 +62,9 @@
"optimize-autoloader": true,
"sort-packages": true
},
"suggest": {
"ext-yaml": "Speeds up YAML config file parsing"
},
"funding": [
{
"type": "other",

626
composer.lock generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -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-musl` - links against musl libc statically
; `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)
CC=${SPC_DEFAULT_CC}
@@ -102,9 +102,9 @@ CXX=${SPC_DEFAULT_CXX}
AR=${SPC_DEFAULT_AR}
LD=${SPC_DEFAULT_LD}
; default compiler flags, used in CMake toolchain file, openssl and pkg-config build
SPC_DEFAULT_C_FLAGS="-fPIC -Os"
SPC_DEFAULT_CXX_FLAGS="-fPIC -Os"
SPC_DEFAULT_LD_FLAGS=""
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_CXXFLAGS="${SPC_DEFAULT_CFLAGS}"
SPC_DEFAULT_LDFLAGS="-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -Wl,-z,noexecstack -Wl,--gc-sections"
; upx executable path
UPX_EXEC=${PKG_ROOT_PATH}/bin/upx
; 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
SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
; 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 ***
; embed type for php, static (libphp.a) or shared (libphp.so)
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
; 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
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
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
@@ -142,9 +142,9 @@ CXX=${SPC_DEFAULT_CXX}
AR=${SPC_DEFAULT_AR}
LD=${SPC_DEFAULT_LD}
; 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_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os"
SPC_DEFAULT_LD_FLAGS=""
SPC_DEFAULT_CFLAGS="--target=${MAC_ARCH}-apple-darwin -O3 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections"
SPC_DEFAULT_CXXFLAGS="${SPC_DEFAULT_CFLAGS}"
SPC_DEFAULT_LDFLAGS="-Wl,-dead_strip"
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
SPC_MICRO_PATCHES=cli_checks,macos_iconv
@@ -152,15 +152,15 @@ SPC_MICRO_PATCHES=cli_checks,macos_iconv
; buildconf command
SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
; 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 ***
; embed type for php, static (libphp.a) or shared (libphp.dylib)
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
; 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
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
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
; minimum compatible macOS version (LLVM vars, availability not guaranteed)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,992 +0,0 @@
{
"attr": {
"artifact": "attr",
"license": {
"type": "file",
"path": "doc/COPYING.LGPL"
},
"type": "library"
},
"brotli": {
"artifact": "brotli",
"headers": [
"brotli"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"pkg-configs": [
"libbrotlicommon",
"libbrotlidec",
"libbrotlienc"
],
"type": "library"
},
"bzip2": {
"artifact": "bzip2",
"headers": [
"bzlib.h"
],
"license": {
"type": "text",
"text": "This program, \"bzip2\", the associated library \"libbzip2\", and all documentation, are copyright (C) 1996-2010 Julian R Seward. All rights reserved. \n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nJulian Seward, jseward@bzip.org bzip2/libbzip2 version 1.0.6 of 6 September 2010\n\nPATENTS: To the best of my knowledge, bzip2 and libbzip2 do not use any patented algorithms. However, I do not have the resources to carry out a patent search. Therefore I cannot give any guarantee of the above statement."
},
"type": "library"
},
"curl": {
"artifact": "curl",
"depends": [
"openssl",
"zlib"
],
"depends@windows": [
"zlib",
"libssh2",
"nghttp2"
],
"frameworks": [
"CoreFoundation",
"CoreServices",
"SystemConfiguration"
],
"headers": [
"curl"
],
"license": {
"type": "file",
"path": "COPYING"
},
"suggests": [
"libssh2",
"brotli",
"nghttp2",
"nghttp3",
"ngtcp2",
"zstd",
"libcares",
"ldap"
],
"suggests@windows": [
"brotli",
"zstd"
],
"type": "library"
},
"fastlz": {
"artifact": "fastlz",
"headers": [
"fastlz/fastlz.h"
],
"license": {
"type": "file",
"path": "LICENSE.MIT"
},
"type": "library"
},
"freetype": {
"artifact": "freetype",
"depends": [
"zlib"
],
"headers": [
"freetype2/freetype/freetype.h",
"freetype2/ft2build.h"
],
"license": {
"type": "file",
"path": "LICENSE.TXT"
},
"suggests": [
"libpng",
"bzip2",
"brotli"
],
"type": "library"
},
"gettext": {
"artifact": "gettext",
"depends": [
"libiconv"
],
"frameworks": [
"CoreFoundation"
],
"license": {
"type": "file",
"path": "gettext-runtime/intl/COPYING.LIB"
},
"suggests": [
"ncurses",
"libxml2"
],
"type": "library"
},
"glfw": {
"artifact": "ext-glfw",
"frameworks": [
"CoreVideo",
"OpenGL",
"Cocoa",
"IOKit"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"gmp": {
"artifact": "gmp",
"headers": [
"gmp.h"
],
"license": {
"type": "text",
"text": "Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2. These licenses make the library free to use, share, and improve, and allow you to pass on the result. The GNU licenses give freedoms, but also set firm restrictions on the use with non-free programs."
},
"type": "library"
},
"gmssl": {
"artifact": "gmssl",
"frameworks": [
"Security"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"grpc": {
"artifact": "grpc",
"depends": [
"zlib",
"openssl",
"libcares"
],
"frameworks": [
"CoreFoundation"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"pkg-configs": [
"grpc"
],
"type": "library"
},
"icu": {
"artifact": "icu",
"license": {
"type": "file",
"path": "LICENSE"
},
"pkg-configs": [
"icu-uc",
"icu-i18n",
"icu-io"
],
"type": "library"
},
"icu-static-win": {
"artifact": "icu-static-win",
"headers@windows": [
"unicode"
],
"license": {
"type": "text",
"text": "none"
},
"type": "library"
},
"imagemagick": {
"artifact": "imagemagick",
"depends": [
"zlib",
"libjpeg",
"libjxl",
"libpng",
"libwebp",
"freetype",
"libtiff",
"libheif",
"bzip2"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"pkg-configs": [
"Magick++-7.Q16HDRI",
"MagickCore-7.Q16HDRI",
"MagickWand-7.Q16HDRI"
],
"suggests": [
"zstd",
"xz",
"libzip",
"libxml2"
],
"type": "library"
},
"imap": {
"artifact": "imap",
"license": {
"type": "file",
"path": "LICENSE"
},
"suggests": [
"openssl"
],
"type": "library"
},
"jbig": {
"artifact": "jbig",
"headers": [
"jbig.h",
"jbig85.h",
"jbig_ar.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"ldap": {
"artifact": "ldap",
"depends": [
"openssl",
"zlib",
"gmp",
"libsodium"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"pkg-configs": [
"ldap",
"lber"
],
"type": "library"
},
"lerc": {
"artifact": "lerc",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libacl": {
"artifact": "libacl",
"depends": [
"attr"
],
"license": {
"type": "file",
"path": "doc/COPYING.LGPL"
},
"type": "library"
},
"libaom": {
"artifact": "libaom",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libargon2": {
"artifact": "libargon2",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libavif": {
"artifact": "libavif",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libcares": {
"artifact": "libcares",
"headers": [
"ares.h",
"ares_dns.h",
"ares_nameser.h"
],
"license": {
"type": "file",
"path": "LICENSE.md"
},
"type": "library"
},
"libde265": {
"artifact": "libde265",
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"libedit": {
"artifact": "libedit",
"depends": [
"ncurses"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"libevent": {
"artifact": "libevent",
"depends": [
"openssl"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libffi": {
"artifact": "libffi",
"headers": [
"ffi.h",
"ffitarget.h"
],
"headers@windows": [
"ffi.h",
"fficonfig.h",
"ffitarget.h"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libffi-win": {
"artifact": "libffi-win",
"headers@windows": [
"ffi.h",
"ffitarget.h",
"fficonfig.h"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libheif": {
"artifact": "libheif",
"depends": [
"libde265",
"libwebp",
"libaom",
"zlib",
"brotli"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"libiconv": {
"artifact": "libiconv",
"headers": [
"iconv.h",
"libcharset.h",
"localcharset.h"
],
"license": {
"type": "file",
"path": "COPYING.LIB"
},
"type": "library"
},
"libiconv-win": {
"artifact": "libiconv-win",
"license": {
"type": "file",
"path": "source/COPYING"
},
"type": "library"
},
"libjpeg": {
"artifact": "libjpeg",
"license": {
"type": "file",
"path": "LICENSE.md"
},
"suggests@windows": [
"zlib"
],
"type": "library"
},
"libjxl": {
"artifact": "libjxl",
"depends": [
"brotli",
"libjpeg",
"libpng",
"libwebp"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"pkg-configs": [
"libjxl",
"libjxl_cms",
"libjxl_threads",
"libhwy"
],
"type": "library"
},
"liblz4": {
"artifact": "liblz4",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libmemcached": {
"artifact": "libmemcached",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libpng": {
"artifact": "libpng",
"depends": [
"zlib"
],
"headers": [
"png.h",
"pngconf.h",
"pnglibconf.h"
],
"headers@windows": [
"png.h",
"pngconf.h"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"librabbitmq": {
"artifact": "librabbitmq",
"depends": [
"openssl"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"librdkafka": {
"artifact": "librdkafka",
"license": {
"type": "file",
"path": "LICENSE"
},
"pkg-configs": [
"rdkafka++-static",
"rdkafka-static"
],
"suggests": [
"curl",
"liblz4",
"openssl",
"zlib",
"zstd"
],
"type": "library"
},
"libsodium": {
"artifact": "libsodium",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"libssh2": {
"artifact": "libssh2",
"depends": [
"openssl"
],
"headers": [
"libssh2.h",
"libssh2_publickey.h",
"libssh2_sftp.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"libtiff": {
"artifact": "libtiff",
"depends": [
"zlib",
"libjpeg"
],
"license": {
"type": "file",
"path": "LICENSE.md"
},
"suggests": [
"lerc",
"libwebp",
"jbig",
"xz",
"zstd"
],
"type": "library"
},
"liburing": {
"artifact": "liburing",
"headers@linux": [
"liburing/",
"liburing.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"pkg-configs": [
"liburing",
"liburing-ffi"
],
"type": "library"
},
"libuuid": {
"artifact": "libuuid",
"headers": [
"uuid/uuid.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"libuv": {
"artifact": "libuv",
"license": [
{
"type": "file",
"path": "LICENSE"
},
{
"type": "file",
"path": "LICENSE-extra"
}
],
"type": "library"
},
"libwebp": {
"artifact": "libwebp",
"license": {
"type": "file",
"path": "COPYING"
},
"pkg-configs": [
"libwebp",
"libwebpdecoder",
"libwebpdemux",
"libwebpmux",
"libsharpyuv"
],
"type": "library"
},
"libxml2": {
"artifact": "libxml2",
"depends": [
"libiconv"
],
"depends@windows": [
"libiconv-win"
],
"headers": [
"libxml2"
],
"license": {
"type": "file",
"path": "Copyright"
},
"pkg-configs": [
"libxml-2.0"
],
"suggests": [
"xz",
"zlib"
],
"suggests@windows": [
"zlib"
],
"type": "library"
},
"libxslt": {
"artifact": "libxslt",
"depends": [
"libxml2"
],
"license": {
"type": "file",
"path": "Copyright"
},
"type": "library"
},
"libyaml": {
"artifact": "libyaml",
"headers": [
"yaml.h"
],
"license": {
"type": "file",
"path": "License"
},
"type": "library"
},
"libzip": {
"artifact": "libzip",
"depends": [
"zlib"
],
"depends@windows": [
"zlib",
"bzip2",
"xz"
],
"headers": [
"zip.h",
"zipconf.h"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"suggests": [
"bzip2",
"xz",
"zstd",
"openssl"
],
"suggests@windows": [
"zstd",
"openssl"
],
"type": "library"
},
"mimalloc": {
"artifact": "mimalloc",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"ncurses": {
"artifact": "ncurses",
"license": {
"type": "file",
"path": "COPYING"
},
"static-libs@unix": [
"libncurses.a"
],
"type": "library"
},
"net-snmp": {
"artifact": "net-snmp",
"depends": [
"openssl",
"zlib"
],
"license": {
"type": "file",
"path": "COPYING"
},
"pkg-configs": [
"netsnmp",
"netsnmp-agent"
],
"type": "library"
},
"nghttp2": {
"artifact": "nghttp2",
"depends": [
"zlib",
"openssl"
],
"headers": [
"nghttp2"
],
"license": {
"type": "file",
"path": "COPYING"
},
"suggests": [
"libxml2",
"nghttp3",
"ngtcp2"
],
"type": "library"
},
"nghttp3": {
"artifact": "nghttp3",
"depends": [
"openssl"
],
"headers": [
"nghttp3"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"ngtcp2": {
"artifact": "ngtcp2",
"depends": [
"openssl"
],
"headers": [
"ngtcp2"
],
"license": {
"type": "file",
"path": "COPYING"
},
"suggests": [
"nghttp3",
"brotli"
],
"type": "library"
},
"onig": {
"artifact": "onig",
"headers": [
"oniggnu.h",
"oniguruma.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"openssl": {
"artifact": "openssl",
"depends": [
"zlib"
],
"headers": [
"openssl"
],
"license": {
"type": "file",
"path": "LICENSE.txt"
},
"type": "library"
},
"postgresql": {
"artifact": "postgresql",
"depends": [
"libiconv",
"libxml2",
"openssl",
"zlib",
"libedit"
],
"license": {
"type": "file",
"path": "COPYRIGHT"
},
"pkg-configs": [
"libpq"
],
"suggests": [
"icu",
"libxslt",
"ldap",
"zstd"
],
"type": "library"
},
"postgresql-win": {
"artifact": "postgresql-win",
"license": {
"type": "text",
"text": "PostgreSQL Database Management System\n(also known as Postgres, formerly as Postgres95)\n\nPortions Copyright (c) 1996-2025, The PostgreSQL Global Development Group\n\nPortions Copyright (c) 1994, The Regents of the University of California\n\nPermission to use, copy, modify, and distribute this software and its\ndocumentation for any purpose, without fee, and without a written\nagreement is hereby granted, provided that the above copyright notice\nand this paragraph and the following two paragraphs appear in all\ncopies.\n\nIN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY\nFOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,\nINCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS\nDOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF\nTHE POSSIBILITY OF SUCH DAMAGE.\n\nTHE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,\nINCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS\nON AN \"AS IS\" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS\nTO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
},
"type": "library"
},
"pthreads4w": {
"artifact": "pthreads4w",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"qdbm": {
"artifact": "qdbm",
"headers@windows": [
"depot.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"re2c": {
"artifact": "re2c",
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
},
"readline": {
"artifact": "readline",
"depends": [
"ncurses"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"snappy": {
"artifact": "snappy",
"depends": [
"zlib"
],
"headers": [
"snappy.h",
"snappy-c.h",
"snappy-sinksource.h",
"snappy-stubs-public.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"sqlite": {
"artifact": "sqlite",
"headers": [
"sqlite3.h",
"sqlite3ext.h"
],
"license": {
"type": "text",
"text": "The author disclaims copyright to this source code. In place of\na legal notice, here is a blessing:\n\n * May you do good and not evil.\n * May you find forgiveness for yourself and forgive others.\n * May you share freely, never taking more than you give."
},
"type": "library"
},
"tidy": {
"artifact": "tidy",
"license": {
"type": "file",
"path": "README/LICENSE.md"
},
"type": "library"
},
"unixodbc": {
"artifact": "unixodbc",
"depends": [
"libiconv"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"watcher": {
"artifact": "watcher",
"headers": [
"wtr/watcher-c.h"
],
"license": {
"type": "file",
"path": "license"
},
"type": "library"
},
"xz": {
"artifact": "xz",
"depends": [
"libiconv"
],
"headers": [
"lzma"
],
"headers@windows": [
"lzma",
"lzma.h"
],
"license": {
"type": "file",
"path": "COPYING"
},
"type": "library"
},
"zlib": {
"artifact": "zlib",
"headers": [
"zlib.h",
"zconf.h"
],
"license": {
"type": "text",
"text": "(C) 1995-2022 Jean-loup Gailly and Mark Adler\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n claim that you wrote the original software. If you use this software\n in a product, an acknowledgment in the product documentation would be\n appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution.\n\nJean-loup Gailly Mark Adler\njloup@gzip.org madler@alumni.caltech.edu"
},
"type": "library"
},
"zstd": {
"artifact": "zstd",
"headers": [
"zdict.h",
"zstd.h",
"zstd_errors.h"
],
"headers@windows": [
"zstd.h",
"zstd_errors.h"
],
"license": {
"type": "file",
"path": "LICENSE"
},
"type": "library"
}
}

View File

@@ -9,6 +9,12 @@ ext-bz2:
arg-type@windows: with
ext-calendar:
type: php-extension
ext-com_dotnet:
type: php-extension
php-extension:
os:
- Windows
arg-type@windows: '--enable-com-dotnet=yes'
ext-ctype:
type: php-extension
ext-curl:
@@ -30,17 +36,20 @@ ext-dba:
ext-dom:
type: php-extension
depends:
- libxml2
- ext-xml
php-extension:
arg-type: '--enable-dom@shared_suffix@ --with-libxml=@build_root_path@'
arg-type: enable
arg-type@windows: with
ext-exif:
type: php-extension
depends@windows:
- ext-mbstring
ext-ffi:
type: php-extension
depends@unix:
- libffi
depends@windows:
- libffi-win
php-extension:
arg-type@unix: '--with-ffi=@shared_suffix@ --enable-zend-signals'
arg-type@windows: with
@@ -65,28 +74,37 @@ ext-gd:
- freetype
php-extension:
arg-type: custom
arg-type@windows: with
ext-gettext:
type: php-extension
depends:
depends@unix:
- gettext
depends@windows:
- gettext-win
php-extension:
arg-type: with-path
arg-type@windows: with
ext-gmp:
type: php-extension
depends:
depends@unix:
- gmp
depends@windows:
- mpir
php-extension:
arg-type: with-path
arg-type@windows: with
ext-iconv:
type: php-extension
depends@unix:
- libiconv
depends@windows:
- libiconv-win
php-extension:
arg-type@unix: with-path
arg-type@windows: with
ext-intl:
type: php-extension
depends@unix:
depends:
- icu
ext-ldap:
type: php-extension
@@ -97,15 +115,20 @@ ext-ldap:
- libsodium
- ext-openssl
php-extension:
os:
- Linux
- Darwin
arg-type: with-path
arg-type@windows: with
ext-libxml:
type: php-extension
depends:
- ext-xml
- libxml2
php-extension:
build-with-php: true
build-shared: false
arg-type: none
arg-type@unix: with-path
arg-type@windows: with
ext-mbregex:
type: php-extension
depends:
@@ -141,6 +164,7 @@ ext-odbc:
- unixodbc
php-extension:
arg-type@unix: '--with-unixODBC@shared_path_suffix@'
arg-type@windows: enable
ext-opcache:
type: php-extension
php-extension:
@@ -162,12 +186,20 @@ ext-password-argon2:
type: php-extension
depends:
- libargon2
suggests:
- ext-openssl
php-extension:
os:
- Linux
- Darwin
arg-type: custom
display-name: ''
ext-pcntl:
type: php-extension
php-extension:
os:
- Linux
- Darwin
ext-pdo:
type: php-extension
ext-pdo_mysql:
@@ -181,7 +213,6 @@ ext-pdo_odbc:
type: php-extension
depends:
- ext-pdo
- ext-odbc
depends@unix:
- unixodbc
- ext-pdo
@@ -190,7 +221,7 @@ ext-pdo_odbc:
arg-type: custom
ext-pdo_pgsql:
type: php-extension
depends@unix:
depends:
- ext-pdo
- ext-pgsql
- postgresql
@@ -207,7 +238,7 @@ ext-pdo_sqlite:
arg-type: with
ext-pgsql:
type: php-extension
depends@unix:
depends:
- postgresql
php-extension:
arg-type: custom
@@ -217,15 +248,19 @@ ext-phar:
- zlib
ext-posix:
type: php-extension
php-extension:
os:
- Linux
- Darwin
ext-readline:
type: php-extension
depends:
depends@unix:
- libedit
depends@windows:
- wineditline
php-extension:
support:
Windows: wip
BSD: wip
arg-type: '--with-libedit --without-readline'
arg-type@windows: with
build-shared: false
build-static: true
ext-session:
@@ -239,7 +274,7 @@ ext-simplexml:
depends:
- ext-xml
php-extension:
arg-type@unix: '--enable-simplexml@shared_suffix@ --with-libxml=@build_root_path@'
arg-type@unix: enable
arg-type@windows: with
build-with-php: true
ext-snmp:
@@ -247,6 +282,9 @@ ext-snmp:
depends:
- net-snmp
php-extension:
os:
- Linux
- Darwin
arg-type: with
ext-soap:
type: php-extension
@@ -254,8 +292,7 @@ ext-soap:
- ext-xml
- ext-session
php-extension:
arg-type@unix: '--enable-soap@shared_suffix@ --with-libxml=@build_root_path@'
arg-type@windows: with
arg-type: enable
build-with-php: true
ext-sockets:
type: php-extension
@@ -276,28 +313,22 @@ ext-sqlite3:
ext-sysvmsg:
type: php-extension
php-extension:
support:
Windows: 'no'
BSD: wip
os:
- Linux
- Darwin
ext-sysvsem:
type: php-extension
php-extension:
support:
Windows: 'no'
BSD: wip
os:
- Linux
- Darwin
ext-sysvshm:
type: php-extension
php-extension:
support:
BSD: wip
ext-tidy:
type: php-extension
depends:
- tidy
php-extension:
support:
Windows: wip
BSD: wip
arg-type: with-path
ext-tokenizer:
type: php-extension
@@ -306,27 +337,28 @@ ext-tokenizer:
ext-xml:
type: php-extension
depends:
- libxml2
- ext-libxml
depends@windows:
- libxml2
- ext-iconv
- ext-libxml
php-extension:
arg-type: '--enable-xml@shared_suffix@ --with-libxml=@build_root_path@'
arg-type@unix: enable
arg-type@windows: with
build-with-php: true
ext-xmlreader:
type: php-extension
depends:
- libxml2
- ext-xml
- ext-dom
php-extension:
arg-type: '--enable-xmlreader@shared_suffix@ --with-libxml=@build_root_path@'
arg-type: enable
build-with-php: true
ext-xmlwriter:
type: php-extension
depends:
- libxml2
- ext-xml
php-extension:
arg-type: '--enable-xmlwriter@shared_suffix@ --with-libxml=@build_root_path@'
arg-type: enable
build-with-php: true
ext-xsl:
type: php-extension

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

@@ -0,0 +1,16 @@
ext-decimal:
type: php-extension
artifact:
source:
type: ghtagtar
repo: php-decimal/ext-decimal
match: 'v2\.\d.*'
extract: php-src/ext/decimal
metadata:
license-files: [LICENSE]
license: MIT
depends:
- libmpdec
php-extension:
arg-type@unix: '--enable-decimal --with-libmpdec-path=@build_root_path@'
arg-type@windows: '--with-decimal'

View File

@@ -0,0 +1,10 @@
ext-deepclone:
type: php-extension
artifact:
source:
type: ghtagtar
repo: symfony/php-ext-deepclone
extract: php-src/ext/deepclone
metadata:
license-files: [LICENSE]
license: PHP-3.01

View File

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

View File

@@ -14,6 +14,7 @@ ext-event:
suggests:
- ext-sockets
php-extension:
support:
Windows: wip
os:
- Linux
- Darwin
arg-type: custom

View File

@@ -7,3 +7,7 @@ ext-excimer:
metadata:
license-files: [LICENSE]
license: PHP-3.01
php-extension:
os:
- Linux
- Darwin

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

@@ -11,4 +11,7 @@ ext-grpc:
- grpc
lang: cpp
php-extension:
os:
- Linux
- Darwin
arg-type@unix: enable-path

View File

@@ -10,4 +10,7 @@ ext-imagick:
depends:
- imagemagick
php-extension:
os:
- Linux
- Darwin
arg-type: custom

View File

@@ -12,4 +12,7 @@ ext-imap:
suggests:
- ext-openssl
php-extension:
os:
- Linux
- Darwin
arg-type: custom

View File

@@ -7,3 +7,6 @@ ext-inotify:
metadata:
license-files: [LICENSE]
license: PHP-3.01
php-extension:
os:
- Linux

View File

@@ -2,8 +2,9 @@ ext-lz4:
type: php-extension
artifact:
source:
type: ghtagtar
repo: kjdev/php-ext-lz4
type: git
url: 'https://github.com/kjdev/php-ext-lz4.git'
rev: master
extract: php-src/ext/lz4
metadata:
license-files: [LICENSE]

View File

@@ -11,4 +11,7 @@ ext-memcache:
- ext-zlib
- ext-session
php-extension:
os:
- Linux
- Darwin
arg-type: '--enable-memcache@shared_suffix@ --with-zlib-dir=@build_root_path@'

View File

@@ -20,4 +20,7 @@ ext-memcached:
- ext-msgpack
- ext-session
php-extension:
os:
- Linux
- Darwin
arg-type: '--enable-memcached@shared_suffix@ --with-zlib-dir=@build_root_path@'

View File

@@ -9,7 +9,9 @@ ext-mongodb:
metadata:
license-files: [LICENSE]
license: PHP-3.01
suggests:
depends@windows:
- ext-openssl
suggests@unix:
- icu
- openssl
- zstd
@@ -18,4 +20,5 @@ ext-mongodb:
- CoreFoundation
- Security
php-extension:
arg-type: custom
arg-type@unix: custom
arg-type@windows: '--enable-mongodb --with-mongodb-client-side-encryption'

View File

@@ -7,3 +7,7 @@ ext-parallel:
metadata:
license-files: [LICENSE]
license: PHP-3.01
depends@windows:
- pthreads4w
php-extension:
arg-type@windows: with

View File

@@ -7,3 +7,7 @@ ext-protobuf:
metadata:
license-files: [LICENSE]
license: BSD-3-Clause
php-extension:
os:
- Linux
- Darwin

View File

@@ -3,7 +3,7 @@ ext-rdkafka:
artifact:
source:
type: ghtar
repo: arnaud-lb/php-rdkafka
repo: php-rdkafka/php-rdkafka
extract: php-src/ext/rdkafka
metadata:
license-files: [LICENSE]
@@ -12,4 +12,7 @@ ext-rdkafka:
- librdkafka
lang: cpp
php-extension:
os:
- Linux
- Darwin
arg-type: custom

View File

@@ -16,3 +16,4 @@ ext-snappy:
lang: cpp
php-extension:
arg-type@unix: '--enable-snappy --with-snappy-includedir=@build_root_path@'
arg-type@windows: '--enable-snappy'

View File

@@ -11,4 +11,7 @@ ext-spx:
depends:
- ext-zlib
php-extension:
os:
- Linux
- Darwin
arg-type: '--enable-SPX@shared_suffix@'

View File

@@ -5,7 +5,6 @@ ext-swoole:
type: ghtar
repo: swoole/swoole-src
extract: php-src/ext/swoole
match: v6\.+
prefer-stable: true
metadata:
license-files: [LICENSE]
@@ -34,6 +33,9 @@ ext-swoole:
- ext-swoole-hook-odbc
lang: cpp
php-extension:
os:
- Linux
- Darwin
arg-type: custom
ext-swoole-hook-mysql:
type: php-extension
@@ -44,6 +46,9 @@ ext-swoole-hook-mysql:
suggests:
- ext-mysqli
php-extension:
os:
- Linux
- Darwin
arg-type: none
display-name: swoole
ext-swoole-hook-odbc:
@@ -52,6 +57,9 @@ ext-swoole-hook-odbc:
- ext-pdo
- unixodbc
php-extension:
os:
- Linux
- Darwin
arg-type: none
display-name: swoole
ext-swoole-hook-pgsql:
@@ -60,6 +68,9 @@ ext-swoole-hook-pgsql:
- ext-pgsql
- ext-pdo
php-extension:
os:
- Linux
- Darwin
arg-type: none
display-name: swoole
ext-swoole-hook-sqlite:
@@ -68,5 +79,8 @@ ext-swoole-hook-sqlite:
- ext-sqlite3
- ext-pdo
php-extension:
os:
- Linux
- Darwin
arg-type: none
display-name: swoole

View File

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

View File

@@ -8,7 +8,4 @@ ext-trader:
license-files: [LICENSE]
license: BSD-2-Clause
php-extension:
support:
BSD: wip
Windows: wip
arg-type: enable

View File

@@ -10,7 +10,7 @@ ext-uuid:
depends:
- libuuid
php-extension:
support:
Windows: wip
BSD: wip
os:
- Linux
- Darwin
arg-type: with-path

View File

@@ -12,7 +12,4 @@ ext-uv:
- libuv
- ext-sockets
php-extension:
support:
Windows: wip
BSD: wip
arg-type: with-path

View File

@@ -8,6 +8,9 @@ ext-xdebug:
license-files: [LICENSE]
license: Xdebug-1.03
php-extension:
os:
- Linux
- Darwin
zend-extension: true
build-static: false
build-shared: true

View File

@@ -11,8 +11,8 @@ ext-xhprof:
depends:
- ext-ctype
php-extension:
support:
Windows: wip
BSD: wip
os:
- Linux
- Darwin
arg-type: enable
build-with-php: true

View File

@@ -13,6 +13,5 @@ ext-xlswriter:
suggests:
- openssl
php-extension:
support:
BSD: wip
arg-type: custom
arg-type@windows: '--with-xlswriter'

View File

@@ -13,3 +13,4 @@ ext-xz:
- xz
php-extension:
arg-type: with-path
arg-type@windows: enable

View File

@@ -8,10 +8,8 @@ ext-zip:
metadata:
license-files: [LICENSE]
license: PHP-3.01
depends@unix:
depends:
- libzip
php-extension:
support:
BSD: wip
arg-type: custom
arg-type@windows: enable

View File

@@ -11,5 +11,8 @@ ext-zstd:
license: MIT
depends:
- zstd
suggests:
- ext-apcu
php-extension:
arg-type: '--enable-zstd --with-libzstd=@build_root_path@'
arg-type@windows: '--enable-zstd'

View File

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

View File

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

View File

@@ -0,0 +1,9 @@
gettext-win:
type: library
artifact:
source:
type: git
url: 'https://github.com/winlibs/gettext.git'
rev: '0.18'
static-libs@windows:
- libintl_a.lib

View File

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

View File

@@ -1,6 +1,17 @@
glfw:
type: library
artifact: glfw
frameworks:
- Cocoa
- CoreFoundation
- CoreVideo
- IOKit
- QuartzCore
headers:
- GLFW/glfw3.h
- GLFW/glfw3native.h
lang: cpp
static-libs@unix:
- libglfw3.a
static-libs@windows:
- glfw3.lib

View File

@@ -3,7 +3,7 @@ gmp:
artifact:
source:
type: filelist
url: 'https://ftp.gnu.org/gnu/gmp/'
url: 'https://ftpmirror.gnu.org/gnu/gmp/'
regex: '/href="(?<file>gmp-(?<version>[^"]+)\.tar\.xz)"/'
source-mirror:
type: url

View File

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

View File

@@ -2,9 +2,8 @@ krb5:
type: library
artifact:
source:
type: ghtagtar
repo: krb5/krb5
match: krb5.+-final
type: url
url: 'https://web.mit.edu/kerberos/dist/krb5/1.22/krb5-1.22.2.tar.gz'
metadata:
license-files: [NOTICE]
license: BSD-3-Clause

View File

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

View File

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

View File

@@ -16,3 +16,4 @@ libevent:
- libevent_core.a
- libevent_extra.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

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

View File

@@ -11,3 +11,5 @@ liblz4:
license: BSD-2-Clause
static-libs@unix:
- liblz4.a
static-libs@windows:
- lz4.lib

View File

@@ -14,3 +14,5 @@ libmaxminddb:
- maxminddb_config.h
static-libs@unix:
- libmaxminddb.a
static-libs@windows:
- libmaxminddb.lib

View File

@@ -0,0 +1,15 @@
libmpdec:
type: library
artifact:
source:
type: url
url: 'https://www.bytereef.org/software/mpdecimal/releases/mpdecimal-4.0.1.tar.gz'
metadata:
license-files: [COPYRIGHT.txt]
license: BSD-2-Clause
headers:
- mpdecimal.h
static-libs@unix:
- libmpdec.a
static-libs@windows:
- libmpdec_a.lib

View File

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

View File

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

View File

@@ -6,7 +6,6 @@ libssh2:
repo: libssh2/libssh2
match: libssh2.+\.tar\.gz
prefer-stable: true
binary: hosted
metadata:
license-files: [COPYING]
license: BSD-3-Clause

View File

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

View File

@@ -9,3 +9,5 @@ libuv:
license: MIT
static-libs@unix:
- libuv.a
static-libs@windows:
- libuv.lib

View File

@@ -13,3 +13,6 @@ libxslt:
static-libs@unix:
- libxslt.a
- libexslt.a
static-libs@windows:
- libxslt_a.lib
- libexslt_a.lib

9
config/pkg/lib/mpir.yml Normal file
View File

@@ -0,0 +1,9 @@
mpir:
type: library
artifact:
source:
type: git
url: 'https://github.com/winlibs/mpir.git'
rev: master
static-libs@windows:
- mpir_a.lib

View File

@@ -4,13 +4,12 @@ openssl:
source:
type: ghrel
repo: openssl/openssl
match: openssl.+\.tar\.gz
match: openssl-3.+\.tar\.gz
prefer-stable: true
source-mirror:
type: filelist
url: 'https://www.openssl.org/source/'
regex: '/href="(?<file>openssl-(?<version>[^"]+)\.tar\.gz)"/'
binary: hosted
regex: '/href="(?<file>openssl-(?<version>3\.[^"]+)\.tar\.gz)"/'
metadata:
license-files: [LICENSE.txt]
license: OpenSSL

View File

@@ -10,3 +10,4 @@ pthreads4w:
license: Apache-2.0
static-libs@windows:
- libpthreadVC3.lib
- pthreadVC3.lib

View File

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

View File

@@ -15,6 +15,13 @@ snappy:
- snappy-c.h
- snappy-sinksource.h
- snappy-stubs-public.h
headers@windows:
- snappy.h
- snappy-c.h
- snappy-sinksource.h
- snappy-stubs-public.h
lang: cpp
static-libs@unix:
- libsnappy.a
static-libs@windows:
- snappy.lib

View File

@@ -10,3 +10,5 @@ tidy:
license: W3C
static-libs@unix:
- libtidy.a
static-libs@windows:
- tidy_a.lib

View File

@@ -8,6 +8,8 @@ watcher:
metadata:
license-files: [license]
license: MIT
frameworks:
- CoreServices
headers:
- wtr/watcher-c.h
lang: cpp

View File

@@ -0,0 +1,14 @@
wineditline:
type: library
artifact:
source:
type: git
url: 'https://github.com/winlibs/wineditline.git'
rev: master
metadata:
license-files: [COPYING]
license: GPL-2.0-or-later
headers:
- editline
static-libs@windows:
- edit_a.lib

View File

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

View File

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

View File

@@ -18,4 +18,5 @@ zstd:
static-libs@unix:
- libzstd.a
static-libs@windows:
- zstd_static.lib
- zstd.lib
- libzstd.lib

View File

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

View File

@@ -11,8 +11,16 @@ frankenphp:
depends:
- php-embed
- go-xcaddy
depends@windows:
- php-embed
- go-win
- pthreads4w
suggests@unix:
- brotli
- watcher
suggests@windows:
- brotli
static-bins@unix:
- frankenphp
static-bins@windows:
- frankenphp.exe

View File

@@ -0,0 +1,10 @@
go-win:
type: target
artifact:
binary: custom
env:
GOROOT: '{pkg_root_path}/go-win'
GOBIN: '{pkg_root_path}/go-win/bin'
GOPATH: '{pkg_root_path}/go-win/go'
path@windows:
- '{pkg_root_path}/go-win/bin'

View File

@@ -1,7 +0,0 @@
{
"repo": "static-php/static-php-cli-hosted",
"prefer-stable": true,
"match-pattern-linux": "{name}-{arch}-{os}-{libc}-{libcver}.txz",
"match-pattern-macos": "{name}-{arch}-{os}.txz",
"match-pattern-windows": "{name}-{arch}-{os}.tgz"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,14 @@
<template>
<div>
<div v-if="missing" class="warning custom-block" style="margin-bottom: 16px">
<p class="custom-block-title">WARNING</p>
<p>Extension list is not generated yet. Run <code>bin/spc dev:gen-ext-docs</code> to generate it.</p>
</div>
<h2>{{ I18N[lang].selectedSystem }}</h2>
<div class="option-line">
<span v-for="(item, index) in osList" :key="index" style="margin-right: 8px">
<input type="radio" :id="'os-' + item.os" :value="item.os" :disabled="item.disabled === true" v-model="selectedSystem" />
<input type="radio" :id="'os-' + item.os" :value="item.os" v-model="selectedSystem" />
<label :for="'os-' + item.os">{{ item.label }}</label>
</span>
</div>
@@ -13,13 +18,14 @@
<option value="aarch64" :disabled="selectedSystem === 'windows'">aarch64</option>
</select>
</div>
<h2>{{ I18N[lang].selectExt }}{{ checkedExts.length > 0 ? (' (' + checkedExts.length + ')') : '' }}</h2>
<div class="box">
<input class="input" v-model="filterText" :placeholder="I18N[lang].searchPlaceholder" />
<br>
<div v-for="item in extFilter" :key="item" class="ext-item">
<div v-for="item in extByOS" :key="item" class="ext-item">
<span>
<input type="checkbox" :id="item" :value="item" v-model="checkedExts" :disabled="extDisableList.indexOf(item) !== -1">
<input type="checkbox" :id="item" :value="item" v-model="checkedExts" />
<label :for="item">
<span>{{ highlightItem(item, 0) }}</span>
<span style="color: orangered; font-weight: bolder">{{ highlightItem(item, 1) }}</span>
@@ -32,50 +38,31 @@
<div class="my-btn" v-if="selectedSystem !== 'windows'" @click="selectAll">{{ I18N[lang].selectAll }}</div>
<div class="my-btn" @click="checkedExts = []">{{ I18N[lang].selectNone }}</div>
<details class="details custom-block" open>
<summary>{{ I18N[lang].buildLibs }}{{ checkedLibs.length > 0 ? (' (' + checkedLibs.length + ')') : '' }}</summary>
<div class="box">
<div v-for="(item, index) in libContain" :key="index" class="ext-item">
<input type="checkbox" :id="index" :value="item" v-model="checkedLibs" :disabled="libDisableList.indexOf(item) !== -1">
<label :for="index">{{ item }}</label>
</div>
</div>
</details>
<div class="tip custom-block">
<p class="custom-block-title">TIP</p>
<p>{{ I18N[lang].depTips }}</p>
<p>{{ I18N[lang].depTips2 }}</p>
</div>
<h2>{{ I18N[lang].buildTarget }}</h2>
<div class="box">
<div v-for="item in TARGET" :key="item" class="ext-item">
<input type="checkbox" :id="'build_' + item" :value="item" v-model="checkedTargets" @change="onTargetChange">
<input type="checkbox" :id="'build_' + item" :value="item" v-model="checkedTargets" />
<label :for="'build_' + item">{{ item }}</label>
</div>
</div>
<div v-if="selectedPhpVersion === '7.4' && (checkedTargets.indexOf('micro') !== -1 || checkedTargets.indexOf('all') !== -1)" class="warning custom-block">
<p class="custom-block-title">WARNING</p>
<p>{{ I18N[lang].microUnavailable }}</p>
</div>
<div v-if="selectedSystem === 'windows' && (checkedTargets.indexOf('fpm') !== -1 || checkedTargets.indexOf('embed') !== -1 || checkedTargets.indexOf('frankenphp') !== -1)" class="warning custom-block">
<div v-if="selectedSystem === 'windows' && (checkedTargets.includes('fpm') || checkedTargets.includes('embed') || checkedTargets.includes('frankenphp'))" class="warning custom-block">
<p class="custom-block-title">WARNING</p>
<p>{{ I18N[lang].windowsSAPIUnavailable }}</p>
</div>
<h2>{{ I18N[lang].buildOptions }}</h2>
<!-- Refactor all build options in table -->
<table>
<!-- buildEnvironment -->
<!-- Build Environment -->
<tr>
<td>{{ I18N[lang].buildEnvironment }}</td>
<td>
<select v-model="selectedEnv">
<option value="native">{{ I18N[lang].buildEnvNative }}</option>
<option value="spc">{{ I18N[lang].buildEnvSpc }}</option>
<option value="docker" v-if="selectedSystem !== 'windows'">{{ I18N[lang].buildEnvDocker }}</option>
<option value="native">{{ I18N[lang].buildEnvNative }}</option>
</select>
</td>
</tr>
<!-- Download PHP version -->
<!-- PHP Version -->
<tr>
<td>{{ I18N[lang].downloadPhpVersion }}</td>
<td>
@@ -84,70 +71,85 @@
</select>
</td>
</tr>
<!-- Enable debug message -->
<!-- Verbose log -->
<tr>
<td>{{ I18N[lang].useDebug }}</td>
<td>{{ I18N[lang].useVerbose }}</td>
<td>
<input type="radio" id="debug-yes" :value="1" v-model="debug" />
<label for="debug-yes">{{ I18N[lang].yes }}</label>
<input type="radio" id="debug-no" :value="0" v-model="debug" />
<label for="debug-no">{{ I18N[lang].no }}</label>
<select v-model="verbosity">
<option value="">{{ I18N[lang].verboseNone }}</option>
<option value="-v">-v</option>
<option value="-vv">-vv</option>
<option value="-vvv">-vvv</option>
</select>
</td>
</tr>
<!-- Enable ZTS -->
<tr>
<td>{{ I18N[lang].useZTS }}</td>
<td>
<input type="radio" id="zts-yes" :value="1" v-model="zts" />
<input type="radio" id="zts-yes" :value="true" v-model="zts" />
<label for="zts-yes">{{ I18N[lang].yes }}</label>
<input type="radio" id="zts-no" :value="0" v-model="zts" />
<input type="radio" id="zts-no" :value="false" v-model="zts" />
<label for="zts-no">{{ I18N[lang].no }}</label>
</td>
</tr>
<!-- download corresponding extensions -->
<!-- Parallel downloads -->
<tr>
<td>{{ I18N[lang].resultShowDownload }}</td>
<td>{{ I18N[lang].dlParallel }}</td>
<td>
<input type="radio" id="show-download-yes" :value="1" v-model="downloadByExt" />
<label for="show-download-yes">{{ I18N[lang].yes }}</label>
<input type="radio" id="show-download-no" :value="0" v-model="downloadByExt" />
<label for="show-download-no">{{ I18N[lang].no }}</label>
<input class="number-input" type="number" v-model.number="dlParallel" min="1" max="50" />
</td>
</tr>
<!-- Download pre-built -->
<!-- Retry count -->
<tr>
<td>{{ I18N[lang].dlRetry }}</td>
<td>
<input class="number-input" type="number" v-model.number="dlRetry" min="0" max="100" />
</td>
</tr>
<!-- Prefer binary (pre-built) -->
<tr>
<td>{{ I18N[lang].usePreBuilt }}</td>
<td>
<input type="radio" id="pre-built-yes" :value="1" v-model="preBuilt" />
<input type="radio" id="pre-built-yes" :value="true" v-model="preBuilt" />
<label for="pre-built-yes">{{ I18N[lang].yes }}</label>
<input type="radio" id="pre-built-no" :value="0" v-model="preBuilt" />
<input type="radio" id="pre-built-no" :value="false" v-model="preBuilt" />
<label for="pre-built-no">{{ I18N[lang].no }}</label>
</td>
</tr>
<!-- Enable UPX -->
<!-- Enable UPX (linux/windows only) -->
<tr v-if="selectedSystem !== 'macos'">
<td>{{ I18N[lang].useUPX }}</td>
<td>
<input type="radio" id="upx-yes" :value="1" v-model="enableUPX" />
<input type="radio" id="upx-yes" :value="true" v-model="enableUPX" />
<label for="upx-yes">{{ I18N[lang].yes }}</label>
<input type="radio" id="upx-no" :value="0" v-model="enableUPX" />
<input type="radio" id="upx-no" :value="false" v-model="enableUPX" />
<label for="upx-no">{{ I18N[lang].no }}</label>
</td>
</tr>
<!-- Keep debug symbols (--no-strip) -->
<tr>
<td>{{ I18N[lang].noStrip }}</td>
<td>
<input type="radio" id="nostrip-yes" :value="true" v-model="noStrip" />
<label for="nostrip-yes">{{ I18N[lang].yes }}</label>
<input type="radio" id="nostrip-no" :value="false" v-model="noStrip" />
<label for="nostrip-no">{{ I18N[lang].no }}</label>
</td>
</tr>
</table>
<h2>{{ I18N[lang].hardcodedINI }}</h2>
<textarea class="textarea" :placeholder="I18N[lang].hardcodedINIPlacehoder" v-model="hardcodedINIData" rows="5" />
<textarea class="textarea" :placeholder="I18N[lang].hardcodedINIPlaceholder" v-model="hardcodedINIData" rows="5" />
<h2>{{ I18N[lang].resultShow }}</h2>
<!-- SPC Binary Download Command -->
<!-- SPC Binary Download Command (spc env only) -->
<div v-if="selectedEnv === 'spc'" class="command-container">
<b>{{ I18N[lang].downloadSPCBinaryCommand }}</b>
<div v-if="selectedSystem !== 'windows'" class="command-preview">
<div class="command-content">
{{ spcDownloadCommand }}
</div>
<button class="copy-btn" @click="copyToClipboard(spcDownloadCommand)" :class="{ 'copied': copiedStates.spcDownload }">
<div class="command-content">{{ spcDownloadCommand }}</div>
<button class="copy-btn" @click="copyToClipboard(spcDownloadCommand, 'spcDownload')" :class="{ 'copied': copiedStates.spcDownload }">
{{ copiedStates.spcDownload ? I18N[lang].copied : I18N[lang].copy }}
</button>
</div>
@@ -155,56 +157,17 @@
<div class="warning custom-block">
<p class="custom-block-title">WARNING</p>
<p>{{ I18N[lang].windowsDownSPCWarning }}</p>
<a href="https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe" target="_blank">https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe</a>
<a href="https://dl.static-php.dev/v3/spc-bin/latest/spc-windows-x86_64.exe" target="_blank">https://dl.static-php.dev/v3/spc-bin/latest/spc-windows-x86_64.exe</a>
</div>
</div>
</div>
<!-- Download Commands -->
<div v-if="downloadByExt" class="command-container">
<b>{{ I18N[lang].downloadExtOnlyCommand }}</b>
<div class="command-preview">
<div class="command-content">
{{ downloadExtCommand }}
</div>
<button class="copy-btn" @click="copyToClipboard(downloadExtCommand)" :class="{ 'copied': copiedStates.downloadExt }">
{{ copiedStates.downloadExt ? I18N[lang].copied : I18N[lang].copy }}
</button>
</div>
</div>
<div v-else class="command-container">
<b>{{ I18N[lang].downloadAllCommand }}</b>
<div class="command-preview">
<div class="command-content">
{{ downloadAllCommand }}
</div>
<button class="copy-btn" @click="copyToClipboard(downloadAllCommand)" :class="{ 'copied': copiedStates.downloadAll }">
{{ copiedStates.downloadAll ? I18N[lang].copied : I18N[lang].copy }}
</button>
</div>
</div>
<!-- UPX Download Command -->
<div class="command-container" v-if="enableUPX">
<b>{{ I18N[lang].downloadUPXCommand }}</b>
<div class="command-preview">
<div class="command-content">
{{ downloadPkgCommand }}
</div>
<button class="copy-btn" @click="copyToClipboard(downloadPkgCommand)" :class="{ 'copied': copiedStates.downloadPkg }">
{{ copiedStates.downloadPkg ? I18N[lang].copied : I18N[lang].copy }}
</button>
</div>
</div>
<!-- Doctor Command -->
<div class="command-container">
<b>{{ I18N[lang].doctorCommand }}</b>
<div class="command-preview">
<div class="command-content">
{{ doctorCommandString }}
</div>
<button class="copy-btn" @click="copyToClipboard(doctorCommandString)" :class="{ 'copied': copiedStates.doctor }">
<div class="command-content">{{ doctorCommandString }}</div>
<button class="copy-btn" @click="copyToClipboard(doctorCommandString, 'doctor')" :class="{ 'copied': copiedStates.doctor }">
{{ copiedStates.doctor ? I18N[lang].copied : I18N[lang].copy }}
</button>
</div>
@@ -214,23 +177,19 @@
<div class="command-container">
<b>{{ I18N[lang].compileCommand }}</b>
<div class="command-preview">
<div class="command-content">
{{ buildCommandString }}
</div>
<button class="copy-btn" @click="copyToClipboard(buildCommandString)" :class="{ 'copied': copiedStates.build }">
<div class="command-content">{{ buildCommandString }}</div>
<button class="copy-btn" @click="copyToClipboard(buildCommandString, 'build')" :class="{ 'copied': copiedStates.build }">
{{ copiedStates.build ? I18N[lang].copied : I18N[lang].copy }}
</button>
</div>
</div>
<!-- Craft.yml -->
<!-- craft.yml -->
<div class="command-container">
<b>craft.yml</b>
<div class="command-preview pre">
<div class="command-content">
{{ craftCommandString }}
</div>
<button class="copy-btn" @click="copyToClipboard(craftCommandString)" :class="{ 'copied': copiedStates.craft }">
<div class="command-content">{{ craftCommandString }}</div>
<button class="copy-btn" @click="copyToClipboard(craftCommandString, 'craft')" :class="{ 'copied': copiedStates.craft }">
{{ copiedStates.craft ? I18N[lang].copied : I18N[lang].copy }}
</button>
</div>
@@ -245,14 +204,12 @@ export default {
</script>
<script setup lang="ts">
import {computed, ref, watch} from "vue";
import extData from '../config/ext.json';
import libData from '../config/lib.json';
import { getAllExtLibsByDeps } from './DependencyUtil.js';
import { computed, ref, watch } from 'vue';
// @ts-ignore VitePress data loader — transformed at build time
import { data as extDataRaw } from '../extensions.data.js';
// Constants
const OS_MAP = new Map([['linux', 'Linux'], ['macos', 'Darwin'], ['windows', 'Windows']]);
const TARGET = ['cli', 'fpm', 'micro', 'embed', 'frankenphp', 'all'];
const TARGET = ['cli', 'fpm', 'micro', 'embed', 'frankenphp', 'cgi'];
const availablePhpVersions = ['8.0', '8.1', '8.2', '8.3', '8.4', '8.5'];
// Props
@@ -263,154 +220,135 @@ const props = defineProps({
}
});
// Reactive data
const ext = ref(extData);
const lib = ref(libData);
const libContain = ref([]);
// Extension data
const missing = extDataRaw.missing ?? false;
const allExtensions: Array<{ name: string; linux: boolean; macos: boolean; windows: boolean }> = extDataRaw.extensions ?? [];
// Reactive state
const filterText = ref('');
const checkedExts = ref([]);
const checkedLibs = ref([]);
const extDisableList = ref([]);
const libDisableList = ref([]);
const checkedTargets = ref(['cli']);
const selectedEnv = ref('spc');
const checkedExts = ref<string[]>([]);
const checkedTargets = ref<string[]>(['cli']);
const selectedEnv = ref<'spc' | 'native'>('spc');
const selectedPhpVersion = ref('8.4');
const selectedSystem = ref('linux');
const selectedArch = ref('x86_64');
const debug = ref(0);
const zts = ref(0);
const downloadByExt = ref(1);
const preBuilt = ref(1);
const enableUPX = ref(0);
const selectedSystem = ref<'linux' | 'macos' | 'windows'>('linux');
const selectedArch = ref<'x86_64' | 'aarch64'>('x86_64');
const verbosity = ref('');
const zts = ref(false);
const preBuilt = ref(true);
const enableUPX = ref(false);
const noStrip = ref(false);
const dlParallel = ref(10);
const dlRetry = ref(5);
const hardcodedINIData = ref('');
const buildCommand = ref('--build-cli');
// Copy states
const copiedStates = ref({
const copiedStates = ref<Record<string, boolean>>({
spcDownload: false,
downloadExt: false,
downloadAll: false,
downloadPkg: false,
doctor: false,
build: false,
craft: false,
doctor: false
});
// OS list
const osList = [
{ os: 'linux', label: 'Linux', disabled: false },
{ os: 'macos', label: 'macOS', disabled: false },
{ os: 'windows', label: 'Windows', disabled: false },
{ os: 'linux', label: 'Linux' },
{ os: 'macos', label: 'macOS' },
{ os: 'windows', label: 'Windows' },
];
// Computed properties
const extFilter = computed(() => {
return Object.entries(ext.value)
.filter(([name]) => isSupported(name, selectedSystem.value))
.map(([name]) => name);
// Computed: extensions filtered by selected OS
const extByOS = computed(() => {
return allExtensions
.filter(item => {
if (selectedSystem.value === 'linux') return item.linux;
if (selectedSystem.value === 'macos') return item.macos;
if (selectedSystem.value === 'windows') return item.windows;
return true;
})
.map(item => item.name);
});
const extList = computed(() => checkedExts.value.join(','));
const additionalLibs = computed(() => {
const ls = checkedLibs.value.filter(item => libDisableList.value.indexOf(item) === -1);
return ls.length > 0 ? ` --with-libs="${ls.join(',')}"` : '';
});
const extList = computed(() => [...checkedExts.value].sort().join(','));
const spcCommand = computed(() => {
switch (selectedEnv.value) {
case 'native':
return 'bin/spc';
case 'spc':
return selectedSystem.value === 'windows' ? '.\\spc.exe' : './spc';
case 'docker':
return 'bin/spc-alpine-docker';
default:
return '';
}
if (selectedEnv.value === 'native') return 'bin/spc';
return selectedSystem.value === 'windows' ? '.\\spc.exe' : './spc';
});
const spcDownloadCommand = computed(() => {
if (selectedSystem.value === 'windows') return '';
return `curl -fsSL -o spc.tgz https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-${selectedSystem.value}-${selectedArch.value}.tar.gz && tar -zxvf spc.tgz && rm spc.tgz`;
const os = selectedSystem.value === 'macos' ? 'macos' : 'linux';
const arch = selectedArch.value;
return `curl -#fSL https://dl.static-php.dev/v3/spc-bin/latest/spc-${os}-${arch} -o spc && chmod +x spc`;
});
const doctorCommandString = computed(() => `${spcCommand.value} doctor --auto-fix`);
const displayINI = computed(() => {
const split = hardcodedINIData.value.split('\n');
const validLines = split.filter(x => x.indexOf('=') >= 1);
return validLines.length > 0 ? ' ' + validLines.map(x => `-I "${x}"`).join(' ') : '';
});
const downloadAllCommand = computed(() => {
return `${spcCommand.value} download --all --with-php=${selectedPhpVersion.value}${preBuilt.value ? ' --prefer-pre-built' : ''}${debug.value ? ' --debug' : ''}`;
});
const downloadExtCommand = computed(() => {
return `${spcCommand.value} download --with-php=${selectedPhpVersion.value} --for-extensions "${extList.value}"${preBuilt.value ? ' --prefer-pre-built' : ''}${debug.value ? ' --debug' : ''}`;
});
const downloadPkgCommand = computed(() => {
return `${spcCommand.value} install-pkg upx${debug.value ? ' --debug' : ''}`;
});
const doctorCommandString = computed(() => {
return `${spcCommand.value} doctor --auto-fix${debug.value ? ' --debug' : ''}`;
const lines = hardcodedINIData.value.split('\n').filter(x => x.indexOf('=') >= 1);
return lines.length > 0 ? ' ' + lines.map(x => `-I "${x}"`).join(' ') : '';
});
const buildCommandString = computed(() => {
return `${spcCommand.value} build ${buildCommand.value} "${extList.value}"${additionalLibs.value}${debug.value ? ' --debug' : ''}${zts.value ? ' --enable-zts' : ''}${enableUPX.value ? ' --with-upx-pack' : ''}${displayINI.value}`;
const sapi = checkedTargets.value.map(x => `--build-${x}`).join(' ');
const php = ` --dl-with-php=${selectedPhpVersion.value}`;
const parallel = ` --dl-parallel=${dlParallel.value}`;
const retry = ` --dl-retry=${dlRetry.value}`;
const ignoreCache = ' --dl-ignore-cache=php-src';
const binary = preBuilt.value ? ' --dl-prefer-binary' : '';
const strip = noStrip.value ? ' --no-strip' : '';
const upx = enableUPX.value ? ' --with-upx-pack' : '';
const ztsFlag = zts.value ? ' --enable-zts' : '';
const verbose = verbosity.value ? ` ${verbosity.value}` : '';
return `${spcCommand.value} build:php "${extList.value}" ${sapi}${php}${parallel}${retry}${ignoreCache}${binary}${strip}${upx}${ztsFlag}${displayINI.value}${verbose}`;
});
const craftCommandString = computed(() => {
let str = `php-version: ${selectedPhpVersion.value}\n`;
str += `extensions: "${extList.value}"\n`;
if (checkedTargets.value.join(',') === 'all') {
str += 'sapi: ' + ['cli', 'fpm', 'micro', 'embed', 'frankenphp'].join(',') + '\n';
// sapi
if (checkedTargets.value.length === 1) {
str += `sapi:\n - ${checkedTargets.value[0]}\n`;
} else {
str += `sapi: ${checkedTargets.value.join(',')}\n`;
str += `sapi:\n`;
checkedTargets.value.forEach(s => { str += ` - ${s}\n`; });
}
if (additionalLibs.value) {
str += `libs: ${additionalLibs.value.replace('--with-libs="', '').replace('"', '').trim()}\n`;
// verbosity (Symfony OutputInterface constants: 64=-v, 128=-vv, 256=-vvv)
const verbosityMap: Record<string, number> = { '-v': 64, '-vv': 128, '-vvv': 256 };
if (verbosity.value && verbosityMap[verbosity.value]) {
str += `verbosity: ${verbosityMap[verbosity.value]}\n`;
}
if (debug.value) {
str += 'debug: true\n';
// download-options
str += `download-options:\n`;
str += ` parallel: ${dlParallel.value}\n`;
str += ` retry: ${dlRetry.value}\n`;
str += ` ignore-cache: php-src\n`;
if (preBuilt.value) str += ` prefer-binary: true\n`;
// build-options (only when needed)
const buildOpts: string[] = [];
if (noStrip.value) buildOpts.push(` no-strip: true`);
if (enableUPX.value) buildOpts.push(` with-upx-pack: true`);
if (zts.value) buildOpts.push(` enable-zts: true`);
const iniLines = hardcodedINIData.value.split('\n').filter(x => x.indexOf('=') >= 1);
if (iniLines.length > 0) {
buildOpts.push(` with-hardcoded-ini:`);
iniLines.forEach(line => buildOpts.push(` - "${line}"`));
}
if (preBuilt.value) {
str += 'download-options:\n';
str += ' prefer-pre-built: true\n';
}
str += '{{position_hold}}';
if (enableUPX.value) {
str += ' with-upx-pack: true\n';
}
if (zts.value) {
str += ' enable-zts: true\n';
}
if (!str.endsWith('{{position_hold}}')) {
str = str.replace('{{position_hold}}', 'build-options:\n');
} else {
str = str.replace('{{position_hold}}', '');
if (buildOpts.length > 0) {
str += `build-options:\n${buildOpts.join('\n')}\n`;
}
return str;
});
// Methods
const isSupported = (extName: string, os: string) => {
const osName = OS_MAP.get(os);
const osSupport = ext.value[extName]?.support?.[osName] ?? 'yes';
return osSupport === 'yes' || osSupport === 'partial';
};
const selectCommon = () => {
checkedExts.value = [
const common = [
'apcu', 'bcmath', 'calendar', 'ctype', 'curl', 'dba', 'dom', 'exif',
'filter', 'fileinfo', 'gd', 'iconv', 'intl', 'mbstring', 'mbregex',
'mysqli', 'mysqlnd', 'openssl', 'opcache', 'pcntl', 'pdo', 'pdo_mysql',
@@ -418,30 +356,18 @@ const selectCommon = () => {
'session', 'simplexml', 'sockets', 'sodium', 'sqlite3', 'tokenizer',
'xml', 'xmlreader', 'xmlwriter', 'xsl', 'zip', 'zlib',
];
const supported = new Set(extByOS.value);
checkedExts.value = common.filter(e => supported.has(e));
};
const selectAll = () => {
checkedExts.value = [...extFilter.value];
};
const onTargetChange = (event: Event) => {
const target = (event.target as HTMLInputElement).value;
if (target === 'all') {
checkedTargets.value = ['all'];
} else {
const allIndex = checkedTargets.value.indexOf('all');
if (allIndex !== -1) {
checkedTargets.value.splice(allIndex, 1);
}
}
buildCommand.value = checkedTargets.value.map(x => `--build-${x}`).join(' ');
checkedExts.value = [...extByOS.value];
};
const highlightItem = (item: string, step: number) => {
if (!filterText.value || !item.includes(filterText.value)) {
return step === 0 ? item : '';
}
const index = item.indexOf(filterText.value);
switch (step) {
case 0: return item.substring(0, index);
@@ -451,30 +377,12 @@ const highlightItem = (item: string, step: number) => {
}
};
const copyToClipboard = async (text: string) => {
const copyToClipboard = async (text: string, key: string) => {
try {
await navigator.clipboard.writeText(text);
// Find which command was copied and update its state
const commandMap = {
[spcDownloadCommand.value]: 'spcDownload',
[downloadExtCommand.value]: 'downloadExt',
[downloadAllCommand.value]: 'downloadAll',
[downloadPkgCommand.value]: 'downloadPkg',
[doctorCommandString.value]: 'doctor',
[buildCommandString.value]: 'build',
[craftCommandString.value]: 'craft'
};
const key = commandMap[text];
if (key) {
copiedStates.value[key] = true;
setTimeout(() => {
copiedStates.value[key] = false;
}, 2000);
}
} catch (err) {
console.error('Failed to copy text: ', err);
// Fallback for older browsers
copiedStates.value[key] = true;
setTimeout(() => { copiedStates.value[key] = false; }, 2000);
} catch {
const textArea = document.createElement('textarea');
textArea.value = text;
document.body.appendChild(textArea);
@@ -484,113 +392,17 @@ const copyToClipboard = async (text: string) => {
}
};
const calculateExtDepends = (input: string[]) => {
const result = new Set<string>();
const dfs = (node: string) => {
let depends: string[] = [];
if (selectedSystem.value === 'linux') {
depends = ext.value[node]?.['ext-depends-linux'] ?? ext.value[node]?.['ext-depends-unix'] ?? ext.value[node]?.['ext-depends'] ?? [];
} else if (selectedSystem.value === 'macos') {
depends = ext.value[node]?.['ext-depends-macos'] ?? ext.value[node]?.['ext-depends-unix'] ?? ext.value[node]?.['ext-depends'] ?? [];
} else if (selectedSystem.value === 'windows') {
depends = ext.value[node]?.['ext-depends-windows'] ?? ext.value[node]?.['ext-depends'] ?? [];
}
if (depends.length === 0) return;
depends.forEach(dep => {
result.add(dep);
dfs(dep);
});
};
input.forEach(dfs);
return Array.from(result);
};
const calculateExtLibDepends = (input: string[]) => {
const result = new Set<string>();
const dfsLib = (node: string) => {
let depends: string[] = [];
if (selectedSystem.value === 'linux') {
depends = lib.value[node]?.['lib-depends-linux'] ?? lib.value[node]?.['lib-depends-unix'] ?? lib.value[node]?.['lib-depends'] ?? [];
} else if (selectedSystem.value === 'macos') {
depends = lib.value[node]?.['lib-depends-macos'] ?? lib.value[node]?.['lib-depends-unix'] ?? lib.value[node]?.['lib-depends'] ?? [];
} else if (selectedSystem.value === 'windows') {
depends = lib.value[node]?.['lib-depends-windows'] ?? lib.value[node]?.['lib-depends'] ?? [];
}
if (depends.length === 0) return;
depends.forEach(dep => {
result.add(dep);
dfsLib(dep);
});
};
const dfsExt = (node: string) => {
let depends: string[] = [];
if (selectedSystem.value === 'linux') {
depends = ext.value[node]?.['lib-depends-linux'] ?? ext.value[node]?.['lib-depends-unix'] ?? ext.value[node]?.['lib-depends'] ?? [];
} else if (selectedSystem.value === 'macos') {
depends = ext.value[node]?.['lib-depends-macos'] ?? ext.value[node]?.['lib-depends-unix'] ?? ext.value[node]?.['lib-depends'] ?? [];
} else if (selectedSystem.value === 'windows') {
depends = ext.value[node]?.['lib-depends-windows'] ?? ext.value[node]?.['lib-depends'] ?? [];
}
if (depends.length === 0) return;
depends.forEach(dep => {
result.add(dep);
dfsLib(dep);
});
};
input.forEach(dfsExt);
return Array.from(result);
};
// Watchers
watch(selectedSystem, () => {
if (selectedSystem.value === 'windows') {
selectedArch.value = 'x86_64';
enableUPX.value = false;
}
// Reset related values when OS changes
checkedExts.value = [];
enableUPX.value = 0;
});
watch(checkedExts, (newValue) => {
// Apply ext-depends
extDisableList.value = calculateExtDepends(newValue);
extDisableList.value.forEach(x => {
if (checkedExts.value.indexOf(x) === -1) {
checkedExts.value.push(x);
}
});
checkedExts.value.sort();
const calculated = getAllExtLibsByDeps({ ext: ext.value, lib: lib.value, os: selectedSystem.value }, checkedExts.value);
libContain.value = calculated.libs.sort();
// Apply lib-depends
checkedLibs.value = [];
libDisableList.value = calculateExtLibDepends(calculated.exts);
libDisableList.value.forEach(x => {
if (checkedLibs.value.indexOf(x) === -1) {
checkedLibs.value.push(x);
}
});
}, { deep: true });
// I18N
const I18N = {
const I18N: Record<string, Record<string, string>> = {
zh: {
selectExt: '选择扩展',
buildTarget: '选择编译目标',
@@ -598,8 +410,8 @@ const I18N = {
buildEnvironment: '编译环境',
buildEnvNative: '本地构建Git 源码)',
buildEnvSpc: '本地构建(独立 spc 二进制)',
buildEnvDocker: 'Alpine Docker 构建',
useDebug: '是否开启调试输出',
useVerbose: '是否输出详细日志',
verboseNone: '不输出(默认)',
yes: '是',
no: '否',
resultShow: '结果展示',
@@ -608,28 +420,22 @@ const I18N = {
selectNone: '全部取消选择',
useZTS: '是否编译线程安全版',
hardcodedINI: '硬编码 INI 选项',
hardcodedINIPlacehoder: '如需要硬编码 ini每行写一个例如memory_limit=2G',
resultShowDownload: '是否展示仅下载对应扩展依赖的命令',
downloadExtOnlyCommand: '只下载对应扩展的依赖包命令',
downloadAllCommand: '下载所有依赖包命令',
downloadUPXCommand: '下载 UPX 命令',
hardcodedINIPlaceholder: '如需要硬编码 ini每行写一个例如memory_limit=2G',
compileCommand: '编译命令',
downloadPhpVersion: '下载 PHP 版本',
downloadSPCBinaryCommand: '下载 spc 二进制命令',
selectedArch: '选择系统架构',
selectedSystem: '选择操作系统',
buildLibs: '要构建的库',
depTips: '选择扩展后,不可选中的项目为必需的依赖,编译的依赖库列表中可选的为现有扩展和依赖库的可选依赖。选择可选依赖后,将生成 --with-libs 参数。',
depTips2: '无法同时构建所有扩展,因为有些扩展之间相互冲突。请根据需要选择扩展。',
microUnavailable: 'micro 不支持 PHP 7.4 及更早版本!',
windowsSAPIUnavailable: 'Windows 目前不支持 fpm、embed、frankenphp 构建!',
useUPX: '是否开启 UPX 压缩(减小二进制体积)',
windowsDownSPCWarning: 'Windows 下请手动下载 spc.exe 二进制文件,解压到当前目录并重命名为 spc.exe',
usePreBuilt: '如果可能,下载预编译的依赖库(减少编译时间)',
windowsDownSPCWarning: 'Windows 下请手动下载 spc.exe 二进制文件!',
usePreBuilt: '如果可能,使用预编译的依赖库(减少编译时间)',
searchPlaceholder: '搜索扩展...',
copy: '复制',
copied: '已复制',
doctorCommand: '自动检查和准备构建环境命令',
dlParallel: '并行下载数1-50',
dlRetry: '失败重试次数',
noStrip: '保留调试符号(--no-strip',
},
en: {
selectExt: 'Select Extensions',
@@ -638,43 +444,58 @@ const I18N = {
buildEnvironment: 'Build Environment',
buildEnvNative: 'Native build (Git source code)',
buildEnvSpc: 'Native build (standalone spc binary)',
buildEnvDocker: 'Alpine docker build',
useDebug: 'Enable debug message',
useVerbose: 'Verbose log output',
verboseNone: 'None (default)',
yes: 'Yes',
no: 'No',
resultShow: 'Result',
selectCommon: 'Select common extensions',
selectAll: 'Select all',
selectNone: 'Unselect all',
useZTS: 'Enable ZTS',
useZTS: 'Enable ZTS (thread-safe)',
hardcodedINI: 'Hardcoded INI options',
hardcodedINIPlacehoder: 'If you need to hardcode ini, write one per line, for example: memory_limit=2G',
resultShowDownload: 'Download with corresponding extension dependencies',
downloadExtOnlyCommand: 'Download sources by extensions command',
downloadAllCommand: 'Download all sources command',
downloadUPXCommand: 'Download UPX command',
compileCommand: 'Compile command',
downloadPhpVersion: 'Download PHP version',
downloadSPCBinaryCommand: 'Download spc binary command',
selectedArch: 'Select build architecture',
selectedSystem: 'Select Build OS',
buildLibs: 'Select Dependencies',
depTips: 'After selecting the extensions, the unselectable items are essential dependencies. In the compiled dependencies list, optional dependencies consist of existing extensions and optional dependencies of libraries. Optional dependencies will be added in --with-libs parameter.',
depTips2: 'It is not possible to build all extensions at the same time, as some extensions conflict with each other. Please select the extensions you need.',
microUnavailable: 'Micro does not support PHP 7.4 and earlier versions!',
hardcodedINIPlaceholder: 'If you need to hardcode ini, write one per line, for example: memory_limit=2G',
compileCommand: 'Build command',
downloadPhpVersion: 'PHP version',
downloadSPCBinaryCommand: 'Download spc binary',
selectedSystem: 'Select OS',
windowsSAPIUnavailable: 'Windows does not support fpm, embed and frankenphp build!',
useUPX: 'Enable UPX compression (reduce binary size)',
windowsDownSPCWarning: 'Please download the binary file manually, extract it to the current directory and rename to spc.exe on Windows!',
usePreBuilt: 'Download pre-built dependencies if possible (reduce compile time)',
windowsDownSPCWarning: 'Please download the spc.exe binary manually on Windows!',
usePreBuilt: 'Use pre-built dependencies where available (reduce compile time)',
searchPlaceholder: 'Search extensions...',
copy: 'Copy',
copied: 'Copied',
doctorCommand: 'Auto-check and prepare build environment command',
doctorCommand: 'Auto-check and prepare build environment',
dlParallel: 'Parallel downloads (1-50)',
dlRetry: 'Retry count on failure',
noStrip: 'Keep debug symbols (--no-strip)',
}
};
</script>
<style scoped>
.number-input {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
width: 80px;
padding: 6px 10px;
background-color: var(--vp-c-bg-soft);
color: var(--vp-c-text-1);
font-size: 14px;
outline: none;
transition: all 0.2s ease;
}
.number-input:hover {
border-color: var(--vp-c-brand-1);
}
.number-input:focus {
border-color: var(--vp-c-brand-1);
box-shadow: 0 0 0 3px var(--vp-c-brand-soft);
}
.box {
display: flex;
flex-wrap: wrap;

View File

@@ -0,0 +1,589 @@
<template>
<div class="deps-map">
<!-- Warning if data missing -->
<div v-if="missing" class="warning custom-block" style="margin-bottom: 16px">
<p class="custom-block-title">WARNING</p>
<p>Dependency data not generated yet. Run <code>bin/spc dev:gen-deps-data</code> to generate it.</p>
</div>
<template v-else>
<!-- Toolbar -->
<div class="deps-toolbar">
<input
class="deps-search"
v-model="searchText"
:placeholder="i18n.searchPlaceholder"
@input="selectedPkg = null"
/>
<div class="deps-filters">
<div class="filter-group">
<button
v-for="t in typeOptions"
:key="t.value"
:class="['filter-btn', { active: selectedType === t.value }]"
@click="selectedType = t.value; selectedPkg = null"
>{{ t.label }}</button>
</div>
<div class="filter-group">
<button
v-for="p in platformOptions"
:key="p.value"
:class="['filter-btn', { active: selectedPlatform === p.value }]"
@click="selectedPlatform = p.value"
>{{ p.label }}</button>
</div>
</div>
</div>
<div class="deps-layout">
<!-- Package list -->
<div class="deps-list">
<div v-if="filteredPackages.length === 0" class="no-results">{{ i18n.noResults }}</div>
<div
v-for="pkg in filteredPackages"
:key="pkg.name"
:class="['pkg-item', { selected: selectedPkg === pkg.name }]"
@click="selectPkg(pkg.name)"
>
<span class="pkg-name">{{ pkg.name }}</span>
<span :class="['pkg-badge', pkg.type === 'php-extension' ? 'badge-ext' : 'badge-lib']">
{{ typeLabel(pkg.type) }}
</span>
</div>
</div>
<!-- Detail panel -->
<div class="deps-detail" v-if="selectedPkg && selectedPkgData">
<h3 class="detail-title">{{ selectedPkg }}</h3>
<span :class="['detail-type-badge', selectedPkgData.type === 'php-extension' ? 'badge-ext' : 'badge-lib']">
{{ typeLabel(selectedPkgData.type) }}
</span>
<!-- OS support for extensions -->
<div v-if="selectedPkgData.type === 'php-extension' && selectedPkgData.os" class="detail-section">
<div class="detail-label">{{ i18n.supportedPlatforms }}</div>
<div class="detail-chips">
<span v-for="os in selectedPkgData.os" :key="os" class="chip chip-os">{{ os }}</span>
</div>
</div>
<!-- Required deps -->
<div class="detail-section">
<div class="detail-label">{{ i18n.requiredDeps }}</div>
<div class="detail-chips" v-if="currentDepends.length > 0">
<span
v-for="dep in currentDepends"
:key="dep"
:class="['chip', 'chip-required', { clickable: packages[dep] }]"
@click="packages[dep] && selectPkg(dep)"
>{{ dep }}</span>
</div>
<div v-else class="no-deps">{{ i18n.none }}</div>
</div>
<!-- Suggested deps -->
<div class="detail-section">
<div class="detail-label">{{ i18n.suggestedDeps }}</div>
<div class="detail-chips" v-if="currentSuggests.length > 0">
<span
v-for="dep in currentSuggests"
:key="dep"
:class="['chip', 'chip-suggested', { clickable: packages[dep] }]"
@click="packages[dep] && selectPkg(dep)"
>{{ dep }}</span>
</div>
<div v-else class="no-deps">{{ i18n.none }}</div>
</div>
<!-- Required by -->
<div class="detail-section">
<div class="detail-label">{{ i18n.requiredBy }}</div>
<div class="detail-chips" v-if="requiredBy.length > 0">
<span
v-for="dep in requiredBy"
:key="dep"
class="chip chip-rev clickable"
@click="selectPkg(dep)"
>{{ dep }}</span>
</div>
<div v-else class="no-deps">{{ i18n.none }}</div>
</div>
<!-- Suggested by -->
<div class="detail-section">
<div class="detail-label">{{ i18n.suggestedBy }}</div>
<div class="detail-chips" v-if="suggestedBy.length > 0">
<span
v-for="dep in suggestedBy"
:key="dep"
class="chip chip-rev-sug clickable"
@click="selectPkg(dep)"
>{{ dep }}</span>
</div>
<div v-else class="no-deps">{{ i18n.none }}</div>
</div>
<!-- Mermaid graph -->
<div class="detail-section" v-if="hasMermaid">
<div class="detail-label">{{ i18n.depGraph }}</div>
<div ref="mermaidEl" class="mermaid-wrap"></div>
</div>
</div>
<!-- Empty state -->
<div class="deps-detail deps-detail-empty" v-else>
<p>{{ i18n.selectHint }}</p>
</div>
</div>
</template>
</div>
</template>
<script setup>
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { useData } from 'vitepress'
import { data as depsData } from '../deps-map.data.js'
const { lang, isDark } = useData()
const missing = depsData.missing
const packages = depsData.packages ?? {}
// --- i18n ---
const I18N = {
zh: {
searchPlaceholder: '搜索包名...',
noResults: '未找到包。',
selectHint: '← 选择一个包以查看其依赖关系。',
supportedPlatforms: '支持的平台',
requiredDeps: '必需依赖',
suggestedDeps: '可选依赖',
requiredBy: '被哪些包依赖',
suggestedBy: '被哪些包建议',
depGraph: '依赖关系图',
none: '无',
},
en: {
searchPlaceholder: 'Search package...',
noResults: 'No packages found.',
selectHint: '← Select a package to view its dependency details.',
supportedPlatforms: 'Supported Platforms',
requiredDeps: 'Required Dependencies',
suggestedDeps: 'Suggested Dependencies',
requiredBy: 'Required By',
suggestedBy: 'Suggested By',
depGraph: 'Dependency Graph',
none: 'None',
},
}
const i18n = computed(() => I18N[lang.value] ?? I18N.en)
// --- State ---
const searchText = ref('')
const selectedType = ref('all')
const selectedPlatform = ref('linux')
const selectedPkg = ref(null)
const mermaidEl = ref(null)
// --- Options ---
const typeOptions = computed(() => [
{ value: 'all', label: lang.value === 'zh' ? '全部' : 'All' },
{ value: 'php-extension', label: lang.value === 'zh' ? '扩展' : 'Extensions' },
{ value: 'library', label: lang.value === 'zh' ? '库' : 'Libraries' },
])
const platformOptions = [
{ value: 'linux', label: 'Linux' },
{ value: 'macos', label: 'macOS' },
{ value: 'windows', label: 'Windows' },
]
function typeLabel(type) {
if (type === 'php-extension') return 'ext'
if (type === 'library') return 'lib'
return type
}
// --- Package list ---
const allPackages = computed(() =>
Object.entries(packages).map(([name, data]) => ({ name, ...data }))
)
const filteredPackages = computed(() => {
let list = allPackages.value
if (selectedType.value !== 'all') {
list = list.filter(p => p.type === selectedType.value)
}
if (searchText.value.trim()) {
const q = searchText.value.trim().toLowerCase()
list = list.filter(p => p.name.toLowerCase().includes(q))
}
return list
})
// --- Selected package ---
const selectedPkgData = computed(() =>
selectedPkg.value ? (packages[selectedPkg.value] ?? null) : null
)
const currentDepends = computed(() =>
selectedPkgData.value?.platforms?.[selectedPlatform.value]?.depends ?? []
)
const currentSuggests = computed(() =>
selectedPkgData.value?.platforms?.[selectedPlatform.value]?.suggests ?? []
)
const requiredBy = computed(() => {
if (!selectedPkg.value) return []
const name = selectedPkg.value
const plat = selectedPlatform.value
return Object.entries(packages)
.filter(([, d]) => (d.platforms?.[plat]?.depends ?? []).includes(name))
.map(([n]) => n)
})
const suggestedBy = computed(() => {
if (!selectedPkg.value) return []
const name = selectedPkg.value
const plat = selectedPlatform.value
return Object.entries(packages)
.filter(([, d]) => (d.platforms?.[plat]?.suggests ?? []).includes(name))
.map(([n]) => n)
})
// --- Mermaid ---
const hasMermaid = computed(
() => currentDepends.value.length > 0 || currentSuggests.value.length > 0
)
function buildMermaidCode() {
const deps = currentDepends.value
const sugs = currentSuggests.value
if (deps.length === 0 && sugs.length === 0) return ''
const safe = s => s.replace(/[^a-zA-Z0-9_]/g, '_')
const root = safe(selectedPkg.value)
const lines = ['graph LR', ` ${root}["${selectedPkg.value}"]`]
const MAX_DEPTH = 6 // max hops from root
const MAX_CHILDREN = 6 // per-node child limit for levels 2+
const visitedNodes = new Set([selectedPkg.value])
const visitedEdges = new Set()
const queue = []
// Level 1: direct required deps — solid arrows, no child limit
for (const dep of deps) {
const ek = `${selectedPkg.value}\0${dep}`
if (!visitedEdges.has(ek)) {
visitedEdges.add(ek)
lines.push(` ${root} --> ${safe(dep)}["${dep}"]`)
}
if (!visitedNodes.has(dep)) {
visitedNodes.add(dep)
queue.push({ name: dep, depth: 1 })
}
}
// BFS: levels 2MAX_DEPTH — dotted arrows, capped children per node
while (queue.length > 0) {
const { name, depth } = queue.shift()
if (depth >= MAX_DEPTH) continue
const children = packages[name]?.platforms?.[selectedPlatform.value]?.depends ?? []
for (const child of children.slice(0, MAX_CHILDREN)) {
const ek = `${name}\0${child}`
if (!visitedEdges.has(ek)) {
visitedEdges.add(ek)
lines.push(` ${safe(name)} -.-> ${safe(child)}["${child}"]`)
}
if (!visitedNodes.has(child)) {
visitedNodes.add(child)
queue.push({ name: child, depth: depth + 1 })
}
}
}
// Suggested deps from root (single level, optional dotted)
for (const sug of sugs) {
lines.push(` ${root} -. optional .-> ${safe(sug)}["${sug}"]`)
}
return lines.join('\n')
}
let mermaidLib = null
async function renderMermaid() {
if (!mermaidEl.value || !hasMermaid.value) return
const code = buildMermaidCode()
if (!code) return
try {
if (!mermaidLib) {
const m = await import('mermaid')
mermaidLib = m.default
}
mermaidLib.initialize({
startOnLoad: false,
theme: isDark.value ? 'dark' : 'default',
securityLevel: 'loose',
})
const id = 'deps-graph-' + Date.now()
const { svg } = await mermaidLib.render(id, code)
if (mermaidEl.value) {
mermaidEl.value.innerHTML = svg
}
} catch {
if (mermaidEl.value) {
mermaidEl.value.innerHTML = `<pre class="mermaid-fallback">${code}</pre>`
}
}
}
function selectPkg(name) {
selectedPkg.value = name
}
watch([selectedPkg, selectedPlatform, isDark], async () => {
await nextTick()
await renderMermaid()
})
onMounted(async () => {
await nextTick()
await renderMermaid()
})
</script>
<style scoped>
.deps-map {
font-size: 14px;
}
/* Toolbar */
.deps-toolbar {
display: flex;
flex-direction: column;
gap: 8px;
margin-bottom: 16px;
}
.deps-search {
width: 100%;
padding: 8px 12px;
border: 1px solid var(--vp-c-divider);
border-radius: 6px;
font-size: 14px;
background: var(--vp-c-bg);
color: var(--vp-c-text-1);
outline: none;
box-sizing: border-box;
}
.deps-search:focus {
border-color: var(--vp-c-brand);
}
.deps-filters {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.filter-group {
display: flex;
gap: 4px;
}
.filter-btn {
padding: 4px 12px;
border: 1px solid var(--vp-c-divider);
border-radius: 20px;
background: var(--vp-c-bg);
color: var(--vp-c-text-2);
font-size: 13px;
cursor: pointer;
transition: all 0.15s;
}
.filter-btn:hover {
border-color: var(--vp-c-brand);
color: var(--vp-c-brand);
}
.filter-btn.active {
background: var(--vp-c-brand);
border-color: var(--vp-c-brand);
color: #fff;
}
/* Layout */
.deps-layout {
display: flex;
gap: 16px;
min-height: 400px;
}
/* Package list */
.deps-list {
width: 260px;
flex-shrink: 0;
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
overflow-y: auto;
max-height: 600px;
}
.no-results {
padding: 16px;
color: var(--vp-c-text-3);
text-align: center;
}
.pkg-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
cursor: pointer;
border-bottom: 1px solid var(--vp-c-divider);
transition: background 0.1s;
}
.pkg-item:last-child {
border-bottom: none;
}
.pkg-item:hover {
background: var(--vp-c-bg-soft);
}
.pkg-item.selected {
background: var(--vp-c-brand-soft);
}
.pkg-name {
font-family: var(--vp-font-family-mono);
font-size: 13px;
word-break: break-all;
}
.pkg-badge {
font-size: 11px;
padding: 1px 6px;
border-radius: 10px;
flex-shrink: 0;
margin-left: 6px;
}
/* Detail panel */
.deps-detail {
flex: 1;
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
overflow-y: auto;
max-height: 600px;
}
.deps-detail-empty {
display: flex;
align-items: center;
justify-content: center;
color: var(--vp-c-text-3);
}
.detail-title {
margin: 0 0 8px 0;
font-size: 16px;
font-family: var(--vp-font-family-mono);
}
.detail-type-badge {
font-size: 12px;
padding: 2px 8px;
border-radius: 10px;
display: inline-block;
margin-bottom: 16px;
}
.detail-section {
margin-bottom: 16px;
}
.detail-label {
font-size: 12px;
font-weight: 600;
color: var(--vp-c-text-2);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 6px;
}
.detail-chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.no-deps {
color: var(--vp-c-text-3);
font-size: 13px;
}
/* Chips */
.chip {
font-family: var(--vp-font-family-mono);
font-size: 12px;
padding: 3px 10px;
border-radius: 12px;
border: 1px solid transparent;
display: inline-block;
}
.chip.clickable {
cursor: pointer;
transition: opacity 0.15s;
}
.chip.clickable:hover {
opacity: 0.75;
}
.chip-required {
background: var(--vp-c-danger-soft);
border-color: var(--vp-c-danger-1);
color: var(--vp-c-danger-1);
}
.chip-suggested {
background: var(--vp-c-warning-soft);
border-color: var(--vp-c-warning-1);
color: var(--vp-c-warning-1);
}
.chip-rev {
background: var(--vp-c-brand-soft);
border-color: var(--vp-c-brand-1);
color: var(--vp-c-brand-1);
}
.chip-rev-sug {
background: var(--vp-c-bg-soft);
border-color: var(--vp-c-divider);
color: var(--vp-c-text-2);
}
.chip-os {
background: var(--vp-c-bg-soft);
border-color: var(--vp-c-divider);
color: var(--vp-c-text-1);
}
/* Badges */
.badge-ext {
background: var(--vp-c-brand-soft);
color: var(--vp-c-brand-1);
}
.badge-lib {
background: var(--vp-c-tip-soft);
color: var(--vp-c-tip-1);
}
/* Mermaid */
.mermaid-wrap {
overflow-x: auto;
padding: 8px 0;
}
.mermaid-fallback {
font-size: 12px;
white-space: pre-wrap;
}
</style>

View File

@@ -1,36 +1,46 @@
<template>
<div>
<header class="DocSearch-SearchBar" style="padding: 0">
<form class="DocSearch-Form searchinput">
<input class="DocSearch-Input" v-model="filterText" placeholder="Filter name..." @input="doFilter" />
</form>
</header>
<table>
<thead>
<tr>
<th>Extension Name</th>
<th>Linux</th>
<th>macOS</th>
<th>FreeBSD</th>
<th>Windows</th>
</tr>
</thead>
<tbody>
<tr v-for="item in filterData">
<td v-if="!item.notes">{{ item.name }}</td>
<td v-else>
<a :href="'./extension-notes.html#' + item.name">{{ item.name }}</a>
</td>
<td>{{ item.linux }}</td>
<td>{{ item.macos }}</td>
<td>{{ item.freebsd }}</td>
<td>{{ item.windows }}</td>
</tr>
</tbody>
</table>
<div v-if="filterData.length === 0" style="margin: 0 4px 20px 4px; color: var(--vp-c-text-2); font-size: 14px">
No result, please try another keyword.
<div v-if="missing" class="warning custom-block" style="margin-bottom: 16px">
<p class="custom-block-title">WARNING</p>
<p>Extension list is not generated yet. Run <code>bin/spc dev:gen-ext-docs</code> to generate it.</p>
</div>
<template v-else>
<header class="DocSearch-SearchBar" style="padding: 0">
<form class="DocSearch-Form searchinput">
<input class="DocSearch-Input" v-model="filterText" placeholder="Filter name..." @input="doFilter" />
</form>
</header>
<table>
<thead>
<tr>
<th>Extension Name</th>
<th>Linux</th>
<th>macOS</th>
<th>Windows</th>
<th>Website</th>
</tr>
</thead>
<tbody>
<tr v-for="item in filterData" :key="item.name">
<td>
<span v-if="!item.hasNotes">{{ item.name }}</span>
<a v-else :href="'./extension-notes.html#' + item.name">{{ item.name }}</a>
</td>
<td>{{ item.linux ? '✅' : '' }}</td>
<td>{{ item.macos ? '✅' : '' }}</td>
<td>{{ item.windows ? '✅' : '' }}</td>
<td>
<a v-if="item.url" :href="item.url" target="_blank" rel="noopener noreferrer" class="ext-source-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="currentColor"><path d="M10 6v2H5v11h11v-5h2v6a1 1 0 01-1 1H4a1 1 0 01-1-1V7a1 1 0 011-1h6zm11-3v8h-2V6.413l-7.793 7.794-1.414-1.414L17.585 5H13V3h8z"/></svg>
</a>
</td>
</tr>
</tbody>
</table>
<div v-if="filterData.length === 0" style="margin: 0 4px 20px 4px; color: var(--vp-c-text-2); font-size: 14px">
No result, please try another keyword.
</div>
</template>
</div>
</template>
@@ -41,34 +51,22 @@ export default {
</script>
<script setup>
import {ref} from "vue";
import ext from '../../../config/ext.json';
import { ref } from 'vue'
import { data as extData } from '../extensions.data.js'
// 将 ext 转换为列表,方便后续操作
const data = ref([]);
for (const [name, item] of Object.entries(ext)) {
data.value.push({
name,
linux: item.support?.Linux === undefined ? 'yes' : (item.support?.Linux === 'wip' ? '' : item.support?.Linux),
macos: item.support?.Darwin === undefined ? 'yes' : (item.support?.Darwin === 'wip' ? '' : item.support?.Darwin),
freebsd: item.support?.BSD === undefined ? 'yes' : (item.support?.BSD === 'wip' ? '' : item.support?.BSD),
windows: item.support?.Windows === undefined ? 'yes' : (item.support?.Windows === 'wip' ? '' : item.support?.Windows),
notes: item.notes === true,
});
}
const filterData = ref(data.value);
const filterText = ref('');
const missing = extData.missing
const data = ref(extData.extensions)
const filterData = ref(extData.extensions)
const filterText = ref('')
const doFilter = () => {
if (filterText.value === '') {
filterData.value = data.value;
return;
filterData.value = data.value
return
}
filterData.value = data.value.filter(item => {
return item.name.toLowerCase().includes(filterText.value.toLowerCase());
});
filterData.value = data.value.filter(item =>
item.name.toLowerCase().includes(filterText.value.toLowerCase())
)
}
</script>
@@ -76,4 +74,14 @@ const doFilter = () => {
.searchinput {
border: 1px solid var(--vp-c-divider);
}
</style>
.ext-source-link {
color: var(--vp-c-text-3);
vertical-align: middle;
opacity: 0.6;
transition: opacity 0.2s;
}
.ext-source-link:hover {
opacity: 1;
color: var(--vp-c-brand-1);
}
</style>

View File

@@ -1,65 +1,84 @@
import sidebarEn from "./sidebar.en";
import sidebarZh from "./sidebar.zh";
// https://vitepress.dev/reference/site-config
export default {
title: "Static PHP",
description: "Build single static PHP binary, with PHP project together, with popular extensions included.",
title: "StaticPHP",
description: "A powerful tool designed for building portable executables including PHP, extensions, and more.",
locales: {
en: {
label: 'English',
lang: 'en',
themeConfig: {
nav: [
{text: 'Guide', link: '/en/guide/',},
{text: 'Advanced', link: '/en/develop/'},
{text: 'Contributing', link: '/en/contributing/'},
{text: 'FAQ', link: '/en/faq/'},
{ text: 'Guide', link: '/en/guide/' },
{ text: 'Develop', link: '/en/develop/' },
{ text: 'Contributing', link: '/en/contributing/' },
{ text: 'FAQ', link: '/en/faq/' },
{
text: 'v3 (alpha)',
items: [
{ text: 'v3 (alpha)', link: '/en/' },
{ text: 'v2', link: 'https://static-php.github.io/v2-docs/' },
],
},
],
sidebar: sidebarEn,
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © 2023-present crazywhalecc'
}
copyright: 'Copyright © 2023-present crazywhalecc',
},
},
},
zh: {
label: '简体中文',
lang: 'zh', // optional, will be added as `lang` attribute on `html` tag
lang: 'zh',
themeConfig: {
nav: [
{text: '构建指南', link: '/zh/guide/'},
{text: '进阶', link: '/zh/develop/'},
{text: '贡献', link: '/zh/contributing/'},
{text: 'FAQ', link: '/zh/faq/'},
{ text: '构建指南', link: '/zh/guide/' },
{ text: '开发者', link: '/zh/develop/' },
{ text: '贡献', link: '/zh/contributing/' },
{ text: 'FAQ', link: '/zh/faq/' },
{
text: 'v3 (alpha)',
items: [
{ text: 'v3 (alpha)', link: '/zh/' },
{ text: 'v2', link: 'https://static-php.github.io/v2-docs/' },
],
},
],
sidebar: sidebarZh,
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © 2023-present crazywhalecc'
}
copyright: 'Copyright © 2023-present crazywhalecc',
},
},
}
},
},
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
logo: '/images/static-php_nobg.png',
nav: [],
socialLinks: [
{icon: 'github', link: 'https://github.com/crazywhalecc/static-php-cli'}
{ icon: 'github', link: 'https://github.com/crazywhalecc/static-php-cli' },
],
footer: {
message: 'Released under the MIT License.',
copyright: 'Copyright © 2023-present crazywhalecc'
copyright: 'Copyright © 2023-present crazywhalecc',
},
externalLinkIcon: true,
search: {
provider: 'algolia',
options: {
appId: 'IHJHUB1SF1',
apiKey: '8266d31cc2ffbd0e059f1c6e5bdaf8fc',
indexName: 'static-php docs',
askAi: {
assistantId: 'b72369b2-60a5-461d-902c-5c18d8c05902',
agentStudio: true,
sidePanel: true,
},
},
},
}
},
}

View File

@@ -0,0 +1,23 @@
import { readFileSync, existsSync } from 'node:fs'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const DATA_PATH = resolve(__dirname, 'deps-data.json')
export default {
watch: [DATA_PATH],
load() {
if (!existsSync(DATA_PATH)) {
console.warn(
'[deps-map.data.js] deps-data.json not found. ' +
'Run `bin/spc dev:gen-deps-data` to generate it.'
)
return { packages: {}, missing: true }
}
const raw = JSON.parse(readFileSync(DATA_PATH, 'utf-8'))
return { packages: raw.packages ?? {}, missing: false }
},
}

View File

@@ -0,0 +1,40 @@
import { readFileSync, existsSync } from 'node:fs'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
const DATA_PATH = resolve(__dirname, 'ext-data.json')
const NOTES_PATH = resolve(__dirname, '../en/guide/extension-notes.md')
export default {
watch: [DATA_PATH, NOTES_PATH],
load() {
if (!existsSync(DATA_PATH)) {
console.warn(
'[extensions.data.js] ext-data.json not found. ' +
'Run `bin/spc dev:gen-ext-docs` to generate it.'
)
return { extensions: [], missing: true }
}
const raw = JSON.parse(readFileSync(DATA_PATH, 'utf-8'))
// Build the set of extension names that have a section in extension-notes.md.
// Headings at level 2 or 3 are matched; leading/trailing whitespace is stripped.
const notesSet = new Set()
if (existsSync(NOTES_PATH)) {
const notesContent = readFileSync(NOTES_PATH, 'utf-8')
for (const match of notesContent.matchAll(/^#{2,3}\s+(\S+)/gm)) {
notesSet.add(match[1].toLowerCase())
}
}
const extensions = raw.extensions.map(ext => ({
...ext,
hasNotes: notesSet.has(ext.name.toLowerCase()),
}))
return { extensions, missing: false }
},
}

118
docs/.vitepress/gen-meta.js Normal file
View File

@@ -0,0 +1,118 @@
#!/usr/bin/env node
/**
* docs:gen-meta — Pre-build metadata generator for VitePress docs.
*
* Checks that the environment is ready (PHP installed, composer dependencies
* present, bin/spc executable), then runs:
* bin/spc dev:gen-deps-data → docs/.vitepress/deps-data.json
* bin/spc dev:gen-ext-docs → docs/.vitepress/ext-data.json
*/
'use strict'
const { execSync, spawnSync } = require('child_process')
const fs = require('fs')
const path = require('path')
// __dirname is docs/.vitepress/, so two levels up is the project root
const ROOT = path.resolve(__dirname, '../..')
function fail(msg) {
console.error(`\x1b[31m[gen-meta] ERROR: ${msg}\x1b[0m`)
process.exit(1)
}
function info(msg) {
console.log(`\x1b[36m[gen-meta] ${msg}\x1b[0m`)
}
function ok(msg) {
console.log(`\x1b[32m[gen-meta] ${msg}\x1b[0m`)
}
// --- 1. Check PHP ------------------------------------------------------------
info('Checking PHP installation...')
const phpResult = spawnSync('php', ['--version'], { encoding: 'utf8' })
if (phpResult.status !== 0 || phpResult.error) {
fail(
'PHP is not installed or not in PATH.\n' +
' Please install PHP 8.1+ and ensure it is available in your PATH.'
)
}
const phpVersion = phpResult.stdout.split('\n')[0].trim()
ok(`Found: ${phpVersion}`)
// --- 2. Check composer CLI ---------------------------------------------------
info('Checking composer...')
const composerCheck = spawnSync('composer', ['--version'], { encoding: 'utf8' })
if (composerCheck.status !== 0 || composerCheck.error) {
fail(
'composer is not installed or not in PATH.\n' +
' Please install Composer: https://getcomposer.org/download/'
)
}
ok(`Found: ${composerCheck.stdout.split('\n')[0].trim()}`)
// --- 3. Install composer dependencies if missing ----------------------------
info('Checking composer dependencies...')
const autoload = path.join(ROOT, 'vendor', 'autoload.php')
if (!fs.existsSync(autoload)) {
info('vendor/autoload.php not found — running composer install --no-dev ...')
const installResult = spawnSync('composer', ['install', '--no-dev'], {
cwd: ROOT,
stdio: 'inherit',
})
if (installResult.status !== 0) {
fail('composer install --no-dev failed (exit code ' + installResult.status + ').')
}
ok('Composer dependencies installed.')
} else {
ok('Composer vendor directory found.')
}
// --- 4. Check bin/spc --------------------------------------------------------
info('Checking bin/spc...')
const spc = path.join(ROOT, 'bin', 'spc')
if (!fs.existsSync(spc)) {
fail('bin/spc not found. Make sure you are in the project root.')
}
// Quick sanity check — list commands
const spcCheck = spawnSync('php', [spc, 'list', '--format=txt'], {
cwd: ROOT,
encoding: 'utf8',
env: { ...process.env, SPC_EXECUTION_SOURCE: '1' },
})
if (spcCheck.status !== 0) {
fail(
'bin/spc failed to run.\n' +
(spcCheck.stderr ?? '') +
'\n Make sure PHP extensions required by static-php-cli are available.'
)
}
ok('bin/spc is operational.')
// --- 5. Run dev:gen-deps-data ------------------------------------------------
info('Running bin/spc dev:gen-deps-data ...')
const depsResult = spawnSync('php', [spc, 'dev:gen-deps-data'], {
cwd: ROOT,
stdio: 'inherit',
env: { ...process.env, SPC_EXECUTION_SOURCE: '1' },
})
if (depsResult.status !== 0) {
fail('dev:gen-deps-data failed (exit code ' + depsResult.status + ').')
}
ok('deps-data.json generated.')
// --- 6. Run dev:gen-ext-docs -------------------------------------------------
info('Running bin/spc dev:gen-ext-docs ...')
const extResult = spawnSync('php', [spc, 'dev:gen-ext-docs'], {
cwd: ROOT,
stdio: 'inherit',
env: { ...process.env, SPC_EXECUTION_SOURCE: '1' },
})
if (extResult.status !== 0) {
fail('dev:gen-ext-docs failed (exit code ' + extResult.status + ').')
}
ok('ext-data.json generated.')
ok('Metadata generation complete. Proceeding to VitePress build...')

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