Compare commits

...

338 Commits

Author SHA1 Message Date
crazywhalecc
ee3be6f374 add pocketmine support 2023-12-21 21:57:03 +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
Jerry Ma
be8eb90b86 cs fix (#166) 2023-09-08 22:12:59 +08:00
Jerry Ma
54e98666e7 Update ConsoleApplication.php 2023-09-08 22:03:40 +08:00
Joseph Bielawski
e8b277ad0d Prevent unknown extension call 2023-09-07 19:05:00 +08:00
Joseph Bielawski
3bd037f48f Rework style of dev command showing extensions details 2023-09-07 19:05:00 +08:00
Joseph Bielawski
4d0e825b43 Adjust dependencies in composer.json file
Removed unsupported Symfony versions
Bump minimal version of dev dependencies to the latest supported
2023-09-06 21:29:04 +08:00
Jerry Ma
b14179a8de Update README-en.md 2023-09-06 16:26:51 +08:00
Jerry Ma
01111c51ee Update README.md 2023-09-06 16:26:22 +08:00
Jerry Ma
e7230d9f50 Update README-en.md 2023-09-06 16:13:43 +08:00
Jerry Ma
c22c5617ad Update README.md 2023-09-06 16:05:38 +08:00
Joseph Bielawski
cae7bb1dda Add GH Action for tests 2023-09-06 15:47:10 +08:00
Joseph Bielawski
c0830a9e1f Allow setting suffix for licence name 2023-09-06 09:53:45 +08:00
Joseph Bielawski
33798ff108 Add simple unit test 2023-09-06 01:00:24 +08:00
Joseph Bielawski
8d348b9e14 Allow setting multiple license in extensions, libraries & sources 2023-09-06 01:00:24 +08:00
Joseph Bielawski
3d2f6e4c3a Sort lib definition 2023-09-04 23:12:13 +08:00
Joseph Bielawski
88e9639482 Fix operator precedence 2023-09-04 23:12:13 +08:00
Joseph Bielawski
0381a1c412 Adjust extension definition after review 2023-09-04 23:12:13 +08:00
Joseph Bielawski
fdc3a7a04b Add snappy extension 2023-09-04 23:12:13 +08:00
crazywhalecc
6de5c1dab0 Remove unused source libressl 2023-08-31 20:27:46 +08:00
Kévin Dunglas
dc28ce0899 fix: curl dependency on openssl 2023-08-31 20:05:37 +08:00
Kévin Dunglas
9286153742 fix: linxml build on macOS 2023-08-29 14:28:12 +08:00
crazywhalecc
f90892c92f fix curl in musl-gcc bug, fix #88 2023-08-27 03:24:32 +08:00
crazywhalecc
5359f3a79a fix webp compile to cmake, fix #95 2023-08-27 03:08:12 +08:00
crazywhalecc
42fbf18bba update license 2023-08-27 00:25:51 +08:00
crazywhalecc
ed227ce00e fix linux libxml2 #75 issue 2023-08-27 00:25:51 +08:00
crazywhalecc
6c49d35aec add libxslt compile command 2023-08-27 00:25:51 +08:00
crazywhalecc
238fd7fc74 add libxslt source 2023-08-27 00:25:51 +08:00
Kévin Dunglas
1ebc58664e ci: remove useless step and dump Compose autoloader 2023-08-26 17:58:34 +08:00
Kévin Dunglas
bcf64cbeef fix: throw if the PHP version doesn't exist 2023-08-26 13:58:09 +08:00
Kévin Dunglas
dc12d4d982 fix: ExceptionHandler:: must not be accessed before initialization 2023-08-26 13:57:43 +08:00
Kévin Dunglas
42e5877a7f fix: check of xz 2023-08-26 13:57:18 +08:00
Kévin Dunglas
a8924ac4fe fix: setup-runtime portability 2023-08-26 13:53:52 +08:00
Jerry Ma
7fb27c0c29 fix reference error 2023-08-23 10:42:53 +08:00
Kévin Dunglas
3d9a3194b2 hide warning 2023-08-22 23:37:34 +08:00
Kévin Dunglas
e7e0ac006f more optims 2023-08-22 23:37:34 +08:00
Kévin Dunglas
cf35a270bb minor: read Dockerfile from stdin 2023-08-22 23:37:34 +08:00
crazywhalecc
3e7ef49bde update README 2023-08-22 18:33:34 +08:00
crazywhalecc
100d31791a fix linux builder cpp link option 2023-08-22 18:19:04 +08:00
Kévin Dunglas
15905c063a fix: use apt-get instead of apt 2023-08-22 09:59:47 +08:00
Kévin Dunglas
4c46f6a762 fix: error when source doesn't exist 2023-08-22 09:56:47 +08:00
Kévin Dunglas
f4327c8c81 fix 2023-08-22 01:50:13 +08:00
Kévin Dunglas
4a4b0e209c detect PHP 8.1+ 2023-08-22 01:50:13 +08:00
Kévin Dunglas
60e06737d7 fix: disable Zend Signals and enable Zend Max Execution Timers for ZTS builds 2023-08-22 01:50:13 +08:00
Kévin Dunglas
d326154241 fix: musl detection on non-x86_64 2023-08-22 00:56:59 +08:00
crazywhalecc
4766ae146f change swoole-pgsql as alternative 2023-08-21 18:31:51 +08:00
kocoten1992
21a4ba7478 add swoole pgsql (--enable-swoole-pgsql) 2023-08-21 18:31:51 +08:00
crazywhalecc
dfdeab70f1 add buildroot bin PATH 2023-08-21 18:10:09 +08:00
crazywhalecc
c8fa767576 Do some code quality check and fix #126 2023-08-21 18:10:09 +08:00
Jerry Ma
9c57ed6439 Update README-en.md 2023-08-20 20:32:28 +08:00
Jerry Ma
585826b438 Update README.md 2023-08-20 20:32:07 +08:00
Kévin Dunglas
cf22949f3b minor: prevent warning when installing cmake with Homebrew 2023-08-20 20:30:07 +08:00
crazywhalecc
a00f8945ba add glfw support for macOS 2023-08-19 00:27:20 +08:00
crazywhalecc
2bc02bdaac add glfw support for macOS 2023-08-19 00:27:20 +08:00
Chuong
b97327d6d7 mongodb source.json change from tgz to zip
since ver https://github.com/mongodb/mongo-php-driver/releases/tag/1.16.2

they don't support tgz anymore.
2023-08-18 17:57:08 +08:00
crazywhalecc
61d1507a4d add redis-session support 2023-08-09 11:01:36 +08:00
crazywhalecc
a6f07051c3 update readme about version and dependencies 2023-08-08 20:35:25 +08:00
crazywhalecc
75417d15b7 change laravel/prompts version 2023-08-08 20:30:06 +08:00
crazywhalecc
4bab7ecfab add laravel/prompts support, and change deploy commands and exception handlers 2023-08-08 20:30:06 +08:00
crazywhalecc
7298e2441b remove list-ext command, use all-ext and alias to support its function 2023-08-08 19:24:11 +08:00
Jerry Ma
1ed104d2f6 Update README-en.md 2023-08-07 11:38:22 +08:00
Jerry Ma
cf6125b9cc Update README.md 2023-08-07 11:38:12 +08:00
crazywhalecc
f2cfe33cdd remove gotop (Why I needed it?) 2023-08-06 12:33:26 +08:00
crazywhalecc
a1e4125ded replace symfony console return values 2023-08-06 10:44:36 +08:00
Viktor Szépe
7a1433a994 Fix output of ExtractCommand 2023-08-06 10:32:15 +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
183 changed files with 11021 additions and 2191 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'
@@ -40,11 +41,6 @@ jobs:
steps:
- uses: actions/checkout@v3
# Install Ubuntu missing packages and mark os suffix
- run: |
sudo apt install musl-tools -y
echo "SPC_BUILD_OS=linux" >> $GITHUB_ENV
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v3
@@ -54,14 +50,14 @@ jobs:
# If there's no Composer cache, install dependencies
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev
run: composer update --no-dev --classmap-authoritative
# Cache downloaded source
- id: cache-download
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 +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'
@@ -54,14 +55,14 @@ jobs:
# If there's no Composer cache, install dependencies
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev
run: composer update --no-dev --classmap-authoritative
# Cache downloaded source
- id: cache-download
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

@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: [ "8.0", "8.1", "8.2" ]
php-version: [ "8.0", "8.1", "8.2", "8.3" ]
steps:
- uses: actions/checkout@v3

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

@@ -0,0 +1,47 @@
name: Upload SPC Binary (Release)
on:
release:
types:
- published
workflow_dispatch:
jobs:
build-release-artifacts:
name: "Upload SPC Binary (Release)"
runs-on: ubuntu-latest
strategy:
matrix:
operating-system:
- "linux-x86_64"
- "macos-x86_64"
- "linux-aarch64"
- "macos-aarch64"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
- name: Reuse static-php-cli-hosted artifacts
uses: dawidd6/action-download-artifact@v2
with:
repo: static-php/static-php-cli-hosted
branch: master
workflow: build-spc-release.yml
name: "spc-${{ matrix.operating-system }}"
- name: "Archive Executable"
run: |
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
- name: upload binaries to release
uses: softprops/action-gh-release@v1
if: ${{startsWith(github.ref, 'refs/tags/') }}
with:
files: ${{ env.filename }}
- name: "Upload Artifact"
uses: actions/upload-artifact@v3
with:
path: spc
name: spc-${{ matrix.operating-system }}

146
.github/workflows/tests.yml vendored Normal file
View File

@@ -0,0 +1,146 @@
name: Tests
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
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: 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
- 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: "Install Dependencies"
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- 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'
- php: '8.3'
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: "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: "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-
- 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)" --with-php=${{ matrix.php }} --debug
- name: "Run Build Tests (build)"
run: bin/spc build "$(php src/globals/test-extensions.php)" --build-cli --build-micro --build-fpm --debug

