Compare commits

...

16 Commits
2.2.1 ... 2.2.4

Author SHA1 Message Date
Jerry Ma
2a03c32bc0 Add full gd support on Windows (#484)
* Add full gd support (libjpeg, libpng, libwebp, libavif, freetype), and related patches

* cs fix

* Fix PHP 8.0 gd build
2024-06-26 20:35:11 +08:00
Jerry Ma
0b8a0504a2 Update GMP ver, using official 6.3.0 version (#483)
* Update GMP ver, using official 6.3.0 version

* Add GMP test
2024-06-26 11:30:19 +08:00
Kévin Dunglas
e9aff8f1d8 fix: error when building libtiff (#481)
* fix: error when building libtiff

* Update test-extensions.php

* Add test token

* Fix windows builds

* Fix token

* Fix token

* Test token

* Test token

* Test token

---------

Co-authored-by: Jerry Ma <jesse2061@outlook.com>
2024-06-25 12:38:38 +08:00
Jerry Ma
93cb7e9fbb Add phpmicro win32 mode support (#478)
* Add phpmicro win32 mode support

* Bump version to 2.2.4

* Add micro win32 build tests for actions

* cs-fix and update deps
2024-06-20 14:46:08 +08:00
DubbleClick
2d2607cd7f replace ext-zend-opcache with ext-opcache for spc extension list (#475)
* replace ext-zend-opcache with ext-opcache for spc extension list

* Use constant to set internal and filter extensions

---------

Co-authored-by: Marc Henderkes <m.henderkes@pc-college.de>
Co-authored-by: crazywhalecc <jesse2061@outlook.com>
2024-06-09 19:38:50 +08:00
Jerry Ma
d80406b8e0 Remove mongodb notes (#474)
* Ignore passed internal extensions

* Add tests

* Add tests

* Remove mongodb notes

* Remove mongodb notes
2024-06-06 01:17:23 +08:00
Jerry Ma
db9645641f Ignore passed internal extensions (#473)
* Ignore passed internal extensions

* Add tests

* Add tests
2024-06-05 23:20:21 +08:00
crazywhalecc
b3018af61c Fix mongodb support on macOS 2024-06-05 13:12:25 +08:00
Jerry Ma
7e6c2b4432 Fix xlswriter with openssl conflict bug (#472)
* Fix xlswriter with openssl conflict bug

* bump version to 2.2.3
2024-06-04 19:31:13 +08:00
crazywhalecc
1ae1c81f9c fix libxml2 patch for older php (limit only to 80, 81) 2024-06-04 12:40:21 +08:00
crazywhalecc
eff698cbe8 fix libxml2 patch for older php (limit only to 80, 81) 2024-06-04 12:30:46 +08:00
Jerry Ma
036e4f52b7 Prevent use building uv on 7.4 (#471)
* Prevent use building uv on 7.4

* Add swoole test

* Use github source for libcares

* Add libcares missing file patch

* Add libcares missing file patch
2024-06-04 12:24:52 +08:00
Jerry Ma
d258417afb Fix several patches & newer phpmicro support (#470)
* use upstream phpmicro

* move src/global/tests to src/global/ext-tests

* move src/global/tests to src/global/ext-tests

* prevent file_get_contents memory insufficience

* update README

* fix libxml >= 2.12 with older PHP (<=8.1) build bug

* cleanup code, support newer phpmicro

* add --no-strip and --with-upx-pack tests

* fix windows sanity check for newer phpmicro

* fix windows sanity check for newer phpmicro

* test

* test

* test

* update deps for ci
2024-06-03 23:16:15 +08:00
crazywhalecc
3057d02e37 Fix macOS --no-strip opposite bug 2024-05-31 00:13:16 +08:00
Jerry Ma
af8204fbf0 Add libxml extension wrapper for composer compatibility (#463)
* Add libxml extension wrapper for compatibility

* Add tests
2024-05-29 14:30:31 +08:00
Jerry Ma
968b3acbce Add gen-ext-docs command (#462) 2024-05-29 13:53:08 +08:00
66 changed files with 3377 additions and 1648 deletions

View File

@@ -12,6 +12,9 @@ on:
permissions: permissions:
contents: read contents: read
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs: jobs:
php-cs-fixer: php-cs-fixer:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -129,13 +132,6 @@ jobs:
extensions: curl, openssl, mbstring extensions: curl, openssl, mbstring
ini-values: memory_limit=-1 ini-values: memory_limit=-1
- name: "Use test token if exists"
if: matrix.os != 'windows-latest'
run: |
if [ "${{ secrets.TEST_GH_TOKEN }}" != "" ]; then
echo "GITHUB_TOKEN=${{ secrets.TEST_GH_TOKEN }}" >> $GITHUB_ENV
fi
- name: "Cache composer packages" - name: "Cache composer packages"
id: composer-cache id: composer-cache
uses: actions/cache@v4 uses: actions/cache@v4
@@ -147,7 +143,7 @@ jobs:
# Cache downloaded source # Cache downloaded source
- id: cache-download - id: cache-download
uses: actions/cache@v3 uses: actions/cache@v4
with: with:
path: downloads path: downloads
key: php-${{ matrix.php }}-dependencies key: php-${{ matrix.php }}-dependencies
@@ -158,14 +154,26 @@ jobs:
- name: "Run Build Tests (doctor)" - name: "Run Build Tests (doctor)"
run: bin/spc doctor --auto-fix run: bin/spc doctor --auto-fix
- name: "Run Build Tests (download)" - name: "Prepare UPX for Windows"
uses: nick-fields/retry@v3 if: matrix.os == 'windows-latest'
with: run: |
timeout_minutes: 10 bin/spc install-pkg upx
max_attempts: 3 echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV
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: "Run Build Tests (build)" - name: "Prepare UPX for Linux"
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 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

View File

@@ -15,9 +15,6 @@ jobs:
steps: steps:
- name: "Checkout static-php-cli" - name: "Checkout static-php-cli"
uses: actions/checkout@v4 uses: actions/checkout@v4
with:
ref: main
path: static-php-cli
- name: "Checkout static-php-cli-docs" - name: "Checkout static-php-cli-docs"
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -33,7 +30,35 @@ jobs:
git config --global user.name "GitHub Actions" git config --global user.name "GitHub Actions"
- name: "Copy Config Files" - 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" - name: "Commit and Push Changes"
run: | run: |

View File

@@ -74,7 +74,7 @@ static-php-cli简称 `spc`)有许多特性:
当前支持编译的 PHP 版本: 当前支持编译的 PHP 版本:
> :warning: 支持,但可能不再提供修复 > :warning: 支持,但 static-php-cli 作者可能不再提供补丁修复
> >
> :heavy_check_mark: 支持 > :heavy_check_mark: 支持
> >
@@ -86,7 +86,7 @@ static-php-cli简称 `spc`)有许多特性:
| 7.3 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 | | 7.3 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 7.4 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 | | 7.4 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 8.0 | :heavy_check_mark: | PHP 官方已停止 8.0 的维护 | | 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.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | | | 8.3 | :heavy_check_mark: | |

View File

@@ -82,7 +82,7 @@ Here is the supported OS and arch, where :octocat: represents support for GitHub
Currently supported PHP versions for compilation: 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 > :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.3 | :warning: | phpmicro and some extensions not supported on 7.x |
| 7.4 | :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.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.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | | | 8.3 | :heavy_check_mark: | |

358
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,8 @@
{ {
"amqp": { "amqp": {
"support": {
"BSD": "wip"
},
"type": "external", "type": "external",
"arg-type": "custom", "arg-type": "custom",
"source": "amqp", "source": "amqp",
@@ -18,6 +21,9 @@
"type": "builtin" "type": "builtin"
}, },
"bz2": { "bz2": {
"support": {
"Windows": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -31,6 +37,7 @@
"type": "builtin" "type": "builtin"
}, },
"curl": { "curl": {
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
"lib-depends": [ "lib-depends": [
@@ -49,6 +56,9 @@
] ]
}, },
"dom": { "dom": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -64,7 +74,21 @@
"type": "external", "type": "external",
"source": "ext-ds" "source": "ext-ds"
}, },
"enchant": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Darwin": "wip",
"Linux": "wip"
},
"type": "wip"
},
"event": { "event": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "ext-event", "source": "ext-event",
"arg-type": "custom", "arg-type": "custom",
@@ -82,6 +106,11 @@
"type": "builtin" "type": "builtin"
}, },
"ffi": { "ffi": {
"support": {
"Linux": "no",
"BSD": "wip"
},
"notes": true,
"arg-type": "custom", "arg-type": "custom",
"type": "builtin", "type": "builtin",
"lib-depends-unix": [ "lib-depends-unix": [
@@ -104,6 +133,10 @@
] ]
}, },
"gd": { "gd": {
"support": {
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -122,6 +155,10 @@
] ]
}, },
"gettext": { "gettext": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -129,6 +166,12 @@
] ]
}, },
"glfw": { "glfw": {
"support": {
"Windows": "wip",
"BSD": "no",
"Linux": "no"
},
"notes": true,
"type": "external", "type": "external",
"arg-type": "custom", "arg-type": "custom",
"source": "ext-glfw", "source": "ext-glfw",
@@ -138,6 +181,10 @@
"lib-depends-windows": [] "lib-depends-windows": []
}, },
"gmp": { "gmp": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -145,6 +192,9 @@
] ]
}, },
"iconv": { "iconv": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -156,10 +206,18 @@
] ]
}, },
"igbinary": { "igbinary": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "igbinary" "source": "igbinary"
}, },
"imagick": { "imagick": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-imagick", "source": "ext-imagick",
"arg-type": "custom", "arg-type": "custom",
@@ -168,6 +226,11 @@
] ]
}, },
"imap": { "imap": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
@@ -178,16 +241,29 @@
] ]
}, },
"inotify": { "inotify": {
"support": {
"Windows": "no",
"BSD": "wip",
"Darwin": "no"
},
"type": "external", "type": "external",
"source": "inotify" "source": "inotify"
}, },
"intl": { "intl": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"lib-depends": [ "lib-depends": [
"icu" "icu"
] ]
}, },
"ldap": { "ldap": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -201,6 +277,16 @@
"openssl" "openssl"
] ]
}, },
"libxml": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "none",
"ext-depends": [
"xml"
]
},
"mbregex": { "mbregex": {
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
@@ -215,7 +301,21 @@
"type": "builtin", "type": "builtin",
"arg-type": "custom" "arg-type": "custom"
}, },
"mcrypt": {
"type": "wip",
"support": {
"Windows": "no",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"memcache": { "memcache": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-memcache", "source": "ext-memcache",
"arg-type": "custom", "arg-type": "custom",
@@ -227,6 +327,11 @@
] ]
}, },
"memcached": { "memcached": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Linux": "no"
},
"type": "external", "type": "external",
"source": "memcached", "source": "memcached",
"arg-type": "custom", "arg-type": "custom",
@@ -240,6 +345,10 @@
] ]
}, },
"mongodb": { "mongodb": {
"support": {
"BSD": "wip",
"Windows": "wip"
},
"type": "external", "type": "external",
"source": "mongodb", "source": "mongodb",
"arg-type": "custom", "arg-type": "custom",
@@ -264,11 +373,22 @@
"zlib" "zlib"
] ]
}, },
"oci8": {
"type": "wip",
"support": {
"Windows": "wip",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"opcache": { "opcache": {
"type": "builtin", "type": "builtin",
"arg-type": "custom" "arg-type": "custom"
}, },
"openssl": { "openssl": {
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -281,6 +401,10 @@
] ]
}, },
"parallel": { "parallel": {
"support": {
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "parallel", "source": "parallel",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -289,6 +413,11 @@
] ]
}, },
"password-argon2": { "password-argon2": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -296,6 +425,9 @@
] ]
}, },
"pcntl": { "pcntl": {
"support": {
"Windows": "no"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
@@ -311,6 +443,10 @@
] ]
}, },
"pdo_pgsql": { "pdo_pgsql": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"ext-depends": [ "ext-depends": [
@@ -322,6 +458,9 @@
] ]
}, },
"pdo_sqlite": { "pdo_sqlite": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
"ext-depends": [ "ext-depends": [
@@ -333,6 +472,10 @@
] ]
}, },
"pdo_sqlsrv": { "pdo_sqlsrv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "pdo_sqlsrv", "source": "pdo_sqlsrv",
"arg-type": "with", "arg-type": "with",
@@ -342,6 +485,11 @@
] ]
}, },
"pgsql": { "pgsql": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -355,19 +503,36 @@
] ]
}, },
"posix": { "posix": {
"support": {
"Windows": "no"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
"protobuf": { "protobuf": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "protobuf" "source": "protobuf"
}, },
"rar": { "rar": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Darwin": "partial"
},
"notes": true,
"type": "external", "type": "external",
"source": "rar", "source": "rar",
"cpp-extension": true "cpp-extension": true
}, },
"readline": { "readline": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -375,6 +540,10 @@
] ]
}, },
"redis": { "redis": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "redis", "source": "redis",
"arg-type": "custom", "arg-type": "custom",
@@ -399,6 +568,9 @@
"cpp-extension": true "cpp-extension": true
}, },
"simplexml": { "simplexml": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
@@ -409,6 +581,10 @@
] ]
}, },
"snappy": { "snappy": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-snappy", "source": "ext-snappy",
"cpp-extension": true, "cpp-extension": true,
@@ -421,6 +597,9 @@
] ]
}, },
"soap": { "soap": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
@@ -434,6 +613,10 @@
"type": "builtin" "type": "builtin"
}, },
"sodium": { "sodium": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
"lib-depends": [ "lib-depends": [
@@ -441,6 +624,9 @@
] ]
}, },
"sqlite3": { "sqlite3": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -449,6 +635,10 @@
] ]
}, },
"sqlsrv": { "sqlsrv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "sqlsrv", "source": "sqlsrv",
"lib-depends": [ "lib-depends": [
@@ -460,6 +650,9 @@
"cpp-extension": true "cpp-extension": true
}, },
"ssh2": { "ssh2": {
"support": {
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-ssh2", "source": "ext-ssh2",
"arg-type": "with-prefix", "arg-type": "with-prefix",
@@ -473,6 +666,11 @@
] ]
}, },
"swoole": { "swoole": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "swoole", "source": "swoole",
"arg-type": "custom", "arg-type": "custom",
@@ -495,6 +693,11 @@
] ]
}, },
"swoole-hook-mysql": { "swoole-hook-mysql": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "addon", "type": "addon",
"arg-type": "custom", "arg-type": "custom",
"ext-depends": [ "ext-depends": [
@@ -507,6 +710,12 @@
] ]
}, },
"swoole-hook-pgsql": { "swoole-hook-pgsql": {
"support": {
"Windows": "no",
"BSD": "wip",
"Darwin": "partial"
},
"notes": true,
"type": "addon", "type": "addon",
"arg-type": "custom", "arg-type": "custom",
"ext-depends": [ "ext-depends": [
@@ -515,6 +724,11 @@
] ]
}, },
"swoole-hook-sqlite": { "swoole-hook-sqlite": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "addon", "type": "addon",
"arg-type": "custom", "arg-type": "custom",
"ext-depends": [ "ext-depends": [
@@ -523,6 +737,11 @@
] ]
}, },
"swow": { "swow": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "swow", "source": "swow",
"arg-type": "custom", "arg-type": "custom",
@@ -536,17 +755,32 @@
] ]
}, },
"sysvmsg": { "sysvmsg": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
"sysvsem": { "sysvsem": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
"sysvshm": { "sysvshm": {
"support": {
"BSD": "wip"
},
"type": "builtin" "type": "builtin"
}, },
"tidy": { "tidy": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -557,6 +791,10 @@
"type": "builtin" "type": "builtin"
}, },
"uuid": { "uuid": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-uuid", "source": "ext-uuid",
"arg-type": "with-prefix", "arg-type": "with-prefix",
@@ -565,6 +803,10 @@
] ]
}, },
"uv": { "uv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-uv", "source": "ext-uv",
"arg-type": "with-prefix", "arg-type": "with-prefix",
@@ -575,7 +817,22 @@
"sockets" "sockets"
] ]
}, },
"xdebug": {
"type": "builtin",
"support": {
"Windows": "wip",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"xhprof": { "xhprof": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "xhprof", "source": "xhprof",
"ext-depends": [ "ext-depends": [
@@ -583,15 +840,26 @@
] ]
}, },
"xlswriter": { "xlswriter": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "xlswriter", "source": "xlswriter",
"arg-type": "custom", "arg-type": "custom",
"ext-depends": [ "ext-depends": [
"zlib", "zlib",
"zip" "zip"
],
"lib-suggests": [
"openssl"
] ]
}, },
"xml": { "xml": {
"support": {
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -603,6 +871,9 @@
] ]
}, },
"xmlreader": { "xmlreader": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
@@ -614,6 +885,9 @@
] ]
}, },
"xmlwriter": { "xmlwriter": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
@@ -624,6 +898,10 @@
] ]
}, },
"xsl": { "xsl": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -635,6 +913,9 @@
] ]
}, },
"yac": { "yac": {
"support": {
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "yac", "source": "yac",
"arg-type-unix": "custom", "arg-type-unix": "custom",
@@ -643,6 +924,10 @@
] ]
}, },
"yaml": { "yaml": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "yaml", "source": "yaml",
"arg-type": "with-prefix", "arg-type": "with-prefix",
@@ -651,6 +936,10 @@
] ]
}, },
"zip": { "zip": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"arg-type-windows": "enable", "arg-type-windows": "enable",
@@ -667,6 +956,10 @@
] ]
}, },
"zstd": { "zstd": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-zstd", "source": "ext-zstd",
"arg-type": "custom", "arg-type": "custom",

View File

@@ -72,6 +72,9 @@
"static-libs-unix": [ "static-libs-unix": [
"libfreetype.a" "libfreetype.a"
], ],
"static-libs-windows": [
"libfreetype_a.lib"
],
"headers-unix": [ "headers-unix": [
"freetype2/freetype/freetype.h", "freetype2/freetype/freetype.h",
"freetype2/ft2build.h" "freetype2/ft2build.h"
@@ -190,6 +193,9 @@
"source": "libavif", "source": "libavif",
"static-libs-unix": [ "static-libs-unix": [
"libavif.a" "libavif.a"
],
"static-libs-windows": [
"avif.lib"
] ]
}, },
"libcares": { "libcares": {
@@ -269,6 +275,12 @@
"static-libs-unix": [ "static-libs-unix": [
"libjpeg.a", "libjpeg.a",
"libturbojpeg.a" "libturbojpeg.a"
],
"static-libs-windows": [
"libjpeg_a.lib"
],
"lib-suggests-windows": [
"zlib"
] ]
}, },
"liblz4": { "liblz4": {
@@ -290,7 +302,8 @@
"libpng16.a" "libpng16.a"
], ],
"static-libs-windows": [ "static-libs-windows": [
"libpng16_static.lib" "libpng16_static.lib",
"libpng_a.lib"
], ],
"headers-unix": [ "headers-unix": [
"png.h", "png.h",
@@ -372,6 +385,12 @@
"libwebpdemux.a", "libwebpdemux.a",
"libwebpmux.a", "libwebpmux.a",
"libsharpyuv.a" "libsharpyuv.a"
],
"static-libs-windows": [
"libwebp.lib",
"libwebpdecoder.lib",
"libwebpdemux.lib",
"libsharpyuv.lib"
] ]
}, },
"libxml2": { "libxml2": {

View File

@@ -179,8 +179,12 @@
} }
}, },
"gmp": { "gmp": {
"type": "ghtagtar", "type": "url",
"repo": "alisw/GMP", "url": "https://dl.static-php.dev/static-php-cli/deps/gmp/gmp-6.3.0.tar.xz",
"alt": {
"type": "ghtagtar",
"repo": "alisw/GMP"
},
"license": { "license": {
"type": "text", "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." "text": "Since version 6, GMP is distributed under the dual licenses, GNU LGPL v3 and GNU GPL v2. These licenses make the library free to use, share, and improve, and allow you to pass on the result. The GNU licenses give freedoms, but also set firm restrictions on the use with non-free programs."
@@ -259,9 +263,14 @@
} }
}, },
"libcares": { "libcares": {
"type": "filelist", "type": "ghrel",
"url": "https://c-ares.org/download/", "repo": "c-ares/c-ares",
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/", "match": "c-ares-.+\\.tar\\.gz",
"alt": {
"type": "filelist",
"url": "https://c-ares.org/download/",
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/"
},
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE.md" "path": "LICENSE.md"
@@ -463,7 +472,7 @@
"type": "git", "type": "git",
"path": "php-src/sapi/micro", "path": "php-src/sapi/micro",
"rev": "master", "rev": "master",
"url": "https://github.com/static-php/phpmicro", "url": "https://github.com/easysoft/phpmicro",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "LICENSE"

View File

@@ -13,6 +13,6 @@ parameters:
- PHP_OS_FAMILY - PHP_OS_FAMILY
excludePaths: excludePaths:
analyseAndScan: analyseAndScan:
- ./src/globals/tests/swoole.php - ./src/globals/ext-tests/swoole.php
- ./src/globals/tests/swoole.phpt - ./src/globals/ext-tests/swoole.phpt
- ./src/globals/test-extensions.php - ./src/globals/test-extensions.php

View File

@@ -8,6 +8,7 @@ use SPC\command\BuildCliCommand;
use SPC\command\BuildLibsCommand; use SPC\command\BuildLibsCommand;
use SPC\command\DeleteDownloadCommand; use SPC\command\DeleteDownloadCommand;
use SPC\command\dev\AllExtCommand; use SPC\command\dev\AllExtCommand;
use SPC\command\dev\GenerateExtDocCommand;
use SPC\command\dev\PhpVerCommand; use SPC\command\dev\PhpVerCommand;
use SPC\command\dev\SortConfigCommand; use SPC\command\dev\SortConfigCommand;
use SPC\command\DoctorCommand; use SPC\command\DoctorCommand;
@@ -24,7 +25,7 @@ use Symfony\Component\Console\Application;
*/ */
final class ConsoleApplication extends Application final class ConsoleApplication extends Application
{ {
public const VERSION = '2.2.1'; public const VERSION = '2.2.4';
public function __construct() public function __construct()
{ {
@@ -48,6 +49,7 @@ final class ConsoleApplication extends Application
new AllExtCommand(), new AllExtCommand(),
new PhpVerCommand(), new PhpVerCommand(),
new SortConfigCommand(), new SortConfigCommand(),
new GenerateExtDocCommand(),
] ]
); );
} }

