mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-02 22:35:43 +08:00
Compare commits
495 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cb1764439 | ||
|
|
847535721c | ||
|
|
e3c542d9df | ||
|
|
b4ed4ea956 | ||
|
|
99aadd3e73 | ||
|
|
c77dc1af6c | ||
|
|
9fd56987ef | ||
|
|
1e494a2213 | ||
|
|
da6d9ffb4b | ||
|
|
d3a001d808 | ||
|
|
d445668d9f | ||
|
|
32f14e16c8 | ||
|
|
46984b6df1 | ||
|
|
96c3e6b935 | ||
|
|
8092f1e481 | ||
|
|
632f904f30 | ||
|
|
8358a985b3 | ||
|
|
e21b5676e7 | ||
|
|
94b3afe6bc | ||
|
|
e4d8e5e4d2 | ||
|
|
88796bc017 | ||
|
|
e23daaa355 | ||
|
|
71017361b5 | ||
|
|
d202de3f50 | ||
|
|
03510073c6 | ||
|
|
8e58592a6e | ||
|
|
96dd5ba87b | ||
|
|
d4c0290195 | ||
|
|
f5d1df5407 | ||
|
|
9664709f21 | ||
|
|
b46655ecfe | ||
|
|
842e0add29 | ||
|
|
254764761d | ||
|
|
5f6c1a0f40 | ||
|
|
d5dcd193cf | ||
|
|
5012da96be | ||
|
|
df0e37cd0f | ||
|
|
4ab7b6bfdc | ||
|
|
f498250001 | ||
|
|
3945ac037b | ||
|
|
b0d8b00fcc | ||
|
|
62b0bf8af0 | ||
|
|
905e080770 | ||
|
|
097ecd3fb0 | ||
|
|
b9359759dd | ||
|
|
50fe366c42 | ||
|
|
9dd89e6b02 | ||
|
|
c03220d1ee | ||
|
|
9db843ab66 | ||
|
|
304973d9bc | ||
|
|
ab386f820c | ||
|
|
4adf1f5e2e | ||
|
|
b4ae87585c | ||
|
|
ae3298472d | ||
|
|
d241cb993e | ||
|
|
8376122634 | ||
|
|
a30e054d7d | ||
|
|
78f4317660 | ||
|
|
3ac3dab6c8 | ||
|
|
1a7e436ee1 | ||
|
|
f11b36ab3c | ||
|
|
e2ef195a84 | ||
|
|
645e2a9fc2 | ||
|
|
d59b8457c6 | ||
|
|
a2d1262cbf | ||
|
|
2f9a1e8601 | ||
|
|
b239f60fe4 | ||
|
|
983521e225 | ||
|
|
aeed04a5ec | ||
|
|
faed569e8a | ||
|
|
49ddb3ec13 | ||
|
|
71c0387ab0 | ||
|
|
e5d2d5e689 | ||
|
|
be2394b39b | ||
|
|
158298b96c | ||
|
|
ffa84f8b91 | ||
|
|
0954ddcc96 | ||
|
|
d9bd96af71 | ||
|
|
2649dcd05c | ||
|
|
939db75268 | ||
|
|
227bf73870 | ||
|
|
05e3898e7a | ||
|
|
9777c9aa93 | ||
|
|
b8d8461e61 | ||
|
|
b977543c72 | ||
|
|
4d87cd11cc | ||
|
|
957daf0547 | ||
|
|
3dae904122 | ||
|
|
e835196972 | ||
|
|
52ed0e2cee | ||
|
|
1e898d271d | ||
|
|
39754cde59 | ||
|
|
a6f7b938e1 | ||
|
|
0ad501af9a | ||
|
|
73035067e3 | ||
|
|
421b3830b6 | ||
|
|
59dcb905fe | ||
|
|
d222190fc7 | ||
|
|
06e9864d19 | ||
|
|
0b1a321615 | ||
|
|
9ee7d7769a | ||
|
|
2440a65d8e | ||
|
|
839931d65f | ||
|
|
2591b48abe | ||
|
|
2549597871 | ||
|
|
2064172bed | ||
|
|
dc19d0c61d | ||
|
|
05c6dc6dab | ||
|
|
4b653bc293 | ||
|
|
1c3476b8e9 | ||
|
|
61ca501c2a | ||
|
|
d916feec62 | ||
|
|
0dcecf6ca4 | ||
|
|
a04deb458f | ||
|
|
34f810571e | ||
|
|
5ab4d140d5 | ||
|
|
104778d17a | ||
|
|
5f8641f417 | ||
|
|
17b69ec1e9 | ||
|
|
8de942c274 | ||
|
|
a7d5a48b48 | ||
|
|
fdc00301c0 | ||
|
|
7620d5900e | ||
|
|
e973fe743e | ||
|
|
149e844d59 | ||
|
|
12ea3218e8 | ||
|
|
f9e7af1c9a | ||
|
|
8d2f6baaa2 | ||
|
|
25a2684e5a | ||
|
|
13e0e12181 | ||
|
|
81df124b42 | ||
|
|
d3d8230a09 | ||
|
|
d4eb199504 | ||
|
|
6562bc200c | ||
|
|
0b322f494b | ||
|
|
ceed1005cc | ||
|
|
6efcb75224 | ||
|
|
a45f2f357d | ||
|
|
0c2de9f936 | ||
|
|
ac005d1e0f | ||
|
|
fce0c2f896 | ||
|
|
a0a0b01cc3 | ||
|
|
450ec21c90 | ||
|
|
7b2c3ac12d | ||
|
|
8d4a375400 | ||
|
|
eda3a9b486 | ||
|
|
5b581a54aa | ||
|
|
5549068275 | ||
|
|
daf0d2eb32 | ||
|
|
bff1a6168f | ||
|
|
54ba41d1b3 | ||
|
|
cb5e13e39a | ||
|
|
269e95e0fe | ||
|
|
dabdb518ce | ||
|
|
eac4763d82 | ||
|
|
fa0ea5443d | ||
|
|
31c71f180b | ||
|
|
5c7552f826 | ||
|
|
fa1bd340f1 | ||
|
|
539aaefd72 | ||
|
|
d54bf42ba8 | ||
|
|
cbfbec41b4 | ||
|
|
db7532cad3 | ||
|
|
6b8df97282 | ||
|
|
584f96484c | ||
|
|
e1e5515694 | ||
|
|
d3ff6fd8c0 | ||
|
|
6bcda6a5a0 | ||
|
|
3828ba7c77 | ||
|
|
a632caed54 | ||
|
|
1e0265e673 | ||
|
|
a39cd9a238 | ||
|
|
2d437952f2 | ||
|
|
7e5b0d6f43 | ||
|
|
cf198e0f0a | ||
|
|
248918e458 | ||
|
|
c4cfc01b88 | ||
|
|
339c03adb2 | ||
|
|
48551cc602 | ||
|
|
e0550b4a45 | ||
|
|
93a55e87d5 | ||
|
|
e68f1ce3fe | ||
|
|
3573007485 | ||
|
|
b961c34d9a | ||
|
|
33e1759caa | ||
|
|
d72ee53cb4 | ||
|
|
a5fa46b82d | ||
|
|
bc15de0dfb | ||
|
|
1f7bdb94fb | ||
|
|
ea64e50ce5 | ||
|
|
ed8b606761 | ||
|
|
b722b3edd4 | ||
|
|
9266a4c504 | ||
|
|
d8ce5f69f4 | ||
|
|
0cfac49560 | ||
|
|
3e9ddc8e01 | ||
|
|
83dd1bd5c3 | ||
|
|
42f448cf17 | ||
|
|
f0319de93e | ||
|
|
c7e9294908 | ||
|
|
c1758bd754 | ||
|
|
bba2d0dbf7 | ||
|
|
00689b951b | ||
|
|
98b7164de3 | ||
|
|
d3e4470e1f | ||
|
|
433c91b68d | ||
|
|
3185d98b1a | ||
|
|
e603e441e7 | ||
|
|
b1bf8bb848 | ||
|
|
b1958ea0c4 | ||
|
|
930849758c | ||
|
|
7ee431725c | ||
|
|
7c866cb0e3 | ||
|
|
266108b25f | ||
|
|
82e3a86f17 | ||
|
|
ba18819b41 | ||
|
|
6b23c90bba | ||
|
|
edfd371973 | ||
|
|
8ed95602e2 | ||
|
|
cee1346bec | ||
|
|
400007c206 | ||
|
|
443e615066 | ||
|
|
ed22945ae2 | ||
|
|
5db084ba0e | ||
|
|
c7b3275a72 | ||
|
|
41cd319d4e | ||
|
|
1c307d0d59 | ||
|
|
9dcda873f3 | ||
|
|
4400c6271e | ||
|
|
0589690eaa | ||
|
|
5449e05898 | ||
|
|
93e64e1d5a | ||
|
|
7a2e237069 | ||
|
|
c95da8c150 | ||
|
|
89afd44344 | ||
|
|
04f100da8b | ||
|
|
2e24976b71 | ||
|
|
36a30cc23b | ||
|
|
869130572f | ||
|
|
2bb08af89b | ||
|
|
b3d41ef969 | ||
|
|
9c904409cd | ||
|
|
859182abff | ||
|
|
c0e88bf4bd | ||
|
|
79bcd35c0e | ||
|
|
2e637524fc | ||
|
|
a2c687599f | ||
|
|
d09a3074ad | ||
|
|
5736964b2e | ||
|
|
edaa82b8c5 | ||
|
|
2a6441a500 | ||
|
|
3bd5a05725 | ||
|
|
a6fbcc954e | ||
|
|
66cebb5fe4 | ||
|
|
e3671387fc | ||
|
|
f7c73c00af | ||
|
|
74536bd2e1 | ||
|
|
a8f2b0096b | ||
|
|
2d192fc390 | ||
|
|
031da802f3 | ||
|
|
5fdeb33031 | ||
|
|
347da67b71 | ||
|
|
65ef9ab20c | ||
|
|
3d64c6349e | ||
|
|
31cf9bb5b7 | ||
|
|
7c4a991c0e | ||
|
|
07f943af7e | ||
|
|
fbf5c958d0 | ||
|
|
672a4102cd | ||
|
|
52d61365b7 | ||
|
|
ff74f0cdaf | ||
|
|
dccfde9f39 | ||
|
|
5db23e1db7 | ||
|
|
b1ae48a209 | ||
|
|
3604ea6d67 | ||
|
|
967292be5c | ||
|
|
4f5335bba4 | ||
|
|
ac7a236763 | ||
|
|
1bf39c1f06 | ||
|
|
678283cd98 | ||
|
|
97a76aba8a | ||
|
|
af464e7b3d | ||
|
|
5ee7dd9200 | ||
|
|
9e1c2c6dd5 | ||
|
|
d29ba16cbc | ||
|
|
7bef45eb32 | ||
|
|
772ab77d2e | ||
|
|
58897c6941 | ||
|
|
8230e1bcec | ||
|
|
279a1dab4b | ||
|
|
9fb5173e3e | ||
|
|
0b37080cdd | ||
|
|
8747266df6 | ||
|
|
12cc422d5b | ||
|
|
bfc56cff72 | ||
|
|
d5405ce436 | ||
|
|
e158cc5886 | ||
|
|
aee040d6a4 | ||
|
|
e637cce6f2 | ||
|
|
98b906db40 | ||
|
|
7625f585d2 | ||
|
|
ed8837fe9f | ||
|
|
a5754125a8 | ||
|
|
6b848da4dd | ||
|
|
2768dc0c40 | ||
|
|
90b2e5568c | ||
|
|
b4f9235cb6 | ||
|
|
86ce7e9d25 | ||
|
|
2e47e8af6b | ||
|
|
d40f2cafec | ||
|
|
e84a246dd2 | ||
|
|
98f32ae0f0 | ||
|
|
5499109278 | ||
|
|
9a5b02692d | ||
|
|
970a74896a | ||
|
|
29179ecb84 | ||
|
|
5e0cccfe3d | ||
|
|
ed52ec9ee1 | ||
|
|
f25d2d5db4 | ||
|
|
e00908d8cb | ||
|
|
c24dc8f518 | ||
|
|
d381e48605 | ||
|
|
8dcec73929 | ||
|
|
9b9644fe63 | ||
|
|
8a70da6291 | ||
|
|
c84eb723ec | ||
|
|
5934e5e881 | ||
|
|
99150e2cef | ||
|
|
8191444fe9 | ||
|
|
5cfba6e83b | ||
|
|
4e9b8980d0 | ||
|
|
c800a53f77 | ||
|
|
6cc7e6cff6 | ||
|
|
d56c060863 | ||
|
|
b6409bded4 | ||
|
|
ca1189b6ca | ||
|
|
75b9d66698 | ||
|
|
6dfd35348f | ||
|
|
0007043f4a | ||
|
|
da1cbeb79c | ||
|
|
a83a457905 | ||
|
|
a4dc177621 | ||
|
|
a7265bf624 | ||
|
|
64dfb57366 | ||
|
|
658e8e74bd | ||
|
|
46b0ecf3fa | ||
|
|
830f379bf6 | ||
|
|
c9b544f8c4 | ||
|
|
11af370fe1 | ||
|
|
1e11559c4b | ||
|
|
8b188bd1b9 | ||
|
|
e0e3bc6d97 | ||
|
|
dbb566ac7c | ||
|
|
37b9704fbb | ||
|
|
c225aeffed | ||
|
|
2e3544f296 | ||
|
|
ce60a9c804 | ||
|
|
b6c0b998b3 | ||
|
|
6277539a79 | ||
|
|
9520d68cda | ||
|
|
812c71f31f | ||
|
|
b3cc360eeb | ||
|
|
39fe6fa081 | ||
|
|
243ee63283 | ||
|
|
24c946d687 | ||
|
|
84d1c789bd | ||
|
|
a983667b90 | ||
|
|
8d9cace469 | ||
|
|
e9d3e48f90 | ||
|
|
ed53394389 | ||
|
|
8893d08ba9 | ||
|
|
5a13daee39 | ||
|
|
c1e9cd2ea3 | ||
|
|
30213da70a | ||
|
|
5d363bdb0b | ||
|
|
630c0d3a5d | ||
|
|
56caef78e3 | ||
|
|
29be3a2e39 | ||
|
|
fbe149bcac | ||
|
|
92cafb36f6 | ||
|
|
8636f2e7c9 | ||
|
|
8f43a09533 | ||
|
|
654c5cba0c | ||
|
|
f9685b82a1 | ||
|
|
f2371d3702 | ||
|
|
fe39aecd72 | ||
|
|
68d176ad26 | ||
|
|
d7627dd81a | ||
|
|
a4e173f16d | ||
|
|
1437be3a9d | ||
|
|
059c32e59c | ||
|
|
e3a4cd6e1d | ||
|
|
dd9a5d8316 | ||
|
|
3b83c1fa7b | ||
|
|
ff128df76b | ||
|
|
cd04a9ea4f | ||
|
|
3b793005fe | ||
|
|
87e073a0b9 | ||
|
|
db8aa15677 | ||
|
|
6ed9749732 | ||
|
|
4e99211bc3 | ||
|
|
824748c2a7 | ||
|
|
fe6a98b30d | ||
|
|
49149cebf1 | ||
|
|
7b6a1b4212 | ||
|
|
965e7a25e2 | ||
|
|
0c3885c33d | ||
|
|
be32190829 | ||
|
|
f1d5916090 | ||
|
|
b2ea479fac | ||
|
|
16cc5df66d | ||
|
|
a63e3f4575 | ||
|
|
6b061e6332 | ||
|
|
4a17491aaa | ||
|
|
06f29712e2 | ||
|
|
4b1d59c5a9 | ||
|
|
1a81fe6a0d | ||
|
|
c63136d484 | ||
|
|
4b500f2dd8 | ||
|
|
9da20497cc | ||
|
|
5efc15b404 | ||
|
|
fa0740f216 | ||
|
|
52430cbdde | ||
|
|
01c4538ce0 | ||
|
|
3183ecceaf | ||
|
|
dd2e7cc129 | ||
|
|
adfa620ef4 | ||
|
|
1a32ddc70a | ||
|
|
4bfca6fe93 | ||
|
|
dbec043894 | ||
|
|
727d78a689 | ||
|
|
9b1e784604 | ||
|
|
50d44d8310 | ||
|
|
3b300698f3 | ||
|
|
899eb94b8b | ||
|
|
451a0c0e34 | ||
|
|
085c1a159c | ||
|
|
ca3f8a350d | ||
|
|
5025850f71 | ||
|
|
fe2f658e08 | ||
|
|
00a49c662b | ||
|
|
be8eb90b86 | ||
|
|
54e98666e7 | ||
|
|
e8b277ad0d | ||
|
|
3bd037f48f | ||
|
|
4d0e825b43 | ||
|
|
b14179a8de | ||
|
|
01111c51ee | ||
|
|
e7230d9f50 | ||
|
|
c22c5617ad | ||
|
|
cae7bb1dda | ||
|
|
c0830a9e1f | ||
|
|
33798ff108 | ||
|
|
8d348b9e14 | ||
|
|
3d2f6e4c3a | ||
|
|
88e9639482 | ||
|
|
0381a1c412 | ||
|
|
fdc3a7a04b | ||
|
|
6de5c1dab0 | ||
|
|
dc28ce0899 | ||
|
|
9286153742 | ||
|
|
f90892c92f | ||
|
|
5359f3a79a | ||
|
|
42fbf18bba | ||
|
|
ed227ce00e | ||
|
|
6c49d35aec | ||
|
|
238fd7fc74 | ||
|
|
1ebc58664e | ||
|
|
bcf64cbeef | ||
|
|
dc12d4d982 | ||
|
|
42e5877a7f | ||
|
|
a8924ac4fe | ||
|
|
7fb27c0c29 | ||
|
|
3d9a3194b2 | ||
|
|
e7e0ac006f | ||
|
|
cf35a270bb | ||
|
|
3e7ef49bde | ||
|
|
100d31791a | ||
|
|
15905c063a | ||
|
|
4c46f6a762 | ||
|
|
f4327c8c81 | ||
|
|
4a4b0e209c | ||
|
|
60e06737d7 | ||
|
|
d326154241 | ||
|
|
4766ae146f | ||
|
|
21a4ba7478 | ||
|
|
dfdeab70f1 | ||
|
|
c8fa767576 | ||
|
|
9c57ed6439 | ||
|
|
585826b438 | ||
|
|
cf22949f3b | ||
|
|
0569c69634 | ||
|
|
1b734073b0 | ||
|
|
47d068e6d3 | ||
|
|
4537bfb247 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -10,4 +10,6 @@ liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
# noinspection YAMLSchemaValidation
|
||||
buy_me_a_coffee: crazywhalecc
|
||||
custom: 'https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md' # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||
|
||||
12
.github/pull_request_template.md
vendored
Normal file
12
.github/pull_request_template.md
vendored
Normal 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`.
|
||||
5
.github/workflows/build-linux-arm.yml
vendored
5
.github/workflows/build-linux-arm.yml
vendored
@@ -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 }}
|
||||
|
||||
12
.github/workflows/build-linux-x86_64.yml
vendored
12
.github/workflows/build-linux-x86_64.yml
vendored
@@ -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 }}
|
||||
|
||||
127
.github/workflows/build-macos-aarch64.yml
vendored
Normal file
127
.github/workflows/build-macos-aarch64.yml
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
name: CI on arm64 macOS
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
description: php version to compile
|
||||
default: '8.2'
|
||||
type: choice
|
||||
options:
|
||||
- '8.3'
|
||||
- '8.2'
|
||||
- '8.1'
|
||||
- '8.0'
|
||||
- '7.4'
|
||||
build-cli:
|
||||
description: build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: build fpm binary
|
||||
type: boolean
|
||||
extensions:
|
||||
description: extensions to compile (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
debug:
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build ${{ inputs.version }} on macOS arm64
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Install macOS missing packages and mark os suffix
|
||||
- run: |
|
||||
brew install automake gzip
|
||||
echo "SPC_BUILD_OS=macos" >> $GITHUB_ENV
|
||||
|
||||
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
tools: pecl, composer
|
||||
extensions: curl, openssl, mbstring, tokenizer
|
||||
ini-values: memory_limit=-1
|
||||
|
||||
|
||||
# Cache composer dependencies
|
||||
- id: cache-composer-deps
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: vendor
|
||||
key: composer-dependencies
|
||||
|
||||
# If there's no Composer cache, install dependencies
|
||||
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
|
||||
run: composer update --no-dev --classmap-authoritative
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
|
||||
|
||||
# With or without debug
|
||||
- if: inputs.debug == true
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
|
||||
# With target select: cli, micro or both
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
|
||||
|
||||
# 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 }} --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 }}
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php
|
||||
|
||||
# Upload micro self-extracted executable
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/micro.sfx
|
||||
|
||||
# Upload fpm executable
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php-fpm
|
||||
|
||||
# Upload extensions metadata
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: license-files
|
||||
path: buildroot/license/
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: build-meta
|
||||
path: |
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
7
.github/workflows/build-macos-x86_64.yml
vendored
7
.github/workflows/build-macos-x86_64.yml
vendored
@@ -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 }}
|
||||
|
||||
40
.github/workflows/download-cache.yml
vendored
40
.github/workflows/download-cache.yml
vendored
@@ -1,40 +0,0 @@
|
||||
name: archive download sources weekly
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: "* 14 * * 5"
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
download:
|
||||
name: cache download sources
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: [ "8.0", "8.1", "8.2" ]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# Cache composer dependencies
|
||||
- id: cache-composer-deps
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: vendor
|
||||
key: composer-dependencies
|
||||
|
||||
# If there's no Composer cache, install dependencies
|
||||
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
|
||||
run: composer update --no-dev
|
||||
|
||||
# If there's no dependencies cache, fetch sources, with or without debug
|
||||
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||
run: ./bin/spc download --with-php=${{ matrix.php-version }} --all --debug
|
||||
|
||||
# Upload downloaded files
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: download-files-${{ matrix.php-version }}
|
||||
path: downloads/
|
||||
125
.github/workflows/release-build.yml
vendored
Normal file
125
.github/workflows/release-build.yml
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
name: Build SPC Binary
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-release-artifacts:
|
||||
name: "Build SPC Binary"
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
- "8.2"
|
||||
micro-version:
|
||||
- "8.2.16"
|
||||
operating-system:
|
||||
- "linux-x86_64"
|
||||
- "macos-x86_64"
|
||||
- "linux-aarch64"
|
||||
- "macos-aarch64"
|
||||
- "windows-x64"
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v4"
|
||||
|
||||
- if: inputs.debug == true
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
|
||||
- name: "Install PHP for official runners"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: none
|
||||
tools: composer:v2
|
||||
php-version: "${{ matrix.php-version }}"
|
||||
ini-values: memory_limit=-1
|
||||
|
||||
- name: "Get Composer Cache Directory"
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: "Cache Composer dependencies"
|
||||
uses: "actions/cache@v3"
|
||||
with:
|
||||
path: "${{ steps.composer-cache.outputs.dir }}"
|
||||
key: "php-${{ matrix.php-version }}-locked-composer-${{ hashFiles('**/composer.lock') }}"
|
||||
restore-keys: |
|
||||
php-${{ matrix.php-version }}-locked-composer
|
||||
|
||||
- name: "Install Locked Dependencies"
|
||||
run: "composer install --no-interaction --no-progress"
|
||||
|
||||
- name: "Build PHAR File"
|
||||
run: "composer build:phar"
|
||||
|
||||
- name: "Download minimal combination"
|
||||
run: |
|
||||
if [ "${{ matrix.operating-system }}" = "windows-x64" ]; then
|
||||
curl https://dl.static-php.dev/static-php-cli/windows/spc-min/php-${{ matrix.micro-version }}-micro-win.zip -o tmp.zip
|
||||
unzip tmp.zip
|
||||
else
|
||||
curl https://dl.static-php.dev/static-php-cli/minimal/php-${{ matrix.micro-version }}-micro-${{ matrix.operating-system }}.tar.gz -o tmp.tgz
|
||||
tar -zxvf tmp.tgz
|
||||
fi
|
||||
|
||||
- name: "Generate Executable"
|
||||
run: |
|
||||
bin/spc micro:combine spc.phar -M micro.sfx -O spc -I "memory_limit=2G"
|
||||
if [ "${{ matrix.operating-system }}" = "windows-x64" ]; then
|
||||
mv spc spc.exe
|
||||
else
|
||||
chmod +x spc
|
||||
fi
|
||||
|
||||
- name: "Archive Executable"
|
||||
run: |
|
||||
if [ "${{ matrix.operating-system }}" != "windows-x64" ]; then
|
||||
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
|
||||
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
|
||||
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
|
||||
if [ "${{ matrix.operating-system }}" == "linux-x86_64" ]; then
|
||||
./spc dev:extensions
|
||||
fi
|
||||
else
|
||||
echo "filename=spc-${{ matrix.operating-system }}.exe" >> $GITHUB_ENV
|
||||
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: "Copy file"
|
||||
run: |
|
||||
if [ "${{ matrix.operating-system }}" != "windows-x64" ]; then
|
||||
mkdir dist/ && cp ${{ env.filename }} dist/ && cp spc dist/spc-$OS
|
||||
else
|
||||
mkdir dist/ && cp spc.exe dist/${{ env.filename }}
|
||||
echo "SUFFIX=.exe" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: upload binaries to release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: ${{startsWith(github.ref, 'refs/tags/') }}
|
||||
with:
|
||||
files: dist/${{ env.filename }}
|
||||
|
||||
- name: "Deploy to Self-Hosted Server"
|
||||
if: github.repository == 'crazywhalecc/static-php-cli'
|
||||
uses: easingthemes/ssh-deploy@main
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SERVER_SECRET_KEY }}
|
||||
ARGS: "-rltgoDzvO"
|
||||
SOURCE: "dist/"
|
||||
REMOTE_HOST: ${{ secrets.DEPLOY_SERVER_HOST }}
|
||||
REMOTE_PORT: ${{ secrets.DEPLOY_SERVER_PORT }}
|
||||
REMOTE_USER: ${{ secrets.DEPLOY_SERVER_USER }}
|
||||
TARGET: ${{ secrets.DEPLOY_SERVER_TARGET_SPC_NIGHTLY }}
|
||||
|
||||
- name: "Upload Artifact"
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
path: spc${{ env.SUFFIX }}
|
||||
name: spc-${{ matrix.operating-system }}${{ env.SUFFIX }}
|
||||
171
.github/workflows/tests.yml
vendored
Normal file
171
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/globals/test-extensions.php'
|
||||
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
|
||||
- windows-latest
|
||||
- macos-14
|
||||
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: "Use test token if exists"
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: |
|
||||
if [ "${{ secrets.TEST_GH_TOKEN }}" != "" ]; then
|
||||
echo "GITHUB_TOKEN=${{ secrets.TEST_GH_TOKEN }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: "Cache Composer packages"
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ matrix.php }}-dependencies
|
||||
|
||||
- name: "Install Dependencies"
|
||||
run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
|
||||
- name: "Run Build Tests (doctor)"
|
||||
run: bin/spc doctor --auto-fix
|
||||
|
||||
- name: "Run Build Tests (download)"
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_on: error
|
||||
command: |
|
||||
bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --for-libs="$(php src/globals/test-extensions.php libs)" --with-php=${{ matrix.php }} --ignore-cache-sources=php-src --debug
|
||||
|
||||
- name: "Run Build Tests (build)"
|
||||
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug
|
||||
43
.github/workflows/update-docs-config.yml
vendored
Normal file
43
.github/workflows/update-docs-config.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
name: Update Docs Config
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'config/**.json'
|
||||
|
||||
jobs:
|
||||
update-docs-config:
|
||||
name: "Update Docs Config"
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'crazywhalecc/static-php-cli'
|
||||
steps:
|
||||
- name: "Checkout static-php-cli"
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main
|
||||
path: static-php-cli
|
||||
|
||||
- name: "Checkout static-php-cli-docs"
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: static-php/static-php-cli-docs
|
||||
ref: master
|
||||
token: ${{ secrets.DOCS_REPO_TOKEN }}
|
||||
path: static-php-cli-docs
|
||||
|
||||
- name: "Set up Git"
|
||||
run: |
|
||||
git config --global user.email "actions@github.com"
|
||||
git config --global user.name "GitHub Actions"
|
||||
|
||||
- name: "Copy Config Files"
|
||||
run: cp -r static-php-cli/config/* static-php-cli-docs/docs/.vitepress/config/
|
||||
|
||||
- name: "Commit and Push Changes"
|
||||
run: |
|
||||
cd static-php-cli-docs
|
||||
git add -A
|
||||
git commit -m "Sync config files from main"
|
||||
git push origin master
|
||||
19
.gitignore
vendored
19
.gitignore
vendored
@@ -4,8 +4,7 @@ docker/libraries/
|
||||
docker/extensions/
|
||||
docker/source/
|
||||
|
||||
# Composer file
|
||||
composer.lock
|
||||
# Vendor files
|
||||
/vendor/
|
||||
|
||||
# default source extract directory
|
||||
@@ -17,11 +16,21 @@ composer.lock
|
||||
# default source build root directory
|
||||
/buildroot/
|
||||
|
||||
# php cs fixer cache file
|
||||
# default package root directory
|
||||
/pkgroot/
|
||||
|
||||
# tools cache files
|
||||
.php-cs-fixer.cache
|
||||
.phpunit.result.cache
|
||||
|
||||
# exclude self-runtime
|
||||
/bin/*
|
||||
!/bin/spc
|
||||
!/bin/setup-runtime
|
||||
!/bin/spc*
|
||||
!/bin/setup-runtime*
|
||||
!/bin/spc-alpine-docker
|
||||
|
||||
# exclude windows build tools
|
||||
/php-sdk-binary-tools/
|
||||
|
||||
# default test directory
|
||||
/tests/var/
|
||||
|
||||
@@ -63,7 +63,8 @@ return (new PhpCsFixer\Config())
|
||||
'phpdoc_summary' => false,
|
||||
'php_unit_test_class_requires_covers' => false,
|
||||
'phpdoc_var_without_name' => false,
|
||||
'fully_qualified_strict_types' => false,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()->in(__DIR__ . '/src')
|
||||
PhpCsFixer\Finder::create()->in([__DIR__ . '/src', __DIR__ . '/tests/SPC'])
|
||||
);
|
||||
|
||||
255
README-en.md
255
README-en.md
@@ -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">
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
|
||||
[]()
|
||||
[]()
|
||||
|
||||
> 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.1 and `mbstring`, `pcntl` extension.
|
||||
|
||||
Here is the architecture support status, where `CI` represents support for GitHub Action builds,
|
||||
`Local` represents support for local builds, and blank represents not currently supported.
|
||||
|
||||
| | x86_64 | aarch64 |
|
||||
|---------|-----------|-----------|
|
||||
| macOS | CI, Local | Local |
|
||||
| Linux | CI, Local | CI, Local |
|
||||
| Windows | | |
|
||||
|
||||
> macOS-arm64 is not supported for GitHub Actions, if you are going to build on arm, you can build it manually on your own machine.
|
||||
|
||||
Currently supported PHP versions for compilation are: `7.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).
|
||||
|
||||
291
README-zh.md
Executable file
291
README-zh.md
Executable file
@@ -0,0 +1,291 @@
|
||||
# static-php-cli
|
||||
|
||||
[](README.md)
|
||||
[](README-zh.md)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/releases)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
|
||||
[](https://static-php.dev/zh/guide/extensions.html)
|
||||
|
||||
**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。
|
||||
|
||||
目前 static-php-cli 支持 `cli`、`fpm`、`embed` 和 `micro` SAPI。
|
||||
|
||||
**static-php-cli**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。
|
||||
|
||||
## 特性
|
||||
|
||||
static-php-cli(简称 `spc`)有许多特性:
|
||||
|
||||
- :handbag: 构建独立的单文件 PHP 解释器,无需任何依赖
|
||||
- :hamburger: 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自执行二进制(将 PHP 代码和 PHP 解释器打包为一个文件)
|
||||
- :pill: 提供一键检查和修复编译环境的 Doctor 模块
|
||||
- :zap: 支持多个系统:`Linux`、`macOS`、`FreeBSD`、`Windows`
|
||||
- :wrench: 高度自定义的代码 patch 功能
|
||||
- :books: 自带编译依赖管理
|
||||
- 📦 提供由自身编译的独立 `spc` 二进制(使用 spc 和 [box](https://github.com/box-project/box) 构建)
|
||||
- :fire: 支持大量 [扩展](https://static-php.dev/zh/guide/extensions.html)
|
||||
- :floppy_disk: 整合 UPX 工具(减小二进制文件体积)
|
||||
|
||||
**静态 php-cli:**
|
||||
|
||||
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
|
||||
|
||||
**使用 phpmicro 打包 PHP 代码:**
|
||||
|
||||
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
|
||||
|
||||
## 文档
|
||||
|
||||
目前 README 编写了基本用法。有关 static-php-cli 所有的功能,请点击这里查看文档:<https://static-php.dev>。
|
||||
|
||||
## 直接下载
|
||||
|
||||
如果你不想自行编译 PHP,可以从本项目现有的示例 Action 下载 Artifact,也可以从自托管的服务器下载。
|
||||
|
||||
- [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/):common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 22MB 左右。
|
||||
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/):bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 70MB 左右。
|
||||
- [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/):minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 6MB 左右。
|
||||
|
||||
对于 Windows 系统,目前支持的扩展较少,故仅提供 SPC 自身运行的最小扩展组合的 `cli` 和 `micro`:[扩展组合 - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/)。
|
||||
|
||||
## 使用 static-php-cli 构建 PHP
|
||||
|
||||
### 编译环境需求
|
||||
|
||||
- PHP >= 8.1(这是 spc 自身需要的版本,不是支持的构建版本)
|
||||
- 扩展:`mbstring,tokenizer,phar`
|
||||
- 系统安装了 `curl` 和 `git`
|
||||
|
||||
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
||||
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含上面提到的扩展和 PHP 版本大于等于 8.1 即可。
|
||||
|
||||
下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
|
||||
|
||||
| | x86_64 | aarch64 |
|
||||
|---------|----------------------|----------------------|
|
||||
| macOS | :octocat: :computer: | :octocat: :computer: |
|
||||
| Linux | :octocat: :computer: | :octocat: :computer: |
|
||||
| Windows | :computer: | |
|
||||
| FreeBSD | :computer: | :computer: |
|
||||
|
||||
当前支持编译的 PHP 版本:
|
||||
|
||||
> :warning: 支持,但可能不再提供修复
|
||||
>
|
||||
> :heavy_check_mark: 支持
|
||||
>
|
||||
> :x: 不支持
|
||||
|
||||
| PHP Version | Status | Comment |
|
||||
|-------------|--------------------|------------------------------|
|
||||
| 7.2 | :x: | |
|
||||
| 7.3 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 7.4 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 8.0 | :heavy_check_mark: | PHP 官方已停止 8.0 的维护 |
|
||||
| 8.1 | :heavy_check_mark: | |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
|
||||
### 支持的扩展
|
||||
|
||||
请先根据下方扩展列表选择你要编译的扩展。
|
||||
|
||||
- [扩展支持列表](https://static-php.dev/zh/guide/extensions.html)
|
||||
- [编译命令生成器](https://static-php.dev/zh/guide/cli-generator.html)
|
||||
|
||||
> 如果这里没有你需要的扩展,可以提交 Issue。
|
||||
|
||||
### 在线构建(使用 GitHub Actions)
|
||||
|
||||
使用 GitHub Action 可以方便地构建一个静态编译的 PHP,同时可以自行定义要编译的扩展。
|
||||
|
||||
1. Fork 本项目。
|
||||
2. 进入项目的 Actions,选择 CI。
|
||||
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`)
|
||||
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`。
|
||||
|
||||
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
|
||||
|
||||
### 本地构建(使用 spc 二进制)
|
||||
|
||||
该项目提供了 static-php-cli 的二进制文件:`spc`。
|
||||
您可以使用 `spc` 二进制文件,无需安装任何运行时(用起来就像 golang 程序)。
|
||||
目前,`spc` 二进制文件提供的平台有 Linux 和 macOS。
|
||||
|
||||
使用以下命令从自托管服务器下载:
|
||||
|
||||
```bash
|
||||
# Download from self-hosted nightly builds (sync with main branch)
|
||||
# For Linux x86_64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
|
||||
# For Linux aarch64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
# macOS x86_64 (Intel)
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
# macOS aarch64 (Apple)
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
|
||||
# Windows (x86_64, win10 build 17063 or later)
|
||||
curl.exe -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
|
||||
|
||||
# Add execute perm (Linux and macOS only)
|
||||
chmod +x ./spc
|
||||
|
||||
# Run (Linux and macOS)
|
||||
./spc --version
|
||||
# Run (Windows powershell)
|
||||
.\spc.exe --version
|
||||
```
|
||||
|
||||
自托管 `spc` 由 GitHub Actions 构建,你也可以从 Actions 直接下载:[此处](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml)。
|
||||
|
||||
### 本地构建(使用 git 源码)
|
||||
|
||||
```bash
|
||||
# clone 仓库即可
|
||||
git clone https://github.com/crazywhalecc/static-php-cli.git
|
||||
```
|
||||
|
||||
如果您的系统上尚未安装 php,我们建议你使用内置的 setup-runtime 自动安装 PHP 和 Composer。
|
||||
|
||||
```bash
|
||||
cd static-php-cli
|
||||
chmod +x bin/setup-runtime
|
||||
# it will download static php (from self-hosted server) and composer (from getcomposer)
|
||||
bin/setup-runtime
|
||||
# initialize composer deps
|
||||
bin/composer install
|
||||
# chmod
|
||||
chmod +x bin/spc
|
||||
bin/spc --version
|
||||
```
|
||||
|
||||
### 开始构建 PHP
|
||||
|
||||
下面是使用 static-php-cli 的基础用法:
|
||||
|
||||
> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `./bin/spc` 替换为 `./spc`。
|
||||
|
||||
```bash
|
||||
# 检查环境依赖,并根据尝试自动安装缺失的编译工具
|
||||
./bin/spc doctor --auto-fix
|
||||
|
||||
# 拉取所有依赖库
|
||||
./bin/spc download --all
|
||||
# 只拉取编译指定扩展需要的所有依赖(推荐)
|
||||
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
|
||||
# 下载编译不同版本的 PHP (--with-php=x.y,推荐 7.3 ~ 8.3)
|
||||
./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
|
||||
|
||||
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
|
||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
|
||||
# 编译线程安全版本 (--enable-zts)
|
||||
./bin/spc build "curl,phar" --enable-zts --build-cli
|
||||
# 编译后使用 UPX 减小可执行文件体积 (--with-upx-pack) (至少压缩至原来的 30~50%)
|
||||
./bin/spc build "curl,phar" --enable-zts --build-cli --with-upx-pack
|
||||
```
|
||||
|
||||
其中,目前支持构建 cli,micro,fpm 和 embed,使用以下参数的一个或多个来指定编译的 SAPI:
|
||||
|
||||
- `--build-cli`:构建 cli 二进制
|
||||
- `--build-micro`:构建 phpmicro 自执行二进制
|
||||
- `--build-fpm`:构建 fpm
|
||||
- `--build-embed`:构建 embed(libphp)
|
||||
- `--build-all`:构建所有
|
||||
|
||||
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
|
||||
|
||||
```bash
|
||||
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
|
||||
./bin/spc download --all --debug
|
||||
```
|
||||
|
||||
## 不同 SAPI 的使用
|
||||
|
||||
### 使用 cli
|
||||
|
||||
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
|
||||
|
||||
采用参数 `--build-cli` 或`--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
|
||||
|
||||
```bash
|
||||
cd buildroot/bin/
|
||||
./php -v # 检查版本
|
||||
./php -m # 检查编译的扩展
|
||||
./php your_code.php # 运行代码
|
||||
./php your_project.phar # 运行打包为 phar 单文件的项目
|
||||
```
|
||||
|
||||
### 使用 micro
|
||||
|
||||
> phpmicro 是一个提供自执行二进制 PHP 的项目,本项目依赖 phpmicro 进行编译自执行二进制。详见 [dixyes/phpmicro](https://github.com/dixyes/phpmicro)。
|
||||
|
||||
采用项目参数 `--build-micro` 或 `--build-all` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,拷贝出来即可。
|
||||
|
||||
使用时应准备好你的项目源码文件,可以是单个 PHP 文件,也可以是 Phar 文件。
|
||||
|
||||
```bash
|
||||
echo "<?php echo 'Hello world' . PHP_EOL;" > code.php
|
||||
cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
./single-app
|
||||
```
|
||||
|
||||
如果打包 PHAR 文件,仅需把 code.php 更换为 phar 文件路径即可。
|
||||
你可以使用 [box-project/box](https://github.com/box-project/box) 将你的 CLI 项目打包为 Phar,
|
||||
然后将它与 phpmicro 结合,生成独立可执行的二进制文件。
|
||||
|
||||
```bash
|
||||
# 使用 static-php-cli 生成的 micro.sfx 结合,也可以直接使用 cat 命令结合它们
|
||||
bin/spc micro:combine my-app.phar
|
||||
cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
|
||||
|
||||
# 使用 micro:combine 结合可以将 INI 选项注入到二进制中
|
||||
bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
|
||||
```
|
||||
|
||||
> 有些情况下的 phar 文件或 PHP 项目可能无法在 micro 环境下运行。
|
||||
|
||||
### 使用 fpm
|
||||
|
||||
采用项目参数 `--build-fpm` 或 `--build-all` 时,最后编译结果会输出一个 `./php-fpm` 的文件。
|
||||
该文件存放在 `buildroot/bin/` 目录,拷贝出来即可使用。
|
||||
|
||||
在正常的 Linux 发行版和 macOS 系统中,安装 php-fpm 后包管理会自动生成默认的 fpm 配置文件。
|
||||
因为 php-fpm 必须指定配置文件才可启动,本项目编译的 php-fpm 不会带任何配置文件,所以需自行编写 `php-fpm.conf` 和 `pool.conf` 配置文件。
|
||||
|
||||
指定 `php-fpm.conf` 可以使用命令参数 `-y`,例如:`./php-fpm -y php-fpm.conf`。
|
||||
|
||||
### 使用 embed
|
||||
|
||||
采用项目参数 `--build-embed` 或 `--build-all` 时,最后编译结果会输出一个 `libphp.a`、`php-config` 以及一系列头文件,存放在 `buildroot/`,你可以在你的其他代码中引入它们。
|
||||
|
||||
如果你知道 [embed SAPI](https://github.com/php/php-src/tree/master/sapi/embed),你应该知道如何使用它。对于有可能编译用到引入其他库的问题,你可以使用 `buildroot/bin/php-config` 来获取编译时的配置。
|
||||
|
||||
另外,有关如何使用此功能的高级示例,请查看[如何使用它构建 FrankenPHP 的静态版本](https://github.com/dunglas/frankenphp/blob/main/docs/static.md)。
|
||||
|
||||
## 贡献
|
||||
|
||||
如果缺少你需要的扩展,可发起 Issue。如果你对本项目较熟悉,也欢迎为本项目发起 Pull Request。
|
||||
|
||||
另外,添加新扩展的贡献方式,可以参考下方 `进阶`。
|
||||
|
||||
如果你想贡献文档内容,请到项目仓库 [static-php/static-php-cli-docs](https://github.com/static-php/static-php-cli-docs) 贡献。
|
||||
|
||||
## 赞助本项目
|
||||
|
||||
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。你捐赠的一部分将会被用于维护 **static-php.dev** 服务器。
|
||||
|
||||
## 开源协议
|
||||
|
||||
本项目采用 MIT License 许可开源,下面是类似的项目:
|
||||
|
||||
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
|
||||
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
|
||||
|
||||
该项目使用了 [dixyes/lwmbs](https://github.com/dixyes/lwmbs) 中的一些代码,例如 Windows 静态构建目标和 libiconv 库支持。
|
||||
lwmbs 使用 [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2) 许可进行分发。对应文件有关于作者和许可的特殊说明,除此之外,均使用 MIT 授权许可。
|
||||
|
||||
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
|
||||
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
|
||||
377
README.md
377
README.md
@@ -1,227 +1,324 @@
|
||||
# static-php-cli
|
||||
|
||||
Compile A Statically Linked PHP With Swoole and other Extensions.
|
||||
[](README-zh.md)
|
||||
[](README.md)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/releases)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
|
||||
[](https://static-php.dev/en/guide/extensions.html)
|
||||
|
||||
**If you are using English, see [English README](README-en.md).**
|
||||
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
|
||||
with popular extensions.
|
||||
|
||||
编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携!(cli SAPI)
|
||||
Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed` and `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">
|
||||
**static-php-cli** also has the ability to package PHP projects
|
||||
along with the PHP interpreter into one single executable file.
|
||||
|
||||
同时可以使用 micro 二进制文件,将 PHP 源码和 PHP 二进制构建为一个文件分发!(由 [dixyes/phpmicro](https://github.com/dixyes/phpmicro) 提供支持)(micro SAPI)
|
||||
## Features
|
||||
|
||||
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
||||
static-php-cli (you can call it `spc`) has a lot of features:
|
||||
|
||||
[]()
|
||||
[]()
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/build.yml)
|
||||
[]()
|
||||
[]()
|
||||
- :handbag: Build single-file php executable, without any dependencies
|
||||
- :hamburger: Build **[phpmicro](https://github.com/dixyes/phpmicro)** self-extracted executable (glue php binary and php source code into one file)
|
||||
- :pill: Automatic build environment checker (Doctor module)
|
||||
- :zap: `Linux`, `macOS`, `FreeBSD`, `Windows` support
|
||||
- :wrench: Configurable source code patches
|
||||
- :books: Build dependency management
|
||||
- 📦 Provide `spc` own standalone executable (built by spc and [box](https://github.com/box-project/box))
|
||||
- :fire: Support many popular [extensions](https://static-php.dev/en/guide/extensions.html)
|
||||
- :floppy_disk: UPX integration (significantly reduces binary size)
|
||||
|
||||
> 项目已重命名 `refactor` 分支为 `main` 分支,请依赖的项目注意更改分支名称。
|
||||
**Single-file standalone php-cli:**
|
||||
|
||||
## 编译环境需求
|
||||
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
|
||||
|
||||
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
||||
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
|
||||
**Combine PHP code with PHP interpreter using phpmicro:**
|
||||
|
||||
下面是架构支持情况,`CI` 代表支持 GitHub Action 构建,`Local` 代表支持本地构建,空 代表暂不支持。
|
||||
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
|
||||
|
||||
| | x86_64 | aarch64 |
|
||||
|---------|-----------|-----------|
|
||||
| macOS | CI, Local | Local |
|
||||
| Linux | CI, Local | CI, Local |
|
||||
| Windows | | |
|
||||
## Documentation
|
||||
|
||||
> macOS-arm64 因 GitHub 暂未提供 arm runner,如果要构建 arm 二进制,可以使用手动构建。
|
||||
The current README contains basic usage. For all the features of static-php-cli,
|
||||
see <https://static-php.dev> .
|
||||
|
||||
目前支持编译的 PHP 版本为:`7.4`,`8.0`,`8.1`,`8.2`。
|
||||
## Direct Download
|
||||
|
||||
## 文档
|
||||
If you don't want to build or want to test first, you can download example pre-compiled artifact from [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml), or from self-hosted server.
|
||||
|
||||
点击这里查看文档:<https://static-php-cli.zhamao.me>。
|
||||
Below are several precompiled static-php binaries with different extension combinations,
|
||||
which can be downloaded directly according to your needs.
|
||||
|
||||
## 使用
|
||||
- [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.
|
||||
|
||||
请先根据下方扩展列表选择你要编译的扩展。
|
||||
For Windows systems, there are currently fewer extensions supported,
|
||||
so only `cli` and `micro` that run the minimum extension combination of SPC itself are provided: [Extension-Combination - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/).
|
||||
|
||||
### 自托管直接下载
|
||||
## Build
|
||||
|
||||
如果你不想自行编译,可以从本项目现有的 Action 下载 Artifact,也可以从自托管的服务器下载:[进入](https://dl.zhamao.xin/static-php-cli/)
|
||||
### Compilation Requirements
|
||||
|
||||
> 自托管的服务器默认包含的扩展有:`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`
|
||||
You can say I made a PHP builder written in PHP, pretty funny.
|
||||
But static-php-cli runtime only requires an environment above PHP 8.1 and extensions mentioned below.
|
||||
|
||||
### 支持的扩展情况
|
||||
- PHP >= 8.1 (This is the version required by spc itself, not the build version)
|
||||
- Extension: `mbstring,tokenizer,phar`
|
||||
- Supported OS with `curl` and `git` installed
|
||||
|
||||
[扩展支持列表](https://static-php-cli.zhamao.me/zh/guide/extensions.html)
|
||||
Here is the supported OS and arch, where :octocat: represents support for GitHub Action builds,
|
||||
:computer: represents support for local manual builds, and blank represents not currently supported.
|
||||
|
||||
> 如果这里没有你需要的扩展,可以提交 Issue。
|
||||
| | x86_64 | aarch64 |
|
||||
|---------|----------------------|----------------------|
|
||||
| macOS | :octocat: :computer: | :octocat: :computer: |
|
||||
| Linux | :octocat: :computer: | :octocat: :computer: |
|
||||
| Windows | :computer: | |
|
||||
| FreeBSD | :computer: | :computer: |
|
||||
|
||||
### 使用 Actions 构建
|
||||
Currently supported PHP versions for compilation:
|
||||
|
||||
使用 GitHub Action 可以方便地构建一个静态编译的 PHP 和 phpmicro,同时可以自行定义要编译的扩展。
|
||||
> :warning: supported but not maintained
|
||||
>
|
||||
> :heavy_check_mark: supported
|
||||
>
|
||||
> :x: not supported
|
||||
|
||||
1. Fork 本项目。
|
||||
2. 进入项目的 Actions,选择 CI。
|
||||
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`)
|
||||
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`。
|
||||
| PHP Version | Status | Comment |
|
||||
|-------------|--------------------|---------------------------------------------------|
|
||||
| 7.2 | :x: | |
|
||||
| 7.3 | :warning: | phpmicro and some extensions not supported on 7.x |
|
||||
| 7.4 | :warning: | phpmicro and some extensions not supported on 7.x |
|
||||
| 8.0 | :heavy_check_mark: | PHP official has stopped maintenance of 8.0 |
|
||||
| 8.1 | :heavy_check_mark: | |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
|
||||
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
|
||||
### Supported Extensions
|
||||
|
||||
### 手动构建
|
||||
Please first select the extension you want to compile based on the extension list below.
|
||||
|
||||
先克隆本项目:
|
||||
- [Supported Extension List](https://static-php.dev/en/guide/extensions.html)
|
||||
- [Command Generator](https://static-php.dev/en/guide/cli-generator.html)
|
||||
|
||||
> If an extension you need is missing, you can submit an issue.
|
||||
|
||||
Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
|
||||
|
||||
### Build Online (using GitHub Actions)
|
||||
|
||||
Use GitHub Action to easily build a statically compiled PHP,
|
||||
and at the same time define the extensions to be compiled by yourself.
|
||||
|
||||
1. Fork me.
|
||||
2. Go to the Actions of the project and select `CI`.
|
||||
3. Select `Run workflow`, fill in the PHP version you want to compile, the target type, and the list of extensions. (extensions comma separated, e.g. `bcmath,curl,mbstring`)
|
||||
4. After waiting for about a period of time, enter the corresponding task and get `Artifacts`.
|
||||
|
||||
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
|
||||
|
||||
### Build Locally (using SPC binary)
|
||||
|
||||
This project provides a binary file of static-php-cli: `spc`.
|
||||
You can use `spc` binary instead of installing any runtime like golang app.
|
||||
Currently, the platforms supported by `spc` binary are Linux and macOS.
|
||||
|
||||
Download from self-hosted nightly builds using commands below:
|
||||
|
||||
```bash
|
||||
# Download from self-hosted nightly builds (sync with main branch)
|
||||
# For Linux x86_64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
|
||||
# For Linux aarch64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
# macOS x86_64 (Intel)
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
# macOS aarch64 (Apple)
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
|
||||
# Windows (x86_64, win10 build 17063 or later)
|
||||
curl.exe -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
|
||||
|
||||
# Add execute perm (Linux and macOS only)
|
||||
chmod +x ./spc
|
||||
|
||||
# Run (Linux and macOS)
|
||||
./spc --version
|
||||
# Run (Windows powershell)
|
||||
.\spc.exe --version
|
||||
```
|
||||
|
||||
Self-hosted `spc` is built by GitHub Actions, you can also download from Actions artifacts [here](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml).
|
||||
|
||||
### Build Locally (using git source)
|
||||
|
||||
```bash
|
||||
# just clone me!
|
||||
git clone https://github.com/crazywhalecc/static-php-cli.git
|
||||
```
|
||||
|
||||
如果你本机没有安装 PHP,你需要先使用包管理(例如 brew、apt、yum、apk 等)安装 php。
|
||||
|
||||
你也可以通过 `bin/setup-runtime` 命令下载静态编译好的 php-cli 和 Composer。下载的 php 和 Composer 将保存为 `bin/php` 和 `bin/composer`。
|
||||
If you have not installed php on your system, we recommend that you use the built-in setup-runtime to install PHP and Composer automatically.
|
||||
|
||||
```bash
|
||||
cd static-php-cli
|
||||
chmod +x bin/setup-runtime
|
||||
./bin/setup-runtime
|
||||
|
||||
# 使用独立的 php 运行 static-php-cli
|
||||
./bin/php bin/spc
|
||||
|
||||
# 使用 composer
|
||||
./bin/php bin/composer
|
||||
```
|
||||
|
||||
下面是使用 static-php-cli 编译静态 php 和 micro 的基础用法:
|
||||
|
||||
```bash
|
||||
# 克隆本项目
|
||||
cd static-php-cli
|
||||
composer update
|
||||
# it will download static php (from self-hosted server) and composer (from getcomposer)
|
||||
bin/setup-runtime
|
||||
# initialize composer deps
|
||||
bin/composer install
|
||||
# chmod
|
||||
chmod +x bin/spc
|
||||
# 检查环境依赖,并根据提示的命令安装缺失的编译工具
|
||||
./bin/spc doctor
|
||||
# 拉取所有依赖库
|
||||
./bin/spc fetch --all
|
||||
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
|
||||
bin/spc --version
|
||||
```
|
||||
|
||||
### Start Building PHP
|
||||
|
||||
Basic usage for building php with some extensions:
|
||||
|
||||
> If you are using the packaged standalone `spc` binary, you need to replace `bin/spc` with `./spc` or `.\spc.exe` in the following commands.
|
||||
|
||||
```bash
|
||||
# Check system tool dependencies, auto-fix them if possible
|
||||
./bin/spc doctor --auto-fix
|
||||
|
||||
# fetch all libraries
|
||||
./bin/spc download --all
|
||||
# only fetch necessary sources by needed extensions (recommended)
|
||||
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
|
||||
# download different PHP version (--with-php=x.y, recommend 7.3 ~ 8.3)
|
||||
./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
|
||||
|
||||
# with bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl extension, build both CLI and phpmicro SAPI
|
||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
|
||||
# build thread-safe (ZTS) version (--enable-zts)
|
||||
./bin/spc build "curl,phar" --enable-zts --build-cli
|
||||
# build, pack executable with UPX (--with-upx-pack) (reduce binary size for 30~50%)
|
||||
./bin/spc build "curl,phar" --enable-zts --build-cli --with-upx-pack
|
||||
```
|
||||
|
||||
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.4 ~ 8.2:
|
||||
Now we support `cli`, `micro`, `fpm` and `embed` SAPI. You can use one or more of the following parameters to specify the compiled SAPI:
|
||||
|
||||
- `--build-cli`: 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
|
||||
|
||||
If anything goes wrong, use `--debug` option to display full terminal output:
|
||||
|
||||
```bash
|
||||
# 优先考虑使用 >= 8.0 的 PHP 版本
|
||||
./bin/spc fetch --with-php=8.2 --all
|
||||
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
|
||||
./bin/spc download --all --debug
|
||||
```
|
||||
|
||||
其中,目前支持构建 cli,micro,fpm 三种静态二进制,使用以下参数的一个或多个来指定编译的 SAPI:
|
||||
## Different SAPI Usage
|
||||
|
||||
- `--build-cli`:构建 cli 二进制
|
||||
- `--build-micro`:构建 phpmicro 自执行二进制
|
||||
- `--build-fpm`:构建 fpm
|
||||
- `--build-all`:构建所有
|
||||
### Use cli
|
||||
|
||||
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
|
||||
> php-cli is a single static binary, you can use it like normal php installed on your system.
|
||||
|
||||
```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 等工具调试,但这样会让静态二进制体积变大。
|
||||
|
||||
### 使用 php-cli
|
||||
|
||||
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
|
||||
|
||||
采用参数 `--build-cli` 或`--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
|
||||
When using the parameter `--build-cli` or `--build-all`,
|
||||
the final compilation result will output a binary file named `./php`,
|
||||
which can be distributed and used directly.
|
||||
This file will be located in the directory `buildroot/bin/`, copy it out for use.
|
||||
|
||||
```bash
|
||||
cd buildroot/bin/
|
||||
./php -v # 检查版本
|
||||
./php -m # 检查编译的扩展
|
||||
./php your_code.php # 运行代码
|
||||
./php your_project.phar # 运行打包为 phar 单文件的项目
|
||||
./php -v # check version
|
||||
./php -m # check extensions
|
||||
./php your_code.php # run your php code
|
||||
./php your_project.phar # run your phar (project archive)
|
||||
```
|
||||
|
||||
### 使用 micro.sfx
|
||||
### Use micro
|
||||
|
||||
> phpmicro 是一个提供自执行二进制 PHP 的项目,本项目依赖 phpmicro 进行编译自执行二进制。详见 [dixyes/phpmicro](https://github.com/dixyes/phpmicro)。
|
||||
> phpmicro is a SelF-extracted eXecutable SAPI module,
|
||||
> provided by [phpmicro](https://github.com/dixyes/phpmicro) project.
|
||||
> But this project is using a [fork](https://github.com/static-php/phpmicro) of phpmicro, because we need to add some features to it.
|
||||
> It can put php runtime and your source code together.
|
||||
|
||||
采用项目参数 `--build-micro` 或 `--build-all` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,拷贝出来即可。
|
||||
When using the parameter `--build-all` or `--build-micro`,
|
||||
the final compilation result will output a file named `./micro.sfx`,
|
||||
which needs to be used with your PHP source code like `code.php`.
|
||||
This file will be located in the path `buildroot/bin/micro.sfx`, simply copy it out for use.
|
||||
|
||||
使用时应准备好你的项目源码文件,可以是单个 PHP 文件,也可以是 Phar 文件。
|
||||
Prepare your project source code, which can be a single PHP file or a Phar file, for use.
|
||||
|
||||
```bash
|
||||
echo "<?php echo 'Hello world' . PHP_EOL;" > code.php
|
||||
cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
./single-app
|
||||
|
||||
# 如果打包 PHAR 文件,仅需把 code.php 更换为 phar 文件路径即可
|
||||
```
|
||||
|
||||
> 有些情况下的 phar 文件可能无法在 micro 环境下运行。
|
||||
If you package a PHAR file, just replace `code.php` with the phar file path.
|
||||
You can use [box-project/box](https://github.com/box-project/box) to package your CLI project as Phar,
|
||||
It is then combined with phpmicro to produce a standalone executable binary.
|
||||
|
||||
### 使用 php-fpm
|
||||
```bash
|
||||
# Use the micro.sfx generated by static-php-cli to combine,
|
||||
bin/spc micro:combine my-app.phar
|
||||
# or you can directly use the cat command to combine them.
|
||||
cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
|
||||
|
||||
采用项目参数 `--build-fpm` 或 `--build-all` 时,最后编译结果会输出一个 `./php-fpm` 的文件。
|
||||
该文件存放在 `buildroot/bin/` 目录,拷贝出来即可使用。
|
||||
# Use micro:combine combination to inject INI options into the binary.
|
||||
bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
|
||||
```
|
||||
|
||||
在正常的 Linux 发行版和 macOS 系统中,安装 php-fpm 后包管理会自动生成默认的 fpm 配置文件。
|
||||
因为 php-fpm 必须指定配置文件才可启动,本项目编译的 php-fpm 不会带任何配置文件,所以需自行编写 `php-fpm.conf` 和 `pool.conf` 配置文件。
|
||||
> In some cases, PHAR files may not run in a micro environment. Overall, micro is not production ready.
|
||||
|
||||
指定 `php-fpm.conf` 可以使用命令参数 `-y`,例如:`./php-fpm -y php-fpm.conf`。
|
||||
### Use fpm
|
||||
|
||||
## 项目支持情况
|
||||
When using the parameter `--build-all` or `--build-fpm`,
|
||||
the final compilation result will output a file named `./php-fpm`,
|
||||
This file will be located in the path `buildroot/bin/`, simply copy it out for use.
|
||||
|
||||
- [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). A portion of your donation will be used to maintain the **static-php.dev** server.
|
||||
|
||||
- [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:
|
||||
|
||||
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php-cli.zhamao.me) 贡献代码或文档。(TODO)
|
||||
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
|
||||
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
|
||||
|
||||
The project uses some code from [dixyes/lwmbs](https://github.com/dixyes/lwmbs), such as windows static build target and libiconv support.
|
||||
lwmbs is licensed under the [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2).
|
||||
|
||||
Due to the special nature of this project,
|
||||
many other open source projects such as curl and protobuf will be used during the project compilation process,
|
||||
and they all have their own open source licenses.
|
||||
|
||||
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.
|
||||
|
||||
@@ -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
|
||||
@@ -35,7 +35,6 @@ while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--mirror)
|
||||
mirror="$2"
|
||||
shift
|
||||
;;
|
||||
--*)
|
||||
echo "Illegal option $1"
|
||||
@@ -46,23 +45,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"
|
||||
__COMPOSER_URL__="https://mirrors.aliyun.com/composer/composer.phar"
|
||||
__PHP_RUNTIME_URL__="https://dl.static-php.dev/static-php-cli/bulk/php-8.2.13-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
|
||||
__COMPOSER_URL__="https://mirrors.tencent.com/composer/composer.phar"
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
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:"
|
||||
|
||||
115
bin/setup-runtime.ps1
Normal file
115
bin/setup-runtime.ps1
Normal file
@@ -0,0 +1,115 @@
|
||||
param (
|
||||
[string] ${action}
|
||||
)
|
||||
|
||||
function AddToPath {
|
||||
param (
|
||||
[string]$pathToAdd
|
||||
)
|
||||
|
||||
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
|
||||
|
||||
if ($currentPath -notlike "*$pathToAdd*") {
|
||||
$newPath = $currentPath + ";$pathToAdd"
|
||||
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
||||
Write-Host "Added '$pathToAdd' to Path."
|
||||
Write-Host "To remove path, use: " -NoNewline
|
||||
Write-Host "bin/setup-runtime remove-path" -ForegroundColor Cyan
|
||||
} else {
|
||||
Write-Host "Path already exists."
|
||||
}
|
||||
}
|
||||
|
||||
function RemoveFromPath {
|
||||
param (
|
||||
[string]$pathToRemove
|
||||
)
|
||||
|
||||
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
|
||||
|
||||
if ($currentPath -like "*$pathToRemove*") {
|
||||
$newPath = $currentPath -replace [regex]::Escape(';' + $pathToRemove), ''
|
||||
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
||||
Write-Host "Removed Path '$pathToRemove'"
|
||||
} else {
|
||||
Write-Host "Path '$pathToRemove' not in Path"
|
||||
}
|
||||
}
|
||||
|
||||
# working dir
|
||||
$WorkingDir = (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Definition))
|
||||
|
||||
if ($action -eq 'add-path') {
|
||||
AddToPath ($WorkingDir + '\runtime')
|
||||
exit 0
|
||||
} elseif ($action -eq 'remove-path') {
|
||||
RemoveFromPath ($WorkingDir + '\runtime')
|
||||
exit 0
|
||||
} elseif (-not($action -eq '')) {
|
||||
Write-Host ("Invalid action: " + $action) -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# get php 8.1 specific version
|
||||
$API = (Invoke-WebRequest -Uri "https://www.php.net/releases/index.php?json&version=8.1") | ConvertFrom-Json
|
||||
|
||||
# php windows download
|
||||
$PHPRuntimeUrl = "https://windows.php.net/downloads/releases/php-" + $API.version + "-Win32-vs16-x64.zip"
|
||||
$ComposerUrl = "https://getcomposer.org/download/latest-stable/composer.phar"
|
||||
|
||||
# create dir
|
||||
New-Item -Path "downloads" -ItemType Directory -Force | Out-Null
|
||||
|
||||
# download php
|
||||
if (-not(Test-Path "downloads\php.zip"))
|
||||
{
|
||||
Write-Host "Downloading PHP ..."
|
||||
Invoke-WebRequest $PHPRuntimeUrl -OutFile "downloads\php.zip"
|
||||
}
|
||||
|
||||
# extract php
|
||||
New-Item -Path "runtime" -ItemType Directory -Force | Out-Null
|
||||
Write-Host "Extracting php.zip ..."
|
||||
Expand-Archive -Path "downloads/php.zip" -DestinationPath "runtime" -Force
|
||||
# make php.ini
|
||||
Move-Item -Path "runtime\php.ini-production" -Destination "runtime\php.ini" -Force
|
||||
$OriginINI = Get-Content -Path "runtime\php.ini" -Raw
|
||||
$OriginINI = $OriginINI -replace ';extension=openssl', 'extension=openssl'
|
||||
$OriginINI = $OriginINI -replace ';extension=curl', 'extension=curl'
|
||||
$OriginINI = $OriginINI -replace ';extension=mbstring', 'extension=mbstring'
|
||||
$OriginINI = $OriginINI -replace ';extension=sodium', 'extension=sodium'
|
||||
$OriginINI = $OriginINI -replace ';extension_dir = "./"', ('extension_dir = "' + (Split-Path -Parent $MyInvocation.MyCommand.Definition) + '\..\runtime\ext"')
|
||||
$OriginINI | Set-Content -Path "runtime\php.ini"
|
||||
|
||||
# download composer
|
||||
if (-not(Test-Path "runtime\composer.phar"))
|
||||
{
|
||||
Write-Host "Downloading composer ..."
|
||||
Invoke-WebRequest $ComposerUrl -OutFile "downloads\composer.phar"
|
||||
Move-Item -Path "downloads\composer.phar" -Destination "runtime\composer.phar" -Force
|
||||
}
|
||||
|
||||
# create runtime\composer.ps1
|
||||
$ComposerContent = '
|
||||
$WorkingDir = (Split-Path -Parent $MyInvocation.MyCommand.Definition)
|
||||
& ($WorkingDir + "\php.exe") (Join-Path $WorkingDir "\composer.phar") @args
|
||||
'
|
||||
$ComposerContent | Set-Content -Path 'runtime\composer.ps1' -Encoding UTF8
|
||||
|
||||
Write-Host "Successfully downloaded PHP and Composer !" -ForegroundColor Green
|
||||
Write-Host "Use static-php-cli: " -NoNewline
|
||||
Write-Host "bin/spc" -ForegroundColor Cyan
|
||||
Write-Host "Use php: " -NoNewline
|
||||
Write-Host "runtime/php" -ForegroundColor Cyan
|
||||
Write-Host "Use composer: " -NoNewline
|
||||
Write-Host "runtime/composer" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Don't forget installing composer dependencies '" -NoNewline
|
||||
Write-Host "runtime/composer install" -ForegroundColor Cyan -NoNewline
|
||||
Write-Host "' before using static-php-cli !"
|
||||
Write-Host ""
|
||||
Write-Host "If you want to use this PHP for quality tools (like phpstan, php-cs-fixer) or other project,"
|
||||
Write-Host "or use PHP, Composer as system executable,"
|
||||
Write-Host "use '" -NoNewline
|
||||
Write-Host "bin/setup-runtime add-path" -ForegroundColor Cyan -NoNewline
|
||||
Write-Host "' to add runtime dir in Path."
|
||||
17
bin/spc
17
bin/spc
@@ -1,16 +1,25 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
use SPC\ConsoleApplication;
|
||||
use SPC\exception\ExceptionHandler;
|
||||
|
||||
if (file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
|
||||
// Current: ./bin (git/project mode)
|
||||
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||
} else {
|
||||
// Current: ./vendor/crazywhalecc/static-php-cli/bin (composer library mode)
|
||||
require_once dirname(__DIR__, 3) . '/autoload.php';
|
||||
}
|
||||
|
||||
// 防止 Micro 打包状态下不支持中文的显示(虽然这个项目目前好像没输出过中文?)
|
||||
if (PHP_OS_FAMILY === 'Windows' && Phar::running()) {
|
||||
exec('CHCP 65001');
|
||||
}
|
||||
|
||||
// 跑,反正一条命令跑就对了
|
||||
try {
|
||||
(new \SPC\ConsoleApplication())->run();
|
||||
(new ConsoleApplication())->run();
|
||||
} catch (Exception $e) {
|
||||
\SPC\exception\ExceptionHandler::getInstance()->handle($e);
|
||||
ExceptionHandler::getInstance()->handle($e);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -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 $@
|
||||
|
||||
12
bin/spc.ps1
Normal file
12
bin/spc.ps1
Normal file
@@ -0,0 +1,12 @@
|
||||
$PHP_Exec = ".\runtime\php.exe"
|
||||
|
||||
if (-not(Test-Path $PHP_Exec)) {
|
||||
$PHP_Exec = Get-Command php.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Definition
|
||||
if (-not $PHP_Exec) {
|
||||
Write-Host "Error: PHP not found, you need to install PHP on your system or use 'bin/setup-runtime'." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
& "$PHP_Exec" ("bin/spc") @args
|
||||
exit $LASTEXITCODE
|
||||
18
box.json
Normal file
18
box.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"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",
|
||||
"output": "spc.phar"
|
||||
}
|
||||
@@ -11,17 +11,18 @@
|
||||
"require": {
|
||||
"php": ">= 8.1",
|
||||
"ext-mbstring": "*",
|
||||
"ext-pcntl": "*",
|
||||
"laravel/prompts": "^0.1.3",
|
||||
"symfony/console": "^6 || ^5 || ^4",
|
||||
"laravel/prompts": "^0.1.12",
|
||||
"symfony/console": "^5.4 || ^6 || ^7",
|
||||
"zhamao/logger": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"nunomaduro/collision": "*",
|
||||
"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.5",
|
||||
"nunomaduro/collision": "^7.8",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^10.3 || ^9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -32,13 +33,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": {
|
||||
@@ -47,5 +54,11 @@
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
}
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"type": "other",
|
||||
"url": "https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
6281
composer.lock
generated
Normal file
6281
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
297
config/ext.json
297
config/ext.json
@@ -1,4 +1,15 @@
|
||||
{
|
||||
"amqp": {
|
||||
"type": "external",
|
||||
"arg-type": "custom",
|
||||
"source": "amqp",
|
||||
"lib-depends": [
|
||||
"librabbitmq"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"apcu": {
|
||||
"type": "external",
|
||||
"source": "apcu"
|
||||
@@ -24,11 +35,18 @@
|
||||
"arg-type": "with",
|
||||
"lib-depends": [
|
||||
"curl"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"zlib",
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"dba": {
|
||||
"type": "builtin",
|
||||
"arg-type-windows": "with"
|
||||
"arg-type": "custom",
|
||||
"lib-suggests": [
|
||||
"qdbm"
|
||||
]
|
||||
},
|
||||
"dom": {
|
||||
"type": "builtin",
|
||||
@@ -37,8 +55,15 @@
|
||||
"lib-depends": [
|
||||
"libxml2",
|
||||
"zlib"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml"
|
||||
]
|
||||
},
|
||||
"ds": {
|
||||
"type": "external",
|
||||
"source": "ext-ds"
|
||||
},
|
||||
"event": {
|
||||
"type": "external",
|
||||
"source": "ext-event",
|
||||
@@ -53,27 +78,17 @@
|
||||
"sockets"
|
||||
]
|
||||
},
|
||||
"memcached": {
|
||||
"type": "external",
|
||||
"source": "memcached",
|
||||
"arg-type": "custom",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"libmemcached"
|
||||
],
|
||||
"ext-depends": [
|
||||
"session",
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"exif": {
|
||||
"type": "builtin"
|
||||
},
|
||||
"ffi": {
|
||||
"arg-type": "custom",
|
||||
"type": "builtin",
|
||||
"lib-depends": [
|
||||
"lib-depends-unix": [
|
||||
"libffi"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"libffi-win"
|
||||
]
|
||||
},
|
||||
"fileinfo": {
|
||||
@@ -108,11 +123,20 @@
|
||||
},
|
||||
"gettext": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"gettext"
|
||||
]
|
||||
},
|
||||
"glfw": {
|
||||
"type": "external",
|
||||
"arg-type": "custom",
|
||||
"source": "ext-glfw",
|
||||
"lib-depends": [
|
||||
"glfw"
|
||||
],
|
||||
"lib-depends-windows": []
|
||||
},
|
||||
"gmp": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
@@ -123,10 +147,18 @@
|
||||
"iconv": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends-windows": [
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends-unix": [
|
||||
"libiconv"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"libiconv-win"
|
||||
]
|
||||
},
|
||||
"igbinary": {
|
||||
"type": "external",
|
||||
"source": "igbinary"
|
||||
},
|
||||
"imagick": {
|
||||
"type": "external",
|
||||
"source": "ext-imagick",
|
||||
@@ -135,22 +167,14 @@
|
||||
"imagemagick"
|
||||
]
|
||||
},
|
||||
"glfw": {
|
||||
"type": "external",
|
||||
"arg-type": "custom",
|
||||
"source": "ext-glfw",
|
||||
"lib-depends": [
|
||||
"glfw"
|
||||
]
|
||||
},
|
||||
"imap": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"imap"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"kerberos"
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"inotify": {
|
||||
@@ -159,16 +183,22 @@
|
||||
},
|
||||
"intl": {
|
||||
"type": "builtin",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"icu"
|
||||
]
|
||||
},
|
||||
"ldap": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"ldap"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"gmp",
|
||||
"libsodium"
|
||||
],
|
||||
"ext-suggests": [
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"mbregex": {
|
||||
@@ -176,14 +206,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",
|
||||
@@ -196,6 +226,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",
|
||||
@@ -222,13 +265,26 @@
|
||||
]
|
||||
},
|
||||
"opcache": {
|
||||
"type": "builtin"
|
||||
"type": "builtin",
|
||||
"arg-type": "custom"
|
||||
},
|
||||
"openssl": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "custom",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"openssl"
|
||||
"openssl",
|
||||
"zlib"
|
||||
],
|
||||
"ext-depends": [
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"password-argon2": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libargon2"
|
||||
]
|
||||
},
|
||||
"pcntl": {
|
||||
@@ -268,6 +324,15 @@
|
||||
"sqlite"
|
||||
]
|
||||
},
|
||||
"pdo_sqlsrv": {
|
||||
"type": "external",
|
||||
"source": "pdo_sqlsrv",
|
||||
"arg-type": "with",
|
||||
"ext-depends": [
|
||||
"pdo",
|
||||
"sqlsrv"
|
||||
]
|
||||
},
|
||||
"pgsql": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
@@ -289,12 +354,10 @@
|
||||
"type": "external",
|
||||
"source": "protobuf"
|
||||
},
|
||||
"pspell": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"lib-depends": [
|
||||
"aspell"
|
||||
]
|
||||
"rar": {
|
||||
"type": "external",
|
||||
"source": "rar",
|
||||
"cpp-extension": true
|
||||
},
|
||||
"readline": {
|
||||
"type": "builtin",
|
||||
@@ -308,7 +371,12 @@
|
||||
"source": "redis",
|
||||
"arg-type": "custom",
|
||||
"ext-suggests": [
|
||||
"session"
|
||||
"session",
|
||||
"igbinary"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"zstd",
|
||||
"liblz4"
|
||||
]
|
||||
},
|
||||
"session": {
|
||||
@@ -317,19 +385,31 @@
|
||||
"shmop": {
|
||||
"type": "builtin"
|
||||
},
|
||||
"simdjson": {
|
||||
"type": "external",
|
||||
"source": "ext-simdjson",
|
||||
"cpp-extension": true
|
||||
},
|
||||
"simplexml": {
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml"
|
||||
]
|
||||
},
|
||||
"snmp": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"snappy": {
|
||||
"type": "external",
|
||||
"source": "ext-snappy",
|
||||
"cpp-extension": true,
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"net-snmp"
|
||||
"snappy"
|
||||
],
|
||||
"ext-suggest": [
|
||||
"apcu"
|
||||
]
|
||||
},
|
||||
"soap": {
|
||||
@@ -337,6 +417,9 @@
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml"
|
||||
]
|
||||
},
|
||||
"sockets": {
|
||||
@@ -352,16 +435,33 @@
|
||||
"sqlite3": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"sqlite"
|
||||
]
|
||||
},
|
||||
"sqlsrv": {
|
||||
"type": "external",
|
||||
"source": "sqlsrv",
|
||||
"lib-depends": [
|
||||
"unixodbc"
|
||||
],
|
||||
"ext-depends-linux": [
|
||||
"pcntl"
|
||||
],
|
||||
"cpp-extension": true
|
||||
},
|
||||
"ssh2": {
|
||||
"type": "external",
|
||||
"source": "ext-ssh2",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libssh2"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"openssl",
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"swoole": {
|
||||
@@ -369,16 +469,50 @@
|
||||
"source": "swoole",
|
||||
"arg-type": "custom",
|
||||
"cpp-extension": true,
|
||||
"unix-only": true,
|
||||
"lib-depends": [
|
||||
"openssl"
|
||||
"libcares",
|
||||
"brotli",
|
||||
"nghttp2",
|
||||
"zlib"
|
||||
],
|
||||
"ext-depends": [
|
||||
"openssl"
|
||||
],
|
||||
"ext-suggests": [
|
||||
"openssl",
|
||||
"curl"
|
||||
],
|
||||
"unix-only": true
|
||||
"ext-suggests": [
|
||||
"swoole-hook-pgsql",
|
||||
"swoole-hook-mysql",
|
||||
"swoole-hook-sqlite"
|
||||
]
|
||||
},
|
||||
"swoole-hook-mysql": {
|
||||
"type": "addon",
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"mysqlnd",
|
||||
"pdo",
|
||||
"pdo_mysql"
|
||||
],
|
||||
"ext-suggests": [
|
||||
"mysqli"
|
||||
]
|
||||
},
|
||||
"swoole-hook-pgsql": {
|
||||
"type": "addon",
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"pgsql",
|
||||
"pdo"
|
||||
]
|
||||
},
|
||||
"swoole-hook-sqlite": {
|
||||
"type": "addon",
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"sqlite3",
|
||||
"pdo"
|
||||
]
|
||||
},
|
||||
"swow": {
|
||||
"type": "external",
|
||||
@@ -402,12 +536,11 @@
|
||||
"unix-only": true
|
||||
},
|
||||
"sysvshm": {
|
||||
"type": "builtin",
|
||||
"unix-only": true
|
||||
"type": "builtin"
|
||||
},
|
||||
"tidy": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"tidy"
|
||||
]
|
||||
@@ -415,6 +548,32 @@
|
||||
"tokenizer": {
|
||||
"type": "builtin"
|
||||
},
|
||||
"uuid": {
|
||||
"type": "external",
|
||||
"source": "ext-uuid",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libuuid"
|
||||
]
|
||||
},
|
||||
"uv": {
|
||||
"type": "external",
|
||||
"source": "ext-uv",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libuv"
|
||||
],
|
||||
"ext-depends": [
|
||||
"sockets"
|
||||
]
|
||||
},
|
||||
"xhprof": {
|
||||
"type": "external",
|
||||
"source": "xhprof",
|
||||
"ext-depends": [
|
||||
"ctype"
|
||||
]
|
||||
},
|
||||
"xlswriter": {
|
||||
"type": "external",
|
||||
"source": "xlswriter",
|
||||
@@ -430,6 +589,9 @@
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"iconv"
|
||||
]
|
||||
},
|
||||
"xmlreader": {
|
||||
@@ -437,6 +599,10 @@
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
"xmlwriter": {
|
||||
@@ -444,13 +610,28 @@
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml"
|
||||
]
|
||||
},
|
||||
"xsl": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libxslt"
|
||||
],
|
||||
"ext-depends": [
|
||||
"xml",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
"yac": {
|
||||
"type": "external",
|
||||
"source": "yac",
|
||||
"arg-type-unix": "custom",
|
||||
"ext-depends-unix": [
|
||||
"igbinary"
|
||||
]
|
||||
},
|
||||
"yaml": {
|
||||
@@ -471,7 +652,7 @@
|
||||
},
|
||||
"zlib": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"arg-type": "custom",
|
||||
"arg-type-windows": "enable",
|
||||
"lib-depends": [
|
||||
"zlib"
|
||||
|
||||
304
config/lib.json
304
config/lib.json
@@ -2,31 +2,19 @@
|
||||
"brotli": {
|
||||
"source": "brotli",
|
||||
"static-libs-unix": [
|
||||
"libbrotlidec-static.a",
|
||||
"libbrotlienc-static.a",
|
||||
"libbrotlicommon-static.a"
|
||||
"libbrotlidec.a",
|
||||
"libbrotlienc.a",
|
||||
"libbrotlicommon.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"brotlicommon-static.lib",
|
||||
"brotlienc-static.lib",
|
||||
"brotlidec-static.lib"
|
||||
"brotlicommon.lib",
|
||||
"brotlienc.lib",
|
||||
"brotlidec.lib"
|
||||
],
|
||||
"headers": [
|
||||
"brotli"
|
||||
]
|
||||
},
|
||||
"glfw": {
|
||||
"source": "ext-glfw",
|
||||
"static-libs-unix": [
|
||||
"libglfw3.a"
|
||||
],
|
||||
"frameworks": [
|
||||
"CoreVideo",
|
||||
"OpenGL",
|
||||
"Cocoa",
|
||||
"IOKit"
|
||||
]
|
||||
},
|
||||
"bzip2": {
|
||||
"source": "bzip2",
|
||||
"static-libs-unix": [
|
||||
@@ -48,33 +36,34 @@
|
||||
"libcurl.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"libcurl.lib"
|
||||
"libcurl_a.lib"
|
||||
],
|
||||
"headers": [
|
||||
"curl"
|
||||
],
|
||||
"lib-depends-unix": [
|
||||
"openssl",
|
||||
"zlib"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"libssh2",
|
||||
"brotli",
|
||||
"nghttp2",
|
||||
"zstd",
|
||||
"openssl"
|
||||
],
|
||||
"lib-suggests-windows": [
|
||||
"lib-depends-windows": [
|
||||
"openssl",
|
||||
"zlib",
|
||||
"libssh2",
|
||||
"nghttp2"
|
||||
],
|
||||
"lib-suggests-unix": [
|
||||
"libssh2",
|
||||
"brotli",
|
||||
"nghttp2",
|
||||
"zstd",
|
||||
"openssl",
|
||||
"idn2",
|
||||
"psl"
|
||||
"zstd"
|
||||
],
|
||||
"lib-suggests-windows": [
|
||||
"brotli",
|
||||
"zstd"
|
||||
],
|
||||
"frameworks": [
|
||||
"CoreFoundation",
|
||||
"CoreServices",
|
||||
"SystemConfiguration"
|
||||
]
|
||||
},
|
||||
@@ -96,6 +85,34 @@
|
||||
"brotli"
|
||||
]
|
||||
},
|
||||
"gettext": {
|
||||
"source": "gettext",
|
||||
"static-libs-unix": [
|
||||
"libintl.a"
|
||||
],
|
||||
"lib-depends": [
|
||||
"libiconv"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"ncurses",
|
||||
"libxml2"
|
||||
],
|
||||
"frameworks": [
|
||||
"CoreFoundation"
|
||||
]
|
||||
},
|
||||
"glfw": {
|
||||
"source": "ext-glfw",
|
||||
"static-libs-unix": [
|
||||
"libglfw3.a"
|
||||
],
|
||||
"frameworks": [
|
||||
"CoreVideo",
|
||||
"OpenGL",
|
||||
"Cocoa",
|
||||
"IOKit"
|
||||
]
|
||||
},
|
||||
"gmp": {
|
||||
"source": "gmp",
|
||||
"static-libs-unix": [
|
||||
@@ -110,6 +127,7 @@
|
||||
},
|
||||
"icu": {
|
||||
"source": "icu",
|
||||
"cpp-library": true,
|
||||
"static-libs-unix": [
|
||||
"libicui18n.a",
|
||||
"libicuio.a",
|
||||
@@ -121,30 +139,71 @@
|
||||
"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"
|
||||
"freetype",
|
||||
"libtiff"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"zstd",
|
||||
"xz",
|
||||
"bzip2",
|
||||
"libzip",
|
||||
"libxml2"
|
||||
]
|
||||
},
|
||||
"imap": {
|
||||
"source": "imap",
|
||||
"static-libs-unix": [
|
||||
"libc-client.a"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"ldap": {
|
||||
"source": "ldap",
|
||||
"static-libs-unix": [
|
||||
"liblber.a",
|
||||
"libldap.a"
|
||||
],
|
||||
"lib-depends": [
|
||||
"openssl",
|
||||
"zlib",
|
||||
"gmp",
|
||||
"libsodium"
|
||||
]
|
||||
},
|
||||
"libargon2": {
|
||||
"source": "libargon2",
|
||||
"static-libs-unix": [
|
||||
"libargon2.a"
|
||||
]
|
||||
},
|
||||
"libavif": {
|
||||
"source": "libavif",
|
||||
"static-libs-unix": [
|
||||
"libavif.a"
|
||||
]
|
||||
},
|
||||
"libcares": {
|
||||
"source": "libcares",
|
||||
"static-libs-unix": [
|
||||
"libcares.a"
|
||||
],
|
||||
"headers-unix": [
|
||||
"ares.h",
|
||||
"ares_dns.h",
|
||||
"ares_nameser.h",
|
||||
"ares_rules.h"
|
||||
]
|
||||
},
|
||||
"libevent": {
|
||||
"source": "libevent",
|
||||
"static-libs-unix": [
|
||||
@@ -175,6 +234,17 @@
|
||||
"ffitarget.h"
|
||||
]
|
||||
},
|
||||
"libffi-win": {
|
||||
"source": "libffi-win",
|
||||
"static-libs-windows": [
|
||||
"libffi.lib"
|
||||
],
|
||||
"headers-windows": [
|
||||
"ffi.h",
|
||||
"ffitarget.h",
|
||||
"fficonfig.h"
|
||||
]
|
||||
},
|
||||
"libiconv": {
|
||||
"source": "libiconv",
|
||||
"static-libs-unix": [
|
||||
@@ -187,6 +257,13 @@
|
||||
"localcharset.h"
|
||||
]
|
||||
},
|
||||
"libiconv-win": {
|
||||
"source": "libiconv-win",
|
||||
"static-libs-windows": [
|
||||
"libiconv.lib",
|
||||
"libiconv_a.lib"
|
||||
]
|
||||
},
|
||||
"libjpeg": {
|
||||
"source": "libjpeg",
|
||||
"static-libs-unix": [
|
||||
@@ -194,16 +271,23 @@
|
||||
"libturbojpeg.a"
|
||||
]
|
||||
},
|
||||
"libmcrypt": {
|
||||
"source": "libmcrypt",
|
||||
"liblz4": {
|
||||
"source": "liblz4",
|
||||
"static-libs-unix": [
|
||||
"libmcrypt.a"
|
||||
"liblz4.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"
|
||||
@@ -221,6 +305,18 @@
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"librabbitmq": {
|
||||
"source": "librabbitmq",
|
||||
"static-libs-unix": [
|
||||
"librabbitmq.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"rabbitmq.4.lib"
|
||||
],
|
||||
"lib-depends": [
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"libsodium": {
|
||||
"source": "libsodium",
|
||||
"static-libs-unix": [
|
||||
@@ -247,6 +343,27 @@
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"libtiff": {
|
||||
"source": "libtiff",
|
||||
"static-libs-unix": [
|
||||
"libtiff.a"
|
||||
]
|
||||
},
|
||||
"libuuid": {
|
||||
"source": "libuuid",
|
||||
"static-libs-unix": [
|
||||
"libuuid.a"
|
||||
],
|
||||
"headers": [
|
||||
"uuid/uuid.h"
|
||||
]
|
||||
},
|
||||
"libuv": {
|
||||
"source": "libuv",
|
||||
"static-libs-unix": [
|
||||
"libuv.a"
|
||||
]
|
||||
},
|
||||
"libwebp": {
|
||||
"source": "libwebp",
|
||||
"static-libs-unix": [
|
||||
@@ -263,27 +380,35 @@
|
||||
"libxml2.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
[
|
||||
"libxml2s.lib",
|
||||
"libxml2_a.lib"
|
||||
]
|
||||
"libxml2s.lib",
|
||||
"libxml2_a.lib"
|
||||
],
|
||||
"headers": [
|
||||
"libxml2"
|
||||
],
|
||||
"lib-depends": [
|
||||
"lib-depends-unix": [
|
||||
"libiconv"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"lib-suggests-unix": [
|
||||
"xz",
|
||||
"zlib",
|
||||
"icu"
|
||||
"icu",
|
||||
"zlib"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"libiconv-win"
|
||||
],
|
||||
"lib-suggests-windows": [
|
||||
"icu",
|
||||
"xz",
|
||||
"zlib",
|
||||
"pthreads4w"
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"libxslt": {
|
||||
"source": "libxslt",
|
||||
"static-libs-unix": [
|
||||
"libxslt.a",
|
||||
"libexslt.a"
|
||||
],
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
]
|
||||
},
|
||||
"libyaml": {
|
||||
@@ -323,12 +448,6 @@
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"mcrypt": {
|
||||
"source": "mcrypt",
|
||||
"static-libs-unix": [
|
||||
"libmcrypt.a"
|
||||
]
|
||||
},
|
||||
"ncurses": {
|
||||
"source": "ncurses",
|
||||
"static-libs-unix": [
|
||||
@@ -360,10 +479,8 @@
|
||||
"libonig.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
[
|
||||
"onig.lib",
|
||||
"onig_a.lib"
|
||||
]
|
||||
"onig.lib",
|
||||
"onig_a.lib"
|
||||
],
|
||||
"headers": [
|
||||
"oniggnu.h",
|
||||
@@ -405,19 +522,22 @@
|
||||
"readline"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"icu"
|
||||
"icu",
|
||||
"libxslt",
|
||||
"ldap",
|
||||
"zstd"
|
||||
]
|
||||
},
|
||||
"pthreads4w": {
|
||||
"source": "pthreads4w",
|
||||
"qdbm": {
|
||||
"source": "qdbm",
|
||||
"static-libs-unix": [
|
||||
"libqdbm.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"libpthreadVC3.lib"
|
||||
"qdbm_a.lib"
|
||||
],
|
||||
"headers-windows": [
|
||||
"_ptw32.h",
|
||||
"pthread.h",
|
||||
"sched.h",
|
||||
"semaphore.h"
|
||||
"depot.h"
|
||||
]
|
||||
},
|
||||
"readline": {
|
||||
@@ -429,16 +549,51 @@
|
||||
"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": [
|
||||
"libsqlite3.a"
|
||||
],
|
||||
"headers-unix": [
|
||||
"static-libs-windows": [
|
||||
"libsqlite3_a.lib"
|
||||
],
|
||||
"headers": [
|
||||
"sqlite3.h",
|
||||
"sqlite3ext.h"
|
||||
]
|
||||
},
|
||||
"tidy": {
|
||||
"source": "tidy",
|
||||
"static-libs-unix": [
|
||||
"libtidy.a"
|
||||
]
|
||||
},
|
||||
"unixodbc": {
|
||||
"source": "unixodbc",
|
||||
"static-libs-unix": [
|
||||
"libodbc.a",
|
||||
"libodbccr.a",
|
||||
"libodbcinst.a"
|
||||
],
|
||||
"lib-depends": [
|
||||
"libiconv"
|
||||
]
|
||||
},
|
||||
"xz": {
|
||||
"source": "xz",
|
||||
"static-libs-unix": [
|
||||
@@ -474,13 +629,6 @@
|
||||
"zconf.h"
|
||||
]
|
||||
},
|
||||
"libmemcached": {
|
||||
"source": "libmemcached",
|
||||
"static-libs-unix": [
|
||||
"libmemcached.a",
|
||||
"libmemcachedutil.a"
|
||||
]
|
||||
},
|
||||
"zstd": {
|
||||
"source": "zstd",
|
||||
"static-libs-unix": [
|
||||
@@ -502,4 +650,4 @@
|
||||
"zstd_errors.h"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
config/pkg.json
Normal file
46
config/pkg.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"musl-toolchain-aarch64-linux": {
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/aarch64-musl-toolchain.tgz"
|
||||
},
|
||||
"musl-toolchain-x86_64-linux": {
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/x86_64-musl-toolchain.tgz"
|
||||
},
|
||||
"nasm-x86_64-win": {
|
||||
"type": "url",
|
||||
"url": "https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/nasm-2.16.01-win64.zip",
|
||||
"extract-files": {
|
||||
"nasm-2.16.01/nasm.exe": "{php_sdk_path}/bin/nasm.exe",
|
||||
"nasm-2.16.01/ndisasm.exe": "{php_sdk_path}/bin/ndisasm.exe"
|
||||
}
|
||||
},
|
||||
"strawberry-perl-x86_64-win": {
|
||||
"type": "url",
|
||||
"url": "https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip"
|
||||
},
|
||||
"upx-aarch64-linux": {
|
||||
"type": "ghrel",
|
||||
"repo": "upx/upx",
|
||||
"match": "upx.+-arm64_linux\\.tar\\.xz",
|
||||
"extract-files": {
|
||||
"upx": "{pkg_root_path}/bin/upx"
|
||||
}
|
||||
},
|
||||
"upx-x86_64-linux": {
|
||||
"type": "ghrel",
|
||||
"repo": "upx/upx",
|
||||
"match": "upx.+-amd64_linux\\.tar\\.xz",
|
||||
"extract-files": {
|
||||
"upx": "{pkg_root_path}/bin/upx"
|
||||
}
|
||||
},
|
||||
"upx-x86_64-win": {
|
||||
"type": "ghrel",
|
||||
"repo": "upx/upx",
|
||||
"match": "upx.+-win64\\.zip",
|
||||
"extract-files": {
|
||||
"upx-*-win64/upx.exe": "{pkg_root_path}/bin/upx.exe"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -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)
|
||||
|
||||
@@ -8,5 +8,11 @@ parameters:
|
||||
- '#Unsafe usage of new static#'
|
||||
- '#class Fiber#'
|
||||
- '#Attribute class JetBrains\\PhpStorm\\ArrayShape does not exist#'
|
||||
- '#Function Swoole\\Coroutine\\run not found.#'
|
||||
dynamicConstantNames:
|
||||
- PHP_OS_FAMILY
|
||||
- PHP_OS_FAMILY
|
||||
excludePaths:
|
||||
analyseAndScan:
|
||||
- ./src/globals/tests/swoole.php
|
||||
- ./src/globals/tests/swoole.phpt
|
||||
- ./src/globals/test-extensions.php
|
||||
@@ -4,51 +4,54 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\command\BuildCliCommand;
|
||||
use SPC\command\BuildLibsCommand;
|
||||
use SPC\command\DeleteDownloadCommand;
|
||||
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\InstallPkgCommand;
|
||||
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-rc5';
|
||||
public const VERSION = '2.1.7';
|
||||
|
||||
/**
|
||||
* @throws \ReflectionException
|
||||
* @throws exception\FileSystemException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('static-php-cli', self::VERSION);
|
||||
|
||||
global $argv;
|
||||
$this->addCommands(
|
||||
[
|
||||
// Common commands
|
||||
new BuildCliCommand(),
|
||||
new BuildLibsCommand(),
|
||||
new DoctorCommand(),
|
||||
new DownloadCommand(),
|
||||
new InstallPkgCommand(),
|
||||
new DeleteDownloadCommand(),
|
||||
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');
|
||||
$phar = class_exists('\\Phar') && \Phar::running() || !class_exists('\\Phar');
|
||||
$commands = array_filter($commands, function ($y) use ($phar) {
|
||||
$archive_blacklist = [
|
||||
'SPC\command\dev\SortConfigCommand',
|
||||
'SPC\command\DeployCommand',
|
||||
];
|
||||
if ($phar && in_array($y, $archive_blacklist)) {
|
||||
return false;
|
||||
}
|
||||
$reflection = new \ReflectionClass($y);
|
||||
return !$reflection->isAbstract() && !$reflection->isInterface();
|
||||
});
|
||||
$this->addCommands(array_map(function ($x) { return new $x(); }, $commands));
|
||||
// Dev commands
|
||||
new AllExtCommand(),
|
||||
new PhpVerCommand(),
|
||||
new SortConfigCommand(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重载以去除一些不必要的默认命令
|
||||
*/
|
||||
protected function getDefaultCommands(): array
|
||||
{
|
||||
return [new HelpCommand(), new ListCommand()];
|
||||
|
||||
@@ -4,107 +4,49 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder;
|
||||
|
||||
use SPC\exception\ExceptionHandler;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\SourceExtractor;
|
||||
use SPC\store\SourceManager;
|
||||
use SPC\util\CustomExt;
|
||||
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 = [];
|
||||
|
||||
/** @var string patch point name */
|
||||
protected string $patch_point = '';
|
||||
|
||||
/**
|
||||
* 构建指定列表的 libs
|
||||
* Build libraries
|
||||
*
|
||||
* @param array<string> $sorted_libraries Libraries to build (if not empty, must sort first)
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
* @internal
|
||||
*/
|
||||
public function buildLibs(array $libraries): void
|
||||
{
|
||||
// 通过扫描目录查找 lib
|
||||
$support_lib_list = [];
|
||||
$classes = FileSystem::getClassesPsr4(
|
||||
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
|
||||
'SPC\\builder\\' . osfamily2dir() . '\\library'
|
||||
);
|
||||
foreach ($classes as $class) {
|
||||
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {
|
||||
$support_lib_list[$class::NAME] = $class;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果传入了空,则默认检查和安置所有支持的lib,libraries为要build的,support_lib_list为支持的列表
|
||||
if ($libraries === [] && $this->isLibsOnly()) {
|
||||
$libraries = array_keys($support_lib_list);
|
||||
}
|
||||
if (!in_array('pkg-config', $libraries)) {
|
||||
array_unshift($libraries, 'pkg-config');
|
||||
}
|
||||
|
||||
// 排序 libs,根据依赖计算一个新的列表出来
|
||||
$libraries = DependencyUtil::getLibsByDeps($libraries);
|
||||
|
||||
// 过滤不支持的库后添加
|
||||
foreach ($libraries as $library) {
|
||||
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!');
|
||||
}
|
||||
$lib = new ($support_lib_list[$library])($this);
|
||||
$this->addLib($lib);
|
||||
}
|
||||
|
||||
// 计算依赖,经过这里的遍历,如果没有抛出异常,说明依赖符合要求,可以继续下面的
|
||||
foreach ($this->libs as $lib) {
|
||||
$lib->calcDependency();
|
||||
}
|
||||
|
||||
SourceExtractor::initSource(libs: $libraries);
|
||||
|
||||
// 构建库
|
||||
foreach ($this->libs as $lib) {
|
||||
match ($lib->tryBuild()) {
|
||||
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'),
|
||||
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
|
||||
};
|
||||
}
|
||||
}
|
||||
abstract public function buildLibs(array $sorted_libraries);
|
||||
|
||||
/**
|
||||
* 添加要编译的 Lib 库
|
||||
* Add library to build.
|
||||
*
|
||||
* @param LibraryBase $library Lib 库对象
|
||||
* @param LibraryBase $library Library object
|
||||
*/
|
||||
public function addLib(LibraryBase $library): void
|
||||
{
|
||||
@@ -112,9 +54,7 @@ abstract class BuilderBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取要编译的 Lib 库对象
|
||||
*
|
||||
* @param string $name 库名称
|
||||
* Get library object by name.
|
||||
*/
|
||||
public function getLib(string $name): ?LibraryBase
|
||||
{
|
||||
@@ -122,9 +62,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 +80,7 @@ abstract class BuilderBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取要编译的扩展对象
|
||||
*
|
||||
* @param string $name 扩展名称
|
||||
* Get extension object by name.
|
||||
*/
|
||||
public function getExt(string $name): ?Extension
|
||||
{
|
||||
@@ -142,7 +88,7 @@ abstract class BuilderBase
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有要编译的扩展对象
|
||||
* Get all extension objects.
|
||||
*
|
||||
* @return Extension[]
|
||||
*/
|
||||
@@ -152,28 +98,33 @@ 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.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function setLibsOnly(bool $status = true): void
|
||||
{
|
||||
@@ -181,21 +132,28 @@ 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
|
||||
* @throws \ReflectionException
|
||||
* @throws WrongUsageException
|
||||
* @internal
|
||||
*/
|
||||
public function proveExts(array $extensions): void
|
||||
{
|
||||
CustomExt::loadCustomExt();
|
||||
SourceExtractor::initSource(sources: ['php-src']);
|
||||
$this->emitPatchPoint('before-php-extract');
|
||||
SourceManager::initSource(sources: ['php-src']);
|
||||
$this->emitPatchPoint('after-php-extract');
|
||||
if ($this->getPHPVersionID() >= 80000) {
|
||||
SourceExtractor::initSource(sources: ['micro']);
|
||||
$this->emitPatchPoint('before-micro-extract');
|
||||
SourceManager::initSource(sources: ['micro']);
|
||||
$this->emitPatchPoint('after-micro-extract');
|
||||
}
|
||||
SourceExtractor::initSource(exts: $extensions);
|
||||
$this->emitPatchPoint('before-exts-extract');
|
||||
SourceManager::initSource(exts: $extensions);
|
||||
$this->emitPatchPoint('after-exts-extract');
|
||||
foreach ($extensions as $extension) {
|
||||
$class = CustomExt::getExtClass($extension);
|
||||
$ext = new $class($extension, $this);
|
||||
@@ -203,26 +161,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
|
||||
*/
|
||||
@@ -230,14 +183,15 @@ abstract class BuilderBase
|
||||
{
|
||||
$ret = [];
|
||||
foreach ($this->exts as $ext) {
|
||||
logger()->info($ext->getName() . ' is using ' . $ext->getConfigureArg());
|
||||
$ret[] = trim($ext->getConfigureArg());
|
||||
}
|
||||
logger()->info('Using configure: ' . implode(' ', $ret));
|
||||
logger()->debug('Using configure: ' . implode(' ', $ret));
|
||||
return implode(' ', $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回是否只编译 libs 的模式
|
||||
* Get libs only mode.
|
||||
*/
|
||||
public function isLibsOnly(): bool
|
||||
{
|
||||
@@ -245,15 +199,67 @@ 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 PHP version from archive file name.
|
||||
*
|
||||
* @param null|string $file php-*.*.*.tar.gz filename, read from lockfile if empty
|
||||
*/
|
||||
public function getPHPVersionFromArchive(?string $file = null): false|string
|
||||
{
|
||||
if ($file === null) {
|
||||
$lock = file_exists(DOWNLOAD_PATH . '/.lock.json') ? file_get_contents(DOWNLOAD_PATH . '/.lock.json') : false;
|
||||
if ($lock === false) {
|
||||
return false;
|
||||
}
|
||||
$lock = json_decode($lock, true);
|
||||
$file = $lock['php-src']['filename'] ?? null;
|
||||
if ($file === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (preg_match('/php-(\d+\.\d+\.\d+)/', $file, $match)) {
|
||||
return $match[1];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get build type name string to display.
|
||||
*
|
||||
* @param int $type Build target type
|
||||
*/
|
||||
public function getBuildTypeName(int $type): string
|
||||
{
|
||||
$ls = [];
|
||||
@@ -266,16 +272,97 @@ 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get builder patch point name.
|
||||
*/
|
||||
public function getPatchPoint(): string
|
||||
{
|
||||
return $this->patch_point;
|
||||
}
|
||||
|
||||
public function emitPatchPoint(string $point_name): void
|
||||
{
|
||||
$this->patch_point = $point_name;
|
||||
if (($patches = $this->getOption('with-added-patch', [])) === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($patches as $patch) {
|
||||
try {
|
||||
if (!file_exists($patch)) {
|
||||
throw new RuntimeException("Additional patch script file {$patch} not found!");
|
||||
}
|
||||
logger()->debug('Running additional patch script: ' . $patch);
|
||||
require $patch;
|
||||
} catch (\Throwable $e) {
|
||||
logger()->critical('Patch script ' . $patch . ' failed to run.');
|
||||
if ($this->getOption('debug')) {
|
||||
ExceptionHandler::getInstance()->handle($e);
|
||||
} else {
|
||||
logger()->critical('Please check with --debug option to see more details.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all libs are downloaded.
|
||||
* If not, throw exception.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
@@ -296,4 +383,22 @@ abstract class BuilderBase
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate micro extension test php code.
|
||||
*/
|
||||
protected function generateMicroExtTests(): string
|
||||
{
|
||||
$php = "<?php\n\necho '[micro-test-start]' . PHP_EOL;\n";
|
||||
|
||||
foreach ($this->getExts() as $ext) {
|
||||
$ext_name = $ext->getDistName();
|
||||
if (!empty($ext_name)) {
|
||||
$php .= "echo 'Running micro with {$ext_name} test' . PHP_EOL;\n";
|
||||
$php .= "assert(extension_loaded('{$ext_name}'));\n\n";
|
||||
}
|
||||
}
|
||||
$php .= "echo '[micro-test-end]';\n";
|
||||
return $php;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ 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;
|
||||
@@ -16,30 +18,33 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||
*/
|
||||
class BuilderProvider
|
||||
{
|
||||
private static ?BuilderBase $builder = null;
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function makeBuilderByInput(InputInterface $input): BuilderBase
|
||||
{
|
||||
return match (PHP_OS_FAMILY) {
|
||||
// 'Windows' => new WindowsBuilder(
|
||||
// binary_sdk_dir: $input->getOption('with-sdk-binary-dir'),
|
||||
// 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,
|
||||
),
|
||||
self::$builder = match (PHP_OS_FAMILY) {
|
||||
'Windows' => new WindowsBuilder($input->getOptions()),
|
||||
'Darwin' => new MacOSBuilder($input->getOptions()),
|
||||
'Linux' => new LinuxBuilder($input->getOptions()),
|
||||
'BSD' => new BSDBuilder($input->getOptions()),
|
||||
default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'),
|
||||
};
|
||||
return self::$builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function getBuilder(): BuilderBase
|
||||
{
|
||||
if (self::$builder === null) {
|
||||
throw new WrongUsageException('Builder has not been initialized');
|
||||
}
|
||||
return self::$builder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class Extension
|
||||
{
|
||||
@@ -34,7 +35,7 @@ class Extension
|
||||
/**
|
||||
* 获取开启该扩展的 PHP 编译添加的参数
|
||||
*
|
||||
* @throws FileSystemException|RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getConfigureArg(): string
|
||||
@@ -42,10 +43,11 @@ class Extension
|
||||
$arg = $this->getEnableArg();
|
||||
switch (PHP_OS_FAMILY) {
|
||||
case 'Windows':
|
||||
$arg = $this->getWindowsConfigureArg();
|
||||
$arg .= $this->getWindowsConfigureArg();
|
||||
break;
|
||||
case 'Darwin':
|
||||
case 'Linux':
|
||||
case 'BSD':
|
||||
$arg .= $this->getUnixConfigureArg();
|
||||
break;
|
||||
}
|
||||
@@ -56,7 +58,6 @@ class Extension
|
||||
* 根据 ext 的 arg-type 获取对应开启的参数,一般都是 --enable-xxx 和 --with-xxx
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getEnableArg(): string
|
||||
@@ -163,6 +164,65 @@ class Extension
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function runCliCheckUnix(): void
|
||||
{
|
||||
// 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
|
||||
[$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, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
|
||||
if ($ret !== 0) {
|
||||
if ($this->builder->getOption('debug')) {
|
||||
var_dump($out);
|
||||
}
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function runCliCheckWindows(): void
|
||||
{
|
||||
// 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
|
||||
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe --ri "' . $this->getDistName() . '"', false);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
|
||||
}
|
||||
|
||||
if (file_exists(FileSystem::convertPath(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(FileSystem::convertPath(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php'))
|
||||
);
|
||||
|
||||
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -r "' . trim($test) . '"');
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
|
||||
@@ -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-windows、lib-depends-win、lib-depends。
|
||||
如果是 macOS 系统,则依次尝试 lib-depends-darwin、lib-depends-unix、lib-depends。
|
||||
如果是 Linux 系统,则依次尝试 lib-depends-linux、lib-depends-unix、lib-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,58 @@ 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->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build');
|
||||
$this->build();
|
||||
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-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 +178,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}");
|
||||
}
|
||||
}
|
||||
|
||||
35
src/SPC/builder/extension/amqp.php
Normal file
35
src/SPC/builder/extension/amqp.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('amqp')]
|
||||
class amqp extends Extension
|
||||
{
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp.h', '/^#warning.*/m', '');
|
||||
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_framing.h', '/^#warning.*/m', '');
|
||||
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_ssl_socket.h', '/^#warning.*/m', '');
|
||||
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_tcp_socket.h', '/^#warning.*/m', '');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
return '--with-amqp --with-librabbitmq-dir=' . BUILD_ROOT_PATH;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
return '--with-amqp';
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
24
src/SPC/builder/extension/dba.php
Normal file
24
src/SPC/builder/extension/dba.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('dba')]
|
||||
class dba extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$qdbm = $this->builder->getLib('qdbm') ? (' --with-qdbm=' . BUILD_ROOT_PATH) : '';
|
||||
return '--enable-dba' . $qdbm;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
$qdbm = $this->builder->getLib('qdbm') ? ' --with-qdbm' : '';
|
||||
return '--with-dba' . $qdbm;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ 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;
|
||||
@@ -31,12 +32,19 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
// Prevent event extension compile error on macOS
|
||||
if ($this->builder instanceof MacOSBuilder) {
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_OPENPTY 1$/m', '');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,4 +14,9 @@ class ffi extends Extension
|
||||
{
|
||||
return '--with-ffi --enable-zend-signals';
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
return '--with-ffi';
|
||||
}
|
||||
}
|
||||
|
||||
40
src/SPC/builder/extension/gettext.php
Normal file
40
src/SPC/builder/extension/gettext.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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('gettext')]
|
||||
class gettext extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
if ($this->builder instanceof MacOSBuilder) {
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/gettext/config.m4', 'AC_CHECK_LIB($GETTEXT_CHECK_IN_LIB', 'AC_CHECK_LIB(intl');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
if ($this->builder instanceof MacOSBuilder) {
|
||||
$frameworks = ' ' . $this->builder->getFrameworks(true) . ' ';
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lintl', $this->getLibFilesString() . $frameworks);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,20 +5,38 @@ 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;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
return '--enable-glfw=static';
|
||||
}
|
||||
}
|
||||
|
||||
27
src/SPC/builder/extension/iconv.php
Normal file
27
src/SPC/builder/extension/iconv.php
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
28
src/SPC/builder/extension/imap.php
Normal file
28
src/SPC/builder/extension/imap.php
Normal 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;
|
||||
}
|
||||
}
|
||||
23
src/SPC/builder/extension/ldap.php
Normal file
23
src/SPC/builder/extension/ldap.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('ldap')]
|
||||
class ldap extends Extension
|
||||
{
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
$output = shell()->execWithResult('$PKG_CONFIG --libs-only-l --static ldap');
|
||||
if (!empty($output[1][0])) {
|
||||
$libs = $output[1][0];
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lldap ', $libs . ' ');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('mbregex')]
|
||||
@@ -19,4 +20,27 @@ class mbregex extends Extension
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* mbregex is not an extension, we need to overwrite the default check.
|
||||
*/
|
||||
public function runCliCheckUnix(): 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 !');
|
||||
}
|
||||
}
|
||||
|
||||
public function runCliCheckWindows(): void
|
||||
{
|
||||
[$ret, $out] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring"', false);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli does not contain mbstring !');
|
||||
}
|
||||
$out = implode("\n", $out);
|
||||
if (!str_contains($out, 'regex')) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,13 @@ use SPC\util\CustomExt;
|
||||
#[CustomExt('mbstring')]
|
||||
class mbstring extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(): string
|
||||
public function getConfigureArg(): string
|
||||
{
|
||||
$arg = '--enable-mbstring';
|
||||
if ($this->builder->getExt('mbregex') === null) {
|
||||
$arg .= ' --disable-mbregex';
|
||||
} else {
|
||||
$arg .= ' --enable-mbregex';
|
||||
}
|
||||
return $arg;
|
||||
}
|
||||
|
||||
@@ -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"'
|
||||
);
|
||||
|
||||
@@ -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 ';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
26
src/SPC/builder/extension/password_argon2.php
Normal file
26
src/SPC/builder/extension/password_argon2.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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 getDistName(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function runCliCheckUnix(): 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
);
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
|
||||
@@ -13,14 +13,14 @@ class redis extends Extension
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$arg = '--enable-redis';
|
||||
if (!$this->builder->getExt('session')) {
|
||||
$arg .= ' --disable-redis-session';
|
||||
} else {
|
||||
$arg .= ' --enable-redis-session';
|
||||
}
|
||||
$arg .= $this->builder->getExt('session') ? ' --enable-redis-session' : ' --disable-redis-session';
|
||||
$arg .= $this->builder->getExt('igbinary') ? ' --enable-redis-igbinary' : ' --disable-redis-igbinary';
|
||||
if ($this->builder->getLib('zstd')) {
|
||||
$arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"';
|
||||
}
|
||||
if ($this->builder->getLib('liblz4')) {
|
||||
$arg .= ' --enable-redis-lz4 --with-liblz4="' . BUILD_ROOT_PATH . '"';
|
||||
}
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
34
src/SPC/builder/extension/simdjson.php
Normal file
34
src/SPC/builder/extension/simdjson.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('simdjson')]
|
||||
class simdjson extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
$php_ver = $this->builder->getPHPVersionID();
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/ext/simdjson/config.m4',
|
||||
'/php_version=(`.*`)$/m',
|
||||
'php_version=' . strval($php_ver)
|
||||
);
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/ext/simdjson/config.m4',
|
||||
'if test -z "$PHP_CONFIG"; then',
|
||||
'if false; then'
|
||||
);
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/ext/simdjson/config.w32',
|
||||
"'yes',",
|
||||
'PHP_SIMDJSON_SHARED,'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
33
src/SPC/builder/extension/snappy.php
Normal file
33
src/SPC/builder/extension/snappy.php
Normal 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 . '"';
|
||||
}
|
||||
}
|
||||
35
src/SPC/builder/extension/sodium.php
Normal file
35
src/SPC/builder/extension/sodium.php
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
);
|
||||
|
||||
@@ -12,11 +12,31 @@ class swoole extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
// enable swoole
|
||||
$arg = '--enable-swoole';
|
||||
$arg .= $this->builder->getLib('openssl') ? ' --enable-openssl' : ' --disable-openssl --without-openssl';
|
||||
$arg .= $this->builder->getLib('brotli') ? (' --enable-brotli --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
|
||||
// curl hook is buggy for static php
|
||||
$arg .= ' --disable-swoole-curl';
|
||||
|
||||
// commonly-used feature: coroutine-time, disable-thread-context
|
||||
$arg .= ' --enable-swoole-coro-time --disable-thread-context';
|
||||
|
||||
// required feature: curl, openssl (but curl hook is buggy for php 8.0)
|
||||
$arg .= $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl';
|
||||
$arg .= ' --enable-openssl';
|
||||
|
||||
// additional feature: c-ares, brotli, nghttp2 (can be disabled, but we enable it by default in config to support full network feature)
|
||||
$arg .= $this->builder->getLib('libcares') ? ' --enable-cares' : '';
|
||||
$arg .= $this->builder->getLib('brotli') ? (' --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
|
||||
$arg .= $this->builder->getLib('nghttp2') ? (' --with-nghttp2-dir=' . BUILD_ROOT_PATH) : '';
|
||||
|
||||
// additional feature: swoole-pgsql, it should depend on lib [postgresql], but it will lack of CFLAGS etc.
|
||||
// so this is a tricky way (enable ext [pgsql,pdo] to add postgresql hook and pdo_pgsql support)
|
||||
$arg .= $this->builder->getExt('swoole-hook-pgsql') ? '' : ' --disable-swoole-pgsql';
|
||||
|
||||
// enable this feature , need remove pdo_sqlite
|
||||
// more info : https://wenda.swoole.com/detail/109023
|
||||
$arg .= $this->builder->getExt('swoole-hook-sqlite') ? '' : ' --disable-swoole-sqlite';
|
||||
|
||||
// enable this feature , need stop pdo_*
|
||||
// $arg .= $this->builder->getLib('unixodbc') ? ' --with-swoole-odbc=unixODBC,' : ' ';
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
41
src/SPC/builder/extension/swoole_hook_mysql.php
Normal file
41
src/SPC/builder/extension/swoole_hook_mysql.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('swoole-hook-mysql')]
|
||||
class swoole_hook_mysql extends Extension
|
||||
{
|
||||
public function getDistName(): string
|
||||
{
|
||||
return 'swoole';
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
// pdo_mysql doesn't need to be disabled
|
||||
// enable swoole-hook-mysql will enable mysqli, pdo, pdo_mysql, we don't need to add any additional options
|
||||
return '';
|
||||
}
|
||||
|
||||
public function runCliCheckUnix(): void
|
||||
{
|
||||
// skip if not enable swoole
|
||||
if ($this->builder->getExt('swoole') === null) {
|
||||
return;
|
||||
}
|
||||
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
|
||||
$out = implode('', $out);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
|
||||
}
|
||||
if (!str_contains($out, 'mysqlnd')) {
|
||||
throw new RuntimeException('swoole mysql hook is not enabled correctly.');
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/SPC/builder/extension/swoole_hook_pgsql.php
Normal file
45
src/SPC/builder/extension/swoole_hook_pgsql.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('swoole-hook-pgsql')]
|
||||
class swoole_hook_pgsql extends Extension
|
||||
{
|
||||
public function getDistName(): string
|
||||
{
|
||||
return 'swoole';
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
// pdo_pgsql need to be disabled
|
||||
if ($this->builder->getExt('pdo_pgsql') !== null) {
|
||||
throw new WrongUsageException('swoole-hook-pgsql provides pdo_pgsql, if you enable pgsql hook for swoole, you must remove pdo_pgsql extension.');
|
||||
}
|
||||
// enable swoole pgsql hook
|
||||
return '--enable-swoole-pgsql';
|
||||
}
|
||||
|
||||
public function runCliCheckUnix(): void
|
||||
{
|
||||
// skip if not enable swoole
|
||||
if ($this->builder->getExt('swoole') === null) {
|
||||
return;
|
||||
}
|
||||
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
|
||||
$out = implode('', $out);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
|
||||
}
|
||||
if (!str_contains($out, 'coroutine_pgsql')) {
|
||||
throw new RuntimeException('swoole pgsql hook is not enabled correctly.');
|
||||
}
|
||||
}
|
||||
}
|
||||
45
src/SPC/builder/extension/swoole_hook_sqlite.php
Normal file
45
src/SPC/builder/extension/swoole_hook_sqlite.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('swoole-hook-sqlite')]
|
||||
class swoole_hook_sqlite extends Extension
|
||||
{
|
||||
public function getDistName(): string
|
||||
{
|
||||
return 'swoole';
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
// pdo_pgsql need to be disabled
|
||||
if ($this->builder->getExt('pdo_sqlite') !== null) {
|
||||
throw new WrongUsageException('swoole-hook-sqlite provides pdo_sqlite, if you enable sqlite hook for swoole, you must remove pdo_sqlite extension.');
|
||||
}
|
||||
// enable swoole pgsql hook
|
||||
return '--enable-swoole-sqlite';
|
||||
}
|
||||
|
||||
public function runCliCheckUnix(): void
|
||||
{
|
||||
// skip if not enable swoole
|
||||
if ($this->builder->getExt('swoole') === null) {
|
||||
return;
|
||||
}
|
||||
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
|
||||
$out = implode('', $out);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
|
||||
}
|
||||
if (!str_contains($out, 'coroutine_sqlite')) {
|
||||
throw new RuntimeException('swoole sqlite hook is not enabled correctly.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
33
src/SPC/builder/extension/xhprof.php
Normal file
33
src/SPC/builder/extension/xhprof.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('xhprof')]
|
||||
class xhprof extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
if (!is_link(SOURCE_PATH . '/php-src/ext/xhprof')) {
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D xhprof xhprof-src\extension');
|
||||
} else {
|
||||
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && ln -s xhprof-src/extension xhprof');
|
||||
}
|
||||
|
||||
// patch config.m4
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/ext/xhprof/config.m4',
|
||||
'if test -f $phpincludedir/ext/pcre/php_pcre.h; then',
|
||||
'if test -f $abs_srcdir/ext/pcre/php_pcre.h; then'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('xml')]
|
||||
@@ -33,4 +34,25 @@ class xml extends Extension
|
||||
$arg .= ' --with-libxml="' . BUILD_ROOT_PATH . '"';
|
||||
return $arg;
|
||||
}
|
||||
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/win32/build/config.w32', 'dllmain.c ', '');
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
$arg = match ($this->name) {
|
||||
'xml' => '--with-xml',
|
||||
'soap' => '--enable-soap',
|
||||
'xmlreader' => '--enable-xmlreader',
|
||||
'xmlwriter' => '--enable-xmlwriter',
|
||||
'dom' => '--with-dom',
|
||||
'simplexml' => '--with-simplexml',
|
||||
default => throw new RuntimeException('Not accept non-xml extension'),
|
||||
};
|
||||
$arg .= ' --with-libxml';
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
26
src/SPC/builder/extension/yac.php
Normal file
26
src/SPC/builder/extension/yac.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('yac')]
|
||||
class yac extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/yac/storage/allocator/yac_allocator.h', 'defined(HAVE_SHM_MMAP_ANON)', 'defined(YAC_ALLOCATOR_H)');
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/yac/serializer/igbinary.c', '#ifdef YAC_ENABLE_IGBINARY', '#if 1');
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/yac/serializer/json.c', '#if YAC_ENABLE_JSON', '#if 1');
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
return '--enable-yac --enable-igbinary --enable-json';
|
||||
}
|
||||
}
|
||||
17
src/SPC/builder/extension/zlib.php
Normal file
17
src/SPC/builder/extension/zlib.php
Normal 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 . '"';
|
||||
}
|
||||
}
|
||||
253
src/SPC/builder/freebsd/BSDBuilder.php
Normal file
253
src/SPC/builder/freebsd/BSDBuilder.php
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\freebsd;
|
||||
|
||||
use SPC\builder\unix\UnixBuilderBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\SourcePatcher;
|
||||
|
||||
class BSDBuilder extends UnixBuilderBase
|
||||
{
|
||||
/** @var bool Micro patch phar flag */
|
||||
private bool $phar_patched = false;
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
$this->options = $options;
|
||||
|
||||
// ---------- set necessary options ----------
|
||||
// set C Compiler (default: clang)
|
||||
f_putenv('CC=' . $this->getOption('cc', 'clang'));
|
||||
// set C++ Composer (default: clang++)
|
||||
f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
|
||||
// set PATH
|
||||
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
|
||||
// set PKG_CONFIG
|
||||
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
|
||||
// set PKG_CONFIG_PATH
|
||||
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig/');
|
||||
|
||||
// set arch (default: current)
|
||||
$this->setOptionIfNotExist('arch', php_uname('m'));
|
||||
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
|
||||
|
||||
// ---------- set necessary compile environments ----------
|
||||
// concurrency
|
||||
$this->concurrency = SystemUtil::getCpuCount();
|
||||
// cflags
|
||||
$this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
|
||||
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
|
||||
// cmake toolchain
|
||||
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('BSD', $this->getOption('arch'), $this->arch_c_flags);
|
||||
|
||||
// create pkgconfig and include dir (some libs cannot create them automatically)
|
||||
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
||||
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Just start to build statically linked php binary
|
||||
*
|
||||
* @param int $build_target build target
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||
{
|
||||
// ---------- Update extra-libs ----------
|
||||
$extra_libs = $this->getOption('extra-libs', '');
|
||||
// add libc++, some extensions or libraries need it (C++ cannot be linked statically)
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : '');
|
||||
if (!$this->getOption('bloat', false)) {
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
|
||||
} else {
|
||||
logger()->info('bloat linking');
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles())));
|
||||
}
|
||||
$this->setOption('extra-libs', $extra_libs);
|
||||
|
||||
$this->emitPatchPoint('before-php-buildconf');
|
||||
SourcePatcher::patchBeforeBuildconf($this);
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||
|
||||
$this->emitPatchPoint('before-php-configure');
|
||||
SourcePatcher::patchBeforeConfigure($this);
|
||||
|
||||
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
||||
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
|
||||
|
||||
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
||||
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
|
||||
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec(
|
||||
'./configure ' .
|
||||
'--prefix= ' .
|
||||
'--with-valgrind=no ' . // Not detect memory leak
|
||||
'--enable-shared=no ' .
|
||||
'--enable-static=yes ' .
|
||||
"CFLAGS='{$this->arch_c_flags} -Werror=unknown-warning-option' " .
|
||||
'--disable-all ' .
|
||||
'--disable-cgi ' .
|
||||
'--disable-phpdbg ' .
|
||||
($enableCli ? '--enable-cli ' : '--disable-cli ') .
|
||||
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
|
||||
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
|
||||
($enableMicro ? '--enable-micro ' : '--disable-micro ') .
|
||||
$json_74 .
|
||||
$zts .
|
||||
$this->makeExtensionArgs()
|
||||
);
|
||||
|
||||
$this->emitPatchPoint('before-php-make');
|
||||
SourcePatcher::patchBeforeMake($this);
|
||||
|
||||
$this->cleanMake();
|
||||
|
||||
if ($enableCli) {
|
||||
logger()->info('building cli');
|
||||
$this->buildCli();
|
||||
}
|
||||
if ($enableFpm) {
|
||||
logger()->info('building fpm');
|
||||
$this->buildFpm();
|
||||
}
|
||||
if ($enableMicro) {
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro();
|
||||
}
|
||||
if ($enableEmbed) {
|
||||
logger()->info('building embed');
|
||||
if ($enableMicro) {
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
|
||||
}
|
||||
$this->buildEmbed();
|
||||
}
|
||||
|
||||
if (php_uname('m') === $this->getOption('arch')) {
|
||||
$this->emitPatchPoint('before-sanity-check');
|
||||
$this->sanityCheck($build_target);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build cli sapi
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
protected function buildCli(): void
|
||||
{
|
||||
$vars = SystemUtil::makeEnvVarString([
|
||||
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a",
|
||||
]);
|
||||
|
||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||
$shell->exec('sed -ie "s|//lib|/lib|g" Makefile');
|
||||
$shell->exec("make -j{$this->concurrency} {$vars} cli");
|
||||
if (!$this->getOption('no-strip', false)) {
|
||||
$shell->exec('strip sapi/cli/php');
|
||||
}
|
||||
$this->deployBinary(BUILD_TARGET_CLI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build phpmicro sapi
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
protected function buildMicro(): void
|
||||
{
|
||||
if ($this->getPHPVersionID() < 80000) {
|
||||
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
||||
}
|
||||
if ($this->getExt('phar')) {
|
||||
$this->phar_patched = true;
|
||||
SourcePatcher::patchMicro(['phar']);
|
||||
}
|
||||
|
||||
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||
$vars = [
|
||||
// with debug information, optimize for size, remove identifiers, patch fake cli for micro
|
||||
'EXTRA_CFLAGS' => '-g -Os' . $enable_fake_cli,
|
||||
// link resolv library (macOS needs it)
|
||||
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a",
|
||||
];
|
||||
$vars = SystemUtil::makeEnvVarString($vars);
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec("make -j{$this->concurrency} {$vars} micro");
|
||||
|
||||
if (!$this->getOption('no-strip', false)) {
|
||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec('strip --strip-all micro.sfx');
|
||||
}
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
|
||||
if ($this->phar_patched) {
|
||||
SourcePatcher::patchMicro(['phar'], true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build fpm sapi
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
protected function buildFpm(): void
|
||||
{
|
||||
$vars = SystemUtil::makeEnvVarString([
|
||||
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a", // link resolv library (macOS needs it)
|
||||
]);
|
||||
|
||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||
$shell->exec("make -j{$this->concurrency} {$vars} fpm");
|
||||
if (!$this->getOption('no-strip', false)) {
|
||||
$shell->exec('strip sapi/fpm/php-fpm');
|
||||
}
|
||||
$this->deployBinary(BUILD_TARGET_FPM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build embed sapi
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function buildEmbed(): void
|
||||
{
|
||||
$vars = SystemUtil::makeEnvVarString([
|
||||
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} /usr/lib/libm.a", // link resolv library (macOS needs it)
|
||||
]);
|
||||
|
||||
shell()
|
||||
->cd(SOURCE_PATH . '/php-src')
|
||||
->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install")
|
||||
// Workaround for https://github.com/php/php-src/issues/12082
|
||||
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o')
|
||||
->exec('mkdir ' . BUILD_ROOT_PATH . '/lib/php-o')
|
||||
->cd(BUILD_ROOT_PATH . '/lib/php-o')
|
||||
->exec('ar x ' . BUILD_ROOT_PATH . '/lib/libphp.a')
|
||||
->exec('rm ' . BUILD_ROOT_PATH . '/lib/libphp.a')
|
||||
->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o')
|
||||
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o');
|
||||
}
|
||||
}
|
||||
46
src/SPC/builder/freebsd/SystemUtil.php
Normal file
46
src/SPC/builder/freebsd/SystemUtil.php
Normal 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),
|
||||
};
|
||||
}
|
||||
}
|
||||
27
src/SPC/builder/freebsd/library/BSDLibraryBase.php
Normal file
27
src/SPC/builder/freebsd/library/BSDLibraryBase.php
Normal 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;
|
||||
}
|
||||
}
|
||||
12
src/SPC/builder/freebsd/library/bzip2.php
Normal file
12
src/SPC/builder/freebsd/library/bzip2.php
Normal 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';
|
||||
}
|
||||
21
src/SPC/builder/freebsd/library/curl.php
Normal file
21
src/SPC/builder/freebsd/library/curl.php
Normal 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;
|
||||
}
|
||||
}
|
||||
12
src/SPC/builder/freebsd/library/onig.php
Normal file
12
src/SPC/builder/freebsd/library/onig.php
Normal 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';
|
||||
}
|
||||
63
src/SPC/builder/freebsd/library/openssl.php
Normal file
63
src/SPC/builder/freebsd/library/openssl.php
Normal 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']);
|
||||
}
|
||||
}
|
||||
15
src/SPC/builder/freebsd/library/pkgconfig.php
Normal file
15
src/SPC/builder/freebsd/library/pkgconfig.php
Normal 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';
|
||||
}
|
||||
12
src/SPC/builder/freebsd/library/zlib.php
Normal file
12
src/SPC/builder/freebsd/library/zlib.php
Normal 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';
|
||||
}
|
||||
@@ -4,102 +4,97 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux;
|
||||
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\traits\UnixBuilderTrait;
|
||||
use SPC\builder\unix\UnixBuilderBase;
|
||||
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
|
||||
class LinuxBuilder extends UnixBuilderBase
|
||||
{
|
||||
/** 编译的 Unix 工具集 */
|
||||
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,65 +119,80 @@ 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())));
|
||||
}
|
||||
|
||||
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}' ";
|
||||
// add libstdc++, some extensions or libraries need it
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : '');
|
||||
$this->setOption('extra-libs', $extra_libs);
|
||||
$cflags = $this->arch_c_flags;
|
||||
$use_lld = '';
|
||||
|
||||
switch ($this->libc) {
|
||||
case 'musl_wrapper':
|
||||
case 'glibc':
|
||||
$cflags .= ' -static-libgcc -I"' . BUILD_INCLUDE_PATH . '"';
|
||||
break;
|
||||
case 'musl':
|
||||
if (str_ends_with($this->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,
|
||||
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
|
||||
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
||||
'LIBS' => '-ldl -lpthread',
|
||||
]);
|
||||
|
||||
$this->emitPatchPoint('before-php-buildconf');
|
||||
SourcePatcher::patchBeforeBuildconf($this);
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||
|
||||
$this->emitPatchPoint('before-php-configure');
|
||||
SourcePatcher::patchBeforeConfigure($this);
|
||||
|
||||
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;
|
||||
|
||||
// upx pack and strip for micro
|
||||
if ($this->getOption('with-upx-pack', false)) {
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
|
||||
'/POST_MICRO_BUILD_COMMANDS=.*/',
|
||||
'POST_MICRO_BUILD_COMMANDS=\$(STRIP) \$(MICRO_STRIP_FLAGS) \$(SAPI_MICRO_PATH) && ' . $this->getOption('upx-exec') . ' --best \$(SAPI_MICRO_PATH)',
|
||||
);
|
||||
} elseif (!$this->getOption('no-strip', false)) {
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
|
||||
'/POST_MICRO_BUILD_COMMANDS=.*/',
|
||||
'POST_MICRO_BUILD_COMMANDS=\$(STRIP) \$(MICRO_STRIP_FLAGS) \$(SAPI_MICRO_PATH)',
|
||||
);
|
||||
} else {
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
|
||||
'/POST_MICRO_BUILD_COMMANDS=.*/',
|
||||
'POST_MICRO_BUILD_COMMANDS=true',
|
||||
);
|
||||
}
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec(
|
||||
"{$this->getOption('ld_library_path')} " .
|
||||
'./configure ' .
|
||||
'--prefix= ' .
|
||||
'--with-valgrind=no ' .
|
||||
@@ -191,43 +201,98 @@ 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' : '') . ' ' .
|
||||
$this->makeExtensionArgs() . ' ' .
|
||||
$envs
|
||||
$zts .
|
||||
$maxExecutionTimers .
|
||||
$this->makeExtensionArgs() .
|
||||
' ' . $envs_build_php . ' '
|
||||
);
|
||||
|
||||
$this->emitPatchPoint('before-php-make');
|
||||
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->emitPatchPoint('before-sanity-check');
|
||||
$this->sanityCheck($build_target);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build cli sapi
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
protected 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('with-upx-pack')) {
|
||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')
|
||||
->exec('strip --strip-all php')
|
||||
->exec($this->getOption('upx-exec') . ' --best php');
|
||||
} elseif (!$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
|
||||
*/
|
||||
protected function buildMicro(): void
|
||||
{
|
||||
if ($this->getPHPVersionID() < 80000) {
|
||||
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
||||
}
|
||||
if ($this->getExt('phar')) {
|
||||
$this->phar_patched = true;
|
||||
SourcePatcher::patchMicro(['phar']);
|
||||
}
|
||||
|
||||
$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");
|
||||
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
|
||||
if ($this->phar_patched) {
|
||||
SourcePatcher::patchMicro(['phar'], true);
|
||||
@@ -235,78 +300,58 @@ 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
|
||||
protected 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");
|
||||
|
||||
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");
|
||||
if ($this->getOption('with-upx-pack')) {
|
||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')
|
||||
->exec('strip --strip-all php-fpm')
|
||||
->exec($this->getOption('upx-exec') . ' --best php-fpm');
|
||||
} elseif (!$this->getOption('no-strip', false)) {
|
||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-all php-fpm');
|
||||
}
|
||||
$this->deployBinary(BUILD_TARGET_FPM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build embed sapi
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function buildEmbed(): void
|
||||
{
|
||||
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
||||
|
||||
shell()
|
||||
->cd(SOURCE_PATH . '/php-src')
|
||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||
->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install");
|
||||
}
|
||||
|
||||
private function getBuildVars($input = []): array
|
||||
{
|
||||
$use_lld = '';
|
||||
if (str_ends_with(getenv('CC'), 'clang') && SystemUtil::findCommand('lld')) {
|
||||
$use_lld = '-Xcompiler -fuse-ld=lld';
|
||||
}
|
||||
$optimization = $this->getOption('no-strip', false) ? '-g -O0' : '-g0 -Os';
|
||||
$cflags = isset($input['EXTRA_CFLAGS']) && $input['EXTRA_CFLAGS'] ? " {$input['EXTRA_CFLAGS']}" : '';
|
||||
$libs = isset($input['EXTRA_LIBS']) && $input['EXTRA_LIBS'] ? " {$input['EXTRA_LIBS']}" : '';
|
||||
$ldflags = isset($input['EXTRA_LDFLAGS_PROGRAM']) && $input['EXTRA_LDFLAGS_PROGRAM'] ? " {$input['EXTRA_LDFLAGS_PROGRAM']}" : '';
|
||||
$tune_c_flags = implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags));
|
||||
return [
|
||||
'EXTRA_CFLAGS' => "{$optimization} -fno-ident -fPIE {$tune_c_flags}{$cflags}",
|
||||
'EXTRA_LIBS' => "{$this->getOption('extra-libs', '')} {$libs}",
|
||||
'EXTRA_LDFLAGS_PROGRAM' => "{$use_lld} -all-static{$ldflags}",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -104,11 +110,7 @@ class SystemUtil
|
||||
public static function getTuneCFlags(string $arch): array
|
||||
{
|
||||
return match ($arch) {
|
||||
'x86_64' => [
|
||||
'-march=corei7',
|
||||
'-mtune=core-avx2',
|
||||
],
|
||||
'arm64', 'aarch64' => [],
|
||||
'x86_64', 'arm64', 'aarch64' => [],
|
||||
default => throw new RuntimeException('unsupported arch: ' . $arch),
|
||||
};
|
||||
}
|
||||
@@ -120,7 +122,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 +131,7 @@ class SystemUtil
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
public static function getCrossCompilePrefix(string $cc, string $arch): string
|
||||
{
|
||||
@@ -159,6 +162,7 @@ class SystemUtil
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public static function findStaticLibs(array $names): ?array
|
||||
{
|
||||
$ret = [];
|
||||
@@ -187,6 +191,7 @@ class SystemUtil
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public static function findHeaders(array $names): ?array
|
||||
{
|
||||
$ret = [];
|
||||
@@ -200,4 +205,21 @@ class SystemUtil
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fully-supported linux distros.
|
||||
*
|
||||
* @return string[] List of supported Linux distro name for doctor
|
||||
*/
|
||||
public static function getSupportedDistros(): array
|
||||
{
|
||||
return [
|
||||
// debian-like
|
||||
'debian', 'ubuntu', 'Deepin',
|
||||
// rhel-like
|
||||
'redhat',
|
||||
// alpine
|
||||
'alpine',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
src/SPC/builder/linux/library/gettext.php
Normal file
12
src/SPC/builder/linux/library/gettext.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class gettext extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\gettext;
|
||||
|
||||
public const NAME = 'gettext';
|
||||
}
|
||||
@@ -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}")
|
||||
|
||||
67
src/SPC/builder/linux/library/imap.php
Normal file
67
src/SPC/builder/linux/library/imap.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class imap extends LinuxLibraryBase
|
||||
{
|
||||
public const NAME = 'imap';
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
$cc = getenv('CC') ?: 'gcc';
|
||||
// FileSystem::replaceFileStr($this->source_dir . '/Makefile', '-DMAC_OSX_KLUDGE=1', '');
|
||||
FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', 'CC=cc', "CC={$cc}");
|
||||
/* FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', '-lcrypto -lz', '-lcrypto');
|
||||
FileSystem::replaceFileStr($this->source_dir . '/src/osdep/unix/Makefile', '-lcrypto', '-lcrypto -lz');
|
||||
FileSystem::replaceFileStr(
|
||||
$this->source_dir . '/src/osdep/unix/ssl_unix.c',
|
||||
"#include <x509v3.h>\n#include <ssl.h>",
|
||||
"#include <ssl.h>\n#include <x509v3.h>"
|
||||
);
|
||||
// SourcePatcher::patchFile('1006_openssl1.1_autoverify.patch', $this->source_dir);
|
||||
SourcePatcher::patchFile('2014_openssl1.1.1_sni.patch', $this->source_dir); */
|
||||
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'SSLINCLUDE=/usr/include/openssl', 'SSLINCLUDE=' . BUILD_INCLUDE_PATH);
|
||||
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'SSLLIB=/usr/lib', 'SSLLIB=' . BUILD_LIB_PATH);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
if ($this->builder->getLib('openssl')) {
|
||||
$ssl_options = 'SPECIALAUTHENTICATORS=ssl SSLTYPE=unix.nopwd SSLINCLUDE=' . BUILD_INCLUDE_PATH . ' SSLLIB=' . BUILD_LIB_PATH;
|
||||
} else {
|
||||
$ssl_options = 'SSLTYPE=none';
|
||||
}
|
||||
shell()->cd($this->source_dir)
|
||||
->exec('make clean')
|
||||
->exec('touch ip6')
|
||||
->exec('chmod +x tools/an')
|
||||
->exec('chmod +x tools/ua')
|
||||
->exec('chmod +x src/osdep/unix/drivers')
|
||||
->exec('chmod +x src/osdep/unix/mkauths')
|
||||
->exec(
|
||||
"yes | make slx {$ssl_options}"
|
||||
);
|
||||
try {
|
||||
shell()
|
||||
->exec("cp -rf {$this->source_dir}/c-client/c-client.a " . BUILD_LIB_PATH . '/libc-client.a')
|
||||
->exec("cp -rf {$this->source_dir}/c-client/*.c " . BUILD_LIB_PATH . '/')
|
||||
->exec("cp -rf {$this->source_dir}/c-client/*.h " . BUILD_INCLUDE_PATH . '/')
|
||||
->exec("cp -rf {$this->source_dir}/src/osdep/unix/*.h " . BUILD_INCLUDE_PATH . '/');
|
||||
} catch (\Throwable) {
|
||||
// last command throws an exception, no idea why since it works
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/SPC/builder/linux/library/ldap.php
Normal file
12
src/SPC/builder/linux/library/ldap.php
Normal 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';
|
||||
}
|
||||
20
src/SPC/builder/linux/library/libargon2.php
Normal file
20
src/SPC/builder/linux/library/libargon2.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libargon2 extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\libargon2;
|
||||
|
||||
public const NAME = 'libargon2';
|
||||
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'LIBRARY_REL ?= lib/x86_64-linux-gnu', 'LIBRARY_REL ?= lib');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
12
src/SPC/builder/linux/library/libcares.php
Normal file
12
src/SPC/builder/linux/library/libcares.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class libcares extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\libcares;
|
||||
|
||||
public const NAME = 'libcares';
|
||||
}
|
||||
50
src/SPC/builder/linux/library/libffi.php
Normal file
50
src/SPC/builder/linux/library/libffi.php
Normal 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']);
|
||||
}
|
||||
}
|
||||
12
src/SPC/builder/linux/library/liblz4.php
Normal file
12
src/SPC/builder/linux/library/liblz4.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class liblz4 extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\liblz4;
|
||||
|
||||
public const NAME = 'liblz4';
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
12
src/SPC/builder/linux/library/librabbitmq.php
Normal file
12
src/SPC/builder/linux/library/librabbitmq.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class librabbitmq extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\librabbitmq;
|
||||
|
||||
public const NAME = 'librabbitmq';
|
||||
}
|
||||
12
src/SPC/builder/linux/library/libtiff.php
Normal file
12
src/SPC/builder/linux/library/libtiff.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class libtiff extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\libtiff;
|
||||
|
||||
public const NAME = 'libtiff';
|
||||
}
|
||||
12
src/SPC/builder/linux/library/libuuid.php
Normal file
12
src/SPC/builder/linux/library/libuuid.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class libuuid extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\libuuid;
|
||||
|
||||
public const NAME = 'libuuid';
|
||||
}
|
||||
12
src/SPC/builder/linux/library/libuv.php
Normal file
12
src/SPC/builder/linux/library/libuv.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class libuv extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\libuv;
|
||||
|
||||
public const NAME = 'libuv';
|
||||
}
|
||||
@@ -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,25 @@ class libxml2 extends LinuxLibraryBase
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function build()
|
||||
public function build(): void
|
||||
{
|
||||
$enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
|
||||
$enable_zlib = $this->builder->getLib('zlib') ? ('ON -DZLIB_LIBRARY=' . BUILD_LIB_PATH . '/libz.a -DZLIB_INCLUDE_DIR=' . BUILD_INCLUDE_PATH) : '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 ' .
|
||||
"{$this->builder->makeCmakeArgs()} " .
|
||||
'cmake ' .
|
||||
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
|
||||
'-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' .
|
||||
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||
'-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 +42,12 @@ class libxml2 extends LinuxLibraryBase
|
||||
'..'
|
||||
)
|
||||
->exec("cmake --build . -j {$this->builder->concurrency}")
|
||||
->exec("make install DESTDIR={$destdir}");
|
||||
->exec('make install');
|
||||
|
||||
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'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
15
src/SPC/builder/linux/library/libxslt.php
Normal file
15
src/SPC/builder/linux/library/libxslt.php
Normal 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';
|
||||
}
|
||||
@@ -1,20 +1,4 @@
|
||||
<?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);
|
||||
|
||||
@@ -22,42 +6,7 @@ namespace SPC\builder\linux\library;
|
||||
|
||||
class nghttp2 extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\nghttp2;
|
||||
|
||||
public const NAME = 'nghttp2';
|
||||
|
||||
public function build()
|
||||
{
|
||||
$args = $this->builder->makeAutoconfArgs(static::NAME, [
|
||||
'zlib' => null,
|
||||
'openssl' => null,
|
||||
'libxml2' => null,
|
||||
'libev' => null,
|
||||
'libcares' => null,
|
||||
'libngtcp2' => null,
|
||||
'libnghttp3' => null,
|
||||
'libbpf' => null,
|
||||
'libevent-openssl' => null,
|
||||
'jansson' => null,
|
||||
'jemalloc' => null,
|
||||
'systemd' => null,
|
||||
'cunit' => null,
|
||||
]);
|
||||
|
||||
[,,$destdir] = SEPARATED_PATH;
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->exec(
|
||||
"{$this->builder->configure_env} ./configure " .
|
||||
'--enable-static ' .
|
||||
'--disable-shared ' .
|
||||
"--host={$this->builder->gnu_arch}-unknown-linux " .
|
||||
'--enable-lib-only ' .
|
||||
'--with-boost=no ' .
|
||||
$args . ' ' .
|
||||
'--prefix='
|
||||
)
|
||||
->exec('make clean')
|
||||
->exec("make -j{$this->builder->concurrency}")
|
||||
->exec("make install DESTDIR={$destdir}");
|
||||
$this->patchPkgconfPrefix(['libnghttp2.pc']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,26 +23,29 @@ namespace SPC\builder\linux\library;
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class 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,21 +61,31 @@ 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}\"")
|
||||
->exec("make install_sw DESTDIR={$destdir}");
|
||||
$this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']);
|
||||
// patch for openssl 3.3.0+
|
||||
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc'), 'prefix=')) {
|
||||
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
|
||||
}
|
||||
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc'), 'prefix=')) {
|
||||
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
|
||||
}
|
||||
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc'), 'prefix=')) {
|
||||
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
src/SPC/builder/linux/library/qdbm.php
Normal file
12
src/SPC/builder/linux/library/qdbm.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class qdbm extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\qdbm;
|
||||
|
||||
public const NAME = 'qdbm';
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user