9
.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
@@ -17,11 +16,15 @@ composer.lock
# default source build root directory
/buildroot/
# php cs fixer cache file
# tools cache files
.php-cs-fixer.cache
.phpunit.result.cache
# exclude self-runtime
/bin/*
!/bin/spc
!/bin/setup-runtime
!/bin/spc-alpine-docker
# default test directory
/tests/var/

View File

@@ -65,5 +65,5 @@ return (new PhpCsFixer\Config())
'phpdoc_var_without_name' => false,
])
->setFinder(
PhpCsFixer\Finder::create()->in(__DIR__ . '/src')
PhpCsFixer\Finder::create()->in([__DIR__ . '/src', __DIR__ . '/tests/SPC'])
);

View File

@@ -1,256 +1,3 @@
# static-php-cli
Compile A Statically Linked PHP With Swoole and other Extensions.
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--rc3-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)]()
> The project has renamed the `refactor` branch to the `main` branch, please pay attention to changing the branch name for dependent projects.
## Compilation Requirements
Yes, this project is written in PHP, pretty funny.
But static-php-cli runtime only requires an environment above PHP 8.0 and `tokenizer`, `iconv` 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.4`, `8.0`, `8.1`, `8.2`.
## 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 7.4 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`.
## Current Status
- [X] Basic CLI framework (by `symfony/console`)
- [X] Linux support
- [X] macOS support
- [X] Exception handler
- [ ] Windows support
- [X] PHP 7.4 support
- [X] fpm support
More functions and features are coming soon, Bugs and TODOs: https://github.com/crazywhalecc/static-php-cli/issues/32
## 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 is based on the tradition of using the MIT License for old versions,
while the new version references source code from some other projects:
- [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. (TODO)
English README has been moved to [README.md](README.md).

254
README-zh.md Executable file
View File

@@ -0,0 +1,254 @@
# static-php-cli
Build single static PHP binary, with PHP project together, with popular extensions included.
🌐 **[中文](README-zh.md)** | **[English](README.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 二进制构建为一个文件分发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">
> 该 SAPI 源自 [dixyes/phpmicro](https://github.com/dixyes/phpmicro) 的 [Fork 仓库](https://github.com/static-php/phpmicro)。
[![Version](https://img.shields.io/badge/Version-2.0--rc8-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/static-php/static-php-cli-hosted/build-php-common.yml?branch=refactor&label=Build%20Common%20Extensions&style=flat-square)](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-common.yml)
[![](https://img.shields.io/badge/Extension%20Counter-65+-yellow.svg?style=flat-square)]()
[![](https://img.shields.io/github/search/crazywhalecc/static-php-cli/TODO?label=TODO%20Counter&style=flat-square)]()
> 项目名称是 static-php-cli但其实支持 cli、fpm、micro 和 embed SAPI 😎
## 文档
目前 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 编写,编译前需要一个 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: |
> macOS-arm64 因 GitHub 暂未提供 arm runner如果要构建 arm 二进制,可以使用手动构建。
目前支持编译的 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。
### 使用 Actions 构建
使用 GitHub Action 可以方便地构建一个静态编译的 PHP同时可以自行定义要编译的扩展。
1. Fork 本项目。
2. 进入项目的 Actions选择 CI。
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
### 手动构建(使用 SPC 二进制)
本项目提供了一个 static-php-cli 的二进制文件,你可以直接下载对应平台的二进制文件,然后使用它来构建静态的 PHP。目前 `spc` 二进制支持的平台有 Linux 和 macOS。
下面是从 GitHub Action 下载的方法:
1. 进入 [GitHub Action](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml)。
2. 选择一个最新的构建任务,进入后选择 `Artifacts`,下载对应平台的二进制文件。
3. 解压 `.zip` 文件。解压后,为其添加执行权限:`chmod +x ./spc`
你也可以从自托管的服务器下载二进制文件:[进入](https://dl.static-php.dev/static-php-cli/spc-bin/nightly/)。
### 手动构建(使用源码)
先克隆本项目:
```bash
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`
```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
# 初始化本项目
cd static-php-cli
composer update
chmod +x bin/spc
```
### 使用 static-php-cli 命令行程序
下面是使用 static-php-cli 编译静态 php 和 micro 的基础用法:
> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `bin/spc` 替换为 `./spc`。
```bash
# 检查环境依赖,并根据提示的命令安装缺失的编译工具
./bin/spc doctor
# 拉取所有依赖库
./bin/spc fetch --all
# 只拉取编译指定扩展需要的所有依赖
./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
# 构建包含 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
```
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.3 ~ 8.3
```bash
# 优先考虑使用 >= 8.0 的 PHP 版本,因为 phpmicro 不支持在 PHP7 中构建
./bin/spc download --with-php=8.2 --all
```
其中,目前支持构建 climicrofpm 三种静态二进制,使用以下参数的一个或多个来指定编译的 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 fetch --all --debug
```
此外,默认编译的 PHP 为 NTS 版本。如需编译线程安全版本ZTS只需添加参数 `--enable-zts` 即可。
```bash
./bin/spc build openssl,pcntl --build-all --enable-zts
```
同时,你也可以使用参数 `--no-strip` 来关闭裁剪,关闭裁剪后可以使用 gdb 等工具调试,但这样会让静态二进制体积变大。
## 不同 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) 贡献代码或文档。

295
README.md
View File

@@ -1,227 +1,290 @@
# static-php-cli
Compile A Statically Linked PHP With Swoole and other Extensions.
Build single static PHP binary, with PHP project together, with popular extensions included.
**If you are using English, see [English README](README-en.md).**
🌐 **[中文](README-zh.md)** | **[English](README.md)**
编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携cli SAPI
The project name is static-php-cli, but it actually supports cli, fpm, micro and embed 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">
Compile a purely static php-cli binary file with various extensions to make PHP applications more portable! (cli SAPI)
同时可以使用 micro 二进制文件,将 PHP 源码和 PHP 二进制构建为一个文件分发!(由 [dixyes/phpmicro](https://github.com/dixyes/phpmicro) 提供支持micro 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">
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
You can also use the micro binary file to combine php binary and php source code into one for distribution! (micro SAPI)
[![Version](https://img.shields.io/badge/Version-2.0--rc3-pink.svg?style=flat-square)]()
<img width="600" alt="2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
> This SAPI feature is from the [Fork](https://github.com/static-php/phpmicro) of [dixyes/phpmicro](https://github.com/dixyes/phpmicro).
[![Version](https://img.shields.io/badge/Version-2.0--rc8-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/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)
[![](https://img.shields.io/badge/Extension%20Counter-65+-yellow.svg?style=flat-square)]([https://static-php.dev/](https://static-php.dev/en/guide/extensions.html))
[![](https://img.shields.io/github/search/crazywhalecc/static-php-cli/TODO?label=TODO%20Counter&style=flat-square)]()
> 项目已重命名 `refactor` 分支为 `main` 分支,请依赖的项目注意更改分支名称。
## Documentation
## 编译环境需求
The current README contains basic usage. For all the features of static-php-cli,
see <https://static-php.dev> .
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 tokenizer 扩展和 PHP 版本大于等于 8.0 即可。
## Direct Download
下面是架构支持情况,`CI` 代表支持 GitHub Action 构建,`Local` 代表支持本地构建,空 代表暂不支持。
If you don't want to compile yourself, you can download example pre-compiled artifact from [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-common.yml), or from self-hosted server.
| | x86_64 | aarch64 |
|---------|-----------|-----------|
| macOS | CI, Local | Local |
| Linux | CI, Local | CI, Local |
| Windows | | |
Below are several precompiled static-php binaries with different extension combinations,
which can be downloaded directly according to your needs.
> macOS-arm64 因 GitHub 暂未提供 arm runner如果要构建 arm 二进制,可以使用手动构建。
- [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.
目前支持编译的 PHP 版本为:`7.4``8.0``8.1``8.2`
## Use static-php-cli to build PHP
## 文档
### Compilation Requirements
点击这里查看文档:<https://static-php-cli.zhamao.me>。
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 :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: |
### 自托管直接下载
> 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.
如果你不想自行编译,可以从本项目现有的 Action 下载 Artifact也可以从自托管的服务器下载[进入](https://dl.zhamao.xin/static-php-cli/)
Currently supported PHP versions for compilation are: `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`.
> 自托管的服务器默认包含的扩展有:`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
### 支持的扩展情况
Please first select the extension you want to compile based on the extension list below.
[扩展支持列表](https://static-php-cli.zhamao.me/zh/guide/extensions.html)
- [Supported Extension List](https://static-php.dev/en/guide/extensions.html)
- [Command Generator](https://static-php.dev/en/guide/cli-generator.html)
> 如果这里没有你需要的扩展,可以提交 Issue
> If an extension you need is missing, you can submit an issue.
### 使用 Actions 构建
Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
使用 GitHub Action 可以方便地构建一个静态编译的 PHP 和 phpmicro同时可以自行定义要编译的扩展。
### GitHub Actions Build
1. Fork 本项目。
2. 进入项目的 Actions选择 CI。
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`
Use GitHub Action to easily build a statically compiled PHP,
and at the same time define the extensions to be compiled by yourself.
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
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 (using SPC binary)
This project provides a binary file of static-php-cli.
You can directly download the binary file of the corresponding platform and then use it to build static PHP.
Currently, the platforms supported by `spc` binary are Linux and macOS.
Here's how to download from GitHub Actions:
1. Enter [GitHub Actions](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml) or [self-hosted nightly builds](https://dl.static-php.dev/static-php-cli/spc-bin/nightly/).
2. If you download from GHA, select the latest build task, select `Artifacts`, and download the binary file of the corresponding platform.
3. If you download from GHA, unzip the `.zip` file. After decompressing, add execution permissions to it: `chmod +x ./spc`.
4. If you download from self-hosted server, download `spc-$os-$arch` file and just use it (don't forget `chmod +x`).
> SPC single-file binary is built by phpmicro and box, and it doesn't need to install PHP. Just treat `spc` as a standalone executable.
### Manual build (using source code)
Clone repo first:
```bash
git clone https://github.com/crazywhalecc/static-php-cli.git
```
如果你本机没有安装 PHP你需要先使用包管理例如 brewaptyumapk 等)安装 php。
If you have not installed php on your system, you can use package management to install PHP (such as brew, apt, yum, apk etc.).
你也可以通过 `bin/setup-runtime` 命令下载静态编译好的 php-cli 和 Composer。下载的 php 和 Composer 将保存为 `bin/php``bin/composer`
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
# 使用独立的 php 运行 static-php-cli
# Use this php runtime to run static-php-cli compiler
./bin/php bin/spc
# 使用 composer
# Use composer
./bin/php bin/composer
```
下面是使用 static-php-cli 编译静态 php 和 micro 的基础用法:
```bash
# 克隆本项目
# Initialize this project
cd static-php-cli
composer update
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
```
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.4 ~ 8.2
### Use static-php-cli
Basic usage for building php and micro 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 版本
# Check system tool dependencies, fix them if possible
./bin/spc doctor
# fetch all libraries
./bin/spc download --all
# only fetch necessary sources by needed extensions
./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
# 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.3:
```bash
# Using PHP >= 8.0 is recommended, because PHP7 cannot use phpmicro
./bin/spc fetch --with-php=8.2 --all
```
其中,目前支持构建 climicrofpm 三种静态二进制,使用以下参数的一个或多个来指定编译的 SAPI
Now we support `cli`, `micro`, `fpm`, 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
```
此外,默认编译的 PHP 为 NTS 版本。如需编译线程安全版本ZTS只需添加参数 `--enable-zts` 即可。
In addition, we build NTS (non-thread-safe) 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
```
同时,你也可以使用参数 `--no-strip` 来关闭裁剪,关闭裁剪后可以使用 gdb 等工具调试,但这样会让静态二进制体积变大。
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
## Different SAPI Usage
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
### Use cli
采用参数 `--build-cli``--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
> 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 # 检查版本
./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.
- [X] 基础结构编写(采用 `symfony/console`
- [X] 错误处理
- [X] macOS 支持
- [ ] Windows 支持
- [X] Linux 支持
- [X] PHP 7.4 支持
- [X] fpm 支持
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.
更多功能和特性正在陆续支持中详见https://github.com/crazywhalecc/static-php-cli/issues/32
Specifying `php-fpm.conf` can use the command parameter `-y`, for example: `./php-fpm -y php-fpm.conf`.
## 贡献
### Use embed
目前支持的扩展较少,如果缺少你需要的扩展,可发起 Issue。如果你对本项目较熟悉也欢迎为本项目发起 Pull Request。
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.
贡献基本原则如下:
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.
- 项目采用了 php-cs-fixer、phpstan 作为代码规范工具,贡献前请对更新的代码执行 `composer analyze``composer cs-fix`
- 涉及到其他开源库的部分应提供对应库的协议,同时对配置文件在修改后采用命令 `sort-config` 排序。有关排序的命令,见文档。
- 应遵循命名规范,例如扩展名称应采取 PHP 内注册的扩展名本身,外部库名应遵循项目本身的名称,内部逻辑的函数、类名、变量等应遵循驼峰、下划线等格式,禁止同一模块混用。
- 涉及编译外部库的命令和 Patch 时应注意兼容不同操作系统。
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).
另外,添加新扩展的贡献方式,可以参考下方 `进阶`
## Contribution
如果你想贡献文档内容,请到项目仓库 [crazywhalecc/static-php-cli-docs](https://github.com/crazywhalecc/static-php-cli-docs) 贡献。
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.
## 赞助本项目
If you want to contribute documentation, please go to [static-php/static-php-cli-docs](https://github.com/static-php/static-php-cli-docs).
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。
Now there is a [static-php](https://github.com/static-php) organization, which is used to store the repo related to the project.
## 开源协议
## Sponsor this project
本项目依据旧版本惯例采用 MIT License 开源,自身的部分代码引用或修改自以下项目:
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)(木兰宽松许可证)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)Apache 2.0 LICENSE、SWOOLE-CLI LICENSE
## Open-Source License
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 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.
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php-cli.zhamao.me) 贡献代码或文档。TODO

View File

@@ -1,4 +1,4 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
# set error-quit, verbose, non-variable-quit
set -eu
@@ -22,10 +22,10 @@ esac
# set project dir
__DIR__=$(cd "$(dirname "$0")" && pwd)
__PROJECT__=$(cd ${__DIR__}/../ && 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
@@ -46,23 +46,27 @@ 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"
__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.aliyun.com/composer/composer.phar"
;;
esac
test -d ${__PROJECT__}/downloads || mkdir ${__PROJECT__}/downloads
if ! command -v curl > /dev/null && command -v apk > /dev/null; then
apk add --no-cache curl
fi
test -d "${__PROJECT__}"/downloads || mkdir "${__PROJECT__}"/downloads
# download static php binary
test -f ${__PROJECT__}/downloads/runtime.tar.gz || { echo "Downloading $__PHP_RUNTIME_URL__ ..." && curl -#fSL -o ${__PROJECT__}/downloads/runtime.tar.gz "$__PHP_RUNTIME_URL__" ; }
test -f ${__DIR__}/php || { tar -xf ${__PROJECT__}/downloads/runtime.tar.gz -C ${__DIR__}/ ; }
chmod +x ${__DIR__}/php
test -f "${__PROJECT__}"/downloads/runtime.tar.gz || { echo "Downloading $__PHP_RUNTIME_URL__ ..." && curl -#fSL -o "${__PROJECT__}"/downloads/runtime.tar.gz "$__PHP_RUNTIME_URL__" ; }
test -f "${__DIR__}"/php || { tar -xf "${__PROJECT__}"/downloads/runtime.tar.gz -C "${__DIR__}"/ ; }
chmod +x "${__DIR__}"/php
# download composer
test -f ${__DIR__}/composer || curl -#fSL -o ${__DIR__}/composer "$__COMPOSER_URL__"
chmod +x ${__DIR__}/composer
test -f "${__DIR__}"/composer || curl -#fSL -o "${__DIR__}"/composer "$__COMPOSER_URL__"
chmod +x "${__DIR__}"/composer
# sanity check for php and composer
${__DIR__}/php -v >/dev/null || { echo "Failed to run php" && exit 1; }
${__DIR__}/php ${__DIR__}/composer --version >/dev/null || { echo "Failed to run composer" && exit 1; }
"${__DIR__}"/php -v >/dev/null || { echo "Failed to run php" && exit 1; }
"${__DIR__}"/php "${__DIR__}"/composer --version >/dev/null || { echo "Failed to run composer" && exit 1; }
echo "Setup runtime OK!"
echo "runtime bin path needs to add manually by command below:"

View File

@@ -1,6 +1,9 @@
#!/usr/bin/env php
<?php
use SPC\ConsoleApplication;
use SPC\exception\ExceptionHandler;
require_once __DIR__ . '/../vendor/autoload.php';
// 防止 Micro 打包状态下不支持中文的显示(虽然这个项目目前好像没输出过中文?)
@@ -8,9 +11,8 @@ if (PHP_OS_FAMILY === 'Windows' && Phar::running()) {
exec('CHCP 65001');
}
// 跑,反正一条命令跑就对了
try {
(new \SPC\ConsoleApplication())->run();
(new ConsoleApplication())->run();
} catch (Exception $e) {
\SPC\exception\ExceptionHandler::getInstance()->handle($e);
ExceptionHandler::getInstance()->handle($e);
}

View File

@@ -2,18 +2,18 @@
# This file is using docker to run commands
self_dir=$(cd "$(dirname "$0")";pwd)
# Detect docker can run
if ! which docker >/dev/null; then
echo "Docker is not installed, please install docker first !"
exit 1
fi
DOCKER_EXECUTABLE="docker"
# shellcheck disable=SC2046
if [ $(id -u) -ne 0 ]; then
if ! docker info > /dev/null 2>&1; then
if [ "$SPC_USE_SUDO" != "yes" ]; then
echo "Docker command requires sudo"
# shellcheck disable=SC2039
echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
exit 1
fi
@@ -33,6 +33,7 @@ x86_64)
;;
aarch64)
ALPINE_FROM=multiarch/alpine:aarch64-edge
# shellcheck disable=SC2039
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
;;
@@ -51,24 +52,53 @@ fi
# Detect docker env is setup
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-$SPC_USE_ARCH; then
echo "Docker container does not exist. Building docker image ..."
ALPINE_DOCKERFILE=$(cat << EOF
$DOCKER_EXECUTABLE build -t cwcc-spc-$SPC_USE_ARCH -f- . <<EOF
FROM $ALPINE_FROM
$SPC_USE_MIRROR
RUN apk update
RUN apk add bash file wget cmake gcc g++ jq autoconf git libstdc++ linux-headers make m4 libgcc binutils bison flex pkgconfig automake curl
RUN apk add build-base xz php81 php81-common php81-pcntl php81-tokenizer php81-phar php81-posix php81-xml composer
RUN mkdir /app
RUN apk update; \
apk add --no-cache \
autoconf \
automake \
gettext \
bash \
binutils \
bison \
build-base \
cmake \
curl \
file \
flex \
g++ \
gcc \
git \
jq \
libgcc \
libtool \
libstdc++ \
linux-headers \
m4 \
make \
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
RUN composer install --no-dev --classmap-authoritative
EOF
)
echo "$ALPINE_DOCKERFILE" > $(pwd)/Dockerfile
$DOCKER_EXECUTABLE build -t cwcc-spc-$SPC_USE_ARCH .
rm $(pwd)/Dockerfile
fi
# Check if in ci (local terminal can execute with -it)
@@ -79,4 +109,5 @@ else
fi
# Run docker
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT=$(pwd) -v $(pwd)/config:/app/config -v $(pwd)/src:/app/src -v $(pwd)/buildroot:/app/buildroot -v $(pwd)/source:/app/source -v $(pwd)/downloads:/app/downloads cwcc-spc-$SPC_USE_ARCH bin/spc $@
# shellcheck disable=SC2068
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" -v "$(pwd)"/config:/app/config -v "$(pwd)"/src:/app/src -v "$(pwd)"/buildroot:/app/buildroot -v "$(pwd)"/source:/app/source -v "$(pwd)"/downloads:/app/downloads cwcc-spc-$SPC_USE_ARCH bin/spc $@

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

@@ -9,20 +9,21 @@
}
],
"require": {
"php": ">= 8.0",
"ext-tokenizer": "*",
"ext-iconv": "*",
"symfony/console": "^6 || ^5 || ^4",
"zhamao/logger": "^1.0",
"crazywhalecc/cli-helper": "^0.1.0",
"nunomaduro/collision": "*",
"ext-pcntl": "*"
"php": ">= 8.1",
"ext-mbstring": "*",
"ext-pcntl": "*",
"laravel/prompts": "^0.1.12",
"symfony/console": "^5.4 || ^6 || ^7",
"zhamao/logger": "^1.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.2 != 3.7.0",
"phpstan/phpstan": "^1.1",
"captainhook/captainhook": "^5.10",
"captainhook/plugin-composer": "^5.3"
"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"
},
"autoload": {
"psr-4": {
@@ -33,13 +34,19 @@
"src/globals/functions.php"
]
},
"autoload-dev": {
"psr-4": {
"SPC\\Tests\\": "tests/SPC"
}
},
"bin": [
"bin/spc"
],
"scripts": {
"analyse": "phpstan analyse --memory-limit 300M",
"cs-fix": "php-cs-fixer fix",
"test": "bin/phpunit --no-coverage"
"test": "vendor/bin/phpunit tests/ --no-coverage",
"build:phar": "vendor/bin/box compile"
},
"config": {
"allow-plugins": {

6030
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,14 @@
"calendar": {
"type": "builtin"
},
"crypto": {
"type": "external",
"arg-type": "with",
"source": "ext-crypto",
"lib-depends": [
"openssl"
]
},
"ctype": {
"type": "builtin"
},
@@ -53,19 +61,6 @@
"sockets"
]
},
"memcached": {
"type": "external",
"source": "memcached",
"arg-type": "custom",
"cpp-extension": true,
"lib-depends": [
"libmemcached"
],
"ext-depends": [
"session",
"zlib"
]
},
"exif": {
"type": "builtin"
},
@@ -113,6 +108,14 @@
"gettext"
]
},
"glfw": {
"type": "external",
"arg-type": "custom",
"source": "ext-glfw",
"lib-depends": [
"glfw"
]
},
"gmp": {
"type": "builtin",
"arg-type": "with-prefix",
@@ -123,10 +126,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",
@@ -137,12 +144,12 @@
},
"imap": {
"type": "builtin",
"arg-type": "with",
"arg-type": "custom",
"lib-depends": [
"imap"
],
"lib-suggests": [
"kerberos"
"openssl"
]
},
"inotify": {
@@ -151,16 +158,30 @@
},
"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"
]
},
"leveldb": {
"type": "external",
"arg-type": "with-prefix",
"source": "pmmp-leveldb",
"lib-depends": [
"leveldb"
]
},
"mbregex": {
@@ -168,14 +189,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",
@@ -188,6 +209,19 @@
"session"
]
},
"memcached": {
"type": "external",
"source": "memcached",
"arg-type": "custom",
"cpp-extension": true,
"lib-depends": [
"libmemcached"
],
"ext-depends": [
"session",
"zlib"
]
},
"mongodb": {
"type": "external",
"source": "mongodb",
@@ -199,6 +233,10 @@
"zlib"
]
},
"morton": {
"type": "external",
"source": "ext-morton"
},
"mysqli": {
"type": "builtin",
"arg-type": "with",
@@ -214,13 +252,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": {
@@ -273,6 +323,16 @@
"zlib"
]
},
"pmmp-chunkutils2": {
"type": "external",
"source": "pmmp-chunkutils2",
"arg-type": "custom",
"cpp-extension": true
},
"pmmpthread": {
"type": "external",
"source": "pmmpthread"
},
"posix": {
"type": "builtin",
"unix-only": true
@@ -288,6 +348,11 @@
"aspell"
]
},
"rar": {
"type": "external",
"source": "rar",
"cpp-extension": true
},
"readline": {
"type": "builtin",
"arg-type": "with-prefix",
@@ -298,7 +363,10 @@
"redis": {
"type": "external",
"source": "redis",
"arg-type": "custom"
"arg-type": "custom",
"ext-suggests": [
"session"
]
},
"session": {
"type": "builtin"
@@ -314,6 +382,18 @@
"libxml2"
]
},
"snappy": {
"type": "external",
"source": "ext-snappy",
"cpp-extension": true,
"arg-type": "custom",
"lib-depends": [
"snappy"
],
"ext-suggest": [
"apcu"
]
},
"snmp": {
"type": "builtin",
"arg-type": "with",
@@ -365,7 +445,8 @@
"openssl"
],
"ext-suggests": [
"curl"
"curl",
"pgsql"
],
"unix-only": true
},
@@ -396,7 +477,7 @@
},
"tidy": {
"type": "builtin",
"arg-type": "with",
"arg-type": "with-prefix",
"lib-depends": [
"tidy"
]
@@ -437,9 +518,13 @@
},
"xsl": {
"type": "builtin",
"arg-type": "with",
"arg-type": "with-prefix",
"lib-depends": [
"libxslt"
],
"ext-depends": [
"xml",
"dom"
]
},
"yaml": {
@@ -460,7 +545,7 @@
},
"zlib": {
"type": "builtin",
"arg-type": "with",
"arg-type": "custom",
"arg-type-windows": "enable",
"lib-depends": [
"zlib"

View File

@@ -42,14 +42,14 @@
"curl"
],
"lib-depends-unix": [
"openssl",
"zlib"
],
"lib-suggests": [
"libssh2",
"brotli",
"nghttp2",
"zstd",
"openssl"
"zstd"
],
"lib-suggests-windows": [
"zlib",
@@ -63,6 +63,7 @@
],
"frameworks": [
"CoreFoundation",
"CoreServices",
"SystemConfiguration"
]
},
@@ -84,6 +85,18 @@
"brotli"
]
},
"glfw": {
"source": "ext-glfw",
"static-libs-unix": [
"libglfw3.a"
],
"frameworks": [
"CoreVideo",
"OpenGL",
"Cocoa",
"IOKit"
]
},
"gmp": {
"source": "gmp",
"static-libs-unix": [
@@ -98,6 +111,7 @@
},
"icu": {
"source": "icu",
"cpp-library": true,
"static-libs-unix": [
"libicui18n.a",
"libicuio.a",
@@ -109,24 +123,59 @@
"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"
]
},
"leveldb": {
"source": "leveldb",
"static-libs-unix": [
"libleveldb.a"
],
"cpp-library": true
},
"libargon2": {
"source": "libargon2",
"static-libs-unix": [
"libargon2.a"
]
},
"libavif": {
"source": "libavif",
"static-libs-unix": [
@@ -188,10 +237,17 @@
"libmcrypt.a"
]
},
"libmemcached": {
"source": "libmemcached",
"static-libs-unix": [
"libmemcached.a",
"libmemcachedutil.a"
]
},
"libpng": {
"source": "libpng",
"static-libs-unix": [
"libpng.a"
"libpng16.a"
],
"static-libs-windows": [
"libpng16_static.lib"
@@ -260,18 +316,26 @@
"libxml2"
],
"lib-depends": [
"libiconv"
"libiconv",
"zlib"
],
"lib-suggests": [
"xz",
"zlib",
"icu"
],
"lib-suggests-windows": [
"icu",
"xz",
"zlib",
"pthreads4w"
"xz"
]
},
"libxslt": {
"source": "libxslt",
"static-libs-unix": [
"libxslt.a",
"libexslt.a"
],
"lib-depends": [
"libxml2"
]
},
"libyaml": {
@@ -393,19 +457,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": {
@@ -417,6 +472,21 @@
"ncurses"
]
},
"snappy": {
"source": "snappy",
"static-libs-unix": [
"libsnappy.a"
],
"headers-unix": [
"snappy.h",
"snappy-c.h",
"snappy-sinksource.h",
"snappy-stubs-public.h"
],
"lib-depends": [
"zlib"
]
},
"sqlite": {
"source": "sqlite",
"static-libs-unix": [
@@ -427,6 +497,12 @@
"sqlite3ext.h"
]
},
"tidy": {
"source": "tidy",
"static-libs-unix": [
"libtidy.a"
]
},
"xz": {
"source": "xz",
"static-libs-unix": [
@@ -462,13 +538,6 @@
"zconf.h"
]
},
"libmemcached": {
"source": "libmemcached",
"static-libs-unix": [
"libmemcached.a",
"libmemcachedutil.a"
]
},
"zstd": {
"source": "zstd",
"static-libs-unix": [
@@ -490,4 +559,4 @@
"zstd_errors.h"
]
}
}
}

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

@@ -4,46 +4,49 @@ declare(strict_types=1);
namespace SPC;
use SPC\command\DeployCommand;
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;
/**
* spc 应用究级入口
* static-php-cli console app entry
*/
class ConsoleApplication extends Application
final class ConsoleApplication extends Application
{
public const VERSION = '2.0-rc4';
public const VERSION = '2.0.0-rc9';
/**
* @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(),
// 生产环境不显示详细的调试错误,只使用 symfony console 自带的错误显示
$this->setCatchExceptions(file_exists(ROOT_DIR . '/.prod') || !in_array('--debug', $argv));
// 通过扫描目录 src/static-php-cli/command/ 添加子命令
$commands = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/command', 'SPC\\command');
$this->addCommands(array_map(function ($x) { return new $x(); }, array_filter($commands, function ($y) {
if (is_a($y, DeployCommand::class, true) && (class_exists('\\Phar') && \Phar::running() || !class_exists('\\Phar'))) {
return false;
}
$reflection = new \ReflectionClass($y);
return !$reflection->isAbstract() && !$reflection->isInterface();
})));
// Dev commands
new AllExtCommand(),
new PhpVerCommand(),
new SortConfigCommand(),
]
);
}
/**
* 重载以去除一些不必要的默认命令
*/
protected function getDefaultCommands(): array
{
return [new HelpCommand(), new ListCommand()];

View File

@@ -15,43 +15,32 @@ use SPC\util\DependencyUtil;
abstract class BuilderBase
{
/** @var bool 是否启用 ZTS 线程安全 */
public bool $zts = false;
/** @var string 编译目标架构 */
public string $arch;
/** @var string GNU 格式的编译目标架构 */
public string $gnu_arch;
/** @var int 编译进程数 */
/** @var int Concurrency */
public int $concurrency = 1;
/** @var array<string, LibraryBase> 要编译的 libs 列表 */
/** @var array<string, LibraryBase> libraries */
protected array $libs = [];
/** @var array<string, Extension> 要编译的扩展列表 */
/** @var array<string, Extension> extensions */
protected array $exts = [];
/** @var array<int, string> 要编译的扩展列表(仅名字列表,用于最后生成编译的扩展列表给 micro */
protected array $plain_extensions = [];
/** @var bool 本次编译是否只编译 libs不编译 PHP */
/** @var bool compile libs only (just mark it) */
protected bool $libs_only = false;
/** @var bool 是否 strip 最终的二进制 */
protected bool $strip = true;
/** @var array<string, mixed> compile options */
protected array $options = [];
/**
* 构建指定列表的 libs
* Build libraries
*
* @param array<string> $libraries Libraries to build
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function buildLibs(array $libraries): void
{
// 通过扫描目录查找 lib
// search all supported libs
$support_lib_list = [];
$classes = FileSystem::getClassesPsr4(
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
@@ -63,36 +52,40 @@ abstract class BuilderBase
}
}
// 如果传入了空则默认检查和安置所有支持的liblibraries为要build的support_lib_list为支持的列表
// if no libs specified, compile all supported libs
if ($libraries === [] && $this->isLibsOnly()) {
$libraries = array_keys($support_lib_list);
}
// pkg-config must be compiled first, whether it is specified or not
if (!in_array('pkg-config', $libraries)) {
array_unshift($libraries, 'pkg-config');
}
// 排序 libs根据依赖计算一个新的列表出来
// append dependencies
$libraries = DependencyUtil::getLibsByDeps($libraries);
// 过滤不支持的库后添加
// add lib object for builder
foreach ($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);
}
// 计算依赖,经过这里的遍历,如果没有抛出异常,说明依赖符合要求,可以继续下面的
// calculate and check dependencies
foreach ($this->libs as $lib) {
$lib->calcDependency();
}
// extract sources
SourceExtractor::initSource(libs: $libraries);
// 构建库
// 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'),
@@ -102,9 +95,9 @@ abstract class BuilderBase
}
/**
* 添加要编译的 Lib 库
* Add library to build.
*
* @param LibraryBase $library Lib 库对象
* @param LibraryBase $library Library object
*/
public function addLib(LibraryBase $library): void
{
@@ -112,9 +105,7 @@ abstract class BuilderBase
}
/**
* 获取要编译的 Lib 库对象
*
* @param string $name 库名称
* Get library object by name.
*/
public function getLib(string $name): ?LibraryBase
{
@@ -122,9 +113,17 @@ abstract class BuilderBase
}
/**
* 添加要编译的扩展
* Get all library objects.
*
* @param Extension $extension 扩展对象
* @return LibraryBase[]
*/
public function getLibs(): array
{
return $this->libs;
}
/**
* Add extension to build.
*/
public function addExt(Extension $extension): void
{
@@ -132,9 +131,7 @@ abstract class BuilderBase
}
/**
* 获取要编译的扩展对象
*
* @param string $name 扩展名称
* Get extension object by name.
*/
public function getExt(string $name): ?Extension
{
@@ -142,7 +139,7 @@ abstract class BuilderBase
}
/**
* 获取所有要编译的扩展对象
* Get all extension objects.
*
* @return Extension[]
*/
@@ -152,28 +149,31 @@ abstract class BuilderBase
}
/**
* 检查 C++ 扩展是否存在
* Check if there is a cpp extensions or libraries.
*
* @throws FileSystemException
* @throws RuntimeException
* @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;
}
/**
* 设置本次 Builder 是否为仅编译库的模式
* Set libs only mode.
*/
public function setLibsOnly(bool $status = true): void
{
@@ -181,7 +181,7 @@ abstract class BuilderBase
}
/**
* 检验 ext 扩展列表是否合理,并声明 Extension 对象,检查扩展的依赖
* Verify the list of "ext" extensions for validity and declare an Extension object to check the dependencies of the extensions.
*
* @throws FileSystemException
* @throws RuntimeException
@@ -203,26 +203,21 @@ abstract class BuilderBase
}
foreach ($this->exts as $ext) {
// 检查下依赖就行了,作用是导入依赖给 Extension 对象,今后可以对库依赖进行选择性处理
$ext->checkDependency();
}
$this->plain_extensions = $extensions;
}
/**
* 开始构建 PHP
* Start to build PHP
*
* @param int $build_target 规则
* @param bool $bloat 保留
* @param int $build_target Build target, see BUILD_TARGET_*
*/
abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = false);
abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE);
/**
* 生成依赖的扩展编译启用参数
* 例如 --enable-mbstring
* Generate extension enable arguments for configure.
* e.g. --enable-mbstring
*
* @throws RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
@@ -237,7 +232,7 @@ abstract class BuilderBase
}
/**
* 返回是否只编译 libs 的模式
* Get libs only mode.
*/
public function isLibsOnly(): bool
{
@@ -245,15 +240,43 @@ abstract class BuilderBase
}
/**
* 获取当前即将编译的 PHP 的版本 ID五位数那个
* 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');
}
/**
* Get build type name string to display.
*
* @param int $type Build target type
*/
public function getBuildTypeName(int $type): string
{
$ls = [];
@@ -266,16 +289,64 @@ 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);
}
public function setStrip(bool $strip): void
/**
* Get builder options (maybe changed by user)
*
* @param string $key Option key
* @param mixed $default If not exists, return this value
*/
public function getOption(string $key, mixed $default = null): mixed
{
$this->strip = $strip;
return $this->options[$key] ?? $default;
}
/**
* 检查是否存在 lib 库对应的源码,如果不存在,则抛出异常
* Get all builder options
*/
public function getOptions(): array
{
return $this->options;
}
/**
* Set builder options if not exists.
*/
public function setOptionIfNotExist(string $key, mixed $value): void
{
if (!isset($this->options[$key])) {
$this->options[$key] = $value;
}
}
/**
* Set builder options.
*/
public function setOption(string $key, mixed $value): void
{
$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);
}
/**
* Check if all libs are downloaded.
* If not, throw exception.
*
* @throws RuntimeException
*/