View File

@@ -9,6 +9,7 @@ use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\Config; use SPC\store\Config;
use SPC\store\FileSystem;
use SPC\store\SourceManager; use SPC\store\SourceManager;
use SPC\util\CustomExt; use SPC\util\CustomExt;
@@ -275,6 +276,24 @@ abstract class BuilderBase
return false; 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. * Get build type name string to display.
* *
@@ -434,4 +453,29 @@ abstract class BuilderBase
$php .= "echo '[micro-test-end]';\n"; $php .= "echo '[micro-test-end]';\n";
return $php; 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; },
],
],
];
}
} }

View File

@@ -27,6 +27,8 @@ class BuilderProvider
*/ */
public static function makeBuilderByInput(InputInterface $input): BuilderBase public static function makeBuilderByInput(InputInterface $input): BuilderBase
{ {
ini_set('memory_limit', '2G');
self::$builder = match (PHP_OS_FAMILY) { self::$builder = match (PHP_OS_FAMILY) {
'Windows' => new WindowsBuilder($input->getOptions()), 'Windows' => new WindowsBuilder($input->getOptions()),
'Darwin' => new MacOSBuilder($input->getOptions()), 'Darwin' => new MacOSBuilder($input->getOptions()),

View File

@@ -170,19 +170,19 @@ class Extension
public function runCliCheckUnix(): void public function runCliCheckUnix(): void
{ {
// Run compile check if build target is cli // 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 // If check failed, throw RuntimeException
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false); [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
} }
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 // Trim additional content & escape special characters to allow inline usage
$test = str_replace( $test = str_replace(
['<?php', 'declare(strict_types=1);', "\n", '"', '$'], ['<?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) . '"'); [$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
@@ -201,19 +201,19 @@ class Extension
public function runCliCheckWindows(): void public function runCliCheckWindows(): void
{ {
// Run compile check if build target is cli // 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 // If check failed, throw RuntimeException
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe --ri "' . $this->getDistName() . '"', false); [$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
} }
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 // Trim additional content & escape special characters to allow inline usage
$test = str_replace( $test = str_replace(
['<?php', 'declare(strict_types=1);', "\n", '"', '$'], ['<?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) . '"'); [$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -r "' . trim($test) . '"');

View File

@@ -5,20 +5,11 @@ declare(strict_types=1);
namespace SPC\builder\extension; namespace SPC\builder\extension;
use SPC\builder\Extension; use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt; use SPC\util\CustomExt;
#[CustomExt('mongodb')] #[CustomExt('mongodb')]
class mongodb extends Extension 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 public function getUnixConfigureArg(): string
{ {
$arg = ' --enable-mongodb '; $arg = ' --enable-mongodb ';

View 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');
}
}
}

View File

@@ -12,6 +12,10 @@ class xlswriter extends Extension
{ {
public function getUnixConfigureArg(): string 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;
} }
} }

View File

@@ -181,7 +181,7 @@ class BSDBuilder extends UnixBuilderBase
} }
if ($this->getExt('phar')) { if ($this->getExt('phar')) {
$this->phar_patched = true; $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' : ''; $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); $this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) { if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true); SourcePatcher::unpatchMicroPhar();
} }
} }

View File

@@ -149,7 +149,11 @@ class LinuxBuilder extends UnixBuilderBase
// process micro upx patch if micro sapi enabled // process micro upx patch if micro sapi enabled
if ($enable_micro) { 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') shell()->cd(SOURCE_PATH . '/php-src')
@@ -236,7 +240,7 @@ class LinuxBuilder extends UnixBuilderBase
} }
if ($this->getExt('phar')) { if ($this->getExt('phar')) {
$this->phar_patched = true; $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' : ''; $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('sed -i "s|//lib|/lib|g" Makefile')
->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} micro"); ->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} micro");
$this->processMicroUPX();
$this->deployBinary(BUILD_TARGET_MICRO); $this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) { 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 * @throws FileSystemException
*/ */
private function processMicroUPX(): void private function processMicroUPXLegacy(): void
{ {
// upx pack and strip for micro // upx pack and strip for micro
// but always restore Makefile.frag.bak first // 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));
}
}
}
} }

