mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
Merge pull request #819 from crazywhalecc/php-85
Add PHP 8.5 initial support
This commit is contained in:
commit
085abd635e
2
.github/workflows/ext-matrix-tests.yml
vendored
2
.github/workflows/ext-matrix-tests.yml
vendored
@ -82,7 +82,7 @@ jobs:
|
||||
- zlib
|
||||
- zstd
|
||||
php-version:
|
||||
- "8.4"
|
||||
- "git"
|
||||
operating-system:
|
||||
- "ubuntu-latest"
|
||||
#- "macos-13"
|
||||
|
||||
4
.github/workflows/tests.yml
vendored
4
.github/workflows/tests.yml
vendored
@ -145,6 +145,10 @@ jobs:
|
||||
os: ${{ fromJSON(needs.define-matrix.outputs.os) }}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: "Update runner packages"
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
|
||||
run: sudo apt-get update && sudo apt-get install -y ca-certificates
|
||||
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
|
||||
23
README-zh.md
23
README-zh.md
@ -76,22 +76,23 @@ static-php-cli(简称 `spc`)有许多特性:
|
||||
|
||||
当前支持编译的 PHP 版本:
|
||||
|
||||
> :warning: 支持,但 static-php-cli 作者可能不再提供补丁修复
|
||||
> :warning: 部分支持,对于新的测试版和旧版本可能存在问题。
|
||||
>
|
||||
> :heavy_check_mark: 支持
|
||||
>
|
||||
> :x: 不支持
|
||||
|
||||
| PHP Version | Status | Comment |
|
||||
|-------------|--------------------|----------------------------------------------|
|
||||
| 7.2 | :x: | |
|
||||
| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
|
||||
| 8.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新 |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
| 8.4 | :heavy_check_mark: | |
|
||||
| PHP Version | Status | Comment |
|
||||
|-------------|--------------------|---------------------------------------------------------|
|
||||
| 7.2 | :x: | |
|
||||
| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
|
||||
| 8.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新,在 8.5 发布后我们不再处理 8.1 相关的 backport 支持 |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
| 8.4 | :heavy_check_mark: | |
|
||||
| 8.5 (alpha) | :warning: | PHP 8.5 目前处于 alpha 阶段 |
|
||||
|
||||
> 这个表格的支持状态是 static-php-cli 对构建对应版本的支持情况,不是 PHP 官方对该版本的支持情况。
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ Here is the supported OS and arch, where :octocat: represents support for GitHub
|
||||
|
||||
Currently supported PHP versions for compilation:
|
||||
|
||||
> :warning: supported but not maintained by static-php-cli authors
|
||||
> :warning: Partial support, there may be issues with newer test versions or older versions.
|
||||
>
|
||||
> :heavy_check_mark: supported
|
||||
>
|
||||
@ -95,10 +95,11 @@ Currently supported PHP versions for compilation:
|
||||
| 7.3 | :x: | phpmicro and some extensions not supported on 7.x |
|
||||
| 7.4 | :x: | phpmicro and some extensions not supported on 7.x |
|
||||
| 8.0 | :warning: | PHP official has stopped maintenance of 8.0, we no longer provide backport support for version 8.0 |
|
||||
| 8.1 | :heavy_check_mark: | PHP official has security fixes only |
|
||||
| 8.1 | :heavy_check_mark: | PHP official has security fixes only, we no longer provide backport support when 8.5 released |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
| 8.4 | :heavy_check_mark: | |
|
||||
| 8.5 (alpha) | :warning: | PHP 8.5 is in alpha |
|
||||
|
||||
> This table shows the support status for static-php-cli in building the corresponding version,
|
||||
> not the official PHP support status for that version.
|
||||
|
||||
@ -104,6 +104,7 @@ RUN apk update; \
|
||||
m4 \
|
||||
make \
|
||||
pkgconfig \
|
||||
re2c \
|
||||
wget \
|
||||
xz \
|
||||
gettext-dev \
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
set -e
|
||||
|
||||
# This file is using docker to run commands
|
||||
SPC_DOCKER_VERSION=v4
|
||||
SPC_DOCKER_VERSION=v5
|
||||
|
||||
# Detect docker can run
|
||||
if ! which docker >/dev/null; then
|
||||
@ -102,17 +102,20 @@ RUN curl -o cmake.tgz -#fSL https://github.com/Kitware/CMake/releases/download/v
|
||||
tar -xzf cmake.tgz -C /cmake --strip-components 1
|
||||
|
||||
WORKDIR /app
|
||||
ADD ./src /app/src
|
||||
COPY ./composer.* /app/
|
||||
ADD ./bin/setup-runtime /app/bin/setup-runtime
|
||||
ADD ./bin/spc /app/bin/spc
|
||||
RUN /app/bin/setup-runtime
|
||||
ADD ./src /app/src
|
||||
RUN /app/bin/php /app/bin/composer install --no-dev
|
||||
ENV SPC_LIBC=glibc
|
||||
ENV PATH="/app/bin:/cmake/bin:/opt/rh/devtoolset-10/root/usr/bin:\$PATH"
|
||||
|
||||
ADD ./config/env.ini /app/config/env.ini
|
||||
ADD ./config /app/config
|
||||
RUN CC=gcc bin/spc doctor --auto-fix --debug
|
||||
RUN if [ -f /app/buildroot/bin/re2c ]; then \
|
||||
cp /app/buildroot/bin/re2c /usr/local/bin/re2c ;\
|
||||
fi
|
||||
|
||||
RUN curl -o make.tgz -fsSL https://ftp.gnu.org/gnu/make/make-4.4.tar.gz && \
|
||||
tar -zxvf make.tgz && \
|
||||
|
||||
@ -23,7 +23,6 @@
|
||||
"captainhook/hook-installer": "^1.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.60",
|
||||
"humbug/box": "^4.5.0 || ^4.6.0",
|
||||
"nunomaduro/collision": "^7.8",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^10.3 || ^9.5"
|
||||
},
|
||||
|
||||
437
composer.lock
generated
437
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "d705cec8270679a463d9e04310208967",
|
||||
"content-hash": "dbefe1ee5c584f6f0cc64c26fb83451c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "illuminate/collections",
|
||||
@ -416,47 +416,47 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v6.4.23",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93"
|
||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/9056771b8eca08d026cd3280deeec3cfd99c4d93",
|
||||
"reference": "9056771b8eca08d026cd3280deeec3cfd99c4d93",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1",
|
||||
"reference": "5f360ebc65c55265a74d23d7fe27f957870158a1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"php": ">=8.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/service-contracts": "^2.5|^3",
|
||||
"symfony/string": "^5.4|^6.0|^7.0"
|
||||
"symfony/string": "^7.2"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/dependency-injection": "<5.4",
|
||||
"symfony/dotenv": "<5.4",
|
||||
"symfony/event-dispatcher": "<5.4",
|
||||
"symfony/lock": "<5.4",
|
||||
"symfony/process": "<5.4"
|
||||
"symfony/dependency-injection": "<6.4",
|
||||
"symfony/dotenv": "<6.4",
|
||||
"symfony/event-dispatcher": "<6.4",
|
||||
"symfony/lock": "<6.4",
|
||||
"symfony/process": "<6.4"
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "1.0|2.0|3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/config": "^5.4|^6.0|^7.0",
|
||||
"symfony/dependency-injection": "^5.4|^6.0|^7.0",
|
||||
"symfony/event-dispatcher": "^5.4|^6.0|^7.0",
|
||||
"symfony/config": "^6.4|^7.0",
|
||||
"symfony/dependency-injection": "^6.4|^7.0",
|
||||
"symfony/event-dispatcher": "^6.4|^7.0",
|
||||
"symfony/http-foundation": "^6.4|^7.0",
|
||||
"symfony/http-kernel": "^6.4|^7.0",
|
||||
"symfony/lock": "^5.4|^6.0|^7.0",
|
||||
"symfony/messenger": "^5.4|^6.0|^7.0",
|
||||
"symfony/process": "^5.4|^6.0|^7.0",
|
||||
"symfony/stopwatch": "^5.4|^6.0|^7.0",
|
||||
"symfony/var-dumper": "^5.4|^6.0|^7.0"
|
||||
"symfony/lock": "^6.4|^7.0",
|
||||
"symfony/messenger": "^6.4|^7.0",
|
||||
"symfony/process": "^6.4|^7.0",
|
||||
"symfony/stopwatch": "^6.4|^7.0",
|
||||
"symfony/var-dumper": "^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@ -490,7 +490,7 @@
|
||||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v6.4.23"
|
||||
"source": "https://github.com/symfony/console/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -501,12 +501,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-27T19:37:22+00:00"
|
||||
"time": "2025-07-30T17:13:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
@ -1040,16 +1044,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"reference": "42f505aff654e62ac7ac2ce21033818297ca89ca",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1107,7 +1111,7 @@
|
||||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/string/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1118,25 +1122,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-20T20:19:01+00:00"
|
||||
"time": "2025-07-10T08:47:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v7.3.1",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "0c3555045a46ab3cd4cc5a69d161225195230edb"
|
||||
"reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/0c3555045a46ab3cd4cc5a69d161225195230edb",
|
||||
"reference": "0c3555045a46ab3cd4cc5a69d161225195230edb",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30",
|
||||
"reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1179,7 +1187,7 @@
|
||||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.3.1"
|
||||
"source": "https://github.com/symfony/yaml/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1190,12 +1198,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-03T06:57:57+00:00"
|
||||
"time": "2025-07-10T08:47:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "zhamao/logger",
|
||||
@ -2078,7 +2090,7 @@
|
||||
},
|
||||
{
|
||||
"name": "captainhook/captainhook-phar",
|
||||
"version": "5.25.6",
|
||||
"version": "5.25.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/captainhook-git/captainhook-phar.git",
|
||||
@ -2132,7 +2144,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/captainhook-git/captainhook/issues",
|
||||
"source": "https://github.com/captainhook-git/captainhook-phar/tree/5.25.6"
|
||||
"source": "https://github.com/captainhook-git/captainhook-phar/tree/5.25.10"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -2831,93 +2843,22 @@
|
||||
],
|
||||
"time": "2025-02-13T23:05:19+00:00"
|
||||
},
|
||||
{
|
||||
"name": "filp/whoops",
|
||||
"version": "2.18.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "59a123a3d459c5a23055802237cb317f609867e5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5",
|
||||
"reference": "59a123a3d459c5a23055802237cb317f609867e5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0",
|
||||
"psr/log": "^1.0.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.0",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3",
|
||||
"symfony/var-dumper": "^4.0 || ^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
|
||||
"whoops/soap": "Formats errors as SOAP responses"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Whoops\\": "src/Whoops/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Filipe Dobreira",
|
||||
"homepage": "https://github.com/filp",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "php error handling for cool kids",
|
||||
"homepage": "https://filp.github.io/whoops/",
|
||||
"keywords": [
|
||||
"error",
|
||||
"exception",
|
||||
"handling",
|
||||
"library",
|
||||
"throwable",
|
||||
"whoops"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/filp/whoops/issues",
|
||||
"source": "https://github.com/filp/whoops/tree/2.18.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/denis-sokolov",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-16T00:02:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "friendsofphp/php-cs-fixer",
|
||||
"version": "v3.84.0",
|
||||
"version": "v3.85.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
|
||||
"reference": "38dad0767bf2a9b516b976852200ae722fe984ca"
|
||||
"reference": "2fb6d7f6c3398dca5786a1635b27405d73a417ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/38dad0767bf2a9b516b976852200ae722fe984ca",
|
||||
"reference": "38dad0767bf2a9b516b976852200ae722fe984ca",
|
||||
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2fb6d7f6c3398dca5786a1635b27405d73a417ba",
|
||||
"reference": "2fb6d7f6c3398dca5786a1635b27405d73a417ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"clue/ndjson-react": "^1.0",
|
||||
"clue/ndjson-react": "^1.3",
|
||||
"composer/semver": "^3.4",
|
||||
"composer/xdebug-handler": "^3.0.5",
|
||||
"ext-filter": "*",
|
||||
@ -2927,12 +2868,12 @@
|
||||
"fidry/cpu-core-counter": "^1.2",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"react/child-process": "^0.6.6",
|
||||
"react/event-loop": "^1.0",
|
||||
"react/promise": "^2.11 || ^3.0",
|
||||
"react/socket": "^1.0",
|
||||
"react/stream": "^1.0",
|
||||
"react/event-loop": "^1.5",
|
||||
"react/promise": "^3.2",
|
||||
"react/socket": "^1.16",
|
||||
"react/stream": "^1.4",
|
||||
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
|
||||
"symfony/console": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/console": "^5.4.47 || ^6.4.13 || ^7.0",
|
||||
"symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0",
|
||||
"symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0",
|
||||
@ -2997,7 +2938,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.84.0"
|
||||
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.85.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3005,7 +2946,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-07-15T18:21:57+00:00"
|
||||
"time": "2025-07-29T22:22:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "humbug/box",
|
||||
@ -3660,16 +3601,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v5.5.0",
|
||||
"version": "v5.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9"
|
||||
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9",
|
||||
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/221b0d0fdf1369c71047ad1d18bb5880017bbc56",
|
||||
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3712,190 +3653,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.0"
|
||||
},
|
||||
"time": "2025-05-31T08:24:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/collision",
|
||||
"version": "v7.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nunomaduro/collision.git",
|
||||
"reference": "995245421d3d7593a6960822063bdba4f5d7cf1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/995245421d3d7593a6960822063bdba4f5d7cf1a",
|
||||
"reference": "995245421d3d7593a6960822063bdba4f5d7cf1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"filp/whoops": "^2.17.0",
|
||||
"nunomaduro/termwind": "^1.17.0",
|
||||
"php": "^8.1.0",
|
||||
"symfony/console": "^6.4.17"
|
||||
},
|
||||
"conflict": {
|
||||
"laravel/framework": ">=11.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"brianium/paratest": "^7.4.8",
|
||||
"laravel/framework": "^10.48.29",
|
||||
"laravel/pint": "^1.21.2",
|
||||
"laravel/sail": "^1.41.0",
|
||||
"laravel/sanctum": "^3.3.3",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"nunomaduro/larastan": "^2.10.0",
|
||||
"orchestra/testbench-core": "^8.35.0",
|
||||
"pestphp/pest": "^2.36.0",
|
||||
"phpunit/phpunit": "^10.5.36",
|
||||
"sebastian/environment": "^6.1.0",
|
||||
"spatie/laravel-ignition": "^2.9.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"./src/Adapters/Phpunit/Autoload.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"NunoMaduro\\Collision\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nuno Maduro",
|
||||
"email": "enunomaduro@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Cli error handling for console/command-line PHP applications.",
|
||||
"keywords": [
|
||||
"artisan",
|
||||
"cli",
|
||||
"command-line",
|
||||
"console",
|
||||
"error",
|
||||
"handling",
|
||||
"laravel",
|
||||
"laravel-zero",
|
||||
"php",
|
||||
"symfony"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nunomaduro/collision/issues",
|
||||
"source": "https://github.com/nunomaduro/collision"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/paypalme/enunomaduro",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nunomaduro",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/nunomaduro",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-14T22:35:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nunomaduro/termwind",
|
||||
"version": "v1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nunomaduro/termwind.git",
|
||||
"reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nunomaduro/termwind/zipball/5369ef84d8142c1d87e4ec278711d4ece3cbf301",
|
||||
"reference": "5369ef84d8142c1d87e4ec278711d4ece3cbf301",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^8.1",
|
||||
"symfony/console": "^6.4.15"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/console": "^10.48.24",
|
||||
"illuminate/support": "^10.48.24",
|
||||
"laravel/pint": "^1.18.2",
|
||||
"pestphp/pest": "^2.36.0",
|
||||
"pestphp/pest-plugin-mock": "2.0.0",
|
||||
"phpstan/phpstan": "^1.12.11",
|
||||
"phpstan/phpstan-strict-rules": "^1.6.1",
|
||||
"symfony/var-dumper": "^6.4.15",
|
||||
"thecodingmachine/phpstan-strict-rules": "^1.0.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Termwind\\Laravel\\TermwindServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Termwind\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nuno Maduro",
|
||||
"email": "enunomaduro@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Its like Tailwind CSS, but for the console.",
|
||||
"keywords": [
|
||||
"cli",
|
||||
"console",
|
||||
"css",
|
||||
"package",
|
||||
"php",
|
||||
"style"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nunomaduro/termwind/issues",
|
||||
"source": "https://github.com/nunomaduro/termwind/tree/v1.17.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/paypalme/enunomaduro",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nunomaduro",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/xiCO2k",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-21T10:36:35+00:00"
|
||||
"time": "2025-07-27T20:03:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/composer-distributor",
|
||||
@ -6881,16 +6641,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb"
|
||||
"reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
|
||||
"reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd",
|
||||
"reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6927,7 +6687,7 @@
|
||||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -6938,25 +6698,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-25T15:15:23+00:00"
|
||||
"time": "2025-07-07T08:17:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d"
|
||||
"reference": "2a6614966ba1074fa93dae0bc804227422df4dfe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d",
|
||||
"reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe",
|
||||
"reference": "2a6614966ba1074fa93dae0bc804227422df4dfe",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -6991,7 +6755,7 @@
|
||||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/finder/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -7002,25 +6766,29 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-30T19:00:26+00:00"
|
||||
"time": "2025-07-15T13:41:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v7.3.0",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/options-resolver.git",
|
||||
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca"
|
||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/afb9a8038025e5dbc657378bfab9198d75f10fca",
|
||||
"reference": "afb9a8038025e5dbc657378bfab9198d75f10fca",
|
||||
"url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
||||
"reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7058,7 +6826,7 @@
|
||||
"options"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.0"
|
||||
"source": "https://github.com/symfony/options-resolver/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -7069,12 +6837,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-04-04T13:12:05+00:00"
|
||||
"time": "2025-07-15T11:36:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-iconv",
|
||||
@ -7296,16 +7068,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v7.3.1",
|
||||
"version": "v7.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42"
|
||||
"reference": "53205bea27450dc5c65377518b3275e126d45e75"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/6e209fbe5f5a7b6043baba46fe5735a4b85d0d42",
|
||||
"reference": "6e209fbe5f5a7b6043baba46fe5735a4b85d0d42",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/53205bea27450dc5c65377518b3275e126d45e75",
|
||||
"reference": "53205bea27450dc5c65377518b3275e126d45e75",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -7317,7 +7089,6 @@
|
||||
"symfony/console": "<6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-iconv": "*",
|
||||
"symfony/console": "^6.4|^7.0",
|
||||
"symfony/http-kernel": "^6.4|^7.0",
|
||||
"symfony/process": "^6.4|^7.0",
|
||||
@ -7360,7 +7131,7 @@
|
||||
"dump"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.3.1"
|
||||
"source": "https://github.com/symfony/var-dumper/tree/v7.3.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -7371,12 +7142,16 @@
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-06-27T19:55:54+00:00"
|
||||
"time": "2025-07-29T20:02:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "thecodingmachine/safe",
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
;
|
||||
; Here's a list of env vars, these value cannot be changed anywhere:
|
||||
;
|
||||
; SPC_VERSION: the version of static-php-cli.
|
||||
; WORKING_DIR: the working directory of the build process. (default: `$(pwd)`)
|
||||
; ROOT_DIR: the root directory of static-php-cli. (default: `/path/to/static-php-cli`, when running in phar or micro mode: `phar://path/to/spc.phar`)
|
||||
; BUILD_ROOT_PATH: the root path of the build process. (default: `$(pwd)/buildroot`)
|
||||
@ -43,6 +44,8 @@ SPC_SKIP_PHP_VERSION_CHECK="no"
|
||||
SPC_SKIP_DOCTOR_CHECK_ITEMS=""
|
||||
; extra modules that xcaddy will include in the FrankenPHP build
|
||||
SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/frankenphp/caddy --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
|
||||
; The display message for php version output (PHP >= 8.4 available)
|
||||
PHP_BUILD_PROVIDER="static-php-cli ${SPC_VERSION}"
|
||||
|
||||
; EXTENSION_DIR where the built php will look for extension when a .ini instructs to load them
|
||||
; only useful for builds targeting not pure-static linking
|
||||
|
||||
@ -488,6 +488,7 @@
|
||||
"opcache": {
|
||||
"type": "builtin",
|
||||
"arg-type-unix": "custom",
|
||||
"arg-type-windows": "enable",
|
||||
"zend-extension": true
|
||||
},
|
||||
"openssl": {
|
||||
@ -530,9 +531,10 @@
|
||||
},
|
||||
"notes": true,
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"libargon2"
|
||||
"libargon2",
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"pcntl": {
|
||||
|
||||
@ -797,6 +797,12 @@
|
||||
"depot.h"
|
||||
]
|
||||
},
|
||||
"re2c": {
|
||||
"source": "re2c",
|
||||
"bin-unix": [
|
||||
"re2c"
|
||||
]
|
||||
},
|
||||
"readline": {
|
||||
"source": "readline",
|
||||
"static-libs-unix": [
|
||||
|
||||
@ -733,7 +733,7 @@
|
||||
"micro": {
|
||||
"type": "git",
|
||||
"path": "php-src/sapi/micro",
|
||||
"rev": "84beta",
|
||||
"rev": "php-85-win",
|
||||
"url": "https://github.com/static-php/phpmicro",
|
||||
"license": {
|
||||
"type": "file",
|
||||
@ -932,6 +932,20 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"re2c": {
|
||||
"type": "ghrel",
|
||||
"repo": "skvadrik/re2c",
|
||||
"match": "re2c.+\\.tar\\.xz",
|
||||
"prefer-stable": true,
|
||||
"alt": {
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/re2c/re2c-4.3.tar.xz"
|
||||
},
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"readline": {
|
||||
"type": "filelist",
|
||||
"url": "https://ftp.gnu.org/pub/gnu/readline/",
|
||||
|
||||
@ -238,6 +238,7 @@ const availablePhpVersions = [
|
||||
'8.2',
|
||||
'8.3',
|
||||
'8.4',
|
||||
'8.5',
|
||||
];
|
||||
|
||||
const I18N = {
|
||||
|
||||
@ -32,7 +32,7 @@ Windows currently only supports the x86_64 architecture, and does not support 32
|
||||
|
||||
## Supported PHP Version
|
||||
|
||||
Currently, static php cli supports PHP versions 8.1 to 8.4, and theoretically supports PHP 8.0 and earlier versions.
|
||||
Currently, static php cli supports PHP versions 8.1 to 8.5, and theoretically supports PHP 8.0 and earlier versions.
|
||||
Simply select the earlier version when downloading.
|
||||
However, due to some extensions and special components that have stopped supporting earlier versions of PHP,
|
||||
static-php-cli will not explicitly support earlier versions.
|
||||
|
||||
@ -242,8 +242,8 @@ Also, it is available when downloading with the `--for-extensions` option.
|
||||
|
||||
|
||||
```bash
|
||||
# Specifying to download a beta version of PHP8.3
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"
|
||||
# Specifying to download a alpha version of PHP 8.5
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz"
|
||||
|
||||
# Specifying to download an older version of the curl library
|
||||
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
|
||||
|
||||
@ -29,6 +29,6 @@ Windows 目前只支持 x86_64 架构,不支持 32 位 x86、不支持 arm64
|
||||
|
||||
## PHP 支持版本
|
||||
|
||||
目前,static-php-cli 对 PHP 8.1 ~ 8.4 版本是支持的,对于 PHP 8.0 及更早版本理论上支持,只需下载时选择早期版本即可。
|
||||
目前,static-php-cli 对 PHP 8.1 ~ 8.5 版本是支持的,对于 PHP 8.0 及更早版本理论上支持,只需下载时选择早期版本即可。
|
||||
但由于部分扩展和特殊组件已对早期版本的 PHP 停止了支持,所以 static-php-cli 不会明确支持早期版本。
|
||||
我们推荐你编译尽可能新的 PHP 版本,以获得更好的体验。
|
||||
|
||||
@ -209,8 +209,8 @@ bin/spc download --from-zip=/path/to/your/download.zip
|
||||
让下载器强制使用你指定的链接下载此 source 的包。使用方法为 `{source-name}:{url}` 即可,可同时重写多个库的下载地址。在使用 `--for-extensions` 选项下载时同样可用。
|
||||
|
||||
```bash
|
||||
# 例如:指定下载测试版的 PHP8.3
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"
|
||||
# 例如:指定下载 Alpha 版的 PHP8.5
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz"
|
||||
|
||||
# 指定下载旧版本的 curl 库
|
||||
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
|
||||
|
||||
@ -339,16 +339,21 @@ abstract class BuilderBase
|
||||
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
|
||||
}
|
||||
|
||||
public function getPHPVersion(): string
|
||||
public function getPHPVersion(bool $exception_on_failure = true): string
|
||||
{
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
|
||||
if (!$exception_on_failure) {
|
||||
return 'unknown';
|
||||
}
|
||||
throw new WrongUsageException('PHP source files are not available, you need to download them first');
|
||||
}
|
||||
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
|
||||
if (preg_match('/PHP_VERSION "(.*)"/', $file, $match) !== 0) {
|
||||
return $match[1];
|
||||
}
|
||||
|
||||
if (!$exception_on_failure) {
|
||||
return 'unknown';
|
||||
}
|
||||
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
|
||||
}
|
||||
|
||||
@ -366,7 +371,7 @@ abstract class BuilderBase
|
||||
}
|
||||
$file = LockFile::getLockFullPath($lock);
|
||||
}
|
||||
if (preg_match('/php-(\d+\.\d+\.\d+(?:RC\d+)?)\.tar\.(?:gz|bz2|xz)/', $file, $match)) {
|
||||
if (preg_match('/php-(\d+\.\d+\.\d+(?:RC\d+|alpha\d+|beta\d+)?)\.tar\.(?:gz|bz2|xz)/', $file, $match)) {
|
||||
return $match[1];
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -183,6 +183,14 @@ class Extension
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before ./configure.bat for Windows
|
||||
*/
|
||||
public function patchBeforeWindowsConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before make
|
||||
* If you need to patch some code, overwrite this
|
||||
|
||||
@ -288,6 +288,16 @@ abstract class LibraryBase
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before windows configure.bat
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeWindowsConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before make
|
||||
* If you need to patch some code, overwrite this
|
||||
|
||||
@ -61,7 +61,7 @@ class curl extends Extension
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
$patched = parent::patchBeforeMake();
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS');
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||
if ($this->builder instanceof WindowsBuilder && !str_contains($extra_libs, 'secur32.lib')) {
|
||||
$extra_libs .= ' secur32.lib';
|
||||
putenv('SPC_EXTRA_LIBS=' . trim($extra_libs));
|
||||
|
||||
@ -49,7 +49,7 @@ class imap extends Extension
|
||||
if (PHP_OS_FAMILY !== 'Linux' || SystemUtil::isMuslDist()) {
|
||||
return $patched;
|
||||
}
|
||||
$extra_libs = trim(getenv('SPC_EXTRA_LIBS') . ' -lcrypt');
|
||||
$extra_libs = trim((getenv('SPC_EXTRA_LIBS') ?: '') . ' -lcrypt');
|
||||
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -26,19 +26,26 @@ class opcache extends Extension
|
||||
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
$version = $this->builder->getPHPVersion();
|
||||
if (file_exists(SOURCE_PATH . '/php-src/.opcache_patched')) {
|
||||
return false;
|
||||
}
|
||||
// if 8.2.0 <= PHP_VERSION < 8.2.23, we need to patch from legacy patch file
|
||||
if (version_compare($this->builder->getPHPVersion(), '8.2.0', '>=') && version_compare($this->builder->getPHPVersion(), '8.2.23', '<')) {
|
||||
if (version_compare($version, '8.2.0', '>=') && version_compare($version, '8.2.23', '<')) {
|
||||
SourcePatcher::patchFile('spc_fix_static_opcache_before_80222.patch', SOURCE_PATH . '/php-src');
|
||||
}
|
||||
// if 8.3.0 <= PHP_VERSION < 8.3.11, we need to patch from legacy patch file
|
||||
elseif (version_compare($this->builder->getPHPVersion(), '8.3.0', '>=') && version_compare($this->builder->getPHPVersion(), '8.3.11', '<')) {
|
||||
elseif (version_compare($version, '8.3.0', '>=') && version_compare($version, '8.3.11', '<')) {
|
||||
SourcePatcher::patchFile('spc_fix_static_opcache_before_80310.patch', SOURCE_PATH . '/php-src');
|
||||
} else {
|
||||
}
|
||||
// if 8.3.12 <= PHP_VERSION < 8.5.0-dev, we need to patch from legacy patch file
|
||||
elseif (version_compare($version, '8.5.0-dev', '<')) {
|
||||
SourcePatcher::patchMicro(items: ['static_opcache']);
|
||||
}
|
||||
// PHP 8.5.0-dev and later supports static opcache without patching
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
return file_put_contents(SOURCE_PATH . '/php-src/.opcache_patched', '1') !== false;
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,19 @@ class openssl extends Extension
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
{
|
||||
$openssl_dir = $this->builder->getPHPVersionID() >= 80400 ? '' : ' --with-openssl-dir=' . BUILD_ROOT_PATH;
|
||||
return '--with-openssl=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . $openssl_dir;
|
||||
$args = '--with-openssl=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . $openssl_dir;
|
||||
if ($this->builder->getPHPVersionID() >= 80500 || ($this->builder->getPHPVersionID() >= 80400 && !$this->builder->getOption('enable-zts'))) {
|
||||
$args .= ' --with-openssl-argon2 OPENSSL_LIBS="-lz"';
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(bool $shared = false): string
|
||||
{
|
||||
$args = '--with-openssl';
|
||||
if ($this->builder->getPHPVersionID() >= 80500 || ($this->builder->getPHPVersionID() >= 80400 && !$this->builder->getOption('enable-zts'))) {
|
||||
$args .= ' --with-openssl-argon2';
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,4 +42,14 @@ class password_argon2 extends Extension
|
||||
}
|
||||
return $patched;
|
||||
}
|
||||
|
||||
public function getConfigureArg(bool $shared = false): string
|
||||
{
|
||||
if ($this->builder->getLib('openssl') !== null) {
|
||||
if ($this->builder->getPHPVersionID() >= 80500 || ($this->builder->getPHPVersionID() >= 80400 && !$this->builder->getOption('enable-zts'))) {
|
||||
return '--without-password-argon2'; // use --with-openssl-argon2 in openssl extension instead
|
||||
}
|
||||
}
|
||||
return '--with-password-argon2';
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ class sqlsrv extends Extension
|
||||
return false;
|
||||
}
|
||||
|
||||
public function patchBeforeConfigure(): bool
|
||||
public function patchBeforeWindowsConfigure(): bool
|
||||
{
|
||||
if ($this->pdo_sqlsrv_patched) {
|
||||
// revert pdo_sqlsrv patch
|
||||
|
||||
@ -66,6 +66,17 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
$phpVersionID = $this->getPHPVersionID();
|
||||
$json_74 = $phpVersionID < 80000 ? '--enable-json ' : '';
|
||||
|
||||
$opcache_jit = !$this->getOption('disable-opcache-jit', false);
|
||||
if ($opcache_jit && ($phpVersionID >= 80500 || $this->getExt('opcache'))) {
|
||||
// php 8.5 contains opcache extension by default,
|
||||
// if opcache_jit is enabled for 8.5 or opcache enabled,
|
||||
// we need to disable undefined behavior sanitizer.
|
||||
f_putenv('SPC_COMPILER_EXTRA=-fno-sanitize=undefined');
|
||||
} elseif ($opcache_jit) {
|
||||
$opcache_jit = false;
|
||||
}
|
||||
$opcache_jit_arg = $opcache_jit ? '--enable-opcache-jit ' : '--disable-opcache-jit ';
|
||||
|
||||
if ($this->getOption('enable-zts', false)) {
|
||||
$maxExecutionTimers = $phpVersionID >= 80100 ? '--enable-zend-max-execution-timers ' : '';
|
||||
$zts = '--enable-zts --disable-zend-signals ';
|
||||
@ -73,10 +84,7 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
$maxExecutionTimers = '';
|
||||
$zts = '';
|
||||
}
|
||||
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';
|
||||
if (!$disable_jit && $this->getExt('opcache')) {
|
||||
f_putenv('SPC_COMPILER_EXTRA=-fno-sanitize=undefined');
|
||||
}
|
||||
|
||||
$config_file_path = $this->getOption('with-config-file-path', false) ?
|
||||
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
||||
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
||||
@ -89,9 +97,10 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
$enableFrankenphp = ($build_target & BUILD_TARGET_FRANKENPHP) === BUILD_TARGET_FRANKENPHP;
|
||||
|
||||
// prepare build php envs
|
||||
// $musl_flag = SPCTarget::getLibc() === 'musl' ? ' -D__MUSL__' : ' -U__MUSL__';
|
||||
$php_configure_env = SystemUtil::makeEnvVarString([
|
||||
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
|
||||
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
|
||||
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH, // . ' -Dsomethinghere', // . $musl_flag,
|
||||
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
||||
// 'LIBS' => SPCTarget::getRuntimeLibs(), // do not pass static libraries here yet, they may contain polyfills for libc functions!
|
||||
]);
|
||||
@ -114,7 +123,7 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
($enableMicro ? '--enable-micro=all-static ' : '--disable-micro ') .
|
||||
$config_file_path .
|
||||
$config_file_scan_dir .
|
||||
$disable_jit .
|
||||
$opcache_jit_arg .
|
||||
$json_74 .
|
||||
$zts .
|
||||
$maxExecutionTimers .
|
||||
@ -335,6 +344,15 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
$this->patchPhpScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return extra variables for php make command.
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
* @throws \ReflectionException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
private function getMakeExtraVars(): array
|
||||
{
|
||||
$config = (new SPCConfigUtil($this, ['libs_only_deps' => true, 'absolute_libs' => true]))->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
|
||||
|
||||
@ -28,6 +28,8 @@ use SPC\store\FileSystem;
|
||||
|
||||
class openssl extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\traits\openssl;
|
||||
|
||||
public const NAME = 'openssl';
|
||||
|
||||
/**
|
||||
@ -37,8 +39,6 @@ class openssl extends LinuxLibraryBase
|
||||
*/
|
||||
public function build(): void
|
||||
{
|
||||
[,,$destdir] = SEPARATED_PATH;
|
||||
|
||||
$extra = '';
|
||||
$ex_lib = '-ldl -pthread';
|
||||
$arch = getenv('SPC_ARCH');
|
||||
|
||||
15
src/SPC/builder/linux/library/re2c.php
Normal file
15
src/SPC/builder/linux/library/re2c.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
/**
|
||||
* a template library class for unix
|
||||
*/
|
||||
class re2c extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\re2c;
|
||||
|
||||
public const NAME = 're2c';
|
||||
}
|
||||
@ -98,9 +98,17 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
$this->emitPatchPoint('before-php-configure');
|
||||
SourcePatcher::patchBeforeConfigure($this);
|
||||
|
||||
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
||||
$phpVersionID = $this->getPHPVersionID();
|
||||
$json_74 = $phpVersionID < 80000 ? '--enable-json ' : '';
|
||||
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
|
||||
|
||||
$opcache_jit = !$this->getOption('disable-opcache-jit', false);
|
||||
// disable opcache jit for PHP < 8.5.0 when opcache is not enabled
|
||||
if ($opcache_jit && $phpVersionID < 80500 && !$this->getExt('opcache')) {
|
||||
$opcache_jit = false;
|
||||
}
|
||||
$opcache_jit_arg = $opcache_jit ? '--enable-opcache-jit ' : '--disable-opcache-jit ';
|
||||
|
||||
$config_file_path = $this->getOption('with-config-file-path', false) ?
|
||||
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
||||
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
||||
@ -135,6 +143,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
|
||||
($enableEmbed ? "--enable-embed={$embed_type} " : '--disable-embed ') .
|
||||
($enableMicro ? '--enable-micro ' : '--disable-micro ') .
|
||||
$opcache_jit_arg .
|
||||
$config_file_path .
|
||||
$config_file_scan_dir .
|
||||
$json_74 .
|
||||
|
||||
@ -28,6 +28,8 @@ use SPC\store\FileSystem;
|
||||
|
||||
class openssl extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\traits\openssl;
|
||||
|
||||
public const NAME = 'openssl';
|
||||
|
||||
/**
|
||||
|
||||
12
src/SPC/builder/macos/library/re2c.php
Normal file
12
src/SPC/builder/macos/library/re2c.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
class re2c extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\re2c;
|
||||
|
||||
public const NAME = 're2c';
|
||||
}
|
||||
38
src/SPC/builder/traits/openssl.php
Normal file
38
src/SPC/builder/traits/openssl.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\traits;
|
||||
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\PkgConfigUtil;
|
||||
|
||||
trait openssl
|
||||
{
|
||||
public function getLibVersion(): ?string
|
||||
{
|
||||
// get openssl version from source directory
|
||||
if (file_exists("{$this->source_dir}/VERSION.dat")) {
|
||||
// parse as INI
|
||||
$version = parse_ini_file("{$this->source_dir}/VERSION.dat");
|
||||
if ($version !== false) {
|
||||
return "{$version['MAJOR']}.{$version['MINOR']}.{$version['PATCH']}";
|
||||
}
|
||||
}
|
||||
// get openssl version from pkg-config
|
||||
if (PHP_OS_FAMILY !== 'Windows') {
|
||||
try {
|
||||
return PkgConfigUtil::getModuleVersion('openssl');
|
||||
} catch (RuntimeException) {
|
||||
}
|
||||
}
|
||||
// get openssl version from header openssl/opensslv.h
|
||||
if (file_exists(BUILD_INCLUDE_PATH . '/openssl/opensslv.h')) {
|
||||
if (preg_match('/OPENSSL_VERSION_STR "(.*)"/', FileSystem::readFile(BUILD_INCLUDE_PATH . '/openssl/opensslv.h'), $match)) {
|
||||
return $match[1];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
32
src/SPC/builder/unix/library/re2c.php
Normal file
32
src/SPC/builder/unix/library/re2c.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\util\executor\UnixCMakeExecutor;
|
||||
|
||||
trait re2c
|
||||
{
|
||||
protected function build(): void
|
||||
{
|
||||
UnixCMakeExecutor::create($this)
|
||||
->addConfigureArgs(
|
||||
'-DRE2C_BUILD_TESTS=OFF',
|
||||
'-DRE2C_BUILD_EXAMPLES=OFF',
|
||||
'-DRE2C_BUILD_DOCS=OFF',
|
||||
'-DRE2C_BUILD_RE2D=OFF',
|
||||
'-DRE2C_BUILD_RE2GO=OFF',
|
||||
'-DRE2C_BUILD_RE2HS=OFF',
|
||||
'-DRE2C_BUILD_RE2JAVA=OFF',
|
||||
'-DRE2C_BUILD_RE2JS=OFF',
|
||||
'-DRE2C_BUILD_RE2OCAML=OFF',
|
||||
'-DRE2C_BUILD_RE2PY=OFF',
|
||||
'-DRE2C_BUILD_RE2RUST=OFF',
|
||||
'-DRE2C_BUILD_RE2SWIFT=OFF',
|
||||
'-DRE2C_BUILD_RE2V=OFF',
|
||||
'-DRE2C_BUILD_RE2ZIG=OFF',
|
||||
)
|
||||
->build();
|
||||
}
|
||||
}
|
||||
@ -89,6 +89,9 @@ class WindowsBuilder extends BuilderBase
|
||||
}
|
||||
}
|
||||
|
||||
$opcache_jit = !$this->getOption('disable-opcache-jit', false);
|
||||
$opcache_jit_arg = $opcache_jit ? '--enable-opcache-jit=yes ' : '--enable-opcache-jit=no ';
|
||||
|
||||
if (($logo = $this->getOption('with-micro-logo')) !== null) {
|
||||
// realpath
|
||||
// $logo = realpath($logo);
|
||||
@ -115,6 +118,7 @@ class WindowsBuilder extends BuilderBase
|
||||
($enableMicro ? ('--enable-micro=yes ' . $micro_logo . $micro_w32) : '--enable-micro=no ') .
|
||||
($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
|
||||
$config_file_scan_dir .
|
||||
$opcache_jit_arg .
|
||||
"{$this->makeStaticExtensionArgs()} " .
|
||||
$zts .
|
||||
'"'
|
||||
|
||||
@ -159,7 +159,7 @@ class BuildPHPCommand extends BuildCommand
|
||||
$indent_texts['UPX Pack'] = 'enabled';
|
||||
}
|
||||
|
||||
$ver = $builder->getPHPVersionFromArchive() ?: $builder->getPHPVersion();
|
||||
$ver = $builder->getPHPVersionFromArchive() ?: $builder->getPHPVersion(false);
|
||||
$indent_texts['PHP Version'] = $ver;
|
||||
|
||||
if (!empty($not_included)) {
|
||||
@ -269,6 +269,7 @@ class BuildPHPCommand extends BuildCommand
|
||||
} catch (WrongUsageException $e) {
|
||||
// WrongUsageException is not an exception, it's a user error, so we just print the error message
|
||||
logger()->critical($e->getMessage());
|
||||
logger()->error($e->getTraceAsString());
|
||||
return static::FAILURE;
|
||||
} catch (\Throwable $e) {
|
||||
if ($this->getOption('debug')) {
|
||||
|
||||
@ -108,12 +108,9 @@ class DownloadCommand extends BaseCommand
|
||||
// Define PHP major version
|
||||
$ver = $this->php_major_ver = $this->getOption('with-php');
|
||||
define('SPC_BUILD_PHP_VERSION', $ver);
|
||||
// match x.y
|
||||
preg_match('/^\d+\.\d+$/', $ver, $matches);
|
||||
if (!$matches) {
|
||||
// match x.y.z
|
||||
preg_match('/^\d+\.\d+\.\d+$/', $ver, $matches);
|
||||
if (!$matches) {
|
||||
if ($ver !== 'git' && !preg_match('/^\d+\.\d+$/', $ver)) {
|
||||
// If not git, we need to check the version format
|
||||
if (!preg_match('/^\d+\.\d+(\.\d+)?$/', $ver)) {
|
||||
logger()->error("bad version arg: {$ver}, x.y or x.y.z required!");
|
||||
return static::FAILURE;
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ use SPC\builder\BuilderProvider;
|
||||
use SPC\command\BaseCommand;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\util\DependencyUtil;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@ -41,7 +42,10 @@ class LibVerCommand extends BaseCommand
|
||||
return static::FAILURE;
|
||||
}
|
||||
|
||||
$builder->proveLibs([$this->getArgument('library')]);
|
||||
// parse the dependencies
|
||||
[, $libs] = DependencyUtil::getExtsAndLibs([], [$this->getArgument('library')]);
|
||||
|
||||
$builder->proveLibs($libs);
|
||||
|
||||
// Check whether lib is extracted
|
||||
if (!is_dir(SOURCE_PATH . '/' . $this->getArgument('library'))) {
|
||||
@ -51,7 +55,7 @@ class LibVerCommand extends BaseCommand
|
||||
|
||||
$version = $builder->getLib($this->getArgument('library'))->getLibVersion();
|
||||
if ($version === null) {
|
||||
$this->output->writeln("<error>Failed to get version of library {$this->getArgument('library')}</error>");
|
||||
$this->output->writeln("<error>Failed to get version of library {$this->getArgument('library')}. The version getter for [{$this->getArgument('library')}] is not implemented.</error>");
|
||||
return static::FAILURE;
|
||||
}
|
||||
$this->output->writeln("<info>{$version}</info>");
|
||||
|
||||
@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\doctor;
|
||||
|
||||
#[\Attribute(\Attribute::TARGET_METHOD)]
|
||||
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||
class AsCheckItem
|
||||
{
|
||||
public mixed $callback = null;
|
||||
|
||||
@ -16,7 +16,7 @@ class LinuxToolCheckList
|
||||
use UnixSystemUtilTrait;
|
||||
|
||||
public const TOOLS_ALPINE = [
|
||||
'make', 'bison', 'flex',
|
||||
'make', 'bison', 're2c', 'flex',
|
||||
'git', 'autoconf', 'automake', 'gettext-dev',
|
||||
'tar', 'unzip', 'gzip',
|
||||
'bzip2', 'cmake', 'gcc',
|
||||
@ -26,7 +26,7 @@ class LinuxToolCheckList
|
||||
];
|
||||
|
||||
public const TOOLS_DEBIAN = [
|
||||
'make', 'bison', 'flex',
|
||||
'make', 'bison', 're2c', 'flex',
|
||||
'git', 'autoconf', 'automake', 'autopoint',
|
||||
'tar', 'unzip', 'gzip',
|
||||
'bzip2', 'cmake', 'patch',
|
||||
@ -35,7 +35,7 @@ class LinuxToolCheckList
|
||||
];
|
||||
|
||||
public const TOOLS_RHEL = [
|
||||
'perl', 'make', 'bison', 'flex',
|
||||
'perl', 'make', 'bison', 're2c', 'flex',
|
||||
'git', 'autoconf', 'automake',
|
||||
'tar', 'unzip', 'gzip', 'gcc',
|
||||
'bzip2', 'cmake', 'patch', 'which',
|
||||
|
||||
@ -19,6 +19,7 @@ class MacOSToolCheckList
|
||||
'curl',
|
||||
'make',
|
||||
'bison',
|
||||
're2c',
|
||||
'flex',
|
||||
'pkg-config',
|
||||
'git',
|
||||
@ -61,6 +62,30 @@ class MacOSToolCheckList
|
||||
return CheckResult::ok();
|
||||
}
|
||||
|
||||
#[AsCheckItem('if bison version is 3.0 or later', limit_os: 'Darwin')]
|
||||
public function checkBisonVersion(array $command_path = []): ?CheckResult
|
||||
{
|
||||
// if the bison command is /usr/bin/bison, it is the system bison that may be too old
|
||||
if (($bison = $this->findCommand('bison', $command_path)) === null) {
|
||||
return CheckResult::fail('bison is not installed or too old', 'build-tools', [['bison']]);
|
||||
}
|
||||
// check version: bison (GNU Bison) x.y(.z)
|
||||
$version = shell()->execWithResult("{$bison} --version", false);
|
||||
if (preg_match('/bison \(GNU Bison\) (\d+)\.(\d+)(?:\.(\d+))?/', $version[1][0], $matches)) {
|
||||
$major = (int) $matches[1];
|
||||
// major should be 3 or later
|
||||
if ($major < 3) {
|
||||
// find homebrew keg-only bison
|
||||
if ($command_path !== []) {
|
||||
return CheckResult::fail("Current {$bison} version is too old: " . $matches[0]);
|
||||
}
|
||||
return $this->checkBisonVersion(['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin']);
|
||||
}
|
||||
return CheckResult::ok($matches[0]);
|
||||
}
|
||||
return CheckResult::fail('bison version cannot be determined');
|
||||
}
|
||||
|
||||
#[AsFixItem('brew')]
|
||||
public function fixBrew(): bool
|
||||
{
|
||||
|
||||
53
src/SPC/doctor/item/Re2cVersionCheck.php
Normal file
53
src/SPC/doctor/item/Re2cVersionCheck.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\doctor\item;
|
||||
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||
use SPC\doctor\AsCheckItem;
|
||||
use SPC\doctor\AsFixItem;
|
||||
use SPC\doctor\CheckResult;
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\Downloader;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
|
||||
class Re2cVersionCheck
|
||||
{
|
||||
use UnixSystemUtilTrait;
|
||||
|
||||
#[AsCheckItem('if re2c version >= 1.0.3', limit_os: 'Linux', level: 20)]
|
||||
#[AsCheckItem('if re2c version >= 1.0.3', limit_os: 'Darwin', level: 20)]
|
||||
public function checkRe2cVersion(): ?CheckResult
|
||||
{
|
||||
$ver = shell(false)->execWithResult('re2c --version', false);
|
||||
// match version: re2c X.X(.X)
|
||||
if ($ver[0] !== 0 || !preg_match('/re2c\s+(\d+\.\d+(\.\d+)?)/', $ver[1][0], $matches)) {
|
||||
return CheckResult::fail('Failed to get re2c version', 'build-re2c');
|
||||
}
|
||||
$version_string = $matches[1];
|
||||
if (version_compare($version_string, '1.0.3') < 0) {
|
||||
return CheckResult::fail('re2c version is too low (' . $version_string . ')', 'build-re2c');
|
||||
}
|
||||
return CheckResult::ok($version_string);
|
||||
}
|
||||
|
||||
#[AsFixItem('build-re2c')]
|
||||
public function buildRe2c(): bool
|
||||
{
|
||||
try {
|
||||
Downloader::downloadSource('re2c');
|
||||
} catch (DownloaderException) {
|
||||
logger()->warning('Failed to download re2c version, trying alternative');
|
||||
$alt = Config::getSource('re2c');
|
||||
$alt = [...$alt, ...$alt['alt'] ?? []];
|
||||
Downloader::downloadSource('re2c', $alt);
|
||||
}
|
||||
$builder = BuilderProvider::makeBuilderByInput(new ArgvInput([]));
|
||||
$builder->proveLibs(['re2c']);
|
||||
$builder->setupLibs();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -10,20 +10,6 @@ class ExceptionHandler
|
||||
|
||||
private static ?ExceptionHandler $obj = null;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
$whoops_class = 'Whoops\Run';
|
||||
$collision_class = 'NunoMaduro\Collision\Handler';
|
||||
if (class_exists($collision_class) && class_exists($whoops_class)) {
|
||||
/* @phpstan-ignore-next-line */
|
||||
$this->whoops = new $whoops_class();
|
||||
$this->whoops->allowQuit(false);
|
||||
$this->whoops->writeToOutput(false);
|
||||
$this->whoops->pushHandler(new $collision_class());
|
||||
$this->whoops->register();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getInstance(): ExceptionHandler
|
||||
{
|
||||
if (self::$obj === null) {
|
||||
@ -34,13 +20,8 @@ class ExceptionHandler
|
||||
|
||||
public function handle(\Throwable $e): void
|
||||
{
|
||||
if (is_null($this->whoops)) {
|
||||
logger()->error('Uncaught ' . get_class($e) . ': ' . $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')');
|
||||
logger()->error($e->getTraceAsString());
|
||||
return;
|
||||
}
|
||||
$this->whoops->handleException($e);
|
||||
|
||||
logger()->error('Uncaught ' . get_class($e) . ': ' . $e->getMessage() . ' at ' . $e->getFile() . '(' . $e->getLine() . ')');
|
||||
logger()->error($e->getTraceAsString());
|
||||
logger()->critical('You can report this exception to static-php-cli GitHub repo.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ namespace SPC\store;
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\builder\unix\UnixBuilderBase;
|
||||
use SPC\builder\windows\WindowsBuilder;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
@ -68,6 +69,35 @@ class SourcePatcher
|
||||
);
|
||||
}
|
||||
|
||||
// Fix PHP VS version
|
||||
if ($builder instanceof WindowsBuilder) {
|
||||
// get vs version
|
||||
$vc = \SPC\builder\windows\SystemUtil::findVisualStudio();
|
||||
$vc_matches = match ($vc['version']) {
|
||||
'vs17' => ['VS17', 'Visual C++ 2022'],
|
||||
'vs16' => ['VS16', 'Visual C++ 2019'],
|
||||
default => ['unknown', 'unknown'],
|
||||
};
|
||||
// patch php-src/win32/build/confutils.js
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '\php-src\win32\build\confutils.js',
|
||||
'var name = "unknown";',
|
||||
"var name = short ? \"{$vc_matches[0]}\" : \"{$vc_matches[1]}\";return name;"
|
||||
);
|
||||
}
|
||||
|
||||
// patch configure.ac
|
||||
$musl = SPCTarget::getLibc() === 'musl';
|
||||
FileSystem::backupFile(SOURCE_PATH . '/php-src/configure.ac');
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/configure.ac',
|
||||
'if command -v ldd >/dev/null && ldd --version 2>&1 | grep ^musl >/dev/null 2>&1',
|
||||
'if ' . ($musl ? 'true' : 'false')
|
||||
);
|
||||
if (getenv('SPC_LIBC') === false && ($libc = SPCTarget::getLibc()) !== null) {
|
||||
putenv("SPC_LIBC={$libc}");
|
||||
}
|
||||
|
||||
// patch php-src/build/php.m4 PKG_CHECK_MODULES -> PKG_CHECK_MODULES_STATIC
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/build/php.m4', 'PKG_CHECK_MODULES(', 'PKG_CHECK_MODULES_STATIC(');
|
||||
|
||||
@ -87,7 +117,8 @@ class SourcePatcher
|
||||
public static function patchBeforeConfigure(BuilderBase $builder): void
|
||||
{
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeConfigure() === true) {
|
||||
$patch = $builder instanceof WindowsBuilder ? $ext->patchBeforeWindowsConfigure() : $ext->patchBeforeConfigure();
|
||||
if ($patch === true) {
|
||||
logger()->info("Extension [{$ext->getName()}] patched before configure");
|
||||
}
|
||||
}
|
||||
@ -97,7 +128,14 @@ class SourcePatcher
|
||||
}
|
||||
}
|
||||
// patch capstone
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/have_capstone="yes"/', 'have_capstone="no"');
|
||||
if (is_unix()) {
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/have_capstone="yes"/', 'have_capstone="no"');
|
||||
}
|
||||
|
||||
if (file_exists(SOURCE_PATH . '/php-src/configure.ac.bak')) {
|
||||
// restore configure.ac
|
||||
FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/configure.ac');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,7 +170,7 @@ class SourcePatcher
|
||||
}
|
||||
$patch_list = $spc_micro_patches;
|
||||
$patches = [];
|
||||
$serial = ['80', '81', '82', '83', '84'];
|
||||
$serial = ['80', '81', '82', '83', '84', '85'];
|
||||
foreach ($patch_list as $patchName) {
|
||||
if (file_exists(SOURCE_PATH . "/php-src/sapi/micro/patches/{$patchName}.patch")) {
|
||||
$patches[] = "sapi/micro/patches/{$patchName}.patch";
|
||||
@ -584,7 +622,7 @@ class SourcePatcher
|
||||
*/
|
||||
public static function patchSPCVersionToPHP(string $version = 'unknown'): void
|
||||
{
|
||||
// detect patch
|
||||
// detect patch (remove this when 8.3 deprecated)
|
||||
$file = FileSystem::readFile(SOURCE_PATH . '/php-src/main/main.c');
|
||||
if (!str_contains($file, 'static-php-cli.version')) {
|
||||
logger()->debug('Inserting static-php-cli.version to php-src');
|
||||
|
||||
@ -21,8 +21,14 @@ class PhpSource extends CustomSourceBase
|
||||
*/
|
||||
public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_DOWNLOAD_SOURCE): void
|
||||
{
|
||||
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.3';
|
||||
Downloader::downloadSource('php-src', $this->getLatestPHPInfo($major), $force);
|
||||
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.4';
|
||||
if ($major === '8.5') {
|
||||
Downloader::downloadSource('php-src', ['type' => 'url', 'url' => 'https://downloads.php.net/~daniels/php-8.5.0alpha4.tar.xz'], $force);
|
||||
} elseif ($major === 'git') {
|
||||
Downloader::downloadSource('php-src', ['type' => 'git', 'url' => 'https://github.com/php/php-src.git', 'rev' => 'master'], $force);
|
||||
} else {
|
||||
Downloader::downloadSource('php-src', self::getLatestPHPInfo($major), $force);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,7 +42,7 @@ class PhpSource extends CustomSourceBase
|
||||
// 查找最新的小版本号
|
||||
$info = json_decode(Downloader::curlExec(
|
||||
url: "https://www.php.net/releases/index.php?json&version={$major_version}",
|
||||
retries: (int) getenv('SPC_DOWNLOAD_RETRIES')
|
||||
retries: intval(getenv('SPC_DOWNLOAD_RETRIES') ?: 0)
|
||||
), true);
|
||||
if (!isset($info['version'])) {
|
||||
throw new DownloaderException("Version {$major_version} not found.");
|
||||
|
||||
@ -7,6 +7,7 @@ namespace SPC\toolchain;
|
||||
use SPC\builder\freebsd\SystemUtil as FreeBSDSystemUtil;
|
||||
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
@ -37,8 +38,19 @@ class ClangNativeToolchain implements ToolchainInterface
|
||||
'Linux' => LinuxSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."),
|
||||
'Darwin' => MacOSSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."),
|
||||
'BSD' => FreeBSDSystemUtil::findCommand($command) ?? throw new WrongUsageException("{$command} not found, please install it or set {$env} to a valid path."),
|
||||
default => throw new \RuntimeException(__CLASS__ . ' is not supported on ' . PHP_OS_FAMILY . '.'),
|
||||
default => throw new RuntimeException(__CLASS__ . ' is not supported on ' . PHP_OS_FAMILY . '.'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public function getCompilerInfo(): ?string
|
||||
{
|
||||
$compiler = getenv('CC') ?: 'clang';
|
||||
$version = shell(false)->execWithResult("{$compiler} --version", false);
|
||||
$head = pathinfo($compiler, PATHINFO_BASENAME);
|
||||
if ($version[0] === 0 && preg_match('/clang version (\d+.\d+.\d+)/', $version[1][0], $match)) {
|
||||
return "{$head} {$match[1]}";
|
||||
}
|
||||
return $head;
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,4 +35,15 @@ class GccNativeToolchain implements ToolchainInterface
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public function getCompilerInfo(): ?string
|
||||
{
|
||||
$compiler = getenv('CC') ?: 'gcc';
|
||||
$version = shell(false)->execWithResult("{$compiler} --version", false);
|
||||
$head = pathinfo($compiler, PATHINFO_BASENAME);
|
||||
if ($version[0] === 0 && preg_match('/gcc.*(\d+.\d+.\d+)/', $version[1][0], $match)) {
|
||||
return "{$head} {$match[1]}";
|
||||
}
|
||||
return $head;
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,4 +9,9 @@ class MSVCToolchain implements ToolchainInterface
|
||||
public function initEnv(): void {}
|
||||
|
||||
public function afterInit(): void {}
|
||||
|
||||
public function getCompilerInfo(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,4 +36,15 @@ class MuslToolchain implements ToolchainInterface
|
||||
throw new WrongUsageException('You are building with musl-libc target in glibc distro, but musl-toolchain is not installed, please install musl-toolchain first. (You can use `doctor` command to install it)');
|
||||
}
|
||||
}
|
||||
|
||||
public function getCompilerInfo(): ?string
|
||||
{
|
||||
$compiler = getenv('CC') ?: getenv('SPC_LINUX_DEFAULT_CC');
|
||||
$version = shell(false)->execWithResult("{$compiler} --version", false);
|
||||
$head = pathinfo($compiler, PATHINFO_BASENAME);
|
||||
if ($version[0] === 0 && preg_match('/linux-musl-cc.*(\d+.\d+.\d+)/', $version[1][0], $match)) {
|
||||
return "{$head} {$match[1]}";
|
||||
}
|
||||
return $head;
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,4 +27,12 @@ interface ToolchainInterface
|
||||
* post-initialization setup or validation.
|
||||
*/
|
||||
public function afterInit(): void;
|
||||
|
||||
/**
|
||||
* Returns the compiler name and version for toolchains.
|
||||
*
|
||||
* If the toolchain does not support compiler information,
|
||||
* this method can return null.
|
||||
*/
|
||||
public function getCompilerInfo(): ?string;
|
||||
}
|
||||
|
||||
@ -61,6 +61,10 @@ class ToolchainManager
|
||||
}
|
||||
$toolchain = getenv('SPC_TOOLCHAIN');
|
||||
/* @var ToolchainInterface $toolchain */
|
||||
(new $toolchain())->afterInit();
|
||||
$instance = new $toolchain();
|
||||
$instance->afterInit();
|
||||
if (getenv('PHP_BUILD_COMPILER') === false && ($compiler_info = $instance->getCompilerInfo())) {
|
||||
GlobalEnvManager::putenv("PHP_BUILD_COMPILER={$compiler_info}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,4 +68,10 @@ class ZigToolchain implements ToolchainInterface
|
||||
GlobalEnvManager::putenv("SPC_EXTRA_LIBS={$extra_libs}");
|
||||
}
|
||||
}
|
||||
|
||||
public function getCompilerInfo(): ?string
|
||||
{
|
||||
$version = shell(false)->execWithResult('zig version', false)[1][0] ?? '';
|
||||
return trim("zig {$version}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,20 +47,20 @@ class ConfigValidator
|
||||
|
||||
// check if license is valid
|
||||
if (isset($src['license'])) {
|
||||
if (!is_assoc_array($src['license'])) {
|
||||
throw new ValidationException("source {$name} license must be object");
|
||||
if (!is_array($src['license'])) {
|
||||
throw new ValidationException("source {$name} license must be an object or array");
|
||||
}
|
||||
if (!isset($src['license']['type'])) {
|
||||
throw new ValidationException("source {$name} license must have type");
|
||||
}
|
||||
if (!in_array($src['license']['type'], ['file', 'text'])) {
|
||||
throw new ValidationException("source {$name} license type is invalid");
|
||||
}
|
||||
if ($src['license']['type'] === 'file' && !isset($src['license']['path'])) {
|
||||
throw new ValidationException("source {$name} license file must have path");
|
||||
}
|
||||
if ($src['license']['type'] === 'text' && !isset($src['license']['text'])) {
|
||||
throw new ValidationException("source {$name} license text must have text");
|
||||
if (is_assoc_array($src['license'])) {
|
||||
self::checkSingleLicense($src['license'], $name);
|
||||
} elseif (is_list_array($src['license'])) {
|
||||
foreach ($src['license'] as $license) {
|
||||
if (!is_assoc_array($license)) {
|
||||
throw new ValidationException("source {$name} license must be an object or array");
|
||||
}
|
||||
self::checkSingleLicense($license, $name);
|
||||
}
|
||||
} else {
|
||||
throw new ValidationException("source {$name} license must be an object or array");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -415,6 +415,31 @@ class ConfigValidator
|
||||
return $craft;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ValidationException
|
||||
*/
|
||||
private static function checkSingleLicense(array $license, string $name): void
|
||||
{
|
||||
if (!is_assoc_array($license)) {
|
||||
throw new ValidationException("source {$name} license must be an object");
|
||||
}
|
||||
if (!isset($license['type'])) {
|
||||
throw new ValidationException("source {$name} license must have type");
|
||||
}
|
||||
if (!in_array($license['type'], ['file', 'text'])) {
|
||||
throw new ValidationException("source {$name} license type is invalid");
|
||||
}
|
||||
if (!in_array($license['type'], ['file', 'text'])) {
|
||||
throw new ValidationException("source {$name} license type is invalid");
|
||||
}
|
||||
if ($license['type'] === 'file' && !isset($license['path'])) {
|
||||
throw new ValidationException("source {$name} license file must have path");
|
||||
}
|
||||
if ($license['type'] === 'text' && !isset($license['text'])) {
|
||||
throw new ValidationException("source {$name} license text must have text");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate source type configuration (shared between source.json and pkg.json)
|
||||
*
|
||||
|
||||
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\builder\macos\SystemUtil;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
@ -117,6 +118,15 @@ class GlobalEnvManager
|
||||
if (!filter_var(getenv('SPC_SKIP_TOOLCHAIN_CHECK'), FILTER_VALIDATE_BOOL)) {
|
||||
ToolchainManager::afterInitToolchain();
|
||||
}
|
||||
// test bison
|
||||
if (PHP_OS_FAMILY === 'Darwin') {
|
||||
if ($bison = SystemUtil::findCommand('bison', ['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin'])) {
|
||||
self::putenv("BISON={$bison}");
|
||||
}
|
||||
if ($yacc = SystemUtil::findCommand('yacc', ['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin'])) {
|
||||
self::putenv("YACC={$yacc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -14,6 +14,21 @@ use SPC\exception\RuntimeException;
|
||||
*/
|
||||
class PkgConfigUtil
|
||||
{
|
||||
/**
|
||||
* Returns the version of a module.
|
||||
* This method uses `pkg-config --modversion` to get the version of the specified module.
|
||||
* If the module is not found, it will throw a RuntimeException.
|
||||
*
|
||||
* @param string $pkg_config_str .pc file str, accepts multiple files
|
||||
* @return string version string, e.g. "1.2.3"
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function getModuleVersion(string $pkg_config_str): string
|
||||
{
|
||||
$result = self::execWithResult("pkg-config --modversion {$pkg_config_str}");
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CFLAGS from pkg-config
|
||||
*
|
||||
|
||||
@ -99,8 +99,11 @@ class SPCTarget
|
||||
*/
|
||||
public static function getLibcVersion(): ?string
|
||||
{
|
||||
$libc = self::getLibc();
|
||||
return SystemUtil::getLibcVersionIfExists($libc);
|
||||
if (PHP_OS_FAMILY === 'Linux') {
|
||||
$libc = self::getLibc();
|
||||
return SystemUtil::getLibcVersionIfExists($libc);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -6,13 +6,27 @@ assert(function_exists('curl_init'));
|
||||
assert(function_exists('curl_setopt'));
|
||||
assert(function_exists('curl_exec'));
|
||||
assert(function_exists('curl_close'));
|
||||
assert(function_exists('curl_version'));
|
||||
$curl_version = curl_version();
|
||||
if (stripos($curl_version['ssl_version'], 'schannel') !== false) {
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, 'https://captive.apple.com/');
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HEADER, 0);
|
||||
$data = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
assert($data !== false);
|
||||
$domain_list = [
|
||||
'https://captive.apple.com/',
|
||||
'https://detectportal.firefox.com/',
|
||||
'https://static-php.dev/',
|
||||
'https://www.example.com/',
|
||||
];
|
||||
$valid = false;
|
||||
foreach ($domain_list as $domain) {
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $domain);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HEADER, 0);
|
||||
$data = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
if ($data !== false) {
|
||||
$valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert($valid);
|
||||
}
|
||||
|
||||
@ -5,5 +5,32 @@ declare(strict_types=1);
|
||||
assert(function_exists('openssl_digest'));
|
||||
assert(openssl_digest('123456', 'md5') === 'e10adc3949ba59abbe56e057f20f883e');
|
||||
if (file_exists('/etc/ssl/openssl.cnf')) {
|
||||
assert(file_get_contents('https://captive.apple.com/') !== false);
|
||||
$domain_list = [
|
||||
'captive.apple.com',
|
||||
'detectportal.firefox.com',
|
||||
'static-php.dev',
|
||||
'www.example.com',
|
||||
];
|
||||
$valid = false;
|
||||
foreach ($domain_list as $domain) {
|
||||
$ssloptions = [
|
||||
'capture_peer_cert' => true,
|
||||
'capture_peer_cert_chain' => true,
|
||||
'allow_self_signed' => false,
|
||||
'CN_match' => $domain,
|
||||
'verify_peer' => true,
|
||||
'SNI_enabled' => true,
|
||||
'SNI_server_name' => $domain,
|
||||
];
|
||||
$context = stream_context_create(['ssl' => $ssloptions]);
|
||||
$result = stream_socket_client("ssl://{$domain}:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $context);
|
||||
if ($result !== false) {
|
||||
$valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert($valid);
|
||||
}
|
||||
if (PHP_VERSION_ID >= 80500 && defined('OPENSSL_VERSION_NUMBER') && OPENSSL_VERSION_NUMBER >= 0x30200000) {
|
||||
assert(function_exists('openssl_password_hash'));
|
||||
}
|
||||
|
||||
@ -6,9 +6,12 @@ use SPC\builder\freebsd\SystemUtil as BSDSystemUtil;
|
||||
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||
use SPC\builder\windows\SystemUtil as WindowsSystemUtil;
|
||||
use SPC\ConsoleApplication;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
// static-php-cli version string
|
||||
const SPC_VERSION = ConsoleApplication::VERSION;
|
||||
// output path for everything, other paths are defined relative to this by default
|
||||
define('BUILD_ROOT_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_ROOT_PATH')) ? $a : (WORKING_DIR . '/buildroot')));
|
||||
// output path for header files for development
|
||||
@ -44,6 +47,7 @@ define('SEPARATED_PATH', [
|
||||
]);
|
||||
|
||||
// add these to env vars with same name
|
||||
GlobalEnvManager::putenv('SPC_VERSION=' . SPC_VERSION);
|
||||
GlobalEnvManager::putenv('BUILD_ROOT_PATH=' . BUILD_ROOT_PATH);
|
||||
GlobalEnvManager::putenv('BUILD_INCLUDE_PATH=' . BUILD_INCLUDE_PATH);
|
||||
GlobalEnvManager::putenv('BUILD_LIB_PATH=' . BUILD_LIB_PATH);
|
||||
|
||||
@ -17,15 +17,17 @@ $test_php_version = [
|
||||
// '8.2',
|
||||
// '8.3',
|
||||
'8.4',
|
||||
// '8.5',
|
||||
'git',
|
||||
];
|
||||
|
||||
// test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available)
|
||||
$test_os = [
|
||||
'macos-13', // bin/spc for x86_64
|
||||
// 'macos-13', // bin/spc for x86_64
|
||||
// 'macos-14', // bin/spc for arm64
|
||||
'macos-15', // bin/spc for arm64
|
||||
// 'ubuntu-latest', // bin/spc-alpine-docker for x86_64
|
||||
'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
|
||||
// 'macos-15', // bin/spc for arm64
|
||||
'ubuntu-latest', // bin/spc-alpine-docker for x86_64
|
||||
// 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
|
||||
'ubuntu-24.04', // bin/spc for x86_64
|
||||
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
|
||||
'ubuntu-24.04-arm', // bin/spc for arm64
|
||||
@ -41,15 +43,15 @@ $no_strip = false;
|
||||
$upx = false;
|
||||
|
||||
// whether to test frankenphp build, only available for macos and linux
|
||||
$frankenphp = true;
|
||||
$frankenphp = false;
|
||||
|
||||
// prefer downloading pre-built packages to speed up the build process
|
||||
$prefer_pre_built = false;
|
||||
|
||||
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
|
||||
$extensions = match (PHP_OS_FAMILY) {
|
||||
'Linux', 'Darwin' => 'ast,bcmath,calendar,ctype,dba,dom,exif,fileinfo,filter,libxml,mbregex,mbstring,pcntl,phar,posix,session,simplexml,sockets,sodium,tokenizer,xml,xmlreader,xmlwriter,zlib',
|
||||
'Windows' => 'intl',
|
||||
'Linux', 'Darwin' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pdo,pdo_mysql,pdo_sqlite,phar,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip',
|
||||
'Windows' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pdo,pdo_mysql,pdo_sqlite,phar,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip',
|
||||
};
|
||||
|
||||
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
|
||||
@ -60,7 +62,7 @@ $shared_extensions = match (PHP_OS_FAMILY) {
|
||||
};
|
||||
|
||||
// If you want to test lib-suggests for all extensions and libraries, set it to true.
|
||||
$with_suggested_libs = true;
|
||||
$with_suggested_libs = false;
|
||||
|
||||
// If you want to test extra libs for extensions, add them below (comma separated, example `libwebp,libavif`). Unnecessary, when $with_suggested_libs is true.
|
||||
$with_libs = match (PHP_OS_FAMILY) {
|
||||
@ -72,7 +74,7 @@ $with_libs = match (PHP_OS_FAMILY) {
|
||||
// You can use `common`, `bulk`, `minimal` or `none`.
|
||||
// note: combination is only available for *nix platform. Windows must use `none` combination
|
||||
$base_combination = match (PHP_OS_FAMILY) {
|
||||
'Linux', 'Darwin' => 'minimal',
|
||||
'Linux', 'Darwin' => 'none',
|
||||
'Windows' => 'none',
|
||||
};
|
||||
|
||||
|
||||
@ -19,6 +19,10 @@ final class PkgConfigUtilTest extends TestCase
|
||||
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
// Skip tests on Windows as pkg-config is not typically available
|
||||
self::markTestSkipped('PkgConfigUtil tests are not applicable on Windows.');
|
||||
}
|
||||
parent::setUpBeforeClass();
|
||||
|
||||
// Save original PATH
|
||||
|
||||
@ -21,6 +21,10 @@ class SPCConfigUtilTest extends TestCase
|
||||
*/
|
||||
public static function setUpBeforeClass(): void
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
// Skip tests on Windows as SPCConfigUtil is not applicable
|
||||
self::markTestSkipped('SPCConfigUtil tests are not applicable on Windows.');
|
||||
}
|
||||
$testdir = WORKING_DIR . '/.configtest';
|
||||
FileSystem::createDir($testdir);
|
||||
FileSystem::writeFile($testdir . '/lib.json', file_get_contents(ROOT_DIR . '/config/lib.json'));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user