Compare commits

...

328 Commits

Author SHA1 Message Date
crazywhalecc
5f8641f417 update README 2024-01-10 11:13:47 +08:00
crazywhalecc
17b69ec1e9 update README 2024-01-10 11:11:45 +08:00
Jerry Ma
8de942c274 Adjust function to protected (#315)
* add `--with-added-patch` command

* add BuilderProvider::getBuilder() function

* cs fix

* add builder() and patch_point() global functions

* bump version to 2.0.1

* adjust function prefix

* adjust function prefix
2024-01-10 11:10:40 +08:00
crazywhalecc
a7d5a48b48 bump version to 2.0.1 2024-01-09 11:51:11 +08:00
crazywhalecc
fdc00301c0 add builder() and patch_point() global functions 2024-01-09 11:51:11 +08:00
crazywhalecc
7620d5900e cs fix 2024-01-09 11:51:11 +08:00
crazywhalecc
e973fe743e add BuilderProvider::getBuilder() function 2024-01-09 11:51:11 +08:00
crazywhalecc
149e844d59 add --with-added-patch command 2024-01-09 11:51:11 +08:00
crazywhalecc
12ea3218e8 fix --from-zip not working bug 2024-01-08 23:36:19 +08:00
crazywhalecc
f9e7af1c9a add deepin support for doctor 2024-01-08 23:36:08 +08:00
Jerry Ma
8d2f6baaa2 Update README.md 2024-01-07 12:54:48 +08:00
crazywhalecc
25a2684e5a add ldap patches (why ext-ldap doesn't use pkg-config to find ldap?) 2024-01-07 12:20:58 +08:00
crazywhalecc
13e0e12181 update patch order 2024-01-07 12:20:58 +08:00
crazywhalecc
81df124b42 update README badge [skip ci] 2024-01-07 12:20:58 +08:00
crazywhalecc
d3d8230a09 add openssl patch 2024-01-07 12:20:58 +08:00
crazywhalecc
d4eb199504 use non-static suffix for brotli 2024-01-07 12:20:58 +08:00
crazywhalecc
6562bc200c fix ldap for macos x86_64 2024-01-07 12:20:58 +08:00
crazywhalecc
0b322f494b test 2024-01-07 12:20:58 +08:00
crazywhalecc
ceed1005cc remove unused download-cache workflow 2024-01-07 12:20:58 +08:00
crazywhalecc
6efcb75224 test ldap 2024-01-07 12:20:58 +08:00
crazywhalecc
a45f2f357d test ldap 2024-01-07 02:28:44 +08:00
crazywhalecc
0c2de9f936 run build test when changing test-extensions.php 2024-01-07 02:22:35 +08:00
crazywhalecc
ac005d1e0f update config to test actions 2024-01-07 02:16:50 +08:00
crazywhalecc
fce0c2f896 update config to test actions 2024-01-07 02:16:17 +08:00
crazywhalecc
a0a0b01cc3 update config to test actions 2024-01-07 02:14:45 +08:00
crazywhalecc
450ec21c90 remove main push test 2024-01-07 02:11:46 +08:00
crazywhalecc
7b2c3ac12d fix if statement for workflow 2024-01-07 02:10:14 +08:00
crazywhalecc
8d4a375400 fix if statement for workflow 2024-01-07 02:03:04 +08:00
crazywhalecc
eda3a9b486 add docs config actions 2024-01-07 01:58:31 +08:00
crazywhalecc
5b581a54aa add docs config actions 2024-01-07 01:57:55 +08:00
crazywhalecc
5549068275 add download cache for tests 2024-01-07 01:24:43 +08:00
crazywhalecc
daf0d2eb32 fix dependency sort 2024-01-07 01:24:43 +08:00
crazywhalecc
bff1a6168f fix imagemagick with curl,brotli errors
symlink breaks imagemagick build
2024-01-07 01:24:43 +08:00
crazywhalecc
54ba41d1b3 fix imap executable permission 2024-01-07 01:24:43 +08:00
crazywhalecc
cb5e13e39a update release-build (Build SPC Binary) workflow 2024-01-07 01:24:43 +08:00
霸气千秋
269e95e0fe fix #307 (#308)
* fix #307 uv 和 swoole 同时启用的时候会提示 uv 找不到

* Update test-extensions.php

* update cs-fixer config for newer version

* revert composer.lock to fit 8.1

---------

Co-authored-by: Jerry Ma <jesse2061@outlook.com>
2024-01-05 19:21:07 +08:00
crazywhalecc
dabdb518ce xz use github 2024-01-03 14:56:39 +08:00
Jerry Ma
eac4763d82 fix libxml2 with icu finding issue (#304)
* fix libxml2 with icu finding issue

* add test
2024-01-03 13:40:48 +08:00
Jerry Ma
fa0ea5443d Update to 2.0.0 2024-01-03 10:36:04 +08:00
好吧,你想说啥
31c71f180b Feature perfect swoole extension config (#297)
* improve swoole static build config

* improve swoole static build config

* improve swoole static build config

* improve swoole static build config

* improve swoole static build config

* add cares config

* update swoole depend  config

* update swoole depend  config

* update cares build   config

* update workflow tests.yaml   config

* fix setup-runtime

* test with clang build

* test with clang build

* update cares build config

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* update cares license

* test build

* test build

* test build

* test build

* test add enable libpq

* test add enable libpq

* test add enable libpq

* test add enable libpq

* test add enable libpq

* test add enable libpq

* test add enable libpq

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* test

* update

* update

* update

* update

* update

* update

* update

* update

* update

* compatible old

* fix code format

* fix code format

* add swoole test case

* add swoole test case

* add phpstan ignore error

* add phpstan ignore error

* add phpstan ignore error

* add phpstan ignore error

* add phpstan ignore error

* update phpstan.neon

* update swoole extension test case

* update swoole test case

* adjust config order and depends

* revert LinuxBuilder

* remove swoole.phpt

* re-adjust swoole args

* update test-extensions and some PHPDoc

* revert: debian and alpine clang doctor install

* revert: MacOSBuilder

* fix: extract hook for archive not working

* revert: build tests

* use addon mode to swoole database hook

* add hook tests

* test minimal

* test minimal

* sort config

---------

Co-authored-by: crazywhalecc <jesse2061@outlook.com>
2024-01-03 10:31:21 +08:00
Jerry Ma
5c7552f826 Update README.md 2023-12-26 01:47:33 +08:00
Jerry Ma
fa1bd340f1 Update README.md 2023-12-26 01:42:52 +08:00
Jerry Ma
539aaefd72 Add initial windows runtime setup (#292)
* add initial windows runtime setup

* add cool console output

* doctor support windows base

* add `add-path` and `remove-path` for bin/setup-runtime

* fix composer.ps1 path

* add windows system util

* add windows cmd and doctor base check

* add windows fallback for laravel/prompts

* cd fix [skip ci]

* dir separator and typo fix [skip ci]
2023-12-24 20:17:06 +08:00
crazywhalecc
d54bf42ba8 add extension xhprof test 2023-12-24 20:15:44 +08:00
crazywhalecc
cbfbec41b4 add extension xhprof 2023-12-24 20:15:44 +08:00
crazywhalecc
db7532cad3 add composer library mode 2023-12-24 14:53:46 +08:00
Jerry Ma
6b8df97282 Add uv/libuv support (#296)
* add uv/libuv support

* sort config
2023-12-23 16:23:37 +08:00
crazywhalecc
584f96484c add liblz4 suggest 2023-12-23 15:18:39 +08:00
crazywhalecc
e1e5515694 fix tests 2023-12-23 15:18:39 +08:00
crazywhalecc
d3ff6fd8c0 sort config 2023-12-23 15:18:39 +08:00
crazywhalecc
6bcda6a5a0 add lz4, igbinary support for redis 2023-12-23 15:18:39 +08:00
crazywhalecc
3828ba7c77 fix x86_64 build 2023-12-22 13:28:22 +08:00
crazywhalecc
a632caed54 add sqlsrv support test 2023-12-22 13:28:22 +08:00
crazywhalecc
1e0265e673 add sqlsrv support 2023-12-22 13:28:22 +08:00
Jerry Ma
a39cd9a238 Update README.md 2023-12-21 12:55:20 +08:00
Jerry Ma
2d437952f2 Update README.md 2023-12-21 12:54:43 +08:00
crazywhalecc
7e5b0d6f43 use bulk combination for setup-runtime 2023-12-21 01:45:54 +08:00
Jerry Ma
cf198e0f0a Merge pull request #64 from mpociot/libargon2-support
Add support for libargon2
2023-12-19 20:49:50 +08:00
crazywhalecc
248918e458 remove ldap test for known reason 2023-12-19 20:04:13 +08:00
crazywhalecc
c4cfc01b88 fix linux build (dont know why linux failed) 2023-12-19 19:37:19 +08:00
crazywhalecc
339c03adb2 fix linux build (dont know why linux failed) 2023-12-19 19:31:56 +08:00
crazywhalecc
48551cc602 add linux support for libargon2 2023-12-19 19:13:19 +08:00
crazywhalecc
e0550b4a45 add argon2 test 2023-12-19 19:04:49 +08:00
crazywhalecc
93a55e87d5 temporarily use pkg-config mirror (freedesktop.org down) 2023-12-19 19:03:16 +08:00
Marcel Pociot
e68f1ce3fe Merge branch 'main' into libargon2-support 2023-12-19 10:05:45 +01:00
crazywhalecc
3573007485 Merge remote-tracking branch 'origin/main' 2023-12-18 00:14:34 +08:00
crazywhalecc
b961c34d9a add ldap test 2023-12-18 00:14:14 +08:00
Jerry Ma
33e1759caa Update README.md 2023-12-17 12:16:54 +08:00
Jerry Ma
d72ee53cb4 Update README.md 2023-12-17 02:02:00 +08:00
crazywhalecc
a5fa46b82d update README 2023-12-17 01:35:28 +08:00
Jerry Ma
bc15de0dfb Update README.md 2023-12-17 01:03:32 +08:00
crazywhalecc
1f7bdb94fb update README 2023-12-17 01:02:02 +08:00
crazywhalecc
ea64e50ce5 fix SourcePatcher::patchFile not working with spc binary 2023-12-16 18:49:38 +08:00
crazywhalecc
ed8b606761 add libtool for macos doctor 2023-12-16 15:07:04 +08:00
Jerry Ma
b722b3edd4 Merge pull request #279 from jingjingxyk/feature_upgrade_libpq
upgrade libpq to v16.1
2023-12-16 12:34:36 +08:00
crazywhalecc
9266a4c504 remove ldap test 2023-12-15 23:36:12 +08:00
crazywhalecc
d8ce5f69f4 fix mongodb support for Linux (mac still broken) 2023-12-15 01:31:01 +08:00
crazywhalecc
0cfac49560 adjust package order 2023-12-15 00:34:22 +08:00
crazywhalecc
3e9ddc8e01 update to rc9 2023-12-10 20:43:52 +08:00
crazywhalecc
83dd1bd5c3 Merge branch 'main' into feature_upgrade_libpq 2023-12-10 19:10:39 +08:00
crazywhalecc
42f448cf17 reformat build log 2023-12-10 19:07:28 +08:00
crazywhalecc
f0319de93e opcache limit php version 2023-12-10 19:07:28 +08:00
crazywhalecc
c7e9294908 fix libtool missing bug for freetype 2023-12-10 19:07:28 +08:00
Jerry Ma
c1758bd754 Update README.md 2023-12-07 16:01:12 +08:00
jingjingxyk
bba2d0dbf7 test remove imap ldap extension 2023-11-30 21:29:57 +08:00
jingjingxyk
00689b951b update ldap depends 2023-11-30 14:19:20 +08:00
jingjingxyk
98b7164de3 test libpq build 2023-11-30 13:09:02 +08:00
jingjingxyk
d3e4470e1f test libpq build 2023-11-30 13:06:36 +08:00
jingjingxyk
433c91b68d test libpq build 2023-11-30 13:01:15 +08:00
jingjingxyk
3185d98b1a test libpq build 2023-11-30 13:00:04 +08:00
jingjingxyk
e603e441e7 test libpq build 2023-11-30 12:56:47 +08:00
jingjingxyk
b1bf8bb848 test libpq build 2023-11-30 12:53:19 +08:00
jingjingxyk
b1958ea0c4 test libpq build 2023-11-30 12:37:20 +08:00
jingjingxyk
930849758c swoole.php and LinuxBuilder.php revert 2023-11-29 22:28:20 +08:00
jingjingxyk
7ee431725c test swoole enable pgsql 2023-11-29 22:22:36 +08:00
jingjingxyk
7c866cb0e3 swoole enable pgsql 2023-11-29 22:19:20 +08:00
jingjingxyk
266108b25f test libpq build config 2023-11-29 22:06:30 +08:00
crazywhalecc
82e3a86f17 bypass error: swoole curl hook is buggy for php 8.0 2023-11-29 20:31:53 +08:00
crazywhalecc
ba18819b41 Merge branch 'main' into feature_upgrade_libpq
# Conflicts:
#	src/globals/test-extensions.php
2023-11-29 19:16:40 +08:00
jingjingxyk
6b23c90bba test build libpq 2023-11-29 16:52:53 +08:00
crazywhalecc
edfd371973 bypass error: unknown warning option '-Wno-logical-op' for macOS 2023-11-29 16:03:30 +08:00
crazywhalecc
8ed95602e2 add tests 2023-11-29 16:03:30 +08:00
crazywhalecc
cee1346bec fix imagemagick linking issue 2023-11-29 16:03:30 +08:00
jingjingxyk
400007c206 test change test-extensions 2023-11-29 15:56:52 +08:00
jingjingxyk
443e615066 Merge remote-tracking branch 'origin/feature_upgrade_libpq' into feature_upgrade_libpq 2023-11-29 15:46:26 +08:00
jingjingxyk
ed22945ae2 test 2023-11-29 15:44:04 +08:00
Jerry Ma
5db084ba0e reduce test extensions 2023-11-29 15:17:21 +08:00
jingjingxyk
c7b3275a72 update libpq build config 2023-11-29 15:06:17 +08:00
Jerry Ma
41cd319d4e Update test-extensions.php 2023-11-29 14:28:39 +08:00
jingjingxyk
1c307d0d59 upgrade libpq to v16.1 2023-11-29 13:30:12 +08:00
Jerry Ma
9dcda873f3 Fix debian libtool bug (#276)
* add libtool installation for debian

* update composer lock

* re-fix libtool check

* re-fix libtool check
2023-11-27 22:35:40 +08:00
crazywhalecc
4400c6271e update composer lock 2023-11-27 21:59:59 +08:00
crazywhalecc
0589690eaa add libtool installation for debian 2023-11-27 21:59:59 +08:00
Jerry Ma
5449e05898 Update README.md 2023-11-24 10:28:35 +08:00
crazywhalecc
93e64e1d5a use php 8.2 to setup php runtime 2023-11-24 01:33:12 +08:00
crazywhalecc
7a2e237069 add php 8.3 support 2023-11-24 01:33:12 +08:00
crazywhalecc
c95da8c150 add tests 2023-11-24 01:23:15 +08:00
crazywhalecc
89afd44344 add tidy support for linux 2023-11-24 01:23:15 +08:00
crazywhalecc
04f100da8b add tidy support 2023-11-24 01:23:15 +08:00
Jerry Ma
2e24976b71 Update README.md 2023-11-22 11:05:57 +08:00
Jerry Ma
36a30cc23b Update README.md 2023-11-21 23:35:34 +08:00
crazywhalecc
869130572f change test 2023-11-21 23:09:20 +08:00
crazywhalecc
2bb08af89b add rar test 2023-11-21 23:09:20 +08:00
crazywhalecc
b3d41ef969 add extension rar 2023-11-21 23:09:20 +08:00
crazywhalecc
9c904409cd use string 2023-11-19 13:47:48 +08:00
crazywhalecc
859182abff remove fail fast 2023-11-19 13:44:12 +08:00
crazywhalecc
c0e88bf4bd prevent setup php from using 8.0 2023-11-19 13:42:40 +08:00
crazywhalecc
79bcd35c0e Add test build things 2023-11-19 13:41:09 +08:00
crazywhalecc
2e637524fc Add test build things 2023-11-19 13:38:55 +08:00
Jerry Ma
a2c687599f Create pull_request_template.md 2023-11-19 13:38:09 +08:00
Kévin Dunglas
d09a3074ad include git metadata 2023-11-16 19:21:54 +08:00
Kévin Dunglas
5736964b2e fix 2023-11-16 19:21:54 +08:00
Kévin Dunglas
edaa82b8c5 autogen 2023-11-16 19:21:54 +08:00
Kévin Dunglas
2a6441a500 switch to git 2023-11-16 19:21:54 +08:00
crazywhalecc
3bd5a05725 remove pthreads4w 2023-11-16 00:12:56 +08:00
Kévin Dunglas
a6fbcc954e fix pthreads4w URL 2023-11-16 00:12:56 +08:00
crazywhalecc
66cebb5fe4 disable brotli if not enabled 2023-11-15 18:29:59 +08:00
crazywhalecc
e3671387fc temporarily use fixed url for freetype 2023-11-15 18:00:06 +08:00
Jerry Ma
f7c73c00af Fix iconv not depends on libiconv in linux 2023-11-14 20:54:03 +08:00
Jerry Ma
74536bd2e1 Change CI download all to --for-extensions (#262)
* Change download all to --for-extensions

* Update build-linux-x86_64.yml

* Update build-linux-arm.yml

* Update build-linux-x86_64.yml

* Update build-macos-x86_64.yml
2023-11-13 17:59:03 +08:00
crazywhalecc
a8f2b0096b cs fix 2023-11-13 16:09:11 +08:00
crazywhalecc
2d192fc390 replace libpng to github 2023-11-13 16:09:11 +08:00
crazywhalecc
031da802f3 apply new patches 2023-11-13 16:09:11 +08:00
crazywhalecc
5fdeb33031 separate linux and macos patches 2023-11-13 16:09:11 +08:00
crazywhalecc
347da67b71 use static-php/imap 2023-11-13 16:09:11 +08:00
crazywhalecc
65ef9ab20c use WrongUsageException for not supported libs 2023-11-13 16:09:11 +08:00
crazywhalecc
3d64c6349e remove kerberos temporarily
--for-extensions is not working with it
2023-11-13 16:09:11 +08:00
DubbleClick
31cf9bb5b7 fix redhat os detection 2023-11-13 16:09:11 +08:00
DubbleClick
7c4a991c0e add imap support 2023-11-13 16:09:11 +08:00
crazywhalecc
07f943af7e add dev:extensions command custom column display 2023-11-06 22:29:52 +08:00
crazywhalecc
fbf5c958d0 sort configs 2023-11-05 17:55:39 +08:00
crazywhalecc
672a4102cd overwrite password-argon2 cli check 2023-11-05 17:53:48 +08:00
crazywhalecc
52d61365b7 Merge branch 'main' into libargon2-support 2023-11-05 17:50:00 +08:00
crazywhalecc
ff74f0cdaf overwrite mbregex cli check 2023-11-05 17:49:30 +08:00
crazywhalecc
dccfde9f39 Adjust mbstring and mbregex dependencies 2023-11-05 17:49:30 +08:00
crazywhalecc
5db23e1db7 let sanity check can be overwritten 2023-11-05 17:49:30 +08:00
crazywhalecc
b1ae48a209 let sanity check can be overwritten 2023-11-05 17:49:30 +08:00
crazywhalecc
3604ea6d67 Update lock 2023-11-05 17:32:29 +08:00
crazywhalecc
967292be5c Remove old configure_env 2023-11-05 17:31:17 +08:00
crazywhalecc
4f5335bba4 Merge branch 'main' into libargon2-support
# Conflicts:
#	config/lib.json
#	config/source.json
2023-11-05 17:25:36 +08:00
crazywhalecc
ac7a236763 Transfer crazywhalecc/phpmicro ownership 2023-11-01 21:07:20 +08:00
crazywhalecc
1bf39c1f06 Update static-php-cli-hosted ownership 2023-11-01 20:51:31 +08:00
Jerry Ma
678283cd98 Update README.md 2023-11-01 20:48:23 +08:00
crazywhalecc
97a76aba8a update README 2023-11-01 20:35:45 +08:00
Jerry Ma
af464e7b3d Update source.json 2023-11-01 20:06:49 +08:00
Jerry Ma
5ee7dd9200 Update README-zh.md 2023-11-01 13:51:12 +08:00
Jerry Ma
9e1c2c6dd5 Update README-zh.md 2023-11-01 13:49:37 +08:00
Jerry Ma
d29ba16cbc Update README.md 2023-11-01 13:49:18 +08:00
Jerry Ma
7bef45eb32 Update README.md 2023-11-01 11:01:44 +08:00
crazywhalecc
772ab77d2e fix glfw linking issue 2023-11-01 10:03:36 +08:00
crazywhalecc
58897c6941 add swoole curl hook support, disable pgsql hook support 2023-11-01 10:03:36 +08:00
Jerry Ma
8230e1bcec Update README.md 2023-11-01 00:02:59 +08:00
crazywhalecc
279a1dab4b fix prompts dependency and box pack path 2023-10-31 18:03:14 +08:00
Jerry Ma
9fb5173e3e Merge pull request #231 from DubbleClick/cplus
Linux c++ support using musl-cross-make toolchains
2023-10-31 13:44:25 +08:00
crazywhalecc
0b37080cdd a good coding font is very important 2023-10-31 12:17:53 +08:00
DubbleClick
8747266df6 make it rc8 2023-10-30 22:22:01 +01:00
DubbleClick
12cc422d5b merge main 2023-10-30 22:20:16 +01:00
DubbleClick
bfc56cff72 refactor build var generation 2023-10-30 22:14:47 +01:00
crazywhalecc
d5405ce436 update to the release version 2023-10-31 01:51:53 +08:00
crazywhalecc
e158cc5886 update composer lock 2023-10-31 01:51:14 +08:00
crazywhalecc
aee040d6a4 use prompts to show table 2023-10-31 01:48:57 +08:00
crazywhalecc
e637cce6f2 use prompts to ask 2023-10-31 01:48:49 +08:00
crazywhalecc
98b906db40 Merge remote-tracking branch 'origin/main' into cplus 2023-10-31 01:02:02 +08:00
crazywhalecc
7625f585d2 fix macos imagemagick libwebp linking issue 2023-10-31 00:59:35 +08:00
crazywhalecc
ed8837fe9f let postgresql use -lc++ in bsd and macos 2023-10-31 00:59:22 +08:00
Jerry Ma
a5754125a8 Update README.md 2023-10-30 20:32:59 +08:00
DubbleClick
6b848da4dd disable musl-gcc wrapper 2023-10-29 18:02:02 +01:00
crazywhalecc
2768dc0c40 adjust doctor for os and linux musl check 2023-10-30 00:35:58 +08:00
crazywhalecc
90b2e5568c update sqlite version 2023-10-29 23:34:17 +08:00
DubbleClick
b4f9235cb6 Merge branch 'main' into cplus 2023-10-29 12:14:58 +01:00
DubbleClick
86ce7e9d25 rename --by-extensions to --for-extensions
--without-suggests to --without-suggestions
2023-10-29 12:00:16 +08:00
DubbleClick
2e47e8af6b specify --with-openssl-dir in php ./configure
I'm not sure if this is correct, please revert if it doesn't fix the issue
2023-10-27 18:42:53 +02:00
DubbleClick
d40f2cafec simplify libpng compilation 2023-10-27 17:37:31 +02:00
DubbleClick
e84a246dd2 add back required -lgomp for imagick extension 2023-10-27 17:33:43 +02:00
crazywhalecc
98f32ae0f0 Use emoji 2023-10-26 20:49:42 +08:00
crazywhalecc
5499109278 Adjust new README 2023-10-26 20:40:32 +08:00
crazywhalecc
9a5b02692d Adjust new README 2023-10-26 20:37:35 +08:00
crazywhalecc
970a74896a Adjust new README 2023-10-26 20:34:58 +08:00
crazywhalecc
29179ecb84 Adjust new README 2023-10-26 20:28:35 +08:00
crazywhalecc
5e0cccfe3d Add --by-extensions for README 2023-10-26 20:20:17 +08:00
crazywhalecc
ed52ec9ee1 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	README-en.md
2023-10-26 20:17:27 +08:00
crazywhalecc
f25d2d5db4 Decided to change README default language to English 2023-10-26 20:17:17 +08:00
crazywhalecc
e00908d8cb Merge remote-tracking branch 'DubbleClick/cplus' into cplus
# Conflicts:
#	src/SPC/builder/unix/library/bzip2.php
2023-10-26 19:45:37 +08:00
DubbleClick
c24dc8f518 create helper method to pass environment variables to 'make' 2023-10-24 12:21:36 +02:00
Jerry Ma
d381e48605 Update README-en.md 2023-10-23 22:44:42 +08:00
crazywhalecc
8dcec73929 let bzip2 use correct CC and AR 2023-10-23 22:27:19 +08:00
crazywhalecc
9b9644fe63 simplify download error message 2023-10-23 20:12:47 +08:00
crazywhalecc
8a70da6291 change instanceof check 2023-10-23 00:41:43 +08:00
crazywhalecc
c84eb723ec [mixed] refactor with putenv, fix imagemagick and c++ build 2023-10-23 00:37:28 +08:00
crazywhalecc
5934e5e881 fix doctor phpunit test 2023-10-22 22:16:20 +08:00
crazywhalecc
99150e2cef add putenv wrapper 2023-10-22 22:14:11 +08:00
crazywhalecc
8191444fe9 refactor musl tool doctor 2023-10-22 21:33:09 +08:00
crazywhalecc
5cfba6e83b Merge branch 'main' into cplus 2023-10-22 17:43:18 +08:00
crazywhalecc
4e9b8980d0 add --by-extensions and --without-suggests options for download command 2023-10-22 17:42:35 +08:00
crazywhalecc
c800a53f77 separate --from-zip in download command 2023-10-22 17:42:35 +08:00
crazywhalecc
6cc7e6cff6 add comment for hard-coded musl version 2023-10-22 17:24:01 +08:00
crazywhalecc
d56c060863 remove --enable-wrapper=gcc for fix-musl 2023-10-22 17:15:12 +08:00
crazywhalecc
b6409bded4 optimize install musl wrapper and cross make function 2023-10-22 16:55:02 +08:00
DubbleClick
ca1189b6ca use ld.gold (revert this if you think this doesn't add benefit) 2023-10-19 18:28:36 +02:00
DubbleClick
75b9d66698 use ar and ld from musl-tools (uses gold-ld and can handle wrong lib order) 2023-10-19 18:24:05 +02:00
DubbleClick
6dfd35348f fix order of imagick libs 2023-10-19 18:24:05 +02:00
DubbleClick
0007043f4a fix imagemagick and postgresql builds with different libs 2023-10-19 18:24:04 +02:00
DubbleClick
da1cbeb79c introduce library_path and ld_library_path options to linuxbuilder (some libs require it to load -lstdc++) 2023-10-19 18:24:03 +02:00
DubbleClick
a83a457905 fix pgsql build on non-alpine 2023-10-19 18:24:03 +02:00
DubbleClick
a4dc177621 install libxml2 and snappy into /lib instead of /lib64 2023-10-19 18:24:02 +02:00
DubbleClick
a7265bf624 add -static linker flag to libicu compilation 2023-10-19 18:24:01 +02:00
DubbleClick
64dfb57366 don't add -liconv on linux (cannot find library when specified that way in extra_libs) 2023-10-19 18:24:01 +02:00
DubbleClick
658e8e74bd use arch-linux-musl toolchains 2023-10-19 18:24:00 +02:00
DubbleClick
46b0ecf3fa allow patching of extra_libs before make on linux too 2023-10-19 18:23:59 +02:00
DubbleClick
830f379bf6 add --disable-opcache-jit option for alpine 2023-10-19 18:23:59 +02:00
crazywhalecc
c9b544f8c4 fix zlib detection in debian linux 2023-10-19 23:19:51 +08:00
DubbleClick
11af370fe1 remove useless softlink libpng.a (pointing to libpng16.a), causes imagick build failure if freetype or png is enabled 2023-10-19 23:19:51 +08:00
DubbleClick
1e11559c4b fix libpng license and libname 2023-10-19 23:19:51 +08:00
crazywhalecc
8b188bd1b9 change icu to ghrel 2023-10-19 00:05:36 +08:00
crazywhalecc
e0e3bc6d97 add detection for ghrel prerelease 2023-10-19 00:05:36 +08:00
crazywhalecc
dbb566ac7c fix curl 7.4.0 CoreServices framework build bug for mac 2023-10-17 18:43:49 +08:00
crazywhalecc
37b9704fbb move option rebuild add position 2023-10-17 18:37:40 +08:00
DubbleClick
c225aeffed introduce --rebuild option to BuildCliCommand.php (who even uses build:libs?) 2023-10-17 18:37:40 +08:00
DubbleClick
2e3544f296 catch exception when license path key is not set, fix libxslt license 2023-10-17 10:08:07 +08:00
Jerry Ma
ce60a9c804 Update README.md 2023-10-16 10:28:10 +08:00
crazywhalecc
b6c0b998b3 add bz2,curl support 2023-10-16 10:28:10 +08:00
crazywhalecc
6277539a79 change README micro repo description 2023-10-16 10:28:10 +08:00
crazywhalecc
9520d68cda add onig and openssl support for BSD 2023-10-16 10:28:10 +08:00
crazywhalecc
812c71f31f update README 2023-10-16 10:28:10 +08:00
crazywhalecc
b3cc360eeb fix extension configure arg for BSD 2023-10-16 10:28:10 +08:00
crazywhalecc
39fe6fa081 fix copyDir for FreeBSD and add debug message 2023-10-16 10:28:10 +08:00
crazywhalecc
243ee63283 fix strip order for micro 2023-10-16 10:28:10 +08:00
crazywhalecc
24c946d687 fix phpunit 2023-10-16 10:28:10 +08:00
crazywhalecc
84d1c789bd add basic FreeBSD support for utils 2023-10-16 10:28:10 +08:00
crazywhalecc
a983667b90 fix docker alpine install package redundant link 2023-10-15 09:42:55 +08:00
crazywhalecc
8d9cace469 fix mongodb release file match 2023-10-14 15:10:15 +08:00
crazywhalecc
e9d3e48f90 simplify hasCppExtension() method 2023-10-14 14:07:48 +08:00
crazywhalecc
ed53394389 add mark library patch function 2023-10-14 14:07:48 +08:00
crazywhalecc
8893d08ba9 adjust linux distro detection 2023-10-14 13:56:40 +08:00
crazywhalecc
5a13daee39 remove redundant LinuxLibraryBase tryBuild 2023-10-14 13:56:13 +08:00
crazywhalecc
c1e9cd2ea3 fix --with-clean to make it work 2023-10-14 11:37:56 +08:00
crazywhalecc
30213da70a change default download php to 8.2 2023-10-14 11:30:43 +08:00
crazywhalecc
5d363bdb0b adjust store classes 2023-10-14 11:23:25 +08:00
crazywhalecc
630c0d3a5d add SourcePatcher::patchFile 2023-10-14 11:18:36 +08:00
Jerry Ma
56caef78e3 Update README.md 2023-10-07 15:37:49 +08:00
Jerry Ma
29be3a2e39 set version to 2.0-rc7 2023-10-05 22:07:44 +08:00
crazywhalecc
fbe149bcac reuse static-php-cli-hosted workflows 2023-10-05 21:58:42 +08:00
crazywhalecc
92cafb36f6 fix bugs when building micro and embed at the same time 2023-10-01 10:01:45 +08:00
Joseph Bielawski
8636f2e7c9 Throw proper exception when PHP source is not available 2023-10-01 01:24:02 +08:00
crazywhalecc
8f43a09533 separate alternative libs 2023-10-01 01:19:35 +08:00
DubbleClick
654c5cba0c fix musl install on rhel 2023-10-01 01:19:35 +08:00
crazywhalecc
f9685b82a1 adjust tool check level 2023-10-01 01:19:35 +08:00
crazywhalecc
f2371d3702 bugfix: complete ldap support for macOS and Linux 2023-10-01 01:19:35 +08:00
crazywhalecc
fe39aecd72 adjust config order 2023-10-01 01:19:35 +08:00
crazywhalecc
68d176ad26 prevent c compiler not found error 2023-10-01 01:19:35 +08:00
crazywhalecc
d7627dd81a correct libc name for linux 2023-10-01 01:19:35 +08:00
crazywhalecc
a4e173f16d add configure flags for unix builder 2023-10-01 01:19:35 +08:00
DubbleClick
1437be3a9d gmp and libsodium for ldap if enabled
only enable openssl when zlib ext is also enabled (missing 'deflate' otherwise)
move back from source/php-src/ext/ldap to source/ldap (fix "LICENSE not found")
2023-10-01 01:19:35 +08:00
DubbleClick
059c32e59c add ext-ldap (openldap) support 2023-10-01 01:19:35 +08:00
DubbleClick
e3a4cd6e1d fix spelling mistake in README-en.md 2023-10-01 01:19:35 +08:00
DubbleClick
dd9a5d8316 add rhel and almalinux support 2023-10-01 01:19:35 +08:00
Joseph Bielawski
3b83c1fa7b Remove dead code from ConsoleApplication class 2023-09-30 13:52:29 +08:00
Rif'at Ahdi R
ff128df76b Update libwebp dependency (fix #208) 2023-09-29 16:07:59 +08:00
crazywhalecc
cd04a9ea4f change all related url to static-php.dev 2023-09-26 22:27:44 +08:00
Jerry Ma
3b793005fe Change domain 2023-09-26 18:32:18 +08:00
Jerry Ma
87e073a0b9 Change domain 2023-09-26 18:29:45 +08:00
crazywhalecc
db8aa15677 adjust micro's phar patch execution location 2023-09-25 10:35:31 +08:00
crazywhalecc
6ed9749732 cs fix and composer update 2023-09-23 17:03:20 +08:00
crazywhalecc
4e99211bc3 add hardcoded-ini option for embed SAPI 2023-09-17 12:21:06 +08:00
crazywhalecc
824748c2a7 remove download cache and minimize download sources 2023-09-16 15:15:46 +08:00
crazywhalecc
fe6a98b30d remove debug option 2023-09-16 15:15:46 +08:00
crazywhalecc
49149cebf1 Add new GH action to build binary SPC 2023-09-16 15:15:46 +08:00
Joseph Bielawski
7b6a1b4212 Simplify adding composer in bin/spc-alpine-docker
Co-authored-by: Kévin Dunglas <kevin@dunglas.fr>
2023-09-15 09:39:27 +08:00
Joseph Bielawski
965e7a25e2 Add composer.lock into repository 2023-09-15 09:39:27 +08:00
Kévin Dunglas
0c3885c33d fix(docker): php82-sodium is required 2023-09-14 10:02:54 +08:00
Joseph Bielawski
be32190829 Sanity check extensions by inline their test code 2023-09-13 23:42:10 +08:00
crazywhalecc
f1d5916090 remove unused old deploy command 2023-09-13 21:45:19 +08:00
Joseph Bielawski
b2ea479fac Remove the phar workflow temporary 2023-09-13 21:45:19 +08:00
Joseph Bielawski
16cc5df66d Temporary disable phar build in GH actions 2023-09-13 21:45:19 +08:00
Joseph Bielawski
a63e3f4575 Add version into phar 2023-09-13 21:45:19 +08:00
Joseph Bielawski
6b061e6332 Adjust box configuration for smaller phar size 2023-09-13 21:45:19 +08:00
Joseph Bielawski
4a17491aaa Initial code to get Box for phar building 2023-09-13 21:45:19 +08:00
Jerry Ma
06f29712e2 Update README.md 2023-09-13 10:03:31 +08:00
Kévin Dunglas
4b1d59c5a9 Link to FrankenPHP docs about embed SAPI in README-en.md 2023-09-13 10:03:31 +08:00
crazywhalecc
1a81fe6a0d change help message for dev:extensions 2023-09-12 23:30:23 +08:00
crazywhalecc
c63136d484 change dev:extensions argument to comma separated 2023-09-12 23:30:23 +08:00
crazywhalecc
4b500f2dd8 remove redundant libssh2 cmake build target option 2023-09-12 23:09:58 +08:00
crazywhalecc
9da20497cc fix ln src and dst for brotli 2023-09-12 22:53:47 +08:00
crazywhalecc
5efc15b404 fix libwebp pkgconfig patch, add custom patch argument 2023-09-12 22:52:20 +08:00
Joseph Bielawski
fa0740f216 Explicitly define application commands 2023-09-12 22:51:50 +08:00
Joseph Bielawski
52430cbdde Rework doctor command 2023-09-12 22:46:44 +08:00
crazywhalecc
01c4538ce0 update README for embed SAPI 2023-09-12 22:44:19 +08:00
Kévin Dunglas
3183ecceaf --disable-opcache-jit 2023-09-12 22:30:13 +08:00
Kévin Dunglas
dd2e7cc129 static opcache patch 2023-09-12 22:30:13 +08:00
Kévin Dunglas
adfa620ef4 Revert "always enable micro"
This reverts commit eb8cefd9ca.
2023-09-12 22:30:13 +08:00
Kévin Dunglas
1a32ddc70a Revert "temporary workaround for PECL certificate expiration"
This reverts commit 7c78003c9f.
2023-09-12 22:30:13 +08:00
Kévin Dunglas
4bfca6fe93 always enable micro 2023-09-12 22:30:13 +08:00
Kévin Dunglas
dbec043894 temporary workaround for PECL certificate expiration 2023-09-12 22:30:13 +08:00
Kévin Dunglas
727d78a689 Revert "fix: replace down URL"
This reverts commit 6eadbca21bf9a3b57058160a2f7ea8f4cc5f21dd.
2023-09-12 22:30:13 +08:00
Kévin Dunglas
9b1e784604 fix: replace down URL 2023-09-12 22:30:13 +08:00
Kévin Dunglas
50d44d8310 explicitly disable unneeded SAPIs 2023-09-12 22:30:13 +08:00
Kévin Dunglas
3b300698f3 use lixml GH mirror because gitlab.gnome.org is down 2023-09-12 22:30:13 +08:00
Kévin Dunglas
899eb94b8b remove useless ls 2023-09-12 22:30:13 +08:00
Kévin Dunglas
451a0c0e34 workaround for macOS 2023-09-12 22:30:13 +08:00
Kévin Dunglas
085c1a159c feat: add support for libphp and the embed SAPI 2023-09-12 22:30:13 +08:00
Joseph Bielawski
ca3f8a350d Prevent fatal error when php source files are missing 2023-09-12 18:19:32 +08:00
crazywhalecc
5025850f71 fix Alpine docker install packages 2023-09-12 12:45:51 +08:00
crazywhalecc
fe2f658e08 dev:sort-config add \n at the end of json 2023-09-12 00:24:01 +08:00
crazywhalecc
00a49c662b add build:libs option --rebuild 2023-09-11 23:47:02 +08:00
Marcel Pociot
0569c69634 remove path 2023-06-03 00:04:02 +02:00
Marcel Pociot
1b734073b0 Merge refactor 2023-06-02 22:47:59 +02:00
Marcel Pociot
47d068e6d3 Merge branch 'refactor' into libargon2-support 2023-06-02 22:47:47 +02:00
Marcel Pociot
4537bfb247 Add support for libargon2 2023-05-31 10:03:40 +02:00
167 changed files with 10783 additions and 1673 deletions

12
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,12 @@
## What does this PR do?
## 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 it's a extension or dependency update, make sure adding related extensions in `src/global/test-extensions.php`.
- [ ] If you changed the behavior of static-php-cli, add docs in [static-php/static-php-cli-docs](https://github.com/static-php/static-php-cli-docs) .
- [ ] If you updated `config/xxxx.json` content, run `bin/spc dev:sort-config xxx`.

View File

@@ -15,6 +15,7 @@ on:
default: '8.2'
type: choice
options:
- '8.3'
- '8.2'
- '8.1'
- '8.0'
@@ -51,7 +52,7 @@ jobs:
uses: actions/cache@v3
with:
path: downloads
key: php-${{ inputs.version }}-dependencies
key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
# With or without debug
- if: inputs.debug == true
@@ -67,7 +68,7 @@ jobs:
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: SPC_USE_ARCH=${{ inputs.operating-system }} ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
run: SPC_USE_ARCH=${{ inputs.operating-system }} ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }}
# Run build command
- run: SPC_USE_ARCH=${{ inputs.operating-system }} ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}

View File

@@ -9,6 +9,7 @@ on:
default: '8.2'
type: choice
options:
- '8.3'
- '8.2'
- '8.1'
- '8.0'
@@ -56,7 +57,7 @@ jobs:
uses: actions/cache@v3
with:
path: downloads
key: php-${{ inputs.version }}-dependencies
key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
# With or without debug
- if: inputs.debug == true
@@ -72,7 +73,7 @@ jobs:
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: CACHE_API_EXEC=yes ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
run: CACHE_API_EXEC=yes ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }}
# Run build command
- run: ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}

View File

@@ -9,6 +9,7 @@ on:
default: '8.2'
type: choice
options:
- '8.3'
- '8.2'
- '8.1'
- '8.0'
@@ -61,7 +62,7 @@ jobs:
uses: actions/cache@v3
with:
path: downloads
key: php-${{ inputs.version }}-dependencies
key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
# With or without debug
- if: inputs.debug == true
@@ -77,7 +78,7 @@ jobs:
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: ./bin/spc download --with-php=${{ inputs.version }} --all ${{ env.SPC_BUILD_DEBUG }}
run: ./bin/spc download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }}
# Run build command
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}

View File

@@ -1,40 +0,0 @@
name: archive download sources weekly
on:
workflow_dispatch:
schedule:
- cron: "* 14 * * 5"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
download:
name: cache download sources
runs-on: ubuntu-latest
strategy:
matrix:
php-version: [ "8.0", "8.1", "8.2" ]
steps:
- uses: actions/checkout@v3
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v3
with:
path: vendor
key: composer-dependencies
# If there's no Composer cache, install dependencies
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: ./bin/spc download --with-php=${{ matrix.php-version }} --all --debug
# Upload downloaded files
- uses: actions/upload-artifact@v3
with:
name: download-files-${{ matrix.php-version }}
path: downloads/

104
.github/workflows/release-build.yml vendored Normal file
View File

@@ -0,0 +1,104 @@
name: Build SPC Binary
on:
push:
branches: [ "main" ]
release:
types:
- published
workflow_dispatch:
jobs:
build-release-artifacts:
name: "Build SPC Binary"
runs-on: ubuntu-latest
strategy:
matrix:
php-version:
- "8.1"
micro-version:
- "8.1.26"
operating-system:
- "linux-x86_64"
- "macos-x86_64"
- "linux-aarch64"
- "macos-aarch64"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
- if: inputs.debug == true
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
- name: "Install PHP for official runners"
uses: "shivammathur/setup-php@v2"
with:
coverage: none
tools: composer:v2
php-version: "${{ matrix.php-version }}"
ini-values: memory_limit=-1
- 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@v3"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-${{ matrix.php-version }}-locked-composer-${{ hashFiles('**/composer.lock') }}"
restore-keys: |
php-${{ matrix.php-version }}-locked-composer
- name: "Install Locked Dependencies"
run: "composer install --no-interaction --no-progress"
- name: "Build PHAR File"
run: "composer build:phar"
- name: "Download minimal combination"
run: |
curl https://dl.static-php.dev/static-php-cli/minimal/php-${{ matrix.micro-version }}-micro-${{ matrix.operating-system }}.tar.gz -o tmp.tgz
tar -zxvf tmp.tgz
- name: "Generate Executable"
run: |
cat micro.sfx spc.phar > spc
chmod +x spc
- name: "Archive Executable"
run: |
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
if [ "${{ matrix.operating-system }}" == "linux-x86_64" ]; then
./spc dev:extensions
fi
- name: "Copy file"
run: "mkdir dist/ && cp ${{ env.filename }} dist/ && cp spc dist/spc-$OS"
- name: upload binaries to release
uses: softprops/action-gh-release@v1
if: ${{startsWith(github.ref, 'refs/tags/') }}
with:
files: ${{ env.filename }}
- name: "Deploy to Self-Hosted Server"
if: github.repository == 'crazywhalecc/static-php-cli'
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SERVER_SECRET_KEY }}
ARGS: "-rltgoDzvO"
SOURCE: "dist/"
REMOTE_HOST: ${{ secrets.DEPLOY_SERVER_HOST }}
REMOTE_PORT: ${{ secrets.DEPLOY_SERVER_PORT }}
REMOTE_USER: ${{ secrets.DEPLOY_SERVER_USER }}
TARGET: ${{ secrets.DEPLOY_SERVER_TARGET_SPC_NIGHTLY }}
- name: "Upload Artifact"
uses: actions/upload-artifact@v3
with:
path: spc
name: spc-${{ matrix.operating-system }}