View File

@@ -233,7 +233,7 @@ class MacOSBuilder extends UnixBuilderBase
} }
if ($this->getExt('phar')) { if ($this->getExt('phar')) {
$this->phar_patched = true; $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' : ''; $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 // patch fake cli for micro
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli; $vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
if (!$this->getOption('no-strip', false)) { if ($this->getOption('no-strip', false)) {
$vars['STRIP'] = 'dsymutil -f '; $vars['STRIP'] = 'dsymutil -f ';
} }
$vars = SystemUtil::makeEnvVarString($vars); $vars = SystemUtil::makeEnvVarString($vars);
@@ -251,7 +251,7 @@ class MacOSBuilder extends UnixBuilderBase
$this->deployBinary(BUILD_TARGET_MICRO); $this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) { if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true); SourcePatcher::unpatchMicroPhar();
} }
} }

View File

@@ -96,7 +96,7 @@ abstract class UnixBuilderBase extends BuilderBase
$support_lib_list = []; $support_lib_list = [];
$classes = FileSystem::getClassesPsr4( $classes = FileSystem::getClassesPsr4(
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library', ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
'SPC\\builder\\' . osfamily2dir() . '\\library' 'SPC\builder\\' . osfamily2dir() . '\library'
); );
foreach ($classes as $class) { foreach ($classes as $class) {
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) { 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 // sanity check for phpmicro
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) { if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if (file_exists(SOURCE_PATH . '/hello.exe')) { $test_task = $this->getMicroTestTasks();
@unlink(SOURCE_PATH . '/hello.exe'); foreach ($test_task as $task_name => $task) {
} $test_file = SOURCE_PATH . '/' . $task_name . '.exe';
file_put_contents( if (file_exists($test_file)) {
SOURCE_PATH . '/hello.exe', @unlink($test_file);
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()) file_put_contents($test_file, file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') . $task['content']);
); chmod($test_file, 0755);
chmod(SOURCE_PATH . '/hello.exe', 0755); [$ret, $out] = shell()->execWithResult($test_file);
[$ret, $output2] = shell()->execWithResult(SOURCE_PATH . '/hello.exe'); foreach ($task['conditions'] as $condition => $closure) {
$raw_out = trim(implode('', $output2)); if (!$closure($ret, $out)) {
$condition[0] = $ret === 0; $raw_out = trim(implode('', $out));
$condition[1] = str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]'); throw new RuntimeException("micro failed sanity check: {$task_name}, condition [{$condition}], ret[{$ret}], out[{$raw_out}]");
foreach ($condition as $k => $v) { }
if (!$v) {
throw new RuntimeException("micro failed sanity check with condition[{$k}], ret[{$ret}], out[{$raw_out}]");
} }
} }
} }