View File

@@ -4,9 +4,10 @@ declare(strict_types=1);
namespace SPC\builder;
use SPC\builder\freebsd\BSDBuilder;
use SPC\builder\linux\LinuxBuilder;
use SPC\builder\macos\MacOSBuilder;
use SPC\builder\windows\WindowsBuilder;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use Symfony\Component\Console\Input\InputInterface;
@@ -17,7 +18,9 @@ use Symfony\Component\Console\Input\InputInterface;
class BuilderProvider
{
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public static function makeBuilderByInput(InputInterface $input): BuilderBase
{
@@ -27,18 +30,9 @@ class BuilderProvider
// vs_ver: $input->getOption('vs-ver'),
// arch: $input->getOption('arch'),
// ),
'Darwin' => new MacOSBuilder(
cc: $input->getOption('cc'),
cxx: $input->getOption('cxx'),
arch: $input->getOption('arch'),
zts: $input->hasOption('enable-zts') ? $input->getOption('enable-zts') : false,
),
'Linux' => new LinuxBuilder(
cc: $input->getOption('cc'),
cxx: $input->getOption('cxx'),
arch: $input->getOption('arch'),
zts: $input->hasOption('enable-zts') ? $input->getOption('enable-zts') : false,
),
'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'),
};
}

View File