View File

@@ -1,98 +1,156 @@
name: Tests
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
push:
branches:
- main
paths:
- 'src/globals/test-extensions.php'
pull_request:
branches: [ "main" ]
permissions:
contents: read
contents: read
jobs:
php-cs-fixer:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
php-cs-fixer:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: "Checkout"
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
tools: pecl, composer, php-cs-fixer
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
tools: pecl, composer, php-cs-fixer
- name: Run PHP-CS-Fixer fix
run: php-cs-fixer fix --dry-run --diff --ansi
- name: Run PHP-CS-Fixer fix
run: php-cs-fixer fix --dry-run --diff --ansi
phpstan:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
phpstan:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: "Checkout"
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
tools: composer
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
tools: composer
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-phpstan-
- name: "Cache Composer packages"
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-phpstan-
- name: Install Dependencies
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: "Install Dependencies"
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Run phpstan
run: vendor/bin/phpstan analyse
- name: "Run phpstan"
run: vendor/bin/phpstan analyse
phpunit:
name: PHPUnit (PHP ${{ matrix.php }})
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
matrix:
include:
- php: '8.1'
- php: '8.2'
fail-fast: false
phpunit:
name: "PHPUnit (PHP ${{ matrix.php }})"
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
matrix:
include:
- php: '8.1'
- php: '8.2'
- php: '8.3'
steps:
- name: Checkout
uses: actions/checkout@v4
steps:
- name: "Checkout"
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php }}"
tools: pecl, composer
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php }}"
tools: pecl, composer
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: "Cache Composer packages"
id: composer-cache
uses: actions/cache@v3
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
- name: "Install Dependencies"
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Run PHPUnit tests
run: |
vendor/bin/phpunit tests/ --no-coverage
- name: "Run PHPUnit Tests"
run: |
vendor/bin/phpunit tests/ --no-coverage
build:
name: "Build PHP Test (PHP ${{ matrix.php }} ${{ matrix.os }})"
runs-on: ${{ matrix.os }}
timeout-minutes: 120
strategy:
matrix:
php:
- "8.0"
- "8.1"
- "8.2"
- "8.3"
os:
- ubuntu-latest
- macos-latest
fail-fast: false
steps:
- name: "Checkout"
uses: actions/checkout@v4
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
tools: pecl, composer
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
- name: "Cache Composer packages"
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
# Cache downloaded source
- id: cache-download
uses: actions/cache@v3
with:
path: downloads
key: php-${{ matrix.php }}-dependencies
- name: "Install Dependencies"
run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: "Run Build Tests (doctor)"
run: bin/spc doctor --auto-fix
- name: "Run Build Tests (download)"
run: bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --with-php=${{ matrix.php }} --debug
- name: "Run Build Tests (build)"
run: bin/spc build $(php src/globals/test-extensions.php cmd) --build-cli --build-micro --build-fpm --debug