View File

@@ -5,9 +5,20 @@ declare(strict_types=1);
namespace SPC\builder\unix\library; namespace SPC\builder\unix\library;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait libcares 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 * @throws RuntimeException
*/ */

View File

@@ -15,14 +15,20 @@ trait libtiff
*/ */
protected function build(): void protected function build(): void
{ {
shell()->cd($this->source_dir) $shell = shell()->cd($this->source_dir)
->exec( ->exec(
'./configure ' . './configure ' .
'--enable-static --disable-shared ' . '--enable-static --disable-shared ' .
'--disable-cxx ' . '--disable-cxx ' .
'--prefix=' '--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 -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH); ->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['libtiff-4.pc']); $this->patchPkgconfPrefix(['libtiff-4.pc']);

View File

@@ -90,6 +90,7 @@ class SystemUtil
$buildroot = str_replace('\\', '\\\\', BUILD_ROOT_PATH); $buildroot = str_replace('\\', '\\\\', BUILD_ROOT_PATH);
$toolchain = <<<CMAKE $toolchain = <<<CMAKE
set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_PROCESSOR x64)
SET(CMAKE_C_FLAGS "{$cflags}") SET(CMAKE_C_FLAGS "{$cflags}")
SET(CMAKE_C_FLAGS_DEBUG "{$cflags}") SET(CMAKE_C_FLAGS_DEBUG "{$cflags}")
SET(CMAKE_CXX_FLAGS "{$cflags}") SET(CMAKE_CXX_FLAGS "{$cflags}")

View File

@@ -80,16 +80,18 @@ class WindowsBuilder extends BuilderBase
$zts = $this->zts ? '--enable-zts=yes ' : '--enable-zts=no '; $zts = $this->zts ? '--enable-zts=yes ' : '--enable-zts=no ';
// with-upx-pack for phpmicro // with-upx-pack for phpmicro
$makefile = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.w32'); if ($enableMicro && version_compare($this->getMicroVersion(), '0.2.0') < 0) {
if ($this->getOption('with-upx-pack', false)) { $makefile = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.w32');
if (!file_exists($makefile . '.originfile')) { if ($this->getOption('with-upx-pack', false)) {
copy($makefile, $makefile . '.originfile'); if (!file_exists($makefile . '.originfile')) {
FileSystem::replaceFileStr($makefile, '$(MICRO_SFX):', '_MICRO_UPX = ' . getenv('UPX_EXEC') . " --best $(MICRO_SFX)\n$(MICRO_SFX):"); copy($makefile, $makefile . '.originfile');
FileSystem::replaceFileStr($makefile, '@$(_MICRO_MT)', "@$(_MICRO_MT)\n\t@$(_MICRO_UPX)"); 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) { if (($logo = $this->getOption('with-micro-logo')) !== null) {
@@ -100,6 +102,8 @@ class WindowsBuilder extends BuilderBase
$micro_logo = ''; $micro_logo = '';
} }
$micro_w32 = $this->getOption('enable-micro-win32') ? ' --enable-micro-win32=yes' : '';
cmd()->cd(SOURCE_PATH . '\php-src') cmd()->cd(SOURCE_PATH . '\php-src')
->exec( ->exec(
"{$this->sdk_prefix} configure.bat --task-args \"" . "{$this->sdk_prefix} configure.bat --task-args \"" .
@@ -109,7 +113,7 @@ class WindowsBuilder extends BuilderBase
'--with-extra-includes=' . BUILD_INCLUDE_PATH . ' ' . '--with-extra-includes=' . BUILD_INCLUDE_PATH . ' ' .
'--with-extra-libs=' . BUILD_LIB_PATH . ' ' . '--with-extra-libs=' . BUILD_LIB_PATH . ' ' .
($enableCli ? '--enable-cli=yes ' : '--enable-cli=no ') . ($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 ') . ($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
"{$this->makeExtensionArgs()} " . "{$this->makeExtensionArgs()} " .
$zts . $zts .
@@ -130,6 +134,8 @@ class WindowsBuilder extends BuilderBase
if ($enableMicro) { if ($enableMicro) {
logger()->info('building micro'); logger()->info('building micro');
$this->buildMicro(); $this->buildMicro();
SourcePatcher::unpatchMicroWin32();
} }
if ($enableEmbed) { if ($enableEmbed) {
logger()->warning('Windows does not currently support embed SAPI.'); logger()->warning('Windows does not currently support embed SAPI.');
@@ -191,14 +197,14 @@ class WindowsBuilder extends BuilderBase
// phar patch for micro // phar patch for micro
if ($this->getExt('phar')) { if ($this->getExt('phar')) {
$this->phar_patched = true; $this->phar_patched = true;
SourcePatcher::patchMicro(['phar']); SourcePatcher::patchMicroPhar($this->getPHPVersionID());
} }
try { try {
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_micro_wrapper.bat --task-args micro"); cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_micro_wrapper.bat --task-args micro");
} finally { } finally {
if ($this->phar_patched) { if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true); SourcePatcher::unpatchMicroPhar();
} }
} }
@@ -210,8 +216,8 @@ class WindowsBuilder extends BuilderBase
// search all supported libs // search all supported libs
$support_lib_list = []; $support_lib_list = [];
$classes = FileSystem::getClassesPsr4( $classes = FileSystem::getClassesPsr4(
ROOT_DIR . '\src\SPC\builder\\' . osfamily2dir() . '\\library', ROOT_DIR . '\src\SPC\builder\\' . osfamily2dir() . '\library',
'SPC\\builder\\' . osfamily2dir() . '\\library' 'SPC\builder\\' . osfamily2dir() . '\library'
); );
foreach ($classes as $class) { foreach ($classes as $class) {
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) { if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {
@@ -283,22 +289,20 @@ class WindowsBuilder extends BuilderBase
// sanity check for phpmicro // sanity check for phpmicro
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) { if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if (file_exists(SOURCE_PATH . '\hello.exe')) { $test_task = $this->getMicroTestTasks();
@unlink(SOURCE_PATH . '\hello.exe'); foreach ($test_task as $task_name => $task) {
} $test_file = SOURCE_PATH . '/' . $task_name . '.exe';
file_put_contents( if (file_exists($test_file)) {
SOURCE_PATH . '\hello.exe', @unlink($test_file);
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()) file_put_contents($test_file, file_get_contents(BUILD_ROOT_PATH . '\bin\micro.sfx') . $task['content']);
); chmod($test_file, 0755);
chmod(SOURCE_PATH . '\hello.exe', 0755); [$ret, $out] = cmd()->execWithResult($test_file);
[$ret, $output2] = cmd()->execWithResult(SOURCE_PATH . '\hello.exe'); foreach ($task['conditions'] as $condition => $closure) {
$raw_out = trim(implode('', $output2)); if (!$closure($ret, $out)) {
$condition[0] = $ret === 0; $raw_out = trim(implode('', $out));
$condition[1] = str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]'); throw new RuntimeException("micro failed sanity check: {$task_name}, condition [{$condition}], ret[{$ret}], out[{$raw_out}]");
foreach ($condition as $k => $v) { }
if (!$v) {
throw new RuntimeException("micro failed sanity check with condition[{$k}], ret[{$ret}], out[{$raw_out}]");
} }
} }
} }
@@ -320,9 +324,11 @@ class WindowsBuilder extends BuilderBase
default => throw new RuntimeException('Deployment does not accept type ' . $type), default => throw new RuntimeException('Deployment does not accept type ' . $type),
}; };
// with-upx-pack for cli // with-upx-pack for cli and micro
if ($this->getOption('with-upx-pack', false) && $type === BUILD_TARGET_CLI) { if ($this->getOption('with-upx-pack', false)) {
cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src)); 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'); logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');

View 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');
}
}

View 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}"
);
}
}