@@ -34,7 +34,7 @@ class Extension
/**
* 获取开启该扩展的 PHP 编译添加的参数
*
* @throws FileSystemException|RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
public function getConfigureArg(): string
@@ -46,6 +46,7 @@ class Extension
break;
case 'Darwin':
case 'Linux':
case 'BSD':
$arg .= $this->getUnixConfigureArg();
break;
}
@@ -56,7 +57,6 @@ class Extension
* 根据 ext 的 arg-type 获取对应开启的参数,一般都是 --enable-xxx 和 --with-xxx
*
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function getEnableArg(): string
@@ -163,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,25 +4,22 @@ 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;
use SPC\store\Config;
/**
* Lib 库的基类操作对象
*/
abstract class LibraryBase
{
/** @var string lib 依赖名称,必须重写 */
/** @var string */
public const NAME = 'unknown';
/** @var string lib 依赖的根目录 */
protected string $source_dir;
/** @var array 依赖列表 */
protected array $dependencies = [];
protected bool $patched = false;
/**
* @throws RuntimeException
*/
@@ -35,7 +32,7 @@ abstract class LibraryBase
}
/**
* 获取 lib 库的根目录
* Get current lib source root dir.
*/
public function getSourceDir(): string
{
@@ -43,10 +40,9 @@ abstract class LibraryBase
}
/**
* 获取当前 lib 库的所有依赖列表
* Get current lib dependencies.
*
* @param bool $recursive 是否递归获取(默认为 False
* @return array<string, LibraryBase> 依赖的 Map
* @return array<string, LibraryBase>
*/
public function getDependencies(bool $recursive = false): array
{
@@ -55,7 +51,6 @@ abstract class LibraryBase
return $this->dependencies;
}
// 下面为递归获取依赖列表,根据依赖顺序
$deps = [];
$added = 1;
@@ -78,20 +73,21 @@ abstract class LibraryBase
}
/**
* 计算依赖列表,不符合依赖将抛出异常
* Calculate dependencies for current library.
*
* @throws RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
public function calcDependency(): void
{
// 先从配置文件添加依赖,这里根据不同的操作系统分别选择不同的元信息
// Add dependencies from the configuration file. Here, choose different metadata based on the operating system.
/*
选择规则:
如果是 Windows 系统,则依次尝试有无 lib-depends-windowslib-depends-winlib-depends
如果是 macOS 系统,则依次尝试 lib-depends-darwinlib-depends-unixlib-depends
如果是 Linux 系统,则依次尝试 lib-depends-linuxlib-depends-unixlib-depends
*/
Rules:
If it is a Windows system, try the following dependencies in order: lib-depends-windows, lib-depends-win, lib-depends.
If it is a macOS system, try the following dependencies in order: lib-depends-darwin, lib-depends-unix, lib-depends.
If it is a Linux system, try the following dependencies in order: lib-depends-linux, lib-depends-unix, lib-depends.
*/
foreach (Config::getLib(static::NAME, 'lib-depends', []) as $dep_name) {
$this->addLibraryDependency($dep_name);
}
@@ -101,11 +97,10 @@ abstract class LibraryBase
}
/**
* 获取当前库编译出来获取到的静态库文件列表
* Get config static libs.
*
* @return string[] 获取编译出来后的需要的静态库文件列表
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function getStaticLibs(): array
{
@@ -113,11 +108,10 @@ abstract class LibraryBase
}
/**
* 获取当前 lib 编译出来的 C Header 文件列表
* Get config headers.
*
* @return string[] 获取编译出来后需要的 C Header 文件列表
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function getHeaders(): array
{
@@ -125,46 +119,56 @@ abstract class LibraryBase
}
/**
* 证明该库是否已编译好且就绪,如果没有就绪,内部会调用 build 来进行构建该库
* Try to build this library, before build, we check first.
*
* BUILD_STATUS_OK if build success
* BUILD_STATUS_ALREADY if already built
* BUILD_STATUS_FAILED if build failed
*
* @throws RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
public function tryBuild(bool $force_build = false): int
{
// 传入 true表明直接编译
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->build();
return BUILD_STATUS_OK;
}
// 看看这些库是不是存在,如果不存在,则调用编译并返回结果状态
// check if these libraries exist, if not, invoke compilation and return the result status
foreach ($this->getStaticLibs() as $name) {
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
$this->tryBuild(true);
return BUILD_STATUS_OK;
}
}
// 头文件同理
// header files the same
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 ($this instanceof MacOSLibraryBase && static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
// pkg-config is treated specially. If it is pkg-config, check if the pkg-config binary exists
if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
$this->tryBuild(true);
return BUILD_STATUS_OK;
}
// 到这里说明所有的文件都存在,就跳过编译
// if all the files exist at this point, skip the compilation process
return BUILD_STATUS_ALREADY;
}
/**
* Patch before build, overwrite this and return true to patch libs
* Patch before build, overwrite this and return true to patch libs.
*/
public function patchBeforeBuild(): bool
{
@@ -172,35 +176,32 @@ abstract class LibraryBase
}
/**
* 获取构建当前 lib 的 Builder 对象
* Get current builder object.
*/
abstract public function getBuilder(): BuilderBase;
/**
* 构建该库需要调用的命令和操作
* Build this library.
*
* @throws RuntimeException
*/
abstract protected function build();
/**
* 添加 lib 库的依赖库
* Add lib dependency
*
* @param string $name 依赖名称
* @param bool $optional 是否是可选依赖(默认为 False
* @throws RuntimeException
*/
protected function addLibraryDependency(string $name, bool $optional = false): void
{
// Log::i("add $name as dep of {$this->name}");
$dep_lib = $this->getBuilder()->getLib($name);
if (!$dep_lib) {
if (!$optional) {
throw new RuntimeException(static::NAME . " requires library {$name}");
}
logger()->debug('enabling ' . static::NAME . " without {$name}");
} else {
if ($dep_lib) {
$this->dependencies[$name] = $dep_lib;
return;
}
if (!$optional) {
throw new RuntimeException(static::NAME . " requires library {$name}");
}
logger()->debug('enabling ' . static::NAME . " without {$name}");
}
}