View File

@@ -0,0 +1,43 @@
name: Update Docs Config
on:
push:
branches:
- main
paths:
- 'config/**.json'
jobs:
update-docs-config:
name: "Update Docs Config"
runs-on: ubuntu-latest
if: github.repository == 'crazywhalecc/static-php-cli'
steps:
- name: "Checkout static-php-cli"
uses: actions/checkout@v4
with:
ref: main
path: static-php-cli
- name: "Checkout static-php-cli-docs"
uses: actions/checkout@v4
with:
repository: static-php/static-php-cli-docs
ref: master
token: ${{ secrets.DOCS_REPO_TOKEN }}
path: static-php-cli-docs
- name: "Set up Git"
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
- name: "Copy Config Files"
run: cp -r static-php-cli/config/* static-php-cli-docs/docs/.vitepress/config/
- name: "Commit and Push Changes"
run: |
cd static-php-cli-docs
git add -A
git commit -m "Sync config files from main"
git push origin master

10
.gitignore vendored
View File

@@ -4,8 +4,7 @@ docker/libraries/
docker/extensions/
docker/source/
# Composer file
composer.lock
# Vendor files
/vendor/
# default source extract directory
@@ -23,9 +22,12 @@ composer.lock
# exclude self-runtime
/bin/*
!/bin/spc
!/bin/setup-runtime
!/bin/spc*
!/bin/setup-runtime*
!/bin/spc-alpine-docker
# exclude windows build tools
/php-sdk-binary-tools/
# default test directory
/tests/var/

View File

@@ -63,6 +63,7 @@ return (new PhpCsFixer\Config())
'phpdoc_summary' => false,
'php_unit_test_class_requires_covers' => false,
'phpdoc_var_without_name' => false,
'fully_qualified_strict_types' => false,
])
->setFinder(
PhpCsFixer\Finder::create()->in([__DIR__ . '/src', __DIR__ . '/tests/SPC'])

View File

@@ -1,245 +1,3 @@
# static-php-cli
Build single static PHP binary, with PHP project together, with popular extensions included.
The project name is static-php-cli, but it actually supports cli, fpm, micro and embed (on the way) SAPI 😎
Compile a purely static php-cli binary file with various extensions to make PHP applications more portable! (cli SAPI)
<img width="600" alt="2023-05-02 15 53 13" src="https://user-images.githubusercontent.com/20330940/235610282-23e58d68-bd35-4092-8465-171cff2d5ba8.png">
You can also use the micro binary file to combine php binary and php source code into one for distribution!
This feature is provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro). (micro SAPI)
<img width="600" alt="2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
[![Version](https://img.shields.io/badge/Version-2.0--rc5-pink.svg?style=flat-square)]()
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)]()
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-linux-x86_64.yml?branch=refactor&label=Linux%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-macos-x86_64.yml?branch=refactor&label=macOS%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
[![](https://img.shields.io/badge/Extension%20Counter-55+-yellow.svg?style=flat-square)]()
[![](https://img.shields.io/github/search/crazywhalecc/static-php-cli/TODO?label=TODO%20Counter&style=flat-square)]()
## Compilation Requirements
Yes, this project is written in PHP, pretty funny.
But static-php-cli runtime only requires an environment above PHP 8.1 and `mbstring`, `pcntl` extension.
Here is the architecture support status, where `CI` represents support for GitHub Action builds,
`Local` represents support for local builds, and blank represents not currently supported.
| | x86_64 | aarch64 |
|---------|-----------|-----------|
| macOS | CI, Local | Local |
| Linux | CI, Local | CI, Local |
| Windows | | |
> macOS-arm64 is not supported for GitHub Actions, if you are going to build on arm, you can build it manually on your own machine.
Currently supported PHP versions for compilation are: `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`.
## Docs
docs here: <https://static-php-cli.zhamao.me>.
## Simple Usage
Please first select the extension you want to compile based on the extension list below.
### Direct Download
If you don't compile yourself, you can download pre-compiled artifact from Actions, or from self-hosted server: [Here](https://dl.zhamao.xin/static-php-cli/)
> self-hosted server contains extensions: `bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip`
### Supported Extensions
[Supported Extension List](https://static-php-cli.zhamao.me/en/guide/extensions.html)
> If there is no extension you need here, you can submit an issue.
### GitHub Actions Build
Use GitHub Action to easily build a statically compiled PHP and phpmicro,
and at the same time define the extensions to be compiled by yourself.
1. Fork me.
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`.
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
- When using ubuntu-latest, it will build linux-x86_64 binary.
- When using macos-latest, it will build macOS-x86_64 binary.
### Manual Build
Clone repo first:
```bash
git clone https://github.com/crazywhalecc/static-php-cli.git
```
If you have not installed php on your system, you can use package management to install PHP (such as brew, apt, yum, apk etc.).
And you can also download single-file php binary and composer using command `bin/setup-runtime`.
The PHP runtime for static-php-cli itself will be downloaded at `bin/php`, and composer is at `bin/composer`.
```bash
cd static-php-cli
chmod +x bin/setup-runtime
# It will download php-cli from self-hosted server and composer from getcomposer.org
./bin/setup-runtime
# Use this php runtime to run static-php-cli compiler
./bin/php bin/spc
# Use composer
./bin/php bin/composer
```
Basic usage for building php and micro with some extensions:
```bash
cd static-php-cli
composer update
chmod +x bin/spc
# Check system tool dependencies, fix them automatically
./bin/spc doctor
# fetch all libraries
./bin/spc fetch --all
# with bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl extension, build both CLI and phpmicro SAPI
./bin/spc build bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl --build-cli --build-micro
```
You can also use the parameter `--with-php=x.y` to specify the downloaded PHP version, currently supports 7.4 ~ 8.2:
```bash
# Using PHP >= 8.0 is recommended, because PHP7 cannot use phpmicro
./bin/spc fetch --with-php=8.2 --all
```
Now we support `cli`, `micro`, `fpm`, you can use one or more of the following parameters to specify the compiled SAPI:
- `--build-cli`: build static cli executable
- `--build-micro`: build static phpmicro self-extracted executable
- `--build-fpm`: build static fpm binary
- `--build-all`: build all
If anything goes wrong, use `--debug` option to display full terminal output:
```bash
./bin/spc build openssl,pcntl,mbstring --debug --build-all
./bin/spc fetch --all --debug
```
In addition, we build NTS by default. If you are going to build ZTS version, just add `--enable-zts` option.
```bash
./bin/spc build openssl,pcntl --build-all --enable-zts
```
Adding option `--no-strip` can produce binaries with debug symbols, in order to debug (using gdb). Disabling strip will increase the size of static binary.
### php-cli Usage
> php-cli is a single static binary, you can use it like normal php installed on your system.
When using the parameter `--build-cli` or `--build-all`,
the final compilation result will output a binary file named `./php`,
which can be distributed and used directly.
This file will be located in the directory `buildroot/bin/`, copy it out for use.
```bash
cd buildroot/bin/
./php -v # check version
./php -m # check extensions
./php your_code.php # run your php code
./php your_project.phar # run your phar (project archive)
```
### micro.sfx Usage
> phpmicro is a SelF-extracted eXecutable SAPI module,
> provided by [dixyes/phpmicro](https://github.com/dixyes/phpmicro).
> It can put php runtime and your source code together.
When using the parameter `--build-all` or `--build-micro`,
the final compilation result will output a file named `./micro.sfx`,
which needs to be used with your PHP source code like `code.php`.
This file will be located in the path `buildroot/bin/micro.sfx`, simply copy it out for use.
Prepare your project source code, which can be a single PHP file or a Phar file, for use.
```bash
echo "<?php echo 'Hello world' . PHP_EOL;" > code.php
cat micro.sfx code.php > single-app && chmod +x single-app
./single-app
# If packing a PHAR file, replace code.php with the Phar file path.
```
> In some cases, PHAR files may not run in a micro environment.
### php-fpm Usage
When using the parameter `--build-all` or `--build-fpm`,
the final compilation result will output a file named `./php-fpm`,
This file will be located in the path `buildroot/bin/`, simply copy it out for use.
In normal Linux distributions and macOS systems, the package manager will automatically generate a default fpm configuration file after installing php-fpm.
Because php-fpm must specify a configuration file before running, the php-fpm compiled by this project will not have any configuration files, so you need to write `php-fpm.conf` and `pool.conf` configuration files yourself.
Specifying `php-fpm.conf` can use the command parameter `-y`, for example: `./php-fpm -y php-fpm.conf`.
## Contribution
Currently, there are only a few supported extensions.
If the extension you need is missing, you can create an issue.
If you are familiar with this project, you are also welcome to initiate a pull request.
The basic principles for contributing are as follows:
- This project uses php-cs-fixer and phpstan as code formatting tools. Before contributing, please run `composer analyze` and `composer cs-fix` on the updated code.
- If other open source libraries are involved, the corresponding licenses should be provided.
Also, configuration files should be sorted using the command `sort-config` after modification.
For more information about sorting commands, see the documentation.
- Naming conventions should be followed, such as using the extension name registered in PHP for the extension name itself,
and external library names should follow the project's own naming conventions. For internal logic functions, class names, variables, etc.,
camelCase and underscore formats should be followed, and mixing within the same module is prohibited.
- When compiling external libraries and creating patches, compatibility with different operating systems should be considered.
If you want to contribute document content, please go to [crazywhalecc/static-php-cli-docs](https://github.com/crazywhalecc/static-php-cli-docs).
Part of the English document is written by me, and part is translated by Google,
and there may be inaccurate descriptions, strange or offensive expressions.
If you are a native English speaker, some corrections to the documentation are welcome.
## Sponsor this project
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
## Open-Source License
This project itself is based on MIT License,
some newly added extensions and dependencies may originate from the following projects (including but not limited to),
and the headers of these code files will also be given additional instructions LICENSE and AUTHOR:
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs) (Mulun Permissive License)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli) (Apache 2.0 LICENSE+SWOOLE-CLI LICENSE)
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.
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.
## Advanced
The refactoring branch of this project is written modularly.
If you are interested in this project and want to join the development,
you can refer to the [Contribution Guide](https://static-php-cli.zhamao.me) of the documentation to contribute code or documentation.
English README has been moved to [README.md](README.md).

267
README-zh.md Executable file
View File

@@ -0,0 +1,267 @@
# static-php-cli
[![Version](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)]()
[![](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://img.shields.io/badge/Extension%20Counter-75+-yellow.svg?style=flat-square)]([https://static-php.dev/](https://static-php.dev/en/guide/extensions.html))
[![](https://dcbadge.vercel.app/api/server/RNpegEYW?style=flat-square&compact=true&theme=default-inverted)](https://discord.gg/RNpegEYW)
**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。
目前 static-php-cli 支持 `cli``fpm``embed``micro` SAPI。
**static-php-cli**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。
- [README - English](./README.md)
- [README - 中文](./README-zh.md)
## 特性
static-php-cli简称 `spc`)有许多特性:
- :handbag: 构建独立的单文件 PHP 解释器,无需任何依赖
- :hamburger: 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自执行二进制(将 PHP 代码和 PHP 解释器打包为一个文件)
- :pill: 提供一键检查和修复编译环境的 Doctor 模块
- :zap: 支持多个系统:`Linux``macOS``FreeBSD`、[`Windows (WIP)`](https://github.com/crazywhalecc/static-php-cli/pull/301)
- :wrench: 高度自定义的代码 patch 功能
- :books: 自带编译依赖管理
- 📦 提供由自身编译的独立 `spc` 二进制(使用 spc 和 [box](https://github.com/box-project/box) 构建)
- :fire: 支持大量 [扩展](https://static-php.dev/zh/guide/extensions.html)
**静态 php-cli:**
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
**使用 phpmicro 打包 PHP 代码:**
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
## 文档
目前 README 编写了基本用法。有关 static-php-cli 所有的功能,请点击这里查看文档:<https://static-php.dev>。
## 直接下载
如果你不想自行编译 PHP可以从本项目现有的示例 Action 下载 Artifact也可以从自托管的服务器下载。
- [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/)common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 22MB 左右。
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/)bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 70MB 左右。
- [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/)minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 6MB 左右。
## 使用 static-php-cli 构建 PHP
### 编译环境需求
- PHP >= 8.1spc 自身是用 PHP 写的)
- 扩展:`mbstring,pcntl,posix,tokenizer,phar`
- 系统安装了 `curl``git`
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
| | x86_64 | aarch64 |
|---------|----------------------|----------------------|
| macOS | :octocat: :computer: | :computer: |
| Linux | :octocat: :computer: | :octocat: :computer: |
| Windows | | |
| FreeBSD | :computer: | :computer: |
目前支持编译的 PHP 版本为:`7.3``7.4``8.0``8.1``8.2``8.3`
### 支持的扩展
请先根据下方扩展列表选择你要编译的扩展。
- [扩展支持列表](https://static-php.dev/zh/guide/extensions.html)
- [编译命令生成器](https://static-php.dev/zh/guide/cli-generator.html)
> 如果这里没有你需要的扩展,可以提交 Issue。
### 在线构建(使用 GitHub Actions
使用 GitHub Action 可以方便地构建一个静态编译的 PHP同时可以自行定义要编译的扩展。
1. Fork 本项目。
2. 进入项目的 Actions选择 CI。
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
### 本地构建(使用 spc 二进制)
该项目提供了 static-php-cli 的二进制文件:`spc`
您可以使用 `spc` 二进制文件,无需安装任何运行时(用起来就像 golang 程序)。
目前,`spc` 二进制文件提供的平台有 Linux 和 macOS。
使用以下命令从自托管服务器下载:
```bash
# Download from self-hosted nightly builds (sync with main branch)
# For Linux x86_64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
# add x perm
chmod +x ./spc
./spc --version
```
自托管 `spc` 由 GitHub Actions 构建,你也可以从 Actions 直接下载:[此处](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml)。
### 本地构建(使用 git 源码)
```bash
# clone 仓库即可
git clone https://github.com/crazywhalecc/static-php-cli.git
```
如果您的系统上尚未安装 php我们建议你使用内置的 setup-runtime 自动安装 PHP 和 Composer。
```bash
cd static-php-cli
chmod +x bin/setup-runtime
# it will download static php (from self-hosted server) and composer (from getcomposer)
bin/setup-runtime
# initialize composer deps
bin/composer install
# chmod
chmod +x bin/spc
bin/spc --version
```
### 开始构建 PHP
下面是使用 static-php-cli 的基础用法:
> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `./bin/spc` 替换为 `./spc`。
```bash
# 检查环境依赖,并根据尝试自动安装缺失的编译工具
./bin/spc doctor --auto-fix
# 拉取所有依赖库
./bin/spc download --all
# 只拉取编译指定扩展需要的所有依赖(推荐)
./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
# 下载编译不同版本的 PHP (--with-php=x.y推荐 7.3 ~ 8.3)
./bin/spc download --for-extensions=openssl,curl,mbstring --with-php=8.1
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
# 编译线程安全版本 (--enable-zts)
./bin/spc build curl,phar --enable-zts --build-cli
```
其中,目前支持构建 climicrofpm 和 embed使用以下参数的一个或多个来指定编译的 SAPI
- `--build-cli`:构建 cli 二进制
- `--build-micro`:构建 phpmicro 自执行二进制
- `--build-fpm`:构建 fpm
- `--build-embed`:构建 embedlibphp
- `--build-all`:构建所有
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
```bash
./bin/spc build openssl,pcntl,mbstring --debug --build-all
./bin/spc download --all --debug
```
## 不同 SAPI 的使用
### 使用 cli
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
采用参数 `--build-cli``--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
```bash
cd buildroot/bin/
./php -v # 检查版本
./php -m # 检查编译的扩展
./php your_code.php # 运行代码
./php your_project.phar # 运行打包为 phar 单文件的项目
```
### 使用 micro
> phpmicro 是一个提供自执行二进制 PHP 的项目,本项目依赖 phpmicro 进行编译自执行二进制。详见 [dixyes/phpmicro](https://github.com/dixyes/phpmicro)。
采用项目参数 `--build-micro``--build-all` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
该文件编译后会存放在 `buildroot/bin/` 目录中,拷贝出来即可。
使用时应准备好你的项目源码文件,可以是单个 PHP 文件,也可以是 Phar 文件。
```bash
echo "<?php echo 'Hello world' . PHP_EOL;" > code.php
cat micro.sfx code.php > single-app && chmod +x single-app
./single-app
```
如果打包 PHAR 文件,仅需把 code.php 更换为 phar 文件路径即可。
你可以使用 [box-project/box](https://github.com/box-project/box) 将你的 CLI 项目打包为 Phar
然后将它与 phpmicro 结合,生成独立可执行的二进制文件。
```bash
# 使用 static-php-cli 生成的 micro.sfx 结合,也可以直接使用 cat 命令结合它们
bin/spc micro:combine my-app.phar
cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
# 使用 micro:combine 结合可以将 INI 选项注入到二进制中
bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
```
> 有些情况下的 phar 文件或 PHP 项目可能无法在 micro 环境下运行。
### 使用 fpm
采用项目参数 `--build-fpm``--build-all` 时,最后编译结果会输出一个 `./php-fpm` 的文件。
该文件存放在 `buildroot/bin/` 目录,拷贝出来即可使用。
在正常的 Linux 发行版和 macOS 系统中,安装 php-fpm 后包管理会自动生成默认的 fpm 配置文件。
因为 php-fpm 必须指定配置文件才可启动,本项目编译的 php-fpm 不会带任何配置文件,所以需自行编写 `php-fpm.conf``pool.conf` 配置文件。
指定 `php-fpm.conf` 可以使用命令参数 `-y`,例如:`./php-fpm -y php-fpm.conf`
### 使用 embed
采用项目参数 `--build-embed``--build-all` 时,最后编译结果会输出一个 `libphp.a``php-config` 以及一系列头文件,存放在 `buildroot/`,你可以在你的其他代码中引入它们。
如果你知道 [embed SAPI](https://github.com/php/php-src/tree/master/sapi/embed),你应该知道如何使用它。对于有可能编译用到引入其他库的问题,你可以使用 `buildroot/bin/php-config` 来获取编译时的配置。
另外,有关如何使用此功能的高级示例,请查看[如何使用它构建 FrankenPHP 的静态版本](https://github.com/dunglas/frankenphp/blob/main/docs/static.md)。
## 贡献
如果缺少你需要的扩展,可发起 Issue。如果你对本项目较熟悉也欢迎为本项目发起 Pull Request。
另外,添加新扩展的贡献方式,可以参考下方 `进阶`
如果你想贡献文档内容,请到项目仓库 [static-php/static-php-cli-docs](https://github.com/static-php/static-php-cli-docs) 贡献。
## 赞助本项目
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。
## 开源协议
本项目依据旧版本惯例采用 MIT License 开源,部分扩展的集成编译命令参考或修改自以下项目:
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)(木兰宽松许可证)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)Apache 2.0 LICENSE、SWOOLE-CLI LICENSE
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
## 进阶
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php.dev) 贡献代码或文档。

340
README.md
View File

@@ -1,215 +1,295 @@
# static-php-cli
Build single static PHP binary, with PHP project together, with popular extensions included.
**If you are using English, see [English README](README-en.md).**
编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携cli SAPI
<img width="600" alt="截屏2023-05-02 15 53 13" src="https://user-images.githubusercontent.com/20330940/235610282-23e58d68-bd35-4092-8465-171cff2d5ba8.png">
同时可以使用 micro 二进制文件,将 PHP 源码和 PHP 二进制构建为一个文件分发!(由 [dixyes/phpmicro](https://github.com/dixyes/phpmicro) 提供支持micro SAPI
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
[![Version](https://img.shields.io/badge/Version-2.0--rc5-pink.svg?style=flat-square)]()
[![Version](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)]()
[![](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://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-linux-x86_64.yml?branch=refactor&label=Linux%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/build-macos-x86_64.yml?branch=refactor&label=macOS%20Build&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
[![](https://img.shields.io/badge/Extension%20Counter-55+-yellow.svg?style=flat-square)]()
[![](https://img.shields.io/github/search/crazywhalecc/static-php-cli/TODO?label=TODO%20Counter&style=flat-square)]()
[![](https://img.shields.io/badge/Extension%20Counter-75+-yellow.svg?style=flat-square)]([https://static-php.dev/](https://static-php.dev/en/guide/extensions.html))
[![](https://dcbadge.vercel.app/api/server/RNpegEYW?style=flat-square&compact=true&theme=default-inverted)](https://discord.gg/RNpegEYW)
> 项目名称是 static-php-cli,但其实支持 cli、fpm、micro 和 embed正在路上SAPI 😎
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
with popular extensions.
## 编译环境需求
Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed` and `micro` SAPI.
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
**static-php-cli** also has the ability to package PHP projects
along with the PHP interpreter into one single executable file.
下面是架构支持情况,`CI` 代表支持 GitHub Action 构建,`Local` 代表支持本地构建,空 代表暂不支持。
- [README - English](./README.md)
- [README - 中文](./README-zh.md)
| | x86_64 | aarch64 |
|---------|-----------|-----------|
| macOS | CI, Local | Local |
| Linux | CI, Local | CI, Local |
| Windows | | |
## Features
> macOS-arm64 因 GitHub 暂未提供 arm runner如果要构建 arm 二进制,可以使用手动构建。
static-php-cli (you can call it `spc`) has a lot of features:
目前支持编译的 PHP 版本为:`7.3``7.4``8.0``8.1``8.2``8.3`
- :handbag: Build single-file php executable, without any dependencies
- :hamburger: Build **[phpmicro](https://github.com/dixyes/phpmicro)** self-extracted executable (glue php binary and php source code into one file)
- :pill: Automatic build environment checker (Doctor module)
- :zap: `Linux`, `macOS`, `FreeBSD`, [`Windows (WIP)`](https://github.com/crazywhalecc/static-php-cli/pull/301) support
- :wrench: Configurable source code patches
- :books: Build dependency management
- 📦 Provide `spc` own standalone executable (built by spc and [box](https://github.com/box-project/box))
- :fire: Support many popular [extensions](https://static-php.dev/en/guide/extensions.html)
## 文档
**Single-file standalone php-cli:**
点击这里查看文档:<https://static-php-cli.zhamao.me>。
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
## 使用
**Combine PHP code with PHP interpreter using phpmicro:**
请先根据下方扩展列表选择你要编译的扩展。
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
### 自托管直接下载
## Documentation
如果你不想自行编译,可以从本项目现有的 Action 下载 Artifact也可以从自托管的服务器下载[进入](https://dl.zhamao.xin/static-php-cli/)
The current README contains basic usage. For all the features of static-php-cli,
see <https://static-php.dev> .
> 自托管的服务器默认包含的扩展有:`bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip`
## 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.
[扩展支持列表](https://static-php-cli.zhamao.me/zh/guide/extensions.html)
Below are several precompiled static-php binaries with different extension combinations,
which can be downloaded directly according to your needs.
> 如果这里没有你需要的扩展,可以提交 Issue。
- [Extension-Combination - common](https://dl.static-php.dev/static-php-cli/common/): `common` contains about [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) commonly used extensions, and the size is about 22MB.
- [Extension-Combination - bulk](https://dl.static-php.dev/static-php-cli/bulk/): `bulk` contains [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) extensions and is about 70MB in size.
- [Extension-Combination - minimal](https://dl.static-php.dev/static-php-cli/minimal/): `minimal` contains [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) extensions and is about 6MB in size.
### 使用 Actions 构建
## Build
使用 GitHub Action 可以方便地构建一个静态编译的 PHP 和 phpmicro同时可以自行定义要编译的扩展。
### Compilation Requirements
1. Fork 本项目。
2. 进入项目的 Actions选择 CI。
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`
- PHP >= 8.1 (static-php-cli is written in PHP)
- Extension: `mbstring,pcntl,posix,tokenizer,phar`
- Supported OS with `curl` and `git` installed
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
You can say I made a PHP builder written in PHP, pretty funny.
But static-php-cli runtime only requires an environment above PHP 8.1 and `mbstring`, `pcntl` extension.
### 手动构建
Here is the supported OS and arch, where :octocat: represents support for GitHub Action builds,
:computer: represents support for local manual builds, and blank represents not currently supported.
先克隆本项目:
| | x86_64 | aarch64 |
|---------|----------------------|----------------------|
| macOS | :octocat: :computer: | :computer: |
| Linux | :octocat: :computer: | :octocat: :computer: |
| Windows | | |
| FreeBSD | :computer: | :computer: |
Currently supported PHP versions for compilation are: `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`.
### Supported Extensions
Please first select the extension you want to compile based on the extension list below.
- [Supported Extension List](https://static-php.dev/en/guide/extensions.html)
- [Command Generator](https://static-php.dev/en/guide/cli-generator.html)
> If an extension you need is missing, you can submit an issue.
Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
### Build Online (using GitHub Actions)
Use GitHub Action to easily build a statically compiled PHP,
and at the same time define the extensions to be compiled by yourself.
1. Fork me.
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`.
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
### Build Locally (using SPC binary)
This project provides a binary file of static-php-cli: `spc`.
You can use `spc` binary instead of installing any runtime like golang app.
Currently, the platforms supported by `spc` binary are Linux and macOS.
Download from self-hosted nightly builds using commands below:
```bash
# Download from self-hosted nightly builds (sync with main branch)
# For Linux x86_64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
# add x perm
chmod +x ./spc
./spc --version
```
Self-hosted `spc` is built by GitHub Actions, you can also download from Actions artifacts [here](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml).
### Build Locally (using git source)
```bash
# just clone me!
git clone https://github.com/crazywhalecc/static-php-cli.git
```
如果你本机没有安装 PHP你需要先使用包管理例如 brew、apt、yum、apk 等)安装 php。
你也可以通过 `bin/setup-runtime` 命令下载静态编译好的 php-cli 和 Composer。下载的 php 和 Composer 将保存为 `bin/php``bin/composer`
If you have not installed php on your system, we recommend that you use the built-in setup-runtime to install PHP and Composer automatically.
```bash
cd static-php-cli
chmod +x bin/setup-runtime
./bin/setup-runtime
# 使用独立的 php 运行 static-php-cli
./bin/php bin/spc
# 使用 composer
./bin/php bin/composer
```
下面是使用 static-php-cli 编译静态 php 和 micro 的基础用法:
```bash
# 克隆本项目
cd static-php-cli
composer update
# it will download static php (from self-hosted server) and composer (from getcomposer)
bin/setup-runtime
# initialize composer deps
bin/composer install
# chmod
chmod +x bin/spc
# 检查环境依赖,并根据提示的命令安装缺失的编译工具
./bin/spc doctor
# 拉取所有依赖库
./bin/spc fetch --all
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
bin/spc --version
```
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.3 ~ 8.3
### Start Building PHP
Basic usage for building php with some extensions:
> If you are using the packaged `spc` binary, you need to replace `bin/spc` with `./spc` in the following commands.
```bash
# 优先考虑使用 >= 8.0 的 PHP 版本,因为 phpmicro 不支持在 PHP7 中构建
./bin/spc fetch --with-php=8.2 --all
# Check system tool dependencies, auto-fix them if possible
./bin/spc doctor --auto-fix
# fetch all libraries
./bin/spc download --all
# only fetch necessary sources by needed extensions (recommended)
./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
# download different PHP version (--with-php=x.y, recommend 7.3 ~ 8.3)
./bin/spc download --for-extensions=openssl,curl,mbstring --with-php=8.1
# with bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl extension, build both CLI and phpmicro SAPI
./bin/spc build bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl --build-cli --build-micro
# build thread-safe (ZTS) version (--enable-zts)
./bin/spc build curl,phar --enable-zts --build-cli
```
其中,目前支持构建 climicrofpm 三种静态二进制,使用以下参数的一个或多个来指定编译的 SAPI
Now we support `cli`, `micro`, `fpm` and `embed` SAPI. You can use one or more of the following parameters to specify the compiled SAPI:
- `--build-cli`:构建 cli 二进制
- `--build-micro`:构建 phpmicro 自执行二进制
- `--build-fpm`:构建 fpm
- `--build-all`:构建所有
- `--build-cli`: build static cli executable
- `--build-micro`: build static phpmicro self-extracted executable
- `--build-fpm`: build static fpm binary
- `--build-embed`: build embed (libphp)
- `--build-all`: build all
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
If anything goes wrong, use `--debug` option to display full terminal output:
```bash
./bin/spc build openssl,pcntl,mbstring --debug --build-all
./bin/spc fetch --all --debug
./bin/spc download --all --debug
```
此外,默认编译的 PHP 为 NTS 版本。如需编译线程安全版本ZTS只需添加参数 `--enable-zts` 即可。
## Different SAPI Usage
```bash
./bin/spc build openssl,pcntl --build-all --enable-zts
```
### Use cli
同时,你也可以使用参数 `--no-strip` 来关闭裁剪,关闭裁剪后可以使用 gdb 等工具调试,但这样会让静态二进制体积变大。
> php-cli is a single static binary, you can use it like normal php installed on your system.
### 使用 php-cli
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
采用参数 `--build-cli``--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
When using the parameter `--build-cli` or `--build-all`,
the final compilation result will output a binary file named `./php`,
which can be distributed and used directly.
This file will be located in the directory `buildroot/bin/`, copy it out for use.
```bash
cd buildroot/bin/
./php -v # 检查版本
./php -m # 检查编译的扩展
./php your_code.php # 运行代码
./php your_project.phar # 运行打包为 phar 单文件的项目
./php -v # check version
./php -m # check extensions
./php your_code.php # run your php code
./php your_project.phar # run your phar (project archive)
```
### 使用 micro.sfx
### Use micro
> phpmicro 是一个提供自执行二进制 PHP 的项目,本项目依赖 phpmicro 进行编译自执行二进制。详见 [dixyes/phpmicro](https://github.com/dixyes/phpmicro)。
> phpmicro is a SelF-extracted eXecutable SAPI module,
> provided by [phpmicro](https://github.com/dixyes/phpmicro) project.
> But this project is using a [fork](https://github.com/static-php/phpmicro) of phpmicro, because we need to add some features to it.
> It can put php runtime and your source code together.
采用项目参数 `--build-micro``--build-all` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
该文件编译后会存放在 `buildroot/bin/` 目录中,拷贝出来即可。
When using the parameter `--build-all` or `--build-micro`,
the final compilation result will output a file named `./micro.sfx`,
which needs to be used with your PHP source code like `code.php`.
This file will be located in the path `buildroot/bin/micro.sfx`, simply copy it out for use.
使用时应准备好你的项目源码文件,可以是单个 PHP 文件,也可以是 Phar 文件。
Prepare your project source code, which can be a single PHP file or a Phar file, for use.
```bash
echo "<?php echo 'Hello world' . PHP_EOL;" > code.php
cat micro.sfx code.php > single-app && chmod +x single-app
./single-app
# 如果打包 PHAR 文件,仅需把 code.php 更换为 phar 文件路径即可
```
> 有些情况下的 phar 文件可能无法在 micro 环境下运行。
If you package a PHAR file, just replace `code.php` with the phar file path.
You can use [box-project/box](https://github.com/box-project/box) to package your CLI project as Phar,
It is then combined with phpmicro to produce a standalone executable binary.
### 使用 php-fpm
```bash
# Use the micro.sfx generated by static-php-cli to combine,
bin/spc micro:combine my-app.phar
# or you can directly use the cat command to combine them.
cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
采用项目参数 `--build-fpm``--build-all` 时,最后编译结果会输出一个 `./php-fpm` 的文件。
该文件存放在 `buildroot/bin/` 目录,拷贝出来即可使用。
# Use micro:combine combination to inject INI options into the binary.
bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
```
在正常的 Linux 发行版和 macOS 系统中,安装 php-fpm 后包管理会自动生成默认的 fpm 配置文件。
因为 php-fpm 必须指定配置文件才可启动,本项目编译的 php-fpm 不会带任何配置文件,所以需自行编写 `php-fpm.conf``pool.conf` 配置文件。
> In some cases, PHAR files may not run in a micro environment. Overall, micro is not production ready.
指定 `php-fpm.conf` 可以使用命令参数 `-y`,例如:`./php-fpm -y php-fpm.conf`
### Use fpm
## 贡献
When using the parameter `--build-all` or `--build-fpm`,
the final compilation result will output a file named `./php-fpm`,
This file will be located in the path `buildroot/bin/`, simply copy it out for use.
目前支持的扩展较少,如果缺少你需要的扩展,可发起 Issue。如果你对本项目较熟悉也欢迎为本项目发起 Pull Request。
In common Linux distributions and macOS systems, the package manager will automatically generate a default fpm configuration file after installing php-fpm.
Because php-fpm must specify a configuration file before running, the php-fpm compiled by this project will not have any configuration files, so you need to write `php-fpm.conf` and `pool.conf` configuration files yourself.
贡献基本原则如下:
Specifying `php-fpm.conf` can use the command parameter `-y`, for example: `./php-fpm -y php-fpm.conf`.
- 项目采用了 php-cs-fixer、phpstan 作为代码规范工具,贡献前请对更新的代码执行 `composer analyze``composer cs-fix`
- 涉及到其他开源库的部分应提供对应库的协议,同时对配置文件在修改后采用命令 `sort-config` 排序。有关排序的命令,见文档。
- 应遵循命名规范,例如扩展名称应采取 PHP 内注册的扩展名本身,外部库名应遵循项目本身的名称,内部逻辑的函数、类名、变量等应遵循驼峰、下划线等格式,禁止同一模块混用。
- 涉及编译外部库的命令和 Patch 时应注意兼容不同操作系统。
### Use embed
另外,添加新扩展的贡献方式,可以参考下方 `进阶`
When using the project parameters `--build-embed` or `--build-all`,
the final compilation result will output a `libphp.a`, `php-config` and a series of header files,
stored in `buildroot/`. You can introduce them in your other projects.
如果你想贡献文档内容,请到项目仓库 [crazywhalecc/static-php-cli-docs](https://github.com/crazywhalecc/static-php-cli-docs) 贡献。
If you know [embed SAPI](https://github.com/php/php-src/tree/master/sapi/embed), you should know how to use it.
You may require the introduction of other libraries during compilation,
you can use `buildroot/bin/php-config` to obtain the compile-time configuration.
## 赞助本项目
For an advanced example of how to use this feature, take a look at [how to use it to build a static version of FrankenPHP](https://github.com/dunglas/frankenphp/blob/main/docs/static.md).
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。
## Contribution
## 开源协议
If the extension you need is missing, you can create an issue.
If you are familiar with this project, you are also welcome to initiate a pull request.
本项目依据旧版本惯例采用 MIT License 开源,自身的部分代码引用或修改自以下项目:
If you want to contribute documentation, please go to [static-php/static-php-cli-docs](https://github.com/static-php/static-php-cli-docs).
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)(木兰宽松许可证)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)Apache 2.0 LICENSE、SWOOLE-CLI LICENSE
Now there is a [static-php](https://github.com/static-php) organization, which is used to store the repo related to the project.
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
## Sponsor this project
## 进阶
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php-cli.zhamao.me) 贡献代码或文档。
## 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)
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.
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

@@ -25,7 +25,7 @@ __DIR__=$(cd "$(dirname "$0")" && pwd)
__PROJECT__=$(cd "${__DIR__}"/../ && pwd)
# set download dir
__PHP_RUNTIME_URL__="https://dl.zhamao.xin/static-php-cli/php-8.2.6-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
__PHP_RUNTIME_URL__="https://dl.static-php.dev/static-php-cli/bulk/php-8.2.13-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
__COMPOSER_URL__="https://getcomposer.org/download/latest-stable/composer.phar"
# use china mirror
@@ -35,7 +35,6 @@ while [ $# -gt 0 ]; do
case "$1" in
--mirror)
mirror="$2"
shift
;;
--*)
echo "Illegal option $1"
@@ -46,8 +45,8 @@ done
case "$mirror" in
china)
__PHP_RUNTIME_URL__="https://dl.zhamao.xin/static-php-cli/php-8.2.6-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
__COMPOSER_URL__="https://mirrors.aliyun.com/composer/composer.phar"
__PHP_RUNTIME_URL__="https://dl.static-php.dev/static-php-cli/bulk/php-8.2.13-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
__COMPOSER_URL__="https://mirrors.tencent.com/composer/composer.phar"
;;
esac

115
bin/setup-runtime.ps1 Normal file
View File

@@ -0,0 +1,115 @@
param (
[string] ${action}
)
function AddToPath {
param (
[string]$pathToAdd
)
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
if ($currentPath -notlike "*$pathToAdd*") {
$newPath = $currentPath + ";$pathToAdd"
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
Write-Host "Added '$pathToAdd' to Path."
Write-Host "To remove path, use: " -NoNewline
Write-Host "bin/setup-runtime remove-path" -ForegroundColor Cyan
} else {
Write-Host "Path already exists."
}
}
function RemoveFromPath {
param (
[string]$pathToRemove
)
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
if ($currentPath -like "*$pathToRemove*") {
$newPath = $currentPath -replace [regex]::Escape($pathToRemove), ''
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
Write-Host "Removed Path '$pathToRemove'"
} else {
Write-Host "Path '$pathToRemove' not in Path"
}
}
# working dir
$WorkingDir = (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Definition))
if ($action -eq 'add-path') {
AddToPath ($WorkingDir + '\runtime')
exit 0
} elseif ($action -eq 'remove-path') {
RemoveFromPath ($WorkingDir + '\runtime')
exit 0
} elseif (-not($action -eq '')) {
Write-Host ("Invalid action: " + $action) -ForegroundColor Red
exit 1
}
# get php 8.1 specific version
$API = (Invoke-WebRequest -Uri "https://www.php.net/releases/index.php?json&version=8.1") | ConvertFrom-Json
# php windows download
$PHPRuntimeUrl = "https://windows.php.net/downloads/releases/php-" + $API.version + "-Win32-vs16-x64.zip"
$ComposerUrl = "https://getcomposer.org/download/latest-stable/composer.phar"
# create dir
New-Item -Path "downloads" -ItemType Directory -Force | Out-Null
# download php
if (-not(Test-Path "downloads\php.zip"))
{
Write-Host "Downloading PHP ..."
Invoke-WebRequest $PHPRuntimeUrl -OutFile "downloads\php.zip"
}
# extract php
New-Item -Path "runtime" -ItemType Directory -Force | Out-Null
Write-Host "Extracting php.zip ..."
Expand-Archive -Path "downloads/php.zip" -DestinationPath "runtime" -Force
# make php.ini
Move-Item -Path "runtime\php.ini-production" -Destination "runtime\php.ini" -Force
$OriginINI = Get-Content -Path "runtime\php.ini" -Raw
$OriginINI = $OriginINI -replace ';extension=openssl', 'extension=openssl'
$OriginINI = $OriginINI -replace ';extension=curl', 'extension=curl'
$OriginINI = $OriginINI -replace ';extension=mbstring', 'extension=mbstring'
$OriginINI = $OriginINI -replace ';extension=sodium', 'extension=sodium'
$OriginINI = $OriginINI -replace ';extension_dir = "./"', ('extension_dir = "' + (Split-Path -Parent $MyInvocation.MyCommand.Definition) + '\..\runtime\ext"')
$OriginINI | Set-Content -Path "runtime\php.ini"
# download composer
if (-not(Test-Path "runtime\composer.phar"))
{
Write-Host "Downloading composer ..."
Invoke-WebRequest $ComposerUrl -OutFile "downloads\composer.phar"
Move-Item -Path "downloads\composer.phar" -Destination "runtime\composer.phar" -Force
}
# create runtime\composer.ps1
$ComposerContent = '
$WorkingDir = (Split-Path -Parent $MyInvocation.MyCommand.Definition)
Start-Process ($WorkingDir + "\php.exe") ($WorkingDir + "\composer.phar " + $args) -NoNewWindow -Wait
'
$ComposerContent | Set-Content -Path 'runtime\composer.ps1' -Encoding UTF8
Write-Host "Successfully downloaded PHP and Composer !" -ForegroundColor Green
Write-Host "Use static-php-cli: " -NoNewline
Write-Host "bin/spc" -ForegroundColor Cyan
Write-Host "Use php: " -NoNewline
Write-Host "runtime/php" -ForegroundColor Cyan
Write-Host "Use composer: " -NoNewline
Write-Host "runtime/composer" -ForegroundColor Cyan
Write-Host ""
Write-Host "Don't forget installing composer dependencies '" -NoNewline
Write-Host "runtime/composer install" -ForegroundColor Cyan -NoNewline
Write-Host "' before using static-php-cli !"
Write-Host ""
Write-Host "If you want to use this PHP for quality tools (like phpstan, php-cs-fixer) or other project,"
Write-Host "or use PHP, Composer as system executable,"
Write-Host "use '" -NoNewline
Write-Host "bin/setup-runtime add-path" -ForegroundColor Cyan -NoNewline
Write-Host "' to add runtime dir in Path."

View File

@@ -4,7 +4,13 @@
use SPC\ConsoleApplication;
use SPC\exception\ExceptionHandler;
require_once __DIR__ . '/../vendor/autoload.php';
if (file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
// Current: ./bin (git/project mode)
require_once dirname(__DIR__) . '/vendor/autoload.php';
} else {
// Current: ./vendor/crazywhalecc/static-php-cli/bin (composer library mode)
require_once dirname(__DIR__, 3) . '/autoload.php';
}
// 防止 Micro 打包状态下不支持中文的显示(虽然这个项目目前好像没输出过中文?)
if (PHP_OS_FAMILY === 'Windows' && Phar::running()) {

View File

@@ -59,12 +59,12 @@ RUN apk update; \
apk add --no-cache \
autoconf \
automake \
gettext \
bash \
binutils \
bison \
build-base \
cmake \
composer \
curl \
file \
flex \
@@ -73,25 +73,31 @@ RUN apk update; \
git \
jq \
libgcc \
libtool \
libstdc++ \
linux-headers \
m4 \
make \
php81 \
php81-common \
php81-pcntl \
php81-phar \
php81-posix \
php81-tokenizer \
php81-xml \
php82 \
php82-common \
php82-pcntl \
php82-phar \
php82-posix \
php82-sodium \
php82-tokenizer \
php82-dom \
php82-xml \
php82-xmlwriter \
composer \
pkgconfig \
wget \
xz
WORKDIR /app
ADD ./src /app/src
ADD ./composer.json /app/composer.json
COPY ./composer.* /app/
ADD ./bin /app/bin
RUN composer update --no-dev --classmap-authoritative
RUN composer install --no-dev --classmap-authoritative
EOF
fi

12
bin/spc.ps1 Normal file
View File

@@ -0,0 +1,12 @@
$PHP_Exec = "runtime\php.exe"
if (-not(Test-Path $PHP_Exec)) {
$PHP_Exec = Get-Command php.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Definition
if (-not $PHP_Exec) {
Write-Host "Error: PHP not found, you need to install PHP on your system or use 'bin/setup-runtime'." -ForegroundColor Red
exit 1
}
}
$phpArgs = "bin\spc " + $args
Start-Process $PHP_Exec -ArgumentList $phpArgs -NoNewWindow -Wait

19
box.json Normal file
View File

@@ -0,0 +1,19 @@
{
"alias": "spc-php.phar",
"banner": false,
"blacklist": [
".github"
],
"directories": [
"config",
"src",
"vendor/psr",
"vendor/laravel/prompts",
"vendor/illuminate",
"vendor/symfony",
"vendor/zhamao"
],
"git-commit-short": "git_commit_short",
"metadata": "ConsoleApplication::VERSION",
"output": "spc.phar"
}

View File

@@ -11,8 +11,7 @@
"require": {
"php": ">= 8.1",
"ext-mbstring": "*",
"ext-pcntl": "*",
"laravel/prompts": "^0.1.3",
"laravel/prompts": "^0.1.12",
"symfony/console": "^5.4 || ^6 || ^7",
"zhamao/logger": "^1.0"
},
@@ -20,6 +19,7 @@
"captainhook/captainhook": "^5.10",
"captainhook/plugin-composer": "^5.3",
"friendsofphp/php-cs-fixer": "^3.25",
"humbug/box": "^4.3",
"nunomaduro/collision": "^7.8",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.3"
@@ -44,7 +44,8 @@
"scripts": {
"analyse": "phpstan analyse --memory-limit 300M",
"cs-fix": "php-cs-fixer fix",
"test": "vendor/bin/phpunit tests/ --no-coverage"
"test": "vendor/bin/phpunit tests/ --no-coverage",
"build:phar": "vendor/bin/box compile"
},
"config": {
"allow-plugins": {

6087
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -118,10 +118,14 @@
"iconv": {
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends-windows": [
"lib-depends": [
"libiconv"
]
},
"igbinary": {
"type": "external",
"source": "igbinary"
},
"imagick": {
"type": "external",
"source": "ext-imagick",
@@ -132,12 +136,12 @@
},
"imap": {
"type": "builtin",
"arg-type": "with",
"arg-type": "custom",
"lib-depends": [
"imap"
],
"lib-suggests": [
"kerberos"
"openssl"
]
},
"inotify": {
@@ -146,16 +150,22 @@
},
"intl": {
"type": "builtin",
"cpp-extension": true,
"lib-depends": [
"icu"
]
},
"ldap": {
"type": "builtin",
"arg-type": "with",
"arg-type": "with-prefix",
"lib-depends": [
"ldap"
],
"lib-suggests": [
"gmp",
"libsodium"
],
"ext-suggests": [
"openssl"
]
},
"mbregex": {
@@ -163,14 +173,14 @@
"arg-type": "custom",
"ext-depends": [
"mbstring"
],
"lib-depends": [
"onig"
]
},
"mbstring": {
"type": "builtin",
"arg-type": "custom",
"lib-depends": [
"onig"
]
"arg-type": "custom"
},
"memcache": {
"type": "external",
@@ -222,13 +232,25 @@
]
},
"opcache": {
"type": "builtin"
"type": "builtin",
"arg-type": "custom"
},
"openssl": {
"type": "builtin",
"arg-type": "with",
"arg-type": "custom",
"lib-depends": [
"openssl"
"openssl",
"zlib"
],
"ext-depends": [
"zlib"
]
},
"password-argon2": {
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
"libargon2"
]
},
"pcntl": {
@@ -296,6 +318,11 @@
"aspell"
]
},
"rar": {
"type": "external",
"source": "rar",
"cpp-extension": true
},
"readline": {
"type": "builtin",
"arg-type": "with-prefix",
@@ -308,7 +335,12 @@
"source": "redis",
"arg-type": "custom",
"ext-suggests": [
"session"
"session",
"igbinary"
],
"lib-suggests": [
"zstd",
"liblz4"
]
},
"session": {
@@ -368,6 +400,17 @@
"sqlite"
]
},
"sqlsrv": {
"type": "external",
"source": "sqlsrv",
"lib-depends": [
"unixodbc"
],
"ext-depends-linux": [
"pcntl"
],
"cpp-extension": true
},
"ssh2": {
"type": "external",
"source": "ext-ssh2",
@@ -381,17 +424,50 @@
"source": "swoole",
"arg-type": "custom",
"cpp-extension": true,
"unix-only": true,
"lib-depends": [
"openssl"
"libcares",
"brotli",
"nghttp2",
"zlib"
],
"ext-depends": [
"openssl"
"openssl",
"curl"
],
"ext-suggests": [
"curl",
"pgsql"
"swoole-hook-pgsql",
"swoole-hook-mysql",
"swoole-hook-sqlite"
]
},
"swoole-hook-mysql": {
"type": "addon",
"arg-type": "custom",
"ext-depends": [
"mysqlnd",
"pdo",
"pdo_mysql"
],
"unix-only": true
"ext-suggests": [
"mysqli"
]
},
"swoole-hook-pgsql": {
"type": "addon",
"arg-type": "custom",
"ext-depends": [
"pgsql",
"pdo"
]
},
"swoole-hook-sqlite": {
"type": "addon",
"arg-type": "custom",
"ext-depends": [
"sqlite3",
"pdo"
]
},
"swow": {
"type": "external",
@@ -420,7 +496,7 @@
},
"tidy": {
"type": "builtin",
"arg-type": "with",
"arg-type": "with-prefix",
"lib-depends": [
"tidy"
]
@@ -428,6 +504,24 @@
"tokenizer": {
"type": "builtin"
},
"uv": {
"type": "external",
"source": "ext-uv",
"arg-type": "with-prefix",
"lib-depends": [
"libuv"
],
"ext-depends": [
"sockets"
]
},
"xhprof": {
"type": "external",
"source": "xhprof",
"ext-depends": [
"ctype"
]
},
"xlswriter": {
"type": "external",
"source": "xlswriter",
@@ -488,7 +582,7 @@
},
"zlib": {
"type": "builtin",
"arg-type": "with",
"arg-type": "custom",
"arg-type-windows": "enable",
"lib-depends": [
"zlib"

View File

@@ -2,14 +2,14 @@
"brotli": {
"source": "brotli",
"static-libs-unix": [
"libbrotlidec-static.a",
"libbrotlienc-static.a",
"libbrotlicommon-static.a"
"libbrotlidec.a",
"libbrotlienc.a",
"libbrotlicommon.a"
],
"static-libs-windows": [
"brotlicommon-static.lib",
"brotlienc-static.lib",
"brotlidec-static.lib"
"brotlicommon.lib",
"brotlienc.lib",
"brotlidec.lib"
],
"headers": [
"brotli"
@@ -63,6 +63,7 @@
],
"frameworks": [
"CoreFoundation",
"CoreServices",
"SystemConfiguration"
]
},
@@ -110,6 +111,7 @@
},
"icu": {
"source": "icu",
"cpp-library": true,
"static-libs-unix": [
"libicui18n.a",
"libicuio.a",
@@ -121,30 +123,70 @@
"source": "imagemagick",
"static-libs-unix": [
"libMagick++-7.Q16HDRI.a",
"libMagickCore-7.Q16HDRI.a",
"libMagickWand-7.Q16HDRI.a"
"libMagickWand-7.Q16HDRI.a",
"libMagickCore-7.Q16HDRI.a"
],
"lib-depends": [
"zlib",
"libpng",
"libjpeg",
"bzip2",
"libwebp",
"freetype"
],
"lib-suggests": [
"zstd",
"xz",
"bzip2",
"libzip",
"libxml2"
]
},
"imap": {
"source": "imap",
"static-libs-unix": [
"libc-client.a"
],
"lib-suggests": [
"openssl"
]
},
"ldap": {
"source": "ldap",
"static-libs-unix": [
"liblber.a",
"libldap.a"
],
"lib-depends": [
"openssl",
"zlib",
"gmp",
"libsodium"
]
},
"libargon2": {
"source": "libargon2",
"static-libs-unix": [
"libargon2.a"
]
},
"libavif": {
"source": "libavif",
"static-libs-unix": [
"libavif.a"
]
},
"libcares": {
"source": "libcares",
"static-libs-unix": [
"libcares.a"
],
"headers-unix": [
"ares.h",
"ares_dns.h",
"ares_nameser.h",
"ares_rules.h"
]
},
"libevent": {
"source": "libevent",
"static-libs-unix": [
@@ -194,10 +236,10 @@
"libturbojpeg.a"
]
},
"libmcrypt": {
"source": "libmcrypt",
"liblz4": {
"source": "liblz4",
"static-libs-unix": [
"libmcrypt.a"
"liblz4.a"
]
},
"libmemcached": {
@@ -210,7 +252,7 @@
"libpng": {
"source": "libpng",
"static-libs-unix": [
"libpng.a"
"libpng16.a"
],
"static-libs-windows": [
"libpng16_static.lib"
@@ -254,6 +296,12 @@
"zlib"
]
},
"libuv": {
"source": "libuv",
"static-libs-unix": [
"libuv.a"
]
},
"libwebp": {
"source": "libwebp",
"static-libs-unix": [
@@ -279,17 +327,12 @@
"libxml2"
],
"lib-depends": [
"libiconv",
"zlib"
"libiconv"
],
"lib-suggests": [
"xz",
"icu"
],
"lib-suggests-windows": [
"icu",
"xz",
"pthreads4w"
"zlib"
]
},
"libxslt": {
@@ -339,12 +382,6 @@
"openssl"
]
},
"mcrypt": {
"source": "mcrypt",
"static-libs-unix": [
"libmcrypt.a"
]
},
"ncurses": {
"source": "ncurses",
"static-libs-unix": [
@@ -421,19 +458,10 @@
"readline"
],
"lib-suggests": [
"icu"
]
},
"pthreads4w": {
"source": "pthreads4w",
"static-libs-windows": [
"libpthreadVC3.lib"
],
"headers-windows": [
"_ptw32.h",
"pthread.h",
"sched.h",
"semaphore.h"
"icu",
"libxslt",
"ldap",
"zstd"
]
},
"readline": {
@@ -451,10 +479,9 @@
"libsnappy.a"
],
"headers-unix": [
"snappy.h",
"snappy-c.h",
"snappy-sinksource.h",
"snappy.h",
"snappy-stubs-internal.h",
"snappy-stubs-public.h"
],
"lib-depends": [
@@ -471,6 +498,23 @@
"sqlite3ext.h"
]
},
"tidy": {
"source": "tidy",
"static-libs-unix": [
"libtidy.a"
]
},
"unixodbc": {
"source": "unixodbc",
"static-libs-unix": [
"libodbc.a",
"libodbccr.a",
"libodbcinst.a"
],
"lib-depends": [
"libiconv"
]
},
"xz": {
"source": "xz",
"static-libs-unix": [

File diff suppressed because one or more lines are too long

View File

@@ -1,3 +1,3 @@
# Extension List
See: [Docs - Extensions](https://static-php-cli.zhamao.me/en/guide/extensions.html)
See: [Docs - Extensions](https://static-php.dev/en/guide/extensions.html)

View File

@@ -8,5 +8,10 @@ parameters:
- '#Unsafe usage of new static#'
- '#class Fiber#'
- '#Attribute class JetBrains\\PhpStorm\\ArrayShape does not exist#'
- '#Function Swoole\\Coroutine\\run not found.#'
dynamicConstantNames:
- PHP_OS_FAMILY
- PHP_OS_FAMILY
excludePaths:
analyseAndScan:
- ./src/globals/tests/swoole.php
- ./src/globals/tests/swoole.phpt

View File

@@ -4,7 +4,16 @@ declare(strict_types=1);
namespace SPC;
use SPC\store\FileSystem;
use SPC\command\BuildCliCommand;
use SPC\command\BuildLibsCommand;
use SPC\command\dev\AllExtCommand;
use SPC\command\dev\PhpVerCommand;
use SPC\command\dev\SortConfigCommand;
use SPC\command\DoctorCommand;
use SPC\command\DownloadCommand;
use SPC\command\DumpLicenseCommand;
use SPC\command\ExtractCommand;
use SPC\command\MicroCombineCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
@@ -12,38 +21,30 @@ use Symfony\Component\Console\Command\ListCommand;
/**
* static-php-cli console app entry
*/
class ConsoleApplication extends Application
final class ConsoleApplication extends Application
{
public const VERSION = '2.0-rc6';
public const VERSION = '2.0.1';
/**
* @throws \ReflectionException
* @throws exception\FileSystemException
*/
public function __construct()
{
parent::__construct('static-php-cli', self::VERSION);
global $argv;
$this->addCommands(
[
new BuildCliCommand(),
new BuildLibsCommand(),
new DoctorCommand(),
new DownloadCommand(),
new DumpLicenseCommand(),
new ExtractCommand(),
new MicroCombineCommand(),
// Detailed debugging errors are not displayed in the production environment. Only the error display provided by Symfony console is used.
$this->setCatchExceptions(file_exists(ROOT_DIR . '/.prod') || !in_array('--debug', $argv));
// Add subcommands by scanning the directory src/static-php-cli/command/
$commands = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/command', 'SPC\\command');
$phar = class_exists('\\Phar') && \Phar::running() || !class_exists('\\Phar');
$commands = array_filter($commands, function ($y) use ($phar) {
$archive_blacklist = [
'SPC\command\dev\SortConfigCommand',
'SPC\command\DeployCommand',
];
if ($phar && in_array($y, $archive_blacklist)) {
return false;
}
$reflection = new \ReflectionClass($y);
return !$reflection->isAbstract() && !$reflection->isInterface();
});
$this->addCommands(array_map(function ($x) { return new $x(); }, $commands));
// Dev commands
new AllExtCommand(),
new PhpVerCommand(),
new SortConfigCommand(),
]
);
}
protected function getDefaultCommands(): array

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace SPC\builder;
use SPC\exception\ExceptionHandler;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
@@ -30,15 +31,19 @@ abstract class BuilderBase
/** @var array<string, mixed> compile options */
protected array $options = [];
/** @var string patch point name */
protected string $patch_point = '';
/**
* Build libraries
*
* @param array<string> $libraries Libraries to build
* @param array<string> $sorted_libraries Libraries to build (if not empty, must sort first)
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
* @internal
*/
public function buildLibs(array $libraries): void
public function buildLibs(array $sorted_libraries): void
{
// search all supported libs
$support_lib_list = [];
@@ -53,23 +58,21 @@ abstract class BuilderBase
}
// if no libs specified, compile all supported libs
if ($libraries === [] && $this->isLibsOnly()) {
if ($sorted_libraries === [] && $this->isLibsOnly()) {
$libraries = array_keys($support_lib_list);
$sorted_libraries = DependencyUtil::getLibsByDeps($libraries);
}
// pkg-config must be compiled first, whether it is specified or not
if (!in_array('pkg-config', $libraries)) {
array_unshift($libraries, 'pkg-config');
if (!in_array('pkg-config', $sorted_libraries)) {
array_unshift($sorted_libraries, 'pkg-config');
}
// append dependencies
$libraries = DependencyUtil::getLibsByDeps($libraries);
// add lib object for builder
foreach ($libraries as $library) {
foreach ($sorted_libraries as $library) {
// if some libs are not supported (but in config "lib.json", throw exception)
if (!isset($support_lib_list[$library])) {
throw new RuntimeException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
throw new WrongUsageException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
}
$lib = new ($support_lib_list[$library])($this);
$this->addLib($lib);
@@ -80,12 +83,17 @@ abstract class BuilderBase
$lib->calcDependency();
}
// patch point
$this->emitPatchPoint('before-libs-extract');
// extract sources
SourceExtractor::initSource(libs: $libraries);
SourceExtractor::initSource(libs: $sorted_libraries);
$this->emitPatchPoint('after-libs-extract');
// build all libs
foreach ($this->libs as $lib) {
match ($lib->tryBuild()) {
match ($lib->tryBuild($this->getOption('rebuild', false))) {
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
BUILD_STATUS_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
@@ -112,6 +120,16 @@ abstract class BuilderBase
return $this->libs[$name] ?? null;
}
/**
* Get all library objects.
*
* @return LibraryBase[]
*/
public function getLibs(): array
{
return $this->libs;
}
/**
* Add extension to build.
*/
@@ -139,27 +157,33 @@ abstract class BuilderBase
}
/**
* Check if there is a cpp extension.
* Check if there is a cpp extensions or libraries.
*
* @throws FileSystemException
* @throws WrongUsageException
*/
public function hasCppExtension(): bool
public function hasCpp(): bool
{
// judge cpp-extension
$exts = array_keys($this->getExts());
$cpp = false;
foreach ($exts as $ext) {
if (Config::getExt($ext, 'cpp-extension', false) === true) {
$cpp = true;
break;
return true;
}
}
return $cpp;
$libs = array_keys($this->getLibs());
foreach ($libs as $lib) {
if (Config::getLib($lib, 'cpp-library', false) === true) {
return true;
}
}
return false;
}
/**
* Set libs only mode.
*
* @internal
*/
public function setLibsOnly(bool $status = true): void
{
@@ -173,15 +197,22 @@ abstract class BuilderBase
* @throws RuntimeException
* @throws \ReflectionException
* @throws WrongUsageException
* @internal
*/
public function proveExts(array $extensions): void
{
CustomExt::loadCustomExt();
$this->emitPatchPoint('before-php-extract');
SourceExtractor::initSource(sources: ['php-src']);
$this->emitPatchPoint('after-php-extract');
if ($this->getPHPVersionID() >= 80000) {
$this->emitPatchPoint('before-micro-extract');
SourceExtractor::initSource(sources: ['micro']);
$this->emitPatchPoint('after-micro-extract');
}
$this->emitPatchPoint('before-exts-extract');
SourceExtractor::initSource(exts: $extensions);
$this->emitPatchPoint('after-exts-extract');
foreach ($extensions as $extension) {
$class = CustomExt::getExtClass($extension);
$ext = new $class($extension, $this);
@@ -213,7 +244,7 @@ abstract class BuilderBase
foreach ($this->exts as $ext) {
$ret[] = trim($ext->getConfigureArg());
}
logger()->info('Using configure: ' . implode(' ', $ret));
logger()->debug('Using configure: ' . implode(' ', $ret));
return implode(' ', $ret);
}
@@ -227,12 +258,35 @@ abstract class BuilderBase
/**
* Get PHP Version ID from php-src/main/php_version.h
*
* @throws RuntimeException
* @throws WrongUsageException
*/
public function getPHPVersionID(): int
{
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
throw new WrongUsageException('PHP source files are not available, you need to download them first');
}
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
preg_match('/PHP_VERSION_ID (\d+)/', $file, $match);
return intval($match[1]);
if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0) {
return intval($match[1]);
}
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
}
public function getPHPVersion(): string
{
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
throw new WrongUsageException('PHP source files are not available, you need to download them first');
}
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
if (preg_match('/PHP_VERSION "(.*)"/', $file, $match) !== 0) {
return $match[1];
}
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
}
/**
@@ -252,6 +306,9 @@ abstract class BuilderBase
if (($type & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
$ls[] = 'fpm';
}
if (($type & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED) {
$ls[] = 'embed';
}
return implode(', ', $ls);
}
@@ -292,6 +349,51 @@ abstract class BuilderBase
$this->options[$key] = $value;
}
public function getEnvString(array $vars = ['cc', 'cxx', 'ar', 'ld']): string
{
$env = [];
foreach ($vars as $var) {
$var = strtoupper($var);
if (getenv($var) !== false) {
$env[] = "{$var}=" . getenv($var);
}
}
return implode(' ', $env);
}
/**
* Get builder patch point name.
*/
public function getPatchPoint(): string
{
return $this->patch_point;
}
public function emitPatchPoint(string $point_name): void
{
$this->patch_point = $point_name;
if (($patches = $this->getOption('with-added-patch', [])) === []) {
return;
}
foreach ($patches as $patch) {
try {
if (!file_exists($patch)) {
throw new RuntimeException("Additional patch script file {$patch} not found!");
}
logger()->debug('Running additional patch script: ' . $patch);
require $patch;
} catch (\Throwable $e) {
logger()->critical('Patch script ' . $patch . ' failed to run.');
if ($this->getOption('debug')) {
ExceptionHandler::getInstance()->handle($e);
} else {
logger()->critical('Please check with --debug option to see more details.');
}
}
}
}
/**
* Check if all libs are downloaded.
* If not, throw exception.

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace SPC\builder;
use SPC\builder\freebsd\BSDBuilder;
use SPC\builder\linux\LinuxBuilder;
use SPC\builder\macos\MacOSBuilder;
use SPC\exception\FileSystemException;
@@ -16,6 +17,8 @@ use Symfony\Component\Console\Input\InputInterface;
*/
class BuilderProvider
{
private static ?BuilderBase $builder = null;
/**
* @throws FileSystemException
* @throws RuntimeException
@@ -23,7 +26,7 @@ class BuilderProvider
*/
public static function makeBuilderByInput(InputInterface $input): BuilderBase
{
return match (PHP_OS_FAMILY) {
self::$builder = match (PHP_OS_FAMILY) {
// 'Windows' => new WindowsBuilder(
// binary_sdk_dir: $input->getOption('with-sdk-binary-dir'),
// vs_ver: $input->getOption('vs-ver'),
@@ -31,7 +34,20 @@ class BuilderProvider
// ),
'Darwin' => new MacOSBuilder($input->getOptions()),
'Linux' => new LinuxBuilder($input->getOptions()),
'BSD' => new BSDBuilder($input->getOptions()),
default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'),
};
return self::$builder;
}
/**
* @throws WrongUsageException
*/
public static function getBuilder(): BuilderBase
{
if (self::$builder === null) {
throw new WrongUsageException('Builder has not been initialized');
}
return self::$builder;
}
}

View File

@@ -46,6 +46,7 @@ class Extension
break;
case 'Darwin':
case 'Linux':
case 'BSD':
$arg .= $this->getUnixConfigureArg();
break;
}
@@ -162,6 +163,35 @@ class Extension
return false;
}
/**
* Run compile check if build target is cli
* If you need to run some check, overwrite this or add your assert in src/globals/tests/{extension_name}.php
* If check failed, throw RuntimeException
*
* @throws RuntimeException
*/
public function runCliCheck(): void
{
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (file_exists(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')) {
// Trim additional content & escape special characters to allow inline usage
$test = str_replace(
['<?php', 'declare(strict_types=1);', "\n", '"', '$'],
['', '', '', '\"', '\$'],
file_get_contents(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')
);
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
}
}
}
/**
* @throws RuntimeException
*/

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace SPC\builder;
use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
@@ -19,6 +18,8 @@ abstract class LibraryBase
protected array $dependencies = [];
protected bool $patched = false;
/**
* @throws RuntimeException
*/
@@ -130,11 +131,18 @@ abstract class LibraryBase
*/
public function tryBuild(bool $force_build = false): int
{
if (file_exists($this->source_dir . '/.spc.patched')) {
$this->patched = true;
}
// force means just build
if ($force_build) {
logger()->info('Building required library [' . static::NAME . ']');
$this->patchBeforeBuild();
if (!$this->patched && $this->patchBeforeBuild()) {
file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!');
}
$this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build');
$this->build();
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-build');
return BUILD_STATUS_OK;
}
@@ -153,7 +161,7 @@ abstract class LibraryBase
}
}
// pkg-config is treated specially. If it is pkg-config, check if the pkg-config binary exists
if ($this instanceof MacOSLibraryBase && static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
$this->tryBuild(true);
return BUILD_STATUS_OK;
}

View File

@@ -17,10 +17,19 @@ class glfw extends Extension
*/
public function patchBeforeBuildconf(): bool
{
if (file_exists(SOURCE_PATH . '/php-src/ext/glfw')) {
return false;
}
FileSystem::copyDir(SOURCE_PATH . '/ext-glfw', SOURCE_PATH . '/php-src/ext/glfw');
return true;
}
public function patchBeforeConfigure(): bool
{
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lglfw ', '-lglfw3 ');
return true;
}
public function getUnixConfigureArg(): string
{
return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH;

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\util\CustomExt;
#[CustomExt('iconv')]
@@ -13,6 +14,9 @@ class iconv extends Extension
public function patchBeforeConfigure(): bool
{
// macOS need to link iconv dynamically, we add it to extra-libs
if (!$this->builder instanceof MacOSBuilder) {
return false;
}
$extra_libs = $this->builder->getOption('extra-libs', '');
if (!str_contains($extra_libs, '-liconv')) {
$extra_libs .= ' -liconv';

View File

@@ -5,17 +5,18 @@ declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\linux\LinuxBuilder;
use SPC\util\CustomExt;
#[CustomExt('imagick')]
class imagick extends Extension
{
public function patchBeforeBuildconf(): bool
public function patchBeforeMake(): bool
{
// linux need to link library manually, we add it to extra-libs
// imagick may call omp_pause_all which requires -lgomp
$extra_libs = $this->builder->getOption('extra-libs', '');
if (!str_contains($extra_libs, 'libMagickCore')) {
$extra_libs .= ' /usr/lib/libMagick++-7.Q16HDRI.a /usr/lib/libMagickCore-7.Q16HDRI.a /usr/lib/libMagickWand-7.Q16HDRI.a';
if ($this->builder instanceof LinuxBuilder) {
$extra_libs .= ' -lgomp ';
}
$this->builder->setOption('extra-libs', $extra_libs);
return true;

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\WrongUsageException;
use SPC\util\CustomExt;
#[CustomExt('imap')]
class imap extends Extension
{
/**
* @throws WrongUsageException
*/
public function getUnixConfigureArg(): string
{
if ($this->builder->getOption('enable-zts')) {
throw new WrongUsageException('ext-imap is not thread safe, do not build it with ZTS builds');
}
$arg = '--with-imap=' . BUILD_ROOT_PATH;
if ($this->builder->getLib('openssl') !== null) {
$arg .= ' --with-imap-ssl=' . BUILD_ROOT_PATH;
}
return $arg;
}
}

View File

@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('ldap')]
class ldap extends Extension
{
public function patchBeforeConfigure(): bool
{
$output = shell()->execWithResult('$PKG_CONFIG --libs-only-l --static ldap');
if (!empty($output[1][0])) {
$libs = $output[1][0];
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lldap ', $libs . ' ');
}
return true;
}
}

View File

@@ -5,18 +5,25 @@ declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\util\CustomExt;
#[CustomExt('mbregex')]
class mbregex extends Extension
{
public function getDistName(): string
{
return 'mbstring';
}
public function getConfigureArg(): string
{
return '';
}
/**
* mbregex is not an extension, we need to overwrite the default check.
*/
public function runCliCheck(): void
{
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring" | grep regex', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !');
}
}
}

View File

@@ -5,11 +5,20 @@ declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('mongodb')]
class mongodb extends Extension
{
public function patchBeforeBuildconf(): bool
{
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/mongodb/config.m4', 'if test -z "$PHP_CONFIG"; then', 'if false; then');
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/mongodb/config.m4', 'PHP_MONGODB_PHP_VERSION=`${PHP_CONFIG} --version`', 'PHP_MONGODB_PHP_VERSION=' . $this->builder->getPHPVersion());
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/mongodb/config.m4', 'PHP_MONGODB_PHP_VERSION_ID=`${PHP_CONFIG} --vernum`', 'PHP_MONGODB_PHP_VERSION_ID=' . $this->builder->getPHPVersionID());
return true;
}
public function getUnixConfigureArg(): string
{
$arg = ' --enable-mongodb ';

View File

@@ -5,11 +5,25 @@ declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\CustomExt;
#[CustomExt('opcache')]
class opcache extends Extension
{
/**
* @throws WrongUsageException
* @throws RuntimeException
*/
public function getUnixConfigureArg(): string
{
if ($this->builder->getPHPVersionID() < 80000) {
throw new WrongUsageException('Statically compiled PHP with Zend Opcache only available for PHP >= 8.0 !');
}
return '--enable-opcache';
}
public function getDistName(): string
{
return 'Zend Opcache';

View File

@@ -6,7 +6,6 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
use SPC\util\Util;
#[CustomExt('openssl')]
class openssl extends Extension
@@ -14,12 +13,18 @@ class openssl extends Extension
public function patchBeforeMake(): bool
{
// patch openssl3 with php8.0 bug
if (file_exists(SOURCE_PATH . '/openssl/VERSION.dat') && Util::getPHPVersionID() < 80100) {
if (file_exists(SOURCE_PATH . '/openssl/VERSION.dat') && $this->builder->getPHPVersionID() < 80100) {
$openssl_c = file_get_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c');
$openssl_c = preg_replace('/REGISTER_LONG_CONSTANT\s*\(\s*"OPENSSL_SSLV23_PADDING"\s*.+;/', '', $openssl_c);
file_put_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c', $openssl_c);
return true;
}
return false;
}
public function getUnixConfigureArg(): string
{
return '--with-openssl=' . BUILD_ROOT_PATH . ' --with-openssl-dir=' . BUILD_ROOT_PATH;
}
}

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\util\CustomExt;
#[CustomExt('password-argon2')]
class password_argon2 extends Extension
{
public function runCliCheck(): void
{
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "assert(defined(\'PASSWORD_ARGON2I\'));"');
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
}
}
}

View File

@@ -13,14 +13,14 @@ class redis extends Extension
public function getUnixConfigureArg(): string
{
$arg = '--enable-redis';
if (!$this->builder->getExt('session')) {
$arg .= ' --disable-redis-session';
} else {
$arg .= ' --enable-redis-session';
}
$arg .= $this->builder->getExt('session') ? ' --enable-redis-session' : ' --disable-redis-session';
$arg .= $this->builder->getExt('igbinary') ? ' --enable-redis-igbinary' : ' --disable-redis-igbinary';
if ($this->builder->getLib('zstd')) {
$arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"';
}
if ($this->builder->getLib('liblz4')) {
$arg .= ' --enable-redis-lz4 --with-liblz4="' . BUILD_ROOT_PATH . '"';
}
return $arg;
}
}

View File

@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('sodium')]
class sodium extends Extension
{
public function patchBeforeBuildconf(): bool
{
// bypass error: unknown warning option '-Wno-logical-op' for macOS
return $this->removeLineContainingString();
}
private function removeLineContainingString(): bool
{
$path = SOURCE_PATH . '/php-src/ext/sodium/config.m4';
$search = '-Wno-logical-op';
if (!file_exists($path)) {
return false;
}
$content = file_get_contents($path);
$lines = preg_split('/\r\n|\n/', $content);
$filteredLines = array_filter($lines, function ($line) use ($search) {
return strpos($line, $search) === false;
});
$newContent = implode("\n", $filteredLines);
file_put_contents($path, $newContent);
return true;
}
}

View File

@@ -12,12 +12,31 @@ class swoole extends Extension
{
public function getUnixConfigureArg(): string
{
// enable swoole
$arg = '--enable-swoole';
$arg .= $this->builder->getExt('pgsql') ? ' --enable-swoole-pgsql' : ' --disable-swoole-pgsql';
$arg .= $this->builder->getLib('openssl') ? ' --enable-openssl' : ' --disable-openssl --without-openssl';
$arg .= $this->builder->getLib('brotli') ? (' --enable-brotli --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
// curl hook is buggy for static php
$arg .= ' --disable-swoole-curl';
// commonly-used feature: coroutine-time, thread-context
$arg .= ' --enable-swoole-coro-time --enable-thread-context';
// required feature: curl, openssl (but curl hook is buggy for php 8.0)
$arg .= $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl';
$arg .= ' --enable-openssl';
// additional feature: c-ares, brotli, nghttp2 (can be disabled, but we enable it by default in config to support full network feature)
$arg .= $this->builder->getLib('libcares') ? ' --enable-cares' : '';
$arg .= $this->builder->getLib('brotli') ? (' --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
$arg .= $this->builder->getLib('nghttp2') ? (' --with-nghttp2-dir=' . BUILD_ROOT_PATH) : '';
// additional feature: swoole-pgsql, it should depend on lib [postgresql], but it will lack of CFLAGS etc.
// so this is a tricky way (enable ext [pgsql,pdo] to add postgresql hook and pdo_pgsql support)
$arg .= $this->builder->getExt('swoole-hook-pgsql') ? '' : ' --disable-swoole-pgsql';
// enable this feature , need remove pdo_sqlite
// more info : https://wenda.swoole.com/detail/109023
$arg .= $this->builder->getExt('swoole-hook-sqlite') ? '' : ' --disable-swoole-sqlite';
// enable this feature , need stop pdo_*
// $arg .= $this->builder->getLib('unixodbc') ? ' --with-swoole-odbc=unixODBC,' : ' ';
return $arg;
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\util\CustomExt;
#[CustomExt('swoole-hook-mysql')]
class swoole_hook_mysql extends Extension
{
public function getUnixConfigureArg(): string
{
// pdo_mysql doesn't need to be disabled
// enable swoole-hook-mysql will enable mysqli, pdo, pdo_mysql, we don't need to add any additional options
return '';
}
public function runCliCheck(): void
{
// skip if not enable swoole
if ($this->builder->getExt('swoole') === null) {
return;
}
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
$out = implode('', $out);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (!str_contains($out, 'mysqlnd')) {
throw new RuntimeException('swoole mysql hook is not enabled correctly.');
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\CustomExt;
#[CustomExt('swoole-hook-pgsql')]
class swoole_hook_pgsql extends Extension
{
public function getUnixConfigureArg(): string
{
// pdo_pgsql need to be disabled
if ($this->builder->getExt('pdo_pgsql') !== null) {
throw new WrongUsageException('swoole-hook-pgsql provides pdo_pgsql, if you enable pgsql hook for swoole, you must remove pdo_pgsql extension.');
}
// enable swoole pgsql hook
return '--enable-swoole-pgsql';
}
public function runCliCheck(): void
{
// skip if not enable swoole
if ($this->builder->getExt('swoole') === null) {
return;
}
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
$out = implode('', $out);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (!str_contains($out, 'coroutine_pgsql')) {
throw new RuntimeException('swoole pgsql hook is not enabled correctly.');
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\CustomExt;
#[CustomExt('swoole-hook-sqlite')]
class swoole_hook_sqlite extends Extension
{
public function getUnixConfigureArg(): string
{
// pdo_pgsql need to be disabled
if ($this->builder->getExt('pdo_sqlite') !== null) {
throw new WrongUsageException('swoole-hook-sqlite provides pdo_sqlite, if you enable sqlite hook for swoole, you must remove pdo_sqlite extension.');
}
// enable swoole pgsql hook
return '--enable-swoole-sqlite';
}
public function runCliCheck(): void
{
// skip if not enable swoole
if ($this->builder->getExt('swoole') === null) {
return;
}
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
$out = implode('', $out);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (!str_contains($out, 'coroutine_sqlite')) {
throw new RuntimeException('swoole sqlite hook is not enabled correctly.');
}
}
}

View File

@@ -7,7 +7,6 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\util\CustomExt;
use SPC\util\Util;
#[CustomExt('swow')]
class swow extends Extension
@@ -25,7 +24,7 @@ class swow extends Extension
*/
public function patchBeforeBuildconf(): bool
{
if (Util::getPHPVersionID() >= 80000 && !is_link(SOURCE_PATH . '/php-src/ext/swow')) {
if ($this->builder->getPHPVersionID() >= 80000 && !is_link(SOURCE_PATH . '/php-src/ext/swow')) {
if (PHP_OS_FAMILY === 'Windows') {
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D swow swow-src\ext');
} else {

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('xhprof')]
class xhprof extends Extension
{
public function patchBeforeBuildconf(): bool
{
if (!is_link(SOURCE_PATH . '/php-src/ext/xhprof')) {
if (PHP_OS_FAMILY === 'Windows') {
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D xhprof xhprof-src\extension');
} else {
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && ln -s xhprof-src/extension xhprof');
}
// patch config.m4
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/xhprof/config.m4',
'if test -f $phpincludedir/ext/pcre/php_pcre.h; then',
'if test -f $abs_srcdir/ext/pcre/php_pcre.h; then'
);
return true;
}
return false;
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('zlib')]
class zlib extends Extension
{
public function getUnixConfigureArg(): string
{
return '--with-zlib --with-zlib-dir="' . BUILD_ROOT_PATH . '"';
}
}

View File

@@ -0,0 +1,257 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd;
use SPC\builder\BuilderBase;
use SPC\builder\traits\UnixBuilderTrait;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\store\SourcePatcher;
class BSDBuilder extends BuilderBase
{
/** Unix compatible builder methods */
use UnixBuilderTrait;
/** @var bool Micro patch phar flag */
private bool $phar_patched = false;
/**
* @throws RuntimeException
* @throws WrongUsageException
* @throws FileSystemException
*/
public function __construct(array $options = [])
{
$this->options = $options;
// ---------- set necessary options ----------
// set C Compiler (default: clang)
f_putenv('CC=' . $this->getOption('cc', 'clang'));
// set C++ Composer (default: clang++)
f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
// set PATH
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
// set PKG_CONFIG
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
// set PKG_CONFIG_PATH
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig/');
// set arch (default: current)
$this->setOptionIfNotExist('arch', php_uname('m'));
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
// ---------- set necessary compile environments ----------
// concurrency
$this->concurrency = SystemUtil::getCpuCount();
// cflags
$this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
// cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('BSD', $this->getOption('arch'), $this->arch_c_flags);
// create pkgconfig and include dir (some libs cannot create them automatically)
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
}
/**
* Just start to build statically linked php binary
*
* @param int $build_target build target
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{
// ---------- Update extra-libs ----------
$extra_libs = $this->getOption('extra-libs', '');
// add libc++, some extensions or libraries need it (C++ cannot be linked statically)
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : '');
if (!$this->getOption('bloat', false)) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
} else {
logger()->info('bloat linking');
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles())));
}
$this->setOption('extra-libs', $extra_libs);
$this->emitPatchPoint('before-php-buildconf');
SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this);
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
shell()->cd(SOURCE_PATH . '/php-src')
->exec(
'./configure ' .
'--prefix= ' .
'--with-valgrind=no ' . // Not detect memory leak
'--enable-shared=no ' .
'--enable-static=yes ' .
"CFLAGS='{$this->arch_c_flags} -Werror=unknown-warning-option' " .
'--disable-all ' .
'--disable-cgi ' .
'--disable-phpdbg ' .
($enableCli ? '--enable-cli ' : '--disable-cli ') .
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
($enableMicro ? '--enable-micro ' : '--disable-micro ') .
$json_74 .
$zts .
$this->makeExtensionArgs()
);
$this->emitPatchPoint('before-php-make');
SourcePatcher::patchBeforeMake($this);
$this->cleanMake();
if ($enableCli) {
logger()->info('building cli');
$this->buildCli();
}
if ($enableFpm) {
logger()->info('building fpm');
$this->buildFpm();
}
if ($enableMicro) {
logger()->info('building micro');
$this->buildMicro();
}
if ($enableEmbed) {
logger()->info('building embed');
if ($enableMicro) {
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
}
$this->buildEmbed();
}
if (php_uname('m') === $this->getOption('arch')) {
$this->emitPatchPoint('before-sanity-check');
$this->sanityCheck($build_target);
}
}
/**
* Build cli sapi
*
* @throws RuntimeException
* @throws FileSystemException
*/
protected function buildCli(): void
{
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a",
]);
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec('sed -ie "s|//lib|/lib|g" Makefile');
$shell->exec("make -j{$this->concurrency} {$vars} cli");
if (!$this->getOption('no-strip', false)) {
$shell->exec('strip sapi/cli/php');
}
$this->deployBinary(BUILD_TARGET_CLI);
}
/**
* Build phpmicro sapi
*
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
protected function buildMicro(): void
{
if ($this->getPHPVersionID() < 80000) {
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
}
if ($this->getExt('phar')) {
$this->phar_patched = true;
SourcePatcher::patchMicro(['phar']);
}
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
$vars = [
// with debug information, optimize for size, remove identifiers, patch fake cli for micro
'EXTRA_CFLAGS' => '-g -Os' . $enable_fake_cli,
// link resolv library (macOS needs it)
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a",
];
$vars = SystemUtil::makeEnvVarString($vars);
shell()->cd(SOURCE_PATH . '/php-src')
->exec("make -j{$this->concurrency} {$vars} micro");
if (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec('strip --strip-all micro.sfx');
}
$this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
}
}
/**
* Build fpm sapi
*
* @throws RuntimeException
* @throws FileSystemException
*/
protected function buildFpm(): void
{
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a", // link resolv library (macOS needs it)
]);
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} {$vars} fpm");
if (!$this->getOption('no-strip', false)) {
$shell->exec('strip sapi/fpm/php-fpm');
}
$this->deployBinary(BUILD_TARGET_FPM);
}
/**
* Build embed sapi
*
* @throws RuntimeException
*/
protected function buildEmbed(): void
{
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a", // link resolv library (macOS needs it)
]);
shell()
->cd(SOURCE_PATH . '/php-src')
->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install")
// Workaround for https://github.com/php/php-src/issues/12082
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o')
->exec('mkdir ' . BUILD_ROOT_PATH . '/lib/php-o')
->cd(BUILD_ROOT_PATH . '/lib/php-o')
->exec('ar x ' . BUILD_ROOT_PATH . '/lib/libphp.a')
->exec('rm ' . BUILD_ROOT_PATH . '/lib/libphp.a')
->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o')
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o');
}
}

View File

@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd;
use SPC\builder\traits\UnixSystemUtilTrait;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
class SystemUtil
{
/** Unix System Util Compatible */
use UnixSystemUtilTrait;
/**
* Get Logic CPU Count for macOS
*
* @throws RuntimeException
*/
public static function getCpuCount(): int
{
[$ret, $output] = shell()->execWithResult('sysctl -n hw.ncpu');
if ($ret !== 0) {
throw new RuntimeException('Failed to get cpu count');
}
return (int) $output[0];
}
/**
* Get Target Arch CFlags
*
* @param string $arch Arch Name
* @return string return Arch CFlags string
* @throws WrongUsageException
*/
public static function getArchCFlags(string $arch): string
{
return match ($arch) {
'amd64', 'x86_64' => '--target=x86_64-unknown-freebsd',
'arm64','aarch64' => '--target=aarch-unknown-freebsd',
default => throw new WrongUsageException('unsupported arch: ' . $arch),
};
}
}

View File

@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd\library;
use SPC\builder\BuilderBase;
use SPC\builder\freebsd\BSDBuilder;
use SPC\builder\LibraryBase;
use SPC\builder\traits\UnixLibraryTrait;
abstract class BSDLibraryBase extends LibraryBase
{
use UnixLibraryTrait;
protected array $headers;
public function __construct(protected BSDBuilder $builder)
{
parent::__construct();
}
public function getBuilder(): BuilderBase
{
return $this->builder;
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd\library;
class bzip2 extends BSDLibraryBase
{
use \SPC\builder\unix\library\bzip2;
public const NAME = 'bzip2';
}

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd\library;
class curl extends BSDLibraryBase
{
use \SPC\builder\unix\library\curl;
public const NAME = 'curl';
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string
{
$libs = parent::getStaticLibFiles($style, $recursive);
if ($this->builder->getLib('openssl')) {
$this->builder->setOption('extra-libs', $this->builder->getOption('extra-libs') . ' /usr/lib/libpthread.a /usr/lib/libdl.a');
}
return $libs;
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd\library;
class onig extends BSDLibraryBase
{
use \SPC\builder\unix\library\onig;
public const NAME = 'onig';
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*
* lwmbs is licensed under Mulan PSL v2. You can use this
* software according to the terms and conditions of the
* Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
*/
declare(strict_types=1);
namespace SPC\builder\freebsd\library;
use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
class openssl extends BSDLibraryBase
{
public const NAME = 'openssl';
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
protected function build(): void
{
[$lib,,$destdir] = SEPARATED_PATH;
// lib:zlib
$extra = '';
$ex_lib = '';
$zlib = $this->builder->getLib('zlib');
if ($zlib instanceof MacOSLibraryBase) {
$extra = 'zlib';
$ex_lib = trim($zlib->getStaticLibFiles() . ' ' . $ex_lib);
}
shell()->cd($this->source_dir)
->exec(
"./Configure no-shared {$extra} " .
'--prefix=/ ' . // use prefix=/
"--libdir={$lib} " .
'--openssldir=/etc/ssl ' .
'BSD-' . arch2gnu($this->builder->getOption('arch'))
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
->exec("make install_sw DESTDIR={$destdir}");
$this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']);
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd\library;
/**
* gmp is a template library class for unix
*/
class pkgconfig extends BSDLibraryBase
{
use \SPC\builder\unix\library\pkgconfig;
public const NAME = 'pkg-config';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\freebsd\library;
class zlib extends BSDLibraryBase
{
use \SPC\builder\unix\library\zlib;
public const NAME = 'zlib';
}

View File

@@ -10,6 +10,7 @@ use SPC\builder\traits\UnixBuilderTrait;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\store\SourcePatcher;
class LinuxBuilder extends BuilderBase
@@ -17,15 +18,9 @@ class LinuxBuilder extends BuilderBase
/** Unix compatible builder methods */
use UnixBuilderTrait;
/** @var string Using libc [musl,glibc] */
public string $libc;
/** @var array Tune cflags */
public array $tune_c_flags;
/** @var string pkg-config env, including PKG_CONFIG_PATH, PKG_CONFIG */
public string $pkgconf_env;
/** @var bool Micro patch phar flag */
private bool $phar_patched = false;
@@ -39,48 +34,55 @@ class LinuxBuilder extends BuilderBase
$this->options = $options;
// ---------- set necessary options ----------
// set C Compiler (default: alpine: gcc, others: musl-gcc)
$this->setOptionIfNotExist('cc', match (SystemUtil::getOSRelease()['dist']) {
'alpine' => 'gcc',
default => 'musl-gcc'
});
// set C++ Compiler (default: g++)
$this->setOptionIfNotExist('cxx', 'g++');
// set C/C++ compilers (default: alpine: gcc, others: musl-cross-make)
if (SystemUtil::isMuslDist()) {
f_putenv("CC={$this->getOption('cc', 'gcc')}");
f_putenv("CXX={$this->getOption('cxx', 'g++')}");
f_putenv("AR={$this->getOption('ar', 'ar')}");
f_putenv("LD={$this->getOption('ld', 'ld.gold')}");
} else {
$arch = arch2gnu(php_uname('m'));
f_putenv("CC={$this->getOption('cc', "{$arch}-linux-musl-gcc")}");
f_putenv("CXX={$this->getOption('cxx', "{$arch}-linux-musl-g++")}");
f_putenv("AR={$this->getOption('ar', "{$arch}-linux-musl-ar")}");
f_putenv("LD={$this->getOption('ld', 'ld.gold')}");
f_putenv("PATH=/usr/local/musl/bin:/usr/local/musl/{$arch}-linux-musl/bin:" . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
// set library path, some libraries need it. (We cannot use `putenv` here, because cmake will be confused)
$this->setOptionIfNotExist('library_path', "LIBRARY_PATH=/usr/local/musl/{$arch}-linux-musl/lib");
$this->setOptionIfNotExist('ld_library_path', "LD_LIBRARY_PATH=/usr/local/musl/{$arch}-linux-musl/lib");
// check musl-cross make installed if we use musl-cross-make
if (str_ends_with(getenv('CC'), 'linux-musl-gcc') && !file_exists("/usr/local/musl/bin/{$arch}-linux-musl-gcc")) {
throw new WrongUsageException('musl-cross-make not installed, please install it first. (You can use `doctor` command to install it)');
}
}
// set PKG_CONFIG
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
// set PKG_CONFIG_PATH
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig');
// set arch (default: current)
$this->setOptionIfNotExist('arch', php_uname('m'));
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
// ---------- set necessary compile environments ----------
// set libc
$this->libc = 'musl'; // SystemUtil::selectLibc($this->cc);
// concurrency
$this->concurrency = SystemUtil::getCpuCount();
// cflags
$this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('cc'), $this->getOption('arch'));
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('cxx'), $this->getOption('arch'));
$this->tune_c_flags = SystemUtil::checkCCFlags(SystemUtil::getTuneCFlags($this->getOption('arch')), $this->getOption('cc'));
$this->arch_c_flags = SystemUtil::getArchCFlags(getenv('CC'), $this->getOption('arch'));
$this->arch_cxx_flags = SystemUtil::getArchCFlags(getenv('CXX'), $this->getOption('arch'));
$this->tune_c_flags = SystemUtil::checkCCFlags(SystemUtil::getTuneCFlags($this->getOption('arch')), getenv('CC'));
// cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile(
'Linux',
$this->getOption('arch'),
$this->arch_c_flags,
$this->getOption('cc'),
$this->getOption('cxx'),
getenv('CC'),
getenv('CXX'),
);
// pkg-config
$vars = [
'PKG_CONFIG' => BUILD_ROOT_PATH . '/bin/pkg-config',
'PKG_CONFIG_PATH' => BUILD_LIB_PATH . '/pkgconfig',
];
$this->pkgconf_env = SystemUtil::makeEnvVarString($vars);
// configure environment
$this->configure_env = SystemUtil::makeEnvVarString([
...$vars,
'CC' => $this->getOption('cc'),
'CXX' => $this->getOption('cxx'),
'PATH' => BUILD_ROOT_PATH . '/bin:' . getenv('PATH'),
]);
// cross-compile does not support yet
// cross-compiling is not supported yet
/*if (php_uname('m') !== $this->arch) {
$this->cross_compile_prefix = SystemUtil::getCrossCompilePrefix($this->cc, $this->arch);
logger()->info('using cross compile prefix: ' . $this->cross_compile_prefix);
@@ -133,39 +135,25 @@ class LinuxBuilder extends BuilderBase
} else {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", array_filter($this->getAllStaticLibFiles())));
}
// add libstdc++, some extensions or libraries need it (C++ cannot be linked statically)
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCppExtension() ? '-lstdc++ ' : '');
// add libstdc++, some extensions or libraries need it
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : '');
$this->setOption('extra-libs', $extra_libs);
$cflags = $this->arch_c_flags;
$use_lld = '';
switch ($this->libc) {
case 'musl_wrapper':
case 'glibc':
$cflags .= ' -static-libgcc -I"' . BUILD_INCLUDE_PATH . '"';
break;
case 'musl':
if (str_ends_with($this->getOption('cc'), 'clang') && SystemUtil::findCommand('lld')) {
$use_lld = '-Xcompiler -fuse-ld=lld';
}
break;
default:
throw new WrongUsageException('libc ' . $this->libc . ' is not implemented yet');
}
$envs = $this->pkgconf_env . ' ' . SystemUtil::makeEnvVarString([
'CC' => $this->getOption('cc'),
'CXX' => $this->getOption('cxx'),
// prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => $cflags,
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
'LIBS' => '-ldl -lpthread',
'PATH' => BUILD_ROOT_PATH . '/bin:' . getenv('PATH'),
]);
$this->emitPatchPoint('before-php-buildconf');
SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this);
$phpVersionID = $this->getPHPVersionID();
@@ -178,9 +166,16 @@ class LinuxBuilder extends BuilderBase
$maxExecutionTimers = '';
$zts = '';
}
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
shell()->cd(SOURCE_PATH . '/php-src')
->exec(
"{$this->getOption('ld_library_path')} " .
'./configure ' .
'--prefix= ' .
'--with-valgrind=no ' .
@@ -189,40 +184,47 @@ class LinuxBuilder extends BuilderBase
'--disable-all ' .
'--disable-cgi ' .
'--disable-phpdbg ' .
'--enable-cli ' .
'--enable-fpm ' .
($enableCli ? '--enable-cli ' : '--disable-cli ') .
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
($enableMicro ? '--enable-micro=all-static ' : '--disable-micro ') .
$disable_jit .
$json_74 .
$zts .
$maxExecutionTimers .
'--enable-micro=all-static ' .
$this->makeExtensionArgs() . ' ' .
$envs
$this->makeExtensionArgs() .
' ' . $envs_build_php . ' '
);
$this->emitPatchPoint('before-php-make');
SourcePatcher::patchBeforeMake($this);
$this->cleanMake();
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
if ($enableCli) {
logger()->info('building cli');
$this->buildCli($extra_libs, $use_lld);
$this->buildCli();
}
if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
if ($enableFpm) {
logger()->info('building fpm');
$this->buildFpm($extra_libs, $use_lld);
$this->buildFpm();
}
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if ($enableMicro) {
logger()->info('building micro');
$this->buildMicro($extra_libs, $use_lld, $cflags);
$this->buildMicro();
}
if ($enableEmbed) {
logger()->info('building embed');
if ($enableMicro) {
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
}
$this->buildEmbed();
}
if (php_uname('m') === $this->getOption('arch')) {
$this->emitPatchPoint('before-sanity-check');
$this->sanityCheck($build_target);
}
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
}
}
/**
@@ -231,13 +233,9 @@ class LinuxBuilder extends BuilderBase
* @throws RuntimeException
* @throws FileSystemException
*/
public function buildCli(string $extra_libs, string $use_lld): void
protected function buildCli(): void
{
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)),
'EXTRA_LIBS' => $extra_libs,
'EXTRA_LDFLAGS_PROGRAM' => "{$use_lld} -all-static",
]);
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec("make -j{$this->concurrency} {$vars} cli");
@@ -252,25 +250,23 @@ class LinuxBuilder extends BuilderBase
/**
* Build phpmicro sapi
*
* @throws RuntimeException
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function buildMicro(string $extra_libs, string $use_lld, string $cflags): void
protected function buildMicro(): void
{
if ($this->getPHPVersionID() < 80000) {
throw new RuntimeException('phpmicro only support PHP >= 8.0!');
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
}
if ($this->getExt('phar')) {
$this->phar_patched = true;
SourcePatcher::patchMicro(['phar']);
}
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . $enable_fake_cli,
'EXTRA_LIBS' => $extra_libs,
'EXTRA_LDFLAGS_PROGRAM' => "{$cflags} {$use_lld} -all-static",
]);
$vars = SystemUtil::makeEnvVarString($this->getBuildVars([
'EXTRA_CFLAGS' => $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '',
]));
shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec("make -j{$this->concurrency} {$vars} micro");
@@ -280,6 +276,10 @@ class LinuxBuilder extends BuilderBase
}
$this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
}
}
/**
@@ -288,14 +288,9 @@ class LinuxBuilder extends BuilderBase
* @throws FileSystemException
* @throws RuntimeException
*/
public function buildFpm(string $extra_libs, string $use_lld): void
protected function buildFpm(): void
{
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)),
'EXTRA_LIBS' => $extra_libs,
'EXTRA_LDFLAGS_PROGRAM' => "{$use_lld} -all-static",
]);
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec("make -j{$this->concurrency} {$vars} fpm");
@@ -306,4 +301,37 @@ class LinuxBuilder extends BuilderBase
$this->deployBinary(BUILD_TARGET_FPM);
}
/**
* Build embed sapi
*
* @throws RuntimeException
*/
protected function buildEmbed(): void
{
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()
->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install");
}
private function getBuildVars($input = []): array
{
$use_lld = '';
if (str_ends_with(getenv('CC'), 'clang') && SystemUtil::findCommand('lld')) {
$use_lld = '-Xcompiler -fuse-ld=lld';
}
$optimization = $this->getOption('no-strip', false) ? '-g -O0' : '-g0 -Os';
$cflags = isset($input['EXTRA_CFLAGS']) && $input['EXTRA_CFLAGS'] ? " {$input['EXTRA_CFLAGS']}" : '';
$libs = isset($input['EXTRA_LIBS']) && $input['EXTRA_LIBS'] ? " {$input['EXTRA_LIBS']}" : '';
$ldflags = isset($input['EXTRA_LDFLAGS_PROGRAM']) && $input['EXTRA_LDFLAGS_PROGRAM'] ? " {$input['EXTRA_LDFLAGS_PROGRAM']}" : '';
$tune_c_flags = implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags));
return [
'EXTRA_CFLAGS' => "{$optimization} -fno-ident -fPIE {$tune_c_flags}{$cflags}",
'EXTRA_LIBS' => "{$this->getOption('extra-libs', '')} {$libs}",
'EXTRA_LDFLAGS_PROGRAM' => "{$use_lld} -all-static{$ldflags}",
];
}
}

View File

@@ -20,6 +20,19 @@ class SystemUtil
'ver' => 'unknown',
];
switch (true) {
case file_exists('/etc/centos-release'):
$lines = file('/etc/centos-release');
goto rh;
case file_exists('/etc/redhat-release'):
$lines = file('/etc/redhat-release');
rh:
foreach ($lines as $line) {
if (preg_match('/release\s+(\d*(\.\d+)*)/', $line, $matches)) {
$ret['dist'] = 'redhat';
$ret['ver'] = $matches[1];
}
}
break;
case file_exists('/etc/os-release'):
$lines = file('/etc/os-release');
foreach ($lines as $line) {
@@ -36,23 +49,15 @@ class SystemUtil
$ret['dist'] = 'redhat';
}
break;
case file_exists('/etc/centos-release'):
$lines = file('/etc/centos-release');
goto rh;
case file_exists('/etc/redhat-release'):
$lines = file('/etc/redhat-release');
rh:
foreach ($lines as $line) {
if (preg_match('/release\s+(\d+(\.\d+)*)/', $line, $matches)) {
$ret['dist'] = 'redhat';
$ret['ver'] = $matches[1];
}
}
break;
}
return $ret;
}
public static function isMuslDist(): bool
{
return static::getOSRelease()['dist'] === 'alpine';
}
public static function getCpuCount(): int
{
$ncpu = 1;
@@ -121,7 +126,7 @@ class SystemUtil
public static function checkCCFlag(string $flag, string $cc): string
{
[$ret] = shell()->execWithResult("echo | {$cc} -E -x c - {$flag}");
[$ret] = shell()->execWithResult("echo | {$cc} -E -x c - {$flag} 2>/dev/null");
if ($ret != 0) {
return '';
}
@@ -204,4 +209,21 @@ class SystemUtil
}
return $ret;
}
/**
* Get fully-supported linux distros.
*
* @return string[] List of supported Linux distro name for doctor
*/
public static function getSupportedDistros(): array
{
return [
// debian-like
'debian', 'ubuntu', 'Deepin',
// rhel-like
'redhat',
// alpine
'alpine',
];
}
}

View File

@@ -8,9 +8,6 @@ use SPC\builder\BuilderBase;
use SPC\builder\LibraryBase;
use SPC\builder\linux\LinuxBuilder;
use SPC\builder\traits\UnixLibraryTrait;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
abstract class LinuxLibraryBase extends LibraryBase
{
@@ -36,53 +33,4 @@ abstract class LinuxLibraryBase extends LibraryBase
{
return $this->builder;
}
/**
* @throws RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
public function tryBuild(bool $force_build = false): int
{
// 传入 true表明直接编译
if ($force_build) {
logger()->info('Building required library [' . static::NAME . ']');
$this->patchBeforeBuild();
$this->build();
return BUILD_STATUS_OK;
}
// 看看这些库是不是存在,如果不存在,则调用编译并返回结果状态
foreach ($this->getStaticLibs() as $name) {
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
$this->tryBuild(true);
return BUILD_STATUS_OK;
}
}
// 头文件同理
foreach ($this->getHeaders() as $name) {
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
$this->tryBuild(true);
return BUILD_STATUS_OK;
}
}
// pkg-config 做特殊处理,如果是 pkg-config 就检查有没有 pkg-config 二进制
if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
$this->tryBuild(true);
return BUILD_STATUS_OK;
}
// 到这里说明所有的文件都存在,就跳过编译
return BUILD_STATUS_ALREADY;
}
protected function makeFakePkgconfs(): void
{
$workspace = BUILD_ROOT_PATH;
if ($workspace === '/') {
$workspace = '';
}
foreach ($this->pkgconfs as $name => $content) {
file_put_contents(BUILD_LIB_PATH . "/pkgconfig/{$name}", "prefix={$workspace}\n" . $content);
}
}
}

View File

@@ -10,11 +10,13 @@ class icu extends LinuxLibraryBase
protected function build(): void
{
$root = BUILD_ROOT_PATH;
$cppflag = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1"';
$cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1"';
$cxxflags = 'CXXFLAGS="-std=c++11"';
$ldflags = 'LDFLAGS="-static"';
shell()->cd($this->source_dir . '/source')
->exec(
"{$this->builder->configure_env} {$cppflag} ./runConfigureICU Linux " .
"{$cppflags} {$cxxflags} {$ldflags} " .
'./runConfigureICU Linux ' .
'--enable-static ' .
'--disable-shared ' .
'--with-data-packaging=static ' .
@@ -25,7 +27,7 @@ class icu extends LinuxLibraryBase
'--enable-tools=yes ' .
'--enable-tests=no ' .
'--enable-samples=no ' .
"--prefix={$root}"
'--prefix=' . BUILD_ROOT_PATH
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")

View File

@@ -0,0 +1,67 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
class imap extends LinuxLibraryBase
{
public const NAME = 'imap';
/**
* @throws FileSystemException
*/
public function patchBeforeBuild(): bool
{
$cc = getenv('CC') ?: 'gcc';
// FileSystem::replaceFileStr($this->source_dir . '/Makefile', '-DMAC_OSX_KLUDGE=1', '');
FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', 'CC=cc', "CC={$cc}");
/* FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', '-lcrypto -lz', '-lcrypto');
FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', '-lcrypto', '-lcrypto -lz');
FileSystem::replaceFileStr(
$this->source_dir . '/src/osdep/unix/ssl_unix.c',
"#include <x509v3.h>\n#include <ssl.h>",
"#include <ssl.h>\n#include <x509v3.h>"
);
// SourcePatcher::patchFile('1006_openssl1.1_autoverify.patch', $this->source_dir);
SourcePatcher::patchFile('2014_openssl1.1.1_sni.patch', $this->source_dir); */
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'SSLINCLUDE=/usr/include/openssl', 'SSLINCLUDE=' . BUILD_INCLUDE_PATH);
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'SSLLIB=/usr/lib', 'SSLLIB=' . BUILD_LIB_PATH);
return true;
}
/**
* @throws RuntimeException
*/
protected function build(): void
{
if ($this->builder->getLib('openssl')) {
$ssl_options = 'SPECIALAUTHENTICATORS=ssl SSLTYPE=unix.nopwd SSLINCLUDE=' . BUILD_INCLUDE_PATH . ' SSLLIB=' . BUILD_LIB_PATH;
} else {
$ssl_options = 'SSLTYPE=none';
}
shell()->cd($this->source_dir)
->exec('make clean')
->exec('touch ip6')
->exec('chmod +x tools/an')
->exec('chmod +x tools/ua')
->exec('chmod +x src/osdep/unix/drivers')
->exec('chmod +x src/osdep/unix/mkauths')
->exec(
"yes | make slx {$ssl_options}"
);
try {
shell()
->exec("cp -rf {$this->source_dir}/c-client/c-client.a " . BUILD_LIB_PATH . '/libc-client.a')
->exec("cp -rf {$this->source_dir}/c-client/*.c " . BUILD_LIB_PATH . '/')
->exec("cp -rf {$this->source_dir}/c-client/*.h " . BUILD_INCLUDE_PATH . '/')
->exec("cp -rf {$this->source_dir}/src/osdep/unix/*.h " . BUILD_INCLUDE_PATH . '/');
} catch (\Throwable) {
// last command throws an exception, no idea why since it works
}
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class ldap extends LinuxLibraryBase
{
use \SPC\builder\unix\library\ldap;
public const NAME = 'ldap';
}

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
class libargon2 extends LinuxLibraryBase
{
use \SPC\builder\unix\library\libargon2;
public const NAME = 'libargon2';
public function patchBeforeBuild(): bool
{
// detect libsodium (The libargon2 conflicts with the libsodium library.)
if ($this->builder->getLib('libsodium') !== null) {
throw new WrongUsageException('libargon2 (required by password-argon2) conflicts with the libsodium library !');
}
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'LIBRARY_REL ?= lib/x86_64-linux-gnu', 'LIBRARY_REL ?= lib');
return true;
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class libcares extends LinuxLibraryBase
{
use \SPC\builder\unix\library\libcares;
public const NAME = 'libcares';
}

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
use SPC\exception\RuntimeException;
class libffi extends LinuxLibraryBase
{
public const NAME = 'libffi';
/**
* @throws RuntimeException
*/
public function build(): void
{
[$lib, , $destdir] = SEPARATED_PATH;
/*$env = $this->builder->pkgconf_env . ' CFLAGS="' . $this->builder->arch_c_flags . '"';
$env .= match ($this->builder->libc) {
'musl_wrapper' => " CC='{$this->builder->getOption('cc')} --static -idirafter " . BUILD_INCLUDE_PATH .
($this->builder->getOption('arch') === php_uname('m') ? '-idirafter /usr/include/ ' : '') .
"-idirafter /usr/include/{$this->builder->getOption('arch')}-linux-gnu/'",
'musl', 'glibc' => " CC='{$this->builder->getOption('cc')}'",
default => throw new RuntimeException('unsupported libc: ' . $this->builder->libc),
};*/
shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->getOption('arch')}-unknown-linux " .
"--target={$this->builder->getOption('arch')}-unknown-linux " .
'--prefix= ' . // use prefix=/
"--libdir={$lib}"
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
if (is_file(BUILD_ROOT_PATH . '/lib64/libffi.a')) {
copy(BUILD_ROOT_PATH . '/lib64/libffi.a', BUILD_ROOT_PATH . '/lib/libffi.a');
unlink(BUILD_ROOT_PATH . '/lib64/libffi.a');
}
$this->patchPkgconfPrefix(['libffi.pc']);
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class liblz4 extends LinuxLibraryBase
{
use \SPC\builder\unix\library\liblz4;
public const NAME = 'liblz4';
}

View File

@@ -20,36 +20,14 @@ declare(strict_types=1);
namespace SPC\builder\linux\library;
use SPC\builder\linux\SystemUtil;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
class libpng extends LinuxLibraryBase
{
public const NAME = 'libpng';
/**
* @throws FileSystemException
*/
public function patchBeforeBuild(): bool
{
FileSystem::replaceFileStr(
SOURCE_PATH . '/libpng/configure',
'-lz',
BUILD_LIB_PATH . '/libz.a'
);
if (SystemUtil::getOSRelease()['dist'] === 'alpine') {
FileSystem::replaceFileStr(
SOURCE_PATH . '/libpng/configure',
'-lm',
'/usr/lib/libm.a'
);
}
return true;
}
/**
* @throws FileSystemException
* @throws RuntimeException
@@ -66,8 +44,8 @@ class libpng extends LinuxLibraryBase
->exec('chmod +x ./configure')
->exec('chmod +x ./install-sh')
->exec(
"{$this->builder->configure_env} ./configure " .
"--host={$this->builder->getOption('gnu-arch')}-unknown-linux " .
'LDFLAGS="-L' . BUILD_LIB_PATH . '" ' .
'./configure ' .
'--disable-shared ' .
'--enable-static ' .
'--enable-hardware-optimizations ' .
@@ -76,10 +54,8 @@ class libpng extends LinuxLibraryBase
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I. -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la")
->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH)
->cd(BUILD_LIB_PATH)
->exec('ln -sf libpng16.a libpng.a');
->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I{$this->source_dir} -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la")
->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX);
$this->cleanLaFiles();
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class libuv extends LinuxLibraryBase
{
use \SPC\builder\unix\library\libuv;
public const NAME = 'libuv';
}

View File

@@ -19,22 +19,21 @@ class libxml2 extends LinuxLibraryBase
public function build(): void
{
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
// $enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
FileSystem::resetDir($this->source_dir . '/build');
shell()->cd($this->source_dir . '/build')
->exec(
"{$this->builder->configure_env} " . ' cmake ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'cmake ' .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DCMAKE_INSTALL_PREFIX=' . escapeshellarg(BUILD_ROOT_PATH) . ' ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DCMAKE_INSTALL_BINDIR=' . escapeshellarg(BUILD_ROOT_PATH . '/bin') . ' ' .
'-DLIBXML2_WITH_ICONV=ON ' .
'-DIconv_IS_BUILT_IN=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' .
"-DLIBXML2_WITH_ZLIB={$enable_zlib} " .
'-DLIBXML2_WITH_ICU=OFF ' .
"-DLIBXML2_WITH_ICU={$enable_icu} " .
"-DLIBXML2_WITH_LZMA={$enable_xz} " .
'-DLIBXML2_WITH_PYTHON=OFF ' .
'-DLIBXML2_WITH_PROGRAMS=OFF ' .
@@ -43,5 +42,11 @@ class libxml2 extends LinuxLibraryBase
)
->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install');
FileSystem::replaceFileStr(
BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc',
'-licudata -licui18n -licuuc',
'-licui18n -licuuc -licudata'
);
}
}

View File

@@ -1,72 +1,12 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*
* lwmbs is licensed under Mulan PSL v2. You can use this
* software according to the terms and conditions of the
* Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
*/
declare(strict_types=1);
namespace SPC\builder\linux\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
class nghttp2 extends LinuxLibraryBase
{
use \SPC\builder\unix\library\nghttp2;
public const NAME = 'nghttp2';
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'zlib' => null,
'openssl' => null,
'libxml2' => null,
'libev' => null,
'libcares' => null,
'libngtcp2' => null,
'libnghttp3' => null,
'libbpf' => null,
'libevent-openssl' => null,
'jansson' => null,
'jemalloc' => null,
'systemd' => null,
'cunit' => null,
]);
[,,$destdir] = SEPARATED_PATH;
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} ./configure " .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->getOption('gnu-arch')}-unknown-linux " .
'--enable-lib-only ' .
'--with-boost=no ' .
$args . ' ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
$this->patchPkgconfPrefix(['libnghttp2.pc']);
}
}

View File

@@ -41,8 +41,8 @@ class openssl extends LinuxLibraryBase
$extra = '';
$ex_lib = '-ldl -pthread';
$env = $this->builder->pkgconf_env . " CFLAGS='{$this->builder->arch_c_flags}'";
$env .= " CC='{$this->builder->getOption('cc')} -static -idirafter " . BUILD_INCLUDE_PATH .
$env = "CFLAGS='{$this->builder->arch_c_flags}'";
$env .= " CC='" . getenv('CC') . ' -static -idirafter ' . BUILD_INCLUDE_PATH .
' -idirafter /usr/include/ ' .
' -idirafter /usr/include/' . $this->builder->getOption('arch') . '-linux-gnu/ ' .
"' ";
@@ -60,11 +60,11 @@ class openssl extends LinuxLibraryBase
$ex_lib = trim($ex_lib);
$clang_postfix = SystemUtil::getCCType($this->builder->getOption('cc')) === 'clang' ? '-clang' : '';
$clang_postfix = SystemUtil::getCCType(getenv('CC')) === 'clang' ? '-clang' : '';
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} {$env} ./Configure no-shared {$extra} " .
"{$env} ./Configure no-shared {$extra} " .
'--prefix=/ ' .
'--libdir=lib ' .
'-static ' .

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class tidy extends LinuxLibraryBase
{
use \SPC\builder\unix\library\tidy;
public const NAME = 'tidy';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class unixodbc extends LinuxLibraryBase
{
use \SPC\builder\unix\library\unixodbc;
public const NAME = 'unixodbc';
}

View File

@@ -10,6 +10,7 @@ use SPC\builder\traits\UnixBuilderTrait;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\store\SourcePatcher;
class MacOSBuilder extends BuilderBase
@@ -31,9 +32,16 @@ class MacOSBuilder extends BuilderBase
// ---------- set necessary options ----------
// set C Compiler (default: clang)
$this->setOptionIfNotExist('cc', 'clang');
f_putenv('CC=' . $this->getOption('cc', 'clang'));
// set C++ Composer (default: clang++)
$this->setOptionIfNotExist('cxx', 'clang++');
f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
// set PATH
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
// set PKG_CONFIG
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
// set PKG_CONFIG_PATH
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig/');
// set arch (default: current)
$this->setOptionIfNotExist('arch', php_uname('m'));
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
@@ -46,15 +54,6 @@ class MacOSBuilder extends BuilderBase
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
// cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch'), $this->arch_c_flags);
// configure environment
$this->configure_env = SystemUtil::makeEnvVarString([
'PKG_CONFIG' => BUILD_ROOT_PATH . '/bin/pkg-config',
'PKG_CONFIG_PATH' => BUILD_LIB_PATH . '/pkgconfig/',
'CC' => $this->getOption('cc'),
'CXX' => $this->getOption('cxx'),
'CFLAGS' => "{$this->arch_c_flags} -Wimplicit-function-declaration -Os",
'PATH' => BUILD_ROOT_PATH . '/bin:' . getenv('PATH'),
]);
// create pkgconfig and include dir (some libs cannot create them automatically)
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
@@ -133,7 +132,7 @@ class MacOSBuilder extends BuilderBase
// add macOS frameworks
$extra_libs .= (empty($extra_libs) ? '' : ' ') . $this->getFrameworks(true);
// add libc++, some extensions or libraries need it (C++ cannot be linked statically)
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCppExtension() ? '-lc++ ' : '');
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : '');
if (!$this->getOption('bloat', false)) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
} else {
@@ -142,15 +141,37 @@ class MacOSBuilder extends BuilderBase
}
$this->setOption('extra-libs', $extra_libs);
$this->emitPatchPoint('before-php-buildconf');
SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this);
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
// prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => " {$this->arch_c_flags} -Werror=unknown-warning-option ",
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
]);
if ($this->getLib('postgresql')) {
shell()
->cd(SOURCE_PATH . '/php-src')
->exec(
'sed -i.backup "s/ac_cv_func_explicit_bzero\" = xyes/ac_cv_func_explicit_bzero\" = x_fake_yes/" ./configure'
);
}
shell()->cd(SOURCE_PATH . '/php-src')
->exec(
'./configure ' .
@@ -158,42 +179,47 @@ class MacOSBuilder extends BuilderBase
'--with-valgrind=no ' . // Not detect memory leak
'--enable-shared=no ' .
'--enable-static=yes ' .
"CFLAGS='{$this->arch_c_flags} -Werror=unknown-warning-option' " .
'--disable-all ' .
'--disable-cgi ' .
'--disable-phpdbg ' .
'--enable-cli ' .
'--enable-fpm ' .
'--enable-micro ' .
($enableCli ? '--enable-cli ' : '--disable-cli ') .
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
($enableMicro ? '--enable-micro ' : '--disable-micro ') .
$json_74 .
$zts .
$this->makeExtensionArgs() . ' ' .
$this->configure_env
$envs_build_php
);
$this->emitPatchPoint('before-php-make');
SourcePatcher::patchBeforeMake($this);
$this->cleanMake();
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
if ($enableCli) {
logger()->info('building cli');
$this->buildCli();
}
if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
if ($enableFpm) {
logger()->info('building fpm');
$this->buildFpm();
}
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if ($enableMicro) {
logger()->info('building micro');
$this->buildMicro();
}
if (php_uname('m') === $this->getOption('arch')) {
$this->sanityCheck($build_target);
if ($enableEmbed) {
logger()->info('building embed');
if ($enableMicro) {
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
}
$this->buildEmbed();
}
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
if (php_uname('m') === $this->getOption('arch')) {
$this->emitPatchPoint('before-sanity-check');
$this->sanityCheck($build_target);
}
}
@@ -203,12 +229,9 @@ class MacOSBuilder extends BuilderBase
* @throws RuntimeException
* @throws FileSystemException
*/
public function buildCli(): void
protected function buildCli(): void
{
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv", // link resolv library (macOS need it)
]);
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} {$vars} cli");
@@ -221,12 +244,14 @@ class MacOSBuilder extends BuilderBase
/**
* Build phpmicro sapi
*
* @throws FileSystemException|RuntimeException
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function buildMicro(): void
protected function buildMicro(): void
{
if ($this->getPHPVersionID() < 80000) {
throw new RuntimeException('phpmicro only support PHP >= 8.0!');
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
}
if ($this->getExt('phar')) {
$this->phar_patched = true;
@@ -237,9 +262,8 @@ class MacOSBuilder extends BuilderBase
$vars = [
// with debug information, optimize for size, remove identifiers, patch fake cli for micro
'EXTRA_CFLAGS' => '-g -Os -fno-ident' . $enable_fake_cli,
// link resolv library (macOS need it)
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv",
];
$vars = $this->getBuildVars($vars);
if (!$this->getOption('no-strip', false)) {
$vars['STRIP'] = 'dsymutil -f ';
}
@@ -248,6 +272,10 @@ class MacOSBuilder extends BuilderBase
shell()->cd(SOURCE_PATH . '/php-src')
->exec("make -j{$this->concurrency} {$vars} micro");
$this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
}
}
/**
@@ -256,12 +284,9 @@ class MacOSBuilder extends BuilderBase
* @throws RuntimeException
* @throws FileSystemException
*/
public function buildFpm(): void
protected function buildFpm(): void
{
$vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv", // link resolv library (macOS need it)
]);
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} {$vars} fpm");
@@ -270,4 +295,37 @@ class MacOSBuilder extends BuilderBase
}
$this->deployBinary(BUILD_TARGET_FPM);
}
/**
* Build embed sapi
*
* @throws RuntimeException
*/
protected function buildEmbed(): void
{
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()
->cd(SOURCE_PATH . '/php-src')
->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install")
// Workaround for https://github.com/php/php-src/issues/12082
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o')
->exec('mkdir ' . BUILD_ROOT_PATH . '/lib/php-o')
->cd(BUILD_ROOT_PATH . '/lib/php-o')
->exec('ar x ' . BUILD_ROOT_PATH . '/lib/libphp.a')
->exec('rm ' . BUILD_ROOT_PATH . '/lib/libphp.a')
->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o')
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o');
}
private function getBuildVars($input = []): array
{
$optimization = $this->getOption('no-strip', false) ? '-g -O0' : '-g0 -Os';
$cflags = isset($input['EXTRA_CFLAGS']) && $input['EXTRA_CFLAGS'] ? " {$input['EXTRA_CFLAGS']}" : '';
$libs = isset($input['EXTRA_LIBS']) && $input['EXTRA_LIBS'] ? " {$input['EXTRA_LIBS']}" : '';
return [
'EXTRA_CFLAGS' => "{$optimization} {$cflags} " . $this->getOption('x-extra-cflags'),
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv {$libs} " . $this->getOption('x-extra-libs'),
];
}
}