View 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');
}
}

View 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');
}
}

View 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}"
);
}
}

View File

@@ -96,6 +96,8 @@ abstract class BaseCommand extends Command
}); });
if ($this->shouldExecute()) { if ($this->shouldExecute()) {
try { try {
// show raw argv list for logger()->debug
logger()->debug('argv: ' . implode(' ', $_SERVER['argv']));
return $this->handle(); return $this->handle();
} catch (WrongUsageException $e) { } catch (WrongUsageException $e) {
$msg = explode("\n", $e->getMessage()); $msg = explode("\n", $e->getMessage());
@@ -142,4 +144,31 @@ abstract class BaseCommand extends Command
logger()->error($fail_msg); logger()->error($fail_msg);
return static::FAILURE; 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;
}));
}
} }

View File

@@ -40,6 +40,7 @@ class BuildCliCommand extends BuildCommand
$this->addOption('without-micro-ext-test', null, null, 'Disable phpmicro with extension test code'); $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-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('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 public function handle(): int
@@ -47,7 +48,7 @@ class BuildCliCommand extends BuildCommand
// transform string to array // transform string to array
$libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs')))); $libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs'))));
// transform string to array // transform string to array
$extensions = array_map('trim', array_filter(explode(',', $this->getArgument('extensions')))); $extensions = $this->parseExtensionList($this->getArgument('extensions'));
// parse rule with options // parse rule with options
$rule = $this->parseRules(); $rule = $this->parseRules();

