mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-03 14:55:39 +08:00
Compare commits
128 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 |
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
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
otechie: # Replace with a single Otechie username
|
otechie: # Replace with a single Otechie username
|
||||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
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']
|
custom: 'https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md' # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
||||||
|
|||||||
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
|
||||||
53
.github/workflows/release-build.yml
vendored
53
.github/workflows/release-build.yml
vendored
@@ -15,14 +15,15 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
php-version:
|
php-version:
|
||||||
- "8.1"
|
- "8.2"
|
||||||
micro-version:
|
micro-version:
|
||||||
- "8.1.26"
|
- "8.2.16"
|
||||||
operating-system:
|
operating-system:
|
||||||
- "linux-x86_64"
|
- "linux-x86_64"
|
||||||
- "macos-x86_64"
|
- "macos-x86_64"
|
||||||
- "linux-aarch64"
|
- "linux-aarch64"
|
||||||
- "macos-aarch64"
|
- "macos-aarch64"
|
||||||
|
- "windows-x64"
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout"
|
- name: "Checkout"
|
||||||
uses: "actions/checkout@v4"
|
uses: "actions/checkout@v4"
|
||||||
@@ -59,31 +60,51 @@ jobs:
|
|||||||
|
|
||||||
- name: "Download minimal combination"
|
- name: "Download minimal combination"
|
||||||
run: |
|
run: |
|
||||||
curl https://dl.static-php.dev/static-php-cli/minimal/php-${{ matrix.micro-version }}-micro-${{ matrix.operating-system }}.tar.gz -o tmp.tgz
|
if [ "${{ matrix.operating-system }}" = "windows-x64" ]; then
|
||||||
tar -zxvf tmp.tgz
|
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"
|
- name: "Generate Executable"
|
||||||
run: |
|
run: |
|
||||||
cat micro.sfx spc.phar > spc
|
bin/spc micro:combine spc.phar -M micro.sfx -O spc -I "memory_limit=2G"
|
||||||
chmod +x spc
|
if [ "${{ matrix.operating-system }}" = "windows-x64" ]; then
|
||||||
|
mv spc spc.exe
|
||||||
|
else
|
||||||
|
chmod +x spc
|
||||||
|
fi
|
||||||
|
|
||||||
- name: "Archive Executable"
|
- name: "Archive Executable"
|
||||||
run: |
|
run: |
|
||||||
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
|
if [ "${{ matrix.operating-system }}" != "windows-x64" ]; then
|
||||||
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
|
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
|
||||||
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
|
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
|
||||||
if [ "${{ matrix.operating-system }}" == "linux-x86_64" ]; then
|
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
|
||||||
./spc dev:extensions
|
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
|
fi
|
||||||
|
|
||||||
- name: "Copy file"
|
- name: "Copy file"
|
||||||
run: "mkdir dist/ && cp ${{ env.filename }} dist/ && cp spc dist/spc-$OS"
|
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
|
- name: upload binaries to release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: ${{startsWith(github.ref, 'refs/tags/') }}
|
if: ${{startsWith(github.ref, 'refs/tags/') }}
|
||||||
with:
|
with:
|
||||||
files: ${{ env.filename }}
|
files: dist/${{ env.filename }}
|
||||||
|
|
||||||
- name: "Deploy to Self-Hosted Server"
|
- name: "Deploy to Self-Hosted Server"
|
||||||
if: github.repository == 'crazywhalecc/static-php-cli'
|
if: github.repository == 'crazywhalecc/static-php-cli'
|
||||||
@@ -100,5 +121,5 @@ jobs:
|
|||||||
- name: "Upload Artifact"
|
- name: "Upload Artifact"
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
path: spc
|
path: spc${{ env.SUFFIX }}
|
||||||
name: spc-${{ matrix.operating-system }}
|
name: spc-${{ matrix.operating-system }}${{ env.SUFFIX }}
|
||||||
|
|||||||
19
.github/workflows/tests.yml
vendored
19
.github/workflows/tests.yml
vendored
@@ -114,6 +114,8 @@ jobs:
|
|||||||
os:
|
os:
|
||||||
- ubuntu-latest
|
- ubuntu-latest
|
||||||
- macos-latest
|
- macos-latest
|
||||||
|
- windows-latest
|
||||||
|
- macos-14
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout"
|
- name: "Checkout"
|
||||||
@@ -127,6 +129,13 @@ jobs:
|
|||||||
extensions: curl, openssl, mbstring
|
extensions: curl, openssl, mbstring
|
||||||
ini-values: memory_limit=-1
|
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"
|
- name: "Cache Composer packages"
|
||||||
id: composer-cache
|
id: composer-cache
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
@@ -150,7 +159,13 @@ jobs:
|
|||||||
run: bin/spc doctor --auto-fix
|
run: bin/spc doctor --auto-fix
|
||||||
|
|
||||||
- name: "Run Build Tests (download)"
|
- name: "Run Build Tests (download)"
|
||||||
run: bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --with-php=${{ matrix.php }} --debug
|
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)"
|
- name: "Run Build Tests (build)"
|
||||||
run: bin/spc build $(php src/globals/test-extensions.php cmd) --build-cli --build-micro --build-fpm --debug
|
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
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,6 +16,9 @@ docker/source/
|
|||||||
# default source build root directory
|
# default source build root directory
|
||||||
/buildroot/
|
/buildroot/
|
||||||
|
|
||||||
|
# default package root directory
|
||||||
|
/pkgroot/
|
||||||
|
|
||||||
# tools cache files
|
# tools cache files
|
||||||
.php-cs-fixer.cache
|
.php-cs-fixer.cache
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
|
|||||||
201
README-zh.md
201
README-zh.md
@@ -1,32 +1,45 @@
|
|||||||
# static-php-cli
|
# static-php-cli
|
||||||
|
|
||||||
Build single static PHP binary, with PHP project together, with popular extensions included.
|
[](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)
|
||||||
|
|
||||||
🌐 **[中文](README-zh.md)** | **[English](README.md)**
|
**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。
|
||||||
|
|
||||||
编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携!(cli SAPI)
|
目前 static-php-cli 支持 `cli`、`fpm`、`embed` 和 `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**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。
|
||||||
|
|
||||||
同时可以使用 micro 二进制文件,将 PHP 源码和 PHP 二进制构建为一个文件分发!(micro SAPI)
|
## 特性
|
||||||
|
|
||||||
<img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
static-php-cli(简称 `spc`)有许多特性:
|
||||||
|
|
||||||
> 该 SAPI 源自 [dixyes/phpmicro](https://github.com/dixyes/phpmicro) 的 [Fork 仓库](https://github.com/static-php/phpmicro)。
|
- :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:**
|
||||||
[]()
|
|
||||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
|
|
||||||
[]()
|
|
||||||
[]()
|
|
||||||
|
|
||||||
> 项目名称是 static-php-cli,但其实支持 cli、fpm、micro 和 embed SAPI 😎
|
<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>。
|
目前 README 编写了基本用法。有关 static-php-cli 所有的功能,请点击这里查看文档:<https://static-php.dev>。
|
||||||
|
|
||||||
## 自托管直接下载
|
## 直接下载
|
||||||
|
|
||||||
如果你不想自行编译 PHP,可以从本项目现有的示例 Action 下载 Artifact,也可以从自托管的服务器下载。
|
如果你不想自行编译 PHP,可以从本项目现有的示例 Action 下载 Artifact,也可以从自托管的服务器下载。
|
||||||
|
|
||||||
@@ -34,27 +47,47 @@ Build single static PHP binary, with PHP project together, with popular extensio
|
|||||||
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/):bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 70MB 左右。
|
- [扩展组合 - 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 左右。
|
- [扩展组合 - 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
|
## 使用 static-php-cli 构建 PHP
|
||||||
|
|
||||||
### 编译环境需求
|
### 编译环境需求
|
||||||
|
|
||||||
|
- PHP >= 8.1(这是 spc 自身需要的版本,不是支持的构建版本)
|
||||||
|
- 扩展:`mbstring,tokenizer,phar`
|
||||||
|
- 系统安装了 `curl` 和 `git`
|
||||||
|
|
||||||
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
||||||
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
|
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含上面提到的扩展和 PHP 版本大于等于 8.1 即可。
|
||||||
|
|
||||||
下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
|
下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
|
||||||
|
|
||||||
| | x86_64 | aarch64 |
|
| | x86_64 | aarch64 |
|
||||||
|---------|----------------------|----------------------|
|
|---------|----------------------|----------------------|
|
||||||
| macOS | :octocat: :computer: | :computer: |
|
| macOS | :octocat: :computer: | :octocat: :computer: |
|
||||||
| Linux | :octocat: :computer: | :octocat: :computer: |
|
| Linux | :octocat: :computer: | :octocat: :computer: |
|
||||||
| Windows | | |
|
| Windows | :computer: | |
|
||||||
| FreeBSD | :computer: | :computer: |
|
| FreeBSD | :computer: | :computer: |
|
||||||
|
|
||||||
> macOS-arm64 因 GitHub 暂未提供 arm runner,如果要构建 arm 二进制,可以使用手动构建。
|
当前支持编译的 PHP 版本:
|
||||||
|
|
||||||
目前支持编译的 PHP 版本为:`7.3`,`7.4`,`8.0`,`8.1`,`8.2`,`8.3`。
|
> :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: | |
|
||||||
|
|
||||||
|
### 支持的扩展
|
||||||
|
|
||||||
请先根据下方扩展列表选择你要编译的扩展。
|
请先根据下方扩展列表选择你要编译的扩展。
|
||||||
|
|
||||||
@@ -63,7 +96,7 @@ Build single static PHP binary, with PHP project together, with popular extensio
|
|||||||
|
|
||||||
> 如果这里没有你需要的扩展,可以提交 Issue。
|
> 如果这里没有你需要的扩展,可以提交 Issue。
|
||||||
|
|
||||||
### 使用 Actions 构建
|
### 在线构建(使用 GitHub Actions)
|
||||||
|
|
||||||
使用 GitHub Action 可以方便地构建一个静态编译的 PHP,同时可以自行定义要编译的扩展。
|
使用 GitHub Action 可以方便地构建一个静态编译的 PHP,同时可以自行定义要编译的扩展。
|
||||||
|
|
||||||
@@ -74,72 +107,85 @@ Build single static PHP binary, with PHP project together, with popular extensio
|
|||||||
|
|
||||||
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
|
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
|
||||||
|
|
||||||
### 手动构建(使用 SPC 二进制)
|
### 本地构建(使用 spc 二进制)
|
||||||
|
|
||||||
本项目提供了一个 static-php-cli 的二进制文件,你可以直接下载对应平台的二进制文件,然后使用它来构建静态的 PHP。目前 `spc` 二进制支持的平台有 Linux 和 macOS。
|
该项目提供了 static-php-cli 的二进制文件:`spc`。
|
||||||
|
您可以使用 `spc` 二进制文件,无需安装任何运行时(用起来就像 golang 程序)。
|
||||||
|
目前,`spc` 二进制文件提供的平台有 Linux 和 macOS。
|
||||||
|
|
||||||
下面是从 GitHub Action 下载的方法:
|
使用以下命令从自托管服务器下载:
|
||||||
|
|
||||||
1. 进入 [GitHub Action](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml)。
|
|
||||||
2. 选择一个最新的构建任务,进入后选择 `Artifacts`,下载对应平台的二进制文件。
|
|
||||||
3. 解压 `.zip` 文件。解压后,为其添加执行权限:`chmod +x ./spc`。
|
|
||||||
|
|
||||||
你也可以从自托管的服务器下载二进制文件:[进入](https://dl.static-php.dev/static-php-cli/spc-bin/nightly/)。
|
|
||||||
|
|
||||||
### 手动构建(使用源码)
|
|
||||||
|
|
||||||
先克隆本项目:
|
|
||||||
|
|
||||||
```bash
|
```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
|
git clone https://github.com/crazywhalecc/static-php-cli.git
|
||||||
```
|
```
|
||||||
|
|
||||||
如果你本机没有安装 PHP,你需要先使用包管理(例如 brew、apt、yum、apk 等)安装 php。
|
如果您的系统上尚未安装 php,我们建议你使用内置的 setup-runtime 自动安装 PHP 和 Composer。
|
||||||
|
|
||||||
你也可以通过 `bin/setup-runtime` 命令下载静态编译好的 php-cli 和 Composer。下载的 php 和 Composer 将保存为 `bin/php` 和 `bin/composer`。
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd static-php-cli
|
cd static-php-cli
|
||||||
chmod +x bin/setup-runtime
|
chmod +x bin/setup-runtime
|
||||||
./bin/setup-runtime
|
# it will download static php (from self-hosted server) and composer (from getcomposer)
|
||||||
|
bin/setup-runtime
|
||||||
# 使用独立的 php 运行 static-php-cli
|
# initialize composer deps
|
||||||
./bin/php bin/spc
|
bin/composer install
|
||||||
|
# chmod
|
||||||
# 使用 composer
|
|
||||||
./bin/php bin/composer
|
|
||||||
|
|
||||||
# 初始化本项目
|
|
||||||
cd static-php-cli
|
|
||||||
composer update
|
|
||||||
chmod +x bin/spc
|
chmod +x bin/spc
|
||||||
|
bin/spc --version
|
||||||
```
|
```
|
||||||
|
|
||||||
### 使用 static-php-cli 命令行程序
|
### 开始构建 PHP
|
||||||
|
|
||||||
下面是使用 static-php-cli 编译静态 php 和 micro 的基础用法:
|
下面是使用 static-php-cli 的基础用法:
|
||||||
|
|
||||||
> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `bin/spc` 替换为 `./spc`。
|
> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `./bin/spc` 替换为 `./spc`。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 检查环境依赖,并根据提示的命令安装缺失的编译工具
|
# 检查环境依赖,并根据尝试自动安装缺失的编译工具
|
||||||
./bin/spc doctor
|
./bin/spc doctor --auto-fix
|
||||||
|
|
||||||
# 拉取所有依赖库
|
# 拉取所有依赖库
|
||||||
./bin/spc fetch --all
|
./bin/spc download --all
|
||||||
# 只拉取编译指定扩展需要的所有依赖
|
# 只拉取编译指定扩展需要的所有依赖(推荐)
|
||||||
./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
|
./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
|
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
|
||||||
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
|
./bin/spc 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
|
||||||
```
|
```
|
||||||
|
|
||||||
你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.3 ~ 8.3:
|
其中,目前支持构建 cli,micro,fpm 和 embed,使用以下参数的一个或多个来指定编译的 SAPI:
|
||||||
|
|
||||||
```bash
|
|
||||||
# 优先考虑使用 >= 8.0 的 PHP 版本,因为 phpmicro 不支持在 PHP7 中构建
|
|
||||||
./bin/spc download --with-php=8.2 --all
|
|
||||||
```
|
|
||||||
|
|
||||||
其中,目前支持构建 cli,micro,fpm 三种静态二进制,使用以下参数的一个或多个来指定编译的 SAPI:
|
|
||||||
|
|
||||||
- `--build-cli`:构建 cli 二进制
|
- `--build-cli`:构建 cli 二进制
|
||||||
- `--build-micro`:构建 phpmicro 自执行二进制
|
- `--build-micro`:构建 phpmicro 自执行二进制
|
||||||
@@ -150,18 +196,10 @@ chmod +x bin/spc
|
|||||||
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
|
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/spc build openssl,pcntl,mbstring --debug --build-all
|
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
|
||||||
./bin/spc fetch --all --debug
|
./bin/spc download --all --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
此外,默认编译的 PHP 为 NTS 版本。如需编译线程安全版本(ZTS),只需添加参数 `--enable-zts` 即可。
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./bin/spc build openssl,pcntl --build-all --enable-zts
|
|
||||||
```
|
|
||||||
|
|
||||||
同时,你也可以使用参数 `--no-strip` 来关闭裁剪,关闭裁剪后可以使用 gdb 等工具调试,但这样会让静态二进制体积变大。
|
|
||||||
|
|
||||||
## 不同 SAPI 的使用
|
## 不同 SAPI 的使用
|
||||||
|
|
||||||
### 使用 cli
|
### 使用 cli
|
||||||
@@ -237,18 +275,17 @@ bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=sys
|
|||||||
|
|
||||||
## 赞助本项目
|
## 赞助本项目
|
||||||
|
|
||||||
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。
|
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。你捐赠的一部分将会被用于维护 **static-php.dev** 服务器。
|
||||||
|
|
||||||
## 开源协议
|
## 开源协议
|
||||||
|
|
||||||
本项目依据旧版本惯例采用 MIT License 开源,部分扩展的集成编译命令参考或修改自以下项目:
|
本项目采用 MIT License 许可开源,下面是类似的项目:
|
||||||
|
|
||||||
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)(木兰宽松许可证)
|
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
|
||||||
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)(Apache 2.0 LICENSE、SWOOLE-CLI LICENSE)
|
- [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 等,它们都有各自的开源协议。
|
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
|
||||||
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
|
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
|
||||||
|
|
||||||
## 进阶
|
|
||||||
|
|
||||||
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php.dev) 贡献代码或文档。
|
|
||||||
|
|||||||
205
README.md
205
README.md
@@ -1,28 +1,41 @@
|
|||||||
# static-php-cli
|
# static-php-cli
|
||||||
|
|
||||||
Build single static PHP binary, with PHP project together, with popular extensions included.
|
[](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)
|
||||||
|
|
||||||
🌐 **[中文](README-zh.md)** | **[English](README.md)**
|
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
|
||||||
|
with popular extensions.
|
||||||
|
|
||||||
> 2.0 Release is coming soon, windows support will be added in v2.1.
|
Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed` and `micro` SAPI.
|
||||||
|
|
||||||
The project name is static-php-cli, but it actually supports cli, fpm, micro and embed SAPI 😎
|
**static-php-cli** also has the ability to package PHP projects
|
||||||
|
along with the PHP interpreter into one single executable file.
|
||||||
|
|
||||||
Compile a purely static php-cli binary file with various extensions to make PHP applications more portable! (cli SAPI)
|
## Features
|
||||||
|
|
||||||
<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 (you can call it `spc`) has a lot of features:
|
||||||
|
|
||||||
You can also use the micro binary file to combine php binary and php source code into one for distribution! (micro SAPI)
|
- :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)
|
||||||
|
|
||||||
<img width="600" alt="2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
|
**Single-file standalone php-cli:**
|
||||||
|
|
||||||
> This SAPI feature is from the [Fork](https://github.com/static-php/phpmicro) of [dixyes/phpmicro](https://github.com/dixyes/phpmicro).
|
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
|
||||||
|
|
||||||
[]()
|
**Combine PHP code with PHP interpreter using phpmicro:**
|
||||||
[]()
|
|
||||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
|
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
|
||||||
[]([https://static-php.dev/](https://static-php.dev/en/guide/extensions.html))
|
|
||||||
[]()
|
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
@@ -31,7 +44,7 @@ see <https://static-php.dev> .
|
|||||||
|
|
||||||
## Direct Download
|
## Direct Download
|
||||||
|
|
||||||
If you don't want to compile yourself, you can download example pre-compiled artifact from [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-common.yml), or from self-hosted server.
|
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.
|
||||||
|
|
||||||
Below are several precompiled static-php binaries with different extension combinations,
|
Below are several precompiled static-php binaries with different extension combinations,
|
||||||
which can be downloaded directly according to your needs.
|
which can be downloaded directly according to your needs.
|
||||||
@@ -40,26 +53,47 @@ which can be downloaded directly according to your needs.
|
|||||||
- [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 - 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.
|
- [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.
|
||||||
|
|
||||||
## Use static-php-cli to build PHP
|
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
|
||||||
|
|
||||||
### Compilation Requirements
|
### Compilation Requirements
|
||||||
|
|
||||||
Yes, this project is written in PHP, pretty funny.
|
You can say I made a PHP builder written in PHP, pretty funny.
|
||||||
But static-php-cli runtime only requires an environment above PHP 8.1 and `mbstring`, `pcntl` extension.
|
But static-php-cli runtime only requires an environment above PHP 8.1 and extensions mentioned below.
|
||||||
|
|
||||||
Here is the architecture support status, where :octocat: represents support for GitHub Action builds,
|
- 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
|
||||||
|
|
||||||
|
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.
|
:computer: represents support for local manual builds, and blank represents not currently supported.
|
||||||
|
|
||||||
| | x86_64 | aarch64 |
|
| | x86_64 | aarch64 |
|
||||||
|---------|----------------------|----------------------|
|
|---------|----------------------|----------------------|
|
||||||
| macOS | :octocat: :computer: | :computer: |
|
| macOS | :octocat: :computer: | :octocat: :computer: |
|
||||||
| Linux | :octocat: :computer: | :octocat: :computer: |
|
| Linux | :octocat: :computer: | :octocat: :computer: |
|
||||||
| Windows | | |
|
| Windows | :computer: | |
|
||||||
| FreeBSD | :computer: | :computer: |
|
| FreeBSD | :computer: | :computer: |
|
||||||
|
|
||||||
> macOS-arm64 is not supported for GitHub Actions, if you are going to build on arm, you can build it manually on your own machine.
|
Currently supported PHP versions for compilation:
|
||||||
|
|
||||||
Currently supported PHP versions for compilation are: `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`.
|
> :warning: supported but not maintained
|
||||||
|
>
|
||||||
|
> :heavy_check_mark: supported
|
||||||
|
>
|
||||||
|
> :x: not supported
|
||||||
|
|
||||||
|
| 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: | |
|
||||||
|
|
||||||
### Supported Extensions
|
### Supported Extensions
|
||||||
|
|
||||||
@@ -72,7 +106,7 @@ Please first select the extension you want to compile based on the extension lis
|
|||||||
|
|
||||||
Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
|
Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
|
||||||
|
|
||||||
### GitHub Actions Build
|
### Build Online (using GitHub Actions)
|
||||||
|
|
||||||
Use GitHub Action to easily build a statically compiled PHP,
|
Use GitHub Action to easily build a statically compiled PHP,
|
||||||
and at the same time define the extensions to be compiled by yourself.
|
and at the same time define the extensions to be compiled by yourself.
|
||||||
@@ -84,80 +118,85 @@ and at the same time define the extensions to be compiled by yourself.
|
|||||||
|
|
||||||
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
|
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.
|
### Build Locally (using SPC binary)
|
||||||
- When using macos-latest, it will build macOS-x86_64 binary.
|
|
||||||
|
|
||||||
### Manual build (using SPC binary)
|
This project provides a binary file of static-php-cli: `spc`.
|
||||||
|
You can use `spc` binary instead of installing any runtime like golang app.
|
||||||
This project provides a binary file of static-php-cli.
|
|
||||||
You can directly download the binary file of the corresponding platform and then use it to build static PHP.
|
|
||||||
Currently, the platforms supported by `spc` binary are Linux and macOS.
|
Currently, the platforms supported by `spc` binary are Linux and macOS.
|
||||||
|
|
||||||
Here's how to download from GitHub Actions:
|
Download from self-hosted nightly builds using commands below:
|
||||||
|
|
||||||
1. Enter [GitHub Actions](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml) or [self-hosted nightly builds](https://dl.static-php.dev/static-php-cli/spc-bin/nightly/).
|
|
||||||
2. If you download from GHA, select the latest build task, select `Artifacts`, and download the binary file of the corresponding platform.
|
|
||||||
3. If you download from GHA, unzip the `.zip` file. After decompressing, add execution permissions to it: `chmod +x ./spc`.
|
|
||||||
4. If you download from self-hosted server, download `spc-$os-$arch` file and just use it (don't forget `chmod +x`).
|
|
||||||
|
|
||||||
> SPC single-file binary is built by phpmicro and box, and it doesn't need to install PHP. Just treat `spc` as a standalone executable.
|
|
||||||
|
|
||||||
### Manual build (using source code)
|
|
||||||
|
|
||||||
Clone repo first:
|
|
||||||
|
|
||||||
```bash
|
```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
|
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.).
|
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.
|
||||||
|
|
||||||
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
|
```bash
|
||||||
cd static-php-cli
|
cd static-php-cli
|
||||||
chmod +x bin/setup-runtime
|
chmod +x bin/setup-runtime
|
||||||
# It will download php-cli from self-hosted server and composer from getcomposer.org
|
# it will download static php (from self-hosted server) and composer (from getcomposer)
|
||||||
./bin/setup-runtime
|
bin/setup-runtime
|
||||||
|
# initialize composer deps
|
||||||
# Use this php runtime to run static-php-cli compiler
|
bin/composer install
|
||||||
./bin/php bin/spc
|
# chmod
|
||||||
|
|
||||||
# Use composer
|
|
||||||
./bin/php bin/composer
|
|
||||||
|
|
||||||
# Initialize this project
|
|
||||||
cd static-php-cli
|
|
||||||
composer update
|
|
||||||
chmod +x bin/spc
|
chmod +x bin/spc
|
||||||
|
bin/spc --version
|
||||||
```
|
```
|
||||||
|
|
||||||
### Use static-php-cli
|
### Start Building PHP
|
||||||
|
|
||||||
Basic usage for building php and micro with some extensions:
|
Basic usage for building php with some extensions:
|
||||||
|
|
||||||
> If you are using the packaged `spc` binary, you need to replace `bin/spc` with `./spc` in the following commands.
|
> 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
|
```bash
|
||||||
# Check system tool dependencies, fix them if possible
|
# Check system tool dependencies, auto-fix them if possible
|
||||||
./bin/spc doctor
|
./bin/spc doctor --auto-fix
|
||||||
|
|
||||||
# fetch all libraries
|
# fetch all libraries
|
||||||
./bin/spc download --all
|
./bin/spc download --all
|
||||||
# only fetch necessary sources by needed extensions
|
# only fetch necessary sources by needed extensions (recommended)
|
||||||
./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
|
./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
|
# 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
|
./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
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also use the parameter `--with-php=x.y` to specify the downloaded PHP version, currently supports 7.4 ~ 8.3:
|
Now we support `cli`, `micro`, `fpm` and `embed` SAPI. You can use one or more of the following parameters to specify the compiled SAPI:
|
||||||
|
|
||||||
```bash
|
|
||||||
# Using PHP >= 8.0 is recommended, because PHP7 cannot use phpmicro
|
|
||||||
./bin/spc fetch --with-php=8.2 --all
|
|
||||||
```
|
|
||||||
|
|
||||||
Now we support `cli`, `micro`, `fpm`, you can use one or more of the following parameters to specify the compiled SAPI:
|
|
||||||
|
|
||||||
- `--build-cli`: build static cli executable
|
- `--build-cli`: build static cli executable
|
||||||
- `--build-micro`: build static phpmicro self-extracted executable
|
- `--build-micro`: build static phpmicro self-extracted executable
|
||||||
@@ -168,18 +207,10 @@ Now we support `cli`, `micro`, `fpm`, you can use one or more of the following p
|
|||||||
If anything goes wrong, use `--debug` option to display full terminal output:
|
If anything goes wrong, use `--debug` option to display full terminal output:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./bin/spc build openssl,pcntl,mbstring --debug --build-all
|
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
|
||||||
./bin/spc fetch --all --debug
|
./bin/spc download --all --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
In addition, we build NTS (non-thread-safe) by default. If you are going to build ZTS version, just add `--enable-zts` option.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./bin/spc build openssl,pcntl --build-all --enable-zts
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Different SAPI Usage
|
## Different SAPI Usage
|
||||||
|
|
||||||
### Use cli
|
### Use cli
|
||||||
@@ -269,7 +300,7 @@ Now there is a [static-php](https://github.com/static-php) organization, which i
|
|||||||
|
|
||||||
## Sponsor this project
|
## Sponsor this project
|
||||||
|
|
||||||
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
|
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.
|
||||||
|
|
||||||
## Open-Source License
|
## Open-Source License
|
||||||
|
|
||||||
@@ -282,10 +313,12 @@ These are similar projects:
|
|||||||
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
|
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
|
||||||
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
|
- [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,
|
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,
|
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.
|
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,
|
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.
|
and comply with the corresponding project's LICENSE.
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ function RemoveFromPath {
|
|||||||
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
|
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
|
||||||
|
|
||||||
if ($currentPath -like "*$pathToRemove*") {
|
if ($currentPath -like "*$pathToRemove*") {
|
||||||
$newPath = $currentPath -replace [regex]::Escape($pathToRemove), ''
|
$newPath = $currentPath -replace [regex]::Escape(';' + $pathToRemove), ''
|
||||||
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
||||||
Write-Host "Removed Path '$pathToRemove'"
|
Write-Host "Removed Path '$pathToRemove'"
|
||||||
} else {
|
} else {
|
||||||
@@ -92,7 +92,7 @@ if (-not(Test-Path "runtime\composer.phar"))
|
|||||||
# create runtime\composer.ps1
|
# create runtime\composer.ps1
|
||||||
$ComposerContent = '
|
$ComposerContent = '
|
||||||
$WorkingDir = (Split-Path -Parent $MyInvocation.MyCommand.Definition)
|
$WorkingDir = (Split-Path -Parent $MyInvocation.MyCommand.Definition)
|
||||||
Start-Process ($WorkingDir + "\php.exe") ($WorkingDir + "\composer.phar " + $args) -NoNewWindow -Wait
|
& ($WorkingDir + "\php.exe") (Join-Path $WorkingDir "\composer.phar") @args
|
||||||
'
|
'
|
||||||
$ComposerContent | Set-Content -Path 'runtime\composer.ps1' -Encoding UTF8
|
$ComposerContent | Set-Content -Path 'runtime\composer.ps1' -Encoding UTF8
|
||||||
|
|
||||||
|
|||||||
1
bin/spc
1
bin/spc
@@ -21,4 +21,5 @@ try {
|
|||||||
(new ConsoleApplication())->run();
|
(new ConsoleApplication())->run();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
ExceptionHandler::getInstance()->handle($e);
|
ExceptionHandler::getInstance()->handle($e);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
$PHP_Exec = "runtime\php.exe"
|
$PHP_Exec = ".\runtime\php.exe"
|
||||||
|
|
||||||
if (-not(Test-Path $PHP_Exec)) {
|
if (-not(Test-Path $PHP_Exec)) {
|
||||||
$PHP_Exec = Get-Command php.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Definition
|
$PHP_Exec = Get-Command php.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Definition
|
||||||
@@ -8,5 +8,5 @@ if (-not(Test-Path $PHP_Exec)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$phpArgs = "bin\spc " + $args
|
& "$PHP_Exec" ("bin/spc") @args
|
||||||
Start-Process $PHP_Exec -ArgumentList $phpArgs -NoNewWindow -Wait
|
exit $LASTEXITCODE
|
||||||
|
|||||||
1
box.json
1
box.json
@@ -14,6 +14,5 @@
|
|||||||
"vendor/zhamao"
|
"vendor/zhamao"
|
||||||
],
|
],
|
||||||
"git-commit-short": "git_commit_short",
|
"git-commit-short": "git_commit_short",
|
||||||
"metadata": "ConsoleApplication::VERSION",
|
|
||||||
"output": "spc.phar"
|
"output": "spc.phar"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
"captainhook/captainhook": "^5.10",
|
"captainhook/captainhook": "^5.10",
|
||||||
"captainhook/plugin-composer": "^5.3",
|
"captainhook/plugin-composer": "^5.3",
|
||||||
"friendsofphp/php-cs-fixer": "^3.25",
|
"friendsofphp/php-cs-fixer": "^3.25",
|
||||||
"humbug/box": "^4.3",
|
"humbug/box": "^4.5",
|
||||||
"nunomaduro/collision": "^7.8",
|
"nunomaduro/collision": "^7.8",
|
||||||
"phpstan/phpstan": "^1.10",
|
"phpstan/phpstan": "^1.10",
|
||||||
"phpunit/phpunit": "^10.3"
|
"phpunit/phpunit": "^10.3 || ^9"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
@@ -54,5 +54,11 @@
|
|||||||
},
|
},
|
||||||
"optimize-autoloader": true,
|
"optimize-autoloader": true,
|
||||||
"sort-packages": true
|
"sort-packages": true
|
||||||
}
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "other",
|
||||||
|
"url": "https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
940
composer.lock
generated
940
composer.lock
generated
File diff suppressed because it is too large
Load Diff
114
config/ext.json
114
config/ext.json
@@ -1,4 +1,15 @@
|
|||||||
{
|
{
|
||||||
|
"amqp": {
|
||||||
|
"type": "external",
|
||||||
|
"arg-type": "custom",
|
||||||
|
"source": "amqp",
|
||||||
|
"lib-depends": [
|
||||||
|
"librabbitmq"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"openssl"
|
||||||
|
]
|
||||||
|
},
|
||||||
"apcu": {
|
"apcu": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "apcu"
|
"source": "apcu"
|
||||||
@@ -24,11 +35,18 @@
|
|||||||
"arg-type": "with",
|
"arg-type": "with",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"curl"
|
"curl"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"zlib",
|
||||||
|
"openssl"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dba": {
|
"dba": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type-windows": "with"
|
"arg-type": "custom",
|
||||||
|
"lib-suggests": [
|
||||||
|
"qdbm"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"dom": {
|
"dom": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
@@ -37,8 +55,15 @@
|
|||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"libxml2",
|
"libxml2",
|
||||||
"zlib"
|
"zlib"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"xml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ds": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "ext-ds"
|
||||||
|
},
|
||||||
"event": {
|
"event": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "ext-event",
|
"source": "ext-event",
|
||||||
@@ -59,8 +84,11 @@
|
|||||||
"ffi": {
|
"ffi": {
|
||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"lib-depends": [
|
"lib-depends-unix": [
|
||||||
"libffi"
|
"libffi"
|
||||||
|
],
|
||||||
|
"lib-depends-windows": [
|
||||||
|
"libffi-win"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"fileinfo": {
|
"fileinfo": {
|
||||||
@@ -95,7 +123,7 @@
|
|||||||
},
|
},
|
||||||
"gettext": {
|
"gettext": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "with",
|
"arg-type": "with-prefix",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"gettext"
|
"gettext"
|
||||||
]
|
]
|
||||||
@@ -106,7 +134,8 @@
|
|||||||
"source": "ext-glfw",
|
"source": "ext-glfw",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"glfw"
|
"glfw"
|
||||||
]
|
],
|
||||||
|
"lib-depends-windows": []
|
||||||
},
|
},
|
||||||
"gmp": {
|
"gmp": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
@@ -118,8 +147,12 @@
|
|||||||
"iconv": {
|
"iconv": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "with-prefix",
|
"arg-type": "with-prefix",
|
||||||
"lib-depends": [
|
"arg-type-windows": "with",
|
||||||
|
"lib-depends-unix": [
|
||||||
"libiconv"
|
"libiconv"
|
||||||
|
],
|
||||||
|
"lib-depends-windows": [
|
||||||
|
"libiconv-win"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"igbinary": {
|
"igbinary": {
|
||||||
@@ -238,6 +271,7 @@
|
|||||||
"openssl": {
|
"openssl": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
|
"arg-type-windows": "with",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"openssl",
|
"openssl",
|
||||||
"zlib"
|
"zlib"
|
||||||
@@ -290,6 +324,15 @@
|
|||||||
"sqlite"
|
"sqlite"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"pdo_sqlsrv": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "pdo_sqlsrv",
|
||||||
|
"arg-type": "with",
|
||||||
|
"ext-depends": [
|
||||||
|
"pdo",
|
||||||
|
"sqlsrv"
|
||||||
|
]
|
||||||
|
},
|
||||||
"pgsql": {
|
"pgsql": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "with-prefix",
|
"arg-type": "with-prefix",
|
||||||
@@ -311,13 +354,6 @@
|
|||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "protobuf"
|
"source": "protobuf"
|
||||||
},
|
},
|
||||||
"pspell": {
|
|
||||||
"type": "builtin",
|
|
||||||
"arg-type": "with",
|
|
||||||
"lib-depends": [
|
|
||||||
"aspell"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"rar": {
|
"rar": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "rar",
|
"source": "rar",
|
||||||
@@ -349,12 +385,19 @@
|
|||||||
"shmop": {
|
"shmop": {
|
||||||
"type": "builtin"
|
"type": "builtin"
|
||||||
},
|
},
|
||||||
|
"simdjson": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "ext-simdjson",
|
||||||
|
"cpp-extension": true
|
||||||
|
},
|
||||||
"simplexml": {
|
"simplexml": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
"arg-type-windows": "with",
|
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"libxml2"
|
"libxml2"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"xml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"snappy": {
|
"snappy": {
|
||||||
@@ -369,18 +412,14 @@
|
|||||||
"apcu"
|
"apcu"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"snmp": {
|
|
||||||
"type": "builtin",
|
|
||||||
"arg-type": "with",
|
|
||||||
"lib-depends": [
|
|
||||||
"net-snmp"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"soap": {
|
"soap": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"libxml2"
|
"libxml2"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"xml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"sockets": {
|
"sockets": {
|
||||||
@@ -396,6 +435,7 @@
|
|||||||
"sqlite3": {
|
"sqlite3": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
"arg-type": "with-prefix",
|
"arg-type": "with-prefix",
|
||||||
|
"arg-type-windows": "with",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"sqlite"
|
"sqlite"
|
||||||
]
|
]
|
||||||
@@ -415,8 +455,13 @@
|
|||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "ext-ssh2",
|
"source": "ext-ssh2",
|
||||||
"arg-type": "with-prefix",
|
"arg-type": "with-prefix",
|
||||||
|
"arg-type-windows": "with",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"libssh2"
|
"libssh2"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"openssl",
|
||||||
|
"zlib"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"swoole": {
|
"swoole": {
|
||||||
@@ -491,8 +536,7 @@
|
|||||||
"unix-only": true
|
"unix-only": true
|
||||||
},
|
},
|
||||||
"sysvshm": {
|
"sysvshm": {
|
||||||
"type": "builtin",
|
"type": "builtin"
|
||||||
"unix-only": true
|
|
||||||
},
|
},
|
||||||
"tidy": {
|
"tidy": {
|
||||||
"type": "builtin",
|
"type": "builtin",
|
||||||
@@ -504,6 +548,14 @@
|
|||||||
"tokenizer": {
|
"tokenizer": {
|
||||||
"type": "builtin"
|
"type": "builtin"
|
||||||
},
|
},
|
||||||
|
"uuid": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "ext-uuid",
|
||||||
|
"arg-type": "with-prefix",
|
||||||
|
"lib-depends": [
|
||||||
|
"libuuid"
|
||||||
|
]
|
||||||
|
},
|
||||||
"uv": {
|
"uv": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "ext-uv",
|
"source": "ext-uv",
|
||||||
@@ -537,6 +589,9 @@
|
|||||||
"arg-type-windows": "with",
|
"arg-type-windows": "with",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"libxml2"
|
"libxml2"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"iconv"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"xmlreader": {
|
"xmlreader": {
|
||||||
@@ -544,6 +599,10 @@
|
|||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"libxml2"
|
"libxml2"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"xml",
|
||||||
|
"dom"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"xmlwriter": {
|
"xmlwriter": {
|
||||||
@@ -551,6 +610,9 @@
|
|||||||
"arg-type": "custom",
|
"arg-type": "custom",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"libxml2"
|
"libxml2"
|
||||||
|
],
|
||||||
|
"ext-depends-windows": [
|
||||||
|
"xml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"xsl": {
|
"xsl": {
|
||||||
@@ -564,6 +626,14 @@
|
|||||||
"dom"
|
"dom"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"yac": {
|
||||||
|
"type": "external",
|
||||||
|
"source": "yac",
|
||||||
|
"arg-type-unix": "custom",
|
||||||
|
"ext-depends-unix": [
|
||||||
|
"igbinary"
|
||||||
|
]
|
||||||
|
},
|
||||||
"yaml": {
|
"yaml": {
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "yaml",
|
"source": "yaml",
|
||||||
|
|||||||
121
config/lib.json
121
config/lib.json
@@ -36,7 +36,7 @@
|
|||||||
"libcurl.a"
|
"libcurl.a"
|
||||||
],
|
],
|
||||||
"static-libs-windows": [
|
"static-libs-windows": [
|
||||||
"libcurl.lib"
|
"libcurl_a.lib"
|
||||||
],
|
],
|
||||||
"headers": [
|
"headers": [
|
||||||
"curl"
|
"curl"
|
||||||
@@ -45,21 +45,21 @@
|
|||||||
"openssl",
|
"openssl",
|
||||||
"zlib"
|
"zlib"
|
||||||
],
|
],
|
||||||
"lib-suggests": [
|
"lib-depends-windows": [
|
||||||
|
"openssl",
|
||||||
|
"zlib",
|
||||||
|
"libssh2",
|
||||||
|
"nghttp2"
|
||||||
|
],
|
||||||
|
"lib-suggests-unix": [
|
||||||
"libssh2",
|
"libssh2",
|
||||||
"brotli",
|
"brotli",
|
||||||
"nghttp2",
|
"nghttp2",
|
||||||
"zstd"
|
"zstd"
|
||||||
],
|
],
|
||||||
"lib-suggests-windows": [
|
"lib-suggests-windows": [
|
||||||
"zlib",
|
|
||||||
"libssh2",
|
|
||||||
"brotli",
|
"brotli",
|
||||||
"nghttp2",
|
"zstd"
|
||||||
"zstd",
|
|
||||||
"openssl",
|
|
||||||
"idn2",
|
|
||||||
"psl"
|
|
||||||
],
|
],
|
||||||
"frameworks": [
|
"frameworks": [
|
||||||
"CoreFoundation",
|
"CoreFoundation",
|
||||||
@@ -85,6 +85,22 @@
|
|||||||
"brotli"
|
"brotli"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"gettext": {
|
||||||
|
"source": "gettext",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libintl.a"
|
||||||
|
],
|
||||||
|
"lib-depends": [
|
||||||
|
"libiconv"
|
||||||
|
],
|
||||||
|
"lib-suggests": [
|
||||||
|
"ncurses",
|
||||||
|
"libxml2"
|
||||||
|
],
|
||||||
|
"frameworks": [
|
||||||
|
"CoreFoundation"
|
||||||
|
]
|
||||||
|
},
|
||||||
"glfw": {
|
"glfw": {
|
||||||
"source": "ext-glfw",
|
"source": "ext-glfw",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -131,7 +147,8 @@
|
|||||||
"libpng",
|
"libpng",
|
||||||
"libjpeg",
|
"libjpeg",
|
||||||
"libwebp",
|
"libwebp",
|
||||||
"freetype"
|
"freetype",
|
||||||
|
"libtiff"
|
||||||
],
|
],
|
||||||
"lib-suggests": [
|
"lib-suggests": [
|
||||||
"zstd",
|
"zstd",
|
||||||
@@ -217,6 +234,17 @@
|
|||||||
"ffitarget.h"
|
"ffitarget.h"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"libffi-win": {
|
||||||
|
"source": "libffi-win",
|
||||||
|
"static-libs-windows": [
|
||||||
|
"libffi.lib"
|
||||||
|
],
|
||||||
|
"headers-windows": [
|
||||||
|
"ffi.h",
|
||||||
|
"ffitarget.h",
|
||||||
|
"fficonfig.h"
|
||||||
|
]
|
||||||
|
},
|
||||||
"libiconv": {
|
"libiconv": {
|
||||||
"source": "libiconv",
|
"source": "libiconv",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -229,6 +257,13 @@
|
|||||||
"localcharset.h"
|
"localcharset.h"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"libiconv-win": {
|
||||||
|
"source": "libiconv-win",
|
||||||
|
"static-libs-windows": [
|
||||||
|
"libiconv.lib",
|
||||||
|
"libiconv_a.lib"
|
||||||
|
]
|
||||||
|
},
|
||||||
"libjpeg": {
|
"libjpeg": {
|
||||||
"source": "libjpeg",
|
"source": "libjpeg",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -270,6 +305,18 @@
|
|||||||
"zlib"
|
"zlib"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"librabbitmq": {
|
||||||
|
"source": "librabbitmq",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"librabbitmq.a"
|
||||||
|
],
|
||||||
|
"static-libs-windows": [
|
||||||
|
"rabbitmq.4.lib"
|
||||||
|
],
|
||||||
|
"lib-depends": [
|
||||||
|
"openssl"
|
||||||
|
]
|
||||||
|
},
|
||||||
"libsodium": {
|
"libsodium": {
|
||||||
"source": "libsodium",
|
"source": "libsodium",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -296,6 +343,21 @@
|
|||||||
"zlib"
|
"zlib"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"libtiff": {
|
||||||
|
"source": "libtiff",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libtiff.a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"libuuid": {
|
||||||
|
"source": "libuuid",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libuuid.a"
|
||||||
|
],
|
||||||
|
"headers": [
|
||||||
|
"uuid/uuid.h"
|
||||||
|
]
|
||||||
|
},
|
||||||
"libuv": {
|
"libuv": {
|
||||||
"source": "libuv",
|
"source": "libuv",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -318,21 +380,25 @@
|
|||||||
"libxml2.a"
|
"libxml2.a"
|
||||||
],
|
],
|
||||||
"static-libs-windows": [
|
"static-libs-windows": [
|
||||||
[
|
"libxml2s.lib",
|
||||||
"libxml2s.lib",
|
"libxml2_a.lib"
|
||||||
"libxml2_a.lib"
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
"headers": [
|
"headers": [
|
||||||
"libxml2"
|
"libxml2"
|
||||||
],
|
],
|
||||||
"lib-depends": [
|
"lib-depends-unix": [
|
||||||
"libiconv"
|
"libiconv"
|
||||||
],
|
],
|
||||||
"lib-suggests": [
|
"lib-suggests-unix": [
|
||||||
"xz",
|
"xz",
|
||||||
"icu",
|
"icu",
|
||||||
"zlib"
|
"zlib"
|
||||||
|
],
|
||||||
|
"lib-depends-windows": [
|
||||||
|
"libiconv-win"
|
||||||
|
],
|
||||||
|
"lib-suggests-windows": [
|
||||||
|
"zlib"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"libxslt": {
|
"libxslt": {
|
||||||
@@ -413,10 +479,8 @@
|
|||||||
"libonig.a"
|
"libonig.a"
|
||||||
],
|
],
|
||||||
"static-libs-windows": [
|
"static-libs-windows": [
|
||||||
[
|
"onig.lib",
|
||||||
"onig.lib",
|
"onig_a.lib"
|
||||||
"onig_a.lib"
|
|
||||||
]
|
|
||||||
],
|
],
|
||||||
"headers": [
|
"headers": [
|
||||||
"oniggnu.h",
|
"oniggnu.h",
|
||||||
@@ -464,6 +528,18 @@
|
|||||||
"zstd"
|
"zstd"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"qdbm": {
|
||||||
|
"source": "qdbm",
|
||||||
|
"static-libs-unix": [
|
||||||
|
"libqdbm.a"
|
||||||
|
],
|
||||||
|
"static-libs-windows": [
|
||||||
|
"qdbm_a.lib"
|
||||||
|
],
|
||||||
|
"headers-windows": [
|
||||||
|
"depot.h"
|
||||||
|
]
|
||||||
|
},
|
||||||
"readline": {
|
"readline": {
|
||||||
"source": "readline",
|
"source": "readline",
|
||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
@@ -493,7 +569,10 @@
|
|||||||
"static-libs-unix": [
|
"static-libs-unix": [
|
||||||
"libsqlite3.a"
|
"libsqlite3.a"
|
||||||
],
|
],
|
||||||
"headers-unix": [
|
"static-libs-windows": [
|
||||||
|
"libsqlite3_a.lib"
|
||||||
|
],
|
||||||
|
"headers": [
|
||||||
"sqlite3.h",
|
"sqlite3.h",
|
||||||
"sqlite3ext.h"
|
"sqlite3ext.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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,16 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"amqp": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/amqp",
|
||||||
|
"path": "php-src/ext/amqp",
|
||||||
|
"filename": "amqp.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"apcu": {
|
"apcu": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://pecl.php.net/get/APCu",
|
"url": "https://pecl.php.net/get/APCu",
|
||||||
@@ -42,6 +52,16 @@
|
|||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ext-ds": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/ds",
|
||||||
|
"path": "php-src/ext/ds",
|
||||||
|
"filename": "ds.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ext-event": {
|
"ext-event": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://bitbucket.org/osmanov/pecl-event/get/3.0.8.tar.gz",
|
"url": "https://bitbucket.org/osmanov/pecl-event/get/3.0.8.tar.gz",
|
||||||
@@ -80,6 +100,16 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ext-simdjson": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/simdjson",
|
||||||
|
"path": "php-src/ext/simdjson",
|
||||||
|
"filename": "simdjson.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ext-snappy": {
|
"ext-snappy": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"path": "php-src/ext/snappy",
|
"path": "php-src/ext/snappy",
|
||||||
@@ -100,6 +130,16 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ext-uuid": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/uuid",
|
||||||
|
"path": "php-src/ext/uuid",
|
||||||
|
"filename": "uuid.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ext-uv": {
|
"ext-uv": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://pecl.php.net/get/uv",
|
"url": "https://pecl.php.net/get/uv",
|
||||||
@@ -129,6 +169,15 @@
|
|||||||
"path": "LICENSE.TXT"
|
"path": "LICENSE.TXT"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"gettext": {
|
||||||
|
"type": "filelist",
|
||||||
|
"url": "https://ftp.gnu.org/pub/gnu/gettext/",
|
||||||
|
"regex": "/href=\"(?<file>gettext-(?<version>[^\"]+)\\.tar\\.xz)\"/",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "COPYING"
|
||||||
|
}
|
||||||
|
},
|
||||||
"gmp": {
|
"gmp": {
|
||||||
"type": "ghtagtar",
|
"type": "ghtagtar",
|
||||||
"repo": "alisw/GMP",
|
"repo": "alisw/GMP",
|
||||||
@@ -195,7 +244,7 @@
|
|||||||
"libargon2": {
|
"libargon2": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"rev": "master",
|
"rev": "master",
|
||||||
"url": "https://github.com/mpociot/phc-winner-argon2",
|
"url": "https://github.com/static-php/phc-winner-argon2",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
@@ -236,6 +285,15 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libffi-win": {
|
||||||
|
"type": "git",
|
||||||
|
"rev": "master",
|
||||||
|
"url": "https://github.com/static-php/libffi-win.git",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libiconv": {
|
"libiconv": {
|
||||||
"type": "filelist",
|
"type": "filelist",
|
||||||
"url": "https://ftp.gnu.org/gnu/libiconv/",
|
"url": "https://ftp.gnu.org/gnu/libiconv/",
|
||||||
@@ -245,6 +303,15 @@
|
|||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libiconv-win": {
|
||||||
|
"type": "git",
|
||||||
|
"rev": "master",
|
||||||
|
"url": "https://github.com/static-php/libiconv-win.git",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "source/COPYING"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libjpeg": {
|
"libjpeg": {
|
||||||
"type": "ghtar",
|
"type": "ghtar",
|
||||||
"repo": "libjpeg-turbo/libjpeg-turbo",
|
"repo": "libjpeg-turbo/libjpeg-turbo",
|
||||||
@@ -280,6 +347,15 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"librabbitmq": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/alanxz/rabbitmq-c.git",
|
||||||
|
"rev": "master",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libsodium": {
|
"libsodium": {
|
||||||
"type": "ghrel",
|
"type": "ghrel",
|
||||||
"repo": "jedisct1/libsodium",
|
"repo": "jedisct1/libsodium",
|
||||||
@@ -298,6 +374,24 @@
|
|||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"libtiff": {
|
||||||
|
"type": "filelist",
|
||||||
|
"url": "https://download.osgeo.org/libtiff/",
|
||||||
|
"regex": "/href=\"(?<file>tiff-(?<version>[^\"]+)\\.tar\\.xz)\"/",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE.md"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libuuid": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/static-php/libuuid.git",
|
||||||
|
"rev": "master",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "COPYING"
|
||||||
|
}
|
||||||
|
},
|
||||||
"libuv": {
|
"libuv": {
|
||||||
"type": "ghtar",
|
"type": "ghtar",
|
||||||
"repo": "libuv/libuv",
|
"repo": "libuv/libuv",
|
||||||
@@ -322,7 +416,7 @@
|
|||||||
},
|
},
|
||||||
"libxml2": {
|
"libxml2": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://github.com/GNOME/libxml2/archive/refs/tags/v2.9.14.tar.gz",
|
"url": "https://github.com/GNOME/libxml2/archive/refs/tags/v2.12.5.tar.gz",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "Copyright"
|
"path": "Copyright"
|
||||||
@@ -421,6 +515,16 @@
|
|||||||
"path": "LICENSE.txt"
|
"path": "LICENSE.txt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pdo_sqlsrv": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/pdo_sqlsrv",
|
||||||
|
"path": "php-src/ext/pdo_sqlsrv",
|
||||||
|
"filename": "pdo_sqlsrv.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"pkg-config": {
|
"pkg-config": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz",
|
"url": "https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz",
|
||||||
@@ -431,7 +535,7 @@
|
|||||||
},
|
},
|
||||||
"postgresql": {
|
"postgresql": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://ftp.postgresql.org/pub/source/v16.1/postgresql-16.1.tar.gz",
|
"url": "https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.bz2",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "COPYRIGHT"
|
"path": "COPYRIGHT"
|
||||||
@@ -447,6 +551,15 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"qdbm": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/static-php/qdbm.git",
|
||||||
|
"rev": "main",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "COPYING"
|
||||||
|
}
|
||||||
|
},
|
||||||
"rar": {
|
"rar": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/static-php/php-rar.git",
|
"url": "https://github.com/static-php/php-rar.git",
|
||||||
@@ -562,14 +675,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"xz": {
|
"xz": {
|
||||||
"type": "ghrel",
|
"type": "url",
|
||||||
"repo": "tukaani-project/xz",
|
"url": "https://fossies.org/linux/misc/xz-5.4.6.tar.xz",
|
||||||
"match": "xz-.+\\.tar\\.gz",
|
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "COPYING"
|
"path": "COPYING"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"yac": {
|
||||||
|
"type": "url",
|
||||||
|
"url": "https://pecl.php.net/get/yac",
|
||||||
|
"path": "php-src/ext/yac",
|
||||||
|
"filename": "yac.tgz",
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"yaml": {
|
"yaml": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"path": "php-src/ext/yaml",
|
"path": "php-src/ext/yaml",
|
||||||
|
|||||||
@@ -14,4 +14,5 @@ parameters:
|
|||||||
excludePaths:
|
excludePaths:
|
||||||
analyseAndScan:
|
analyseAndScan:
|
||||||
- ./src/globals/tests/swoole.php
|
- ./src/globals/tests/swoole.php
|
||||||
- ./src/globals/tests/swoole.phpt
|
- ./src/globals/tests/swoole.phpt
|
||||||
|
- ./src/globals/test-extensions.php
|
||||||
@@ -6,6 +6,7 @@ namespace SPC;
|
|||||||
|
|
||||||
use SPC\command\BuildCliCommand;
|
use SPC\command\BuildCliCommand;
|
||||||
use SPC\command\BuildLibsCommand;
|
use SPC\command\BuildLibsCommand;
|
||||||
|
use SPC\command\DeleteDownloadCommand;
|
||||||
use SPC\command\dev\AllExtCommand;
|
use SPC\command\dev\AllExtCommand;
|
||||||
use SPC\command\dev\PhpVerCommand;
|
use SPC\command\dev\PhpVerCommand;
|
||||||
use SPC\command\dev\SortConfigCommand;
|
use SPC\command\dev\SortConfigCommand;
|
||||||
@@ -13,6 +14,7 @@ use SPC\command\DoctorCommand;
|
|||||||
use SPC\command\DownloadCommand;
|
use SPC\command\DownloadCommand;
|
||||||
use SPC\command\DumpLicenseCommand;
|
use SPC\command\DumpLicenseCommand;
|
||||||
use SPC\command\ExtractCommand;
|
use SPC\command\ExtractCommand;
|
||||||
|
use SPC\command\InstallPkgCommand;
|
||||||
use SPC\command\MicroCombineCommand;
|
use SPC\command\MicroCombineCommand;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Command\HelpCommand;
|
use Symfony\Component\Console\Command\HelpCommand;
|
||||||
@@ -23,7 +25,7 @@ use Symfony\Component\Console\Command\ListCommand;
|
|||||||
*/
|
*/
|
||||||
final class ConsoleApplication extends Application
|
final class ConsoleApplication extends Application
|
||||||
{
|
{
|
||||||
public const VERSION = '2.0.0';
|
public const VERSION = '2.1.7';
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
@@ -31,10 +33,13 @@ final class ConsoleApplication extends Application
|
|||||||
|
|
||||||
$this->addCommands(
|
$this->addCommands(
|
||||||
[
|
[
|
||||||
|
// Common commands
|
||||||
new BuildCliCommand(),
|
new BuildCliCommand(),
|
||||||
new BuildLibsCommand(),
|
new BuildLibsCommand(),
|
||||||
new DoctorCommand(),
|
new DoctorCommand(),
|
||||||
new DownloadCommand(),
|
new DownloadCommand(),
|
||||||
|
new InstallPkgCommand(),
|
||||||
|
new DeleteDownloadCommand(),
|
||||||
new DumpLicenseCommand(),
|
new DumpLicenseCommand(),
|
||||||
new ExtractCommand(),
|
new ExtractCommand(),
|
||||||
new MicroCombineCommand(),
|
new MicroCombineCommand(),
|
||||||
|
|||||||
@@ -4,14 +4,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder;
|
namespace SPC\builder;
|
||||||
|
|
||||||
|
use SPC\exception\ExceptionHandler;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\SourceManager;
|
||||||
use SPC\store\SourceExtractor;
|
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
use SPC\util\DependencyUtil;
|
|
||||||
|
|
||||||
abstract class BuilderBase
|
abstract class BuilderBase
|
||||||
{
|
{
|
||||||
@@ -30,6 +29,9 @@ abstract class BuilderBase
|
|||||||
/** @var array<string, mixed> compile options */
|
/** @var array<string, mixed> compile options */
|
||||||
protected array $options = [];
|
protected array $options = [];
|
||||||
|
|
||||||
|
/** @var string patch point name */
|
||||||
|
protected string $patch_point = '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build libraries
|
* Build libraries
|
||||||
*
|
*
|
||||||
@@ -37,60 +39,9 @@ abstract class BuilderBase
|
|||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function buildLibs(array $sorted_libraries): void
|
abstract public function buildLibs(array $sorted_libraries);
|
||||||
{
|
|
||||||
// search all supported libs
|
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if no libs specified, compile all supported libs
|
|
||||||
if ($sorted_libraries === [] && $this->isLibsOnly()) {
|
|
||||||
$libraries = array_keys($support_lib_list);
|
|
||||||
$sorted_libraries = DependencyUtil::getLibsByDeps($libraries);
|
|
||||||
}
|
|
||||||
|
|
||||||
// pkg-config must be compiled first, whether it is specified or not
|
|
||||||
if (!in_array('pkg-config', $sorted_libraries)) {
|
|
||||||
array_unshift($sorted_libraries, 'pkg-config');
|
|
||||||
}
|
|
||||||
|
|
||||||
// add lib object for builder
|
|
||||||
foreach ($sorted_libraries as $library) {
|
|
||||||
// if some libs are not supported (but in config "lib.json", throw exception)
|
|
||||||
if (!isset($support_lib_list[$library])) {
|
|
||||||
throw new WrongUsageException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
|
|
||||||
}
|
|
||||||
$lib = new ($support_lib_list[$library])($this);
|
|
||||||
$this->addLib($lib);
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate and check dependencies
|
|
||||||
foreach ($this->libs as $lib) {
|
|
||||||
$lib->calcDependency();
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract sources
|
|
||||||
SourceExtractor::initSource(libs: $sorted_libraries);
|
|
||||||
|
|
||||||
// build all libs
|
|
||||||
foreach ($this->libs as $lib) {
|
|
||||||
match ($lib->tryBuild($this->getOption('rebuild', false))) {
|
|
||||||
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
|
|
||||||
BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
|
|
||||||
BUILD_STATUS_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
|
|
||||||
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add library to build.
|
* Add library to build.
|
||||||
@@ -172,6 +123,8 @@ abstract class BuilderBase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set libs only mode.
|
* Set libs only mode.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function setLibsOnly(bool $status = true): void
|
public function setLibsOnly(bool $status = true): void
|
||||||
{
|
{
|
||||||
@@ -185,15 +138,22 @@ abstract class BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws \ReflectionException
|
* @throws \ReflectionException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
|
* @internal
|
||||||
*/
|
*/
|
||||||
public function proveExts(array $extensions): void
|
public function proveExts(array $extensions): void
|
||||||
{
|
{
|
||||||
CustomExt::loadCustomExt();
|
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) {
|
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) {
|
foreach ($extensions as $extension) {
|
||||||
$class = CustomExt::getExtClass($extension);
|
$class = CustomExt::getExtClass($extension);
|
||||||
$ext = new $class($extension, $this);
|
$ext = new $class($extension, $this);
|
||||||
@@ -223,6 +183,7 @@ abstract class BuilderBase
|
|||||||
{
|
{
|
||||||
$ret = [];
|
$ret = [];
|
||||||
foreach ($this->exts as $ext) {
|
foreach ($this->exts as $ext) {
|
||||||
|
logger()->info($ext->getName() . ' is using ' . $ext->getConfigureArg());
|
||||||
$ret[] = trim($ext->getConfigureArg());
|
$ret[] = trim($ext->getConfigureArg());
|
||||||
}
|
}
|
||||||
logger()->debug('Using configure: ' . implode(' ', $ret));
|
logger()->debug('Using configure: ' . implode(' ', $ret));
|
||||||
@@ -270,6 +231,30 @@ abstract class BuilderBase
|
|||||||
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
|
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.
|
* Get build type name string to display.
|
||||||
*
|
*
|
||||||
@@ -342,6 +327,39 @@ abstract class BuilderBase
|
|||||||
return implode(' ', $env);
|
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.
|
* Check if all libs are downloaded.
|
||||||
* If not, throw exception.
|
* If not, throw exception.
|
||||||
@@ -365,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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace SPC\builder;
|
|||||||
use SPC\builder\freebsd\BSDBuilder;
|
use SPC\builder\freebsd\BSDBuilder;
|
||||||
use SPC\builder\linux\LinuxBuilder;
|
use SPC\builder\linux\LinuxBuilder;
|
||||||
use SPC\builder\macos\MacOSBuilder;
|
use SPC\builder\macos\MacOSBuilder;
|
||||||
|
use SPC\builder\windows\WindowsBuilder;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
@@ -17,6 +18,8 @@ use Symfony\Component\Console\Input\InputInterface;
|
|||||||
*/
|
*/
|
||||||
class BuilderProvider
|
class BuilderProvider
|
||||||
{
|
{
|
||||||
|
private static ?BuilderBase $builder = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
@@ -24,16 +27,24 @@ class BuilderProvider
|
|||||||
*/
|
*/
|
||||||
public static function makeBuilderByInput(InputInterface $input): BuilderBase
|
public static function makeBuilderByInput(InputInterface $input): BuilderBase
|
||||||
{
|
{
|
||||||
return match (PHP_OS_FAMILY) {
|
self::$builder = match (PHP_OS_FAMILY) {
|
||||||
// 'Windows' => new WindowsBuilder(
|
'Windows' => new WindowsBuilder($input->getOptions()),
|
||||||
// binary_sdk_dir: $input->getOption('with-sdk-binary-dir'),
|
|
||||||
// vs_ver: $input->getOption('vs-ver'),
|
|
||||||
// arch: $input->getOption('arch'),
|
|
||||||
// ),
|
|
||||||
'Darwin' => new MacOSBuilder($input->getOptions()),
|
'Darwin' => new MacOSBuilder($input->getOptions()),
|
||||||
'Linux' => new LinuxBuilder($input->getOptions()),
|
'Linux' => new LinuxBuilder($input->getOptions()),
|
||||||
'BSD' => new BSDBuilder($input->getOptions()),
|
'BSD' => new BSDBuilder($input->getOptions()),
|
||||||
default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'),
|
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\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
class Extension
|
class Extension
|
||||||
{
|
{
|
||||||
@@ -42,7 +43,7 @@ class Extension
|
|||||||
$arg = $this->getEnableArg();
|
$arg = $this->getEnableArg();
|
||||||
switch (PHP_OS_FAMILY) {
|
switch (PHP_OS_FAMILY) {
|
||||||
case 'Windows':
|
case 'Windows':
|
||||||
$arg = $this->getWindowsConfigureArg();
|
$arg .= $this->getWindowsConfigureArg();
|
||||||
break;
|
break;
|
||||||
case 'Darwin':
|
case 'Darwin':
|
||||||
case 'Linux':
|
case 'Linux':
|
||||||
@@ -164,14 +165,13 @@ class Extension
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run compile check if build target is cli
|
|
||||||
* If you need to run some check, overwrite this or add your assert in src/globals/tests/{extension_name}.php
|
|
||||||
* If check failed, throw RuntimeException
|
|
||||||
*
|
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public function runCliCheck(): void
|
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);
|
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false);
|
||||||
if ($ret !== 0) {
|
if ($ret !== 0) {
|
||||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
|
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
|
||||||
@@ -185,7 +185,38 @@ class Extension
|
|||||||
file_get_contents(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')
|
file_get_contents(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')
|
||||||
);
|
);
|
||||||
|
|
||||||
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
|
[$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) {
|
if ($ret !== 0) {
|
||||||
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
|
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,9 @@ abstract class LibraryBase
|
|||||||
if (!$this->patched && $this->patchBeforeBuild()) {
|
if (!$this->patched && $this->patchBeforeBuild()) {
|
||||||
file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!');
|
file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!');
|
||||||
}
|
}
|
||||||
|
$this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build');
|
||||||
$this->build();
|
$this->build();
|
||||||
|
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-build');
|
||||||
return BUILD_STATUS_OK;
|
return BUILD_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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';
|
||||||
|
}
|
||||||
|
}
|
||||||
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;
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
use SPC\builder\Extension;
|
use SPC\builder\Extension;
|
||||||
|
use SPC\builder\macos\MacOSBuilder;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
@@ -34,4 +35,16 @@ class event extends Extension
|
|||||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-levent_openssl/', $this->getLibFilesString());
|
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-levent_openssl/', $this->getLibFilesString());
|
||||||
return true;
|
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';
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,4 +34,9 @@ class glfw extends Extension
|
|||||||
{
|
{
|
||||||
return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH;
|
return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getWindowsConfigureArg(): string
|
||||||
|
{
|
||||||
|
return '--enable-glfw=static';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ use SPC\util\CustomExt;
|
|||||||
#[CustomExt('mbregex')]
|
#[CustomExt('mbregex')]
|
||||||
class mbregex extends Extension
|
class mbregex extends Extension
|
||||||
{
|
{
|
||||||
|
public function getDistName(): string
|
||||||
|
{
|
||||||
|
return 'mbstring';
|
||||||
|
}
|
||||||
|
|
||||||
public function getConfigureArg(): string
|
public function getConfigureArg(): string
|
||||||
{
|
{
|
||||||
return '';
|
return '';
|
||||||
@@ -19,11 +24,23 @@ class mbregex extends Extension
|
|||||||
/**
|
/**
|
||||||
* mbregex is not an extension, we need to overwrite the default check.
|
* mbregex is not an extension, we need to overwrite the default check.
|
||||||
*/
|
*/
|
||||||
public function runCliCheck(): void
|
public function runCliCheckUnix(): void
|
||||||
{
|
{
|
||||||
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring" | grep regex', false);
|
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring" | grep regex', false);
|
||||||
if ($ret !== 0) {
|
if ($ret !== 0) {
|
||||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !');
|
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')]
|
#[CustomExt('mbstring')]
|
||||||
class mbstring extends Extension
|
class mbstring extends Extension
|
||||||
{
|
{
|
||||||
public function getUnixConfigureArg(): string
|
public function getConfigureArg(): string
|
||||||
{
|
{
|
||||||
$arg = '--enable-mbstring';
|
$arg = '--enable-mbstring';
|
||||||
if ($this->builder->getExt('mbregex') === null) {
|
if ($this->builder->getExt('mbregex') === null) {
|
||||||
$arg .= ' --disable-mbregex';
|
$arg .= ' --disable-mbregex';
|
||||||
|
} else {
|
||||||
|
$arg .= ' --enable-mbregex';
|
||||||
}
|
}
|
||||||
return $arg;
|
return $arg;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,12 @@ use SPC\util\CustomExt;
|
|||||||
#[CustomExt('password-argon2')]
|
#[CustomExt('password-argon2')]
|
||||||
class password_argon2 extends Extension
|
class password_argon2 extends Extension
|
||||||
{
|
{
|
||||||
public function runCliCheck(): void
|
public function getDistName(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function runCliCheckUnix(): void
|
||||||
{
|
{
|
||||||
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "assert(defined(\'PASSWORD_ARGON2I\'));"');
|
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "assert(defined(\'PASSWORD_ARGON2I\'));"');
|
||||||
if ($ret !== 0) {
|
if ($ret !== 0) {
|
||||||
|
|||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,8 +15,8 @@ class swoole extends Extension
|
|||||||
// enable swoole
|
// enable swoole
|
||||||
$arg = '--enable-swoole';
|
$arg = '--enable-swoole';
|
||||||
|
|
||||||
// commonly-used feature: coroutine-time, thread-context
|
// commonly-used feature: coroutine-time, disable-thread-context
|
||||||
$arg .= ' --enable-swoole-coro-time --enable-thread-context';
|
$arg .= ' --enable-swoole-coro-time --disable-thread-context';
|
||||||
|
|
||||||
// required feature: curl, openssl (but curl hook is buggy for php 8.0)
|
// 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 .= $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl';
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ use SPC\util\CustomExt;
|
|||||||
#[CustomExt('swoole-hook-mysql')]
|
#[CustomExt('swoole-hook-mysql')]
|
||||||
class swoole_hook_mysql extends Extension
|
class swoole_hook_mysql extends Extension
|
||||||
{
|
{
|
||||||
|
public function getDistName(): string
|
||||||
|
{
|
||||||
|
return 'swoole';
|
||||||
|
}
|
||||||
|
|
||||||
public function getUnixConfigureArg(): string
|
public function getUnixConfigureArg(): string
|
||||||
{
|
{
|
||||||
// pdo_mysql doesn't need to be disabled
|
// pdo_mysql doesn't need to be disabled
|
||||||
@@ -18,7 +23,7 @@ class swoole_hook_mysql extends Extension
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runCliCheck(): void
|
public function runCliCheckUnix(): void
|
||||||
{
|
{
|
||||||
// skip if not enable swoole
|
// skip if not enable swoole
|
||||||
if ($this->builder->getExt('swoole') === null) {
|
if ($this->builder->getExt('swoole') === null) {
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ use SPC\util\CustomExt;
|
|||||||
#[CustomExt('swoole-hook-pgsql')]
|
#[CustomExt('swoole-hook-pgsql')]
|
||||||
class swoole_hook_pgsql extends Extension
|
class swoole_hook_pgsql extends Extension
|
||||||
{
|
{
|
||||||
|
public function getDistName(): string
|
||||||
|
{
|
||||||
|
return 'swoole';
|
||||||
|
}
|
||||||
|
|
||||||
public function getUnixConfigureArg(): string
|
public function getUnixConfigureArg(): string
|
||||||
{
|
{
|
||||||
// pdo_pgsql need to be disabled
|
// pdo_pgsql need to be disabled
|
||||||
@@ -22,7 +27,7 @@ class swoole_hook_pgsql extends Extension
|
|||||||
return '--enable-swoole-pgsql';
|
return '--enable-swoole-pgsql';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runCliCheck(): void
|
public function runCliCheckUnix(): void
|
||||||
{
|
{
|
||||||
// skip if not enable swoole
|
// skip if not enable swoole
|
||||||
if ($this->builder->getExt('swoole') === null) {
|
if ($this->builder->getExt('swoole') === null) {
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ use SPC\util\CustomExt;
|
|||||||
#[CustomExt('swoole-hook-sqlite')]
|
#[CustomExt('swoole-hook-sqlite')]
|
||||||
class swoole_hook_sqlite extends Extension
|
class swoole_hook_sqlite extends Extension
|
||||||
{
|
{
|
||||||
|
public function getDistName(): string
|
||||||
|
{
|
||||||
|
return 'swoole';
|
||||||
|
}
|
||||||
|
|
||||||
public function getUnixConfigureArg(): string
|
public function getUnixConfigureArg(): string
|
||||||
{
|
{
|
||||||
// pdo_pgsql need to be disabled
|
// pdo_pgsql need to be disabled
|
||||||
@@ -22,7 +27,7 @@ class swoole_hook_sqlite extends Extension
|
|||||||
return '--enable-swoole-sqlite';
|
return '--enable-swoole-sqlite';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function runCliCheck(): void
|
public function runCliCheckUnix(): void
|
||||||
{
|
{
|
||||||
// skip if not enable swoole
|
// skip if not enable swoole
|
||||||
if ($this->builder->getExt('swoole') === null) {
|
if ($this->builder->getExt('swoole') === null) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace SPC\builder\extension;
|
|||||||
|
|
||||||
use SPC\builder\Extension;
|
use SPC\builder\Extension;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
#[CustomExt('xml')]
|
#[CustomExt('xml')]
|
||||||
@@ -33,4 +34,25 @@ class xml extends Extension
|
|||||||
$arg .= ' --with-libxml="' . BUILD_ROOT_PATH . '"';
|
$arg .= ' --with-libxml="' . BUILD_ROOT_PATH . '"';
|
||||||
return $arg;
|
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';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,19 +4,15 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\freebsd;
|
namespace SPC\builder\freebsd;
|
||||||
|
|
||||||
use SPC\builder\BuilderBase;
|
use SPC\builder\unix\UnixBuilderBase;
|
||||||
use SPC\builder\traits\UnixBuilderTrait;
|
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
|
|
||||||
class BSDBuilder extends BuilderBase
|
class BSDBuilder extends UnixBuilderBase
|
||||||
{
|
{
|
||||||
/** Unix compatible builder methods */
|
|
||||||
use UnixBuilderTrait;
|
|
||||||
|
|
||||||
/** @var bool Micro patch phar flag */
|
/** @var bool Micro patch phar flag */
|
||||||
private bool $phar_patched = false;
|
private bool $phar_patched = false;
|
||||||
|
|
||||||
@@ -81,10 +77,12 @@ class BSDBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
$this->setOption('extra-libs', $extra_libs);
|
$this->setOption('extra-libs', $extra_libs);
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-buildconf');
|
||||||
SourcePatcher::patchBeforeBuildconf($this);
|
SourcePatcher::patchBeforeBuildconf($this);
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-configure');
|
||||||
SourcePatcher::patchBeforeConfigure($this);
|
SourcePatcher::patchBeforeConfigure($this);
|
||||||
|
|
||||||
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
||||||
@@ -115,6 +113,7 @@ class BSDBuilder extends BuilderBase
|
|||||||
$this->makeExtensionArgs()
|
$this->makeExtensionArgs()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-make');
|
||||||
SourcePatcher::patchBeforeMake($this);
|
SourcePatcher::patchBeforeMake($this);
|
||||||
|
|
||||||
$this->cleanMake();
|
$this->cleanMake();
|
||||||
@@ -140,6 +139,7 @@ class BSDBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (php_uname('m') === $this->getOption('arch')) {
|
if (php_uname('m') === $this->getOption('arch')) {
|
||||||
|
$this->emitPatchPoint('before-sanity-check');
|
||||||
$this->sanityCheck($build_target);
|
$this->sanityCheck($build_target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,7 +150,7 @@ class BSDBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildCli(): void
|
protected function buildCli(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString([
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||||
@@ -173,7 +173,7 @@ class BSDBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function buildMicro(): void
|
protected function buildMicro(): void
|
||||||
{
|
{
|
||||||
if ($this->getPHPVersionID() < 80000) {
|
if ($this->getPHPVersionID() < 80000) {
|
||||||
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
||||||
@@ -211,7 +211,7 @@ class BSDBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildFpm(): void
|
protected function buildFpm(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString([
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||||
@@ -231,7 +231,7 @@ class BSDBuilder extends BuilderBase
|
|||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public function buildEmbed(): void
|
protected function buildEmbed(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString([
|
$vars = SystemUtil::makeEnvVarString([
|
||||||
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
|
||||||
|
|||||||
@@ -4,20 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\linux;
|
namespace SPC\builder\linux;
|
||||||
|
|
||||||
use SPC\builder\BuilderBase;
|
|
||||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||||
use SPC\builder\traits\UnixBuilderTrait;
|
use SPC\builder\unix\UnixBuilderBase;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
|
|
||||||
class LinuxBuilder extends BuilderBase
|
class LinuxBuilder extends UnixBuilderBase
|
||||||
{
|
{
|
||||||
/** Unix compatible builder methods */
|
|
||||||
use UnixBuilderTrait;
|
|
||||||
|
|
||||||
/** @var array Tune cflags */
|
/** @var array Tune cflags */
|
||||||
public array $tune_c_flags;
|
public array $tune_c_flags;
|
||||||
|
|
||||||
@@ -147,10 +143,13 @@ class LinuxBuilder extends BuilderBase
|
|||||||
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
||||||
'LIBS' => '-ldl -lpthread',
|
'LIBS' => '-ldl -lpthread',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-buildconf');
|
||||||
SourcePatcher::patchBeforeBuildconf($this);
|
SourcePatcher::patchBeforeBuildconf($this);
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-configure');
|
||||||
SourcePatcher::patchBeforeConfigure($this);
|
SourcePatcher::patchBeforeConfigure($this);
|
||||||
|
|
||||||
$phpVersionID = $this->getPHPVersionID();
|
$phpVersionID = $this->getPHPVersionID();
|
||||||
@@ -170,6 +169,27 @@ class LinuxBuilder extends BuilderBase
|
|||||||
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
|
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
|
||||||
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
|
$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')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec(
|
->exec(
|
||||||
"{$this->getOption('ld_library_path')} " .
|
"{$this->getOption('ld_library_path')} " .
|
||||||
@@ -193,6 +213,7 @@ class LinuxBuilder extends BuilderBase
|
|||||||
' ' . $envs_build_php . ' '
|
' ' . $envs_build_php . ' '
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-make');
|
||||||
SourcePatcher::patchBeforeMake($this);
|
SourcePatcher::patchBeforeMake($this);
|
||||||
|
|
||||||
$this->cleanMake();
|
$this->cleanMake();
|
||||||
@@ -218,6 +239,7 @@ class LinuxBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (php_uname('m') === $this->getOption('arch')) {
|
if (php_uname('m') === $this->getOption('arch')) {
|
||||||
|
$this->emitPatchPoint('before-sanity-check');
|
||||||
$this->sanityCheck($build_target);
|
$this->sanityCheck($build_target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,14 +250,18 @@ class LinuxBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildCli(): void
|
protected function buildCli(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec("make -j{$this->concurrency} {$vars} cli");
|
->exec("make -j{$this->concurrency} {$vars} cli");
|
||||||
|
|
||||||
if (!$this->getOption('no-strip', false)) {
|
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');
|
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')->exec('strip --strip-all php');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +275,7 @@ class LinuxBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function buildMicro(): void
|
protected function buildMicro(): void
|
||||||
{
|
{
|
||||||
if ($this->getPHPVersionID() < 80000) {
|
if ($this->getPHPVersionID() < 80000) {
|
||||||
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
||||||
@@ -266,10 +292,6 @@ class LinuxBuilder extends BuilderBase
|
|||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec("make -j{$this->concurrency} {$vars} micro");
|
->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);
|
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||||
|
|
||||||
if ($this->phar_patched) {
|
if ($this->phar_patched) {
|
||||||
@@ -283,17 +305,20 @@ class LinuxBuilder extends BuilderBase
|
|||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public function buildFpm(): void
|
protected function buildFpm(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec("make -j{$this->concurrency} {$vars} fpm");
|
->exec("make -j{$this->concurrency} {$vars} fpm");
|
||||||
|
|
||||||
if (!$this->getOption('no-strip', false)) {
|
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');
|
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-all php-fpm');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_FPM);
|
$this->deployBinary(BUILD_TARGET_FPM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +327,7 @@ class LinuxBuilder extends BuilderBase
|
|||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public function buildEmbed(): void
|
protected function buildEmbed(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
||||||
|
|
||||||
|
|||||||
@@ -110,11 +110,7 @@ class SystemUtil
|
|||||||
public static function getTuneCFlags(string $arch): array
|
public static function getTuneCFlags(string $arch): array
|
||||||
{
|
{
|
||||||
return match ($arch) {
|
return match ($arch) {
|
||||||
'x86_64' => [
|
'x86_64', 'arm64', 'aarch64' => [],
|
||||||
'-march=corei7',
|
|
||||||
'-mtune=core-avx2',
|
|
||||||
],
|
|
||||||
'arm64', 'aarch64' => [],
|
|
||||||
default => throw new RuntimeException('unsupported arch: ' . $arch),
|
default => throw new RuntimeException('unsupported arch: ' . $arch),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -209,4 +205,21 @@ class SystemUtil
|
|||||||
}
|
}
|
||||||
return $ret;
|
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',
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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';
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\linux\library;
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
use SPC\exception\WrongUsageException;
|
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
class libargon2 extends LinuxLibraryBase
|
class libargon2 extends LinuxLibraryBase
|
||||||
@@ -15,10 +14,6 @@ class libargon2 extends LinuxLibraryBase
|
|||||||
|
|
||||||
public function patchBeforeBuild(): bool
|
public function patchBeforeBuild(): bool
|
||||||
{
|
{
|
||||||
// detect libsodium (The libargon2 conflicts with the libsodium library.)
|
|
||||||
if ($this->builder->getLib('libsodium') !== null) {
|
|
||||||
throw new WrongUsageException('libargon2 (required by password-argon2) conflicts with the libsodium library !');
|
|
||||||
}
|
|
||||||
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'LIBRARY_REL ?= lib/x86_64-linux-gnu', 'LIBRARY_REL ?= lib');
|
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'LIBRARY_REL ?= lib/x86_64-linux-gnu', 'LIBRARY_REL ?= lib');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
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';
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ class libxml2 extends LinuxLibraryBase
|
|||||||
*/
|
*/
|
||||||
public function build(): void
|
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_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
|
||||||
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ class libxml2 extends LinuxLibraryBase
|
|||||||
'cmake ' .
|
'cmake ' .
|
||||||
'-DCMAKE_BUILD_TYPE=Release ' .
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
|
||||||
|
'-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' .
|
||||||
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
'-DBUILD_SHARED_LIBS=OFF ' .
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
'-DIconv_IS_BUILT_IN=OFF ' .
|
'-DIconv_IS_BUILT_IN=OFF ' .
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ use SPC\builder\linux\SystemUtil;
|
|||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
class openssl extends LinuxLibraryBase
|
class openssl extends LinuxLibraryBase
|
||||||
{
|
{
|
||||||
@@ -76,5 +77,15 @@ class openssl extends LinuxLibraryBase
|
|||||||
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
||||||
->exec("make install_sw DESTDIR={$destdir}");
|
->exec("make install_sw DESTDIR={$destdir}");
|
||||||
$this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']);
|
$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';
|
||||||
|
}
|
||||||
@@ -4,20 +4,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\macos;
|
namespace SPC\builder\macos;
|
||||||
|
|
||||||
use SPC\builder\BuilderBase;
|
|
||||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||||
use SPC\builder\traits\UnixBuilderTrait;
|
use SPC\builder\unix\UnixBuilderBase;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
|
|
||||||
class MacOSBuilder extends BuilderBase
|
class MacOSBuilder extends UnixBuilderBase
|
||||||
{
|
{
|
||||||
/** Unix compatible builder methods */
|
|
||||||
use UnixBuilderTrait;
|
|
||||||
|
|
||||||
/** @var bool Micro patch phar flag */
|
/** @var bool Micro patch phar flag */
|
||||||
private bool $phar_patched = false;
|
private bool $phar_patched = false;
|
||||||
|
|
||||||
@@ -141,10 +137,12 @@ class MacOSBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
$this->setOption('extra-libs', $extra_libs);
|
$this->setOption('extra-libs', $extra_libs);
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-buildconf');
|
||||||
SourcePatcher::patchBeforeBuildconf($this);
|
SourcePatcher::patchBeforeBuildconf($this);
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-configure');
|
||||||
SourcePatcher::patchBeforeConfigure($this);
|
SourcePatcher::patchBeforeConfigure($this);
|
||||||
|
|
||||||
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
||||||
@@ -190,6 +188,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
$envs_build_php
|
$envs_build_php
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$this->emitPatchPoint('before-php-make');
|
||||||
SourcePatcher::patchBeforeMake($this);
|
SourcePatcher::patchBeforeMake($this);
|
||||||
|
|
||||||
$this->cleanMake();
|
$this->cleanMake();
|
||||||
@@ -215,6 +214,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (php_uname('m') === $this->getOption('arch')) {
|
if (php_uname('m') === $this->getOption('arch')) {
|
||||||
|
$this->emitPatchPoint('before-sanity-check');
|
||||||
$this->sanityCheck($build_target);
|
$this->sanityCheck($build_target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildCli(): void
|
protected function buildCli(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
||||||
|
|
||||||
@@ -244,7 +244,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function buildMicro(): void
|
protected function buildMicro(): void
|
||||||
{
|
{
|
||||||
if ($this->getPHPVersionID() < 80000) {
|
if ($this->getPHPVersionID() < 80000) {
|
||||||
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
||||||
@@ -280,7 +280,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public function buildFpm(): void
|
protected function buildFpm(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ class MacOSBuilder extends BuilderBase
|
|||||||
*
|
*
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public function buildEmbed(): void
|
protected function buildEmbed(): void
|
||||||
{
|
{
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
|
||||||
|
|
||||||
|
|||||||
12
src/SPC/builder/macos/library/gettext.php
Normal file
12
src/SPC/builder/macos/library/gettext.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
class gettext extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
use \SPC\builder\unix\library\gettext;
|
||||||
|
|
||||||
|
public const NAME = 'gettext';
|
||||||
|
}
|
||||||
12
src/SPC/builder/macos/library/librabbitmq.php
Normal file
12
src/SPC/builder/macos/library/librabbitmq.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
class librabbitmq extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
use \SPC\builder\unix\library\librabbitmq;
|
||||||
|
|
||||||
|
public const NAME = 'librabbitmq';
|
||||||
|
}
|
||||||
12
src/SPC/builder/macos/library/libtiff.php
Normal file
12
src/SPC/builder/macos/library/libtiff.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
class libtiff extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
use \SPC\builder\unix\library\libtiff;
|
||||||
|
|
||||||
|
public const NAME = 'libtiff';
|
||||||
|
}
|
||||||
12
src/SPC/builder/macos/library/libuuid.php
Normal file
12
src/SPC/builder/macos/library/libuuid.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
class libuuid extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
use \SPC\builder\unix\library\libuuid;
|
||||||
|
|
||||||
|
public const NAME = 'libuuid';
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ class libxml2 extends MacOSLibraryBase
|
|||||||
*/
|
*/
|
||||||
protected function build(): void
|
protected 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_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
|
||||||
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
|
||||||
|
|
||||||
@@ -29,6 +29,7 @@ class libxml2 extends MacOSLibraryBase
|
|||||||
// '--debug-find ' .
|
// '--debug-find ' .
|
||||||
'-DCMAKE_BUILD_TYPE=Release ' .
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
|
||||||
|
'-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' .
|
||||||
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
'-DBUILD_SHARED_LIBS=OFF ' .
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
'-DLIBXML2_WITH_ICONV=ON ' .
|
'-DLIBXML2_WITH_ICONV=ON ' .
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ namespace SPC\builder\macos\library;
|
|||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
class openssl extends MacOSLibraryBase
|
class openssl extends MacOSLibraryBase
|
||||||
{
|
{
|
||||||
@@ -58,5 +59,15 @@ class openssl extends MacOSLibraryBase
|
|||||||
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
||||||
->exec("make install_sw DESTDIR={$destdir}");
|
->exec("make install_sw DESTDIR={$destdir}");
|
||||||
$this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']);
|
$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/macos/library/qdbm.php
Normal file
12
src/SPC/builder/macos/library/qdbm.php
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\macos\library;
|
||||||
|
|
||||||
|
class qdbm extends MacOSLibraryBase
|
||||||
|
{
|
||||||
|
use \SPC\builder\unix\library\qdbm;
|
||||||
|
|
||||||
|
public const NAME = 'qdbm';
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace SPC\builder\traits;
|
|
||||||
|
|
||||||
trait LibraryTrait {}
|
|
||||||
@@ -12,8 +12,6 @@ use SPC\store\FileSystem;
|
|||||||
|
|
||||||
trait UnixLibraryTrait
|
trait UnixLibraryTrait
|
||||||
{
|
{
|
||||||
use LibraryTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
@@ -50,7 +48,7 @@ trait UnixLibraryTrait
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
public function makeAutoconfEnv(string $prefix = null): string
|
public function makeAutoconfEnv(?string $prefix = null): string
|
||||||
{
|
{
|
||||||
if ($prefix === null) {
|
if ($prefix === null) {
|
||||||
$prefix = str_replace('-', '_', strtoupper(static::NAME));
|
$prefix = str_replace('-', '_', strtoupper(static::NAME));
|
||||||
|
|||||||
@@ -2,15 +2,19 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace SPC\builder\traits;
|
namespace SPC\builder\unix;
|
||||||
|
|
||||||
|
use SPC\builder\BuilderBase;
|
||||||
use SPC\builder\linux\LinuxBuilder;
|
use SPC\builder\linux\LinuxBuilder;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\Config;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\store\SourceManager;
|
||||||
|
use SPC\util\DependencyUtil;
|
||||||
|
|
||||||
trait UnixBuilderTrait
|
abstract class UnixBuilderBase extends BuilderBase
|
||||||
{
|
{
|
||||||
/** @var string cflags */
|
/** @var string cflags */
|
||||||
public string $arch_c_flags;
|
public string $arch_c_flags;
|
||||||
@@ -49,77 +53,6 @@ trait UnixBuilderTrait
|
|||||||
return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles);
|
return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sanity check after build complete
|
|
||||||
*
|
|
||||||
* @throws RuntimeException
|
|
||||||
*/
|
|
||||||
public function sanityCheck(int $build_target): void
|
|
||||||
{
|
|
||||||
// sanity check for php-cli
|
|
||||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
|
||||||
logger()->info('running cli sanity check');
|
|
||||||
[$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"');
|
|
||||||
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
|
|
||||||
throw new RuntimeException('cli failed sanity check');
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->exts as $ext) {
|
|
||||||
logger()->debug('testing ext: ' . $ext->getName());
|
|
||||||
$ext->runCliCheck();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sanity check for phpmicro
|
|
||||||
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
|
||||||
if (file_exists(SOURCE_PATH . '/hello.exe')) {
|
|
||||||
@unlink(SOURCE_PATH . '/hello.exe');
|
|
||||||
}
|
|
||||||
file_put_contents(
|
|
||||||
SOURCE_PATH . '/hello.exe',
|
|
||||||
file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') .
|
|
||||||
'<?php echo "hello";'
|
|
||||||
);
|
|
||||||
chmod(SOURCE_PATH . '/hello.exe', 0755);
|
|
||||||
[$ret, $output2] = shell()->execWithResult(SOURCE_PATH . '/hello.exe');
|
|
||||||
if ($ret !== 0 || trim($out = implode('', $output2)) !== 'hello') {
|
|
||||||
throw new RuntimeException('micro failed sanity check, ret[' . $ret . '], out[' . ($out ?? 'NULL') . ']');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将编译好的二进制文件发布到 buildroot
|
|
||||||
*
|
|
||||||
* @param int $type 发布类型
|
|
||||||
* @throws RuntimeException
|
|
||||||
* @throws FileSystemException
|
|
||||||
*/
|
|
||||||
public function deployBinary(int $type): bool
|
|
||||||
{
|
|
||||||
$src = match ($type) {
|
|
||||||
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
|
|
||||||
BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
|
|
||||||
BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm',
|
|
||||||
default => throw new RuntimeException('Deployment does not accept type ' . $type),
|
|
||||||
};
|
|
||||||
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
|
||||||
FileSystem::createDir(BUILD_ROOT_PATH . '/bin');
|
|
||||||
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '/bin/'));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run php clean
|
|
||||||
*
|
|
||||||
* @throws RuntimeException
|
|
||||||
*/
|
|
||||||
public function cleanMake(): void
|
|
||||||
{
|
|
||||||
logger()->info('cleaning up');
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')->exec('make clean');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return generic cmake options when configuring cmake projects
|
* Return generic cmake options when configuring cmake projects
|
||||||
*/
|
*/
|
||||||
@@ -156,4 +89,139 @@ trait UnixBuilderTrait
|
|||||||
}
|
}
|
||||||
return $extra;
|
return $extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function buildLibs(array $sorted_libraries): void
|
||||||
|
{
|
||||||
|
// search all supported libs
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no libs specified, compile all supported libs
|
||||||
|
if ($sorted_libraries === [] && $this->isLibsOnly()) {
|
||||||
|
$libraries = array_keys($support_lib_list);
|
||||||
|
$sorted_libraries = DependencyUtil::getLibs($libraries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pkg-config must be compiled first, whether it is specified or not
|
||||||
|
if (!in_array('pkg-config', $sorted_libraries)) {
|
||||||
|
array_unshift($sorted_libraries, 'pkg-config');
|
||||||
|
}
|
||||||
|
|
||||||
|
// add lib object for builder
|
||||||
|
foreach ($sorted_libraries as $library) {
|
||||||
|
// if some libs are not supported (but in config "lib.json", throw exception)
|
||||||
|
if (!isset($support_lib_list[$library])) {
|
||||||
|
throw new WrongUsageException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
|
||||||
|
}
|
||||||
|
$lib = new ($support_lib_list[$library])($this);
|
||||||
|
$this->addLib($lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate and check dependencies
|
||||||
|
foreach ($this->libs as $lib) {
|
||||||
|
$lib->calcDependency();
|
||||||
|
}
|
||||||
|
|
||||||
|
// patch point
|
||||||
|
$this->emitPatchPoint('before-libs-extract');
|
||||||
|
|
||||||
|
// extract sources
|
||||||
|
SourceManager::initSource(libs: $sorted_libraries);
|
||||||
|
|
||||||
|
$this->emitPatchPoint('after-libs-extract');
|
||||||
|
|
||||||
|
// build all libs
|
||||||
|
foreach ($this->libs as $lib) {
|
||||||
|
match ($lib->tryBuild($this->getOption('rebuild', false))) {
|
||||||
|
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
|
||||||
|
BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
|
||||||
|
BUILD_STATUS_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
|
||||||
|
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanity check after build complete
|
||||||
|
*
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function sanityCheck(int $build_target): void
|
||||||
|
{
|
||||||
|
// sanity check for php-cli
|
||||||
|
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||||
|
logger()->info('running cli sanity check');
|
||||||
|
[$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"');
|
||||||
|
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
|
||||||
|
throw new RuntimeException('cli failed sanity check');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->exts as $ext) {
|
||||||
|
logger()->debug('testing ext: ' . $ext->getName());
|
||||||
|
$ext->runCliCheckUnix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity check for phpmicro
|
||||||
|
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||||
|
if (file_exists(SOURCE_PATH . '/hello.exe')) {
|
||||||
|
@unlink(SOURCE_PATH . '/hello.exe');
|
||||||
|
}
|
||||||
|
file_put_contents(
|
||||||
|
SOURCE_PATH . '/hello.exe',
|
||||||
|
file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') .
|
||||||
|
($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests())
|
||||||
|
);
|
||||||
|
chmod(SOURCE_PATH . '/hello.exe', 0755);
|
||||||
|
[$ret, $output2] = shell()->execWithResult(SOURCE_PATH . '/hello.exe');
|
||||||
|
$raw_out = trim(implode('', $output2));
|
||||||
|
$condition[0] = $ret === 0;
|
||||||
|
$condition[1] = str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
|
||||||
|
foreach ($condition as $k => $v) {
|
||||||
|
if (!$v) {
|
||||||
|
throw new RuntimeException("micro failed sanity check with condition[{$k}], ret[{$ret}], out[{$raw_out}]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将编译好的二进制文件发布到 buildroot
|
||||||
|
*
|
||||||
|
* @param int $type 发布类型
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function deployBinary(int $type): bool
|
||||||
|
{
|
||||||
|
$src = match ($type) {
|
||||||
|
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
|
||||||
|
BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
|
||||||
|
BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm',
|
||||||
|
default => throw new RuntimeException('Deployment does not accept type ' . $type),
|
||||||
|
};
|
||||||
|
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
||||||
|
FileSystem::createDir(BUILD_ROOT_PATH . '/bin');
|
||||||
|
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '/bin/'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run php clean
|
||||||
|
*
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function cleanMake(): void
|
||||||
|
{
|
||||||
|
logger()->info('cleaning up');
|
||||||
|
shell()->cd(SOURCE_PATH . '/php-src')->exec('make clean');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ trait curl
|
|||||||
// compile!
|
// compile!
|
||||||
shell()->cd($this->source_dir . '/build')
|
shell()->cd($this->source_dir . '/build')
|
||||||
->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ../CMakeLists.txt')
|
->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ../CMakeLists.txt')
|
||||||
->exec("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF {$extra} ..")
|
->exec("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF -DBUILD_LIBCURL_DOCS=OFF {$extra} ..")
|
||||||
->exec("make -j{$this->builder->concurrency}")
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
||||||
// patch pkgconf
|
// patch pkgconf
|
||||||
|
|||||||
28
src/SPC/builder/unix/library/gettext.php
Normal file
28
src/SPC/builder/unix/library/gettext.php
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
trait gettext
|
||||||
|
{
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
$extra = $this->builder->getLib('ncurses') ? ('--with-libncurses-prefix=' . BUILD_ROOT_PATH . ' ') : '';
|
||||||
|
$extra .= $this->builder->getLib('libxml2') ? ('--with-libxml2-prefix=' . BUILD_ROOT_PATH . ' ') : '';
|
||||||
|
shell()->cd($this->source_dir)
|
||||||
|
->exec(
|
||||||
|
'./configure ' .
|
||||||
|
'--enable-static ' .
|
||||||
|
'--disable-shared ' .
|
||||||
|
'--disable-java ' .
|
||||||
|
'--disable-c+ ' .
|
||||||
|
$extra .
|
||||||
|
'--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' .
|
||||||
|
'--prefix=' . BUILD_ROOT_PATH
|
||||||
|
)
|
||||||
|
->exec('make clean')
|
||||||
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
|
->exec('make install');
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/SPC/builder/unix/library/librabbitmq.php
Normal file
35
src/SPC/builder/unix/library/librabbitmq.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
trait librabbitmq
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
// CMake needs a clean build directory
|
||||||
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
|
// Start build
|
||||||
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
->exec(
|
||||||
|
'cmake ' .
|
||||||
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
|
'-DBUILD_STATIC_LIBS=ON ' .
|
||||||
|
'..'
|
||||||
|
)
|
||||||
|
->exec("cmake --build . -j {$this->builder->concurrency}")
|
||||||
|
->exec('make install');
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/SPC/builder/unix/library/libtiff.php
Normal file
30
src/SPC/builder/unix/library/libtiff.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
|
||||||
|
trait libtiff
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
shell()->cd($this->source_dir)
|
||||||
|
->exec(
|
||||||
|
'./configure ' .
|
||||||
|
'--enable-static --disable-shared ' .
|
||||||
|
'--disable-cxx ' .
|
||||||
|
'--prefix='
|
||||||
|
)
|
||||||
|
->exec('make clean')
|
||||||
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
|
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
||||||
|
$this->patchPkgconfPrefix(['libtiff-4.pc']);
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/SPC/builder/unix/library/libuuid.php
Normal file
46
src/SPC/builder/unix/library/libuuid.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
trait libuuid
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
->exec(
|
||||||
|
'cmake ' .
|
||||||
|
"{$this->builder->makeCmakeArgs()} " .
|
||||||
|
'..'
|
||||||
|
)
|
||||||
|
->exec("cmake --build . -j {$this->builder->concurrency}");
|
||||||
|
copy($this->source_dir . '/build/libuuid.a', BUILD_LIB_PATH . '/libuuid.a');
|
||||||
|
FileSystem::createDir(BUILD_INCLUDE_PATH . '/uuid');
|
||||||
|
copy($this->source_dir . '/uuid.h', BUILD_INCLUDE_PATH . '/uuid/uuid.h');
|
||||||
|
$pc = FileSystem::readFile($this->source_dir . '/uuid.pc.in');
|
||||||
|
$pc = str_replace([
|
||||||
|
'@prefix@',
|
||||||
|
'@exec_prefix@',
|
||||||
|
'@libdir@',
|
||||||
|
'@includedir@',
|
||||||
|
'@LIBUUID_VERSION@',
|
||||||
|
], [
|
||||||
|
BUILD_ROOT_PATH,
|
||||||
|
'${prefix}',
|
||||||
|
'${prefix}/lib',
|
||||||
|
'${prefix}/include',
|
||||||
|
'1.0.3',
|
||||||
|
], $pc);
|
||||||
|
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/uuid.pc', $pc);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ trait ncurses
|
|||||||
'--without-tests ' .
|
'--without-tests ' .
|
||||||
'--without-dlsym ' .
|
'--without-dlsym ' .
|
||||||
'--without-debug ' .
|
'--without-debug ' .
|
||||||
'-enable-symlinks' .
|
'-enable-symlinks ' .
|
||||||
'--bindir=' . BUILD_ROOT_PATH . '/bin ' .
|
'--bindir=' . BUILD_ROOT_PATH . '/bin ' .
|
||||||
'--includedir=' . BUILD_ROOT_PATH . '/include ' .
|
'--includedir=' . BUILD_ROOT_PATH . '/include ' .
|
||||||
'--libdir=' . BUILD_ROOT_PATH . '/lib ' .
|
'--libdir=' . BUILD_ROOT_PATH . '/lib ' .
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ trait pkgconfig
|
|||||||
{
|
{
|
||||||
protected function build(): void
|
protected function build(): void
|
||||||
{
|
{
|
||||||
$macos_env = "CFLAGS='{$this->builder->arch_c_flags} -Wimplicit-function-declaration' ";
|
$macos_env = "CFLAGS='{$this->builder->arch_c_flags} -Wimplicit-function-declaration -Wno-int-conversion' ";
|
||||||
$linux_env = 'LDFLAGS=--static ';
|
$linux_env = 'LDFLAGS=--static ';
|
||||||
|
|
||||||
shell()->cd($this->source_dir)
|
shell()->cd($this->source_dir)
|
||||||
@@ -21,6 +21,8 @@ trait pkgconfig
|
|||||||
'--disable-shared ' .
|
'--disable-shared ' .
|
||||||
'--enable-static ' .
|
'--enable-static ' .
|
||||||
'--with-internal-glib ' .
|
'--with-internal-glib ' .
|
||||||
|
'--disable-host-tool ' .
|
||||||
|
'--with-pic ' .
|
||||||
'--prefix=' . BUILD_ROOT_PATH . ' ' .
|
'--prefix=' . BUILD_ROOT_PATH . ' ' .
|
||||||
'--without-sysroot ' .
|
'--without-sysroot ' .
|
||||||
'--without-system-include-path ' .
|
'--without-system-include-path ' .
|
||||||
@@ -29,6 +31,7 @@ trait pkgconfig
|
|||||||
)
|
)
|
||||||
->exec('make clean')
|
->exec('make clean')
|
||||||
->exec("make -j{$this->builder->concurrency}")
|
->exec("make -j{$this->builder->concurrency}")
|
||||||
->exec('make install');
|
->exec('make install-exec');
|
||||||
|
shell()->exec('strip ' . BUILD_ROOT_PATH . '/bin/pkg-config');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,26 +27,31 @@ trait postgresql
|
|||||||
'libxslt' => 'libxslt',
|
'libxslt' => 'libxslt',
|
||||||
'icu' => 'icu-i18n',
|
'icu' => 'icu-i18n',
|
||||||
];
|
];
|
||||||
|
$error_exec_cnt = 0;
|
||||||
|
|
||||||
foreach ($optional_packages as $lib => $pkg) {
|
foreach ($optional_packages as $lib => $pkg) {
|
||||||
if ($this->getBuilder()->getLib($lib)) {
|
if ($this->getBuilder()->getLib($lib)) {
|
||||||
$packages .= ' ' . $pkg;
|
$packages .= ' ' . $pkg;
|
||||||
$output = shell()->execWithResult("pkg-config --static {$pkg}");
|
$output = shell()->execWithResult("pkg-config --static {$pkg}");
|
||||||
|
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||||
logger()->info(var_export($output[1], true));
|
logger()->info(var_export($output[1], true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = shell()->execWithResult("pkg-config --cflags-only-I --static {$packages}");
|
$output = shell()->execWithResult("pkg-config --cflags-only-I --static {$packages}");
|
||||||
|
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||||
if (!empty($output[1][0])) {
|
if (!empty($output[1][0])) {
|
||||||
$cppflags = $output[1][0];
|
$cppflags = $output[1][0];
|
||||||
$envs .= " CPPFLAGS=\"{$cppflags}\"";
|
$envs .= " CPPFLAGS=\"{$cppflags}\"";
|
||||||
}
|
}
|
||||||
$output = shell()->execWithResult("pkg-config --libs-only-L --static {$packages}");
|
$output = shell()->execWithResult("pkg-config --libs-only-L --static {$packages}");
|
||||||
|
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||||
if (!empty($output[1][0])) {
|
if (!empty($output[1][0])) {
|
||||||
$ldflags = $output[1][0];
|
$ldflags = $output[1][0];
|
||||||
$envs .= $this instanceof MacOSLibraryBase ? " LDFLAGS=\"{$ldflags}\" " : " LDFLAGS=\"{$ldflags} -static\" ";
|
$envs .= $this instanceof MacOSLibraryBase ? " LDFLAGS=\"{$ldflags}\" " : " LDFLAGS=\"{$ldflags} -static\" ";
|
||||||
}
|
}
|
||||||
$output = shell()->execWithResult("pkg-config --libs-only-l --static {$packages}");
|
$output = shell()->execWithResult("pkg-config --libs-only-l --static {$packages}");
|
||||||
|
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||||
if (!empty($output[1][0])) {
|
if (!empty($output[1][0])) {
|
||||||
$libs = $output[1][0];
|
$libs = $output[1][0];
|
||||||
$libcpp = '';
|
$libcpp = '';
|
||||||
@@ -55,14 +60,23 @@ trait postgresql
|
|||||||
}
|
}
|
||||||
$envs .= " LIBS=\"{$libs}{$libcpp}\" ";
|
$envs .= " LIBS=\"{$libs}{$libcpp}\" ";
|
||||||
}
|
}
|
||||||
|
if ($error_exec_cnt > 0) {
|
||||||
|
throw new RuntimeException('Failed to get pkg-config information!');
|
||||||
|
}
|
||||||
|
|
||||||
FileSystem::resetDir($this->source_dir . '/build');
|
FileSystem::resetDir($this->source_dir . '/build');
|
||||||
|
|
||||||
# 有静态链接配置 参考文件: src/interfaces/libpq/Makefile
|
$version = $this->getVersion();
|
||||||
shell()->cd($this->source_dir . '/build')
|
// 16.1 workaround
|
||||||
->exec('sed -i.backup "s/invokes exit\'; exit 1;/invokes exit\';/" ../src/interfaces/libpq/Makefile')
|
if (version_compare($version, '16.1') >= 0) {
|
||||||
->exec('sed -i.backup "278 s/^/# /" ../src/Makefile.shlib')
|
# 有静态链接配置 参考文件: src/interfaces/libpq/Makefile
|
||||||
->exec('sed -i.backup "402 s/^/# /" ../src/Makefile.shlib');
|
shell()->cd($this->source_dir . '/build')
|
||||||
|
->exec('sed -i.backup "s/invokes exit\'; exit 1;/invokes exit\';/" ../src/interfaces/libpq/Makefile')
|
||||||
|
->exec('sed -i.backup "278 s/^/# /" ../src/Makefile.shlib')
|
||||||
|
->exec('sed -i.backup "402 s/^/# /" ../src/Makefile.shlib');
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException('Unsupported version for postgresql: ' . $version . ' !');
|
||||||
|
}
|
||||||
|
|
||||||
// configure
|
// configure
|
||||||
shell()->cd($this->source_dir . '/build')
|
shell()->cd($this->source_dir . '/build')
|
||||||
@@ -101,4 +115,17 @@ trait postgresql
|
|||||||
->exec("rm -rf {$builddir}/lib/*.so")
|
->exec("rm -rf {$builddir}/lib/*.so")
|
||||||
->exec("rm -rf {$builddir}/lib/*.dylib");
|
->exec("rm -rf {$builddir}/lib/*.dylib");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getVersion(): string
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$file = FileSystem::readFile($this->source_dir . '/meson.build');
|
||||||
|
if (preg_match("/^\\s+version:\\s?'(.*)'/m", $file, $match)) {
|
||||||
|
return $match[1];
|
||||||
|
}
|
||||||
|
return 'unknown';
|
||||||
|
} catch (FileSystemException) {
|
||||||
|
return 'unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
src/SPC/builder/unix/library/qdbm.php
Normal file
33
src/SPC/builder/unix/library/qdbm.php
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
|
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
trait qdbm
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
shell()->cd($this->source_dir)
|
||||||
|
->exec(
|
||||||
|
'./configure ' .
|
||||||
|
'--enable-static --disable-shared ' .
|
||||||
|
'--prefix='
|
||||||
|
)
|
||||||
|
->exec('make clean');
|
||||||
|
FileSystem::replaceFileRegex($this->source_dir . '/Makefile', '/MYLIBS = libqdbm.a.*/m', 'MYLIBS = libqdbm.a');
|
||||||
|
shell()->cd($this->source_dir)
|
||||||
|
->exec("make -j{$this->builder->concurrency}" . ($this instanceof MacOSLibraryBase ? ' mac' : ''))
|
||||||
|
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
||||||
|
$this->patchPkgconfPrefix(['qdbm.pc']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,17 +4,25 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\windows;
|
namespace SPC\builder\windows;
|
||||||
|
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
class SystemUtil
|
class SystemUtil
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param string $name 命令名称
|
* Find windows program using executable name.
|
||||||
* @param array $paths 寻找的目标路径(如果不传入,则使用环境变量 PATH)
|
*
|
||||||
* @return null|string 找到了返回命令路径,找不到返回 null
|
* @param string $name command name (xxx.exe)
|
||||||
|
* @param array $paths search path (default use env path)
|
||||||
|
* @return null|string null if not found, string is absolute path
|
||||||
*/
|
*/
|
||||||
public static function findCommand(string $name, array $paths = []): ?string
|
public static function findCommand(string $name, array $paths = [], bool $include_sdk_bin = false): ?string
|
||||||
{
|
{
|
||||||
if (!$paths) {
|
if (!$paths) {
|
||||||
$paths = explode(PATH_SEPARATOR, getenv('Path'));
|
$paths = explode(PATH_SEPARATOR, getenv('Path'));
|
||||||
|
if ($include_sdk_bin) {
|
||||||
|
$paths[] = PHP_SDK_PATH . '\bin';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
foreach ($paths as $path) {
|
foreach ($paths as $path) {
|
||||||
if (file_exists($path . DIRECTORY_SEPARATOR . $name)) {
|
if (file_exists($path . DIRECTORY_SEPARATOR . $name)) {
|
||||||
@@ -23,4 +31,74 @@ class SystemUtil
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find Visual Studio installation.
|
||||||
|
*
|
||||||
|
* @return array<string, string>|false False if not installed, array contains 'version' and 'dir'
|
||||||
|
*/
|
||||||
|
public static function findVisualStudio(): array|false
|
||||||
|
{
|
||||||
|
$check_path = [
|
||||||
|
'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe' => 'vs17',
|
||||||
|
'C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\MSBuild.exe' => 'vs17',
|
||||||
|
'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Current\Bin\MSBuild.exe' => 'vs17',
|
||||||
|
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe' => 'vs16',
|
||||||
|
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe' => 'vs16',
|
||||||
|
'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe' => 'vs16',
|
||||||
|
];
|
||||||
|
foreach ($check_path as $path => $vs_version) {
|
||||||
|
if (file_exists($path)) {
|
||||||
|
$vs_ver = $vs_version;
|
||||||
|
$d_dir = dirname($path, 4);
|
||||||
|
return [
|
||||||
|
'version' => $vs_ver,
|
||||||
|
'dir' => $d_dir,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get CPU count for concurrency.
|
||||||
|
*/
|
||||||
|
public static function getCpuCount(): int
|
||||||
|
{
|
||||||
|
$result = f_exec('echo %NUMBER_OF_PROCESSORS%', $out, $code);
|
||||||
|
if ($code !== 0 || !$result) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return intval($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create CMake toolchain file.
|
||||||
|
*
|
||||||
|
* @param null|string $cflags CFLAGS for cmake, default use '/MT /Os /Ob1 /DNDEBUG /D_ACRTIMP= /D_CRTIMP='
|
||||||
|
* @param null|string $ldflags LDFLAGS for cmake, default use '/nodefaultlib:msvcrt /nodefaultlib:msvcrtd /defaultlib:libcmt'
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public static function makeCmakeToolchainFile(?string $cflags = null, ?string $ldflags = null): string
|
||||||
|
{
|
||||||
|
if ($cflags === null) {
|
||||||
|
$cflags = '/MT /Os /Ob1 /DNDEBUG /D_ACRTIMP= /D_CRTIMP=';
|
||||||
|
}
|
||||||
|
if ($ldflags === null) {
|
||||||
|
$ldflags = '/nodefaultlib:msvcrt /nodefaultlib:msvcrtd /defaultlib:libcmt';
|
||||||
|
}
|
||||||
|
$buildroot = str_replace('\\', '\\\\', BUILD_ROOT_PATH);
|
||||||
|
$toolchain = <<<CMAKE
|
||||||
|
set(CMAKE_SYSTEM_NAME Windows)
|
||||||
|
SET(CMAKE_C_FLAGS "{$cflags}")
|
||||||
|
SET(CMAKE_C_FLAGS_DEBUG "{$cflags}")
|
||||||
|
SET(CMAKE_CXX_FLAGS "{$cflags}")
|
||||||
|
SET(CMAKE_CXX_FLAGS_DEBUG "{$cflags}")
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "{$ldflags}")
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH "{$buildroot}")
|
||||||
|
SET(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
|
||||||
|
CMAKE;
|
||||||
|
FileSystem::writeFile(SOURCE_PATH . '\toolchain.cmake', $toolchain);
|
||||||
|
return realpath(SOURCE_PATH . '\toolchain.cmake');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
377
src/SPC/builder/windows/WindowsBuilder.php
Normal file
377
src/SPC/builder/windows/WindowsBuilder.php
Normal file
@@ -0,0 +1,377 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows;
|
||||||
|
|
||||||
|
use SPC\builder\BuilderBase;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\Config;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\store\SourceManager;
|
||||||
|
use SPC\store\SourcePatcher;
|
||||||
|
use SPC\util\DependencyUtil;
|
||||||
|
|
||||||
|
class WindowsBuilder extends BuilderBase
|
||||||
|
{
|
||||||
|
/** @var string cmake toolchain file */
|
||||||
|
public string $cmake_toolchain_file;
|
||||||
|
|
||||||
|
public string $sdk_prefix;
|
||||||
|
|
||||||
|
private bool $zts;
|
||||||
|
|
||||||
|
/** @var bool Micro patch phar flag */
|
||||||
|
private bool $phar_patched = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function __construct(array $options = [])
|
||||||
|
{
|
||||||
|
$this->options = $options;
|
||||||
|
|
||||||
|
// ---------- set necessary options ----------
|
||||||
|
// set sdk (require visual studio 16 or 17)
|
||||||
|
$vs = SystemUtil::findVisualStudio()['version'];
|
||||||
|
$this->sdk_prefix = PHP_SDK_PATH . "\\phpsdk-{$vs}-x64.bat -t";
|
||||||
|
|
||||||
|
// set zts
|
||||||
|
$this->zts = $this->getOption('enable-zts', false);
|
||||||
|
|
||||||
|
// set concurrency
|
||||||
|
$this->concurrency = SystemUtil::getCpuCount();
|
||||||
|
|
||||||
|
// make cmake toolchain
|
||||||
|
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile();
|
||||||
|
|
||||||
|
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
|
||||||
|
f_mkdir(BUILD_LIB_PATH, recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||||
|
{
|
||||||
|
// ---------- Update extra-libs ----------
|
||||||
|
$extra_libs = $this->getOption('extra-libs', '');
|
||||||
|
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
|
||||||
|
$this->setOption('extra-libs', $extra_libs);
|
||||||
|
$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;
|
||||||
|
|
||||||
|
SourcePatcher::patchBeforeBuildconf($this);
|
||||||
|
|
||||||
|
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} buildconf.bat");
|
||||||
|
|
||||||
|
SourcePatcher::patchBeforeConfigure($this);
|
||||||
|
|
||||||
|
$zts = $this->zts ? '--enable-zts=yes ' : '--enable-zts=no ';
|
||||||
|
|
||||||
|
// with-upx-pack for phpmicro
|
||||||
|
$makefile = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.w32');
|
||||||
|
if ($this->getOption('with-upx-pack', false)) {
|
||||||
|
if (!file_exists($makefile . '.originfile')) {
|
||||||
|
copy($makefile, $makefile . '.originfile');
|
||||||
|
FileSystem::replaceFileStr($makefile, '$(MICRO_SFX):', "_MICRO_UPX = {$this->getOption('upx-exec')} --best $(MICRO_SFX)\n$(MICRO_SFX):");
|
||||||
|
FileSystem::replaceFileStr($makefile, '@$(_MICRO_MT)', "@$(_MICRO_MT)\n\t@$(_MICRO_UPX)");
|
||||||
|
}
|
||||||
|
} elseif (file_exists($makefile . '.originfile')) {
|
||||||
|
copy($makefile . '.originfile', $makefile);
|
||||||
|
unlink($makefile . '.originfile');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($logo = $this->getOption('with-micro-logo')) !== null) {
|
||||||
|
// realpath
|
||||||
|
$logo = realpath($logo);
|
||||||
|
$micro_logo = '--enable-micro-logo=' . $logo . ' ';
|
||||||
|
} else {
|
||||||
|
$micro_logo = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd()->cd(SOURCE_PATH . '\php-src')
|
||||||
|
->exec(
|
||||||
|
"{$this->sdk_prefix} configure.bat --task-args \"" .
|
||||||
|
'--disable-all ' .
|
||||||
|
'--disable-cgi ' .
|
||||||
|
'--with-php-build=' . BUILD_ROOT_PATH . ' ' .
|
||||||
|
'--with-extra-includes=' . BUILD_INCLUDE_PATH . ' ' .
|
||||||
|
'--with-extra-libs=' . BUILD_LIB_PATH . ' ' .
|
||||||
|
($enableCli ? '--enable-cli=yes ' : '--enable-cli=no ') .
|
||||||
|
($enableMicro ? ('--enable-micro=yes ' . $micro_logo) : '--enable-micro=no ') .
|
||||||
|
($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
|
||||||
|
"{$this->makeExtensionArgs()} " .
|
||||||
|
$zts .
|
||||||
|
'"'
|
||||||
|
);
|
||||||
|
|
||||||
|
SourcePatcher::patchBeforeMake($this);
|
||||||
|
|
||||||
|
$this->cleanMake();
|
||||||
|
|
||||||
|
if ($enableCli) {
|
||||||
|
logger()->info('building cli');
|
||||||
|
$this->buildCli();
|
||||||
|
}
|
||||||
|
if ($enableFpm) {
|
||||||
|
logger()->warning('Windows does not support fpm SAPI, I will skip it.');
|
||||||
|
}
|
||||||
|
if ($enableMicro) {
|
||||||
|
logger()->info('building micro');
|
||||||
|
$this->buildMicro();
|
||||||
|
}
|
||||||
|
if ($enableEmbed) {
|
||||||
|
logger()->warning('Windows does not currently support embed SAPI.');
|
||||||
|
// logger()->info('building embed');
|
||||||
|
$this->buildEmbed();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->sanityCheck($build_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
public function buildCli(): void
|
||||||
|
{
|
||||||
|
SourcePatcher::patchWindowsCLITarget();
|
||||||
|
|
||||||
|
// add nmake wrapper
|
||||||
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cli_wrapper.bat', "nmake /nologo LIBS_CLI=\"{$this->getOption('extra-libs')} ws2_32.lib shell32.lib\" EXTRA_LD_FLAGS_PROGRAM= %*");
|
||||||
|
|
||||||
|
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cli_wrapper.bat --task-args php.exe");
|
||||||
|
|
||||||
|
$this->deployBinary(BUILD_TARGET_CLI);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildEmbed(): void
|
||||||
|
{
|
||||||
|
// TODO: add embed support for windows
|
||||||
|
/*
|
||||||
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_embed_wrapper.bat', 'nmake /nologo %*');
|
||||||
|
|
||||||
|
cmd()->cd(SOURCE_PATH . '\php-src')
|
||||||
|
->exec("{$this->sdk_prefix} nmake_embed_wrapper.bat --task-args php8embed.lib");
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public function buildMicro(): void
|
||||||
|
{
|
||||||
|
// workaround for fiber (originally from https://github.com/dixyes/lwmbs/blob/master/windows/MicroBuild.php)
|
||||||
|
$makefile = FileSystem::readFile(SOURCE_PATH . '\php-src\Makefile');
|
||||||
|
if ($this->getPHPVersionID() >= 80200 && str_contains($makefile, 'FIBER_ASM_ARCH')) {
|
||||||
|
$makefile .= "\r\n" . '$(MICRO_SFX): $(BUILD_DIR)\Zend\jump_$(FIBER_ASM_ARCH)_ms_pe_masm.obj $(BUILD_DIR)\Zend\make_$(FIBER_ASM_ARCH)_ms_pe_masm.obj' . "\r\n\r\n";
|
||||||
|
} elseif ($this->getPHPVersionID() >= 80400 && str_contains($makefile, 'FIBER_ASM_ABI')) {
|
||||||
|
$makefile .= "\r\n" . '$(MICRO_SFX): $(BUILD_DIR)\Zend\jump_$(FIBER_ASM_ABI).obj $(BUILD_DIR)\Zend\make_$(FIBER_ASM_ABI).obj' . "\r\n\r\n";
|
||||||
|
}
|
||||||
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\Makefile', $makefile);
|
||||||
|
|
||||||
|
// add nmake wrapper
|
||||||
|
$fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' /DPHP_MICRO_FAKE_CLI" ' : '';
|
||||||
|
$wrapper = "nmake /nologo LIBS_MICRO=\"{$this->getOption('extra-libs')} ws2_32.lib shell32.lib\" CFLAGS_MICRO=\"/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1{$fake_cli}\" %*";
|
||||||
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_micro_wrapper.bat', $wrapper);
|
||||||
|
|
||||||
|
// phar patch for micro
|
||||||
|
if ($this->getExt('phar')) {
|
||||||
|
$this->phar_patched = true;
|
||||||
|
SourcePatcher::patchMicro(['phar']);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_micro_wrapper.bat --task-args micro");
|
||||||
|
} finally {
|
||||||
|
if ($this->phar_patched) {
|
||||||
|
SourcePatcher::patchMicro(['phar'], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildLibs(array $sorted_libraries): void
|
||||||
|
{
|
||||||
|
// search all supported libs
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no libs specified, compile all supported libs
|
||||||
|
if ($sorted_libraries === [] && $this->isLibsOnly()) {
|
||||||
|
$libraries = array_keys($support_lib_list);
|
||||||
|
$sorted_libraries = DependencyUtil::getLibs($libraries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add lib object for builder
|
||||||
|
foreach ($sorted_libraries as $library) {
|
||||||
|
// if some libs are not supported (but in config "lib.json", throw exception)
|
||||||
|
if (!isset($support_lib_list[$library])) {
|
||||||
|
throw new WrongUsageException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
|
||||||
|
}
|
||||||
|
$lib = new ($support_lib_list[$library])($this);
|
||||||
|
$this->addLib($lib);
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate and check dependencies
|
||||||
|
foreach ($this->libs as $lib) {
|
||||||
|
$lib->calcDependency();
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract sources
|
||||||
|
SourceManager::initSource(libs: $sorted_libraries);
|
||||||
|
|
||||||
|
// build all libs
|
||||||
|
foreach ($this->libs as $lib) {
|
||||||
|
match ($lib->tryBuild($this->getOption('rebuild', false))) {
|
||||||
|
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
|
||||||
|
BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
|
||||||
|
BUILD_STATUS_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
|
||||||
|
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
public function cleanMake(): void
|
||||||
|
{
|
||||||
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_clean_wrapper.bat', 'nmake /nologo %*');
|
||||||
|
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_clean_wrapper.bat --task-args \"clean\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run extension and PHP cli and micro check
|
||||||
|
*
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
public function sanityCheck(mixed $build_target): void
|
||||||
|
{
|
||||||
|
// sanity check for php-cli
|
||||||
|
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||||
|
logger()->info('running cli sanity check');
|
||||||
|
[$ret, $output] = cmd()->execWithResult(BUILD_ROOT_PATH . '\bin\php.exe -r "echo \"hello\";"');
|
||||||
|
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
|
||||||
|
throw new RuntimeException('cli failed sanity check');
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->exts as $ext) {
|
||||||
|
logger()->debug('testing ext: ' . $ext->getName());
|
||||||
|
$ext->runCliCheckWindows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sanity check for phpmicro
|
||||||
|
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||||
|
if (file_exists(SOURCE_PATH . '\hello.exe')) {
|
||||||
|
@unlink(SOURCE_PATH . '\hello.exe');
|
||||||
|
}
|
||||||
|
file_put_contents(
|
||||||
|
SOURCE_PATH . '\hello.exe',
|
||||||
|
file_get_contents(BUILD_ROOT_PATH . '\bin\micro.sfx') .
|
||||||
|
($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests())
|
||||||
|
);
|
||||||
|
chmod(SOURCE_PATH . '\hello.exe', 0755);
|
||||||
|
[$ret, $output2] = cmd()->execWithResult(SOURCE_PATH . '\hello.exe');
|
||||||
|
$raw_out = trim(implode('', $output2));
|
||||||
|
$condition[0] = $ret === 0;
|
||||||
|
$condition[1] = str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
|
||||||
|
foreach ($condition as $k => $v) {
|
||||||
|
if (!$v) {
|
||||||
|
throw new RuntimeException("micro failed sanity check with condition[{$k}], ret[{$ret}], out[{$raw_out}]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将编译好的二进制文件发布到 buildroot
|
||||||
|
*
|
||||||
|
* @param int $type 发布类型
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function deployBinary(int $type): bool
|
||||||
|
{
|
||||||
|
$ts = $this->zts ? '_TS' : '';
|
||||||
|
$src = match ($type) {
|
||||||
|
BUILD_TARGET_CLI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php.exe",
|
||||||
|
BUILD_TARGET_MICRO => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\micro.sfx",
|
||||||
|
default => throw new RuntimeException('Deployment does not accept type ' . $type),
|
||||||
|
};
|
||||||
|
|
||||||
|
// with-upx-pack for cli
|
||||||
|
if ($this->getOption('with-upx-pack', false) && $type === BUILD_TARGET_CLI) {
|
||||||
|
cmd()->exec($this->getOption('upx-exec') . ' --best ' . escapeshellarg($src));
|
||||||
|
}
|
||||||
|
|
||||||
|
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
||||||
|
FileSystem::createDir(BUILD_ROOT_PATH . '\bin');
|
||||||
|
|
||||||
|
cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '\bin\\'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws WrongUsageException
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function getAllStaticLibFiles(): array
|
||||||
|
{
|
||||||
|
$libs = [];
|
||||||
|
|
||||||
|
// reorder libs
|
||||||
|
foreach ($this->libs as $lib) {
|
||||||
|
foreach ($lib->getDependencies() as $dep) {
|
||||||
|
$libs[] = $dep;
|
||||||
|
}
|
||||||
|
$libs[] = $lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
$libFiles = [];
|
||||||
|
$libNames = [];
|
||||||
|
// merge libs
|
||||||
|
foreach ($libs as $lib) {
|
||||||
|
if (!in_array($lib::NAME, $libNames, true)) {
|
||||||
|
$libNames[] = $lib::NAME;
|
||||||
|
array_unshift($libFiles, ...$lib->getStaticLibs());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $libFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate command wrapper prefix for php-sdk internal commands.
|
||||||
|
*
|
||||||
|
* @param string $internal_cmd command in php-sdk-tools\bin
|
||||||
|
* @return string Example: C:\php-sdk-tools\phpsdk-vs17-x64.bat -t source\cmake_wrapper.bat --task-args
|
||||||
|
*/
|
||||||
|
public function makeSimpleWrapper(string $internal_cmd): string
|
||||||
|
{
|
||||||
|
$wrapper_bat = SOURCE_PATH . '\\' . crc32($internal_cmd) . '_wrapper.bat';
|
||||||
|
if (!file_exists($wrapper_bat)) {
|
||||||
|
file_put_contents($wrapper_bat, $internal_cmd . ' %*');
|
||||||
|
}
|
||||||
|
return "{$this->sdk_prefix} {$wrapper_bat} --task-args";
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/SPC/builder/windows/library/WindowsLibraryBase.php
Normal file
72
src/SPC/builder/windows/library/WindowsLibraryBase.php
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\builder\BuilderBase;
|
||||||
|
use SPC\builder\LibraryBase;
|
||||||
|
use SPC\builder\windows\WindowsBuilder;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
abstract class WindowsLibraryBase extends LibraryBase
|
||||||
|
{
|
||||||
|
public function __construct(protected WindowsBuilder $builder)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBuilder(): BuilderBase
|
||||||
|
{
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string
|
||||||
|
{
|
||||||
|
$libs = [$this];
|
||||||
|
if ($recursive) {
|
||||||
|
array_unshift($libs, ...array_values($this->getDependencies(recursive: true)));
|
||||||
|
}
|
||||||
|
|
||||||
|
$sep = match ($style) {
|
||||||
|
'autoconf' => ' ',
|
||||||
|
'cmake' => ';',
|
||||||
|
default => throw new RuntimeException('style only support autoconf and cmake'),
|
||||||
|
};
|
||||||
|
$ret = [];
|
||||||
|
foreach ($libs as $lib) {
|
||||||
|
$libFiles = [];
|
||||||
|
foreach ($lib->getStaticLibs() as $name) {
|
||||||
|
$name = str_replace(' ', '\ ', FileSystem::convertPath(BUILD_LIB_PATH . "/{$name}"));
|
||||||
|
$name = str_replace('"', '\"', $name);
|
||||||
|
$libFiles[] = $name;
|
||||||
|
}
|
||||||
|
array_unshift($ret, implode($sep, $libFiles));
|
||||||
|
}
|
||||||
|
return implode($sep, $ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a nmake wrapper file.
|
||||||
|
*
|
||||||
|
* @param string $content nmake wrapper content
|
||||||
|
* @param string $default_filename default nmake wrapper filename
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function makeNmakeWrapper(string $content, string $default_filename = ''): string
|
||||||
|
{
|
||||||
|
if ($default_filename === '') {
|
||||||
|
$default_filename = $this->source_dir . '\nmake_wrapper.bat';
|
||||||
|
}
|
||||||
|
FileSystem::writeFile($default_filename, $content);
|
||||||
|
return 'nmake_wrapper.bat';
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/SPC/builder/windows/library/curl.php
Normal file
24
src/SPC/builder/windows/library/curl.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class curl extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'curl';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
cmd()->cd($this->source_dir . '\winbuild')
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('nmake'),
|
||||||
|
'/f Makefile.vc WITH_DEVEL=' . BUILD_ROOT_PATH . ' ' .
|
||||||
|
'WITH_PREFIX=' . BUILD_ROOT_PATH . ' ' .
|
||||||
|
'mode=static RTLIBCFG=static WITH_SSL=static WITH_NGHTTP2=static WITH_SSH2=static ENABLE_IPV6=yes WITH_ZLIB=static MACHINE=x64 DEBUG=no'
|
||||||
|
);
|
||||||
|
FileSystem::copyDir($this->source_dir . '\include\curl', BUILD_INCLUDE_PATH . '\curl');
|
||||||
|
}
|
||||||
|
}
|
||||||
46
src/SPC/builder/windows/library/libffi_win.php
Normal file
46
src/SPC/builder/windows/library/libffi_win.php
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\builder\windows\SystemUtil;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class libffi_win extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'libffi-win';
|
||||||
|
|
||||||
|
protected function build()
|
||||||
|
{
|
||||||
|
$vs_ver_dir = match (SystemUtil::findVisualStudio()['version']) {
|
||||||
|
'vs17' => '/win32/vs17_x64',
|
||||||
|
'vs16' => '/win32/vs16_x64',
|
||||||
|
default => throw new RuntimeException('Current VS version is not supported yet!'),
|
||||||
|
};
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir . $vs_ver_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('msbuild'),
|
||||||
|
'libffi-msvc.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'
|
||||||
|
);
|
||||||
|
FileSystem::createDir(BUILD_LIB_PATH);
|
||||||
|
FileSystem::createDir(BUILD_INCLUDE_PATH);
|
||||||
|
copy($this->source_dir . $vs_ver_dir . '\x64\Release\libffi.lib', BUILD_LIB_PATH . '\libffi.lib');
|
||||||
|
copy($this->source_dir . $vs_ver_dir . '\x64\Release\libffi.pdb', BUILD_LIB_PATH . '\libffi.pdb');
|
||||||
|
copy($this->source_dir . '\include\ffi.h', BUILD_INCLUDE_PATH . '\ffi.h');
|
||||||
|
|
||||||
|
FileSystem::replaceFileStr(BUILD_INCLUDE_PATH . '\ffi.h', '#define LIBFFI_H', "#define LIBFFI_H\n#define FFI_BUILDING");
|
||||||
|
copy($this->source_dir . '\src\x86\ffitarget.h', BUILD_INCLUDE_PATH . '\ffitarget.h');
|
||||||
|
copy($this->source_dir . '\fficonfig.h', BUILD_INCLUDE_PATH . '\fficonfig.h');
|
||||||
|
|
||||||
|
// copy($this->source_dir . '\msvc_build\out\static-Release\X64\libffi.lib', BUILD_LIB_PATH . '\libffi.lib');
|
||||||
|
// copy($this->source_dir . '\msvc_build\include\ffi.h', BUILD_INCLUDE_PATH . '\ffi.h');
|
||||||
|
// copy($this->source_dir . '\msvc_build\include\fficonfig.h', BUILD_INCLUDE_PATH . '\fficonfig.h');
|
||||||
|
// copy($this->source_dir . '\src\x86\ffitarget.h', BUILD_INCLUDE_PATH . '\ffitarget.h');
|
||||||
|
|
||||||
|
// FileSystem::replaceFileStr(BUILD_INCLUDE_PATH . '\ffi.h', '..\..\src\x86\ffitarget.h', 'ffitarget.h');
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/SPC/builder/windows/library/libiconv_win.php
Normal file
35
src/SPC/builder/windows/library/libiconv_win.php
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\builder\windows\SystemUtil;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class libiconv_win extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'libiconv-win';
|
||||||
|
|
||||||
|
protected function build()
|
||||||
|
{
|
||||||
|
$vs_ver_dir = match (SystemUtil::findVisualStudio()['version']) {
|
||||||
|
'vs17' => '/MSVC17',
|
||||||
|
'vs16' => '/MSVC16',
|
||||||
|
default => throw new RuntimeException('Current VS version is not supported yet!'),
|
||||||
|
};
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir . $vs_ver_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('msbuild'),
|
||||||
|
'libiconv.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'
|
||||||
|
);
|
||||||
|
FileSystem::createDir(BUILD_LIB_PATH);
|
||||||
|
FileSystem::createDir(BUILD_INCLUDE_PATH);
|
||||||
|
copy($this->source_dir . $vs_ver_dir . '\x64\lib\libiconv.lib', BUILD_LIB_PATH . '\libiconv.lib');
|
||||||
|
copy($this->source_dir . $vs_ver_dir . '\x64\lib\libiconv_a.lib', BUILD_LIB_PATH . '\libiconv_a.lib');
|
||||||
|
copy($this->source_dir . '\source\include\iconv.h', BUILD_INCLUDE_PATH . '\iconv.h');
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/SPC/builder/windows/library/librabbitmq.php
Normal file
36
src/SPC/builder/windows/library/librabbitmq.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class librabbitmq extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'librabbitmq';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
// reset cmake
|
||||||
|
FileSystem::resetDir($this->source_dir . '\build');
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
'-B build ' .
|
||||||
|
'-A x64 ' .
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
|
'-DBUILD_STATIC_LIBS=ON ' .
|
||||||
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||||
|
)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||||
|
);
|
||||||
|
rename(BUILD_LIB_PATH . '\librabbitmq.4.lib', BUILD_LIB_PATH . '\rabbitmq.4.lib');
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/SPC/builder/windows/library/libssh2.php
Normal file
38
src/SPC/builder/windows/library/libssh2.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class libssh2 extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'libssh2';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
$zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
|
||||||
|
// reset cmake
|
||||||
|
FileSystem::resetDir($this->source_dir . '\build');
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
'-B build ' .
|
||||||
|
'-A x64 ' .
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
|
'-DBUILD_STATIC_LIBS=ON ' .
|
||||||
|
'-DBUILD_TESTING=OFF ' .
|
||||||
|
"-DENABLE_ZLIB_COMPRESSION={$zlib} " .
|
||||||
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||||
|
)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/SPC/builder/windows/library/libxml2.php
Normal file
44
src/SPC/builder/windows/library/libxml2.php
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class libxml2 extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'libxml2';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
$zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
|
||||||
|
// reset cmake
|
||||||
|
FileSystem::resetDir($this->source_dir . '\build');
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
'-B build ' .
|
||||||
|
'-A x64 ' .
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
|
'-DBUILD_STATIC_LIBS=ON ' .
|
||||||
|
"-DLIBXML2_WITH_ZLIB={$zlib} " .
|
||||||
|
'-DLIBXML2_WITH_PYTHON=OFF ' .
|
||||||
|
'-DLIBXML2_WITH_ICONV=ON ' .
|
||||||
|
'-DIconv_LIBRARY=' . BUILD_LIB_PATH . ' ' .
|
||||||
|
'-DIconv_INCLUDE_DIR=' . BUILD_INCLUDE_PATH . ' ' .
|
||||||
|
'-DLIBXML2_WITH_LZMA=OFF ' . // xz not supported yet
|
||||||
|
'-DLIBXML2_WITH_PROGRAMS=OFF ' .
|
||||||
|
'-DLIBXML2_WITH_TESTS=OFF ' .
|
||||||
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||||
|
)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||||
|
);
|
||||||
|
copy(BUILD_LIB_PATH . '\libxml2s.lib', BUILD_LIB_PATH . '\libxml2_a.lib');
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/SPC/builder/windows/library/nghttp2.php
Normal file
37
src/SPC/builder/windows/library/nghttp2.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class nghttp2 extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'nghttp2';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
// reset cmake
|
||||||
|
FileSystem::resetDir($this->source_dir . '\build');
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
'-B build ' .
|
||||||
|
'-A x64 ' .
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
|
'-DENABLE_SHARED_LIB=OFF ' .
|
||||||
|
'-DENABLE_STATIC_LIB=ON ' .
|
||||||
|
'-DENABLE_STATIC_CRT=ON ' .
|
||||||
|
'-DENABLE_LIB_ONLY=ON ' .
|
||||||
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||||
|
)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
src/SPC/builder/windows/library/onig.php
Normal file
37
src/SPC/builder/windows/library/onig.php
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class onig extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'onig';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
// reset cmake
|
||||||
|
FileSystem::resetDir($this->source_dir . '\build');
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
'-B build ' .
|
||||||
|
'-A x64 ' .
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
|
'-DBUILD_STATIC_LIBS=ON ' .
|
||||||
|
'-DMSVC_STATIC_RUNTIME=ON ' .
|
||||||
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||||
|
)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||||
|
);
|
||||||
|
copy(BUILD_LIB_PATH . '/onig.lib', BUILD_LIB_PATH . '/onig_a.lib');
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/SPC/builder/windows/library/openssl.php
Normal file
45
src/SPC/builder/windows/library/openssl.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\builder\windows\SystemUtil;
|
||||||
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class openssl extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'openssl';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
$perl_path_native = PKG_ROOT_PATH . '\strawberry-perl-' . arch2gnu(php_uname('m')) . '-win\perl\bin\perl.exe';
|
||||||
|
$perl = file_exists($perl_path_native) ? ($perl_path_native) : SystemUtil::findCommand('perl.exe');
|
||||||
|
if ($perl === null) {
|
||||||
|
throw new RuntimeException('You need to install perl first! (easiest way is using static-php-cli command "doctor")');
|
||||||
|
}
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper($perl),
|
||||||
|
'Configure zlib VC-WIN64A ' .
|
||||||
|
'no-shared ' .
|
||||||
|
'--prefix=' . quote(BUILD_ROOT_PATH) . ' ' .
|
||||||
|
'--with-zlib-lib=' . quote(BUILD_LIB_PATH) . ' ' .
|
||||||
|
'--with-zlib-include=' . quote(BUILD_INCLUDE_PATH) . ' ' .
|
||||||
|
'--release ' .
|
||||||
|
'no-legacy '
|
||||||
|
);
|
||||||
|
|
||||||
|
// patch zlib
|
||||||
|
FileSystem::replaceFileStr($this->source_dir . '\Makefile', 'ZLIB1', 'zlibstatic.lib');
|
||||||
|
// patch debug: https://stackoverflow.com/questions/18486243/how-do-i-build-openssl-statically-linked-against-windows-runtime
|
||||||
|
FileSystem::replaceFileStr($this->source_dir . '\Makefile', '/debug', '/incremental:no /opt:icf /dynamicbase /nxcompat /ltcg /nodefaultlib:msvcrt');
|
||||||
|
cmd()->cd($this->source_dir)->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('nmake'),
|
||||||
|
'install_dev ' .
|
||||||
|
'CNF_LDFLAGS="/NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:msvcrt /NODEFAULTLIB:msvcrtd /DEFAULTLIB:libcmt /LIBPATH:' . BUILD_LIB_PATH . ' zlibstatic.lib"'
|
||||||
|
);
|
||||||
|
copy($this->source_dir . '\ms\applink.c', BUILD_INCLUDE_PATH . '\openssl\applink.c');
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/SPC/builder/windows/library/qdbm.php
Normal file
24
src/SPC/builder/windows/library/qdbm.php
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class qdbm extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'qdbm';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('nmake'),
|
||||||
|
'/f VCMakefile'
|
||||||
|
);
|
||||||
|
copy($this->source_dir . '\qdbm_a.lib', BUILD_LIB_PATH . '\qdbm_a.lib');
|
||||||
|
copy($this->source_dir . '\depot.h', BUILD_INCLUDE_PATH . '\depot.h');
|
||||||
|
// FileSystem::copyDir($this->source_dir . '\include\curl', BUILD_INCLUDE_PATH . '\curl');
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/SPC/builder/windows/library/sqlite.php
Normal file
21
src/SPC/builder/windows/library/sqlite.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
class sqlite extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'sqlite';
|
||||||
|
|
||||||
|
public function patchBeforeBuild(): bool
|
||||||
|
{
|
||||||
|
copy(ROOT_DIR . '/src/globals/extra/Makefile-sqlite', $this->source_dir . '/Makefile');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
cmd()->cd($this->source_dir)->execWithWrapper($this->builder->makeSimpleWrapper('nmake'), 'PREFIX=' . BUILD_ROOT_PATH . ' install-static');
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/SPC/builder/windows/library/zlib.php
Normal file
38
src/SPC/builder/windows/library/zlib.php
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\windows\library;
|
||||||
|
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
|
||||||
|
class zlib extends WindowsLibraryBase
|
||||||
|
{
|
||||||
|
public const NAME = 'zlib';
|
||||||
|
|
||||||
|
protected function build(): void
|
||||||
|
{
|
||||||
|
// reset cmake
|
||||||
|
FileSystem::resetDir($this->source_dir . '\build');
|
||||||
|
|
||||||
|
// start build
|
||||||
|
cmd()->cd($this->source_dir)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
'-B build ' .
|
||||||
|
'-A x64 ' .
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||||
|
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||||
|
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||||
|
'-DSKIP_INSTALL_FILES=ON ' .
|
||||||
|
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||||
|
)
|
||||||
|
->execWithWrapper(
|
||||||
|
$this->builder->makeSimpleWrapper('cmake'),
|
||||||
|
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||||
|
);
|
||||||
|
copy(BUILD_LIB_PATH . '\zlibstatic.lib', BUILD_LIB_PATH . '\zlib_a.lib');
|
||||||
|
unlink(BUILD_ROOT_PATH . '\bin\zlib.dll');
|
||||||
|
unlink(BUILD_LIB_PATH . '\zlib.lib');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@ abstract class BaseCommand extends Command
|
|||||||
|
|
||||||
protected OutputInterface $output;
|
protected OutputInterface $output;
|
||||||
|
|
||||||
public function __construct(string $name = null)
|
public function __construct(?string $name = null)
|
||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
$this->addOption('debug', null, null, 'Enable debug mode');
|
$this->addOption('debug', null, null, 'Enable debug mode');
|
||||||
@@ -56,11 +56,6 @@ abstract class BaseCommand extends Command
|
|||||||
// 如果 return false 则错误会继续递交给 PHP 标准错误处理
|
// 如果 return false 则错误会继续递交给 PHP 标准错误处理
|
||||||
return true;
|
return true;
|
||||||
}, E_ALL | E_STRICT);
|
}, E_ALL | E_STRICT);
|
||||||
if ($input->getOption('debug')) {
|
|
||||||
global $ob_logger;
|
|
||||||
$ob_logger = new ConsoleLogger(LogLevel::DEBUG);
|
|
||||||
define('DEBUG_MODE', true);
|
|
||||||
}
|
|
||||||
$version = ConsoleApplication::VERSION;
|
$version = ConsoleApplication::VERSION;
|
||||||
if (!$this->no_motd) {
|
if (!$this->no_motd) {
|
||||||
echo " _ _ _ _
|
echo " _ _ _ _
|
||||||
@@ -83,6 +78,14 @@ abstract class BaseCommand extends Command
|
|||||||
$this->input = $input;
|
$this->input = $input;
|
||||||
$this->output = $output;
|
$this->output = $output;
|
||||||
|
|
||||||
|
global $ob_logger;
|
||||||
|
if ($input->getOption('debug')) {
|
||||||
|
$ob_logger = new ConsoleLogger(LogLevel::DEBUG, decorated: !$input->getOption('no-ansi'));
|
||||||
|
define('DEBUG_MODE', true);
|
||||||
|
} else {
|
||||||
|
$ob_logger = new ConsoleLogger(decorated: !$input->getOption('no-ansi'));
|
||||||
|
}
|
||||||
|
|
||||||
// windows fallback
|
// windows fallback
|
||||||
Prompt::fallbackWhen(PHP_OS_FAMILY === 'Windows');
|
Prompt::fallbackWhen(PHP_OS_FAMILY === 'Windows');
|
||||||
ConfirmPrompt::fallbackUsing(function (ConfirmPrompt $prompt) use ($input, $output) {
|
ConfirmPrompt::fallbackUsing(function (ConfirmPrompt $prompt) use ($input, $output) {
|
||||||
|
|||||||
@@ -23,18 +23,22 @@ class BuildCliCommand extends BuildCommand
|
|||||||
{
|
{
|
||||||
$this->addArgument('extensions', InputArgument::REQUIRED, 'The extensions will be compiled, comma separated');
|
$this->addArgument('extensions', InputArgument::REQUIRED, 'The extensions will be compiled, comma separated');
|
||||||
$this->addOption('with-libs', null, InputOption::VALUE_REQUIRED, 'add additional libraries, comma separated', '');
|
$this->addOption('with-libs', null, InputOption::VALUE_REQUIRED, 'add additional libraries, comma separated', '');
|
||||||
$this->addOption('build-micro', null, null, 'build micro');
|
$this->addOption('build-micro', null, null, 'Build micro SAPI');
|
||||||
$this->addOption('build-cli', null, null, 'build cli');
|
$this->addOption('build-cli', null, null, 'Build cli SAPI');
|
||||||
$this->addOption('build-fpm', null, null, 'build fpm');
|
$this->addOption('build-fpm', null, null, 'Build fpm SAPI');
|
||||||
$this->addOption('build-embed', null, null, 'build embed');
|
$this->addOption('build-embed', null, null, 'Build embed SAPI');
|
||||||
$this->addOption('build-all', null, null, 'build cli, micro, fpm, embed');
|
$this->addOption('build-all', null, null, 'Build all SAPI');
|
||||||
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
|
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
|
||||||
$this->addOption('enable-zts', null, null, 'enable ZTS support');
|
$this->addOption('enable-zts', null, null, 'enable ZTS support');
|
||||||
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');
|
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');
|
||||||
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
|
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
|
||||||
$this->addOption('with-micro-fake-cli', null, null, 'Enable phpmicro fake cli');
|
$this->addOption('with-micro-fake-cli', null, null, 'Let phpmicro\'s PHP_SAPI use "cli" instead of "micro"');
|
||||||
$this->addOption('with-suggested-libs', 'L', null, 'Build with suggested libs for selected exts and libs');
|
$this->addOption('with-suggested-libs', 'L', null, 'Build with suggested libs for selected exts and libs');
|
||||||
$this->addOption('with-suggested-exts', 'E', null, 'Build with suggested extensions for selected exts');
|
$this->addOption('with-suggested-exts', 'E', null, 'Build with suggested extensions for selected exts');
|
||||||
|
$this->addOption('with-added-patch', 'P', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Inject patch script outside');
|
||||||
|
$this->addOption('without-micro-ext-test', null, null, 'Disable phpmicro with extension test code');
|
||||||
|
$this->addOption('with-upx-pack', null, null, 'Compress / pack binary using UPX tool (linux/windows only)');
|
||||||
|
$this->addOption('with-micro-logo', null, InputOption::VALUE_REQUIRED, 'Use custom .ico for micro.sfx (windows only)');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
@@ -56,30 +60,79 @@ class BuildCliCommand extends BuildCommand
|
|||||||
$this->output->writeln("<comment>\t--build-all\tBuild all SAPI: cli, micro, fpm, embed</comment>");
|
$this->output->writeln("<comment>\t--build-all\tBuild all SAPI: cli, micro, fpm, embed</comment>");
|
||||||
return static::FAILURE;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
|
if ($rule === BUILD_TARGET_ALL) {
|
||||||
|
logger()->warning('--build-all option makes `--no-strip` always true, be aware!');
|
||||||
|
}
|
||||||
|
if (($rule & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO && $this->getOption('with-micro-logo')) {
|
||||||
|
$logo = $this->getOption('with-micro-logo');
|
||||||
|
if (!file_exists($logo)) {
|
||||||
|
logger()->error('Logo file ' . $logo . ' not exist !');
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check upx
|
||||||
|
$suffix = PHP_OS_FAMILY === 'Windows' ? '.exe' : '';
|
||||||
|
if ($this->getOption('with-upx-pack')) {
|
||||||
|
// only available for linux for now
|
||||||
|
if (!in_array(PHP_OS_FAMILY, ['Linux', 'Windows'])) {
|
||||||
|
logger()->error('UPX is only available on Linux and Windows!');
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
// need to install this manually
|
||||||
|
if (!file_exists(PKG_ROOT_PATH . '/bin/upx' . $suffix)) {
|
||||||
|
global $argv;
|
||||||
|
logger()->error('upx does not exist, please install it first:');
|
||||||
|
logger()->error('');
|
||||||
|
logger()->error("\t" . $argv[0] . ' install-pkg upx');
|
||||||
|
logger()->error('');
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
// exclusive with no-strip
|
||||||
|
if ($this->getOption('no-strip')) {
|
||||||
|
logger()->warning('--with-upx-pack conflicts with --no-strip, --no-strip won\'t work!');
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// create builder
|
// create builder
|
||||||
$builder = BuilderProvider::makeBuilderByInput($this->input);
|
$builder = BuilderProvider::makeBuilderByInput($this->input);
|
||||||
// calculate dependencies
|
$include_suggest_ext = $this->getOption('with-suggested-exts');
|
||||||
[$extensions, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps($extensions, $libraries);
|
$include_suggest_lib = $this->getOption('with-suggested-libs');
|
||||||
|
[$extensions, $libraries, $not_included] = DependencyUtil::getExtsAndLibs($extensions, $libraries, $include_suggest_ext, $include_suggest_lib);
|
||||||
|
|
||||||
// print info
|
// print info
|
||||||
$indent_texts = [
|
$indent_texts = [
|
||||||
'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')',
|
'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')',
|
||||||
'Build SAPI' => $builder->getBuildTypeName($rule),
|
'Build SAPI' => $builder->getBuildTypeName($rule),
|
||||||
'Extensions (' . count($extensions) . ')' => implode(', ', $extensions),
|
'Extensions (' . count($extensions) . ')' => implode(',', $extensions),
|
||||||
'Libraries (' . count($libraries) . ')' => implode(', ', $libraries),
|
'Libraries (' . count($libraries) . ')' => implode(',', $libraries),
|
||||||
'Strip Binaries' => $builder->getOption('no-strip') ? 'no' : 'yes',
|
'Strip Binaries' => $builder->getOption('no-strip') ? 'no' : 'yes',
|
||||||
'Enable ZTS' => $builder->getOption('enable-zts') ? 'yes' : 'no',
|
'Enable ZTS' => $builder->getOption('enable-zts') ? 'yes' : 'no',
|
||||||
];
|
];
|
||||||
if (!empty($this->input->getOption('with-hardcoded-ini'))) {
|
if (!empty($this->input->getOption('with-hardcoded-ini'))) {
|
||||||
$indent_texts['Hardcoded INI'] = $this->input->getOption('with-hardcoded-ini');
|
$indent_texts['Hardcoded INI'] = $this->input->getOption('with-hardcoded-ini');
|
||||||
}
|
}
|
||||||
$this->printFormatInfo($indent_texts);
|
if ($this->input->getOption('disable-opcache-jit')) {
|
||||||
|
$indent_texts['Opcache JIT'] = 'disabled';
|
||||||
|
}
|
||||||
|
if ($this->input->getOption('with-upx-pack') && in_array(PHP_OS_FAMILY, ['Linux', 'Windows'])) {
|
||||||
|
$indent_texts['UPX Pack'] = 'enabled';
|
||||||
|
$builder->setOption('upx-exec', FileSystem::convertPath(PKG_ROOT_PATH . '/bin/upx' . $suffix));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$ver = $builder->getPHPVersion();
|
||||||
|
$indent_texts['PHP Version'] = $ver;
|
||||||
|
} catch (\Throwable) {
|
||||||
|
if (($ver = $builder->getPHPVersionFromArchive()) !== false) {
|
||||||
|
$indent_texts['PHP Version'] = $ver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($not_included)) {
|
if (!empty($not_included)) {
|
||||||
logger()->warning('Some extensions will be enabled due to dependencies: ' . implode(',', $not_included));
|
$indent_texts['Extra Exts (' . count($not_included) . ')'] = implode(', ', $not_included);
|
||||||
}
|
}
|
||||||
logger()->info('Build will start after 2s ...');
|
$this->printFormatInfo($indent_texts);
|
||||||
|
logger()->notice('Build will start after 2s ...');
|
||||||
sleep(2);
|
sleep(2);
|
||||||
|
|
||||||
if ($this->input->getOption('with-clean')) {
|
if ($this->input->getOption('with-clean')) {
|
||||||
@@ -102,6 +155,9 @@ class BuildCliCommand extends BuildCommand
|
|||||||
SourcePatcher::patchHardcodedINI($custom_ini);
|
SourcePatcher::patchHardcodedINI($custom_ini);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add static-php-cli.version to main.c, in order to debug php failure more easily
|
||||||
|
SourcePatcher::patchSPCVersionToPHP($this->getApplication()->getVersion());
|
||||||
|
|
||||||
// start to build
|
// start to build
|
||||||
$builder->buildPHP($rule);
|
$builder->buildPHP($rule);
|
||||||
|
|
||||||
@@ -119,13 +175,17 @@ class BuildCliCommand extends BuildCommand
|
|||||||
$fixed = ' (host system)';
|
$fixed = ' (host system)';
|
||||||
}
|
}
|
||||||
if (($rule & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
if (($rule & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||||
logger()->info('Static php binary path' . $fixed . ': ' . $build_root_path . '/bin/php');
|
$win_suffix = PHP_OS_FAMILY === 'Windows' ? '.exe' : '';
|
||||||
|
$path = FileSystem::convertPath("{$build_root_path}/bin/php{$win_suffix}");
|
||||||
|
logger()->info("Static php binary path{$fixed}: {$path}");
|
||||||
}
|
}
|
||||||
if (($rule & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
if (($rule & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||||
logger()->info('phpmicro binary path' . $fixed . ': ' . $build_root_path . '/bin/micro.sfx');
|
$path = FileSystem::convertPath("{$build_root_path}/bin/micro.sfx");
|
||||||
|
logger()->info("phpmicro binary path{$fixed}: {$path}");
|
||||||
}
|
}
|
||||||
if (($rule & BUILD_TARGET_FPM) === BUILD_TARGET_FPM) {
|
if (($rule & BUILD_TARGET_FPM) === BUILD_TARGET_FPM && PHP_OS_FAMILY !== 'Windows') {
|
||||||
logger()->info('Static php-fpm binary path' . $fixed . ': ' . $build_root_path . '/bin/php-fpm');
|
$path = FileSystem::convertPath("{$build_root_path}/bin/php-fpm");
|
||||||
|
logger()->info("Static php-fpm binary path{$fixed}: {$path}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// export metadata
|
// export metadata
|
||||||
@@ -134,7 +194,8 @@ class BuildCliCommand extends BuildCommand
|
|||||||
// export licenses
|
// export licenses
|
||||||
$dumper = new LicenseDumper();
|
$dumper = new LicenseDumper();
|
||||||
$dumper->addExts($extensions)->addLibs($libraries)->addSources(['php-src'])->dump(BUILD_ROOT_PATH . '/license');
|
$dumper->addExts($extensions)->addLibs($libraries)->addSources(['php-src'])->dump(BUILD_ROOT_PATH . '/license');
|
||||||
logger()->info('License path' . $fixed . ': ' . $build_root_path . '/license/');
|
$path = FileSystem::convertPath("{$build_root_path}/license/");
|
||||||
|
logger()->info("License path{$fixed}: {$path}");
|
||||||
return static::SUCCESS;
|
return static::SUCCESS;
|
||||||
} catch (WrongUsageException $e) {
|
} catch (WrongUsageException $e) {
|
||||||
// WrongUsageException is not an exception, it's a user error, so we just print the error message
|
// WrongUsageException is not an exception, it's a user error, so we just print the error message
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use Symfony\Component\Console\Input\InputOption;
|
|||||||
|
|
||||||
abstract class BuildCommand extends BaseCommand
|
abstract class BuildCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
public function __construct(string $name = null)
|
public function __construct(?string $name = null)
|
||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class BuildLibsCommand extends BuildCommand
|
|||||||
// 只编译 library 的情况下,标记
|
// 只编译 library 的情况下,标记
|
||||||
$builder->setLibsOnly();
|
$builder->setLibsOnly();
|
||||||
// 编译和检查库完整
|
// 编译和检查库完整
|
||||||
$libraries = DependencyUtil::getLibsByDeps($libraries);
|
$libraries = DependencyUtil::getLibs($libraries);
|
||||||
$builder->buildLibs($libraries);
|
$builder->buildLibs($libraries);
|
||||||
|
|
||||||
$time = round(microtime(true) - START_TIME, 3);
|
$time = round(microtime(true) - START_TIME, 3);
|
||||||
|
|||||||
86
src/SPC/command/DeleteDownloadCommand.php
Normal file
86
src/SPC/command/DeleteDownloadCommand.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command;
|
||||||
|
|
||||||
|
use SPC\exception\DownloaderException;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\FileSystem;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
#[AsCommand('del-download', 'Remove locked download source or package using name', ['delete-download', 'del-down'])]
|
||||||
|
class DeleteDownloadCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
public function configure(): void
|
||||||
|
{
|
||||||
|
$this->addArgument('sources', InputArgument::REQUIRED, 'The sources/packages will be deleted, comma separated');
|
||||||
|
$this->addOption('all', 'A', null, 'Delete all downloaded and locked sources/packages');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
|
{
|
||||||
|
if ($input->getOption('all')) {
|
||||||
|
$input->setArgument('sources', '');
|
||||||
|
}
|
||||||
|
parent::initialize($input, $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// get source list that will be downloaded
|
||||||
|
$sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
|
||||||
|
if (empty($sources)) {
|
||||||
|
logger()->notice('Removing downloads/ directory ...');
|
||||||
|
FileSystem::removeDir(DOWNLOAD_PATH);
|
||||||
|
logger()->info('Removed downloads/ dir!');
|
||||||
|
return static::SUCCESS;
|
||||||
|
}
|
||||||
|
$chosen_sources = $sources;
|
||||||
|
$lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? [];
|
||||||
|
|
||||||
|
foreach ($chosen_sources as $source) {
|
||||||
|
$source = trim($source);
|
||||||
|
if (!isset($lock[$source])) {
|
||||||
|
logger()->warning("Source/Package [{$source}] not locked or not downloaded, skipped.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// remove download file/dir if exists
|
||||||
|
if ($lock[$source]['source_type'] === 'archive') {
|
||||||
|
if (file_exists($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$source]['filename']))) {
|
||||||
|
logger()->info('Deleting file ' . $path);
|
||||||
|
unlink($path);
|
||||||
|
} else {
|
||||||
|
logger()->warning("Source/Package [{$source}] file not found, skip deleting file.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (is_dir($path = FileSystem::convertPath(DOWNLOAD_PATH . '/' . $lock[$source]['dirname']))) {
|
||||||
|
logger()->info('Deleting dir ' . $path);
|
||||||
|
FileSystem::removeDir($path);
|
||||||
|
} else {
|
||||||
|
logger()->warning("Source/Package [{$source}] directory not found, skip deleting dir.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove locked sources
|
||||||
|
unset($lock[$source]);
|
||||||
|
}
|
||||||
|
FileSystem::writeFile(DOWNLOAD_PATH . '/.lock.json', json_encode($lock, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
|
||||||
|
logger()->info('Delete success!');
|
||||||
|
return static::SUCCESS;
|
||||||
|
} catch (DownloaderException $e) {
|
||||||
|
logger()->error($e->getMessage());
|
||||||
|
return static::FAILURE;
|
||||||
|
} catch (WrongUsageException $e) {
|
||||||
|
logger()->critical($e->getMessage());
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,26 +36,61 @@ class DownloadCommand extends BaseCommand
|
|||||||
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');
|
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');
|
||||||
$this->addOption('from-zip', 'Z', InputOption::VALUE_REQUIRED, 'Fetch from zip archive');
|
$this->addOption('from-zip', 'Z', InputOption::VALUE_REQUIRED, 'Fetch from zip archive');
|
||||||
$this->addOption('for-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"');
|
$this->addOption('for-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"');
|
||||||
|
$this->addOption('for-libs', 'l', InputOption::VALUE_REQUIRED, 'Fetch by libraries, e.g "libcares,openssl,onig"');
|
||||||
$this->addOption('without-suggestions', null, null, 'Do not fetch suggested sources when using --for-extensions');
|
$this->addOption('without-suggestions', null, null, 'Do not fetch suggested sources when using --for-extensions');
|
||||||
|
$this->addOption('ignore-cache-sources', null, InputOption::VALUE_REQUIRED, 'Ignore some source caches, comma separated, e.g "php-src,curl,openssl"', '');
|
||||||
|
$this->addOption('retry', 'R', InputOption::VALUE_REQUIRED, 'Set retry time when downloading failed (default: 0)', '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
public function initialize(InputInterface $input, OutputInterface $output): void
|
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
{
|
{
|
||||||
if (
|
// mode: --all
|
||||||
$input->getOption('all')
|
if ($input->getOption('all')) {
|
||||||
|| $input->getOption('clean')
|
$input->setArgument('sources', implode(',', array_keys(Config::getSources())));
|
||||||
|| $input->getOption('from-zip')
|
parent::initialize($input, $output);
|
||||||
|| $input->getOption('for-extensions')
|
return;
|
||||||
) {
|
}
|
||||||
|
// mode: --clean and --from-zip
|
||||||
|
if ($input->getOption('clean') || $input->getOption('from-zip')) {
|
||||||
$input->setArgument('sources', '');
|
$input->setArgument('sources', '');
|
||||||
|
parent::initialize($input, $output);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// mode: normal
|
||||||
|
if (!empty($input->getArgument('sources'))) {
|
||||||
|
$final_sources = array_map('trim', array_filter(explode(',', $input->getArgument('sources'))));
|
||||||
|
} else {
|
||||||
|
$final_sources = [];
|
||||||
|
}
|
||||||
|
// mode: --for-extensions
|
||||||
|
if ($for_ext = $input->getOption('for-extensions')) {
|
||||||
|
$ext = array_map('trim', array_filter(explode(',', $for_ext)));
|
||||||
|
$sources = $this->calculateSourcesByExt($ext, !$input->getOption('without-suggestions'));
|
||||||
|
if (PHP_OS_FAMILY !== 'Windows') {
|
||||||
|
array_unshift($sources, 'pkg-config');
|
||||||
|
}
|
||||||
|
array_unshift($sources, 'php-src', 'micro');
|
||||||
|
$final_sources = array_merge($final_sources, array_diff($sources, $final_sources));
|
||||||
|
}
|
||||||
|
// mode: --for-libs
|
||||||
|
if ($for_lib = $input->getOption('for-libs')) {
|
||||||
|
$lib = array_map('trim', array_filter(explode(',', $for_lib)));
|
||||||
|
$sources = $this->calculateSourcesByLib($lib, !$input->getOption('without-suggestions'));
|
||||||
|
$final_sources = array_merge($final_sources, array_diff($sources, $final_sources));
|
||||||
|
}
|
||||||
|
if (!empty($final_sources)) {
|
||||||
|
$input->setArgument('sources', implode(',', $final_sources));
|
||||||
}
|
}
|
||||||
parent::initialize($input, $output);
|
parent::initialize($input, $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws DownloaderException
|
|
||||||
* @throws RuntimeException
|
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
@@ -93,6 +128,10 @@ class DownloadCommand extends BaseCommand
|
|||||||
return static::FAILURE;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// retry
|
||||||
|
$retry = intval($this->getOption('retry'));
|
||||||
|
f_putenv('SPC_RETRY_TIME=' . $retry);
|
||||||
|
|
||||||
// Use shallow-clone can reduce git resource download
|
// Use shallow-clone can reduce git resource download
|
||||||
if ($this->getOption('shallow-clone')) {
|
if ($this->getOption('shallow-clone')) {
|
||||||
define('GIT_SHALLOW_CLONE', true);
|
define('GIT_SHALLOW_CLONE', true);
|
||||||
@@ -107,19 +146,12 @@ class DownloadCommand extends BaseCommand
|
|||||||
Config::$source['openssl']['regex'] = '/href="(?<file>openssl-(?<version>1.[^"]+)\.tar\.gz)\"/';
|
Config::$source['openssl']['regex'] = '/href="(?<file>openssl-(?<version>1.[^"]+)\.tar\.gz)\"/';
|
||||||
}
|
}
|
||||||
|
|
||||||
// --for-extensions
|
$chosen_sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
|
||||||
if ($for_ext = $this->getOption('for-extensions')) {
|
$force_list = array_map('trim', array_filter(explode(',', $this->getOption('ignore-cache-sources'))));
|
||||||
$ext = array_map('trim', array_filter(explode(',', $for_ext)));
|
|
||||||
$sources = $this->calculateSourcesByExt($ext, !$this->getOption('without-suggestions'));
|
if ($this->getOption('all')) {
|
||||||
array_unshift($sources, 'php-src', 'micro', 'pkg-config');
|
logger()->notice('Downloading with --all option will take more times to download, we recommend you to download with --for-extensions option !');
|
||||||
} else {
|
|
||||||
// get source list that will be downloaded
|
|
||||||
$sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
|
|
||||||
if (empty($sources)) {
|
|
||||||
$sources = array_keys(Config::getSources());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$chosen_sources = $sources;
|
|
||||||
|
|
||||||
// Process -U options
|
// Process -U options
|
||||||
$custom_urls = [];
|
$custom_urls = [];
|
||||||
@@ -150,7 +182,7 @@ class DownloadCommand extends BaseCommand
|
|||||||
Downloader::downloadSource($source, $new_config, true);
|
Downloader::downloadSource($source, $new_config, true);
|
||||||
} else {
|
} else {
|
||||||
logger()->info("Fetching source {$source} [{$ni}/{$cnt}]");
|
logger()->info("Fetching source {$source} [{$ni}/{$cnt}]");
|
||||||
Downloader::downloadSource($source, Config::getSource($source));
|
Downloader::downloadSource($source, Config::getSource($source), in_array($source, $force_list));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$time = round(microtime(true) - START_TIME, 3);
|
$time = round(microtime(true) - START_TIME, 3);
|
||||||
@@ -165,6 +197,10 @@ class DownloadCommand extends BaseCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws RuntimeException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
private function downloadFromZip(string $path): int
|
private function downloadFromZip(string $path): int
|
||||||
{
|
{
|
||||||
if (!file_exists($path)) {
|
if (!file_exists($path)) {
|
||||||
@@ -188,9 +224,12 @@ class DownloadCommand extends BaseCommand
|
|||||||
// create downloads
|
// create downloads
|
||||||
try {
|
try {
|
||||||
if (PHP_OS_FAMILY !== 'Windows') {
|
if (PHP_OS_FAMILY !== 'Windows') {
|
||||||
f_passthru('mkdir ' . DOWNLOAD_PATH . ' && cd ' . DOWNLOAD_PATH . ' && unzip ' . escapeshellarg($path));
|
$abs_path = realpath($path);
|
||||||
|
f_passthru('mkdir ' . DOWNLOAD_PATH . ' && cd ' . DOWNLOAD_PATH . ' && unzip ' . escapeshellarg($abs_path));
|
||||||
|
} else {
|
||||||
|
// Windows TODO
|
||||||
|
throw new WrongUsageException('Windows currently does not support --from-zip !');
|
||||||
}
|
}
|
||||||
// Windows TODO
|
|
||||||
|
|
||||||
if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) {
|
if (!file_exists(DOWNLOAD_PATH . '/.lock.json')) {
|
||||||
throw new RuntimeException('.lock.json not exist in "downloads/"');
|
throw new RuntimeException('.lock.json not exist in "downloads/"');
|
||||||
@@ -206,13 +245,14 @@ class DownloadCommand extends BaseCommand
|
|||||||
/**
|
/**
|
||||||
* Calculate the sources by extensions
|
* Calculate the sources by extensions
|
||||||
*
|
*
|
||||||
* @param array $extensions extension list
|
* @param array $extensions extension list
|
||||||
|
* @param bool $include_suggests include suggested libs and extensions (default: true)
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
private function calculateSourcesByExt(array $extensions, bool $include_suggests = true): array
|
private function calculateSourcesByExt(array $extensions, bool $include_suggests = true): array
|
||||||
{
|
{
|
||||||
[$extensions, $libraries] = $include_suggests ? DependencyUtil::getAllExtLibsByDeps($extensions) : DependencyUtil::getExtLibsByDeps($extensions);
|
[$extensions, $libraries] = $include_suggests ? DependencyUtil::getExtsAndLibs($extensions, [], true, true) : DependencyUtil::getExtsAndLibs($extensions);
|
||||||
$sources = [];
|
$sources = [];
|
||||||
foreach ($extensions as $extension) {
|
foreach ($extensions as $extension) {
|
||||||
if (Config::getExt($extension, 'type') === 'external') {
|
if (Config::getExt($extension, 'type') === 'external') {
|
||||||
@@ -224,4 +264,22 @@ class DownloadCommand extends BaseCommand
|
|||||||
}
|
}
|
||||||
return array_values(array_unique($sources));
|
return array_values(array_unique($sources));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the sources by libraries
|
||||||
|
*
|
||||||
|
* @param array $libs library list
|
||||||
|
* @param bool $include_suggests include suggested libs (default: true)
|
||||||
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
private function calculateSourcesByLib(array $libs, bool $include_suggests = true): array
|
||||||
|
{
|
||||||
|
$libs = DependencyUtil::getLibs($libs, $include_suggests);
|
||||||
|
$sources = [];
|
||||||
|
foreach ($libs as $library) {
|
||||||
|
$sources[] = Config::getLib($library, 'source');
|
||||||
|
}
|
||||||
|
return array_values(array_unique($sources));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ class DumpLicenseCommand extends BaseCommand
|
|||||||
{
|
{
|
||||||
$this->addOption('for-extensions', null, InputOption::VALUE_REQUIRED, 'Dump by extensions and related libraries', null);
|
$this->addOption('for-extensions', null, InputOption::VALUE_REQUIRED, 'Dump by extensions and related libraries', null);
|
||||||
$this->addOption('without-php', null, InputOption::VALUE_NONE, 'Dump without php-src');
|
$this->addOption('without-php', null, InputOption::VALUE_NONE, 'Dump without php-src');
|
||||||
$this->addOption('by-libs', null, InputOption::VALUE_REQUIRED, 'Dump by libraries', null);
|
$this->addOption('for-libs', null, InputOption::VALUE_REQUIRED, 'Dump by libraries', null);
|
||||||
$this->addOption('by-sources', null, InputOption::VALUE_REQUIRED, 'Dump by original sources (source.json)', null);
|
$this->addOption('for-sources', null, InputOption::VALUE_REQUIRED, 'Dump by original sources (source.json)', null);
|
||||||
$this->addOption('dump-dir', null, InputOption::VALUE_REQUIRED, 'Change dump directory', BUILD_ROOT_PATH . '/license');
|
$this->addOption('dump-dir', null, InputOption::VALUE_REQUIRED, 'Change dump directory', BUILD_ROOT_PATH . '/license');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ class DumpLicenseCommand extends BaseCommand
|
|||||||
// 从参数中获取要编译的 extensions,并转换为数组
|
// 从参数中获取要编译的 extensions,并转换为数组
|
||||||
$extensions = array_map('trim', array_filter(explode(',', $this->getOption('for-extensions'))));
|
$extensions = array_map('trim', array_filter(explode(',', $this->getOption('for-extensions'))));
|
||||||
// 根据提供的扩展列表获取依赖库列表并编译
|
// 根据提供的扩展列表获取依赖库列表并编译
|
||||||
[$extensions, $libraries] = DependencyUtil::getExtLibsByDeps($extensions);
|
[$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions);
|
||||||
$dumper->addExts($extensions);
|
$dumper->addExts($extensions);
|
||||||
$dumper->addLibs($libraries);
|
$dumper->addLibs($libraries);
|
||||||
if (!$this->getOption('without-php')) {
|
if (!$this->getOption('without-php')) {
|
||||||
@@ -52,22 +52,22 @@ class DumpLicenseCommand extends BaseCommand
|
|||||||
$this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir'));
|
$this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir'));
|
||||||
return static::SUCCESS;
|
return static::SUCCESS;
|
||||||
}
|
}
|
||||||
if ($this->getOption('by-libs') !== null) {
|
if ($this->getOption('for-libs') !== null) {
|
||||||
$libraries = array_map('trim', array_filter(explode(',', $this->getOption('by-libs'))));
|
$libraries = array_map('trim', array_filter(explode(',', $this->getOption('for-libs'))));
|
||||||
$libraries = DependencyUtil::getLibsByDeps($libraries);
|
$libraries = DependencyUtil::getLibs($libraries);
|
||||||
$dumper->addLibs($libraries);
|
$dumper->addLibs($libraries);
|
||||||
$dumper->dump($this->getOption('dump-dir'));
|
$dumper->dump($this->getOption('dump-dir'));
|
||||||
$this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir'));
|
$this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir'));
|
||||||
return static::SUCCESS;
|
return static::SUCCESS;
|
||||||
}
|
}
|
||||||
if ($this->getOption('by-sources') !== null) {
|
if ($this->getOption('for-sources') !== null) {
|
||||||
$sources = array_map('trim', array_filter(explode(',', $this->getOption('by-sources'))));
|
$sources = array_map('trim', array_filter(explode(',', $this->getOption('for-sources'))));
|
||||||
$dumper->addSources($sources);
|
$dumper->addSources($sources);
|
||||||
$dumper->dump($this->getOption('dump-dir'));
|
$dumper->dump($this->getOption('dump-dir'));
|
||||||
$this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir'));
|
$this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir'));
|
||||||
return static::SUCCESS;
|
return static::SUCCESS;
|
||||||
}
|
}
|
||||||
$this->output->writeln('You must use one of "--for-extensions=", "--by-libs=", "--by-sources=" to dump');
|
$this->output->writeln('You must use one of "--for-extensions=", "--for-libs=", "--for-sources=" to dump');
|
||||||
return static::FAILURE;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ use SPC\builder\traits\UnixSystemUtilTrait;
|
|||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\SourceExtractor;
|
use SPC\store\SourceManager;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
|
||||||
#[AsCommand('extract', 'Extract required sources')]
|
#[AsCommand('extract', 'Extract required sources', ['extract-source'])]
|
||||||
class ExtractCommand extends BaseCommand
|
class ExtractCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
use UnixSystemUtilTrait;
|
use UnixSystemUtilTrait;
|
||||||
@@ -34,7 +34,7 @@ class ExtractCommand extends BaseCommand
|
|||||||
$this->output->writeln('<error>sources cannot be empty, at least contain one !</error>');
|
$this->output->writeln('<error>sources cannot be empty, at least contain one !</error>');
|
||||||
return static::FAILURE;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
SourceExtractor::initSource(sources: $sources);
|
SourceManager::initSource(sources: $sources);
|
||||||
logger()->info('Extract done !');
|
logger()->info('Extract done !');
|
||||||
return static::SUCCESS;
|
return static::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
86
src/SPC/command/InstallPkgCommand.php
Normal file
86
src/SPC/command/InstallPkgCommand.php
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command;
|
||||||
|
|
||||||
|
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||||
|
use SPC\exception\DownloaderException;
|
||||||
|
use SPC\exception\FileSystemException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\store\Config;
|
||||||
|
use SPC\store\PackageManager;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
|
#[AsCommand('install-pkg', 'Install additional packages', ['i', 'install-package'])]
|
||||||
|
class InstallPkgCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
use UnixSystemUtilTrait;
|
||||||
|
|
||||||
|
public function configure(): void
|
||||||
|
{
|
||||||
|
$this->addArgument('packages', InputArgument::REQUIRED, 'The packages will be installed, comma separated');
|
||||||
|
$this->addOption('shallow-clone', null, null, 'Clone shallow');
|
||||||
|
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws FileSystemException
|
||||||
|
*/
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Use shallow-clone can reduce git resource download
|
||||||
|
if ($this->getOption('shallow-clone')) {
|
||||||
|
define('GIT_SHALLOW_CLONE', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process -U options
|
||||||
|
$custom_urls = [];
|
||||||
|
foreach ($this->input->getOption('custom-url') as $value) {
|
||||||
|
[$pkg_name, $url] = explode(':', $value, 2);
|
||||||
|
$custom_urls[$pkg_name] = $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
$chosen_pkgs = array_map('trim', array_filter(explode(',', $this->getArgument('packages'))));
|
||||||
|
|
||||||
|
// Download them
|
||||||
|
f_mkdir(DOWNLOAD_PATH);
|
||||||
|
$ni = 0;
|
||||||
|
$cnt = count($chosen_pkgs);
|
||||||
|
|
||||||
|
foreach ($chosen_pkgs as $pkg) {
|
||||||
|
++$ni;
|
||||||
|
if (isset($custom_urls[$pkg])) {
|
||||||
|
$config = Config::getPkg($pkg);
|
||||||
|
$new_config = [
|
||||||
|
'type' => 'url',
|
||||||
|
'url' => $custom_urls[$pkg],
|
||||||
|
];
|
||||||
|
if (isset($config['extract'])) {
|
||||||
|
$new_config['extract'] = $config['extract'];
|
||||||
|
}
|
||||||
|
if (isset($config['filename'])) {
|
||||||
|
$new_config['filename'] = $config['filename'];
|
||||||
|
}
|
||||||
|
logger()->info("Installing source {$pkg} from custom url [{$ni}/{$cnt}]");
|
||||||
|
PackageManager::installPackage($pkg, $new_config);
|
||||||
|
} else {
|
||||||
|
logger()->info("Fetching package {$pkg} [{$ni}/{$cnt}]");
|
||||||
|
PackageManager::installPackage($pkg, Config::getPkg($pkg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$time = round(microtime(true) - START_TIME, 3);
|
||||||
|
logger()->info('Install packages complete, used ' . $time . ' s !');
|
||||||
|
return static::SUCCESS;
|
||||||
|
} catch (DownloaderException $e) {
|
||||||
|
logger()->error($e->getMessage());
|
||||||
|
return static::FAILURE;
|
||||||
|
} catch (WrongUsageException $e) {
|
||||||
|
logger()->critical($e->getMessage());
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -87,6 +87,10 @@ class MicroCombineCommand extends BaseCommand
|
|||||||
// 8. Combine !
|
// 8. Combine !
|
||||||
$output = FileSystem::isRelativePath($output) ? (WORKING_DIR . '/' . $output) : $output;
|
$output = FileSystem::isRelativePath($output) ? (WORKING_DIR . '/' . $output) : $output;
|
||||||
$file_target = file_get_contents($micro_file) . $ini_part . file_get_contents($file);
|
$file_target = file_get_contents($micro_file) . $ini_part . file_get_contents($file);
|
||||||
|
if (PHP_OS_FAMILY === 'Windows' && !str_ends_with(strtolower($output), '.exe')) {
|
||||||
|
$output .= '.exe';
|
||||||
|
}
|
||||||
|
$output = FileSystem::convertPath($output);
|
||||||
$result = file_put_contents($output, $file_target);
|
$result = file_put_contents($output, $file_target);
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
$this->output->writeln('<error>Combine failed.</error>');
|
$this->output->writeln('<error>Combine failed.</error>');
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ use Symfony\Component\Console\Input\InputArgument;
|
|||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
use function Laravel\Prompts\table;
|
|
||||||
|
|
||||||
#[AsCommand('dev:extensions', 'Helper command that lists available extension details', ['list-ext'])]
|
#[AsCommand('dev:extensions', 'Helper command that lists available extension details', ['list-ext'])]
|
||||||
class AllExtCommand extends BaseCommand
|
class AllExtCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
@@ -61,7 +59,7 @@ class AllExtCommand extends BaseCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
[, $libraries, $not_included] = DependencyUtil::getExtLibsByDeps([$extension]);
|
[, $libraries, $not_included] = DependencyUtil::getExtsAndLibs([$extension]);
|
||||||
} catch (WrongUsageException) {
|
} catch (WrongUsageException) {
|
||||||
$libraries = $not_included = [];
|
$libraries = $not_included = [];
|
||||||
}
|
}
|
||||||
@@ -88,7 +86,8 @@ class AllExtCommand extends BaseCommand
|
|||||||
if ($data === []) {
|
if ($data === []) {
|
||||||
$style->warning('Unknown extension selected: ' . implode(',', $extensions));
|
$style->warning('Unknown extension selected: ' . implode(',', $extensions));
|
||||||
} else {
|
} else {
|
||||||
table($columns, $data);
|
$func = PHP_OS_FAMILY === 'Windows' ? [$style, 'table'] : '\Laravel\Prompts\table';
|
||||||
|
call_user_func($func, $columns, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return static::SUCCESS;
|
return static::SUCCESS;
|
||||||
|
|||||||
@@ -57,6 +57,15 @@ class SortConfigCommand extends BaseCommand
|
|||||||
return static::FAILURE;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'pkg':
|
||||||
|
$file = json_decode(FileSystem::readFile(ROOT_DIR . '/config/pkg.json'), true);
|
||||||
|
ConfigValidator::validatePkgs($file);
|
||||||
|
ksort($file);
|
||||||
|
if (!file_put_contents(ROOT_DIR . '/config/pkg.json', json_encode($file, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n")) {
|
||||||
|
$this->output->writeln('<error>Write file pkg.json failed!</error>');
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
$this->output->writeln("<error>invalid config name: {$name}</error>");
|
$this->output->writeln("<error>invalid config name: {$name}</error>");
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class BSDToolCheckList
|
|||||||
$prefix = '';
|
$prefix = '';
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
shell(true)->exec("ASSUME_ALWAYS_YES=yes {$prefix} pkg install -y " . implode(' ', $missing));
|
shell(true)->exec("ASSUME_ALWAYS_YES=yes {$prefix}pkg install -y " . implode(' ', $missing));
|
||||||
} catch (RuntimeException) {
|
} catch (RuntimeException) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use SPC\exception\RuntimeException;
|
|||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Downloader;
|
use SPC\store\Downloader;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\store\PackageManager;
|
||||||
|
|
||||||
class LinuxMuslCheck
|
class LinuxMuslCheck
|
||||||
{
|
{
|
||||||
@@ -84,7 +85,6 @@ class LinuxMuslCheck
|
|||||||
|
|
||||||
/** @noinspection PhpUnused */
|
/** @noinspection PhpUnused */
|
||||||
/**
|
/**
|
||||||
* @throws DownloaderException
|
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
@@ -98,15 +98,10 @@ class LinuxMuslCheck
|
|||||||
logger()->warning('Current user is not root, using sudo for running command');
|
logger()->warning('Current user is not root, using sudo for running command');
|
||||||
}
|
}
|
||||||
$arch = arch2gnu(php_uname('m'));
|
$arch = arch2gnu(php_uname('m'));
|
||||||
$musl_compile_source = [
|
PackageManager::installPackage("musl-toolchain-{$arch}-linux");
|
||||||
'type' => 'url',
|
$pkg_root = PKG_ROOT_PATH . "/musl-toolchain-{$arch}-linux";
|
||||||
'url' => "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/{$arch}-musl-toolchain.tgz",
|
shell()->exec("{$prefix}cp -rf {$pkg_root}/* /usr/local/musl");
|
||||||
];
|
FileSystem::removeDir($pkg_root);
|
||||||
logger()->info('Downloading ' . $musl_compile_source['url']);
|
|
||||||
Downloader::downloadSource('musl-compile', $musl_compile_source);
|
|
||||||
logger()->info('Extracting musl-cross');
|
|
||||||
FileSystem::extractSource('musl-compile', DOWNLOAD_PATH . "/{$arch}-musl-toolchain.tgz");
|
|
||||||
shell()->exec($prefix . 'cp -rf ' . SOURCE_PATH . '/musl-compile/* /usr/local/musl');
|
|
||||||
return true;
|
return true;
|
||||||
} catch (RuntimeException) {
|
} catch (RuntimeException) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ class LinuxToolCheckList
|
|||||||
'xz',
|
'xz',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
private const PROVIDED_COMMAND = [
|
||||||
|
'binutils-gold' => 'ld.gold',
|
||||||
|
];
|
||||||
|
|
||||||
/** @noinspection PhpUnused */
|
/** @noinspection PhpUnused */
|
||||||
#[AsCheckItem('if necessary tools are installed', limit_os: 'Linux', level: 999)]
|
#[AsCheckItem('if necessary tools are installed', limit_os: 'Linux', level: 999)]
|
||||||
public function checkCliTools(): ?CheckResult
|
public function checkCliTools(): ?CheckResult
|
||||||
@@ -52,9 +56,9 @@ class LinuxToolCheckList
|
|||||||
default => self::TOOLS_DEBIAN,
|
default => self::TOOLS_DEBIAN,
|
||||||
};
|
};
|
||||||
$missing = [];
|
$missing = [];
|
||||||
foreach ($required as $cmd) {
|
foreach ($required as $package) {
|
||||||
if ($this->findCommand($cmd) === null) {
|
if ($this->findCommand(self::PROVIDED_COMMAND[$package] ?? $package) === null) {
|
||||||
$missing[] = $cmd;
|
$missing[] = $package;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty($missing)) {
|
if (!empty($missing)) {
|
||||||
@@ -62,6 +66,7 @@ class LinuxToolCheckList
|
|||||||
'ubuntu',
|
'ubuntu',
|
||||||
'alpine',
|
'alpine',
|
||||||
'redhat',
|
'redhat',
|
||||||
|
'Deepin',
|
||||||
'debian' => CheckResult::fail(implode(', ', $missing) . ' not installed on your system', 'install-linux-tools', [$distro, $missing]),
|
'debian' => CheckResult::fail(implode(', ', $missing) . ' not installed on your system', 'install-linux-tools', [$distro, $missing]),
|
||||||
default => CheckResult::fail(implode(', ', $missing) . ' not installed on your system'),
|
default => CheckResult::fail(implode(', ', $missing) . ' not installed on your system'),
|
||||||
};
|
};
|
||||||
@@ -69,8 +74,24 @@ class LinuxToolCheckList
|
|||||||
return CheckResult::ok();
|
return CheckResult::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[AsCheckItem('if cmake version >= 3.18', limit_os: 'Linux')]
|
||||||
|
public function checkCMakeVersion(): ?CheckResult
|
||||||
|
{
|
||||||
|
$check_cmd = 'cmake --version';
|
||||||
|
$pattern = '/cmake version (.*)/m';
|
||||||
|
$out = shell()->execWithResult($check_cmd, false)[1][0];
|
||||||
|
if (preg_match($pattern, $out, $match)) {
|
||||||
|
$ver = $match[1];
|
||||||
|
if (version_compare($ver, '3.18.0') <= 0) {
|
||||||
|
return CheckResult::fail('cmake version is too low (' . $ver . '), please update it manually!');
|
||||||
|
}
|
||||||
|
return CheckResult::ok($match[1]);
|
||||||
|
}
|
||||||
|
return CheckResult::fail('Failed to get cmake version');
|
||||||
|
}
|
||||||
|
|
||||||
/** @noinspection PhpUnused */
|
/** @noinspection PhpUnused */
|
||||||
#[AsCheckItem('if necessary packages are installed', limit_os: 'Linux')]
|
#[AsCheckItem('if necessary linux headers are installed', limit_os: 'Linux')]
|
||||||
public function checkSystemOSPackages(): ?CheckResult
|
public function checkSystemOSPackages(): ?CheckResult
|
||||||
{
|
{
|
||||||
if (SystemUtil::isMuslDist()) {
|
if (SystemUtil::isMuslDist()) {
|
||||||
@@ -90,7 +111,7 @@ class LinuxToolCheckList
|
|||||||
public function fixBuildTools(array $distro, array $missing): bool
|
public function fixBuildTools(array $distro, array $missing): bool
|
||||||
{
|
{
|
||||||
$install_cmd = match ($distro['dist']) {
|
$install_cmd = match ($distro['dist']) {
|
||||||
'ubuntu', 'debian' => 'apt-get install -y',
|
'ubuntu', 'debian', 'Deepin' => 'apt-get install -y',
|
||||||
'alpine' => 'apk add',
|
'alpine' => 'apk add',
|
||||||
'redhat' => 'dnf install -y',
|
'redhat' => 'dnf install -y',
|
||||||
default => throw new RuntimeException('Current linux distro does not have an auto-install script for musl packages yet.'),
|
default => throw new RuntimeException('Current linux distro does not have an auto-install script for musl packages yet.'),
|
||||||
@@ -101,7 +122,7 @@ class LinuxToolCheckList
|
|||||||
logger()->warning('Current user is not root, using sudo for running command');
|
logger()->warning('Current user is not root, using sudo for running command');
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
$is_debian = in_array($distro['dist'], ['debian', 'ubuntu']);
|
$is_debian = in_array($distro['dist'], ['debian', 'ubuntu', 'Deepin']);
|
||||||
$to_install = $is_debian ? str_replace('xz', 'xz-utils', $missing) : $missing;
|
$to_install = $is_debian ? str_replace('xz', 'xz-utils', $missing) : $missing;
|
||||||
// debian, alpine libtool -> libtoolize
|
// debian, alpine libtool -> libtoolize
|
||||||
$to_install = str_replace('libtoolize', 'libtool', $to_install);
|
$to_install = str_replace('libtoolize', 'libtool', $to_install);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user