View File

@@ -44,6 +44,11 @@ class curl extends MacOSLibraryBase
'/NOT SYSTEMCONFIGURATION_FRAMEWORK/m',
'FALSE'
);
FileSystem::replaceFileRegex(
SOURCE_PATH . '/curl/CMakeLists.txt',
'/NOT CORESERVICES_FRAMEWORK/m',
'FALSE'
);
return true;
}
}

View File

@@ -19,7 +19,7 @@ class glfw extends MacOSLibraryBase
{
// compile
shell()->cd(SOURCE_PATH . '/ext-glfw/vendor/glfw')
->exec("{$this->builder->configure_env} cmake . {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF")
->exec("cmake . {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF")
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
// patch pkgconf

View File

@@ -12,7 +12,7 @@ class icu extends MacOSLibraryBase
{
$root = BUILD_ROOT_PATH;
shell()->cd($this->source_dir . '/source')
->exec("{$this->builder->configure_env} ./runConfigureICU MacOSX --enable-static --disable-shared --prefix={$root}")
->exec("./runConfigureICU MacOSX --enable-static --disable-shared --prefix={$root}")
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install');

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\store\SourcePatcher;
class imap extends MacOSLibraryBase
{
public const NAME = 'imap';
/**
* @throws FileSystemException
* @throws RuntimeException
*/
public function patchBeforeBuild(): bool
{
$cc = getenv('CC') ?: 'clang';
SourcePatcher::patchFile('0001_imap_macos.patch', $this->source_dir);
// FileSystem::replaceFileStr($this->source_dir . '/Makefile', '-DMAC_OSX_KLUDGE=1', '');
FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', 'CC=cc', "CC={$cc}");
/* FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', '-lcrypto -lz', '-lcrypto');
FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', '-lcrypto', '-lcrypto -lz');
FileSystem::replaceFileStr(
$this->source_dir . '/src/osdep/unix/ssl_unix.c',
"#include <x509v3.h>\n#include <ssl.h>",
"#include <ssl.h>\n#include <x509v3.h>"
);
// SourcePatcher::patchFile('1006_openssl1.1_autoverify.patch', $this->source_dir);
SourcePatcher::patchFile('2014_openssl1.1.1_sni.patch', $this->source_dir); */
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'SSLINCLUDE=/usr/include/openssl', 'SSLINCLUDE=' . BUILD_INCLUDE_PATH);
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'SSLLIB=/usr/lib', 'SSLLIB=' . BUILD_LIB_PATH);
return true;
}
/**
* @throws RuntimeException
*/
protected function build(): void
{
if ($this->builder->getLib('openssl')) {
$ssl_options = 'SPECIALAUTHENTICATORS=ssl SSLTYPE=unix.nopwd SSLINCLUDE=' . BUILD_INCLUDE_PATH . ' SSLLIB=' . BUILD_LIB_PATH;
} else {
$ssl_options = 'SSLTYPE=none';
}
shell()->cd($this->source_dir)
->exec('make clean')
->exec('touch ip6')
->exec('chmod +x tools/an')
->exec('chmod +x tools/ua')
->exec('chmod +x src/osdep/unix/drivers')
->exec('chmod +x src/osdep/unix/mkauths')
->exec(
"yes | EXTRACFLAGS='-Wimplicit-function-declaration -include $(xcrun --show-sdk-path)/usr/include/poll.h -include $(xcrun --show-sdk-path)/usr/include/time.h -include $(xcrun --show-sdk-path)/usr/include/utime.h' make osx {$ssl_options}"
);
try {
shell()
->exec("cp -rf {$this->source_dir}/c-client/c-client.a " . BUILD_LIB_PATH . '/libc-client.a')
->exec("cp -rf {$this->source_dir}/c-client/*.c " . BUILD_LIB_PATH . '/')
->exec("cp -rf {$this->source_dir}/c-client/*.h " . BUILD_INCLUDE_PATH . '/')
->exec("cp -rf {$this->source_dir}/src/osdep/unix/*.h " . BUILD_INCLUDE_PATH . '/');
} catch (\Throwable) {
// last command throws an exception, no idea why since it works
}
}
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class ldap extends MacOSLibraryBase
{
use \SPC\builder\unix\library\ldap;
public const NAME = 'ldap';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class libargon2 extends MacOSLibraryBase
{
use \SPC\builder\unix\library\libargon2;
public const NAME = 'libargon2';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class libcares extends MacOSLibraryBase
{
use \SPC\builder\unix\library\libcares;
public const NAME = 'libcares';
}

View File

@@ -20,7 +20,7 @@ class libffi extends MacOSLibraryBase
[, , $destdir] = SEPARATED_PATH;
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} ./configure " .
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->getOption('arch')}-apple-darwin " .

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class liblz4 extends MacOSLibraryBase
{
use \SPC\builder\unix\library\liblz4;
public const NAME = 'liblz4';
}

View File

@@ -18,7 +18,7 @@ class libmemcached extends MacOSLibraryBase
shell()->cd($this->source_dir)
->exec('chmod +x configure')
->exec(
"{$this->builder->configure_env} ./configure " .
'./configure ' .
'--enable-static --disable-shared ' .
'--disable-sasl ' .
"--prefix={$rootdir}"

View File

@@ -44,7 +44,7 @@ class libpng extends MacOSLibraryBase
->exec('chmod +x ./configure')
->exec('chmod +x ./install-sh')
->exec(
"{$this->builder->configure_env} ./configure " .
'./configure ' .
"--host={$this->builder->getOption('gnu-arch')}-apple-darwin " .
'--disable-shared ' .
'--enable-static ' .

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class libuv extends MacOSLibraryBase
{
use \SPC\builder\unix\library\libuv;
public const NAME = 'libuv';
}

View File

@@ -18,35 +18,26 @@ class libxml2 extends MacOSLibraryBase
*/
protected function build(): void
{
// macOS need to link iconv dynamically, we add it to extra-libs
$extra_libs = $this->builder->getOption('extra-libs', '');
if (!str_contains($extra_libs, '-liconv')) {
$extra_libs .= ' -liconv';
}
$this->builder->setOption('extra-libs', $extra_libs);
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
// $enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
[, , $destdir] = SEPARATED_PATH;
FileSystem::resetDir($this->source_dir . '/build');
shell()->cd($this->source_dir . '/build')
->exec(
"{$this->builder->configure_env} " . ' cmake ' .
'cmake ' .
// '--debug-find ' .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' .
"-DLIBXML2_WITH_ZLIB={$enable_zlib} " .
'-DLIBXML2_WITH_ICU=OFF ' .
"-DLIBXML2_WITH_ICU={$enable_icu} " .
"-DLIBXML2_WITH_LZMA={$enable_xz} " .
'-DLIBXML2_WITH_PYTHON=OFF ' .
'-DLIBXML2_WITH_PROGRAMS=OFF ' .
'-DLIBXML2_WITH_TESTS=OFF ' .
"-DCMAKE_INSTALL_PREFIX={$destdir} " .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'..'
)
->exec("cmake --build . -j {$this->builder->concurrency}")

View File

@@ -20,51 +20,9 @@ declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
class nghttp2 extends MacOSLibraryBase
{
use \SPC\builder\unix\library\nghttp2;
public const NAME = 'nghttp2';
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'zlib' => null,
'openssl' => null,
'libxml2' => null,
'libev' => null,
'libcares' => null,
'libngtcp2' => null,
'libnghttp3' => null,
'libbpf' => null,
'libevent-openssl' => null,
'jansson' => null,
'jemalloc' => null,
'systemd' => null,
'cunit' => null,
]);
[,,$destdir] = SEPARATED_PATH;
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} " . ' ./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->getOption('gnu-arch')}-apple-darwin " .
'--enable-lib-only ' .
'--with-boost=no ' .
$args . ' ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
$this->patchPkgconfPrefix(['libnghttp2.pc']);
}
}