View File

@@ -68,7 +68,7 @@ class DownloadCommand extends BaseCommand
} }
// mode: --for-extensions // mode: --for-extensions
if ($for_ext = $input->getOption('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')); $sources = $this->calculateSourcesByExt($ext, !$input->getOption('without-suggestions'));
if (PHP_OS_FAMILY !== 'Windows') { if (PHP_OS_FAMILY !== 'Windows') {
array_unshift($sources, 'pkg-config'); array_unshift($sources, 'pkg-config');

View File

@@ -37,7 +37,7 @@ class DumpLicenseCommand extends BaseCommand
$dumper = new LicenseDumper(); $dumper = new LicenseDumper();
if ($this->getOption('for-extensions') !== null) { if ($this->getOption('for-extensions') !== null) {
// 从参数中获取要编译的 extensions并转换为数组 // 从参数中获取要编译的 extensions并转换为数组
$extensions = array_map('trim', array_filter(explode(',', $this->getOption('for-extensions')))); $extensions = $this->parseExtensionList($this->getOption('for-extensions'));
// 根据提供的扩展列表获取依赖库列表并编译 // 根据提供的扩展列表获取依赖库列表并编译
[$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions); [$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions);
$dumper->addExts($extensions); $dumper->addExts($extensions);

View 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;
}
}

View File

@@ -70,7 +70,7 @@ final class CheckListHandler
*/ */
private function loadCheckList(bool $include_manual = false): array 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); $ref = new \ReflectionClass($class);
foreach ($ref->getMethods() as $method) { foreach ($ref->getMethods() as $method) {
foreach ($method->getAttributes() as $a) { foreach ($method->getAttributes() as $a) {

View File

@@ -337,7 +337,7 @@ class Downloader
); );
break; break;
case 'custom': // Custom download method, like API-based download or other 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) { foreach ($classes as $class) {
if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) { if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) {
(new $class())->fetch($force); (new $class())->fetch($force);
@@ -437,7 +437,7 @@ class Downloader
); );
break; break;
case 'custom': // Custom download method, like API-based download or other 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) { foreach ($classes as $class) {
if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) { if (is_a($class, CustomSourceBase::class, true) && $class::NAME === $name) {
(new $class())->fetch($force); (new $class())->fetch($force);

View File

@@ -436,6 +436,21 @@ class FileSystem
return str_replace(array_keys($replacement), array_values($replacement), $path); 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 RuntimeException
* @throws FileSystemException * @throws FileSystemException

View File

@@ -18,6 +18,8 @@ class SourcePatcher
FileSystem::addSourceExtractHook('micro', [SourcePatcher::class, 'patchMicro']); FileSystem::addSourceExtractHook('micro', [SourcePatcher::class, 'patchMicro']);
FileSystem::addSourceExtractHook('openssl', [SourcePatcher::class, 'patchOpenssl11Darwin']); FileSystem::addSourceExtractHook('openssl', [SourcePatcher::class, 'patchOpenssl11Darwin']);
FileSystem::addSourceExtractHook('swoole', [SourcePatcher::class, 'patchSwoole']); FileSystem::addSourceExtractHook('swoole', [SourcePatcher::class, 'patchSwoole']);
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchPhpLibxml212']);
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchGDWin32']);
} }
/** /**
@@ -46,6 +48,12 @@ class SourcePatcher
'' ''
); );
} }
if ($builder->getOption('enable-micro-win32')) {
SourcePatcher::patchMicroWin32();
} else {
SourcePatcher::unpatchMicroWin32();
}
} }
/** /**
@@ -200,6 +208,11 @@ class SourcePatcher
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'install-micro', ''); 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 // call extension patch before make
foreach ($builder->getExts() as $ext) { foreach ($builder->getExts() as $ext) {
if ($ext->patchBeforeMake() === true) { if ($ext->patchBeforeMake() === true) {
@@ -268,6 +281,36 @@ class SourcePatcher
return $result; return $result;
} }
public static function patchMicroPhar(int $version_id): void
{
FileSystem::backupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c');
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/phar/phar.c',
'static zend_op_array *phar_compile_file',
"char *micro_get_filename(void);\n\nstatic zend_op_array *phar_compile_file"
);
if ($version_id < 80100) {
// PHP 8.0.x
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/phar/phar.c',
'if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, "://")) {',
'if ((strstr(file_handle->filename, micro_get_filename()) || strstr(file_handle->filename, ".phar")) && !strstr(file_handle->filename, "://")) {'
);
} else {
// PHP >= 8.1
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/phar/phar.c',
'if (strstr(ZSTR_VAL(file_handle->filename), ".phar") && !strstr(ZSTR_VAL(file_handle->filename), "://")) {',
'if ((strstr(ZSTR_VAL(file_handle->filename), micro_get_filename()) || strstr(ZSTR_VAL(file_handle->filename), ".phar")) && !strstr(ZSTR_VAL(file_handle->filename), "://")) {'
);
}
}
public static function unpatchMicroPhar(): void
{
FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c');
}
/** /**
* Patch cli SAPI Makefile for Windows. * Patch cli SAPI Makefile for Windows.
* *
@@ -296,6 +339,44 @@ class SourcePatcher
FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines)); FileSystem::writeFile(SOURCE_PATH . '/php-src/Makefile', implode("\r\n", $lines));
} }
public static function patchPhpLibxml212(): bool
{
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0) {
$ver_id = intval($match[1]);
if ($ver_id < 80000) {
return false;
}
if ($ver_id < 80100) {
self::patchFile('spc_fix_libxml2_12_php80.patch', SOURCE_PATH . '/php-src');
return true;
}
if ($ver_id < 80200) {
self::patchFile('spc_fix_libxml2_12_php81.patch', SOURCE_PATH . '/php-src');
return true;
}
return false;
}
return false;
}
public static function patchGDWin32(): bool
{
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0) {
$ver_id = intval($match[1]);
if ($ver_id < 80200) {
// see: https://github.com/php/php-src/commit/243966177e39eb71822935042c3f13fa6c5b9eed
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/gd/libgd/gdft.c', '#ifndef MSWIN32', '#ifndef _WIN32');
}
// custom config.w32, because official config.w32 is hard-coded many things
$origin = $ver_id >= 80100 ? file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_81.w32') : file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_80.w32');
file_put_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32.bak', file_get_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32'));
return file_put_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32', $origin) !== false;
}
return false;
}
/** /**
* Add additional `static-php-cli.version` ini value for PHP source. * Add additional `static-php-cli.version` ini value for PHP source.
* *
@@ -311,4 +392,20 @@ class SourcePatcher
FileSystem::writeFile(SOURCE_PATH . '/php-src/main/main.c', $file); FileSystem::writeFile(SOURCE_PATH . '/php-src/main/main.c', $file);
} }
} }
public static function patchMicroWin32(): void
{
// patch micro win32
if (!file_exists(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak')) {
copy(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c', SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak');
FileSystem::replaceFileStr(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c', '#include "php_variables.h"', '#include "php_variables.h"' . "\n#define PHP_MICRO_WIN32_NO_CONSOLE 1");
}
}
public static function unpatchMicroWin32(): void
{
if (file_exists(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak')) {
rename(SOURCE_PATH . '\php-src\sapi\micro\php_micro.c.win32bak', SOURCE_PATH . '\php-src\sapi\micro\php_micro.c');
}
}
} }

View File

@@ -23,7 +23,7 @@ class CustomExt
*/ */
public static function loadCustomExt(): void 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) { foreach ($classes as $class) {
$reflection = new \ReflectionClass($class); $reflection = new \ReflectionClass($class);
foreach ($reflection->getAttributes(CustomExt::class) as $attribute) { foreach ($reflection->getAttributes(CustomExt::class) as $attribute) {

View 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');

View File

@@ -38,6 +38,23 @@ const DANGER_CMD = [
'rmdir', 'rmdir',
]; ];
// spc internal extensions
const SPC_INTERNAL_EXTENSIONS = [
'core',
'hash',
'json',
'reflection',
'spl',
'standard',
];
// spc extension alias
const SPC_EXTENSION_ALIAS = [
'zend opcache' => 'opcache',
'zend-opcache' => 'opcache',
'zendopcache' => 'opcache',
];
// file replace strategy // file replace strategy
const REPLACE_FILE_STR = 1; const REPLACE_FILE_STR = 1;
const REPLACE_FILE_PREG = 2; const REPLACE_FILE_PREG = 2;

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
assert(class_exists('\\DOMDocument')); assert(class_exists('\DOMDocument'));
$doc = new 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>'); $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'); assert($doc->getElementById('app')->nodeValue === 'Hello');

View File

@@ -2,4 +2,4 @@
declare(strict_types=1); declare(strict_types=1);
assert(class_exists('\\Redis')); assert(class_exists('\Redis'));

View File

@@ -0,0 +1,5 @@
<?php
declare(strict_types=1);
assert(class_exists('\ZipArchive'));

View 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");
}

View 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");
}