View File

@@ -7,6 +7,7 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\exception\FileSystemException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
@@ -15,11 +16,12 @@ class bz2 extends Extension
{
/**
* @throws FileSystemException
* @throws WrongUsageException
*/
public function patchBeforeConfigure(): bool
{
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, '/-lbz2/', $this->getLibFilesString() . $frameworks);
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-lbz2/', $this->getLibFilesString() . $frameworks);
return true;
}
}

View File

@@ -7,12 +7,16 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\exception\FileSystemException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('curl')]
class curl extends Extension
{
/**
* @throws FileSystemException
*/
public function patchBeforeBuildconf(): bool
{
logger()->info('patching before-configure for curl checks');
@@ -42,11 +46,12 @@ class curl extends Extension
/**
* @throws FileSystemException
* @throws WrongUsageException
*/
public function patchBeforeConfigure(): bool
{
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, '/-lcurl/', $this->getLibFilesString() . $frameworks);
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-lcurl/', $this->getLibFilesString() . $frameworks);
return true;
}
}

View File

@@ -31,12 +31,7 @@ class event extends Extension
*/
public function patchBeforeConfigure(): bool
{
FileSystem::replaceFile(
SOURCE_PATH . '/php-src/configure',
REPLACE_FILE_PREG,
'/-levent_openssl/',
$this->getLibFilesString()
);
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-levent_openssl/', $this->getLibFilesString());
return true;
}
}

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('glfw')]
class glfw extends Extension
{
/**
* @throws RuntimeException
*/
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

@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\util\CustomExt;
#[CustomExt('iconv')]
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';
}
$this->builder->setOption('extra-libs', $extra_libs);
return true;
}
}

View File