View File

@@ -48,7 +48,7 @@ class openssl extends MacOSLibraryBase
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} ./Configure no-shared {$extra} " .
"./Configure no-shared {$extra} " .
'--prefix=/ ' . // use prefix=/
"--libdir={$lib} " .
'--openssldir=/System/Library/OpenSSL ' .

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class tidy extends MacOSLibraryBase
{
use \SPC\builder\unix\library\tidy;
public const NAME = 'tidy';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class unixodbc extends MacOSLibraryBase
{
use \SPC\builder\unix\library\unixodbc;
public const NAME = 'unixodbc';
}

View File

@@ -21,9 +21,6 @@ trait UnixBuilderTrait
/** @var string cmake toolchain file */
public string $cmake_toolchain_file;
/** @var string configure environments */
public string $configure_env;
/**
* @throws WrongUsageException
* @throws FileSystemException
@@ -52,12 +49,49 @@ trait UnixBuilderTrait
return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles);
}
/**
* Return generic cmake options when configuring cmake projects
*/
public function makeCmakeArgs(): string
{
$extra = $this instanceof LinuxBuilder ? '-DCMAKE_C_COMPILER=' . getenv('CC') . ' ' : '';
return $extra .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DCMAKE_INSTALL_PREFIX=/ ' .
'-DCMAKE_INSTALL_BINDIR=/bin ' .
'-DCMAKE_INSTALL_LIBDIR=/lib ' .
'-DCMAKE_INSTALL_INCLUDEDIR=/include ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->cmake_toolchain_file}";
}
/**
* Generate configure flags
*/
public function makeAutoconfFlags(int $flag = AUTOCONF_ALL): string
{
$extra = '';
// TODO: add auto pkg-config support
if (($flag & AUTOCONF_LIBS) === AUTOCONF_LIBS) {
$extra .= 'LIBS="' . BUILD_LIB_PATH . '" ';
}
if (($flag & AUTOCONF_CFLAGS) === AUTOCONF_CFLAGS) {
$extra .= 'CFLAGS="-I' . BUILD_INCLUDE_PATH . '" ';
}
if (($flag & AUTOCONF_CPPFLAGS) === AUTOCONF_CPPFLAGS) {
$extra .= 'CPPFLAGS="-I' . BUILD_INCLUDE_PATH . '" ';
}
if (($flag & AUTOCONF_LDFLAGS) === AUTOCONF_LDFLAGS) {
$extra .= 'LDFLAGS="-L' . BUILD_LIB_PATH . '" ';
}
return $extra;
}
/**
* Sanity check after build complete
*
* @throws RuntimeException
*/
public function sanityCheck(int $build_target): void
protected function sanityCheck(int $build_target): void
{
// sanity check for php-cli
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
@@ -66,18 +100,10 @@ trait UnixBuilderTrait
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
throw new RuntimeException('cli failed sanity check');
}
foreach ($this->exts as $ext) {
logger()->debug('testing ext: ' . $ext->getName());
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $ext->getDistName() . '"', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $ext->getName() . ' failed compile check');
}
if (file_exists(ROOT_DIR . '/src/globals/tests/' . $ext->getName() . '.php')) {
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php ' . ROOT_DIR . '/src/globals/tests/' . $ext->getName() . '.php');
if ($ret !== 0) {
throw new RuntimeException('extension ' . $ext->getName() . ' failed sanity check');
}
}
$ext->runCliCheck();
}
}
@@ -106,7 +132,7 @@ trait UnixBuilderTrait
* @throws RuntimeException
* @throws FileSystemException
*/
public function deployBinary(int $type): bool
protected function deployBinary(int $type): bool
{
$src = match ($type) {
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
@@ -125,23 +151,9 @@ trait UnixBuilderTrait
*
* @throws RuntimeException
*/
public function cleanMake(): void
protected function cleanMake(): void
{
logger()->info('cleaning up');
shell()->cd(SOURCE_PATH . '/php-src')->exec('make clean');
}
/**
* Return generic cmake options when configuring cmake projects
*/
public function makeCmakeArgs(): string
{
[$lib, $include] = SEPARATED_PATH;
$extra = $this instanceof LinuxBuilder ? '-DCMAKE_C_COMPILER=' . $this->getOption('cc') . ' ' : '';
return $extra . '-DCMAKE_BUILD_TYPE=Release ' .
'-DCMAKE_INSTALL_PREFIX=/ ' .
"-DCMAKE_INSTALL_LIBDIR={$lib} " .
"-DCMAKE_INSTALL_INCLUDEDIR={$include} " .
"-DCMAKE_TOOLCHAIN_FILE={$this->cmake_toolchain_file}";
}
}

View File

@@ -66,7 +66,7 @@ trait UnixLibraryTrait
* @throws FileSystemException
* @throws RuntimeException
*/
public function patchPkgconfPrefix(array $files, int $patch_option = PKGCONF_PATCH_ALL): void
public function patchPkgconfPrefix(array $files, int $patch_option = PKGCONF_PATCH_ALL, ?array $custom_replace = null): void
{
logger()->info('Patching library [' . static::NAME . '] pkgconfig');
foreach ($files as $name) {
@@ -81,6 +81,7 @@ trait UnixLibraryTrait
$file = ($patch_option & PKGCONF_PATCH_EXEC_PREFIX) === PKGCONF_PATCH_EXEC_PREFIX ? preg_replace('/^exec_prefix=.*$/m', 'exec_prefix=${prefix}', $file) : $file;
$file = ($patch_option & PKGCONF_PATCH_LIBDIR) === PKGCONF_PATCH_LIBDIR ? preg_replace('/^libdir=.*$/m', 'libdir=${prefix}/lib', $file) : $file;
$file = ($patch_option & PKGCONF_PATCH_INCLUDEDIR) === PKGCONF_PATCH_INCLUDEDIR ? preg_replace('/^includedir=.*$/m', 'includedir=${prefix}/include', $file) : $file;
$file = ($patch_option & PKGCONF_PATCH_CUSTOM) === PKGCONF_PATCH_CUSTOM && $custom_replace !== null ? preg_replace($custom_replace[0], $custom_replace[1], $file) : $file;
FileSystem::writeFile($realpath, $file);
}
}

View File

@@ -19,7 +19,7 @@ trait brotli
FileSystem::resetDir($this->source_dir . '/build-dir');
shell()->cd($this->source_dir . '/build-dir')
->exec(
$this->builder->configure_env . ' cmake ' .
'cmake ' .
"{$this->builder->makeCmakeArgs()} " .
'-DBUILD_SHARED_LIBS=OFF ' .
'..'
@@ -27,10 +27,7 @@ trait brotli
->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['libbrotlicommon.pc', 'libbrotlidec.pc', 'libbrotlienc.pc']);
shell()->cd(BUILD_ROOT_PATH . '/lib')
->exec('ln -s libbrotlicommon-static.a libbrotlicommon.a')
->exec('ln -s libbrotlidec-static.a libbrotlidec.a')
->exec('ln -s libbrotlienc-static.a libbrotlienc.a');
shell()->cd(BUILD_ROOT_PATH . '/lib')->exec('ln -sf libbrotlicommon.a libbrotli.a');
foreach (FileSystem::scanDirFiles(BUILD_ROOT_PATH . '/lib/', false, true) as $filename) {
if (str_starts_with($filename, 'libbrotli') && (str_contains($filename, '.so') || str_ends_with($filename, '.dylib'))) {
unlink(BUILD_ROOT_PATH . '/lib/' . $filename);

View File

@@ -9,8 +9,8 @@ trait bzip2
protected function build(): void
{
shell()->cd($this->source_dir)
->exec("make {$this->builder->configure_env} PREFIX='" . BUILD_ROOT_PATH . "' clean")
->exec("make -j{$this->builder->concurrency} {$this->builder->configure_env} PREFIX='" . BUILD_ROOT_PATH . "' libbz2.a")
->exec("make PREFIX='" . BUILD_ROOT_PATH . "' clean")
->exec("make -j{$this->builder->concurrency} {$this->builder->getEnvString()} PREFIX='" . BUILD_ROOT_PATH . "' libbz2.a")
->exec('cp libbz2.a ' . BUILD_LIB_PATH)
->exec('cp bzlib.h ' . BUILD_INCLUDE_PATH);
}

View File

@@ -39,8 +39,8 @@ trait curl
} else {
$extra .= '-DUSE_NGHTTP2=OFF ';
}
// TODO: ldap is not supported yet
$extra .= '-DCURL_DISABLE_LDAP=ON ';
// lib:ldap
$extra .= $this->builder->getLib('ldap') ? '-DCURL_DISABLE_LDAP=OFF ' : '-DCURL_DISABLE_LDAP=ON ';
// lib:zstd
$extra .= $this->builder->getLib('zstd') ? '-DCURL_ZSTD=ON ' : '-DCURL_ZSTD=OFF ';
// lib:idn2
@@ -52,7 +52,7 @@ trait curl
// compile
shell()->cd($this->source_dir . '/build')
->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ../CMakeLists.txt')
->exec("{$this->builder->configure_env} cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF {$extra} ..")
->exec("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF {$extra} ..")
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
// patch pkgconf

View File

@@ -26,8 +26,9 @@ trait freetype
$suggested .= ' ';
shell()->cd($this->source_dir)
->exec('sh autogen.sh')
->exec(
"{$this->builder->configure_env} ./configure " .
'./configure ' .
'--enable-static --disable-shared --without-harfbuzz --prefix= ' .
$suggested
)

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