View 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__ */

View File

@@ -56,7 +56,7 @@ function arch2gnu(string $arch): string
*/ */
function match_pattern(string $pattern, string $subject): bool function match_pattern(string $pattern, string $subject): bool
{ {
$pattern = str_replace(['\*', '\\\\.*'], ['.*', '\*'], preg_quote($pattern, '/')); $pattern = str_replace(['\*', '\\\.*'], ['.*', '\*'], preg_quote($pattern, '/'));
$pattern = '/^' . $pattern . '$/i'; $pattern = '/^' . $pattern . '$/i';
return preg_match($pattern, $subject) === 1; return preg_match($pattern, $subject) === 1;
} }

View 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 {

View 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);

View File

@@ -11,18 +11,22 @@ declare(strict_types=1);
// --------------------------------- edit area --------------------------------- // --------------------------------- 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`). // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
$extensions = match (PHP_OS_FAMILY) { $extensions = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'parallel', 'Linux', 'Darwin' => 'sockets',
'Windows' => 'mbstring,pdo_sqlite,mbregex,parallel', 'Windows' => 'mbstring,pdo_sqlite,mbregex,gd',
}; };
// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`). // If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`).
$with_libs = match (PHP_OS_FAMILY) { $with_libs = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => '', 'Linux', 'Darwin' => '',
'Windows' => '', 'Windows' => 'libjpeg,libwebp,libavif,freetype',
}; };
// Please change your test base combination. We recommend testing with `common`. // Please change your test base combination. We recommend testing with `common`.
@@ -74,5 +78,7 @@ echo match ($argv[1]) {
'libs_cmd' => ($final_libs === '' ? '' : (' --with-libs=' . $final_libs)), 'libs_cmd' => ($final_libs === '' ? '' : (' --with-libs=' . $final_libs)),
'cmd' => $final_extensions_cmd . ($final_libs === '' ? '' : (' --with-libs=' . $final_libs)), 'cmd' => $final_extensions_cmd . ($final_libs === '' ? '' : (' --with-libs=' . $final_libs)),
'zts' => $zts ? '--enable-zts' : '', 'zts' => $zts ? '--enable-zts' : '',
'no_strip' => $no_strip ? '--no-strip' : '',
'upx' => $upx ? '--with-upx-pack' : '',
default => '', default => '',
}; };

