mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-03 06:45:39 +08:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a03c32bc0 | ||
|
|
0b8a0504a2 | ||
|
|
e9aff8f1d8 | ||
|
|
93cb7e9fbb | ||
|
|
2d2607cd7f | ||
|
|
d80406b8e0 | ||
|
|
db9645641f | ||
|
|
b3018af61c | ||
|
|
7e6c2b4432 | ||
|
|
1ae1c81f9c | ||
|
|
eff698cbe8 | ||
|
|
036e4f52b7 | ||
|
|
d258417afb | ||
|
|
3057d02e37 | ||
|
|
af8204fbf0 | ||
|
|
968b3acbce | ||
|
|
5d2bd93bd7 | ||
|
|
4ba92b08ca | ||
|
|
11076b1355 | ||
|
|
71770a0a5f | ||
|
|
98d3766fe8 | ||
|
|
1fdb6b439e | ||
|
|
3136d6edc1 | ||
|
|
3e84becf77 | ||
|
|
1632c25223 | ||
|
|
e6c308c242 |
11
.github/workflows/release-build.yml
vendored
11
.github/workflows/release-build.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
jobs:
|
||||
build-release-artifacts:
|
||||
name: "Build SPC Binary"
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: macos-14
|
||||
strategy:
|
||||
matrix:
|
||||
php-version:
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: "Cache Composer dependencies"
|
||||
uses: "actions/cache@v3"
|
||||
uses: "actions/cache@v4"
|
||||
with:
|
||||
path: "${{ steps.composer-cache.outputs.dir }}"
|
||||
key: "php-${{ matrix.php-version }}-locked-composer-${{ hashFiles('**/composer.lock') }}"
|
||||
@@ -76,6 +76,9 @@ jobs:
|
||||
else
|
||||
chmod +x spc
|
||||
fi
|
||||
if [ "${{ matrix.operating-system }}" = "macos-aarch64" ] || [ "${{ matrix.operating-system }}" = "macos-x86_64" ]; then
|
||||
sudo xattr -cr ./spc
|
||||
fi
|
||||
|
||||
- name: "Archive Executable"
|
||||
run: |
|
||||
@@ -83,7 +86,7 @@ jobs:
|
||||
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
|
||||
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
|
||||
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
|
||||
if [ "${{ matrix.operating-system }}" == "linux-x86_64" ]; then
|
||||
if [ "${{ matrix.operating-system }}" == "macos-aarch64" ]; then
|
||||
./spc dev:extensions
|
||||
fi
|
||||
else
|
||||
@@ -119,7 +122,7 @@ jobs:
|
||||
TARGET: ${{ secrets.DEPLOY_SERVER_TARGET_SPC_NIGHTLY }}
|
||||
|
||||
- name: "Upload Artifact"
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: spc${{ env.SUFFIX }}
|
||||
name: spc-${{ matrix.operating-system }}${{ env.SUFFIX }}
|
||||
|
||||
54
.github/workflows/tests.yml
vendored
54
.github/workflows/tests.yml
vendored
@@ -12,6 +12,9 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
php-cs-fixer:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -48,7 +51,7 @@ jobs:
|
||||
|
||||
- name: "Cache Composer packages"
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -86,7 +89,7 @@ jobs:
|
||||
|
||||
- name: "Cache Composer packages"
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -113,7 +116,7 @@ jobs:
|
||||
- "8.3"
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-latest
|
||||
- macos-13
|
||||
- windows-latest
|
||||
- macos-14
|
||||
fail-fast: false
|
||||
@@ -129,16 +132,9 @@ jobs:
|
||||
extensions: curl, openssl, mbstring
|
||||
ini-values: memory_limit=-1
|
||||
|
||||
- name: "Use test token if exists"
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: |
|
||||
if [ "${{ secrets.TEST_GH_TOKEN }}" != "" ]; then
|
||||
echo "GITHUB_TOKEN=${{ secrets.TEST_GH_TOKEN }}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: "Cache Composer packages"
|
||||
- name: "Cache composer packages"
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -147,7 +143,7 @@ jobs:
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ matrix.php }}-dependencies
|
||||
@@ -158,14 +154,26 @@ jobs:
|
||||
- name: "Run Build Tests (doctor)"
|
||||
run: bin/spc doctor --auto-fix
|
||||
|
||||
- name: "Run Build Tests (download)"
|
||||
uses: nick-fields/retry@v3
|
||||
with:
|
||||
timeout_minutes: 10
|
||||
max_attempts: 3
|
||||
retry_on: error
|
||||
command: |
|
||||
bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --for-libs="$(php src/globals/test-extensions.php libs)" --with-php=${{ matrix.php }} --ignore-cache-sources=php-src --debug --retry=3
|
||||
- name: "Prepare UPX for Windows"
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
bin/spc install-pkg upx
|
||||
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV
|
||||
|
||||
- name: "Run Build Tests (build)"
|
||||
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug
|
||||
- name: "Prepare UPX for Linux"
|
||||
if: matrix.os == 'ubunut-latest'
|
||||
run: |
|
||||
bin/spc install-pkg upx
|
||||
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV
|
||||
|
||||
- name: "Run Build Tests (download)"
|
||||
run: |
|
||||
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 --retry=5
|
||||
|
||||
- name: "Run Build Tests (build, *nix)"
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug
|
||||
|
||||
- name: "Run Build Tests (build, windows)"
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $env:UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --debug --enable-micro-win32
|
||||
33
.github/workflows/update-docs-config.yml
vendored
33
.github/workflows/update-docs-config.yml
vendored
@@ -15,9 +15,6 @@ jobs:
|
||||
steps:
|
||||
- name: "Checkout static-php-cli"
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main
|
||||
path: static-php-cli
|
||||
|
||||
- name: "Checkout static-php-cli-docs"
|
||||
uses: actions/checkout@v4
|
||||
@@ -33,7 +30,35 @@ jobs:
|
||||
git config --global user.name "GitHub Actions"
|
||||
|
||||
- name: "Copy Config Files"
|
||||
run: cp -r static-php-cli/config/* static-php-cli-docs/docs/.vitepress/config/
|
||||
run: cp -r config/* static-php-cli-docs/docs/.vitepress/config/
|
||||
|
||||
- name: "Install PHP for official runners"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: none
|
||||
tools: composer:v2
|
||||
php-version: 8.2
|
||||
ini-values: memory_limit=-1
|
||||
|
||||
- name: "Get Composer Cache Directory"
|
||||
id: composer-cache
|
||||
run: |
|
||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: "Cache Composer dependencies"
|
||||
uses: "actions/cache@v4"
|
||||
with:
|
||||
path: "${{ steps.composer-cache.outputs.dir }}"
|
||||
key: "php-8.2-locked-composer-${{ hashFiles('**/composer.lock') }}"
|
||||
restore-keys: |
|
||||
php-8.2-locked-composer
|
||||
|
||||
- name: "Install Locked Dependencies"
|
||||
run: "composer install --no-interaction --no-progress"
|
||||
|
||||
- name: "Generate Extension Support List"
|
||||
run: |
|
||||
bin/spc dev:gen-ext-docs > static-php-cli-docs/docs/extensions.md
|
||||
|
||||
- name: "Commit and Push Changes"
|
||||
run: |
|
||||
|
||||
13
README-zh.md
13
README-zh.md
@@ -43,9 +43,12 @@ static-php-cli(简称 `spc`)有许多特性:
|
||||
|
||||
如果你不想自行编译 PHP,可以从本项目现有的示例 Action 下载 Artifact,也可以从自托管的服务器下载。
|
||||
|
||||
- [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/):common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 22MB 左右。
|
||||
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/):bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 70MB 左右。
|
||||
- [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/):minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 6MB 左右。
|
||||
- [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/):common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 7.5MB 左右。
|
||||
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/):bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 25MB 左右。
|
||||
- [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/):minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 3MB 左右。
|
||||
|
||||
> Linux 和 Windows 默认启用了 UPX 压缩,可减小 30~50% 的 PHP 二进制体积。
|
||||
> macOS 当前不支持 UPX,所以上述预编译的 macOS 版本体积可能较大。
|
||||
|
||||
对于 Windows 系统,目前支持的扩展较少,故仅提供 SPC 自身运行的最小扩展组合的 `cli` 和 `micro`:[扩展组合 - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/)。
|
||||
|
||||
@@ -71,7 +74,7 @@ static-php-cli(简称 `spc`)有许多特性:
|
||||
|
||||
当前支持编译的 PHP 版本:
|
||||
|
||||
> :warning: 支持,但可能不再提供修复
|
||||
> :warning: 支持,但 static-php-cli 作者可能不再提供补丁修复
|
||||
>
|
||||
> :heavy_check_mark: 支持
|
||||
>
|
||||
@@ -83,7 +86,7 @@ static-php-cli(简称 `spc`)有许多特性:
|
||||
| 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.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新 |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
|
||||
|
||||
13
README.md
13
README.md
@@ -49,9 +49,12 @@ If you don't want to build or want to test first, you can download example pre-c
|
||||
Below are several precompiled static-php binaries with different extension combinations,
|
||||
which can be downloaded directly according to your needs.
|
||||
|
||||
- [Extension-Combination - common](https://dl.static-php.dev/static-php-cli/common/): `common` contains about [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) commonly used extensions, and the size is about 22MB.
|
||||
- [Extension-Combination - bulk](https://dl.static-php.dev/static-php-cli/bulk/): `bulk` contains [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) extensions and is about 70MB in size.
|
||||
- [Extension-Combination - minimal](https://dl.static-php.dev/static-php-cli/minimal/): `minimal` contains [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) extensions and is about 6MB in size.
|
||||
- [Extension-Combination - common](https://dl.static-php.dev/static-php-cli/common/): `common` contains about [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) commonly used extensions, and the size is about 7.5MB.
|
||||
- [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 25MB 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 3MB in size.
|
||||
|
||||
> Linux and Windows supports UPX compression for binaries, which can reduce the size of the binary by 30% to 50%.
|
||||
> macOS does not support UPX compression, so the size of the pre-built binaries for mac is larger.
|
||||
|
||||
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/).
|
||||
@@ -79,7 +82,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
|
||||
> :warning: supported but not maintained by static-php-cli authors
|
||||
>
|
||||
> :heavy_check_mark: supported
|
||||
>
|
||||
@@ -91,7 +94,7 @@ Currently supported PHP versions for compilation:
|
||||
| 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.1 | :heavy_check_mark: | PHP official has security fixes only |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
|
||||
|
||||
1
box.json
1
box.json
@@ -4,6 +4,7 @@
|
||||
"blacklist": [
|
||||
".github"
|
||||
],
|
||||
"compression": "GZ",
|
||||
"directories": [
|
||||
"config",
|
||||
"src",
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
"zhamao/logger": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"captainhook/captainhook": "^5.10",
|
||||
"captainhook/plugin-composer": "^5.3",
|
||||
"captainhook/captainhook-phar": "^5.23",
|
||||
"captainhook/hook-installer": "^1.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.25",
|
||||
"humbug/box": "^4.5",
|
||||
"nunomaduro/collision": "^7.8",
|
||||
@@ -50,7 +50,9 @@
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"phpstan/extension-installer": true,
|
||||
"captainhook/plugin-composer": true
|
||||
"captainhook/hook-installer": true,
|
||||
"captainhook/plugin-composer": true,
|
||||
"captainhook/captainhook-phar": true
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
|
||||
1794
composer.lock
generated
1794
composer.lock
generated
File diff suppressed because it is too large
Load Diff
1639
config/ext.json
1639
config/ext.json
File diff suppressed because it is too large
Load Diff
1331
config/lib.json
1331
config/lib.json
File diff suppressed because it is too large
Load Diff
@@ -179,8 +179,12 @@
|
||||
}
|
||||
},
|
||||
"gmp": {
|
||||
"type": "ghtagtar",
|
||||
"repo": "alisw/GMP",
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/gmp/gmp-6.3.0.tar.xz",
|
||||
"alt": {
|
||||
"type": "ghtagtar",
|
||||
"repo": "alisw/GMP"
|
||||
},
|
||||
"license": {
|
||||
"type": "text",
|
||||
"text": "Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2. These licenses make the library free to use, share, and improve, and allow you to pass on the result. The GNU licenses give freedoms, but also set firm restrictions on the use with non-free programs."
|
||||
@@ -259,9 +263,14 @@
|
||||
}
|
||||
},
|
||||
"libcares": {
|
||||
"type": "filelist",
|
||||
"url": "https://c-ares.org/download/",
|
||||
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/",
|
||||
"type": "ghrel",
|
||||
"repo": "c-ares/c-ares",
|
||||
"match": "c-ares-.+\\.tar\\.gz",
|
||||
"alt": {
|
||||
"type": "filelist",
|
||||
"url": "https://c-ares.org/download/",
|
||||
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/"
|
||||
},
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE.md"
|
||||
@@ -463,7 +472,7 @@
|
||||
"type": "git",
|
||||
"path": "php-src/sapi/micro",
|
||||
"rev": "master",
|
||||
"url": "https://github.com/static-php/phpmicro",
|
||||
"url": "https://github.com/easysoft/phpmicro",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -515,6 +524,16 @@
|
||||
"path": "LICENSE.txt"
|
||||
}
|
||||
},
|
||||
"parallel": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/parallel",
|
||||
"path": "php-src/ext/parallel",
|
||||
"filename": "parallel.tgz",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"pdo_sqlsrv": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/pdo_sqlsrv",
|
||||
@@ -551,6 +570,15 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"pthreads4w": {
|
||||
"type": "git",
|
||||
"rev": "master",
|
||||
"url": "https://git.code.sf.net/p/pthreads4w/code",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"qdbm": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/static-php/qdbm.git",
|
||||
|
||||
@@ -13,6 +13,6 @@ parameters:
|
||||
- PHP_OS_FAMILY
|
||||
excludePaths:
|
||||
analyseAndScan:
|
||||
- ./src/globals/tests/swoole.php
|
||||
- ./src/globals/tests/swoole.phpt
|
||||
- ./src/globals/ext-tests/swoole.php
|
||||
- ./src/globals/ext-tests/swoole.phpt
|
||||
- ./src/globals/test-extensions.php
|
||||
@@ -8,6 +8,7 @@ use SPC\command\BuildCliCommand;
|
||||
use SPC\command\BuildLibsCommand;
|
||||
use SPC\command\DeleteDownloadCommand;
|
||||
use SPC\command\dev\AllExtCommand;
|
||||
use SPC\command\dev\GenerateExtDocCommand;
|
||||
use SPC\command\dev\PhpVerCommand;
|
||||
use SPC\command\dev\SortConfigCommand;
|
||||
use SPC\command\DoctorCommand;
|
||||
@@ -16,16 +17,15 @@ use SPC\command\DumpLicenseCommand;
|
||||
use SPC\command\ExtractCommand;
|
||||
use SPC\command\InstallPkgCommand;
|
||||
use SPC\command\MicroCombineCommand;
|
||||
use SPC\command\SwitchPhpVersionCommand;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Command\HelpCommand;
|
||||
use Symfony\Component\Console\Command\ListCommand;
|
||||
|
||||
/**
|
||||
* static-php-cli console app entry
|
||||
*/
|
||||
final class ConsoleApplication extends Application
|
||||
{
|
||||
public const VERSION = '2.2.0';
|
||||
public const VERSION = '2.2.4';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -43,17 +43,14 @@ final class ConsoleApplication extends Application
|
||||
new DumpLicenseCommand(),
|
||||
new ExtractCommand(),
|
||||
new MicroCombineCommand(),
|
||||
new SwitchPhpVersionCommand(),
|
||||
|
||||
// Dev commands
|
||||
new AllExtCommand(),
|
||||
new PhpVerCommand(),
|
||||
new SortConfigCommand(),
|
||||
new GenerateExtDocCommand(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function getDefaultCommands(): array
|
||||
{
|
||||
return [new HelpCommand(), new ListCommand()];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ 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\util\CustomExt;
|
||||
|
||||
@@ -33,7 +34,7 @@ abstract class BuilderBase
|
||||
protected string $patch_point = '';
|
||||
|
||||
/**
|
||||
* Build libraries
|
||||
* Convert libraries to class
|
||||
*
|
||||
* @param array<string> $sorted_libraries Libraries to build (if not empty, must sort first)
|
||||
* @throws FileSystemException
|
||||
@@ -41,7 +42,27 @@ abstract class BuilderBase
|
||||
* @throws WrongUsageException
|
||||
* @internal
|
||||
*/
|
||||
abstract public function buildLibs(array $sorted_libraries);
|
||||
abstract public function proveLibs(array $sorted_libraries);
|
||||
|
||||
/**
|
||||
* Build libraries
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function buildLibs(): void
|
||||
{
|
||||
// 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.
|
||||
@@ -255,6 +276,24 @@ abstract class BuilderBase
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getMicroVersion(): false|string
|
||||
{
|
||||
$file = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/php_micro.h');
|
||||
if (!file_exists($file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$content = file_get_contents($file);
|
||||
$ver = '';
|
||||
preg_match('/#define PHP_MICRO_VER_MAJ (\d)/m', $content, $match);
|
||||
$ver .= $match[1] . '.';
|
||||
preg_match('/#define PHP_MICRO_VER_MIN (\d)/m', $content, $match);
|
||||
$ver .= $match[1] . '.';
|
||||
preg_match('/#define PHP_MICRO_VER_PAT (\d)/m', $content, $match);
|
||||
$ver .= $match[1];
|
||||
return $ver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get build type name string to display.
|
||||
*
|
||||
@@ -335,6 +374,19 @@ abstract class BuilderBase
|
||||
return $this->patch_point;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate libs and exts can be compiled successfully in current environment
|
||||
*/
|
||||
public function validateLibsAndExts(): void
|
||||
{
|
||||
foreach ($this->libs as $lib) {
|
||||
$lib->validate();
|
||||
}
|
||||
foreach ($this->exts as $ext) {
|
||||
$ext->validate();
|
||||
}
|
||||
}
|
||||
|
||||
public function emitPatchPoint(string $point_name): void
|
||||
{
|
||||
$this->patch_point = $point_name;
|
||||
@@ -401,4 +453,29 @@ abstract class BuilderBase
|
||||
$php .= "echo '[micro-test-end]';\n";
|
||||
return $php;
|
||||
}
|
||||
|
||||
protected function getMicroTestTasks(): array
|
||||
{
|
||||
return [
|
||||
'micro_ext_test' => [
|
||||
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests()),
|
||||
'conditions' => [
|
||||
// program success
|
||||
function ($ret) { return $ret === 0; },
|
||||
// program returns expected output
|
||||
function ($ret, $out) {
|
||||
$raw_out = trim(implode('', $out));
|
||||
return str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
|
||||
},
|
||||
],
|
||||
],
|
||||
'micro_zend_bug_test' => [
|
||||
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "hello";' : file_get_contents(ROOT_DIR . '/src/globals/common-tests/micro_zend_mm_heap_corrupted.txt')),
|
||||
'conditions' => [
|
||||
// program success
|
||||
function ($ret) { return $ret === 0; },
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ class BuilderProvider
|
||||
*/
|
||||
public static function makeBuilderByInput(InputInterface $input): BuilderBase
|
||||
{
|
||||
ini_set('memory_limit', '2G');
|
||||
|
||||
self::$builder = match (PHP_OS_FAMILY) {
|
||||
'Windows' => new WindowsBuilder($input->getOptions()),
|
||||
'Darwin' => new MacOSBuilder($input->getOptions()),
|
||||
|
||||
@@ -170,19 +170,19 @@ class Extension
|
||||
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 you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php
|
||||
// If check failed, throw RuntimeException
|
||||
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')) {
|
||||
if (file_exists(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php')) {
|
||||
// Trim additional content & escape special characters to allow inline usage
|
||||
$test = str_replace(
|
||||
['<?php', 'declare(strict_types=1);', "\n", '"', '$'],
|
||||
['', '', '', '\"', '\$'],
|
||||
file_get_contents(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')
|
||||
file_get_contents(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php')
|
||||
);
|
||||
|
||||
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
|
||||
@@ -201,19 +201,19 @@ class Extension
|
||||
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 you need to run some check, overwrite this or add your assert in src/globals/ext-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'))) {
|
||||
if (file_exists(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-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'))
|
||||
file_get_contents(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php'))
|
||||
);
|
||||
|
||||
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -r "' . trim($test) . '"');
|
||||
@@ -223,6 +223,11 @@ class Extension
|
||||
}
|
||||
}
|
||||
|
||||
public function validate(): void
|
||||
{
|
||||
// do nothing, just throw wrong usage exception if not valid
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
|
||||
@@ -177,6 +177,11 @@ abstract class LibraryBase
|
||||
return false;
|
||||
}
|
||||
|
||||
public function validate(): void
|
||||
{
|
||||
// do nothing, just throw wrong usage exception if not valid
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current builder object.
|
||||
*/
|
||||
|
||||
@@ -14,11 +14,15 @@ class imap extends Extension
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getUnixConfigureArg(): string
|
||||
public function validate(): void
|
||||
{
|
||||
if ($this->builder->getOption('enable-zts')) {
|
||||
throw new WrongUsageException('ext-imap is not thread safe, do not build it with ZTS builds');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$arg = '--with-imap=' . BUILD_ROOT_PATH;
|
||||
if ($this->builder->getLib('openssl') !== null) {
|
||||
$arg .= ' --with-imap-ssl=' . BUILD_ROOT_PATH;
|
||||
|
||||
@@ -5,20 +5,11 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('mongodb')]
|
||||
class mongodb extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/mongodb/config.m4', 'if test -z "$PHP_CONFIG"; then', 'if false; then');
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/mongodb/config.m4', 'PHP_MONGODB_PHP_VERSION=`${PHP_CONFIG} --version`', 'PHP_MONGODB_PHP_VERSION=' . $this->builder->getPHPVersion());
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/mongodb/config.m4', 'PHP_MONGODB_PHP_VERSION_ID=`${PHP_CONFIG} --vernum`', 'PHP_MONGODB_PHP_VERSION_ID=' . $this->builder->getPHPVersionID());
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$arg = ' --enable-mongodb ';
|
||||
|
||||
@@ -16,11 +16,15 @@ class opcache extends Extension
|
||||
* @throws WrongUsageException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getUnixConfigureArg(): string
|
||||
public function validate(): void
|
||||
{
|
||||
if ($this->builder->getPHPVersionID() < 80000) {
|
||||
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
|
||||
throw new WrongUsageException('Statically compiled PHP with Zend Opcache only available for PHP >= 8.0 !');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
return '--enable-opcache';
|
||||
}
|
||||
|
||||
|
||||
20
src/SPC/builder/extension/parallel.php
Normal file
20
src/SPC/builder/extension/parallel.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('parallel')]
|
||||
class parallel extends Extension
|
||||
{
|
||||
public function validate(): void
|
||||
{
|
||||
if (!$this->builder->getOption('enable-zts')) {
|
||||
throw new WrongUsageException('ext-parallel must be built with ZTS builds. Use "--enable-zts" option!');
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/SPC/builder/extension/protobuf.php
Normal file
19
src/SPC/builder/extension/protobuf.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('protobuf')]
|
||||
class protobuf extends Extension
|
||||
{
|
||||
public function validate(): void
|
||||
{
|
||||
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
|
||||
throw new \RuntimeException('The latest protobuf extension requires PHP 8.0 or later');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,16 @@ class swoole_hook_pgsql extends Extension
|
||||
return 'swoole';
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
public function validate(): void
|
||||
{
|
||||
// pdo_pgsql need to be disabled
|
||||
if ($this->builder->getExt('pdo_pgsql') !== null) {
|
||||
throw new WrongUsageException('swoole-hook-pgsql provides pdo_pgsql, if you enable pgsql hook for swoole, you must remove pdo_pgsql extension.');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
// enable swoole pgsql hook
|
||||
return '--enable-swoole-pgsql';
|
||||
}
|
||||
|
||||
@@ -17,12 +17,16 @@ class swoole_hook_sqlite extends Extension
|
||||
return 'swoole';
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
public function validate(): void
|
||||
{
|
||||
// pdo_pgsql need to be disabled
|
||||
if ($this->builder->getExt('pdo_sqlite') !== null) {
|
||||
throw new WrongUsageException('swoole-hook-sqlite provides pdo_sqlite, if you enable sqlite hook for swoole, you must remove pdo_sqlite extension.');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
// enable swoole pgsql hook
|
||||
return '--enable-swoole-sqlite';
|
||||
}
|
||||
|
||||
@@ -11,6 +11,13 @@ use SPC\util\CustomExt;
|
||||
#[CustomExt('swow')]
|
||||
class swow extends Extension
|
||||
{
|
||||
public function validate(): void
|
||||
{
|
||||
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
|
||||
throw new RuntimeException('The latest swow extension requires PHP 8.0 or later');
|
||||
}
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$arg = '--enable-swow';
|
||||
|
||||
19
src/SPC/builder/extension/uv.php
Normal file
19
src/SPC/builder/extension/uv.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('uv')]
|
||||
class uv extends Extension
|
||||
{
|
||||
public function validate(): void
|
||||
{
|
||||
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
|
||||
throw new \RuntimeException('The latest uv extension requires PHP 8.0 or later');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,10 @@ class xlswriter extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
return '--with-xlswriter --enable-reader';
|
||||
$arg = '--with-xlswriter --enable-reader';
|
||||
if ($this->builder->getLib('openssl')) {
|
||||
$arg .= ' --with-openssl=' . BUILD_ROOT_PATH;
|
||||
}
|
||||
return $arg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class BSDBuilder extends UnixBuilderBase
|
||||
// ---------- set necessary options ----------
|
||||
// set C Compiler (default: clang)
|
||||
f_putenv('CC=' . $this->getOption('cc', 'clang'));
|
||||
// set C++ Composer (default: clang++)
|
||||
// set C++ Compiler (default: clang++)
|
||||
f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
|
||||
// set PATH
|
||||
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
|
||||
@@ -86,7 +86,8 @@ class BSDBuilder extends UnixBuilderBase
|
||||
SourcePatcher::patchBeforeConfigure($this);
|
||||
|
||||
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
|
||||
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
|
||||
$zts_enable = $this->getPHPVersionID() < 80000 ? '--enable-maintainer-zts --disable-zend-signals' : '--enable-zts --disable-zend-signals';
|
||||
$zts = $this->getOption('enable-zts', false) ? $zts_enable : '';
|
||||
|
||||
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
||||
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||
@@ -180,7 +181,7 @@ class BSDBuilder extends UnixBuilderBase
|
||||
}
|
||||
if ($this->getExt('phar')) {
|
||||
$this->phar_patched = true;
|
||||
SourcePatcher::patchMicro(['phar']);
|
||||
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
||||
}
|
||||
|
||||
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||
@@ -201,7 +202,7 @@ class BSDBuilder extends UnixBuilderBase
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
|
||||
if ($this->phar_patched) {
|
||||
SourcePatcher::patchMicro(['phar'], true);
|
||||
SourcePatcher::unpatchMicroPhar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,9 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
}
|
||||
|
||||
/**
|
||||
* Build PHP from source.
|
||||
*
|
||||
* @param int $build_target Build target, use `BUILD_TARGET_*` constants
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
@@ -131,10 +134,10 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
}
|
||||
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';
|
||||
|
||||
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
||||
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
|
||||
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
|
||||
$enable_cli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
||||
$enable_fpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||
$enable_micro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
|
||||
$enable_embed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
|
||||
|
||||
// prepare build php envs
|
||||
$envs_build_php = SystemUtil::makeEnvVarString([
|
||||
@@ -144,49 +147,22 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
'LIBS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LIBS'),
|
||||
]);
|
||||
|
||||
// upx pack and strip for micro
|
||||
// but always restore Makefile.frag.bak first
|
||||
if (file_exists(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak')) {
|
||||
copy(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak', SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag');
|
||||
}
|
||||
if ($this->getOption('with-upx-pack', false)) {
|
||||
// judge $(MAKE) micro_2s_objs SFX_FILESIZE=`$(STAT_SIZE) $(SAPI_MICRO_PATH)` count
|
||||
// if 2, replace src/globals/extra/micro-triple-Makefile.frag file content
|
||||
if (substr_count(FileSystem::readFile(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag'), '$(MAKE) micro_2s_objs SFX_FILESIZE=`$(STAT_SIZE) $(SAPI_MICRO_PATH)`') === 2) {
|
||||
// bak first
|
||||
copy(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag', SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak');
|
||||
// replace Makefile.frag content
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag', FileSystem::readFile(ROOT_DIR . '/src/globals/extra/micro-triple-Makefile.frag'));
|
||||
// process micro upx patch if micro sapi enabled
|
||||
if ($enable_micro) {
|
||||
if (version_compare($this->getMicroVersion(), '0.2.0') < 0) {
|
||||
// for phpmicro 0.1.x
|
||||
$this->processMicroUPXLegacy();
|
||||
}
|
||||
// with upx pack always need strip
|
||||
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) && ' . getenv('UPX_EXEC') . ' --best \$(SAPI_MICRO_PATH)',
|
||||
);
|
||||
} elseif (!$this->getOption('no-strip', false)) {
|
||||
// not-no-strip means strip (default behavior)
|
||||
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 {
|
||||
// just no strip
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
|
||||
'/POST_MICRO_BUILD_COMMANDS=.*/',
|
||||
'POST_MICRO_BUILD_COMMANDS=true',
|
||||
);
|
||||
// micro latest needs do strip and upx pack later (strip, upx, cut binary manually supported)
|
||||
}
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec(
|
||||
getenv('SPC_CMD_PREFIX_PHP_CONFIGURE') . ' ' .
|
||||
($enableCli ? '--enable-cli ' : '--disable-cli ') .
|
||||
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
|
||||
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
|
||||
($enableMicro ? '--enable-micro=all-static ' : '--disable-micro ') .
|
||||
($enable_cli ? '--enable-cli ' : '--disable-cli ') .
|
||||
($enable_fpm ? '--enable-fpm ' : '--disable-fpm ') .
|
||||
($enable_embed ? '--enable-embed=static ' : '--disable-embed ') .
|
||||
($enable_micro ? '--enable-micro=all-static ' : '--disable-micro ') .
|
||||
$disable_jit .
|
||||
$json_74 .
|
||||
$zts .
|
||||
@@ -200,21 +176,21 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
|
||||
$this->cleanMake();
|
||||
|
||||
if ($enableCli) {
|
||||
if ($enable_cli) {
|
||||
logger()->info('building cli');
|
||||
$this->buildCli();
|
||||
}
|
||||
if ($enableFpm) {
|
||||
if ($enable_fpm) {
|
||||
logger()->info('building fpm');
|
||||
$this->buildFpm();
|
||||
}
|
||||
if ($enableMicro) {
|
||||
if ($enable_micro) {
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro();
|
||||
}
|
||||
if ($enableEmbed) {
|
||||
if ($enable_embed) {
|
||||
logger()->info('building embed');
|
||||
if ($enableMicro) {
|
||||
if ($enable_micro) {
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
|
||||
}
|
||||
$this->buildEmbed();
|
||||
@@ -264,7 +240,7 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
}
|
||||
if ($this->getExt('phar')) {
|
||||
$this->phar_patched = true;
|
||||
SourcePatcher::patchMicro(['phar']);
|
||||
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
||||
}
|
||||
|
||||
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||
@@ -278,10 +254,12 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||
->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} micro");
|
||||
|
||||
$this->processMicroUPX();
|
||||
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
|
||||
if ($this->phar_patched) {
|
||||
SourcePatcher::patchMicro(['phar'], true);
|
||||
SourcePatcher::unpatchMicroPhar();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,4 +308,70 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
'EXTRA_LDFLAGS_PROGRAM' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply option --no-strip and --with-upx-pack for micro sapi (only for phpmicro 0.1.x)
|
||||
*
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
private function processMicroUPXLegacy(): void
|
||||
{
|
||||
// upx pack and strip for micro
|
||||
// but always restore Makefile.frag.bak first
|
||||
if (file_exists(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak')) {
|
||||
copy(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak', SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag');
|
||||
}
|
||||
if ($this->getOption('with-upx-pack', false)) {
|
||||
// judge $(MAKE) micro_2s_objs SFX_FILESIZE=`$(STAT_SIZE) $(SAPI_MICRO_PATH)` count
|
||||
// if 2, replace src/globals/extra/micro-triple-Makefile.frag file content
|
||||
if (substr_count(FileSystem::readFile(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag'), '$(MAKE) micro_2s_objs SFX_FILESIZE=`$(STAT_SIZE) $(SAPI_MICRO_PATH)`') === 2) {
|
||||
// bak first
|
||||
copy(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag', SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak');
|
||||
// replace Makefile.frag content
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag', FileSystem::readFile(ROOT_DIR . '/src/globals/extra/micro-triple-Makefile.frag'));
|
||||
}
|
||||
// with upx pack always need strip
|
||||
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) && ' . getenv('UPX_EXEC') . ' --best \$(SAPI_MICRO_PATH)',
|
||||
);
|
||||
} elseif (!$this->getOption('no-strip', false)) {
|
||||
// not-no-strip means strip (default behavior)
|
||||
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 {
|
||||
// just no strip
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
|
||||
'/POST_MICRO_BUILD_COMMANDS=.*/',
|
||||
'POST_MICRO_BUILD_COMMANDS=true',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function processMicroUPX(): void
|
||||
{
|
||||
if (version_compare($this->getMicroVersion(), '0.2.0') >= 0 && !$this->getOption('no-strip', false)) {
|
||||
shell()->exec('strip --strip-all ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx');
|
||||
|
||||
if ($this->getOption('with-upx-pack')) {
|
||||
// strip first
|
||||
shell()->exec(getenv('UPX_EXEC') . ' --best ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx');
|
||||
// cut binary with readelf
|
||||
[$ret, $out] = shell()->execWithResult('readelf -l ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx | awk \'/LOAD|GNU_STACK/ {getline; print $1, $2, $3, $4, $6, $7}\'');
|
||||
$out[1] = explode(' ', $out[1]);
|
||||
$offset = $out[1][0];
|
||||
if ($ret !== 0 || !str_starts_with($offset, '0x')) {
|
||||
throw new RuntimeException('Cannot find offset in readelf output');
|
||||
}
|
||||
$offset = hexdec($offset);
|
||||
// remove upx extra wastes
|
||||
file_put_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx', substr(file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx'), 0, $offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
}
|
||||
if ($this->getExt('phar')) {
|
||||
$this->phar_patched = true;
|
||||
SourcePatcher::patchMicro(['phar']);
|
||||
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
||||
}
|
||||
|
||||
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||
@@ -241,7 +241,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
|
||||
// patch fake cli for micro
|
||||
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
|
||||
if (!$this->getOption('no-strip', false)) {
|
||||
if ($this->getOption('no-strip', false)) {
|
||||
$vars['STRIP'] = 'dsymutil -f ';
|
||||
}
|
||||
$vars = SystemUtil::makeEnvVarString($vars);
|
||||
@@ -251,7 +251,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
|
||||
if ($this->phar_patched) {
|
||||
SourcePatcher::patchMicro(['phar'], true);
|
||||
SourcePatcher::unpatchMicroPhar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,13 +90,13 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
return $extra;
|
||||
}
|
||||
|
||||
public function buildLibs(array $sorted_libraries): void
|
||||
public function proveLibs(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'
|
||||
'SPC\builder\\' . osfamily2dir() . '\library'
|
||||
);
|
||||
foreach ($classes as $class) {
|
||||
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {
|
||||
@@ -137,16 +137,6 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
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'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,22 +162,20 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
|
||||
// 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}]");
|
||||
$test_task = $this->getMicroTestTasks();
|
||||
foreach ($test_task as $task_name => $task) {
|
||||
$test_file = SOURCE_PATH . '/' . $task_name . '.exe';
|
||||
if (file_exists($test_file)) {
|
||||
@unlink($test_file);
|
||||
}
|
||||
file_put_contents($test_file, file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') . $task['content']);
|
||||
chmod($test_file, 0755);
|
||||
[$ret, $out] = shell()->execWithResult($test_file);
|
||||
foreach ($task['conditions'] as $condition => $closure) {
|
||||
if (!$closure($ret, $out)) {
|
||||
$raw_out = trim(implode('', $out));
|
||||
throw new RuntimeException("micro failed sanity check: {$task_name}, condition [{$condition}], ret[{$ret}], out[{$raw_out}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,20 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
trait libcares
|
||||
{
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
if (!file_exists($this->source_dir . '/src/lib/thirdparty/apple/dnsinfo.h')) {
|
||||
FileSystem::createDir($this->source_dir . '/src/lib/thirdparty/apple');
|
||||
copy(ROOT_DIR . '/src/globals/extra/libcares_dnsinfo.h', $this->source_dir . '/src/lib/thirdparty/apple/dnsinfo.h');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
|
||||
@@ -15,14 +15,20 @@ trait libtiff
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
shell()->cd($this->source_dir)
|
||||
$shell = shell()->cd($this->source_dir)
|
||||
->exec(
|
||||
'./configure ' .
|
||||
'--enable-static --disable-shared ' .
|
||||
'--disable-cxx ' .
|
||||
'--prefix='
|
||||
)
|
||||
->exec('make clean')
|
||||
);
|
||||
|
||||
// TODO: Remove this check when https://gitlab.com/libtiff/libtiff/-/merge_requests/635 will be merged and released
|
||||
if (file_exists($this->source_dir . '/html')) {
|
||||
$shell->exec('make clean');
|
||||
}
|
||||
|
||||
$shell
|
||||
->exec("make -j{$this->builder->concurrency}")
|
||||
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
|
||||
$this->patchPkgconfPrefix(['libtiff-4.pc']);
|
||||
|
||||
@@ -90,6 +90,7 @@ class SystemUtil
|
||||
$buildroot = str_replace('\\', '\\\\', BUILD_ROOT_PATH);
|
||||
$toolchain = <<<CMAKE
|
||||
set(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(CMAKE_SYSTEM_PROCESSOR x64)
|
||||
SET(CMAKE_C_FLAGS "{$cflags}")
|
||||
SET(CMAKE_C_FLAGS_DEBUG "{$cflags}")
|
||||
SET(CMAKE_CXX_FLAGS "{$cflags}")
|
||||
|
||||
@@ -80,16 +80,18 @@ class WindowsBuilder extends BuilderBase
|
||||
$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 = ' . getenv('UPX_EXEC') . " --best $(MICRO_SFX)\n$(MICRO_SFX):");
|
||||
FileSystem::replaceFileStr($makefile, '@$(_MICRO_MT)', "@$(_MICRO_MT)\n\t@$(_MICRO_UPX)");
|
||||
if ($enableMicro && version_compare($this->getMicroVersion(), '0.2.0') < 0) {
|
||||
$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 = ' . getenv('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');
|
||||
}
|
||||
} elseif (file_exists($makefile . '.originfile')) {
|
||||
copy($makefile . '.originfile', $makefile);
|
||||
unlink($makefile . '.originfile');
|
||||
}
|
||||
|
||||
if (($logo = $this->getOption('with-micro-logo')) !== null) {
|
||||
@@ -100,6 +102,8 @@ class WindowsBuilder extends BuilderBase
|
||||
$micro_logo = '';
|
||||
}
|
||||
|
||||
$micro_w32 = $this->getOption('enable-micro-win32') ? ' --enable-micro-win32=yes' : '';
|
||||
|
||||
cmd()->cd(SOURCE_PATH . '\php-src')
|
||||
->exec(
|
||||
"{$this->sdk_prefix} configure.bat --task-args \"" .
|
||||
@@ -109,7 +113,7 @@ class WindowsBuilder extends BuilderBase
|
||||
'--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 ') .
|
||||
($enableMicro ? ('--enable-micro=yes ' . $micro_logo . $micro_w32) : '--enable-micro=no ') .
|
||||
($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
|
||||
"{$this->makeExtensionArgs()} " .
|
||||
$zts .
|
||||
@@ -130,6 +134,8 @@ class WindowsBuilder extends BuilderBase
|
||||
if ($enableMicro) {
|
||||
logger()->info('building micro');
|
||||
$this->buildMicro();
|
||||
|
||||
SourcePatcher::unpatchMicroWin32();
|
||||
}
|
||||
if ($enableEmbed) {
|
||||
logger()->warning('Windows does not currently support embed SAPI.');
|
||||
@@ -191,27 +197,27 @@ class WindowsBuilder extends BuilderBase
|
||||
// phar patch for micro
|
||||
if ($this->getExt('phar')) {
|
||||
$this->phar_patched = true;
|
||||
SourcePatcher::patchMicro(['phar']);
|
||||
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
||||
}
|
||||
|
||||
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);
|
||||
SourcePatcher::unpatchMicroPhar();
|
||||
}
|
||||
}
|
||||
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
}
|
||||
|
||||
public function buildLibs(array $sorted_libraries): void
|
||||
public function proveLibs(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'
|
||||
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) {
|
||||
@@ -242,16 +248,6 @@ class WindowsBuilder extends BuilderBase
|
||||
|
||||
// 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'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,6 +267,12 @@ class WindowsBuilder extends BuilderBase
|
||||
*/
|
||||
public function sanityCheck(mixed $build_target): void
|
||||
{
|
||||
// remove all .dll from `buildroot/bin/`
|
||||
logger()->debug('Removing all .dll files from buildroot/bin/');
|
||||
$dlls = glob(BUILD_BIN_PATH . '\*.dll');
|
||||
foreach ($dlls as $dll) {
|
||||
@unlink($dll);
|
||||
}
|
||||
// sanity check for php-cli
|
||||
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
|
||||
logger()->info('running cli sanity check');
|
||||
@@ -287,22 +289,20 @@ class WindowsBuilder extends BuilderBase
|
||||
|
||||
// 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}]");
|
||||
$test_task = $this->getMicroTestTasks();
|
||||
foreach ($test_task as $task_name => $task) {
|
||||
$test_file = SOURCE_PATH . '/' . $task_name . '.exe';
|
||||
if (file_exists($test_file)) {
|
||||
@unlink($test_file);
|
||||
}
|
||||
file_put_contents($test_file, file_get_contents(BUILD_ROOT_PATH . '\bin\micro.sfx') . $task['content']);
|
||||
chmod($test_file, 0755);
|
||||
[$ret, $out] = cmd()->execWithResult($test_file);
|
||||
foreach ($task['conditions'] as $condition => $closure) {
|
||||
if (!$closure($ret, $out)) {
|
||||
$raw_out = trim(implode('', $out));
|
||||
throw new RuntimeException("micro failed sanity check: {$task_name}, condition [{$condition}], ret[{$ret}], out[{$raw_out}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,9 +324,11 @@ class WindowsBuilder extends BuilderBase
|
||||
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(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src));
|
||||
// with-upx-pack for cli and micro
|
||||
if ($this->getOption('with-upx-pack', false)) {
|
||||
if ($type === BUILD_TARGET_CLI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) {
|
||||
cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src));
|
||||
}
|
||||
}
|
||||
|
||||
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
||||
|
||||
36
src/SPC/builder/windows/library/freetype.php
Normal file
36
src/SPC/builder/windows/library/freetype.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class freetype extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'freetype';
|
||||
|
||||
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 ' .
|
||||
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||
)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper('cmake'),
|
||||
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||
);
|
||||
// freetype.lib to libfreetype_a.lib
|
||||
copy(BUILD_LIB_PATH . '\freetype.lib', BUILD_LIB_PATH . '\libfreetype_a.lib');
|
||||
}
|
||||
}
|
||||
37
src/SPC/builder/windows/library/libavif.php
Normal file
37
src/SPC/builder/windows/library/libavif.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libavif extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libavif';
|
||||
|
||||
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 ' .
|
||||
'-DAVIF_BUILD_APPS=OFF ' .
|
||||
'-DAVIF_BUILD_TESTS=OFF ' .
|
||||
'-DAVID_ENABLE_GTEST=OFF ' .
|
||||
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||
)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper('cmake'),
|
||||
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||
);
|
||||
}
|
||||
}
|
||||
41
src/SPC/builder/windows/library/libjpeg.php
Normal file
41
src/SPC/builder/windows/library/libjpeg.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libjpeg extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libjpeg';
|
||||
|
||||
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 ' .
|
||||
'-DENABLE_SHARED=OFF ' .
|
||||
'-DENABLE_STATIC=ON ' .
|
||||
'-DBUILD_TESTING=OFF ' .
|
||||
'-DWITH_JAVA=OFF ' .
|
||||
'-DWITH_CRT_DLL=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}"
|
||||
);
|
||||
copy(BUILD_LIB_PATH . '\jpeg-static.lib', BUILD_LIB_PATH . '\libjpeg_a.lib');
|
||||
}
|
||||
}
|
||||
40
src/SPC/builder/windows/library/libpng.php
Normal file
40
src/SPC/builder/windows/library/libpng.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libpng extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libpng';
|
||||
|
||||
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 ' .
|
||||
'-DSKIP_INSTALL_PROGRAM=ON ' .
|
||||
'-DSKIP_INSTALL_FILES=ON ' .
|
||||
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||
'-DPNG_STATIC=ON ' .
|
||||
'-DPNG_SHARED=OFF ' .
|
||||
'-DPNG_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 . '\libpng16_static.lib', BUILD_LIB_PATH . '\libpng_a.lib');
|
||||
}
|
||||
}
|
||||
45
src/SPC/builder/windows/library/libwebp.php
Normal file
45
src/SPC/builder/windows/library/libwebp.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libwebp extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libwebp';
|
||||
|
||||
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 ' .
|
||||
'-DWEBP_LINK_STATIC=ON ' .
|
||||
'-DWEBP_BUILD_ANIM_UTILS=OFF ' .
|
||||
'-DWEBP_BUILD_CWEBP=OFF ' .
|
||||
'-DWEBP_BUILD_DWEBP=OFF ' .
|
||||
'-DWEBP_BUILD_GIF2WEBP=OFF ' .
|
||||
'-DWEBP_BUILD_IMG2WEBP=OFF ' .
|
||||
'-DWEBP_BUILD_VWEBP=OFF ' .
|
||||
'-DWEBP_BUILD_WEBPINFO=OFF ' .
|
||||
'-DWEBP_BUILD_LIBWEBPMUX=OFF ' .
|
||||
'-DWEBP_BUILD_WEBPMUX=OFF ' .
|
||||
'-DWEBP_BUILD_EXTRAS=OFF ' .
|
||||
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||
)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper('cmake'),
|
||||
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||
);
|
||||
}
|
||||
}
|
||||
29
src/SPC/builder/windows/library/pthreads4w.php
Normal file
29
src/SPC/builder/windows/library/pthreads4w.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
class pthreads4w extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'pthreads4w';
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
cmd()->cd($this->source_dir)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper(
|
||||
'nmake /E /nologo /f Makefile ' .
|
||||
'DESTROOT=' . BUILD_ROOT_PATH . ' ' .
|
||||
'XCFLAGS="/MT" ' . // no dll
|
||||
'EHFLAGS="/I. /DHAVE_CONFIG_H /Os /Ob2 /D__PTW32_STATIC_LIB /D__PTW32_BUILD_INLINED"'
|
||||
),
|
||||
'pthreadVC3.inlined_static_stamp'
|
||||
);
|
||||
copy($this->source_dir . '\libpthreadVC3.lib', BUILD_LIB_PATH . '\libpthreadVC3.lib');
|
||||
copy($this->source_dir . '\_ptw32.h', BUILD_INCLUDE_PATH . '\_ptw32.h');
|
||||
copy($this->source_dir . '\pthread.h', BUILD_INCLUDE_PATH . '\pthread.h');
|
||||
copy($this->source_dir . '\sched.h', BUILD_INCLUDE_PATH . '\sched.h');
|
||||
copy($this->source_dir . '\semaphore.h', BUILD_INCLUDE_PATH . '\semaphore.h');
|
||||
}
|
||||
}
|
||||
@@ -96,6 +96,8 @@ abstract class BaseCommand extends Command
|
||||
});
|
||||
if ($this->shouldExecute()) {
|
||||
try {
|
||||
// show raw argv list for logger()->debug
|
||||
logger()->debug('argv: ' . implode(' ', $_SERVER['argv']));
|
||||
return $this->handle();
|
||||
} catch (WrongUsageException $e) {
|
||||
$msg = explode("\n", $e->getMessage());
|
||||
@@ -132,4 +134,41 @@ abstract class BaseCommand extends Command
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function logWithResult(bool $result, string $success_msg, string $fail_msg): int
|
||||
{
|
||||
if ($result) {
|
||||
logger()->info($success_msg);
|
||||
return static::SUCCESS;
|
||||
}
|
||||
logger()->error($fail_msg);
|
||||
return static::FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse extension list from string, replace alias and filter internal extensions.
|
||||
*
|
||||
* @param string $ext_list Extension string list, e.g. "mbstring,posix,sockets"
|
||||
*/
|
||||
protected function parseExtensionList(string $ext_list): array
|
||||
{
|
||||
// replace alias
|
||||
$ls = array_map(function ($x) {
|
||||
$lower = strtolower(trim($x));
|
||||
if (isset(SPC_EXTENSION_ALIAS[$lower])) {
|
||||
logger()->notice("Extension [{$lower}] is an alias of [" . SPC_EXTENSION_ALIAS[$lower] . '], it will be replaced.');
|
||||
return SPC_EXTENSION_ALIAS[$lower];
|
||||
}
|
||||
return $lower;
|
||||
}, explode(',', $ext_list));
|
||||
|
||||
// filter internals
|
||||
return array_values(array_filter($ls, function ($x) {
|
||||
if (in_array($x, SPC_INTERNAL_EXTENSIONS)) {
|
||||
logger()->warning("Extension [{$x}] is an builtin extension, it will be ignored.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use ZM\Logger\ConsoleColor;
|
||||
|
||||
#[AsCommand('build', 'build PHP')]
|
||||
#[AsCommand('build', 'build PHP', ['build:php'])]
|
||||
class BuildCliCommand extends BuildCommand
|
||||
{
|
||||
public function configure(): void
|
||||
@@ -40,6 +40,7 @@ class BuildCliCommand extends BuildCommand
|
||||
$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)');
|
||||
$this->addOption('enable-micro-win32', null, null, 'Enable win32 mode for phpmicro (Windows only)');
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
@@ -47,7 +48,7 @@ class BuildCliCommand extends BuildCommand
|
||||
// transform string to array
|
||||
$libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs'))));
|
||||
// transform string to array
|
||||
$extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions'))));
|
||||
$extensions = $this->parseExtensionList($this->getArgument('extensions'));
|
||||
|
||||
// parse rule with options
|
||||
$rule = $this->parseRules();
|
||||
@@ -93,6 +94,9 @@ class BuildCliCommand extends BuildCommand
|
||||
if ($this->getOption('no-strip')) {
|
||||
logger()->warning('--with-upx-pack conflicts with --no-strip, --no-strip won\'t work!');
|
||||
}
|
||||
if (($rule & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
|
||||
logger()->warning('Some cases micro.sfx cannot be packed via UPX due to dynamic size bug, be aware!');
|
||||
}
|
||||
}
|
||||
try {
|
||||
// create builder
|
||||
@@ -133,17 +137,23 @@ class BuildCliCommand extends BuildCommand
|
||||
}
|
||||
$this->printFormatInfo($this->getDefinedEnvs(), true);
|
||||
$this->printFormatInfo($indent_texts);
|
||||
|
||||
logger()->notice('Build will start after 2s ...');
|
||||
sleep(2);
|
||||
|
||||
// compile libraries
|
||||
$builder->proveLibs($libraries);
|
||||
// check extensions
|
||||
$builder->proveExts($extensions);
|
||||
// validate libs and exts
|
||||
$builder->validateLibsAndExts();
|
||||
// build libraries
|
||||
$builder->buildLibs();
|
||||
|
||||
if ($this->input->getOption('with-clean')) {
|
||||
logger()->info('Cleaning source dir...');
|
||||
FileSystem::removeDir(SOURCE_PATH);
|
||||
}
|
||||
// compile libraries
|
||||
$builder->buildLibs($libraries);
|
||||
// check extensions
|
||||
$builder->proveExts($extensions);
|
||||
|
||||
// Process -I option
|
||||
$custom_ini = [];
|
||||
|
||||
@@ -61,7 +61,11 @@ class BuildLibsCommand extends BuildCommand
|
||||
$builder->setLibsOnly();
|
||||
// 编译和检查库完整
|
||||
$libraries = DependencyUtil::getLibs($libraries);
|
||||
$builder->buildLibs($libraries);
|
||||
logger()->info('Building libraries: ' . implode(',', $libraries));
|
||||
sleep(2);
|
||||
$builder->proveLibs($libraries);
|
||||
$builder->validateLibsAndExts();
|
||||
$builder->buildLibs();
|
||||
|
||||
$time = round(microtime(true) - START_TIME, 3);
|
||||
logger()->info('Build libs complete, used ' . $time . ' s !');
|
||||
|
||||
@@ -68,7 +68,7 @@ class DownloadCommand extends BaseCommand
|
||||
}
|
||||
// mode: --for-extensions
|
||||
if ($for_ext = $input->getOption('for-extensions')) {
|
||||
$ext = array_map('trim', array_filter(explode(',', $for_ext)));
|
||||
$ext = $this->parseExtensionList($for_ext);
|
||||
$sources = $this->calculateSourcesByExt($ext, !$input->getOption('without-suggestions'));
|
||||
if (PHP_OS_FAMILY !== 'Windows') {
|
||||
array_unshift($sources, 'pkg-config');
|
||||
|
||||
@@ -37,7 +37,7 @@ class DumpLicenseCommand extends BaseCommand
|
||||
$dumper = new LicenseDumper();
|
||||
if ($this->getOption('for-extensions') !== null) {
|
||||
// 从参数中获取要编译的 extensions,并转换为数组
|
||||
$extensions = array_map('trim', array_filter(explode(',', $this->getOption('for-extensions'))));
|
||||
$extensions = $this->parseExtensionList($this->getOption('for-extensions'));
|
||||
// 根据提供的扩展列表获取依赖库列表并编译
|
||||
[$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions);
|
||||
$dumper->addExts($extensions);
|
||||
@@ -57,8 +57,11 @@ class DumpLicenseCommand extends BaseCommand
|
||||
$libraries = DependencyUtil::getLibs($libraries);
|
||||
$dumper->addLibs($libraries);
|
||||
$dumper->dump($this->getOption('dump-dir'));
|
||||
$this->output->writeln('Dump target dir: ' . $this->getOption('dump-dir'));
|
||||
return static::SUCCESS;
|
||||
return $this->logWithResult(
|
||||
$dumper->dump($this->getOption('dump-dir')),
|
||||
'Dump target dir: ' . $this->getOption('dump-dir'),
|
||||
'Dump failed!'
|
||||
);
|
||||
}
|
||||
if ($this->getOption('for-sources') !== null) {
|
||||
$sources = array_map('trim', array_filter(explode(',', $this->getOption('for-sources'))));
|
||||
|
||||
67
src/SPC/command/SwitchPhpVersionCommand.php
Normal file
67
src/SPC/command/SwitchPhpVersionCommand.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command;
|
||||
|
||||
use SPC\store\Config;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
#[AsCommand('switch-php-version', description: 'Switch downloaded PHP version')]
|
||||
class SwitchPhpVersionCommand extends BaseCommand
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->addArgument(
|
||||
'php-major-version',
|
||||
InputArgument::REQUIRED,
|
||||
'PHP major version (supported: 7.4, 8.0, 8.1, 8.2, 8.3)',
|
||||
null,
|
||||
fn () => ['7.4', '8.0', '8.1', '8.2', '8.3']
|
||||
);
|
||||
$this->no_motd = true;
|
||||
|
||||
$this->addOption('retry', 'R', InputOption::VALUE_REQUIRED, 'Set retry time when downloading failed (default: 0)', '0');
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$php_ver = $this->input->getArgument('php-major-version');
|
||||
if (!in_array($php_ver, ['7.4', '8.0', '8.1', '8.2', '8.3'])) {
|
||||
$this->output->writeln('<error>Invalid PHP major version ' . $php_ver . ' !</error>');
|
||||
return static::FAILURE;
|
||||
}
|
||||
|
||||
// detect if downloads/.lock.json exists
|
||||
$lock_file = DOWNLOAD_PATH . '/.lock.json';
|
||||
// parse php-src part of lock file
|
||||
$lock_data = json_decode(file_get_contents($lock_file), true);
|
||||
// get php-src downloaded file name
|
||||
$php_src = $lock_data['php-src'];
|
||||
$file = DOWNLOAD_PATH . '/' . ($php_src['filename'] ?? '.donot.delete.me');
|
||||
if (file_exists($file)) {
|
||||
$this->output->writeln('<info>Removing old PHP source...</info>');
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
// Download new PHP source
|
||||
$this->output->writeln('<info>Downloading PHP source...</info>');
|
||||
define('SPC_BUILD_PHP_VERSION', $php_ver);
|
||||
|
||||
// retry
|
||||
$retry = intval($this->getOption('retry'));
|
||||
f_putenv('SPC_RETRY_TIME=' . $retry);
|
||||
|
||||
Downloader::downloadSource('php-src', Config::getSource('php-src'));
|
||||
|
||||
// Remove source/php-src dir
|
||||
FileSystem::removeDir(SOURCE_PATH . '/php-src');
|
||||
|
||||
$this->output->writeln('<info>Switched to PHP ' . $php_ver . ' successfully!</info>');
|
||||
return static::SUCCESS;
|
||||
}
|
||||
}
|
||||
80
src/SPC/command/dev/GenerateExtDocCommand.php
Normal file
80
src/SPC/command/dev/GenerateExtDocCommand.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command\dev;
|
||||
|
||||
use SPC\command\BaseCommand;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\ConfigValidator;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand('dev:gen-ext-docs', 'Generate extension list markdown', [], true)]
|
||||
class GenerateExtDocCommand extends BaseCommand
|
||||
{
|
||||
protected bool $no_motd = true;
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
// Get ext.json
|
||||
$exts = json_decode(FileSystem::readFile(ROOT_DIR . '/config/ext.json'), true);
|
||||
ConfigValidator::validateExts($exts);
|
||||
// Markdown table needs format, we need to calculate the max length of each column
|
||||
$max_name = 0;
|
||||
$max_linux = 5;
|
||||
$max_macos = 5;
|
||||
$max_freebsd = 7;
|
||||
$max_windows = 7;
|
||||
$md_lines = [];
|
||||
foreach ($exts as $ext_name => $ext) {
|
||||
// notes is optional
|
||||
$name = ($ext['notes'] ?? false) === true ? "[{$ext_name}](./extension-notes#{$ext_name})" : $ext_name;
|
||||
// calculate max length
|
||||
$max_name = max($max_name, strlen($name));
|
||||
|
||||
// linux
|
||||
$linux = match ($ext['support']['Linux'] ?? 'yes') {
|
||||
'wip' => '',
|
||||
default => $ext['support']['Linux'] ?? 'yes',
|
||||
};
|
||||
$max_linux = max($max_linux, strlen($linux));
|
||||
|
||||
// macos
|
||||
$macos = match ($ext['support']['Darwin'] ?? 'yes') {
|
||||
'wip' => '',
|
||||
default => $ext['support']['Darwin'] ?? 'yes',
|
||||
};
|
||||
$max_macos = max($max_macos, strlen($macos));
|
||||
|
||||
// freebsd
|
||||
$freebsd = match ($ext['support']['BSD'] ?? 'yes') {
|
||||
'wip' => '',
|
||||
default => $ext['support']['BSD'] ?? 'yes',
|
||||
};
|
||||
$max_freebsd = max($max_freebsd, strlen($freebsd));
|
||||
|
||||
// windows
|
||||
$windows = match ($ext['support']['Windows'] ?? 'yes') {
|
||||
'wip' => '',
|
||||
default => $ext['support']['Windows'] ?? 'yes',
|
||||
};
|
||||
$max_windows = max($max_windows, strlen($windows));
|
||||
$md_lines[] = [
|
||||
$name,
|
||||
$linux,
|
||||
$macos,
|
||||
$freebsd,
|
||||
$windows,
|
||||
];
|
||||
}
|
||||
|
||||
// generate markdown
|
||||
$md = '| ' . str_pad('Extension Name', $max_name) . ' | ' . str_pad('Linux', $max_linux) . ' | ' . str_pad('macOS', $max_macos) . ' | ' . str_pad('FreeBSD', $max_freebsd) . ' | ' . str_pad('Windows', $max_windows) . ' |' . PHP_EOL;
|
||||
$md .= '| ' . str_repeat('-', $max_name) . ' | ' . str_repeat('-', $max_linux) . ' | ' . str_repeat('-', $max_macos) . ' | ' . str_repeat('-', $max_freebsd) . ' | ' . str_repeat('-', $max_windows) . ' |' . PHP_EOL;
|
||||
foreach ($md_lines as $line) {
|
||||
$md .= '| ' . str_pad($line[0], $max_name) . ' | ' . str_pad($line[1], $max_linux) . ' | ' . str_pad($line[2], $max_macos) . ' | ' . str_pad($line[3], $max_freebsd) . ' | ' . str_pad($line[4], $max_windows) . ' |' . PHP_EOL;
|
||||
}
|
||||
$this->output->writeln($md);
|
||||
return static::SUCCESS;
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,7 @@ final class CheckListHandler
|
||||
*/
|
||||
private function loadCheckList(bool $include_manual = false): array
|
||||
{
|
||||
foreach (FileSystem::getClassesPsr4(__DIR__ . '/item', 'SPC\\doctor\\item') as $class) {
|
||||
foreach (FileSystem::getClassesPsr4(__DIR__ . '/item', 'SPC\doctor\item') as $class) {
|
||||
$ref = new \ReflectionClass($class);
|
||||
foreach ($ref->getMethods() as $method) {
|
||||
foreach ($method->getAttributes() as $a) {
|
||||
|
||||
@@ -337,7 +337,7 @@ class Downloader
|
||||
);
|
||||
break;
|
||||
case 'custom': // Custom download method, like API-based download or other
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\\store\\source');
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\store\source');
|
||||
foreach ($classes as $class) {
|
||||
if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) {
|
||||
(new $class())->fetch($force);
|
||||
@@ -437,7 +437,7 @@ class Downloader
|
||||
);
|
||||
break;
|
||||
case 'custom': // Custom download method, like API-based download or other
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\\store\\source');
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/source', 'SPC\store\source');
|
||||
foreach ($classes as $class) {
|
||||
if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) {
|
||||
(new $class())->fetch($force);
|
||||
|
||||
@@ -436,6 +436,21 @@ class FileSystem
|
||||
return str_replace(array_keys($replacement), array_values($replacement), $path);
|
||||
}
|
||||
|
||||
public static function backupFile(string $path): string
|
||||
{
|
||||
copy($path, $path . '.bak');
|
||||
return $path . '.bak';
|
||||
}
|
||||
|
||||
public static function restoreBackupFile(string $path): void
|
||||
{
|
||||
if (!file_exists($path . '.bak')) {
|
||||
throw new RuntimeException('Cannot find bak file for ' . $path);
|
||||
}
|
||||
copy($path . '.bak', $path);
|
||||
unlink($path . '.bak');
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
|
||||
@@ -18,6 +18,8 @@ class SourcePatcher
|
||||
FileSystem::addSourceExtractHook('micro', [SourcePatcher::class, 'patchMicro']);
|
||||
FileSystem::addSourceExtractHook('openssl', [SourcePatcher::class, 'patchOpenssl11Darwin']);
|
||||
FileSystem::addSourceExtractHook('swoole', [SourcePatcher::class, 'patchSwoole']);
|
||||
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchPhpLibxml212']);
|
||||
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchGDWin32']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,6 +48,12 @@ class SourcePatcher
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
if ($builder->getOption('enable-micro-win32')) {
|
||||
SourcePatcher::patchMicroWin32();
|
||||
} else {
|
||||
SourcePatcher::unpatchMicroWin32();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,6 +208,11 @@ class SourcePatcher
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'install-micro', '');
|
||||
}
|
||||
|
||||
// no asan
|
||||
// if (strpos(file_get_contents(SOURCE_PATH . '/php-src/Makefile'), 'CFLAGS_CLEAN = -g') === false) {
|
||||
// FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'CFLAGS_CLEAN = ', 'CFLAGS_CLEAN = -g -fsanitize=address ');
|
||||
// }
|
||||
|
||||
// call extension patch before make
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeMake() === true) {
|
||||
@@ -268,6 +281,36 @@ class SourcePatcher
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function patchMicroPhar(int $version_id): void
|
||||
{
|
||||
FileSystem::backupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c');
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/ext/phar/phar.c',
|
||||
'static zend_op_array *phar_compile_file',
|
||||
"char *micro_get_filename(void);\n\nstatic zend_op_array *phar_compile_file"
|
||||
);
|
||||
if ($version_id < 80100) {
|
||||
// PHP 8.0.x
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/ext/phar/phar.c',
|
||||
'if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, "://")) {',
|
||||
'if ((strstr(file_handle->filename, micro_get_filename()) || strstr(file_handle->filename, ".phar")) && !strstr(file_handle->filename, "://")) {'
|
||||
);
|
||||
} else {
|
||||
// PHP >= 8.1
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/ext/phar/phar.c',
|
||||
'if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) {',
|
||||
'if ((strstr(ZSTR_VAL(file_handle->filename), micro_get_filename()) || strstr(ZSTR_VAL(file_handle->filename), ".phar")) && !strstr(ZSTR_VAL(file_handle->filename), "://")) {'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static function unpatchMicroPhar(): void
|
||||
{
|
||||
FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c');
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch cli SAPI Makefile for Windows.
|
||||
*
|
||||
@@ -296,6 +339,44 @@ class SourcePatcher
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines));
|
||||
}
|
||||
|
||||
public static function patchPhpLibxml212(): bool
|
||||
{
|
||||
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
|
||||
if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0) {
|
||||
$ver_id = intval($match[1]);
|
||||
if ($ver_id < 80000) {
|
||||
return false;
|
||||
}
|
||||
if ($ver_id < 80100) {
|
||||
self::patchFile('spc_fix_libxml2_12_php80.patch', SOURCE_PATH . '/php-src');
|
||||
return true;
|
||||
}
|
||||
if ($ver_id < 80200) {
|
||||
self::patchFile('spc_fix_libxml2_12_php81.patch', SOURCE_PATH . '/php-src');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function patchGDWin32(): bool
|
||||
{
|
||||
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
|
||||
if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0) {
|
||||
$ver_id = intval($match[1]);
|
||||
if ($ver_id < 80200) {
|
||||
// see: https://github.com/php/php-src/commit/243966177e39eb71822935042c3f13fa6c5b9eed
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/gd/libgd/gdft.c', '#ifndef MSWIN32', '#ifndef _WIN32');
|
||||
}
|
||||
// custom config.w32, because official config.w32 is hard-coded many things
|
||||
$origin = $ver_id >= 80100 ? file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_81.w32') : file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_80.w32');
|
||||
file_put_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32.bak', file_get_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32'));
|
||||
return file_put_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32', $origin) !== false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add additional `static-php-cli.version` ini value for PHP source.
|
||||
*
|
||||
@@ -311,4 +392,20 @@ class SourcePatcher
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/main/main.c', $file);
|
||||
}
|
||||
}
|
||||
|
||||
public static function patchMicroWin32(): void
|
||||
{
|
||||
// patch micro win32
|
||||
if (!file_exists(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak')) {
|
||||
copy(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c', SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak');
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c', '#include "php_variables.h"', '#include "php_variables.h"' . "\n#define PHP_MICRO_WIN32_NO_CONSOLE 1");
|
||||
}
|
||||
}
|
||||
|
||||
public static function unpatchMicroWin32(): void
|
||||
{
|
||||
if (file_exists(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak')) {
|
||||
rename(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak', SOURCE_PATH . '\php-src\sapi\micro\php_micro.c');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class CustomExt
|
||||
*/
|
||||
public static function loadCustomExt(): void
|
||||
{
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\\builder\\extension');
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\builder\extension');
|
||||
foreach ($classes as $class) {
|
||||
$reflection = new \ReflectionClass($class);
|
||||
foreach ($reflection->getAttributes(CustomExt::class) as $attribute) {
|
||||
|
||||
@@ -51,7 +51,7 @@ class GlobalEnvManager
|
||||
|
||||
// Init system-specific env
|
||||
match (PHP_OS_FAMILY) {
|
||||
'Windows' => self::initWindowsEnv($builder),
|
||||
'Windows' => self::initWindowsEnv(),
|
||||
'Darwin' => self::initDarwinEnv($builder),
|
||||
'Linux' => self::initLinuxEnv($builder),
|
||||
'BSD' => 'TODO',
|
||||
@@ -59,7 +59,7 @@ class GlobalEnvManager
|
||||
};
|
||||
}
|
||||
|
||||
private static function initWindowsEnv(BuilderBase $builder): void
|
||||
private static function initWindowsEnv(): void
|
||||
{
|
||||
// Windows need php-sdk binary tools
|
||||
self::initIfNotExists('PHP_SDK_PATH', WORKING_DIR . DIRECTORY_SEPARATOR . 'php-sdk-binary-tools');
|
||||
@@ -69,7 +69,7 @@ class GlobalEnvManager
|
||||
private static function initLinuxEnv(BuilderBase $builder): void
|
||||
{
|
||||
// Init C Compiler and C++ Compiler (alpine)
|
||||
if (\SPC\builder\linux\SystemUtil::isMuslDist()) {
|
||||
if (LinuxSystemUtil::isMuslDist()) {
|
||||
self::initIfNotExists('CC', 'gcc');
|
||||
self::initIfNotExists('CXX', 'g++');
|
||||
self::initIfNotExists('AR', 'ar');
|
||||
|
||||
@@ -10,6 +10,9 @@ use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
/**
|
||||
* License dumper, dump source license files to target directory
|
||||
*/
|
||||
class LicenseDumper
|
||||
{
|
||||
private array $exts = [];
|
||||
@@ -37,6 +40,10 @@ class LicenseDumper
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump source licenses to target directory
|
||||
*
|
||||
* @param string $target_dir Target directory
|
||||
* @return bool Success or not
|
||||
* @throws WrongUsageException
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
@@ -55,20 +62,29 @@ class LicenseDumper
|
||||
|
||||
$source_name = Config::getExt($ext, 'source');
|
||||
foreach ($this->getSourceLicenses($source_name) as $index => $license) {
|
||||
file_put_contents("{$target_dir}/ext_{$ext}_{$index}.txt", $license);
|
||||
$result = file_put_contents("{$target_dir}/ext_{$ext}_{$index}.txt", $license);
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->libs as $lib) {
|
||||
$source_name = Config::getLib($lib, 'source');
|
||||
foreach ($this->getSourceLicenses($source_name) as $index => $license) {
|
||||
file_put_contents("{$target_dir}/lib_{$lib}_{$index}.txt", $license);
|
||||
$result = file_put_contents("{$target_dir}/lib_{$lib}_{$index}.txt", $license);
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->sources as $source) {
|
||||
foreach ($this->getSourceLicenses($source) as $index => $license) {
|
||||
file_put_contents("{$target_dir}/src_{$source}_{$index}.txt", $license);
|
||||
$result = file_put_contents("{$target_dir}/src_{$source}_{$index}.txt", $license);
|
||||
if ($result === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class Patcher
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function patchLinuxConfigHeader(string $libc): void
|
||||
{
|
||||
switch ($libc) {
|
||||
case 'musl_wrapper':
|
||||
// bad checks
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_STRLCPY 1$/m', '');
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_STRLCAT 1$/m', '');
|
||||
// no break
|
||||
case 'musl':
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_FUNC_ATTRIBUTE_IFUNC 1$/m', '');
|
||||
break;
|
||||
case 'glibc':
|
||||
// avoid lcrypt dependency
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_CRYPT 1$/m', '');
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_CRYPT_R 1$/m', '');
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_CRYPT_H 1$/m', '');
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException('not implemented');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@ class UnixShell
|
||||
|
||||
private array $env = [];
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct(?bool $debug = null)
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
|
||||
@@ -15,6 +15,9 @@ class WindowsCmd
|
||||
|
||||
private array $env = [];
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct(?bool $debug = null)
|
||||
{
|
||||
if (PHP_OS_FAMILY !== 'Windows') {
|
||||
|
||||
361
src/globals/common-tests/micro_zend_mm_heap_corrupted.txt
Normal file
361
src/globals/common-tests/micro_zend_mm_heap_corrupted.txt
Normal file
@@ -0,0 +1,361 @@
|
||||
<?php
|
||||
define('K_SP', ' ');
|
||||
define('K_exclam', '!');
|
||||
define('K_quotedbl', '"');
|
||||
define('K_numbersign', '#');
|
||||
define('K_dollar', '$');
|
||||
define('K_percent', '%');
|
||||
define('K_ampersand', '&');
|
||||
define('K_apostrophe', "'");
|
||||
define('K_parentleft', '(');
|
||||
define('K_parentright', ')');
|
||||
define('K_asterisk', '*');
|
||||
define('K_plus', '+');
|
||||
define('K_comma', ',');
|
||||
define('K_minus', '-');
|
||||
define('K_period', '.');
|
||||
define('K_slash', '/');
|
||||
define('K_0', '0');
|
||||
define('K_1', '1');
|
||||
define('K_2', '2');
|
||||
define('K_3', '3');
|
||||
define('K_4', '4');
|
||||
define('K_5', '5');
|
||||
define('K_6', '6');
|
||||
define('K_7', '7');
|
||||
define('K_8', '8');
|
||||
define('K_9', '9');
|
||||
define('K_colon', ':');
|
||||
define('K_semicolon', ';');
|
||||
define('K_less', '<');
|
||||
define('K_equal', '=');
|
||||
define('K_greater', '>');
|
||||
define('K_question', '?');
|
||||
define('K_at', '@');
|
||||
define('K_A', 'A');
|
||||
define('K_B', 'B');
|
||||
define('K_C', 'C');
|
||||
define('K_D', 'D');
|
||||
define('K_E', 'E');
|
||||
define('K_F', 'F');
|
||||
define('K_G', 'G');
|
||||
define('K_H', 'H');
|
||||
define('K_I', 'I');
|
||||
define('K_J', 'J');
|
||||
define('K_K', 'K');
|
||||
define('K_L', 'L');
|
||||
define('K_M', 'M');
|
||||
define('K_N', 'N');
|
||||
define('K_O', 'O');
|
||||
define('K_P', 'P');
|
||||
define('K_Q', 'Q');
|
||||
define('K_R', 'R');
|
||||
define('K_S', 'S');
|
||||
define('K_T', 'T');
|
||||
define('K_U', 'U');
|
||||
define('K_V', 'V');
|
||||
define('K_W', 'W');
|
||||
define('K_X', 'X');
|
||||
define('K_Y', 'Y');
|
||||
define('K_Z', 'Z');
|
||||
define('K_bracketleft', '[');
|
||||
define('K_bracketright', ']');
|
||||
define('K_circum', '^');
|
||||
define('K_underscore', '_');
|
||||
define('K_grave', '`');
|
||||
define('K_a', 'a');
|
||||
define('K_b', 'b');
|
||||
define('K_c', 'c');
|
||||
define('K_d', 'd');
|
||||
define('K_e', 'e');
|
||||
define('K_f', 'f');
|
||||
define('K_g', 'g');
|
||||
define('K_h', 'h');
|
||||
define('K_i', 'i');
|
||||
define('K_j', 'j');
|
||||
define('K_k', 'k');
|
||||
define('K_l', 'l');
|
||||
define('K_m', 'm');
|
||||
define('K_n', 'n');
|
||||
define('K_o', 'o');
|
||||
define('K_p', 'p');
|
||||
define('K_q', 'q');
|
||||
define('K_r', 'r');
|
||||
define('K_s', 's');
|
||||
define('K_t', 't');
|
||||
define('K_u', 'u');
|
||||
define('K_v', 'v');
|
||||
define('K_w', 'w');
|
||||
define('K_x', 'x');
|
||||
define('K_y', 'y');
|
||||
define('K_z', 'z');
|
||||
define('K_braceleft', '{');
|
||||
define('K_bar', '|');
|
||||
define('K_braceright', '}');
|
||||
define('K_tilde', '~');
|
||||
define('K_BS', '\\b');
|
||||
define('K_TAB', "\t");
|
||||
define('K_LF', "\n");
|
||||
define('K_CR', "\r");
|
||||
define('K_quoteleft', '`');
|
||||
define('K_quoteright', "'");
|
||||
define('K_PAUSE', 65299);
|
||||
define('K_ESC', 65307);
|
||||
define('K_HOME', 65360);
|
||||
define('K_LEFT', 65361);
|
||||
define('K_UP', 65362);
|
||||
define('K_RIGHT', 65363);
|
||||
define('K_DOWN', 65364);
|
||||
define('K_PGUP', 65365);
|
||||
define('K_PGDN', 65366);
|
||||
define('K_END', 65367);
|
||||
define('K_MIDDLE', 65291);
|
||||
define('K_Print', 65377);
|
||||
define('K_INS', 65379);
|
||||
define('K_Menu', 65383);
|
||||
define('K_DEL', 65535);
|
||||
define('K_F1', 65470);
|
||||
define('K_F2', 65471);
|
||||
define('K_F3', 65472);
|
||||
define('K_F4', 65473);
|
||||
define('K_F5', 65474);
|
||||
define('K_F6', 65475);
|
||||
define('K_F7', 65476);
|
||||
define('K_F8', 65477);
|
||||
define('K_F9', 65478);
|
||||
define('K_F10', 65479);
|
||||
define('K_F11', 65480);
|
||||
define('K_F12', 65481);
|
||||
define('K_F13', 65482);
|
||||
define('K_F14', 65483);
|
||||
define('K_F15', 65484);
|
||||
define('K_F16', 65485);
|
||||
define('K_F17', 65486);
|
||||
define('K_F18', 65487);
|
||||
define('K_F19', 65488);
|
||||
define('K_F20', 65489);
|
||||
define('K_LSHIFT', 65505);
|
||||
define('K_RSHIFT', 65506);
|
||||
define('K_LCTRL', 65507);
|
||||
define('K_RCTRL', 65508);
|
||||
define('K_LALT', 65513);
|
||||
define('K_RALT', 65514);
|
||||
define('K_NUM', 65407);
|
||||
define('K_SCROLL', 65300);
|
||||
define('K_CAPS', 65509);
|
||||
define('K_CLEAR', 65490);
|
||||
define('K_HELP', 65491);
|
||||
define('K_ccedilla', 231);
|
||||
define('K_Ccedilla', 199);
|
||||
define('K_acute', 180);
|
||||
define('K_diaeresis', 168);
|
||||
define('IUP_RUN', 'RUN');
|
||||
define('IUP_ENGLISH', 'ENGLISH');
|
||||
define('IUP_PORTUGUESE', 'PORTUGUESE');
|
||||
define('IUP_SBH', 'SBH');
|
||||
define('IUP_SBV', 'SBV');
|
||||
define('IUP_IDLE_ACTION', 'IDLE_ACTION');
|
||||
define('IUP_ACTION', 'ACTION');
|
||||
define('IUP_GETFOCUS_CB', 'GETFOCUS_CB');
|
||||
define('IUP_KILLFOCUS_CB', 'KILLFOCUS_CB');
|
||||
define('IUP_K_ANY', 'K_ANY');
|
||||
define('IUP_KEYPRESS_CB', 'KEYPRESS_CB');
|
||||
define('IUP_HELP_CB', 'HELP_CB');
|
||||
define('IUP_SCROLL_CB', 'SCROLL_CB');
|
||||
define('IUP_RESIZE_CB', 'RESIZE_CB');
|
||||
define('IUP_MOTION_CB', 'MOTION_CB');
|
||||
define('IUP_BUTTON_CB', 'BUTTON_CB');
|
||||
define('IUP_ENTERWINDOW_CB', 'ENTERWINDOW_CB');
|
||||
define('IUP_LEAVEWINDOW_CB', 'LEAVEWINDOW_CB');
|
||||
define('IUP_WHEEL_CB', 'WHEEL_CB');
|
||||
define('IUP_MASK_CB', 'MASK_CB');
|
||||
define('IUP_OPEN_CB', 'OPEN_CB');
|
||||
define('IUP_HIGHLIGHT_CB', 'HIGHLIGHT_CB');
|
||||
define('IUP_MENUCLOSE_CB', 'MENUCLOSE_CB');
|
||||
define('IUP_MAP_CB', 'MAP_CB');
|
||||
define('IUP_CLOSE_CB', 'CLOSE_CB');
|
||||
define('IUP_SHOW_CB', 'SHOW_CB');
|
||||
define('IUP_DROPFILES_CB', 'DROPFILES_CB');
|
||||
define('IUP_WOM_CB', 'WOM_CB');
|
||||
define('IUP_DIRECTION', 'DIRECTION');
|
||||
define('IUP_ACTIVE', 'ACTIVE');
|
||||
define('IUP_BGCOLOR', 'BGCOLOR');
|
||||
define('IUP_FRAMECOLOR', 'FRAMECOLOR');
|
||||
define('IUP_FGCOLOR', 'FGCOLOR');
|
||||
define('IUP_COLOR', 'COLOR');
|
||||
define('IUP_WID', 'WID');
|
||||
define('IUP_SIZE', 'SIZE');
|
||||
define('IUP_RASTERSIZE', 'RASTERSIZE');
|
||||
define('IUP_TITLE', 'TITLE');
|
||||
define('IUP_VALUE', 'VALUE');
|
||||
define('IUP_VISIBLE', 'VISIBLE');
|
||||
define('IUP_FONT', 'FONT');
|
||||
define('IUP_TIP', 'TIP');
|
||||
define('IUP_EXPAND', 'EXPAND');
|
||||
define('IUP_SEPARATOR', 'SEPARATOR');
|
||||
define('IUP_HOTSPOT', 'HOTSPOT');
|
||||
define('IUP_HEIGHT', 'HEIGHT');
|
||||
define('IUP_WIDTH', 'WIDTH');
|
||||
define('IUP_KEY', 'KEY');
|
||||
define('IUP_MULTIPLE', 'MULTIPLE');
|
||||
define('IUP_DROPDOWN', 'DROPDOWN');
|
||||
define('IUP_VISIBLE_ITEMS', 'VISIBLE_ITEMS');
|
||||
define('IUP_MARGIN', 'MARGIN');
|
||||
define('IUP_GAP', 'GAP');
|
||||
define('IUP_ALIGNMENT', 'ALIGNMENT');
|
||||
define('IUP_IMAGE', 'IMAGE');
|
||||
define('IUP_IMINACTIVE', 'IMINACTIVE');
|
||||
define('IUP_IMPRESS', 'IMPRESS');
|
||||
define('IUP_WIN_SAVEBITS', 'WIN_SAVEBITS');
|
||||
define('IUP_NC', 'NC');
|
||||
define('IUP_MASK', 'MASK');
|
||||
define('IUP_APPEND', 'APPEND');
|
||||
define('IUP_BORDER', 'BORDER');
|
||||
define('IUP_CARET', 'CARET');
|
||||
define('IUP_SELECTION', 'SELECTION');
|
||||
define('IUP_SELECTEDTEXT', 'SELECTEDTEXT');
|
||||
define('IUP_INSERT', 'INSERT');
|
||||
define('IUP_CONID', 'CONID');
|
||||
define('IUP_CURSOR', 'CURSOR');
|
||||
define('IUP_ICON', 'ICON');
|
||||
define('IUP_MENUBOX', 'MENUBOX');
|
||||
define('IUP_MINBOX', 'MINBOX');
|
||||
define('IUP_MAXBOX', 'MAXBOX');
|
||||
define('IUP_RESIZE', 'RESIZE');
|
||||
define('IUP_MENU', 'MENU');
|
||||
define('IUP_STARTFOCUS', 'STARTFOCUS');
|
||||
define('IUP_PARENTDIALOG', 'PARENTDIALOG');
|
||||
define('IUP_SHRINK', 'SHRINK');
|
||||
define('IUP_DEFAULTENTER', 'DEFAULTENTER');
|
||||
define('IUP_DEFAULTESC', 'DEFAULTESC');
|
||||
define('IUP_X', 'X');
|
||||
define('IUP_Y', 'Y');
|
||||
define('IUP_TOOLBOX', 'TOOLBOX');
|
||||
define('IUP_CONTROL', 'CONTROL');
|
||||
define('IUP_READONLY', 'READONLY');
|
||||
define('IUP_SCROLLBAR', 'SCROLLBAR');
|
||||
define('IUP_POSY', 'POSY');
|
||||
define('IUP_POSX', 'POSX');
|
||||
define('IUP_DX', 'DX');
|
||||
define('IUP_DY', 'DY');
|
||||
define('IUP_XMAX', 'XMAX');
|
||||
define('IUP_XMIN', 'XMIN');
|
||||
define('IUP_YMAX', 'YMAX');
|
||||
define('IUP_YMIN', 'YMIN');
|
||||
define('IUP_RED', '255 0 0');
|
||||
define('IUP_GREEN', '0 255 0');
|
||||
define('IUP_BLUE', '0 0 255');
|
||||
define('IUP_MIN', 'MIN');
|
||||
define('IUP_MAX', 'MAX');
|
||||
define('IUP_TIME', 'TIME');
|
||||
define('IUP_DRAG', 'DRAG');
|
||||
define('IUP_DROP', 'DROP');
|
||||
define('IUP_REPAINT', 'REPAINT');
|
||||
define('IUP_TOPMOST', 'TOPMOST');
|
||||
define('IUP_CLIPCHILDREN', 'CLIPCHILDREN');
|
||||
define('IUP_DIALOGTYPE', 'DIALOGTYPE');
|
||||
define('IUP_FILE', 'FILE');
|
||||
define('IUP_MULTIPLEFILES', 'MULTIPLEFILES');
|
||||
define('IUP_FILTER', 'FILTER');
|
||||
define('IUP_FILTERUSED', 'FILTERUSED');
|
||||
define('IUP_FILTERINFO', 'FILTERINFO');
|
||||
define('IUP_EXTFILTER', 'EXTFILTER');
|
||||
define('IUP_DIRECTORY', 'DIRECTORY');
|
||||
define('IUP_ALLOWNEW', 'ALLOWNEW');
|
||||
define('IUP_NOOVERWRITEPROMPT', 'NOOVERWRITEPROMPT');
|
||||
define('IUP_NOCHANGEDIR', 'NOCHANGEDIR');
|
||||
define('IUP_FILEEXIST', 'FILEEXIST');
|
||||
define('IUP_STATUS', 'STATUS');
|
||||
define('IUP_LOCKLOOP', 'LOCKLOOP');
|
||||
define('IUP_SYSTEM', 'SYSTEM');
|
||||
define('IUP_DRIVER', 'DRIVER');
|
||||
define('IUP_SCREENSIZE', 'SCREENSIZE');
|
||||
define('IUP_SYSTEMLANGUAGE', 'SYSTEMLANGUAGE');
|
||||
define('IUP_COMPUTERNAME', 'COMPUTERNAME');
|
||||
define('IUP_USERNAME', 'USERNAME');
|
||||
define('IUP_OPEN', 'OPEN');
|
||||
define('IUP_SAVE', 'SAVE');
|
||||
define('IUP_DIR', 'DIR');
|
||||
define('IUP_HORIZONTAL', 'HORIZONTAL');
|
||||
define('IUP_VERTICAL', 'VERTICAL');
|
||||
define('IUP_YES', 'YES');
|
||||
define('IUP_NO', 'NO');
|
||||
define('IUP_ON', 'ON');
|
||||
define('IUP_OFF', 'OFF');
|
||||
define('IUP_ACENTER', 'ACENTER');
|
||||
define('IUP_ALEFT', 'ALEFT');
|
||||
define('IUP_ARIGHT', 'ARIGHT');
|
||||
define('IUP_ATOP', 'ATOP');
|
||||
define('IUP_ABOTTOM', 'ABOTTOM');
|
||||
define('IUP_NORTH', 'NORTH');
|
||||
define('IUP_SOUTH', 'SOUTH');
|
||||
define('IUP_WEST', 'WEST');
|
||||
define('IUP_EAST', 'EAST');
|
||||
define('IUP_NE', 'NE');
|
||||
define('IUP_SE', 'SE');
|
||||
define('IUP_NW', 'NW');
|
||||
define('IUP_SW', 'SW');
|
||||
define('IUP_FULLSCREEN', 'FULLSCREEN');
|
||||
define('IUP_FULL', 'FULL');
|
||||
define('IUP_HALF', 'HALF');
|
||||
define('IUP_THIRD', 'THIRD');
|
||||
define('IUP_QUARTER', 'QUARTER');
|
||||
define('IUP_EIGHTH', 'EIGHTH');
|
||||
define('IUP_ARROW', 'ARROW');
|
||||
define('IUP_BUSY', 'BUSY');
|
||||
define('IUP_RESIZE_N', 'RESIZE_N');
|
||||
define('IUP_RESIZE_S', 'RESIZE_S');
|
||||
define('IUP_RESIZE_E', 'RESIZE_E');
|
||||
define('IUP_RESIZE_W', 'RESIZE_W');
|
||||
define('IUP_RESIZE_NE', 'RESIZE_NE');
|
||||
define('IUP_RESIZE_NW', 'RESIZE_NW');
|
||||
define('IUP_RESIZE_SE', 'RESIZE_SE');
|
||||
define('IUP_RESIZE_SW', 'RESIZE_SW');
|
||||
define('IUP_MOVE', 'MOVE');
|
||||
define('IUP_HAND', 'HAND');
|
||||
define('IUP_NONE', 'NONE');
|
||||
define('IUP_IUP', 'IUP');
|
||||
define('IUP_CROSS', 'CROSS');
|
||||
define('IUP_PEN', 'PEN');
|
||||
define('IUP_TEXT', 'TEXT');
|
||||
define('IUP_RESIZE_C', 'RESIZE_C');
|
||||
define('IUP_OPENHAND', 'OPENHAND');
|
||||
define('IUP_K_exclam', 'K_exclam');
|
||||
define('IUP_K_quotedbl', 'K_quotedbl');
|
||||
define('IUP_K_numbersign', 'K_numbersign');
|
||||
define('IUP_K_dollar', 'K_dollar');
|
||||
define('IUP_K_percent', 'K_percent');
|
||||
define('IUP_K_ampersand', 'K_ampersand');
|
||||
define('IUP_K_quoteright', 'K_quoteright');
|
||||
define('IUP_K_parentleft', 'K_parentleft');
|
||||
define('IUP_K_parentright', 'K_parentright');
|
||||
define('IUP_K_asterisk', 'K_asterisk');
|
||||
define('IUP_K_plus', 'K_plus');
|
||||
define('IUP_K_comma', 'K_comma');
|
||||
define('IUP_K_minus', 'K_minus');
|
||||
define('IUP_K_period', 'K_period');
|
||||
define('IUP_K_slash', 'K_slash');
|
||||
define('IUP_K_0', 'K_0');
|
||||
define('IUP_K_1', 'K_1');
|
||||
define('IUP_K_2', 'K_2');
|
||||
define('IUP_K_3', 'K_3');
|
||||
define('IUP_K_4', 'K_4');
|
||||
define('IUP_K_5', 'K_5');
|
||||
define('IUP_K_6', 'K_6');
|
||||
define('IUP_K_7', 'K_7');
|
||||
define('IUP_K_8', 'K_8');
|
||||
define('IUP_K_9', 'K_9');
|
||||
define('IUP_K_colon', 'K_colon');
|
||||
define('IUP_K_semicolon', 'K_semicolon ');
|
||||
define('IUP_K_less', 'K_less');
|
||||
define('IUP_K_equal', 'K_equal');
|
||||
define('IUP_K_greater', 'K_greater');
|
||||
define('IUP_K_question', 'K_question');
|
||||
define('IUP_K_at', 'K_at');
|
||||
define('IUP_K_A', 'K_A');
|
||||
define('IUP_K_B', 'K_B');
|
||||
define('IUP_K_C', 'K_C');
|
||||
define('IUP_K_D', 'K_D');
|
||||
define('IUP_K_E', 'K_E');
|
||||
define('IUP_K_F', 'K_F');
|
||||
define('IUP_K_G', 'K_G');
|
||||
@@ -38,6 +38,23 @@ const DANGER_CMD = [
|
||||
'rmdir',
|
||||
];
|
||||
|
||||
// spc internal extensions
|
||||
const SPC_INTERNAL_EXTENSIONS = [
|
||||
'core',
|
||||
'hash',
|
||||
'json',
|
||||
'reflection',
|
||||
'spl',
|
||||
'standard',
|
||||
];
|
||||
|
||||
// spc extension alias
|
||||
const SPC_EXTENSION_ALIAS = [
|
||||
'zend opcache' => 'opcache',
|
||||
'zend-opcache' => 'opcache',
|
||||
'zendopcache' => 'opcache',
|
||||
];
|
||||
|
||||
// file replace strategy
|
||||
const REPLACE_FILE_STR = 1;
|
||||
const REPLACE_FILE_PREG = 2;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
assert(class_exists('\\DOMDocument'));
|
||||
assert(class_exists('\DOMDocument'));
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadHtml('<html><head><meta charset="UTF-8"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head><body id="app">Hello</body></html>');
|
||||
assert($doc->getElementById('app')->nodeValue === 'Hello');
|
||||
5
src/globals/ext-tests/parallel.php
Normal file
5
src/globals/ext-tests/parallel.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
assert(class_exists('\parallel\Runtime'));
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
assert(class_exists('\\Redis'));
|
||||
assert(class_exists('\Redis'));
|
||||
5
src/globals/ext-tests/zip.php
Normal file
5
src/globals/ext-tests/zip.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
assert(class_exists('\ZipArchive'));
|
||||
86
src/globals/extra/gd_config_80.w32
Normal file
86
src/globals/extra/gd_config_80.w32
Normal file
@@ -0,0 +1,86 @@
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("gd", "Bundled GD support", "yes");
|
||||
|
||||
if (PHP_GD != "no") {
|
||||
// check for gd.h (required)
|
||||
if (!CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd")) {
|
||||
ERROR("gd not enabled; libraries and headers not found");
|
||||
}
|
||||
|
||||
// zlib ext support (required)
|
||||
if (!CHECK_LIB("zlib_a.lib;zlib.lib", "gd", PHP_GD)) {
|
||||
ERROR("gd not enabled; zlib not enabled");
|
||||
}
|
||||
|
||||
// libjpeg lib support
|
||||
if (CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("jpeglib.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) {
|
||||
AC_DEFINE("HAVE_LIBJPEG", 1, "JPEG support");
|
||||
AC_DEFINE("HAVE_GD_JPG", 1, "JPEG support");
|
||||
}
|
||||
|
||||
// libpng16 lib support
|
||||
if (CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng16")) {
|
||||
AC_DEFINE("HAVE_LIBPNG", 1, "PNG support");
|
||||
AC_DEFINE("HAVE_GD_PNG", 1, "PNG support");
|
||||
}
|
||||
|
||||
// freetype lib support
|
||||
if (CHECK_LIB("libfreetype_a.lib;libfreetype.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("ft2build.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\freetype2;" + PHP_PHP_BUILD + "\\include\\freetype")) {
|
||||
AC_DEFINE("HAVE_LIBFREETYPE", 1, "FreeType support");
|
||||
AC_DEFINE("HAVE_GD_FREETYPE", 1, "FreeType support");
|
||||
}
|
||||
|
||||
// xpm lib support
|
||||
if (CHECK_LIB("libXpm_a.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11")) {
|
||||
AC_DEFINE("HAVE_LIBXPM", 1, "XPM support");
|
||||
AC_DEFINE("HAVE_GD_XPM", 1, "XPM support");
|
||||
}
|
||||
|
||||
// iconv lib support
|
||||
if ((CHECK_LIB("libiconv_a.lib;libiconv.lib", "gd", PHP_GD) || CHECK_LIB("iconv_a.lib;iconv.lib", "gd", PHP_GD)) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_GD", PHP_GD)) {
|
||||
AC_DEFINE("HAVE_LIBICONV", 1, "Iconv support");
|
||||
}
|
||||
|
||||
// libwebp lib support
|
||||
if ((CHECK_LIB("libwebp_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebp.lib", "gd", PHP_GD)) &&
|
||||
CHECK_LIB("libsharpyuv.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") &&
|
||||
CHECK_HEADER_ADD_INCLUDE("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) {
|
||||
AC_DEFINE("HAVE_LIBWEBP", 1, "WebP support");
|
||||
AC_DEFINE("HAVE_GD_WEBP", 1, "WebP support");
|
||||
}
|
||||
|
||||
// libavif lib is not supported on php <= 8.0
|
||||
|
||||
CHECK_LIB("User32.lib", "gd", PHP_GD);
|
||||
CHECK_LIB("Gdi32.lib", "gd", PHP_GD);
|
||||
|
||||
EXTENSION("gd", "gd.c", null, "-Iext/gd/libgd");
|
||||
ADD_SOURCES("ext/gd/libgd", "gd.c \
|
||||
gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \
|
||||
gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \
|
||||
gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \
|
||||
gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c gd_xbm.c gd_security.c gd_transform.c \
|
||||
gd_filter.c gd_pixelate.c gd_rotate.c gd_color_match.c gd_webp.c \
|
||||
gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c gd_tga.c", "gd");
|
||||
|
||||
AC_DEFINE('HAVE_LIBGD', 1, 'GD support');
|
||||
AC_DEFINE('HAVE_GD_BUNDLED', 1, "Bundled GD");
|
||||
AC_DEFINE('HAVE_GD_BMP', 1, "BMP support");
|
||||
AC_DEFINE('HAVE_GD_TGA', 1, "TGA support");
|
||||
ADD_FLAG("CFLAGS_GD", " \
|
||||
/D PHP_GD_EXPORTS=1 \
|
||||
/D HAVE_GD_GET_INTERPOLATION \
|
||||
");
|
||||
if (ICC_TOOLSET) {
|
||||
ADD_FLAG("LDFLAGS_GD", "/nodefaultlib:libcmt");
|
||||
}
|
||||
|
||||
PHP_INSTALL_HEADERS("", "ext/gd ext/gd/libgd");
|
||||
}
|
||||
94
src/globals/extra/gd_config_81.w32
Normal file
94
src/globals/extra/gd_config_81.w32
Normal file
@@ -0,0 +1,94 @@
|
||||
// vim:ft=javascript
|
||||
|
||||
ARG_WITH("gd", "Bundled GD support", "yes");
|
||||
|
||||
if (PHP_GD != "no") {
|
||||
// check for gd.h (required)
|
||||
if (!CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd")) {
|
||||
ERROR("gd not enabled; libraries and headers not found");
|
||||
}
|
||||
|
||||
// zlib ext support (required)
|
||||
if (!CHECK_LIB("zlib_a.lib;zlib.lib", "gd", PHP_GD)) {
|
||||
ERROR("gd not enabled; zlib not enabled");
|
||||
}
|
||||
|
||||
// libjpeg lib support
|
||||
if (CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("jpeglib.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) {
|
||||
AC_DEFINE("HAVE_LIBJPEG", 1, "JPEG support");
|
||||
AC_DEFINE("HAVE_GD_JPG", 1, "JPEG support");
|
||||
}
|
||||
|
||||
// libpng16 lib support
|
||||
if (CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng16")) {
|
||||
AC_DEFINE("HAVE_LIBPNG", 1, "PNG support");
|
||||
AC_DEFINE("HAVE_GD_PNG", 1, "PNG support");
|
||||
}
|
||||
|
||||
// freetype lib support
|
||||
if (CHECK_LIB("libfreetype_a.lib;libfreetype.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("ft2build.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\freetype2;" + PHP_PHP_BUILD + "\\include\\freetype")) {
|
||||
AC_DEFINE("HAVE_LIBFREETYPE", 1, "FreeType support");
|
||||
AC_DEFINE("HAVE_GD_FREETYPE", 1, "FreeType support");
|
||||
}
|
||||
|
||||
// xpm lib support
|
||||
if (CHECK_LIB("libXpm_a.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11")) {
|
||||
AC_DEFINE("HAVE_LIBXPM", 1, "XPM support");
|
||||
AC_DEFINE("HAVE_GD_XPM", 1, "XPM support");
|
||||
}
|
||||
|
||||
// iconv lib support
|
||||
if ((CHECK_LIB("libiconv_a.lib;libiconv.lib", "gd", PHP_GD) || CHECK_LIB("iconv_a.lib;iconv.lib", "gd", PHP_GD)) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_GD", PHP_GD)) {
|
||||
AC_DEFINE("HAVE_LIBICONV", 1, "Iconv support");
|
||||
}
|
||||
|
||||
// libwebp lib support
|
||||
if ((CHECK_LIB("libwebp_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebp.lib", "gd", PHP_GD)) &&
|
||||
CHECK_LIB("libsharpyuv.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") &&
|
||||
CHECK_HEADER_ADD_INCLUDE("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) {
|
||||
AC_DEFINE("HAVE_LIBWEBP", 1, "WebP support");
|
||||
AC_DEFINE("HAVE_GD_WEBP", 1, "WebP support");
|
||||
}
|
||||
|
||||
// libavif lib support
|
||||
if (CHECK_LIB("avif_a.lib", "gd", PHP_GD) &&
|
||||
CHECK_LIB("aom_a.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) {
|
||||
ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF");
|
||||
} else if (CHECK_LIB("avif.lib", "gd", PHP_GD) &&
|
||||
CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) {
|
||||
ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF");
|
||||
}
|
||||
|
||||
CHECK_LIB("User32.lib", "gd", PHP_GD);
|
||||
CHECK_LIB("Gdi32.lib", "gd", PHP_GD);
|
||||
|
||||
EXTENSION("gd", "gd.c", null, "-Iext/gd/libgd");
|
||||
ADD_SOURCES("ext/gd/libgd", "gd.c \
|
||||
gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \
|
||||
gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \
|
||||
gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \
|
||||
gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c gd_xbm.c gd_security.c gd_transform.c \
|
||||
gd_filter.c gd_pixelate.c gd_rotate.c gd_color_match.c gd_webp.c gd_avif.c \
|
||||
gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c gd_tga.c", "gd");
|
||||
|
||||
AC_DEFINE('HAVE_LIBGD', 1, 'GD support');
|
||||
AC_DEFINE('HAVE_GD_BUNDLED', 1, "Bundled GD");
|
||||
AC_DEFINE('HAVE_GD_BMP', 1, "BMP support");
|
||||
AC_DEFINE('HAVE_GD_TGA', 1, "TGA support");
|
||||
ADD_FLAG("CFLAGS_GD", " \
|
||||
/D PHP_GD_EXPORTS=1 \
|
||||
/D HAVE_GD_GET_INTERPOLATION \
|
||||
");
|
||||
if (ICC_TOOLSET) {
|
||||
ADD_FLAG("LDFLAGS_GD", "/nodefaultlib:libcmt");
|
||||
}
|
||||
|
||||
PHP_INSTALL_HEADERS("", "ext/gd ext/gd/libgd");
|
||||
}
|
||||
128
src/globals/extra/libcares_dnsinfo.h
Normal file
128
src/globals/extra/libcares_dnsinfo.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2006, 2008, 2009, 2011-2013, 2015-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DNSINFO_H__
|
||||
#define __DNSINFO_H__
|
||||
|
||||
/*
|
||||
* These routines provide access to the systems DNS configuration
|
||||
*/
|
||||
|
||||
#include <os/availability.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define DNSINFO_VERSION 20170629
|
||||
|
||||
#define DEFAULT_SEARCH_ORDER 200000 /* search order for the "default" resolver domain name */
|
||||
|
||||
#define DNS_PTR(type, name) \
|
||||
union { \
|
||||
type name; \
|
||||
uint64_t _ ## name ## _p; \
|
||||
}
|
||||
|
||||
#define DNS_VAR(type, name) \
|
||||
type name
|
||||
|
||||
|
||||
#pragma pack(4)
|
||||
typedef struct {
|
||||
struct in_addr address;
|
||||
struct in_addr mask;
|
||||
} dns_sortaddr_t;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#pragma pack(4)
|
||||
typedef struct {
|
||||
DNS_PTR(char *, domain); /* domain */
|
||||
DNS_VAR(int32_t, n_nameserver); /* # nameserver */
|
||||
DNS_PTR(struct sockaddr **, nameserver);
|
||||
DNS_VAR(uint16_t, port); /* port (in host byte order) */
|
||||
DNS_VAR(int32_t, n_search); /* # search */
|
||||
DNS_PTR(char **, search);
|
||||
DNS_VAR(int32_t, n_sortaddr); /* # sortaddr */
|
||||
DNS_PTR(dns_sortaddr_t **, sortaddr);
|
||||
DNS_PTR(char *, options); /* options */
|
||||
DNS_VAR(uint32_t, timeout); /* timeout */
|
||||
DNS_VAR(uint32_t, search_order); /* search_order */
|
||||
DNS_VAR(uint32_t, if_index);
|
||||
DNS_VAR(uint32_t, flags);
|
||||
DNS_VAR(uint32_t, reach_flags); /* SCNetworkReachabilityFlags */
|
||||
DNS_VAR(uint32_t, service_identifier);
|
||||
DNS_PTR(char *, cid); /* configuration identifer */
|
||||
DNS_PTR(char *, if_name); /* if_index interface name */
|
||||
} dns_resolver_t;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
#define DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS 0x0002 /* always requesting for A dns records in queries */
|
||||
#define DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS 0x0004 /* always requesting for AAAA dns records in queries */
|
||||
|
||||
#define DNS_RESOLVER_FLAGS_REQUEST_ALL_RECORDS \
|
||||
(DNS_RESOLVER_FLAGS_REQUEST_A_RECORDS | DNS_RESOLVER_FLAGS_REQUEST_AAAA_RECORDS)
|
||||
|
||||
#define DNS_RESOLVER_FLAGS_SCOPED 0x1000 /* configuration is for scoped questions */
|
||||
#define DNS_RESOLVER_FLAGS_SERVICE_SPECIFIC 0x2000 /* configuration is service-specific */
|
||||
#define DNS_RESOLVER_FLAGS_SUPPLEMENTAL 0x4000 /* supplemental match configuration */
|
||||
|
||||
|
||||
#pragma pack(4)
|
||||
typedef struct {
|
||||
DNS_VAR(int32_t, n_resolver); /* resolver configurations */
|
||||
DNS_PTR(dns_resolver_t **, resolver);
|
||||
DNS_VAR(int32_t, n_scoped_resolver); /* "scoped" resolver configurations */
|
||||
DNS_PTR(dns_resolver_t **, scoped_resolver);
|
||||
DNS_VAR(uint64_t, generation);
|
||||
DNS_VAR(int32_t, n_service_specific_resolver);
|
||||
DNS_PTR(dns_resolver_t **, service_specific_resolver);
|
||||
DNS_VAR(uint32_t, version);
|
||||
} dns_config_t;
|
||||
#pragma pack()
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*
|
||||
* DNS configuration access APIs
|
||||
*/
|
||||
const char *
|
||||
dns_configuration_notify_key (void) API_AVAILABLE(macos(10.4), ios(2.0));
|
||||
|
||||
dns_config_t *
|
||||
dns_configuration_copy (void) API_AVAILABLE(macos(10.4), ios(2.0));
|
||||
|
||||
void
|
||||
dns_configuration_free (dns_config_t *config) API_AVAILABLE(macos(10.4), ios(2.0));
|
||||
|
||||
void
|
||||
_dns_configuration_ack (dns_config_t *config,
|
||||
const char *bundle_id) API_AVAILABLE(macos(10.8), ios(6.0));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* __DNSINFO_H__ */
|
||||
@@ -47,13 +47,26 @@ function arch2gnu(string $arch): string
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Match pattern function
|
||||
* Example: match_pattern('*.txt', 'test.txt') will return true.
|
||||
*
|
||||
* @param string $pattern Pattern string
|
||||
* @param string $subject Subject string
|
||||
*/
|
||||
function match_pattern(string $pattern, string $subject): bool
|
||||
{
|
||||
$pattern = str_replace(['\*', '\\\\.*'], ['.*', '\*'], preg_quote($pattern, '/'));
|
||||
$pattern = str_replace(['\*', '\\\.*'], ['.*', '\*'], preg_quote($pattern, '/'));
|
||||
$pattern = '/^' . $pattern . '$/i';
|
||||
return preg_match($pattern, $subject) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote a string with a quote character
|
||||
*
|
||||
* @param string $str String to quote
|
||||
* @param string $quote Quote character, default: `"`
|
||||
*/
|
||||
function quote(string $str, string $quote = '"'): string
|
||||
{
|
||||
return $quote . $str . $quote;
|
||||
@@ -61,7 +74,6 @@ function quote(string $str, string $quote = '"'): string
|
||||
|
||||
/**
|
||||
* Get Family name of current OS
|
||||
*
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
function osfamily2dir(): string
|
||||
@@ -76,6 +88,41 @@ function osfamily2dir(): string
|
||||
};
|
||||
}
|
||||
|
||||
function shell(?bool $debug = null): UnixShell
|
||||
{
|
||||
/* @noinspection PhpUnhandledExceptionInspection */
|
||||
return new UnixShell($debug);
|
||||
}
|
||||
|
||||
function cmd(?bool $debug = null): WindowsCmd
|
||||
{
|
||||
/* @noinspection PhpUnhandledExceptionInspection */
|
||||
return new WindowsCmd($debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current builder.
|
||||
*
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
function builder(): BuilderBase
|
||||
{
|
||||
return BuilderProvider::getBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current patch point.
|
||||
*
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
function patch_point(): string
|
||||
{
|
||||
return BuilderProvider::getBuilder()->getPatchPoint();
|
||||
}
|
||||
|
||||
// ------- function f_* part -------
|
||||
// f_ means standard function wrapper
|
||||
|
||||
/**
|
||||
* Execute the shell command, and the output will be directly printed in the terminal. If there is an error, an exception will be thrown
|
||||
*
|
||||
@@ -126,33 +173,3 @@ function f_putenv(string $env): bool
|
||||
logger()->debug('Setting env: ' . $env);
|
||||
return putenv($env);
|
||||
}
|
||||
|
||||
function shell(?bool $debug = null): UnixShell
|
||||
{
|
||||
return new UnixShell($debug);
|
||||
}
|
||||
|
||||
function cmd(?bool $debug = null): WindowsCmd
|
||||
{
|
||||
return new WindowsCmd($debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current builder.
|
||||
*
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
function builder(): BuilderBase
|
||||
{
|
||||
return BuilderProvider::getBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current patch point.
|
||||
*
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
function patch_point(): string
|
||||
{
|
||||
return BuilderProvider::getBuilder()->getPatchPoint();
|
||||
}
|
||||
|
||||
89
src/globals/patch/spc_fix_libxml2_12_php80.patch
Normal file
89
src/globals/patch/spc_fix_libxml2_12_php80.patch
Normal file
@@ -0,0 +1,89 @@
|
||||
diff --git a/ext/dom/document.c b/ext/dom/document.c
|
||||
index 02522b50..6d1b0740 100644
|
||||
--- a/ext/dom/document.c
|
||||
+++ b/ext/dom/document.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#if defined(HAVE_LIBXML) && defined(HAVE_DOM)
|
||||
#include "php_dom.h"
|
||||
#include <libxml/SAX.h>
|
||||
+#include <libxml/xmlsave.h>
|
||||
#ifdef LIBXML_SCHEMAS_ENABLED
|
||||
#include <libxml/relaxng.h>
|
||||
#include <libxml/xmlschemas.h>
|
||||
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
|
||||
index 73486ae2..59bd3d20 100644
|
||||
--- a/ext/libxml/libxml.c
|
||||
+++ b/ext/libxml/libxml.c
|
||||
@@ -382,7 +382,7 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
|
||||
|
||||
if (encoding) {
|
||||
char *end;
|
||||
-
|
||||
+
|
||||
encoding += sizeof("charset=")-1;
|
||||
if (*encoding == '"') {
|
||||
encoding++;
|
||||
@@ -481,7 +481,11 @@ static void _php_libxml_free_error(void *ptr)
|
||||
xmlResetError((xmlErrorPtr) ptr);
|
||||
}
|
||||
|
||||
-static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg)
|
||||
+#if LIBXML_VERSION >= 21200
|
||||
+static void _php_list_set_error_structure(const xmlError *error, const char *msg)
|
||||
+#else
|
||||
+static void _php_list_set_error_structure(xmlError *error, const char *msg)
|
||||
+#endif
|
||||
{
|
||||
xmlError error_copy;
|
||||
int ret;
|
||||
@@ -732,7 +736,11 @@ PHP_LIBXML_API void php_libxml_ctx_warning(void *ctx, const char *msg, ...)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
+#if LIBXML_VERSION >= 21200
|
||||
+PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, const xmlError *error)
|
||||
+#else
|
||||
PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, xmlErrorPtr error)
|
||||
+#endif
|
||||
{
|
||||
_php_list_set_error_structure(error, NULL);
|
||||
|
||||
@@ -1035,11 +1043,9 @@ PHP_FUNCTION(libxml_use_internal_errors)
|
||||
/* {{{ Retrieve last error from libxml */
|
||||
PHP_FUNCTION(libxml_get_last_error)
|
||||
{
|
||||
- xmlErrorPtr error;
|
||||
-
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
- error = xmlGetLastError();
|
||||
+ const xmlError *error = xmlGetLastError();
|
||||
|
||||
if (error) {
|
||||
object_init_ex(return_value, libxmlerror_class_entry);
|
||||
diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h
|
||||
index d0ce7cec..02717417 100644
|
||||
--- a/ext/libxml/php_libxml.h
|
||||
+++ b/ext/libxml/php_libxml.h
|
||||
@@ -35,6 +35,7 @@ extern zend_module_entry libxml_module_entry;
|
||||
|
||||
#include "zend_smart_str.h"
|
||||
#include <libxml/tree.h>
|
||||
+#include <libxml/parser.h>
|
||||
|
||||
#define LIBXML_SAVE_NOEMPTYTAG 1<<2
|
||||
|
||||
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
|
||||
index e5e7f2f9..00b58b87 100644
|
||||
--- a/ext/soap/php_sdl.c
|
||||
+++ b/ext/soap/php_sdl.c
|
||||
@@ -331,8 +331,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
|
||||
sdl_restore_uri_credentials(ctx);
|
||||
|
||||
if (!wsdl) {
|
||||
- xmlErrorPtr xmlErrorPtr = xmlGetLastError();
|
||||
-
|
||||
+ const xmlError *xmlErrorPtr = xmlGetLastError();
|
||||
if (xmlErrorPtr) {
|
||||
soap_error2(E_ERROR, "Parsing WSDL: Couldn't load from '%s' : %s", struri, xmlErrorPtr->message);
|
||||
} else {
|
||||
55
src/globals/patch/spc_fix_libxml2_12_php81.patch
Normal file
55
src/globals/patch/spc_fix_libxml2_12_php81.patch
Normal file
@@ -0,0 +1,55 @@
|
||||
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
|
||||
index 3959b362..6cdfbd39 100644
|
||||
--- a/ext/libxml/libxml.c
|
||||
+++ b/ext/libxml/libxml.c
|
||||
@@ -483,7 +483,11 @@ static void _php_libxml_free_error(void *ptr)
|
||||
xmlResetError((xmlErrorPtr) ptr);
|
||||
}
|
||||
|
||||
-static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg)
|
||||
+#if LIBXML_VERSION >= 21200
|
||||
+static void _php_list_set_error_structure(const xmlError *error, const char *msg)
|
||||
+#else
|
||||
+static void _php_list_set_error_structure(xmlError *error, const char *msg)
|
||||
+#endif
|
||||
{
|
||||
xmlError error_copy;
|
||||
int ret;
|
||||
@@ -736,7 +740,11 @@ PHP_LIBXML_API void php_libxml_ctx_warning(void *ctx, const char *msg, ...)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
+#if LIBXML_VERSION >= 21200
|
||||
+PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, const xmlError *error)
|
||||
+#else
|
||||
PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, xmlErrorPtr error)
|
||||
+#endif
|
||||
{
|
||||
_php_list_set_error_structure(error, NULL);
|
||||
|
||||
@@ -1009,11 +1017,9 @@ PHP_FUNCTION(libxml_use_internal_errors)
|
||||
/* {{{ Retrieve last error from libxml */
|
||||
PHP_FUNCTION(libxml_get_last_error)
|
||||
{
|
||||
- xmlErrorPtr error;
|
||||
-
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
|
||||
- error = xmlGetLastError();
|
||||
+ const xmlError *error = xmlGetLastError();
|
||||
|
||||
if (error) {
|
||||
object_init_ex(return_value, libxmlerror_class_entry);
|
||||
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
|
||||
index 651eab23..7a7ce304 100644
|
||||
--- a/ext/soap/php_sdl.c
|
||||
+++ b/ext/soap/php_sdl.c
|
||||
@@ -332,7 +332,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
|
||||
sdl_restore_uri_credentials(ctx);
|
||||
|
||||
if (!wsdl) {
|
||||
- xmlErrorPtr xmlErrorPtr = xmlGetLastError();
|
||||
+ const xmlError *xmlErrorPtr = xmlGetLastError();
|
||||
|
||||
if (xmlErrorPtr) {
|
||||
soap_error2(E_ERROR, "Parsing WSDL: Couldn't load from '%s' : %s", struri, xmlErrorPtr->message);
|
||||
@@ -11,23 +11,29 @@ declare(strict_types=1);
|
||||
|
||||
// --------------------------------- edit area ---------------------------------
|
||||
|
||||
$zts = false;
|
||||
|
||||
$no_strip = false;
|
||||
|
||||
$upx = true;
|
||||
|
||||
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
|
||||
$extensions = match (PHP_OS_FAMILY) {
|
||||
'Linux', 'Darwin' => 'readline,pgsql,xml,dom,mbstring,mbregex,pdo_pgsql',
|
||||
'Windows' => 'mbstring,pdo_sqlite,mbregex',
|
||||
'Linux', 'Darwin' => 'sockets',
|
||||
'Windows' => 'mbstring,pdo_sqlite,mbregex,gd',
|
||||
};
|
||||
|
||||
// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`).
|
||||
$with_libs = match (PHP_OS_FAMILY) {
|
||||
'Linux', 'Darwin' => '',
|
||||
'Windows' => '',
|
||||
'Windows' => 'libjpeg,libwebp,libavif,freetype',
|
||||
};
|
||||
|
||||
// Please change your test base combination. We recommend testing with `common`.
|
||||
// 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' => 'none',
|
||||
'Linux', 'Darwin' => 'minimal',
|
||||
'Windows' => 'none',
|
||||
};
|
||||
|
||||
@@ -71,5 +77,8 @@ echo match ($argv[1]) {
|
||||
'libs' => $final_libs,
|
||||
'libs_cmd' => ($final_libs === '' ? '' : (' --with-libs=' . $final_libs)),
|
||||
'cmd' => $final_extensions_cmd . ($final_libs === '' ? '' : (' --with-libs=' . $final_libs)),
|
||||
'zts' => $zts ? '--enable-zts' : '',
|
||||
'no_strip' => $no_strip ? '--no-strip' : '',
|
||||
'upx' => $upx ? '--with-upx-pack' : '',
|
||||
default => '',
|
||||
};
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
assert(class_exists('\\ZipArchive'));
|
||||
@@ -94,7 +94,7 @@ class FileSystemTest extends TestCase
|
||||
*/
|
||||
public function testGetClassesPsr4()
|
||||
{
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\\builder\\extension');
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/builder/extension', 'SPC\builder\extension');
|
||||
foreach ($classes as $class) {
|
||||
$this->assertIsString($class);
|
||||
new \ReflectionClass($class);
|
||||
@@ -185,9 +185,9 @@ class FileSystemTest extends TestCase
|
||||
public function testIsRelativePath()
|
||||
{
|
||||
$this->assertTrue(FileSystem::isRelativePath('.'));
|
||||
$this->assertTrue(FileSystem::isRelativePath('.\\sdf'));
|
||||
$this->assertTrue(FileSystem::isRelativePath('.\sdf'));
|
||||
if (DIRECTORY_SEPARATOR === '\\') {
|
||||
$this->assertFalse(FileSystem::isRelativePath('C:\\asdasd/fwe\asd'));
|
||||
$this->assertFalse(FileSystem::isRelativePath('C:\asdasd/fwe\asd'));
|
||||
} else {
|
||||
$this->assertFalse(FileSystem::isRelativePath('/fwefwefewf'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user