@@ -5,11 +5,23 @@ 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 patchBeforeMake(): bool
{
// imagick may call omp_pause_all which requires -lgomp
$extra_libs = $this->builder->getOption('extra-libs', '');
if ($this->builder instanceof LinuxBuilder) {
$extra_libs .= ' -lgomp ';
}
$this->builder->setOption('extra-libs', $extra_libs);
return true;
}
public function getUnixConfigureArg(): string
{
return '--with-imagick=' . BUILD_ROOT_PATH;

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

@@ -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,6 +5,7 @@ declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\FileSystemException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
@@ -16,17 +17,18 @@ class memcache extends Extension
return '--enable-memcache --with-zlib-dir=' . BUILD_ROOT_PATH;
}
/**
* @throws FileSystemException
*/
public function patchBeforeBuildconf(): bool
{
FileSystem::replaceFile(
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
REPLACE_FILE_STR,
'if test -d $abs_srcdir/src ; then',
'if test -d $abs_srcdir/main ; then'
);
FileSystem::replaceFile(
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/memcache/config9.m4',
REPLACE_FILE_STR,
'export CPPFLAGS="$CPPFLAGS $INCLUDES"',
'export CPPFLAGS="$CPPFLAGS $INCLUDES -I$abs_srcdir/main"'
);

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

@@ -17,9 +17,8 @@ class pdo_sqlite extends Extension
*/
public function patchBeforeConfigure(): bool
{
FileSystem::replaceFile(
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/configure',
REPLACE_FILE_PREG,
'/sqlite3_column_table_name=yes/',
'sqlite3_column_table_name=no'
);

View File

@@ -17,9 +17,8 @@ class pgsql extends Extension
*/
public function patchBeforeConfigure(): bool
{
FileSystem::replaceFile(
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/configure',
REPLACE_FILE_PREG,
'/-lpq/',
$this->getLibFilesString()
);

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('pmmp-chunkutils2')]
class pmmp_chunkutils2 extends Extension
{
public function getDistName(): string
{
return 'chunkutils2';
}
public function getUnixConfigureArg(): string
{
return '--enable-chunkutils2';
}
}

View File

@@ -17,9 +17,8 @@ class readline extends Extension
*/
public function patchBeforeConfigure(): bool
{
FileSystem::replaceFile(
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/configure',
REPLACE_FILE_PREG,
'/-lncurses/',
$this->getLibFilesString()
);

View File

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

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\exception\FileSystemException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('snappy')]
class snappy extends Extension
{
/**
* @throws FileSystemException
*/
public function patchBeforeConfigure(): bool
{
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/configure',
'/-lsnappy/',
$this->getLibFilesString() . ($this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++')
);
return true;
}
public function getUnixConfigureArg(): string
{
return '--enable-snappy --with-snappy-includedir="' . BUILD_ROOT_PATH . '"';
}
}

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

@@ -17,9 +17,8 @@ class ssh2 extends Extension
*/
public function patchBeforeConfigure(): bool
{
FileSystem::replaceFile(
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/configure',
REPLACE_FILE_PREG,
'/-lssh2/',
$this->getLibFilesString()
);

View File

@@ -13,10 +13,12 @@ class swoole extends Extension
public function getUnixConfigureArg(): string
{
$arg = '--enable-swoole';
// pgsql hook is buggy for static php
$arg .= ' --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';
$arg .= $this->builder->getLib('brotli') ? (' --enable-brotli --with-brotli-dir=' . BUILD_ROOT_PATH) : ' --disable-brotli';
// swoole curl hook is buggy for php 8.0
$arg .= $this->builder->getExt('curl') && $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl';
return $arg;
}
}

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
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
@@ -19,9 +19,12 @@ class swow extends Extension
return $arg;
}
/**
* @throws RuntimeException
*/
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,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,253 @@
<?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);
SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
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()
);
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->sanityCheck($build_target);
}
}
/**
* Build cli sapi
*
* @throws RuntimeException
* @throws FileSystemException
*/
public 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
*/
public 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
*/
public 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
*/
public 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,96 +10,95 @@ 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;
/**
* Linux 系统环境下的构建器
*/
class LinuxBuilder extends BuilderBase
{
/** 编译的 Unix 工具集 */
/** Unix compatible builder methods */
use UnixBuilderTrait;
/** @var string[] Linux 环境下编译依赖的命令 */
public const REQUIRED_COMMANDS = ['make', 'bison', 'flex', 'git', 'autoconf', 'automake', 'tar', 'unzip', /* 'xz', 好像不需要 */ 'gzip', 'bzip2', 'cmake'];
/** @var string 使用的 libc */
public string $libc;
/** @var array 特殊架构下的 cflags */
/** @var array Tune cflags */
public array $tune_c_flags;
/** @var string pkg-config 环境变量 */
public string $pkgconf_env;
/** @var string 交叉编译变量 */
public string $cross_compile_prefix = '';
public string $note_section = "Je pense, donc je suis\0";
/** @var bool Micro patch phar flag */
private bool $phar_patched = false;
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function __construct(?string $cc = null, ?string $cxx = null, ?string $arch = null, bool $zts = false)
public function __construct(array $options = [])
{
// 初始化一些默认参数
$this->cc = $cc ?? match (SystemUtil::getOSRelease()['dist']) {
'alpine' => 'gcc',
default => 'musl-gcc'
};
$this->cxx = $cxx ?? 'g++';
$this->arch = $arch ?? php_uname('m');
$this->gnu_arch = arch2gnu($this->arch);
$this->zts = $zts;
$this->libc = 'musl'; // SystemUtil::selectLibc($this->cc);
$this->options = $options;
// 根据 CPU 线程数设置编译进程数
// ---------- set necessary options ----------
// 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')));
// concurrency
$this->concurrency = SystemUtil::getCpuCount();
// 设置 cflags
$this->arch_c_flags = SystemUtil::getArchCFlags($this->cc, $this->arch);
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->cxx, $this->arch);
$this->tune_c_flags = SystemUtil::checkCCFlags(SystemUtil::getTuneCFlags($this->arch), $this->cc);
// 设置 cmake
// cflags
$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(
os: 'Linux',
target_arch: $this->arch,
cflags: $this->arch_c_flags,
cc: $this->cc,
cxx: $this->cxx
'Linux',
$this->getOption('arch'),
$this->arch_c_flags,
getenv('CC'),
getenv('CXX'),
);
// 设置 pkgconfig
$this->pkgconf_env = 'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig"';
// 设置 configure 依赖的环境变量
$this->configure_env =
$this->pkgconf_env . ' ' .
"CC='{$this->cc}' " .
"CXX='{$this->cxx}' " .
(php_uname('m') === $this->arch ? '' : "CFLAGS='{$this->arch_c_flags}'");
// 交叉编译依赖的TODO
if (php_uname('m') !== $this->arch) {
// 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);
$this->configure_env .= " CROSS_COMPILE='{$this->cross_compile_prefix}'";
}
}*/
$missing = [];
foreach (self::REQUIRED_COMMANDS as $cmd) {
if (SystemUtil::findCommand($cmd) === null) {
$missing[] = $cmd;
}
}
if (!empty($missing)) {
throw new WrongUsageException('missing system commands: ' . implode(', ', $missing));
}
// 创立 pkg-config 和放头文件的目录
// 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);
}
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function makeAutoconfArgs(string $name, array $libSpecs): string
{
$ret = '';
@@ -124,50 +123,29 @@ class LinuxBuilder extends BuilderBase
/**
* @throws RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $with_clean = false, bool $bloat = false)
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{
if (!$bloat) {
$extra_libs = implode(' ', $this->getAllStaticLibFiles());
// ---------- Update extra-libs ----------
$extra_libs = $this->getOption('extra-libs', '');
// non-bloat linking
if (!$this->getOption('bloat', false)) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
} else {
logger()->info('bloat linking');
$extra_libs = implode(
' ',
array_map(
fn ($x) => "-Xcompiler {$x}",
array_filter($this->getAllStaticLibFiles())
)
);
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", array_filter($this->getAllStaticLibFiles())));
}
// add libstdc++, some extensions or libraries need it
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : '');
$this->setOption('extra-libs', $extra_libs);
if ($this->hasCppExtension()) {
$extra_libs .= ' -lstdc++';
}
if ($this->getExt('imagick')) {
$extra_libs .= ' /usr/lib/libMagick++-7.Q16HDRI.a /usr/lib/libMagickCore-7.Q16HDRI.a /usr/lib/libMagickWand-7.Q16HDRI.a';
}
$envs = $this->pkgconf_env . ' ' .
"CC='{$this->cc}' " .
"CXX='{$this->cxx}' ";
$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->cc, 'clang') && SystemUtil::findCommand('lld')) {
$use_lld = '-Xcompiler -fuse-ld=lld';
}
break;
default:
throw new WrongUsageException('libc ' . $this->libc . ' is not implemented yet');
}
$envs = "{$envs} CFLAGS='{$cflags}' LIBS='-ldl -lpthread'";
// prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => $cflags,
'LIBS' => '-ldl -lpthread',
]);
SourcePatcher::patchBeforeBuildconf($this);
@@ -175,14 +153,26 @@ class LinuxBuilder extends BuilderBase
SourcePatcher::patchBeforeConfigure($this);
if ($this->getPHPVersionID() < 80000) {
$json_74 = '--enable-json ';
$phpVersionID = $this->getPHPVersionID();
$json_74 = $phpVersionID < 80000 ? '--enable-json ' : '';
if ($this->getOption('enable-zts', false)) {
$maxExecutionTimers = $phpVersionID >= 80100 ? '--enable-zend-max-execution-timers ' : '';
$zts = '--enable-zts --disable-zend-signals ';
} else {
$json_74 = '';
$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 ' .
@@ -191,43 +181,96 @@ 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 .
'--enable-micro=all-static ' .
($this->zts ? '--enable-zts' : '') . ' ' .
$zts .
$maxExecutionTimers .
$this->makeExtensionArgs() . ' ' .
$envs
$envs_build_php
);
SourcePatcher::patchBeforeMake($this);
file_put_contents('/tmp/comment', $this->note_section);
// 清理
$this->cleanMake();
if ($bloat) {
logger()->info('bloat linking');
$extra_libs = "-Wl,--whole-archive {$extra_libs} -Wl,--no-whole-archive";
}
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->arch) {
if (php_uname('m') === $this->getOption('arch')) {
$this->sanityCheck($build_target);
}
}
/**
* Build cli sapi
*
* @throws RuntimeException
* @throws FileSystemException
*/
public function buildCli(): void
{
$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");
if (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')->exec('strip --strip-all php');
}
$this->deployBinary(BUILD_TARGET_CLI);
}
/**
* Build phpmicro sapi
*
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public 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']);
}
$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");
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);
@@ -235,78 +278,54 @@ class LinuxBuilder extends BuilderBase
}
/**
* @throws RuntimeException
*/
public function buildCli(string $extra_libs, string $use_lld): void
{
shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec(
'make -j' . $this->concurrency .
' 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' " .
'cli'
);
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')
->exec("{$this->cross_compile_prefix}objcopy --only-keep-debug php php.debug")
->exec('elfedit --output-osabi linux php')
->exec("{$this->cross_compile_prefix}strip --strip-all php")
->exec("{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php.debug --remove-section=.note php");
$this->deployBinary(BUILD_TARGET_CLI);
}
/**
* @throws RuntimeException
*/
public function buildMicro(string $extra_libs, string $use_lld, string $cflags): void
{
if ($this->getPHPVersionID() < 80000) {
throw new RuntimeException('phpmicro only support PHP >= 8.0!');
}
if ($this->getExt('phar')) {
$this->phar_patched = true;
SourcePatcher::patchMicro(['phar']);
}
shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec(
"make -j{$this->concurrency} " .
'EXTRA_CFLAGS=' . quote('-g -Os -fno-ident ' . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags))) . ' ' .
'EXTRA_LIBS=' . quote($extra_libs) . ' ' .
'EXTRA_LDFLAGS_PROGRAM=' . quote("{$cflags} {$use_lld}" . ' -all-static', "'") . ' ' .
'micro'
);
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec("{$this->cross_compile_prefix}strip --strip-all micro.sfx");
$this->deployBinary(BUILD_TARGET_MICRO);
}
/**
* 构建 fpm
* Build fpm sapi
*
* @throws FileSystemException|RuntimeException
* @throws FileSystemException
* @throws RuntimeException
*/
public function buildFpm(string $extra_libs, string $use_lld): void
public function buildFpm(): void
{
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec(
'make -j' . $this->concurrency .
' 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' " .
'fpm'
);
->exec("make -j{$this->concurrency} {$vars} fpm");
if (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-all php-fpm');
}
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')
->exec("{$this->cross_compile_prefix}objcopy --only-keep-debug php-fpm php-fpm.debug")
->exec('elfedit --output-osabi linux php-fpm')
->exec("{$this->cross_compile_prefix}strip --strip-all php-fpm")
->exec("{$this->cross_compile_prefix}objcopy --update-section .comment=/tmp/comment --add-gnu-debuglink=php-fpm.debug --remove-section=.note php-fpm");
$this->deployBinary(BUILD_TARGET_FPM);
}
/**
* Build embed sapi
*
* @throws RuntimeException
*/
public 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']}" : '';
return [
'EXTRA_CFLAGS' => "{$optimization} -fno-ident -fPIE " . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . $cflags,
'EXTRA_LIBS' => $this->getOption('extra-libs', '') . $libs,
'EXTRA_LDFLAGS_PROGRAM' => "{$use_lld} -all-static" . $ldflags,
];
}
}

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace SPC\builder\linux;
use JetBrains\PhpStorm\ArrayShape;
use SPC\builder\traits\UnixSystemUtilTrait;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
@@ -13,7 +12,7 @@ class SystemUtil
{
use UnixSystemUtilTrait;
#[ArrayShape(['dist' => 'mixed|string', 'ver' => 'mixed|string'])]
/** @noinspection PhpMissingBreakStatementInspection */
public static function getOSRelease(): array
{
$ret = [
@@ -21,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) {
@@ -37,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;
@@ -81,6 +85,8 @@ class SystemUtil
/**
* @throws RuntimeException
* @throws WrongUsageException
* @throws WrongUsageException
*/
public static function getArchCFlags(string $cc, string $arch): string
{
@@ -120,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 '';
}
@@ -129,6 +135,7 @@ class SystemUtil
/**
* @throws RuntimeException
* @noinspection PhpUnused
*/
public static function getCrossCompilePrefix(string $cc, string $arch): string
{
@@ -159,6 +166,7 @@ class SystemUtil
return null;
}
/** @noinspection PhpUnused */
public static function findStaticLibs(array $names): ?array
{
$ret = [];
@@ -187,6 +195,7 @@ class SystemUtil
return null;
}
/** @noinspection PhpUnused */
public static function findHeaders(array $names): ?array
{
$ret = [];

View File

@@ -8,7 +8,6 @@ use SPC\builder\BuilderBase;
use SPC\builder\LibraryBase;
use SPC\builder\linux\LinuxBuilder;
use SPC\builder\traits\UnixLibraryTrait;
use SPC\exception\RuntimeException;
abstract class LinuxLibraryBase extends LibraryBase
{
@@ -34,51 +33,4 @@ abstract class LinuxLibraryBase extends LibraryBase
{
return $this->builder;
}
/**
* @throws RuntimeException
*/
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()
{
$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

@@ -8,13 +8,15 @@ class icu extends LinuxLibraryBase
{
public const NAME = 'icu';
protected function build()
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,63 @@
<?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(
"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,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class leveldb extends LinuxLibraryBase
{
use \SPC\builder\unix\library\leveldb;
public const NAME = 'leveldb';
}

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,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

@@ -20,41 +20,22 @@ declare(strict_types=1);
namespace SPC\builder\linux\library;
use SPC\builder\linux\SystemUtil;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\exception\WrongUsageException;
class libpng extends LinuxLibraryBase
{
public const NAME = 'libpng';
public function patchBeforeBuild(): bool
{
FileSystem::replaceFile(
SOURCE_PATH . '/libpng/configure',
REPLACE_FILE_STR,
'-lz',
BUILD_LIB_PATH . '/libz.a'
);
if (SystemUtil::getOSRelease()['dist'] === 'alpine') {
FileSystem::replaceFile(
SOURCE_PATH . '/libpng/configure',
REPLACE_FILE_STR,
'-lm',
'/usr/lib/libm.a'
);
}
return true;
}
/**
* @throws RuntimeException
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function build()
public function build(): void
{
$optimizations = match ($this->builder->arch) {
$optimizations = match ($this->builder->getOption('arch')) {
'x86_64' => '--enable-intel-sse ',
'arm64' => '--enable-arm-neon ',
default => '',
@@ -63,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->gnu_arch}-unknown-linux " .
'LDFLAGS="-L' . BUILD_LIB_PATH . '" ' .
'./configure ' .
'--disable-shared ' .
'--enable-static ' .
'--enable-hardware-optimizations ' .
@@ -73,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

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace SPC\builder\linux\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
@@ -13,23 +14,22 @@ class libxml2 extends LinuxLibraryBase
/**
* @throws RuntimeException
* @throws FileSystemException
*/
public function build()
public function build(): void
{
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
[$lib, $include, $destdir] = SEPARATED_PATH;
FileSystem::resetDir($this->source_dir . '/build');
shell()->cd($this->source_dir . '/build')
->exec(
"{$this->builder->configure_env} " . ' cmake ' .
'cmake ' .
"{$this->builder->makeCmakeArgs()} " .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' .
'-DIconv_IS_BUILT_IN=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' .
"-DLIBXML2_WITH_ZLIB={$enable_zlib} " .
"-DLIBXML2_WITH_ICU={$enable_icu} " .
"-DLIBXML2_WITH_LZMA={$enable_xz} " .
@@ -39,15 +39,12 @@ class libxml2 extends LinuxLibraryBase
'..'
)
->exec("cmake --build . -j {$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
if (is_dir(BUILD_INCLUDE_PATH . '/libxml2/libxml')) {
if (is_dir(BUILD_INCLUDE_PATH . '/libxml')) {
shell()->exec('rm -rf "' . BUILD_INCLUDE_PATH . '/libxml"');
}
$path = FileSystem::convertPath(BUILD_INCLUDE_PATH . '/libxml2/libxml');
$dst_path = FileSystem::convertPath(BUILD_INCLUDE_PATH . '/');
shell()->exec('mv "' . $path . '" "' . $dst_path . '"');
}
FileSystem::replaceFileStr(
BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc',
'-licudata -licui18n -licuuc',
'-licui18n -licuuc -licudata'
);
}
}

View File

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

View File

@@ -20,11 +20,20 @@ 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
{
public const NAME = 'nghttp2';
public function build()
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'zlib' => null,
@@ -46,10 +55,10 @@ class nghttp2 extends LinuxLibraryBase
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} ./configure " .
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->gnu_arch}-unknown-linux " .
"--host={$this->builder->getOption('gnu-arch')}-unknown-linux " .
'--enable-lib-only ' .
'--with-boost=no ' .
$args . ' ' .

View File

@@ -23,26 +23,28 @@ namespace SPC\builder\linux\library;
use SPC\builder\linux\SystemUtil;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
class openssl extends LinuxLibraryBase
{
public const NAME = 'openssl';
/**
* @throws RuntimeException
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function build()
public function build(): void
{
[$lib,$include,$destdir] = SEPARATED_PATH;
[,,$destdir] = SEPARATED_PATH;
$extra = '';
$ex_lib = '-ldl -pthread';
$env = $this->builder->pkgconf_env . " CFLAGS='{$this->builder->arch_c_flags}'";
$env .= " CC='{$this->builder->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->arch . '-linux-gnu/ ' .
' -idirafter /usr/include/' . $this->builder->getOption('arch') . '-linux-gnu/ ' .
"' ";
// lib:zlib
$zlib = $this->builder->getLib('zlib');
@@ -58,17 +60,17 @@ class openssl extends LinuxLibraryBase
$ex_lib = trim($ex_lib);
$clang_postfix = SystemUtil::getCCType($this->builder->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 ' .
"{$zlib_extra}" .
'no-legacy ' .
"linux-{$this->builder->arch}{$clang_postfix}"
"linux-{$this->builder->getOption('arch')}{$clang_postfix}"
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")

View File

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

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

@@ -10,59 +10,58 @@ 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;
/**
* macOS 系统环境下的构建器
* 源于 Config但因为感觉叫 Config 不太合适,就换成了 Builder
*/
class MacOSBuilder extends BuilderBase
{
/** 编译的 Unix 工具集 */
/** Unix compatible builder methods */
use UnixBuilderTrait;
/** @var bool 标记是否 patch phar */
/** @var bool Micro patch phar flag */
private bool $phar_patched = false;
/**
* @param null|string $cc C编译器名称如果不传入则默认使用clang
* @param null|string $cxx C++编译器名称如果不传入则默认使用clang++
* @param null|string $arch 当前架构,如果不传入则默认使用当前系统架构
* @throws RuntimeException
* @throws WrongUsageException
* @throws FileSystemException
*/
public function __construct(?string $cc = null, ?string $cxx = null, ?string $arch = null, bool $zts = false)
public function __construct(array $options = [])
{
// 如果是 Debug 模式,才使用 set -x 显示每条执行的命令
$this->set_x = defined('DEBUG_MODE') ? 'set -x' : 'true';
// 初始化一些默认参数
$this->cc = $cc ?? 'clang';
$this->cxx = $cxx ?? 'clang++';
$this->arch = $arch ?? php_uname('m');
$this->gnu_arch = arch2gnu($this->arch);
$this->zts = $zts;
// 根据 CPU 线程数设置编译进程数
$this->concurrency = SystemUtil::getCpuCount();
// 设置 cflags
$this->arch_c_flags = SystemUtil::getArchCFlags($this->arch);
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->arch);
// 设置 cmake
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->arch, $this->arch_c_flags);
// 设置 configure 依赖的环境变量
$this->configure_env =
'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" ' .
'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' .
"CC='{$this->cc}' " .
"CXX='{$this->cxx}' " .
"CFLAGS='{$this->arch_c_flags} -Wimplicit-function-declaration -Os'";
$this->options = $options;
// 创立 pkg-config 和放头文件的目录
// ---------- 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('Darwin', $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);
}
/**
* 生成库构建采用的 autoconf 参数列表
* [deprecated] 生成库构建采用的 autoconf 参数列表
*
* @param string $name 要构建的 lib 库名,传入仅供输出日志
* @param array $lib_specs 依赖的 lib 库的 autoconf 文件
@@ -76,7 +75,6 @@ class MacOSBuilder extends BuilderBase
$arr = $arr ?? [];
$disableArgs = $arr[0] ?? null;
$prefix = $arr[1] ?? null;
if ($lib instanceof MacOSLibraryBase) {
logger()->info("{$name} \033[32;1mwith\033[0;1m {$libName} support");
$ret .= '--with-' . $libName . '=yes ';
@@ -89,9 +87,11 @@ class MacOSBuilder extends BuilderBase
}
/**
* 返回 macOS 系统依赖的框架列表
* Get dynamically linked macOS frameworks
*
* @param bool $asString 是否以字符串形式返回(默认为 False
* @param bool $asString If true, return as string
* @throws FileSystemException
* @throws WrongUsageException
*/
public function getFrameworks(bool $asString = false): array|string
{
@@ -118,85 +118,145 @@ class MacOSBuilder extends BuilderBase
}
/**
* Just start to build statically linked php binary
*
* @param int $build_target build target
* @param bool $bloat just raw add all lib files
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function buildPHP(int $build_target = BUILD_TARGET_NONE, bool $bloat = false): void
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{
$extra_libs = $this->getFrameworks(true) . ' ' . ($this->hasCppExtension() ? '-lc++ ' : '');
if (!$bloat) {
$extra_libs .= implode(' ', $this->getAllStaticLibFiles());
// ---------- Update extra-libs ----------
$extra_libs = $this->getOption('extra-libs', '');
// 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->hasCpp() ? '-lc++ ' : '');
if (!$this->getOption('bloat', false)) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
} else {
logger()->info('bloat linking');
$extra_libs .= implode(
' ',
array_map(
fn ($x) => "-Wl,-force_load,{$x}",
array_filter($this->getAllStaticLibFiles())
)
);
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles())));
}
$this->setOption('extra-libs', $extra_libs);
// patch before buildconf
SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
SourcePatcher::patchBeforeConfigure($this);
if ($this->getLib('libxml2') || $this->getExt('iconv')) {
$extra_libs .= ' -liconv';
}
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
if ($this->getPHPVersionID() < 80000) {
$json_74 = '--enable-json ';
} else {
$json_74 = '';
}
$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 ' . // 不检测内存泄漏
'--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 ' .
($enableCli ? '--enable-cli ' : '--disable-cli ') .
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
($enableMicro ? '--enable-micro ' : '--disable-micro ') .
$json_74 .
'--enable-micro ' .
($this->zts ? '--enable-zts' : '') . ' ' .
$this->makeExtensionArgs() . ' ' .
$this->configure_env
$zts .
$this->makeExtensionArgs()
);
SourcePatcher::patchBeforeMake($this);
$this->cleanMake();
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
if ($enableCli) {
logger()->info('building cli');
$this->buildCli($extra_libs);
$this->buildCli();
}
if (($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
if ($enableFpm) {
logger()->info('building fpm');
$this->buildFpm($extra_libs);
$this->buildFpm();
}
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if ($enableMicro) {
logger()->info('building micro');
$this->buildMicro($extra_libs);
$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->arch) {
if (php_uname('m') === $this->getOption('arch')) {
$this->sanityCheck($build_target);
}
}
/**
* Build cli sapi
*
* @throws RuntimeException
* @throws FileSystemException
*/
public 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 needs it)
]);
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} {$vars} cli");
if (!$this->getOption('no-strip', false)) {
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
}
$this->deployBinary(BUILD_TARGET_CLI);
}
/**
* Build phpmicro sapi
*
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public 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 -fno-ident' . $enable_fake_cli,
// link resolv library (macOS needs it)
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv",
];
if (!$this->getOption('no-strip', false)) {
$vars['STRIP'] = 'dsymutil -f ';
}
$vars = SystemUtil::makeEnvVarString($vars);
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);
@@ -204,54 +264,48 @@ class MacOSBuilder extends BuilderBase
}
/**
* 构建 cli
* Build fpm sapi
*
* @throws RuntimeException
* @throws FileSystemException
*/
public function buildCli(string $extra_libs): void
public 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 needs it)
]);
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" cli");
if ($this->strip) {
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
}
$this->deployBinary(BUILD_TARGET_CLI);
}
/**
* 构建 phpmicro
*
* @throws FileSystemException|RuntimeException
*/
public function buildMicro(string $extra_libs): void
{
if ($this->getPHPVersionID() < 80000) {
throw new RuntimeException('phpmicro only support PHP >= 8.0!');
}
if ($this->getExt('phar')) {
$this->phar_patched = true;
SourcePatcher::patchMicro(['phar']);
}
shell()->cd(SOURCE_PATH . '/php-src')
->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" " . ($this->strip ? 'STRIP="dsymutil -f " ' : '') . 'micro');
$this->deployBinary(BUILD_TARGET_MICRO);
}
/**
* 构建 fpm
*
* @throws RuntimeException
* @throws FileSystemException
*/
public function buildFpm(string $extra_libs): void
{
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} EXTRA_CFLAGS=\"-g -Os -fno-ident\" EXTRA_LIBS=\"{$extra_libs} -lresolv\" fpm");
if ($this->strip) {
$shell->exec("make -j{$this->concurrency} {$vars} fpm");
if (!$this->getOption('no-strip', false)) {
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm');
}
$this->deployBinary(BUILD_TARGET_FPM);
}
/**
* Build embed sapi
*
* @throws RuntimeException
*/
public function buildEmbed(): 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 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