View File

@@ -1,5 +0,0 @@
<?php
declare(strict_types=1);
assert(class_exists('\\ZipArchive'));

View File

@@ -94,7 +94,7 @@ class FileSystemTest extends TestCase
*/ */
public function testGetClassesPsr4() 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) { foreach ($classes as $class) {
$this->assertIsString($class); $this->assertIsString($class);
new \ReflectionClass($class); new \ReflectionClass($class);
@@ -185,9 +185,9 @@ class FileSystemTest extends TestCase
public function testIsRelativePath() public function testIsRelativePath()
{ {
$this->assertTrue(FileSystem::isRelativePath('.')); $this->assertTrue(FileSystem::isRelativePath('.'));
$this->assertTrue(FileSystem::isRelativePath('.\\sdf')); $this->assertTrue(FileSystem::isRelativePath('.\sdf'));
if (DIRECTORY_SEPARATOR === '\\') { if (DIRECTORY_SEPARATOR === '\\') {
$this->assertFalse(FileSystem::isRelativePath('C:\\asdasd/fwe\asd')); $this->assertFalse(FileSystem::isRelativePath('C:\asdasd/fwe\asd'));
} else { } else {
$this->assertFalse(FileSystem::isRelativePath('/fwefwefewf')); $this->assertFalse(FileSystem::isRelativePath('/fwefwefewf'));
} }