mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-12 11:25:35 +08:00
Compare commits
30 Commits
2.2.1
...
eb00e0012f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb00e0012f | ||
|
|
f645c8869a | ||
|
|
351e391221 | ||
|
|
1d78a231db | ||
|
|
9463cf94ca | ||
|
|
ba127f4e00 | ||
|
|
d4da18e869 | ||
|
|
334a3bdf5d | ||
|
|
a1f632e8c9 | ||
|
|
3445a2cd58 | ||
|
|
3100911802 | ||
|
|
a6236eb98c | ||
|
|
c22488ec57 | ||
|
|
0857a19c3c | ||
|
|
2a03c32bc0 | ||
|
|
0b8a0504a2 | ||
|
|
e9aff8f1d8 | ||
|
|
93cb7e9fbb | ||
|
|
2d2607cd7f | ||
|
|
d80406b8e0 | ||
|
|
db9645641f | ||
|
|
b3018af61c | ||
|
|
7e6c2b4432 | ||
|
|
1ae1c81f9c | ||
|
|
eff698cbe8 | ||
|
|
036e4f52b7 | ||
|
|
d258417afb | ||
|
|
3057d02e37 | ||
|
|
af8204fbf0 | ||
|
|
968b3acbce |
44
.github/workflows/tests.yml
vendored
44
.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
|
||||
@@ -129,13 +132,6 @@ 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"
|
||||
id: composer-cache
|
||||
uses: actions/cache@v4
|
||||
@@ -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)" $(php src/globals/test-extensions.php zts) --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: |
|
||||
|
||||
@@ -74,7 +74,7 @@ static-php-cli(简称 `spc`)有许多特性:
|
||||
|
||||
当前支持编译的 PHP 版本:
|
||||
|
||||
> :warning: 支持,但可能不再提供修复
|
||||
> :warning: 支持,但 static-php-cli 作者可能不再提供补丁修复
|
||||
>
|
||||
> :heavy_check_mark: 支持
|
||||
>
|
||||
@@ -86,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: | |
|
||||
|
||||
|
||||
@@ -82,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
|
||||
>
|
||||
@@ -94,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: | |
|
||||
|
||||
|
||||
358
composer.lock
generated
358
composer.lock
generated
File diff suppressed because it is too large
Load Diff
1650
config/ext.json
1650
config/ext.json
File diff suppressed because it is too large
Load Diff
1340
config/lib.json
1340
config/lib.json
File diff suppressed because it is too large
Load Diff
5
config/pre-built.json
Normal file
5
config/pre-built.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"repo": "static-php/static-php-cli-hosted",
|
||||
"match-pattern": "{name}-{arch}-{os}.tgz",
|
||||
"pack-config": {}
|
||||
}
|
||||
@@ -47,6 +47,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "curl/curl",
|
||||
"match": "curl.+\\.tar\\.xz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
@@ -179,8 +180,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."
|
||||
@@ -190,6 +195,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "unicode-org/icu",
|
||||
"match": "icu4c.+-src\\.tgz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -259,9 +265,15 @@
|
||||
}
|
||||
},
|
||||
"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",
|
||||
"prefer-stable": true,
|
||||
"alt": {
|
||||
"type": "filelist",
|
||||
"url": "https://c-ares.org/download/",
|
||||
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/"
|
||||
},
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE.md"
|
||||
@@ -271,6 +283,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "libevent/libevent",
|
||||
"match": "libevent.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -280,6 +293,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "libffi/libffi",
|
||||
"match": "libffi.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -324,6 +338,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "lz4/lz4",
|
||||
"match": "lz4-.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -360,6 +375,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "jedisct1/libsodium",
|
||||
"match": "libsodium-\\d+(\\.\\d+)*\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -369,6 +385,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "libssh2/libssh2",
|
||||
"match": "libssh2.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
@@ -435,6 +452,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "yaml/libyaml",
|
||||
"match": "yaml-.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "License"
|
||||
@@ -444,6 +462,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "nih-at/libzip",
|
||||
"match": "libzip.+\\.tar\\.xz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -463,7 +482,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"
|
||||
@@ -474,6 +493,7 @@
|
||||
"repo": "mongodb/mongo-php-driver",
|
||||
"path": "php-src/ext/mongodb",
|
||||
"match": "mongodb.+\\.tgz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -492,6 +512,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "nghttp2/nghttp2",
|
||||
"match": "nghttp2.+\\.tar\\.xz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
@@ -501,6 +522,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "kkos/oniguruma",
|
||||
"match": "onig-.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
@@ -640,6 +662,7 @@
|
||||
"type": "ghtar",
|
||||
"path": "php-src/ext/swoole",
|
||||
"repo": "swoole/swoole-src",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -725,6 +748,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "madler/zlib",
|
||||
"match": "zlib.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "text",
|
||||
"text": "(C) 1995-2022 Jean-loup Gailly and Mark Adler\n\nThis software is provided 'as-is', without any express or implied\nwarranty. In no event will the authors be held liable for any damages\narising from the use of this software.\n\nPermission is granted to anyone to use this software for any purpose,\nincluding commercial applications, and to alter it and redistribute it\nfreely, subject to the following restrictions:\n\n1. The origin of this software must not be misrepresented; you must not\n claim that you wrote the original software. If you use this software\n in a product, an acknowledgment in the product documentation would be\n appreciated but is not required.\n2. Altered source versions must be plainly marked as such, and must not be\n misrepresented as being the original software.\n3. This notice may not be removed or altered from any source distribution.\n\nJean-loup Gailly Mark Adler\njloup@gzip.org madler@alumni.caltech.edu"
|
||||
@@ -734,6 +758,7 @@
|
||||
"type": "ghrel",
|
||||
"repo": "facebook/zstd",
|
||||
"match": "zstd.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
|
||||
@@ -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,9 @@ use SPC\command\BuildCliCommand;
|
||||
use SPC\command\BuildLibsCommand;
|
||||
use SPC\command\DeleteDownloadCommand;
|
||||
use SPC\command\dev\AllExtCommand;
|
||||
use SPC\command\dev\ExtVerCommand;
|
||||
use SPC\command\dev\GenerateExtDocCommand;
|
||||
use SPC\command\dev\LibVerCommand;
|
||||
use SPC\command\dev\PhpVerCommand;
|
||||
use SPC\command\dev\SortConfigCommand;
|
||||
use SPC\command\DoctorCommand;
|
||||
@@ -24,7 +27,7 @@ use Symfony\Component\Console\Application;
|
||||
*/
|
||||
final class ConsoleApplication extends Application
|
||||
{
|
||||
public const VERSION = '2.2.1';
|
||||
public const VERSION = '2.3.0';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -47,7 +50,10 @@ final class ConsoleApplication extends Application
|
||||
// Dev commands
|
||||
new AllExtCommand(),
|
||||
new PhpVerCommand(),
|
||||
new LibVerCommand(),
|
||||
new ExtVerCommand(),
|
||||
new SortConfigCommand(),
|
||||
new GenerateExtDocCommand(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -160,7 +161,7 @@ abstract class BuilderBase
|
||||
* @throws WrongUsageException
|
||||
* @internal
|
||||
*/
|
||||
public function proveExts(array $extensions): void
|
||||
public function proveExts(array $extensions, bool $skip_check_deps = false): void
|
||||
{
|
||||
CustomExt::loadCustomExt();
|
||||
$this->emitPatchPoint('before-php-extract');
|
||||
@@ -180,6 +181,10 @@ abstract class BuilderBase
|
||||
$this->addExt($ext);
|
||||
}
|
||||
|
||||
if ($skip_check_deps) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->exts as $ext) {
|
||||
$ext->checkDependency();
|
||||
}
|
||||
@@ -275,6 +280,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.
|
||||
*
|
||||
@@ -434,4 +457,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', '4G');
|
||||
|
||||
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) . '"');
|
||||
@@ -228,6 +228,16 @@ class Extension
|
||||
// do nothing, just throw wrong usage exception if not valid
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current extension version
|
||||
*
|
||||
* @return null|string Version string or null
|
||||
*/
|
||||
public function getExtVersion(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
|
||||
@@ -182,6 +182,16 @@ abstract class LibraryBase
|
||||
// do nothing, just throw wrong usage exception if not valid
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current lib version
|
||||
*
|
||||
* @return null|string Version string or null
|
||||
*/
|
||||
public function getLibVersion(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current builder object.
|
||||
*/
|
||||
|
||||
@@ -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 ';
|
||||
|
||||
36
src/SPC/builder/extension/sqlsrv.php
Normal file
36
src/SPC/builder/extension/sqlsrv.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('sqlsrv')]
|
||||
class sqlsrv extends Extension
|
||||
{
|
||||
private bool $pdo_sqlsrv_patched = false;
|
||||
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows' && $this->builder->getExt('pdo_sqlsrv') === null) {
|
||||
// support sqlsrv without pdo_sqlsrv
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/sqlsrv/config.w32', 'PHP_PDO_SQLSRV', '"no"');
|
||||
$this->pdo_sqlsrv_patched = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
if ($this->pdo_sqlsrv_patched) {
|
||||
// revert pdo_sqlsrv patch
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/sqlsrv/config.w32', '"no" == "no"', 'PHP_PDO_SQLSRV == "no"');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,18 @@ use SPC\util\CustomExt;
|
||||
#[CustomExt('swoole')]
|
||||
class swoole extends Extension
|
||||
{
|
||||
public function getExtVersion(): ?string
|
||||
{
|
||||
// Get version from source directory
|
||||
$file = SOURCE_PATH . '/php-src/ext/swoole/include/swoole_version.h';
|
||||
// Match #define SWOOLE_VERSION "5.1.3"
|
||||
$pattern = '/#define SWOOLE_VERSION "(.+)"/';
|
||||
if (preg_match($pattern, file_get_contents($file), $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
// enable swoole
|
||||
|
||||
@@ -18,7 +18,7 @@ class swow extends Extension
|
||||
}
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(): string
|
||||
public function getConfigureArg(): string
|
||||
{
|
||||
$arg = '--enable-swow';
|
||||
$arg .= $this->builder->getLib('openssl') ? ' --enable-swow-ssl' : ' --disable-swow-ssl';
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,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' : '';
|
||||
@@ -202,7 +202,7 @@ class BSDBuilder extends UnixBuilderBase
|
||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
||||
|
||||
if ($this->phar_patched) {
|
||||
SourcePatcher::patchMicro(['phar'], true);
|
||||
SourcePatcher::unpatchMicroPhar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,7 +149,11 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
|
||||
// process micro upx patch if micro sapi enabled
|
||||
if ($enable_micro) {
|
||||
$this->processMicroUPX();
|
||||
if (version_compare($this->getMicroVersion(), '0.2.0') < 0) {
|
||||
// for phpmicro 0.1.x
|
||||
$this->processMicroUPXLegacy();
|
||||
}
|
||||
// micro latest needs do strip and upx pack later (strip, upx, cut binary manually supported)
|
||||
}
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
@@ -236,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' : '';
|
||||
@@ -250,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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,11 +310,11 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply option --no-strip and --with-upx-pack for micro sapi.
|
||||
* Apply option --no-strip and --with-upx-pack for micro sapi (only for phpmicro 0.1.x)
|
||||
*
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
private function processMicroUPX(): void
|
||||
private function processMicroUPXLegacy(): void
|
||||
{
|
||||
// upx pack and strip for micro
|
||||
// but always restore Makefile.frag.bak first
|
||||
@@ -346,4 +352,26 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
$this->arch_c_flags = getenv('SPC_DEFAULT_C_FLAGS');
|
||||
$this->arch_cxx_flags = getenv('SPC_DEFAULT_CXX_FLAGS');
|
||||
// cmake toolchain
|
||||
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch'), $this->arch_c_flags);
|
||||
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch', php_uname('m')), $this->arch_c_flags);
|
||||
|
||||
// create pkgconfig and include dir (some libs cannot create them automatically)
|
||||
f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true);
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class SystemUtil
|
||||
*/
|
||||
public static function getCpuCount(): int
|
||||
{
|
||||
[$ret, $output] = shell()->execWithResult('sysctl -n hw.ncpu');
|
||||
[$ret, $output] = shell()->execWithResult('sysctl -n hw.ncpu', false);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('Failed to get cpu count');
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
$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) {
|
||||
@@ -162,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']);
|
||||
|
||||
@@ -10,51 +10,27 @@ use SPC\store\FileSystem;
|
||||
|
||||
trait libyaml
|
||||
{
|
||||
public function getLibVersion(): ?string
|
||||
{
|
||||
// Match version from CMakeLists.txt:
|
||||
// Format: set (YAML_VERSION_MAJOR 0)
|
||||
// set (YAML_VERSION_MINOR 2)
|
||||
// set (YAML_VERSION_PATCH 5)
|
||||
$content = FileSystem::readFile($this->source_dir . '/CMakeLists.txt');
|
||||
if (preg_match('/set \(YAML_VERSION_MAJOR (\d+)\)/', $content, $major)
|
||||
&& preg_match('/set \(YAML_VERSION_MINOR (\d+)\)/', $content, $minor)
|
||||
&& preg_match('/set \(YAML_VERSION_PATCH (\d+)\)/', $content, $patch)) {
|
||||
return "{$major[1]}.{$minor[1]}.{$patch[1]}";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
// prepare cmake/config.h.in
|
||||
if (!is_file(SOURCE_PATH . '/libyaml/cmake/config.h.in')) {
|
||||
f_mkdir(SOURCE_PATH . '/libyaml/cmake');
|
||||
file_put_contents(
|
||||
SOURCE_PATH . '/libyaml/cmake/config.h.in',
|
||||
<<<'EOF'
|
||||
#define YAML_VERSION_MAJOR @YAML_VERSION_MAJOR@
|
||||
#define YAML_VERSION_MINOR @YAML_VERSION_MINOR@
|
||||
#define YAML_VERSION_PATCH @YAML_VERSION_PATCH@
|
||||
#define YAML_VERSION_STRING "@YAML_VERSION_STRING@"
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
// prepare yamlConfig.cmake.in
|
||||
if (!is_file(SOURCE_PATH . '/libyaml/yamlConfig.cmake.in')) {
|
||||
file_put_contents(
|
||||
SOURCE_PATH . '/libyaml/yamlConfig.cmake.in',
|
||||
<<<'EOF'
|
||||
# Config file for the yaml library.
|
||||
#
|
||||
# It defines the following variables:
|
||||
# yaml_LIBRARIES - libraries to link against
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set_and_check(yaml_TARGETS "@PACKAGE_CONFIG_DIR_CONFIG@/yamlTargets.cmake")
|
||||
|
||||
if(NOT yaml_TARGETS_IMPORTED)
|
||||
set(yaml_TARGETS_IMPORTED 1)
|
||||
include(${yaml_TARGETS})
|
||||
endif()
|
||||
|
||||
set(yaml_LIBRARIES yaml)
|
||||
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
[$lib, $include, $destdir] = SEPARATED_PATH;
|
||||
|
||||
FileSystem::resetDir($this->source_dir . '/build');
|
||||
|
||||
@@ -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,14 +197,14 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,8 +216,8 @@ class WindowsBuilder extends BuilderBase
|
||||
// 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) {
|
||||
@@ -283,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}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,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');
|
||||
|
||||
21
src/SPC/builder/windows/library/bzip2.php
Normal file
21
src/SPC/builder/windows/library/bzip2.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
class bzip2 extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'bzip2';
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
$nmake = $this->builder->makeSimpleWrapper('nmake /nologo /f Makefile.msc CFLAGS="-DWIN32 -MT -Ox -D_FILE_OFFSET_BITS=64 -nologo"');
|
||||
cmd()->cd($this->source_dir)
|
||||
->execWithWrapper($nmake, 'clean')
|
||||
->execWithWrapper($nmake, 'lib');
|
||||
copy($this->source_dir . '\libbz2.lib', BUILD_LIB_PATH . '\libbz2.lib');
|
||||
copy($this->source_dir . '\libbz2.lib', BUILD_LIB_PATH . '\libbz2_a.lib');
|
||||
copy($this->source_dir . '\bzlib.h', BUILD_INCLUDE_PATH . '\bzlib.h');
|
||||
}
|
||||
}
|
||||
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}"
|
||||
);
|
||||
}
|
||||
}
|
||||
44
src/SPC/builder/windows/library/libyaml.php
Normal file
44
src/SPC/builder/windows/library/libyaml.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libyaml extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libyaml';
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
// reset cmake
|
||||
FileSystem::resetDir($this->source_dir . '\build');
|
||||
|
||||
// check missing files: cmake\config.h.in and .\YamlConfig.cmake.in
|
||||
if (!file_exists($this->source_dir . '\cmake\config.h.in')) {
|
||||
FileSystem::createDir($this->source_dir . '\cmake');
|
||||
copy(ROOT_DIR . '\src\globals\extra\libyaml_config.h.in', $this->source_dir . '\cmake\config.h.in');
|
||||
}
|
||||
if (!file_exists($this->source_dir . '\YamlConfig.cmake.in')) {
|
||||
copy(ROOT_DIR . '\src\globals\extra\libyaml_YamlConfig.cmake.in', $this->source_dir . '\YamlConfig.cmake.in');
|
||||
}
|
||||
|
||||
// start build
|
||||
cmd()->cd($this->source_dir)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper('cmake'),
|
||||
'-B build ' .
|
||||
'-A x64 ' .
|
||||
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
|
||||
'-DCMAKE_BUILD_TYPE=Release ' .
|
||||
'-DBUILD_SHARED_LIBS=OFF ' .
|
||||
'-DBUILD_TESTING=OFF ' .
|
||||
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
|
||||
)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper('cmake'),
|
||||
"--build build --config Release --target install -j{$this->builder->concurrency}"
|
||||
);
|
||||
}
|
||||
}
|
||||
46
src/SPC/builder/windows/library/libzip.php
Normal file
46
src/SPC/builder/windows/library/libzip.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libzip extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libzip';
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
// reset cmake
|
||||
FileSystem::resetDir($this->source_dir . '\build');
|
||||
|
||||
$openssl = $this->builder->getLib('openssl') ? 'ON' : 'OFF';
|
||||
$zstd = $this->builder->getLib('zstd') ? 'ON' : 'OFF';
|
||||
|
||||
// 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 ' .
|
||||
'-DENABLE_BZIP2=ON ' .
|
||||
'-DENABLE_LZMA=ON ' .
|
||||
"-DENABLE_ZSTD={$zstd} " .
|
||||
"-DENABLE_OPENSSL={$openssl} " .
|
||||
'-DBUILD_TOOLS=OFF ' .
|
||||
'-DBUILD_DOC=OFF ' .
|
||||
'-DBUILD_EXAMPLES=OFF ' .
|
||||
'-DBUILD_REGRESS=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 . '\zip.lib', BUILD_LIB_PATH . '\libzip_a.lib');
|
||||
}
|
||||
}
|
||||
39
src/SPC/builder/windows/library/xz.php
Normal file
39
src/SPC/builder/windows/library/xz.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class xz extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'xz';
|
||||
|
||||
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}"
|
||||
);
|
||||
|
||||
// copy liblzma.lib to liblzma_a.lib
|
||||
copy(BUILD_LIB_PATH . '/liblzma.lib', BUILD_LIB_PATH . '/liblzma_a.lib');
|
||||
// patch lzma.h
|
||||
FileSystem::replaceFileStr(BUILD_INCLUDE_PATH . '/lzma.h', 'defined(LZMA_API_STATIC)', 'defined(_WIN32)');
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
@@ -142,4 +144,31 @@ abstract class BaseCommand extends Command
|
||||
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;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -38,7 +38,7 @@ class DownloadCommand extends BaseCommand
|
||||
$this->addOption('for-extensions', 'e', InputOption::VALUE_REQUIRED, 'Fetch by extensions, e.g "openssl,mbstring"');
|
||||
$this->addOption('for-libs', 'l', InputOption::VALUE_REQUIRED, 'Fetch by libraries, e.g "libcares,openssl,onig"');
|
||||
$this->addOption('without-suggestions', null, null, 'Do not fetch suggested sources when using --for-extensions');
|
||||
$this->addOption('ignore-cache-sources', null, InputOption::VALUE_REQUIRED, 'Ignore some source caches, comma separated, e.g "php-src,curl,openssl"', '');
|
||||
$this->addOption('ignore-cache-sources', null, InputOption::VALUE_OPTIONAL, 'Ignore some source caches, comma separated, e.g "php-src,curl,openssl"', '');
|
||||
$this->addOption('retry', 'R', InputOption::VALUE_REQUIRED, 'Set retry time when downloading failed (default: 0)', '0');
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
@@ -147,8 +147,12 @@ class DownloadCommand extends BaseCommand
|
||||
}
|
||||
|
||||
$chosen_sources = array_map('trim', array_filter(explode(',', $this->getArgument('sources'))));
|
||||
$force_list = array_map('trim', array_filter(explode(',', $this->getOption('ignore-cache-sources'))));
|
||||
|
||||
$force_all = empty($this->getOption('ignore-cache-sources'));
|
||||
if (!$force_all) {
|
||||
$force_list = array_map('trim', array_filter(explode(',', $this->getOption('ignore-cache-sources'))));
|
||||
} else {
|
||||
$force_list = [];
|
||||
}
|
||||
if ($this->getOption('all')) {
|
||||
logger()->notice('Downloading with --all option will take more times to download, we recommend you to download with --for-extensions option !');
|
||||
}
|
||||
@@ -182,7 +186,7 @@ class DownloadCommand extends BaseCommand
|
||||
Downloader::downloadSource($source, $new_config, true);
|
||||
} else {
|
||||
logger()->info("Fetching source {$source} [{$ni}/{$cnt}]");
|
||||
Downloader::downloadSource($source, Config::getSource($source), in_array($source, $force_list));
|
||||
Downloader::downloadSource($source, Config::getSource($source), $force_all || in_array($source, $force_list));
|
||||
}
|
||||
}
|
||||
$time = round(microtime(true) - START_TIME, 3);
|
||||
|
||||
@@ -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);
|
||||
|
||||
51
src/SPC/command/dev/ExtVerCommand.php
Normal file
51
src/SPC/command/dev/ExtVerCommand.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command\dev;
|
||||
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\command\BaseCommand;
|
||||
use SPC\store\Config;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand('dev:ext-version', 'Returns version of extension from source directory', ['dev:ext-ver'])]
|
||||
class ExtVerCommand extends BaseCommand
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->addArgument('extension', InputArgument::REQUIRED, 'The library name');
|
||||
}
|
||||
|
||||
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
$this->no_motd = true;
|
||||
parent::initialize($input, $output);
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
// Get lib object
|
||||
$builder = BuilderProvider::makeBuilderByInput($this->input);
|
||||
|
||||
$ext_conf = Config::getExt($this->getArgument('extension'));
|
||||
$builder->proveExts([$this->getArgument('extension')], true);
|
||||
|
||||
// Check whether lib is extracted
|
||||
// if (!is_dir(SOURCE_PATH . '/' . $this->getArgument('library'))) {
|
||||
// $this->output->writeln("<error>Library {$this->getArgument('library')} is not extracted</error>");
|
||||
// return static::FAILURE;
|
||||
// }
|
||||
|
||||
$version = $builder->getExt($this->getArgument('extension'))->getExtVersion();
|
||||
if ($version === null) {
|
||||
$this->output->writeln("<error>Failed to get version of extension {$this->getArgument('extension')}</error>");
|
||||
return static::FAILURE;
|
||||
}
|
||||
$this->output->writeln("<info>{$version}</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;
|
||||
}
|
||||
}
|
||||
60
src/SPC/command/dev/LibVerCommand.php
Normal file
60
src/SPC/command/dev/LibVerCommand.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\command\dev;
|
||||
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\command\BaseCommand;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
#[AsCommand('dev:lib-version', 'Returns version of library from source directory', ['dev:lib-ver'])]
|
||||
class LibVerCommand extends BaseCommand
|
||||
{
|
||||
public function configure()
|
||||
{
|
||||
$this->addArgument('library', InputArgument::REQUIRED, 'The library name');
|
||||
}
|
||||
|
||||
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||
{
|
||||
$this->no_motd = true;
|
||||
parent::initialize($input, $output);
|
||||
}
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
// Get lib object
|
||||
$builder = BuilderProvider::makeBuilderByInput($this->input);
|
||||
$builder->setLibsOnly();
|
||||
|
||||
// check lib name exist in lib.json
|
||||
try {
|
||||
Config::getLib($this->getArgument('library'));
|
||||
} catch (WrongUsageException $e) {
|
||||
$this->output->writeln("<error>Library {$this->getArgument('library')} is not supported yet</error>");
|
||||
return static::FAILURE;
|
||||
}
|
||||
|
||||
$builder->proveLibs([$this->getArgument('library')]);
|
||||
|
||||
// Check whether lib is extracted
|
||||
if (!is_dir(SOURCE_PATH . '/' . $this->getArgument('library'))) {
|
||||
$this->output->writeln("<error>Library {$this->getArgument('library')} is not extracted</error>");
|
||||
return static::FAILURE;
|
||||
}
|
||||
|
||||
$version = $builder->getLib($this->getArgument('library'))->getLibVersion();
|
||||
if ($version === null) {
|
||||
$this->output->writeln("<error>Failed to get version of library {$this->getArgument('library')}</error>");
|
||||
return static::FAILURE;
|
||||
}
|
||||
$this->output->writeln("<info>{$version}</info>");
|
||||
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) {
|
||||
|
||||
@@ -16,7 +16,7 @@ use SPC\store\source\CustomSourceBase;
|
||||
class Downloader
|
||||
{
|
||||
/**
|
||||
* Get latest version from BitBucket tag
|
||||
* Get latest version from BitBucket tag (type = bitbuckettag)
|
||||
*
|
||||
* @param string $name source name
|
||||
* @param array $source source meta info: [repo]
|
||||
@@ -51,7 +51,7 @@ class Downloader
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest version from GitHub tarball
|
||||
* Get latest version from GitHub tarball (type = ghtar / ghtagtar)
|
||||
*
|
||||
* @param string $name source name
|
||||
* @param array $source source meta info: [repo]
|
||||
@@ -68,7 +68,16 @@ class Downloader
|
||||
hooks: [[CurlHook::class, 'setupGithubToken']],
|
||||
retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0)
|
||||
), true);
|
||||
$url = $data[0]['tarball_url'];
|
||||
|
||||
if (($source['prefer-stable'] ?? false) === true) {
|
||||
$url = $data[0]['tarball_url'];
|
||||
} else {
|
||||
$id = 0;
|
||||
while ($data[$id]['prerelease'] === true) {
|
||||
++$id;
|
||||
}
|
||||
$url = $data[$id]['tarball_url'] ?? null;
|
||||
}
|
||||
if (!$url) {
|
||||
throw new DownloaderException("failed to find {$name} source");
|
||||
}
|
||||
@@ -106,7 +115,7 @@ class Downloader
|
||||
), true);
|
||||
$url = null;
|
||||
foreach ($data as $release) {
|
||||
if ($release['prerelease'] === true) {
|
||||
if (($source['prefer-stable'] ?? false) === true && $release['prerelease'] === true) {
|
||||
continue;
|
||||
}
|
||||
foreach ($release['assets'] as $asset) {
|
||||
@@ -337,7 +346,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 +446,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);
|
||||
|
||||
@@ -195,7 +195,7 @@ class FileSystem
|
||||
}
|
||||
try {
|
||||
self::extractArchive($filename, $target);
|
||||
self::emitSourceExtractHook($name);
|
||||
self::emitSourceExtractHook($name, $target);
|
||||
} catch (RuntimeException $e) {
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
f_passthru('rmdir /s /q ' . $target);
|
||||
@@ -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
|
||||
@@ -503,10 +518,10 @@ class FileSystem
|
||||
return file_put_contents($filename, $file);
|
||||
}
|
||||
|
||||
private static function emitSourceExtractHook(string $name): void
|
||||
private static function emitSourceExtractHook(string $name, string $target): void
|
||||
{
|
||||
foreach ((self::$_extract_hook[$name] ?? []) as $hook) {
|
||||
if ($hook() === true) {
|
||||
if ($hook($name, $target) === true) {
|
||||
logger()->info('Patched source [' . $name . '] after extracted');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use SPC\builder\linux\LinuxBuilder;
|
||||
use SPC\builder\unix\UnixBuilderBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
|
||||
class SourcePatcher
|
||||
{
|
||||
@@ -18,12 +19,21 @@ 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']);
|
||||
FileSystem::addSourceExtractHook('sqlsrv', [SourcePatcher::class, 'patchSQLSRVWin32']);
|
||||
FileSystem::addSourceExtractHook('pdo_sqlsrv', [SourcePatcher::class, 'patchSQLSRVWin32']);
|
||||
FileSystem::addSourceExtractHook('yaml', [SourcePatcher::class, 'patchYamlWin32']);
|
||||
FileSystem::addSourceExtractHook('libyaml', [SourcePatcher::class, 'patchLibYaml']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Source patcher runner before buildconf
|
||||
*
|
||||
* @param BuilderBase $builder Builder
|
||||
* @param BuilderBase $builder Builder
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function patchBeforeBuildconf(BuilderBase $builder): void
|
||||
{
|
||||
@@ -46,6 +56,12 @@ class SourcePatcher
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
if ($builder->getOption('enable-micro-win32')) {
|
||||
SourcePatcher::patchMicroWin32();
|
||||
} else {
|
||||
SourcePatcher::unpatchMicroWin32();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +85,7 @@ class SourcePatcher
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public static function patchMicro(?array $list = null, bool $reverse = false): bool
|
||||
public static function patchMicro(): bool
|
||||
{
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/sapi/micro/php_micro.c')) {
|
||||
return false;
|
||||
@@ -104,7 +120,7 @@ class SourcePatcher
|
||||
if (PHP_OS_FAMILY === 'Darwin') {
|
||||
$default[] = 'macos_iconv';
|
||||
}
|
||||
$patch_list = $list ?? $default;
|
||||
$patch_list = $default;
|
||||
$patches = [];
|
||||
$serial = ['80', '81', '82', '83', '84'];
|
||||
foreach ($patch_list as $patchName) {
|
||||
@@ -127,7 +143,7 @@ class SourcePatcher
|
||||
|
||||
f_passthru(
|
||||
'cd ' . SOURCE_PATH . '/php-src && ' .
|
||||
(PHP_OS_FAMILY === 'Windows' ? 'type' : 'cat') . ' ' . $patchesStr . ' | patch -p1 ' . ($reverse ? '-R' : '')
|
||||
(PHP_OS_FAMILY === 'Windows' ? 'type' : 'cat') . ' ' . $patchesStr . ' | patch -p1 '
|
||||
);
|
||||
|
||||
return true;
|
||||
@@ -175,6 +191,9 @@ class SourcePatcher
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public static function patchSwoole(): bool
|
||||
{
|
||||
// swoole hook needs pdo/pdo.h
|
||||
@@ -200,6 +219,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 +292,75 @@ class SourcePatcher
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
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), "://")) {'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function unpatchMicroPhar(): void
|
||||
{
|
||||
FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix the compilation issue of sqlsrv and pdo_sqlsrv on Windows (/sdl check is too strict and will cause Zend compilation to fail)
|
||||
*
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public static function patchSQLSRVWin32(string $source_name): bool
|
||||
{
|
||||
$source_name = preg_replace('/[^a-z_]/', '', $source_name);
|
||||
if (file_exists(SOURCE_PATH . '/php-src/ext/' . $source_name . '/config.w32')) {
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/' . $source_name . '/config.w32', '/sdl', '');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function patchYamlWin32(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/yaml/config.w32', "lib.substr(lib.length - 6, 6) == '_a.lib'", "lib.substr(lib.length - 6, 6) == '_a.lib' || 'yes' == 'yes'");
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function patchLibYaml(string $name, string $target): bool
|
||||
{
|
||||
if (!file_exists("{$target}\\cmake\\config.h.in")) {
|
||||
FileSystem::createDir("{$target}\\cmake");
|
||||
copy(ROOT_DIR . '\src\globals\extra\libyaml_config.h.in', "{$target}\\cmake\\config.h.in");
|
||||
}
|
||||
if (!file_exists("{$target}\\YamlConfig.cmake.in")) {
|
||||
copy(ROOT_DIR . '\src\globals\extra\libyaml_YamlConfig.cmake.in', "{$target}\\YamlConfig.cmake.in");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch cli SAPI Makefile for Windows.
|
||||
*
|
||||
@@ -282,7 +375,7 @@ class SourcePatcher
|
||||
$line_num = 0;
|
||||
$found = false;
|
||||
foreach ($lines as $v) {
|
||||
if (strpos($v, '$(BUILD_DIR)\php.exe:') !== false) {
|
||||
if (str_contains($v, '$(BUILD_DIR)\php.exe:')) {
|
||||
$found = $line_num;
|
||||
break;
|
||||
}
|
||||
@@ -296,6 +389,50 @@ class SourcePatcher
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
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 +448,23 @@ class SourcePatcher
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/main/main.c', $file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
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) {
|
||||
|
||||
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,24 @@ const DANGER_CMD = [
|
||||
'rmdir',
|
||||
];
|
||||
|
||||
// spc internal extensions
|
||||
const SPC_INTERNAL_EXTENSIONS = [
|
||||
'core',
|
||||
'hash',
|
||||
'json',
|
||||
'pcre',
|
||||
'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');
|
||||
@@ -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__ */
|
||||
10
src/globals/extra/libyaml_YamlConfig.cmake.in
Normal file
10
src/globals/extra/libyaml_YamlConfig.cmake.in
Normal file
@@ -0,0 +1,10 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set_and_check(yaml_TARGETS "@PACKAGE_CONFIG_DIR_CONFIG@/yamlTargets.cmake")
|
||||
|
||||
if(NOT yaml_TARGETS_IMPORTED)
|
||||
set(yaml_TARGETS_IMPORTED 1)
|
||||
include(${yaml_TARGETS})
|
||||
endif()
|
||||
|
||||
set(yaml_LIBRARIES yaml)
|
||||
4
src/globals/extra/libyaml_config.h.in
Normal file
4
src/globals/extra/libyaml_config.h.in
Normal file
@@ -0,0 +1,4 @@
|
||||
#define YAML_VERSION_MAJOR @YAML_VERSION_MAJOR@
|
||||
#define YAML_VERSION_MINOR @YAML_VERSION_MINOR@
|
||||
#define YAML_VERSION_PATCH @YAML_VERSION_PATCH@
|
||||
#define YAML_VERSION_STRING "@YAML_VERSION_STRING@"
|
||||
@@ -56,7 +56,7 @@ function arch2gnu(string $arch): 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;
|
||||
}
|
||||
|
||||
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,12 +11,16 @@ declare(strict_types=1);
|
||||
|
||||
// --------------------------------- edit area ---------------------------------
|
||||
|
||||
$zts = true;
|
||||
$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' => 'parallel',
|
||||
'Windows' => 'mbstring,pdo_sqlite,mbregex,parallel',
|
||||
'Linux', 'Darwin' => 'sockets',
|
||||
'Windows' => 'mbstring,pdo_sqlite,mbregex,bz2,sqlsrv,pdo_sqlsrv,yaml,zip,rar,apcu,swow',
|
||||
};
|
||||
|
||||
// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`).
|
||||
@@ -74,5 +78,7 @@ echo match ($argv[1]) {
|
||||
'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