@@ -10,11 +10,11 @@ use SPC\exception\WrongUsageException;
class SystemUtil
{
/** macOS 兼容 unix 的系统工具 */
/** Unix System Util Compatible */
use UnixSystemUtilTrait;
/**
* 获取系统 CPU 逻辑内核数
* Get Logic CPU Count for macOS
*
* @throws RuntimeException
*/
@@ -29,9 +29,10 @@ class SystemUtil
}
/**
* 获取不同架构对应的 cflags 参数
* Get Target Arch CFlags
*
* @param string $arch 架构名称
* @param string $arch Arch Name
* @return string return Arch CFlags string
* @throws WrongUsageException
*/
public static function getArchCFlags(string $arch): string

View File

@@ -8,6 +8,8 @@ use SPC\builder\BuilderBase;
use SPC\builder\LibraryBase;
use SPC\builder\macos\MacOSBuilder;
use SPC\builder\traits\UnixLibraryTrait;
use SPC\exception\FileSystemException;
use SPC\exception\WrongUsageException;
use SPC\store\Config;
abstract class MacOSLibraryBase extends LibraryBase
@@ -27,7 +29,8 @@ abstract class MacOSLibraryBase extends LibraryBase
}
/**
* 获取当前 lib 库依赖的 macOS framework
* @throws WrongUsageException
* @throws FileSystemException
*/
public function getFrameworks(): array
{

View File

@@ -34,18 +34,21 @@ class curl extends MacOSLibraryBase
*/
public function patchBeforeBuild(): bool
{
FileSystem::replaceFile(
FileSystem::replaceFileRegex(
SOURCE_PATH . '/curl/CMakeLists.txt',
REPLACE_FILE_PREG,
'/NOT COREFOUNDATION_FRAMEWORK/m',
'FALSE'
);
FileSystem::replaceFile(
FileSystem::replaceFileRegex(
SOURCE_PATH . '/curl/CMakeLists.txt',
REPLACE_FILE_PREG,
'/NOT SYSTEMCONFIGURATION_FRAMEWORK/m',
'FALSE'
);
FileSystem::replaceFileRegex(
SOURCE_PATH . '/curl/CMakeLists.txt',
'/NOT CORESERVICES_FRAMEWORK/m',
'FALSE'
);
return true;
}
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
class glfw extends MacOSLibraryBase
{
public const NAME = 'glfw';
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
// compile
shell()->cd(SOURCE_PATH . '/ext-glfw/vendor/glfw')
->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
$this->patchPkgconfPrefix(['glfw3.pc']);
}
}

View File

@@ -8,11 +8,11 @@ class icu extends MacOSLibraryBase
{
public const NAME = 'icu';
protected function build()
protected function build(): void
{
$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,66 @@
<?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(
"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 leveldb extends MacOSLibraryBase
{
use \SPC\builder\unix\library\leveldb;
public const NAME = 'leveldb';
}

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

@@ -1,39 +1,30 @@
<?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\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
class libffi extends MacOSLibraryBase
{
public const NAME = 'libffi';
protected function build()
/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build(): void
{
[$lib, , $destdir] = SEPARATED_PATH;
[, , $destdir] = SEPARATED_PATH;
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} ./configure " .
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->arch}-apple-darwin " .
"--target={$this->builder->arch}-apple-darwin " .
"--host={$this->builder->getOption('arch')}-apple-darwin " .
"--target={$this->builder->getOption('arch')}-apple-darwin " .
'--prefix= ' // use prefix=/
)
->exec('make clean')

View File

@@ -11,14 +11,14 @@ class libmemcached extends MacOSLibraryBase
{
public const NAME = 'libmemcached';
public function build()
public function build(): void
{
$rootdir = BUILD_ROOT_PATH;
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

@@ -22,6 +22,7 @@ namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
class libpng extends MacOSLibraryBase
{
@@ -30,10 +31,11 @@ class libpng extends MacOSLibraryBase
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
protected function build()
protected function build(): void
{
$optimizations = match ($this->builder->arch) {
$optimizations = match ($this->builder->getOption('arch')) {
'x86_64' => '--enable-intel-sse ',
'arm64' => '--enable-arm-neon ',
default => '',
@@ -42,8 +44,8 @@ class libpng extends MacOSLibraryBase
->exec('chmod +x ./configure')
->exec('chmod +x ./install-sh')
->exec(
"{$this->builder->configure_env} ./configure " .
"--host={$this->builder->gnu_arch}-apple-darwin " .
'./configure ' .
"--host={$this->builder->getOption('gnu-arch')}-apple-darwin " .
'--disable-shared ' .
'--enable-static ' .
'--enable-hardware-optimizations ' .

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
@@ -13,34 +14,31 @@ class libxml2 extends MacOSLibraryBase
/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build()
protected function build(): void
{
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
[$lib, $include, $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 ' .
"{$this->builder->makeCmakeArgs()} " .
'-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}")
->exec('make install');
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
}
}

View File

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

View File

@@ -20,11 +20,18 @@ declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
class nghttp2 extends MacOSLibraryBase
{
public const NAME = 'nghttp2';
protected function build()
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'zlib' => null,
@@ -46,10 +53,10 @@ class nghttp2 extends MacOSLibraryBase
shell()->cd($this->source_dir)
->exec(
"{$this->builder->configure_env} " . ' ./configure ' .
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->gnu_arch}-apple-darwin " .
"--host={$this->builder->getOption('gnu-arch')}-apple-darwin " .
'--enable-lib-only ' .
'--with-boost=no ' .
$args . ' ' .

View File

@@ -20,11 +20,20 @@ declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
class openssl extends MacOSLibraryBase
{
public const NAME = 'openssl';
protected function build()
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
protected function build(): void
{
[$lib,,$destdir] = SEPARATED_PATH;
@@ -39,11 +48,11 @@ 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 ' .
"darwin64-{$this->builder->arch}-cc"
"darwin64-{$this->builder->getOption('arch')}-cc"
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")

View File

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

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

@@ -4,6 +4,4 @@ declare(strict_types=1);
namespace SPC\builder\traits;
trait LibraryTrait
{
}
trait LibraryTrait {}

View File

@@ -7,31 +7,24 @@ namespace SPC\builder\traits;
use SPC\builder\linux\LinuxBuilder;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
trait UnixBuilderTrait
{
/** @var string 设置的命令前缀,设置为 set -x 可以在终端打印命令 */
public string $set_x = 'set -x';
/** @var string C 编译器命令 */
public string $cc;
/** @var string C++ 编译器命令 */
public string $cxx;
/** @var string cflags 参数 */
/** @var string cflags */
public string $arch_c_flags;
/** @var string C++ flags 参数 */
/** @var string C++ flags */
public string $arch_cxx_flags;
/** @var string cmake toolchain file */
public string $cmake_toolchain_file;
/** @var string configure 环境依赖的变量 */
public string $configure_env;
/**
* @throws WrongUsageException
* @throws FileSystemException
*/
public function getAllStaticLibFiles(): array
{
$libs = [];
@@ -70,18 +63,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();
}
}
@@ -125,7 +110,7 @@ trait UnixBuilderTrait
}
/**
* 清理编译好的文件
* Run php clean
*
* @throws RuntimeException
*/
@@ -140,12 +125,35 @@ trait UnixBuilderTrait
*/
public function makeCmakeArgs(): string
{
[$lib, $include] = SEPARATED_PATH;
$extra = $this instanceof LinuxBuilder ? '-DCMAKE_C_COMPILER=' . $this->cc . ' ' : '';
return $extra . '-DCMAKE_BUILD_TYPE=Release ' .
$extra = $this instanceof LinuxBuilder ? '-DCMAKE_C_COMPILER=' . getenv('CC') . ' ' : '';
return $extra .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DCMAKE_INSTALL_PREFIX=/ ' .
"-DCMAKE_INSTALL_LIBDIR={$lib} " .
"-DCMAKE_INSTALL_INCLUDEDIR={$include} " .
'-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;
}
}

View File

@@ -7,6 +7,7 @@ namespace SPC\builder\traits;
use SPC\builder\LibraryBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
trait UnixLibraryTrait
@@ -16,6 +17,7 @@ trait UnixLibraryTrait
/**
* @throws RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string
{
@@ -43,6 +45,11 @@ trait UnixLibraryTrait
return implode($sep, $ret);
}
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function makeAutoconfEnv(string $prefix = null): string
{
if ($prefix === null) {
@@ -59,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) {
@@ -74,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);
}
}
@@ -82,7 +90,7 @@ trait UnixLibraryTrait
* remove libtool archive files
*
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function cleanLaFiles(): void
{

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace SPC\builder\traits;
use SPC\exception\FileSystemException;
use SPC\store\FileSystem;
/**
@@ -14,11 +15,12 @@ trait UnixSystemUtilTrait
/**
* 生成 toolchain.cmake用于 cmake 构建
*
* @param string $os 操作系统代号
* @param string $target_arch 目标架构
* @param string $cflags CFLAGS 参数
* @param null|string $cc CC 参数(默认空)
* @param null|string $cxx CXX 参数(默认空)
* @param string $os 操作系统代号
* @param string $target_arch 目标架构
* @param string $cflags CFLAGS 参数
* @param null|string $cc CC 参数(默认空)
* @param null|string $cxx CXX 参数(默认空)
* @throws FileSystemException
*/
public static function makeCmakeToolchainFile(
string $os,
@@ -76,4 +78,20 @@ CMAKE;
}
return null;
}
/**
* @param array $vars Variables, like: ["CFLAGS" => "-Ixxx"]
* @return string like: CFLAGS="-Ixxx"
*/
public static function makeEnvVarString(array $vars): string
{
$str = '';
foreach ($vars as $key => $value) {
if ($str !== '') {
$str .= ' ';
}
$str .= $key . '=' . escapeshellarg($value);
}
return $str;
}
}

View File

@@ -4,16 +4,22 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait brotli
{
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
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 ' .
'..'
@@ -22,9 +28,9 @@ trait brotli
->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');
->exec('ln -s libbrotlicommon.a libbrotlicommon-static.a')
->exec('ln -s libbrotlidec.a libbrotlidec-static.a')
->exec('ln -s libbrotlienc.a libbrotlienc-static.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);

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