Compare commits

...

81 Commits
2.3.6 ... 2.4.4

Author SHA1 Message Date
Jerry Ma
36b4ef306e Fix libtiff dependencies, avoid using system libraries (#588)
* Remove tmate debugger

* Bump version to 2.4.4

* Fix libtiff dependencies may wrongly added

* Add matrix tests

* Add tmate debug

* Disable libdeflate for libtiff

* Remove ssh debugger
2025-01-25 16:15:53 +08:00
crazywhalecc
4bd3a2ae25 Add ssh debug 2025-01-25 12:20:54 +08:00
crazywhalecc
dd647c53ec Add doctor for build-unix CI 2025-01-25 11:35:47 +08:00
crazywhalecc
0c0d16bbb3 Try new build CI 2025-01-25 11:30:59 +08:00
crazywhalecc
c665a18b79 Try new build CI 2025-01-25 11:29:18 +08:00
crazywhalecc
16d448b97c Try new build CI 2025-01-25 11:09:13 +08:00
crazywhalecc
27ccc1189f Try new build CI 2025-01-25 10:59:44 +08:00
Jerry Ma
eecebbcd4d Fix x86_64 macOS CI invalid options 2025-01-25 09:48:15 +08:00
Jerry Ma
2ca5ad075b Add legacy CentOS distro support (#585) 2025-01-13 20:42:09 +08:00
Jean-François Lépine
20dad4cdb3 Merge pull request #583 from Halleck45/support_ast_extension
Support AST extension
2025-01-13 11:11:32 +08:00
crazywhalecc
a3e0ad6b9f Add PHP 8.4 support for cli-generator 2025-01-13 09:33:25 +08:00
Jerry Ma
4b16631d45 Fix openssl missing cert bug for Linux & macOS (#581)
* Fix openssl missing cert bug for linux

* Fix openssl missing cert bug for macOS
2024-12-24 22:06:31 +08:00
Jerry Ma
944f4af914 Update FUNDING.yml 2024-12-23 11:05:21 +08:00
Jerry Ma
4865c1c124 Update README.md 2024-12-23 11:04:46 +08:00
Jerry Ma
78aea56de4 Add aom patch for alpine linux (#579) 2024-12-20 12:18:34 +08:00
Jerry Ma
adbe2e80f3 Update ConsoleApplication.php 2024-12-19 12:28:49 +08:00
Jerry Ma
192c8cde87 Add libaom, libde265, libheif support, for imagick AVIF format support (#575)
* Add libaom, libde265, libheif support, for imagick AVIF format support

* Fix aom optimization

* Fix aom build command

* Fix libheif build command

* Fix libheif build

* cs fix
2024-12-19 12:23:39 +08:00
Adam
d4ec366c5f Update SQLite to 3.45 (#574)
* Force SQLite 3.45 build from source.

* Update SQLite to 3.45.

* Sort config.

* Minimize changes.
2024-12-15 20:03:48 +08:00
Jerry Ma
bad28fa263 Merge pull request #256 from crazywhalecc/ext/rdkafka
Add extension rdkafka support
2024-12-13 16:23:21 +08:00
crazywhalecc
985cd6781e Add macOS x86_64 test 2024-12-13 15:36:51 +08:00
crazywhalecc
44dcc830f4 Add rdkafka tests 2024-12-13 15:23:55 +08:00
crazywhalecc
10ef4c0d3b Adjust config 2024-12-13 15:22:54 +08:00
crazywhalecc
d0fbc5ab2d Merge branch 'main' into ext/rdkafka
# Conflicts:
#	src/globals/test-extensions.php
2024-12-13 15:12:05 +08:00
crazywhalecc
1bc7bc3421 Addd embed docs 2024-12-13 15:05:44 +08:00
crazywhalecc
8b9b70704a Fix test 2024-12-13 15:05:44 +08:00
crazywhalecc
804020210d Fix test 2024-12-13 15:05:44 +08:00
crazywhalecc
5c51305978 Add embed build tests 2024-12-13 15:05:44 +08:00
crazywhalecc
43cc9d0ba3 Add command, bump version 2024-12-13 15:05:44 +08:00
crazywhalecc
52869218e0 Fix grpc redundant static lib 2024-12-13 15:05:44 +08:00
crazywhalecc
82e11e52dd Fix gettext build 2024-12-13 15:05:44 +08:00
crazywhalecc
955c367a47 Fix pgsql embed builds 2024-12-13 15:05:44 +08:00
crazywhalecc
a613e9a84f Add spc-config command 2024-12-13 15:05:44 +08:00
crazywhalecc
c4b9660cd7 Add embed sanity check 2024-12-13 15:05:44 +08:00
crazywhalecc
f433866671 Add embed spc-config output instead of php-config 2024-12-13 15:05:44 +08:00
crazywhalecc
fdc4a907c7 Fix pgsql missing symbol 2024-12-09 21:57:35 +08:00
Jerry Ma
cf37e16e38 Update build-macos-x86_64.yml 2024-12-06 13:13:50 +08:00
Jerry Ma
2aa42123f6 Update build-macos-x86_64.yml 2024-12-06 13:07:52 +08:00
crazywhalecc
bc7dba6125 Fix parallel config.m4 2024-12-05 18:51:57 +08:00
crazywhalecc
3ce24da15c Fix patch point tests 2024-12-05 18:51:57 +08:00
crazywhalecc
3659e20b0d Fix patch point tests 2024-12-05 18:51:57 +08:00
crazywhalecc
a90a57ffab Add extension configure tests 2024-12-05 18:51:57 +08:00
crazywhalecc
45bdb6a66b Add extension configure tests 2024-12-05 18:51:57 +08:00
crazywhalecc
64258e3513 Fix pgsql linux builds with PHP 8.4 2024-12-05 18:30:19 +08:00
crazywhalecc
fe72b800c6 Add pgsql tests 2024-12-05 13:48:27 +08:00
crazywhalecc
39bc44322e cs-fix 2024-12-05 13:48:27 +08:00
crazywhalecc
1a0e6ee717 cs-fix, add tests 2024-12-05 13:48:27 +08:00
crazywhalecc
cc088b6382 Let grpc use openssl 2024-12-05 13:48:27 +08:00
crazywhalecc
b9f709c23d Change ext.json for pgsql 2024-12-05 13:48:27 +08:00
crazywhalecc
05b602d38c Fix pgsql with PHP 8.4 embed missing libs bug 2024-12-05 13:48:27 +08:00
Simon Hamp
a8a071de1a Add missing step 2024-12-01 16:11:05 +08:00
crazywhalecc
391555b1f5 Update docs 2024-11-23 11:55:29 +08:00
crazywhalecc
62b0bf8eca Remove PHP 8.1 libxml2 patch 2024-11-23 11:55:29 +08:00
crazywhalecc
1ab464431f Update workflows, add php 8.4 2024-11-23 11:55:29 +08:00
crazywhalecc
f04b54bc2a Update docs 2024-11-23 11:55:29 +08:00
crazywhalecc
e1652a4b36 Sort config 2024-11-23 11:55:29 +08:00
crazywhalecc
8c586fe7d9 Remove RC version for PHP 8.4 2024-11-23 11:55:29 +08:00
crazywhalecc
d2c929cb72 Update to RC4 2024-11-23 11:55:29 +08:00
crazywhalecc
b9584e48ac Fix FileSystem remove soft link directory 2024-11-23 11:55:29 +08:00
crazywhalecc
e269d1ba00 Fix gettext sanity check 2024-11-23 11:55:29 +08:00
crazywhalecc
87750c462f Do not cache PHP 2024-11-23 11:55:29 +08:00
crazywhalecc
219edb6b59 Add extension matrix tests 2024-11-23 11:55:29 +08:00
crazywhalecc
4f87e01bff Use similar optimize flags for compiling PHP (bump major ver) 2024-11-23 11:55:29 +08:00
crazywhalecc
5f69e957ac Add 8.1-8.3 test 2024-11-23 11:55:29 +08:00
crazywhalecc
756bdbf92f Fix imagick build for PHP 8.4 2024-11-23 11:55:29 +08:00
crazywhalecc
610fb66b0c Remove --with-zlib-dir that has been removed in 8.4 2024-11-23 11:55:29 +08:00
crazywhalecc
1186bac49c Update README 2024-11-23 11:55:29 +08:00
crazywhalecc
f6fe902c76 Fix sodium build, remove build patches 2024-11-23 11:55:29 +08:00
crazywhalecc
f984516a67 Change swoole source to git master instead of pecl (6.0 has not been released) 2024-11-23 11:55:29 +08:00
crazywhalecc
0d2f6456fb Change default download php version to 8.3 2024-11-23 11:55:29 +08:00
crazywhalecc
2fc61d8e5c Remove 8.1-8.3 tests 2024-11-23 11:55:29 +08:00
crazywhalecc
12b119e235 Fix display PHP version when using archive 2024-11-23 11:55:29 +08:00
crazywhalecc
6fa5f75963 Fix imap library build in macOS Sequoia 2024-11-23 11:55:29 +08:00
crazywhalecc
1fa5514c57 8.4 download imap separately, compatible with 8.1-8.3 2024-11-23 11:55:29 +08:00
crazywhalecc
73e3480bdf Add 8.4 support for switch-php-version command 2024-11-23 11:55:29 +08:00
crazywhalecc
ddafdf8987 Add PHP 8.4 support (testing) 2024-11-23 11:55:29 +08:00
crazywhalecc
2bfc5e1d74 Add grpc support for macOS and Linux 2024-11-10 10:42:04 +08:00
yinheli
3c4d47d072 feat: improve downloader retry (#558)
- Refactored to remove duplicate retry expressions by utilizing the getRetryTime() method.
- Fixed a typo in the log message.
2024-11-09 10:50:08 +08:00
crazywhalecc
c840165fa8 Add tests for rdkafka 2024-09-23 16:52:01 +08:00
crazywhalecc
4e95d969e3 Merge branch 'refs/heads/main' into ext/rdkafka
# Conflicts:
#	config/source.json
2024-09-23 16:25:59 +08:00
daddeffe
330dd2bfc6 Added optional zlib and disabled two extension (#545)
asd
2024-09-23 16:19:40 +08:00
crazywhalecc
c0b52fc2d1 Add extension rdkafka support 2023-11-05 17:09:48 +08:00
96 changed files with 1819 additions and 684 deletions

4
.github/FUNDING.yml vendored
View File

@@ -1,9 +1,9 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
github: [crazywhalecc]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: crazywhalecc # Replace with a single Ko-fi username
# ko_fi: crazywhalecc # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username

View File

@@ -1,130 +0,0 @@
name: CI on arm linux
on:
workflow_dispatch:
inputs:
operating-system:
required: true
description: Compile target arch (Linux only)
type: choice
options:
- aarch64
version:
required: true
description: php version to compile
default: '8.2'
type: choice
options:
- '8.3'
- '8.2'
- '8.1'
- '8.0'
- '7.4'
build-cli:
description: build cli binary
default: true
type: boolean
build-micro:
description: build phpmicro binary
type: boolean
build-fpm:
description: build fpm binary
type: boolean
extensions:
description: extensions to compile (comma separated)
required: true
type: string
prefer-pre-built:
description: prefer pre-built binaries (reduce build time)
type: boolean
default: true
debug:
description: enable debug logs
type: boolean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build:
name: build ${{ inputs.version }} on ${{ inputs.operating-system }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v4
with:
path: vendor
key: composer-dependencies
# If there's no Composer cache, install dependencies
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev --classmap-authoritative
- name: Generate hashed key for download cache
run: |
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
# Cache downloaded source
- id: cache-download
uses: actions/cache@v4
with:
path: downloads
key: php-${{ env.INPUT_HASH }}
# With or without debug
- if: inputs.debug == true
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
- if: inputs.prefer-pre-built == true
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
# With target select: cli, micro or both
- if: ${{ inputs.build-cli == true }}
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
- if: ${{ inputs.build-micro == true }}
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
- if: ${{ inputs.build-fpm == true }}
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: SPC_USE_ARCH=${{ inputs.operating-system }} ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
# Run build command
- run: SPC_USE_ARCH=${{ inputs.operating-system }} ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4
with:
name: php-${{ inputs.version }}-linux-${{ inputs.operating-system }}
path: buildroot/bin/php
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4
with:
name: micro-${{ inputs.version }}-linux-${{ inputs.operating-system }}
path: buildroot/bin/micro.sfx
# Upload fpm executable
- if: ${{ inputs.build-fpm == true }}
uses: actions/upload-artifact@v4
with:
name: php-fpm-${{ inputs.version }}-linux-${{ inputs.operating-system }}
path: buildroot/bin/php-fpm
# Upload extensions metadata
- uses: actions/upload-artifact@v4
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v4
with:
name: build-meta
path: |
buildroot/build-extensions.json
buildroot/build-libraries.json

View File

@@ -1,125 +0,0 @@
name: CI on x86_64 linux
on:
workflow_dispatch:
inputs:
version:
required: true
description: php version to compile
default: '8.2'
type: choice
options:
- '8.3'
- '8.2'
- '8.1'
- '8.0'
- '7.4'
build-cli:
description: build cli binary
default: true
type: boolean
build-micro:
description: build phpmicro binary
type: boolean
build-fpm:
description: build fpm binary
type: boolean
extensions:
description: extensions to compile (comma separated)
required: true
type: string
prefer-pre-built:
description: prefer pre-built binaries (reduce build time)
type: boolean
default: true
debug:
description: enable debug logs
type: boolean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build:
name: build ${{ inputs.version }} on Linux x86_64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v4
with:
path: vendor
key: composer-dependencies
# If there's no Composer cache, install dependencies
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev --classmap-authoritative
- name: Generate hashed key for download cache
run: |
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
# Cache downloaded source
- id: cache-download
uses: actions/cache@v4
with:
path: downloads
key: php-${{ env.INPUT_HASH }}
# With or without debug
- if: inputs.debug == true
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
- if: inputs.prefer-pre-built == true
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
# With target select: cli, micro or both
- if: ${{ inputs.build-cli == true }}
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
- if: ${{ inputs.build-micro == true }}
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
- if: ${{ inputs.build-fpm == true }}
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: CACHE_API_EXEC=yes ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
# Run build command
- run: ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4
with:
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4
with:
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/micro.sfx
# Upload fpm executable
- if: ${{ inputs.build-fpm == true }}
uses: actions/upload-artifact@v4
with:
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php-fpm
# Upload extensions metadata
- uses: actions/upload-artifact@v4
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v4
with:
name: build-meta
path: |
buildroot/build-extensions.json
buildroot/build-libraries.json

View File

@@ -1,139 +0,0 @@
name: CI on arm64 macOS
on:
workflow_dispatch:
inputs:
version:
required: true
description: php version to compile
default: '8.2'
type: choice
options:
- '8.3'
- '8.2'
- '8.1'
- '8.0'
- '7.4'
build-cli:
description: build cli binary
default: true
type: boolean
build-micro:
description: build phpmicro binary
type: boolean
build-fpm:
description: build fpm binary
type: boolean
extensions:
description: extensions to compile (comma separated)
required: true
type: string
prefer-pre-built:
description: prefer pre-built binaries (reduce build time)
type: boolean
default: true
debug:
description: enable debug logs
type: boolean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build:
name: build ${{ inputs.version }} on macOS arm64
runs-on: macos-14
steps:
- uses: actions/checkout@v4
# Install macOS missing packages and mark os suffix
- run: |
brew install automake gzip
echo "SPC_BUILD_OS=macos" >> $GITHUB_ENV
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
tools: pecl, composer
extensions: curl, openssl, mbstring, tokenizer
ini-values: memory_limit=-1
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v4
with:
path: vendor
key: composer-dependencies
# If there's no Composer cache, install dependencies
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev --classmap-authoritative
- name: Generate hashed key for download cache
run: |
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
# Cache downloaded source
- id: cache-download
uses: actions/cache@v4
with:
path: downloads
key: php-${{ env.INPUT_HASH }}
# With or without debug
- if: inputs.debug == true
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
- if: inputs.prefer-pre-built == true
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
# With target select: cli, micro or both
- if: ${{ inputs.build-cli == true }}
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
- if: ${{ inputs.build-micro == true }}
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
- if: ${{ inputs.build-fpm == true }}
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: ./bin/spc download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
# Run build command
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4
with:
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4
with:
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/micro.sfx
# Upload fpm executable
- if: ${{ inputs.build-fpm == true }}
uses: actions/upload-artifact@v4
with:
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php-fpm
# Upload extensions metadata
- uses: actions/upload-artifact@v4
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v4
with:
name: build-meta
path: |
buildroot/build-extensions.json
buildroot/build-libraries.json

View File

@@ -1,138 +0,0 @@
name: CI on x86_64 macOS
on:
workflow_dispatch:
inputs:
version:
required: true
description: php version to compile
default: '8.2'
type: choice
options:
- '8.3'
- '8.2'
- '8.1'
- '8.0'
- '7.4'
build-cli:
description: build cli binary
default: true
type: boolean
build-micro:
description: build phpmicro binary
type: boolean
build-fpm:
description: build fpm binary
type: boolean
extensions:
description: extensions to compile (comma separated)
required: true
type: string
prefer-pre-built:
description: prefer pre-built binaries (reduce build time)
type: boolean
default: true
debug:
description: enable debug logs
type: boolean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build:
name: build ${{ inputs.version }} on macOS x86_64
runs-on: macos-13
steps:
- uses: actions/checkout@v4
# Install macOS missing packages and mark os suffix
- run: |
brew install automake gzip
echo "SPC_BUILD_OS=macos" >> $GITHUB_ENV
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: 8.1
tools: pecl, composer
extensions: curl, openssl, mbstring, tokenizer
ini-values: memory_limit=-1
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v4
with:
path: vendor
key: composer-dependencies
# If there's no Composer cache, install dependencies
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev --classmap-authoritative
- name: Generate hashed key for download cache
run: |
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
# Cache downloaded source
- id: cache-download
uses: actions/cache@v4
with:
path: downloads
key: php-${{ env.INPUT_HASH }}
# With or without debug
- if: inputs.debug == true
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
- if: inputs.prefer-pre-built == true
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
# With target select: cli, micro or both
- if: ${{ inputs.build-cli == true }}
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
- if: ${{ inputs.build-micro == true }}
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
- if: ${{ inputs.build-fpm == true }}
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
# If there's no dependencies cache, fetch sources, with or without debug
- if: steps.cache-download.outputs.cache-hit != 'true'
run: ./bin/spc download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
# Run build command
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4
with:
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4
with:
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/micro.sfx
# Upload fpm executable
- if: ${{ inputs.build-fpm == true }}
uses: actions/upload-artifact@v4
with:
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php-fpm
# Upload extensions metadata
- uses: actions/upload-artifact@v4
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v4
with:
name: build-meta
path: |
buildroot/build-extensions.json
buildroot/build-libraries.json

190
.github/workflows/build-unix.yml vendored Normal file
View File

@@ -0,0 +1,190 @@
name: "CI on Unix"
on:
workflow_dispatch:
inputs:
os:
required: true
description: Build target OS
type: choice
options:
- 'linux-x86_64'
- 'linux-aarch64'
- 'macos-x86_64'
- 'macos-aarch64'
php-version:
required: true
description: PHP version to compile
default: '8.3'
type: choice
options:
- '8.4'
- '8.3'
- '8.2'
- '8.1'
- '8.0'
extensions:
description: Extensions to build (comma separated)
required: true
type: string
extra-libs:
description: Extra libraries to build (optional, comma separated)
type: string
build-cli:
description: Build cli binary
default: true
type: boolean
build-micro:
description: Build phpmicro binary
type: boolean
build-fpm:
description: Build fpm binary
type: boolean
prefer-pre-built:
description: Prefer pre-built binaries (reduce build time)
type: boolean
default: true
debug:
description: Show full build logs
type: boolean
no-strip:
description: Keep debug symbols for debugging
type: boolean
default: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
define-build:
name: "Define Build Scripts"
runs-on: ubuntu-latest
outputs:
run: ${{ steps.gendef.outputs.run }}
download: ${{ steps.gendef.outputs.download }}
build: ${{ steps.gendef.outputs.build }}
steps:
- name: "Checkout"
uses: actions/checkout@v4
- name: "Define"
id: gendef
run: |
case "${{ inputs.os }}" in
linux-x86_64)
DOWN_CMD="./bin/spc-alpine-docker download"
BUILD_CMD="./bin/spc-alpine-docker build"
RUNS_ON="ubuntu-latest"
;;
linux-aarch64)
DOWN_CMD="SPC_USE_ARCH=aarch64 ./bin/spc-alpine-docker download"
BUILD_CMD="SPC_USE_ARCH=aarch64 ./bin/spc-alpine-docker build"
RUNS_ON="ubuntu-latest"
;;
macos-x86_64)
DOWN_CMD="composer update --no-dev --classmap-authoritative && ./bin/spc doctor --auto-fix && ./bin/spc download"
BUILD_CMD="./bin/spc build"
RUNS_ON="macos-13"
;;
macos-aarch64)
DOWN_CMD="composer update --no-dev --classmap-authoritative && ./bin/spc doctor --auto-fix && ./bin/spc download"
BUILD_CMD="./bin/spc build"
RUNS_ON="macos-14"
;;
esac
DOWN_CMD="$DOWN_CMD --with-php=${{ inputs.php-version }} --for-extensions=${{ inputs.extensions }} --ignore-cache-sources=php-src"
BUILD_CMD="$BUILD_CMD ${{ inputs.extensions }}"
if [ -n "${{ inputs.extra-libs }}" ]; then
DOWN_CMD="$DOWN_CMD --for-libs=${{ inputs.extra-libs }}"
BUILD_CMD="$BUILD_CMD --with-libs=${{ inputs.extra-libs }}"
fi
if [ ${{ inputs.debug }} == true ]; then
DOWN_CMD="$DOWN_CMD --debug"
BUILD_CMD="$BUILD_CMD --debug"
fi
if [ ${{ inputs.prefer-pre-built }} == true ]; then
DOWN_CMD="$DOWN_CMD --prefer-pre-built"
fi
if [ ${{ inputs.build-cli }} == true ]; then
BUILD_CMD="$BUILD_CMD --build-cli"
fi
if [ ${{ inputs.build-micro }} == true ]; then
BUILD_CMD="$BUILD_CMD --build-micro"
fi
if [ ${{ inputs.build-fpm }} == true ]; then
BUILD_CMD="$BUILD_CMD --build-fpm"
fi
echo 'download='"$DOWN_CMD" >> "$GITHUB_OUTPUT"
echo 'build='"$BUILD_CMD" >> "$GITHUB_OUTPUT"
echo 'run='"$RUNS_ON" >> "$GITHUB_OUTPUT"
build:
name: "Build ${{ inputs.version }} on ${{ inputs.os }}"
runs-on: ${{ needs.define-build.outputs.run }}
needs: define-build
timeout-minutes: 240
steps:
- name: "Checkout"
uses: actions/checkout@v4
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: ${{ inputs.php-version }}
tools: pecl, composer
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
env:
phpts: nts
# Cache downloaded source
- id: cache-download
uses: actions/cache@v4
with:
path: downloads
key: php-dependencies-${{ inputs.os }}
- name: "Download sources"
run: ${{ needs.define-build.outputs.download }}
- name: "Build PHP"
run: ${{ needs.define-build.outputs.build }}
#- name: Setup tmate session
# if: ${{ failure() }}
# uses: mxschmitt/action-tmate@v3
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
name: "Upload PHP cli SAPI"
uses: actions/upload-artifact@v4
with:
name: php-cli-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/bin/php
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
name: "Upload PHP micro SAPI"
uses: actions/upload-artifact@v4
with:
name: php-micro-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/bin/micro.sfx
# Upload fpm executable
- if: ${{ inputs.build-fpm == true }}
name: "Upload PHP fpm SAPI"
uses: actions/upload-artifact@v4
with:
name: php-fpm-${{ inputs.php-version }}-${{ inputs.os }}
path: buildroot/bin/php-fpm
# Upload extensions metadata
- uses: actions/upload-artifact@v4
name: "Upload License Files"
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v4
name: "Upload Build Metadata"
with:
name: build-meta
path: |
buildroot/build-extensions.json
buildroot/build-libraries.json

View File

@@ -9,11 +9,11 @@ on:
default: '8.2'
type: choice
options:
- '8.4'
- '8.3'
- '8.2'
- '8.1'
- '8.0'
- '7.4'
build-cli:
description: build cli binary
default: true

148
.github/workflows/ext-matrix-tests.yml vendored Normal file
View File

@@ -0,0 +1,148 @@
name: "Extension matrix tests"
on:
workflow_dispatch:
pull_request:
branches: [ "main" ]
paths:
- '.github/workflows/ext-matrix-tests.yml'
jobs:
test:
name: "${{ matrix.extension }} (PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }})"
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
extension:
- amqp
- apcu
- bcmath
- bz2
- calendar
- ctype
- curl
- dba
- dom
- ds
- event
- exif
- filter
- fileinfo
- ftp
- gd
- gettext
- gmp
- iconv
- igbinary
- imagick
- imap
- intl
- ldap
- mbstring,mbregex
- memcache
- mysqli,mysqlnd,pdo_mysql
- opcache
- openssl
- pcntl
- password-argon2
- pcntl
- pdo
- pgsql,pdo_pgsql
- phar
- posix
- rar
- protobuf
- readline
- redis
- session
- shmop
- simdjson
- simplexml,xml
- snappy
- soap
- sockets
- sodium
- sqlite3,pdo_sqlite
- sqlsrv
- ssh2
- swoole
- swoole,swoole-hook-pgsql,swoole-hook-mysql,swoole-hook-sqlite
- swow
- sysvmsg,sysvsem,sysvshm
- tidy
- tokenizer
- uuid
- uv
- xhprof
- xlswriter
- xmlwriter,xmlreader
- xsl
- yac
- yaml
- zip
- zlib
- zstd
php-version:
- "8.4"
operating-system:
- "ubuntu-latest"
#- "macos-13"
#- "debian-arm64-self-hosted"
- "macos-14"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
- name: OS type
id: os-type
run: |
OS=""
if [ "${{ matrix.operating-system }}" = "ubuntu-latest" ]; then
OS="linux-x86_64"
elif [ "${{ matrix.operating-system }}" = "macos-13" ]; then
OS="macos-x86_64"
elif [ "${{ matrix.operating-system }}" = "debian-arm64-self-hosted" ]; then
OS="linux-aarch64"
elif [ "${{ matrix.operating-system }}" = "macos-14" ]; then
OS="macos-aarch64"
fi
echo "OS=$OS" >> $GITHUB_ENV
- name: "Setup PHP"
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
tools: pecl, composer
extensions: curl, openssl, mbstring
ini-values: memory_limit=-1
env:
phpts: nts
- name: "Install Dependencies"
run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- id: cache-download
uses: actions/cache@v4
with:
path: downloads
key: php-${{ matrix.php-version }}-dependencies-for-tests
# If there's no dependencies cache, fetch sources
- name: "Download sources"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./bin/spc download --with-php=${{ matrix.php-version }} --for-extensions=${{ matrix.extension }} --debug --ignore-cache-sources=php-src
- name: "Build library: ${{ matrix.library }}"
run: |
SPC_USE_SUDO=yes ./bin/spc doctor --auto-fix
if [ "${{ env.OS }}" = "linux-x86_64" ]; then
./bin/spc install-pkg upx
UPX=--with-upx-pack
elif [ "${{ env.OS }}" = "linux-aarch64" ]; then
./bin/spc install-pkg upx
UPX=--with-upx-pack
fi
./bin/spc build --build-cli --build-micro --build-fpm ${{ matrix.extension }} --debug $UPX --with-suggested-libs --with-suggested-exts

View File

@@ -82,6 +82,7 @@ jobs:
- php: '8.1'
- php: '8.2'
- php: '8.3'
- php: '8.4'
steps:
- name: "Checkout"
@@ -198,3 +199,7 @@ jobs:
- name: "Run Build Tests (build)"
run: php src/globals/test-extensions.php build_cmd ${{ matrix.os }} ${{ matrix.php }}
- name: "Run Build Tests (build - embed for non-windows)"
if: matrix.os != 'windows-latest'
run: php src/globals/test-extensions.php build_embed_cmd ${{ matrix.os }} ${{ matrix.php }}

View File

@@ -82,16 +82,18 @@ static-php-cli简称 `spc`)有许多特性:
>
> :x: 不支持
| PHP Version | Status | Comment |
|-------------|--------------------|------------------------------|
| 7.2 | :x: | |
| 7.3 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 7.4 | :warning: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 8.0 | :heavy_check_mark: | PHP 官方已停止 8.0 的维护 |
| 8.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新 |
| 8.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | |
| 8.4 | :x: | WIP |
| PHP Version | Status | Comment |
|-------------|--------------------|----------------------------------------------|
| 7.2 | :x: | |
| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
| 8.1 | :heavy_check_mark: | PHP 官方仅对 8.1 提供安全更新 |
| 8.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | |
| 8.4 | :heavy_check_mark: | |
> 这个表格的支持状态是 static-php-cli 对构建对应版本的支持情况,不是 PHP 官方对该版本的支持情况。
### 支持的扩展

View File

@@ -89,16 +89,19 @@ Currently supported PHP versions for compilation:
>
> :x: not supported
| PHP Version | Status | Comment |
|-------------|--------------------|---------------------------------------------------|
| 7.2 | :x: | |
| 7.3 | :warning: | phpmicro and some extensions not supported on 7.x |
| 7.4 | :warning: | phpmicro and some extensions not supported on 7.x |
| 8.0 | :heavy_check_mark: | PHP official has stopped maintenance of 8.0 |
| 8.1 | :heavy_check_mark: | PHP official has security fixes only |
| 8.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | |
| 8.4 | :x: | WIP |
| PHP Version | Status | Comment |
|-------------|--------------------|----------------------------------------------------------------------------------------------------|
| 7.2 | :x: | |
| 7.3 | :x: | phpmicro and some extensions not supported on 7.x |
| 7.4 | :x: | phpmicro and some extensions not supported on 7.x |
| 8.0 | :warning: | PHP official has stopped maintenance of 8.0, we no longer provide backport support for version 8.0 |
| 8.1 | :heavy_check_mark: | PHP official has security fixes only |
| 8.2 | :heavy_check_mark: | |
| 8.3 | :heavy_check_mark: | |
| 8.4 | :heavy_check_mark: | |
> This table shows the support status for static-php-cli in building the corresponding version,
> not the official PHP support status for that version.
### Supported Extensions
@@ -310,7 +313,7 @@ Now there is a [static-php](https://github.com/static-php) organization, which i
## Sponsor this project
You can sponsor my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md). A portion of your donation will be used to maintain the **static-php.dev** server.
You can sponsor me or my project from [GitHub Sponsor](https://github.com/crazywhalecc). A portion of your donation will be used to maintain the **static-php.dev** server.
## Open-Source License

28
composer.lock generated
View File

@@ -2529,16 +2529,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.64.0",
"version": "v3.65.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "58dd9c931c785a79739310aef5178928305ffa67"
"reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/58dd9c931c785a79739310aef5178928305ffa67",
"reference": "58dd9c931c785a79739310aef5178928305ffa67",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/79d4f3e77b250a7d8043d76c6af8f0695e8a469f",
"reference": "79d4f3e77b250a7d8043d76c6af8f0695e8a469f",
"shasum": ""
},
"require": {
@@ -2548,7 +2548,7 @@
"ext-filter": "*",
"ext-json": "*",
"ext-tokenizer": "*",
"fidry/cpu-core-counter": "^1.0",
"fidry/cpu-core-counter": "^1.2",
"php": "^7.4 || ^8.0",
"react/child-process": "^0.6.5",
"react/event-loop": "^1.0",
@@ -2568,18 +2568,18 @@
"symfony/stopwatch": "^5.4 || ^6.0 || ^7.0"
},
"require-dev": {
"facile-it/paraunit": "^1.3 || ^2.3",
"infection/infection": "^0.29.5",
"justinrainbow/json-schema": "^5.2",
"facile-it/paraunit": "^1.3.1 || ^2.4",
"infection/infection": "^0.29.8",
"justinrainbow/json-schema": "^5.3 || ^6.0",
"keradus/cli-executor": "^2.1",
"mikey179/vfsstream": "^1.6.11",
"mikey179/vfsstream": "^1.6.12",
"php-coveralls/php-coveralls": "^2.7",
"php-cs-fixer/accessible-object": "^1.1",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5",
"phpunit/phpunit": "^9.6.19 || ^10.5.21 || ^11.2",
"symfony/var-dumper": "^5.4 || ^6.0 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
"phpunit/phpunit": "^9.6.21 || ^10.5.38 || ^11.4.3",
"symfony/var-dumper": "^5.4.47 || ^6.4.15 || ^7.1.8",
"symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.1.6"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
@@ -2620,7 +2620,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.64.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.65.0"
},
"funding": [
{
@@ -2628,7 +2628,7 @@
"type": "github"
}
],
"time": "2024-08-30T23:09:38+00:00"
"time": "2024-11-25T00:39:24+00:00"
},
{
"name": "humbug/box",

View File

@@ -94,7 +94,7 @@ SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_PHP_DEFAULT_OPTIMIZE_CFLAGS} -fno-ident
; EXTRA_LIBS for `make` php
SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS=""
; EXTRA_LDFLAGS_PROGRAM for `make` php
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static"
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -Wl,-O1 -pie"
[macos]
; compiler environments

View File

@@ -17,6 +17,10 @@
"type": "external",
"source": "apcu"
},
"ast": {
"type": "external",
"source": "ast"
},
"bcmath": {
"type": "builtin"
},
@@ -199,6 +203,19 @@
"gmssl"
]
},
"grpc": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "grpc",
"arg-type-unix": "custom",
"cpp-extension": true,
"lib-depends": [
"grpc"
]
},
"iconv": {
"support": {
"BSD": "wip"
@@ -242,7 +259,8 @@
"BSD": "wip"
},
"notes": true,
"type": "builtin",
"type": "external",
"source": "ext-imap",
"arg-type": "custom",
"lib-depends": [
"imap"
@@ -510,7 +528,7 @@
},
"notes": true,
"type": "builtin",
"arg-type": "with-prefix",
"arg-type": "custom",
"lib-depends": [
"postgresql"
]
@@ -546,6 +564,19 @@
"source": "rar",
"cpp-extension": true
},
"rdkafka": {
"support": {
"BSD": "wip",
"Windows": "wip"
},
"type": "external",
"source": "ext-rdkafka",
"arg-type": "custom",
"cpp-extension": true,
"lib-depends": [
"librdkafka"
]
},
"readline": {
"support": {
"Windows": "wip",

View File

@@ -139,6 +139,20 @@
"Security"
]
},
"grpc": {
"source": "grpc",
"static-libs-unix": [
"libgrpc.a",
"libcares.a"
],
"lib-depends": [
"zlib",
"openssl"
],
"frameworks": [
"CoreFoundation"
]
},
"icu": {
"source": "icu",
"cpp-library": true,
@@ -162,7 +176,8 @@
"libjpeg",
"libwebp",
"freetype",
"libtiff"
"libtiff",
"libheif"
],
"lib-suggests": [
"zstd",
@@ -194,6 +209,13 @@
"libsodium"
]
},
"libaom": {
"source": "libaom",
"static-libs-unix": [
"libaom.a"
],
"cpp-library": true
},
"libargon2": {
"source": "libargon2",
"static-libs-unix": [
@@ -221,6 +243,13 @@
"ares_rules.h"
]
},
"libde265": {
"source": "libde265",
"static-libs-unix": [
"libde265.a"
],
"cpp-library": true
},
"libevent": {
"source": "libevent",
"static-libs-unix": [
@@ -262,6 +291,19 @@
"fficonfig.h"
]
},
"libheif": {
"source": "libheif",
"static-libs-unix": [
"libheif.a"
],
"lib-depends": [
"libde265",
"libwebp",
"libaom",
"zlib",
"brotli"
]
},
"libiconv": {
"source": "libiconv",
"static-libs-unix": [
@@ -341,6 +383,18 @@
"openssl"
]
},
"librdkafka": {
"source": "librdkafka",
"static-libs-unix": [
"librdkafka.a",
"librdkafka++.a",
"librdkafka-static.a"
],
"cpp-library": true,
"lib-suggests": [
"zstd"
]
},
"libsodium": {
"source": "libsodium",
"static-libs-unix": [
@@ -371,6 +425,10 @@
"source": "libtiff",
"static-libs-unix": [
"libtiff.a"
],
"lib-depends": [
"zlib",
"libjpeg"
]
},
"libuuid": {

View File

@@ -26,6 +26,16 @@
"path": "LICENSE"
}
},
"ast": {
"type": "url",
"url": "https://pecl.php.net/get/ast",
"path": "php-src/ext/ast",
"filename": "ast.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"brotli": {
"type": "ghtar",
"repo": "google/brotli",
@@ -36,9 +46,13 @@
}
},
"bzip2": {
"type": "filelist",
"url": "https://sourceware.org/pub/bzip2/",
"regex": "/href=\"(?<file>bzip2-(?<version>[^\"]+)\\.tar\\.gz)\"/",
"alt": {
"type": "filelist",
"url": "https://sourceware.org/pub/bzip2/",
"regex": "/href=\"(?<file>bzip2-(?<version>[^\"]+)\\.tar\\.gz)\"/"
},
"type": "url",
"url": "https://dl.static-php.dev/static-php-cli/deps/bzip2/bzip2-1.0.8.tar.gz",
"provide-pre-built": true,
"license": {
"type": "text",
@@ -102,6 +116,18 @@
"path": "LICENSE"
}
},
"ext-imap": {
"type": "url",
"url": "https://pecl.php.net/get/imap",
"path": "php-src/ext/imap",
"filename": "imap.tgz",
"license": {
"type": "file",
"path": [
"LICENSE"
]
}
},
"ext-memcache": {
"type": "url",
"url": "https://pecl.php.net/get/memcache",
@@ -112,6 +138,15 @@
"path": "LICENSE"
}
},
"ext-rdkafka": {
"type": "ghtar",
"repo": "arnaud-lb/php-rdkafka",
"path": "php-src/ext/rdkafka",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-simdjson": {
"type": "url",
"url": "https://pecl.php.net/get/simdjson",
@@ -211,6 +246,16 @@
"path": "LICENSE"
}
},
"grpc": {
"type": "git",
"rev": "v1.68.x",
"url": "https://github.com/grpc/grpc.git",
"provide-pre-built": true,
"license": {
"type": "file",
"path": "LICENSE"
}
},
"icu": {
"type": "ghrel",
"repo": "unicode-org/icu",
@@ -268,6 +313,16 @@
"path": "LICENSE"
}
},
"libaom": {
"type": "git",
"rev": "main",
"url": "https://aomedia.googlesource.com/aom",
"provide-pre-built": true,
"license": {
"type": "file",
"path": "LICENSE"
}
},
"libargon2": {
"type": "git",
"rev": "master",
@@ -303,6 +358,17 @@
"path": "LICENSE.md"
}
},
"libde265": {
"type": "ghrel",
"repo": "strukturag/libde265",
"match": "libde265-.+\\.tar\\.gz",
"prefer-stable": true,
"provide-pre-built": true,
"license": {
"type": "file",
"path": "COPYING"
}
},
"libevent": {
"type": "ghrel",
"repo": "libevent/libevent",
@@ -333,6 +399,17 @@
"path": "LICENSE"
}
},
"libheif": {
"type": "ghrel",
"repo": "strukturag/libheif",
"match": "libheif-.+\\.tar\\.gz",
"prefer-stable": true,
"provide-pre-built": true,
"license": {
"type": "file",
"path": "COPYING"
}
},
"libiconv": {
"type": "filelist",
"url": "https://ftp.gnu.org/gnu/libiconv/",
@@ -399,6 +476,14 @@
"path": "LICENSE"
}
},
"librdkafka": {
"type": "ghtar",
"repo": "confluentinc/librdkafka",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"libsodium": {
"type": "ghrel",
"repo": "jedisct1/libsodium",
@@ -513,7 +598,7 @@
"micro": {
"type": "git",
"path": "php-src/sapi/micro",
"rev": "master",
"rev": "84beta",
"url": "https://github.com/static-php/phpmicro",
"license": {
"type": "file",
@@ -708,7 +793,7 @@
},
"sqlite": {
"type": "url",
"url": "https://www.sqlite.org/2023/sqlite-autoconf-3430200.tar.gz",
"url": "https://www.sqlite.org/2024/sqlite-autoconf-3450200.tar.gz",
"provide-pre-built": true,
"license": {
"type": "text",
@@ -726,13 +811,18 @@
}
},
"swoole": {
"type": "ghtar",
"path": "php-src/ext/swoole",
"repo": "swoole/swoole-src",
"prefer-stable": true,
"type": "git",
"rev": "master",
"url": "https://github.com/swoole/swoole-src.git",
"license": {
"type": "file",
"path": "LICENSE"
},
"alt": {
"type": "ghtar",
"repo": "swoole/swoole-src",
"prefer-stable": true
}
},
"swow": {

View File

@@ -225,11 +225,11 @@ const isSupported = (extName, os) => {
};
const availablePhpVersions = [
'7.4',
'8.0',
'8.1',
'8.2',
'8.3',
'8.4',
];
const I18N = {

View File

@@ -84,3 +84,11 @@ For Linux systems, you can download the [cacert.pem](https://curl.se/docs/caextr
For the certificate locations of different distros, please refer to [Golang docs](https://go.dev/src/crypto/x509/root_linux.go).
> INI configuration `openssl.cafile` cannot be set dynamically using the `ini_set()` function, because `openssl.cafile` is a `PHP_INI_SYSTEM` type configuration and can only be set in the `php.ini` file.
## Why don't we support older versions of PHP?
Because older versions of PHP have many problems, such as security issues, performance issues, and functional issues.
In addition, many older versions of PHP are not compatible with the latest dependency libraries,
which is one of the reasons why older versions of PHP are not supported.
You can use older versions compiled earlier by static-php-cli, such as PHP 8.0, but earlier versions will not be explicitly supported.

View File

@@ -74,6 +74,12 @@ bin/setup-runtime -action add-path
bin/setup-runtime -action remove-path
```
Finally, now that you have PHP and Composer installed, you need to install static-php-cli's Composer dependencies:
```shell
composer install
```
### Install other Tools (automatic)
For `php-sdk-binary-tools`, `strawberry-perl`, and `nasm`,

View File

@@ -46,7 +46,7 @@ This extension contains an implementation of the coroutine environment for `pdo_
## swow
1. Only PHP version >= 8.0 is supported.
1. Only PHP 8.0 ~ 8.4 is supported.
## imap

View File

@@ -36,7 +36,7 @@ Windows currently only supports the x86_64 architecture, and does not support 32
## Supported PHP Version
Currently, static php cli supports PHP versions 8.0 to 8.3, and theoretically supports PHP 7.4 and earlier versions.
Currently, static php cli supports PHP versions 8.1 to 8.4, and theoretically supports PHP 8.0 and earlier versions.
Simply select the earlier version when downloading.
However, due to some extensions and special components that have stopped supporting earlier versions of PHP,
static-php-cli will not explicitly support earlier versions.

View File

@@ -142,9 +142,9 @@ including php-src and the source code of various dependent libraries.
# Download all dependencies
bin/spc download --all
# Download all dependent packages, and specify the main version of PHP to download, optional: 7.3, 7.4, 8.0, 8.1, 8.2, 8.3
# Download all dependent packages, and specify the main version of PHP to download, optional: 8.1, 8.2, 8.3, 8.4
# Also supports specific version of php release: 8.3.10, 8.2.22, etc.
bin/spc download --all --with-php=8.2
bin/spc download --all --with-php=8.3
# Show download progress bar while downloading (curl)
bin/spc download --all --debug
@@ -272,12 +272,12 @@ If you want to build multiple versions of PHP and don't want to build other depe
you can use `switch-php-version` to quickly switch to another version and compile after compiling one version:
```shell
# switch to 8.3
bin/spc switch-php-version 8.3
# switch to 8.4
bin/spc switch-php-version 8.4
# build
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
# switch to 8.0
bin/spc switch-php-version 8.0
# switch to 8.1
bin/spc switch-php-version 8.1
# build
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
```
@@ -553,3 +553,76 @@ If you need to build multiple times locally, the following method can save you t
- If you want to rebuild once, but do not re-download the source code, you can first `rm -rf buildroot source` to delete the compilation directory and source code directory, and then rebuild.
- If you want to update a version of a dependency, you can use `bin/spc del-download <source-name>` to delete the specified source code, and then use `download <source-name>` to download it again.
- If you want to update all dependent versions, you can use `bin/spc download --clean` to delete all downloaded sources, and then download them again.
## embed usage
If you want to embed static-php into other C language programs, you can use `--build-embed` to build an embed version of PHP.
```bash
bin/spc build {your extensions} --build-embed --debug
```
Under normal circumstances, PHP embed will generate `php-config` after compilation.
For static-php, we provide `spc-config` to obtain the parameters during compilation.
In addition, when using embed SAPI (libphp.a), you need to use the same compiler as libphp, otherwise there will be a link error.
Here is the basic usage of spc-config:
```bash
# output all flags and options
bin/spc spc-config curl,zlib,phar,openssl
# output libs
bin/spc spc-config curl,zlib,phar,openssl --libs
# output includes
bin/spc spc-config curl,zlib,phar,openssl --includes
```
By default, static-php uses the following compilers on different systems:
- macOS: `clang`
- Linux (Alpine Linux): `gcc`
- Linux (glibc based distros, x86_64): `/usr/local/musl/bin/x86_64-linux-musl-gcc`
- Linux (glibc based distros, aarch64): `/usr/local/musl/bin/aarch64-linux-musl-gcc`
- FreeBSD: `clang`
Here is an example of using embed SAPI:
```c
// embed.c
#include <sapi/embed/php_embed.h>
int main(int argc,char **argv){
PHP_EMBED_START_BLOCK(argc,argv)
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle,"embed.php");
if(php_execute_script(&file_handle) == FAILURE){
php_printf("Failed to execute PHP script.\n");
}
PHP_EMBED_END_BLOCK()
return 0;
}
```
```php
<?php
// embed.php
echo "Hello world!\n";
```
```bash
# compile in debian/ubuntu x86_64
/usr/local/musl/bin/x86_64-linux-musl-gcc embed.c $(bin/spc spc-config bcmath,zlib) -static -o embed
# compile in macOS/FreeBSD
clang embed.c $(bin/spc spc-config bcmath,zlib) -o embed
./embed
# out: Hello world!
```

View File

@@ -70,4 +70,10 @@ PHP 代码的编译器是完全不同的项目,因此不会考虑额外的情
对于 Linux 系统,你可以从 curl 官方网站下载 [cacert.pem](https://curl.se/docs/caextract.html) 文件,也可以使用系统自带的证书文件。
有关不同发行版的证书位置,可参考 [Go 标准库](https://go.dev/src/crypto/x509/root_linux.go)。
> INI 配置 `openssl.cafile` 不可以使用 `ini_set()` 函数动态设置,因为 `openssl.cafile` 是一个 `PHP_INI_SYSTEM` 类型的配置,只能在 `php.ini` 文件中设置。
> INI 配置 `openssl.cafile` 不可以使用 `ini_set()` 函数动态设置,因为 `openssl.cafile` 是一个 `PHP_INI_SYSTEM` 类型的配置,只能在 `php.ini` 文件中设置。
## 为什么不支持旧版本 PHP
因为旧版本的 PHP 有很多问题,比如安全问题、性能问题、功能问题等。此外,旧版本的 PHP 很多都无法与最新的依赖库兼容,这也是不支持旧版本 PHP 的原因之一。
你可以使用 static-php-cli 早期编译好的旧版本,如 PHP 8.0,但是不会明确支持早期版本。

View File

@@ -43,7 +43,7 @@ swoole-hook-sqlite 与 `pdo_sqlite` 扩展冲突。如需使用 Swoole 和 `pdo_
## swow
1. swow 仅支持 PHP >= 8.0 版本。
1. swow 仅支持 PHP 8.0 ~ 8.4 版本。
## imap

View File

@@ -29,6 +29,6 @@ Windows 目前只支持 x86_64 架构,不支持 32 位 x86、不支持 arm64
## PHP 支持版本
目前static-php-cli 对 PHP 7.4 ~ 8.3 版本是支持的,对于 PHP 7.4 及更早版本理论上支持,只需下载时选择早期版本即可。
目前static-php-cli 对 PHP 8.1 ~ 8.4 版本是支持的,对于 PHP 8.0 及更早版本理论上支持,只需下载时选择早期版本即可。
但由于部分扩展和特殊组件已对早期版本的 PHP 停止了支持,所以 static-php-cli 不会明确支持早期版本。
我们推荐你编译尽可能新的 PHP 版本,以获得更好的体验。

View File

@@ -141,8 +141,8 @@ bin/spc download --for-extensions="curl,pcntl,xml,mbstring" --prefer-pre-built
# 下载所有依赖包
bin/spc download --all
# 下载所有依赖包,并指定下载的 PHP 主版本,可选:7.37.48.08.18.28.3,也可以使用特定的版本,如 8.3.10。
bin/spc download --all --with-php=8.2
# 下载所有依赖包,并指定下载的 PHP 主版本可选8.18.28.38.4也可以使用特定的版本,如 8.3.10。
bin/spc download --all --with-php=8.3
# 下载时显示下载进度条curl
bin/spc download --all --debug
@@ -236,12 +236,12 @@ bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
如果你想构建多个版本的 PHP且不想每次都重复构建其他依赖库可以使用 `switch-php-version` 在编译好一个版本后快速切换至另一个版本并编译:
```shell
# switch to 8.3
bin/spc switch-php-version 8.3
# switch to 8.4
bin/spc switch-php-version 8.4
# build
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
# switch to 8.0
bin/spc switch-php-version 8.0
# switch to 8.1
bin/spc switch-php-version 8.1
# build
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
```
@@ -493,3 +493,75 @@ static-php-cli 开放的方法非常多,文档中无法一一列举,但只
- 如果你想重新构建一次,但不重新下载源码,可以先 `rm -rf buildroot source` 删除编译目录和源码目录,然后重新构建。
- 如果你想更新某个依赖的版本,可以使用 `bin/spc del-download <source-name>` 删除指定的源码,然后使用 `download <source-name>` 重新下载。
- 如果你想更新所有依赖的版本,可以使用 `bin/spc download --clean` 删除所有下载的源码,然后重新下载。
## embed 使用
如果你想将 static-php 嵌入到其他 C 语言程序中,可以使用 `--build-embed` 构建一个 embed 版本的 PHP。
```bash
bin/spc build {your extensions} --build-embed --debug
```
在通常的情况下PHP embed 编译后会生成 `php-config`。对于 static-php我们提供了 `spc-config`,用于获取编译时的参数。
另外,在使用 embed SAPIlibphp.a你需要使用和编译 libphp 相同的编译器,否则会出现链接错误。
下面是 spc-config 的基本用法:
```bash
# output all flags and options
bin/spc spc-config curl,zlib,phar,openssl
# output libs
bin/spc spc-config curl,zlib,phar,openssl --libs
# output includes
bin/spc spc-config curl,zlib,phar,openssl --includes
```
默认情况下static-php 在不同系统使用的编译器分别是:
- macOS: `clang`
- Linux (Alpine Linux): `gcc`
- Linux (glibc based distros, x86_64): `/usr/local/musl/bin/x86_64-linux-musl-gcc`
- Linux (glibc based distros, aarch64): `/usr/local/musl/bin/aarch64-linux-musl-gcc`
- FreeBSD: `clang`
下面是一个使用 embed SAPI 的例子:
```c
// embed.c
#include <sapi/embed/php_embed.h>
int main(int argc,char **argv){
PHP_EMBED_START_BLOCK(argc,argv)
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle,"embed.php");
if(php_execute_script(&file_handle) == FAILURE){
php_printf("Failed to execute PHP script.\n");
}
PHP_EMBED_END_BLOCK()
return 0;
}
```
```php
<?php
// embed.php
echo "Hello world!\n";
```
```bash
# compile in debian/ubuntu x86_64
/usr/local/musl/bin/x86_64-linux-musl-gcc embed.c $(bin/spc spc-config bcmath,zlib) -static -o embed
# compile in macOS/FreeBSD
clang embed.c $(bin/spc spc-config bcmath,zlib) -o embed
./embed
# out: Hello world!
```

View File

@@ -22,6 +22,7 @@ use SPC\command\DumpLicenseCommand;
use SPC\command\ExtractCommand;
use SPC\command\InstallPkgCommand;
use SPC\command\MicroCombineCommand;
use SPC\command\SPCConfigCommand;
use SPC\command\SwitchPhpVersionCommand;
use Symfony\Component\Console\Application;
@@ -30,7 +31,7 @@ use Symfony\Component\Console\Application;
*/
final class ConsoleApplication extends Application
{
public const VERSION = '2.3.6';
public const VERSION = '2.4.4';
public function __construct()
{
@@ -52,6 +53,7 @@ final class ConsoleApplication extends Application
new ExtractCommand(),
new MicroCombineCommand(),
new SwitchPhpVersionCommand(),
new SPCConfigCommand(),
// Dev commands
new AllExtCommand(),

View File

@@ -6,6 +6,7 @@ namespace SPC\builder;
use SPC\exception\ExceptionHandler;
use SPC\exception\FileSystemException;
use SPC\exception\InterruptException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\Config;
@@ -24,6 +25,12 @@ abstract class BuilderBase
/** @var array<string, Extension> extensions */
protected array $exts = [];
/** @var array<int, string> extension names */
protected array $ext_list = [];
/** @var array<int, string> library names */
protected array $lib_list = [];
/** @var bool compile libs only (just mark it) */
protected bool $libs_only = false;
@@ -160,7 +167,7 @@ abstract class BuilderBase
* @throws FileSystemException
* @throws RuntimeException
* @throws \ReflectionException
* @throws WrongUsageException
* @throws \Throwable|WrongUsageException
* @internal
*/
public function proveExts(array $extensions, bool $skip_check_deps = false): void
@@ -190,6 +197,7 @@ abstract class BuilderBase
foreach ($this->exts as $ext) {
$ext->checkDependency();
}
$this->ext_list = $extensions;
}
/**
@@ -276,7 +284,7 @@ abstract class BuilderBase
return false;
}
}
if (preg_match('/php-(\d+\.\d+\.\d+)/', $file, $match)) {
if (preg_match('/php-(\d+\.\d+\.\d+(?:RC\d+)?)\.tar\.(?:gz|bz2|xz)/', $file, $match)) {
return $match[1];
}
return false;
@@ -407,6 +415,13 @@ abstract class BuilderBase
}
logger()->debug('Running additional patch script: ' . $patch);
require $patch;
} catch (InterruptException $e) {
if ($e->getCode() === 0) {
logger()->notice('Patch script ' . $patch . ' interrupted' . ($e->getMessage() ? (': ' . $e->getMessage()) : '.'));
} else {
logger()->error('Patch script ' . $patch . ' interrupted with error code [' . $e->getCode() . ']' . ($e->getMessage() ? (': ' . $e->getMessage()) : '.'));
}
exit($e->getCode());
} catch (\Throwable $e) {
logger()->critical('Patch script ' . $patch . ' failed to run.');
if ($this->getOption('debug')) {
@@ -414,6 +429,7 @@ abstract class BuilderBase
} else {
logger()->critical('Please check with --debug option to see more details.');
}
throw $e;
}
}
}

View File

@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\builder\windows\WindowsBuilder;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
use SPC\util\GlobalEnvManager;
#[CustomExt('grpc')]
class grpc extends Extension
{
public function patchBeforeBuildconf(): bool
{
// soft link to the grpc source code
if ($this->builder instanceof WindowsBuilder) {
// not support windows yet
throw new \RuntimeException('grpc extension does not support windows yet');
}
if (!is_link(SOURCE_PATH . '/php-src/ext/grpc')) {
shell()->exec('ln -s ' . $this->builder->getLib('grpc')->getSourceDir() . '/src/php/ext/grpc ' . SOURCE_PATH . '/php-src/ext/grpc');
$macos = $this->builder instanceof MacOSBuilder ? "\n" . ' LDFLAGS="$LDFLAGS -framework CoreFoundation"' : '';
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/ext/grpc/config.m4', '/GRPC_LIBDIR=.*$/m', 'GRPC_LIBDIR=' . BUILD_LIB_PATH . $macos);
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/ext/grpc/config.m4', '/SEARCH_PATH=.*$/m', 'SEARCH_PATH="' . BUILD_ROOT_PATH . '"');
return true;
}
return false;
}
public function patchBeforeMake(): bool
{
// add -Wno-strict-prototypes
GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS=' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') . ' -Wno-strict-prototypes');
return true;
}
public function getUnixConfigureArg(): string
{
return '--enable-grpc=' . BUILD_ROOT_PATH . '/grpc GRPC_LIB_SUBDIR=' . BUILD_LIB_PATH;
}
}

View File

@@ -6,6 +6,7 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('parallel')]
@@ -17,4 +18,10 @@ class parallel extends Extension
throw new WrongUsageException('ext-parallel must be built with ZTS builds. Use "--enable-zts" option!');
}
}
public function patchBeforeBuildconf(): bool
{
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/ext/parallel/config.m4', '/PHP_VERSION=.*/m', '');
return true;
}
}

View File

@@ -6,6 +6,8 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
@@ -14,6 +16,8 @@ class pgsql extends Extension
{
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function patchBeforeConfigure(): bool
{
@@ -24,4 +28,16 @@ class pgsql extends Extension
);
return true;
}
/**
* @throws WrongUsageException
* @throws RuntimeException
*/
public function getUnixConfigureArg(): string
{
if ($this->builder->getPHPVersionID() >= 80400) {
return '--with-pgsql PGSQL_CFLAGS=-I' . BUILD_INCLUDE_PATH . ' PGSQL_LIBS="-L' . BUILD_LIB_PATH . ' -lpq -lpgport -lpgcommon"';
}
return '--with-pgsql=' . BUILD_ROOT_PATH;
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('rdkafka')]
class rdkafka extends Extension
{
public function patchBeforeMake(): bool
{
// when compiling rdkafka with inline builds, it shows some errors, I don't know why.
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/rdkafka/rdkafka.c',
"#ifdef HAS_RD_KAFKA_TRANSACTIONS\n#include \"kafka_error_exception.h\"\n#endif",
'#include "kafka_error_exception.h"'
);
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/rdkafka/kafka_error_exception.h',
['#ifdef HAS_RD_KAFKA_TRANSACTIONS', '#endif'],
''
);
return true;
}
public function getConfigureArg(): string
{
$pkgconf_libs = shell()->execWithResult('pkg-config --libs --static rdkafka')[1];
$pkgconf_libs = trim(implode('', $pkgconf_libs));
return '--with-rdkafka=' . BUILD_ROOT_PATH . ' LIBS="' . $pkgconf_libs . '"';
}
}

View File

@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('sodium')]
class sodium extends Extension
{
public function patchBeforeBuildconf(): bool
{
// bypass error: unknown warning option '-Wno-logical-op' for macOS
return $this->removeLineContainingString();
}
private function removeLineContainingString(): bool
{
$path = SOURCE_PATH . '/php-src/ext/sodium/config.m4';
$search = '-Wno-logical-op';
if (!file_exists($path)) {
return false;
}
$content = file_get_contents($path);
$lines = preg_split('/\r\n|\n/', $content);
$filteredLines = array_filter($lines, function ($line) use ($search) {
return strpos($line, $search) === false;
});
$newContent = implode("\n", $filteredLines);
file_put_contents($path, $newContent);
return true;
}
}

View File

@@ -12,6 +12,9 @@ class zlib extends Extension
{
public function getUnixConfigureArg(): string
{
if ($this->builder->getPHPVersionID() >= 80400) {
return '--with-zlib';
}
return '--with-zlib --with-zlib-dir="' . BUILD_ROOT_PATH . '"';
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -21,13 +21,16 @@ class SystemUtil
switch (true) {
case file_exists('/etc/centos-release'):
$lines = file('/etc/centos-release');
$centos = true;
goto rh;
case file_exists('/etc/redhat-release'):
$lines = file('/etc/redhat-release');
$centos = false;
rh:
foreach ($lines as $line) {
if (preg_match('/release\s+(\d*(\.\d+)*)/', $line, $matches)) {
$ret['dist'] = 'redhat';
/* @phpstan-ignore-next-line */
$ret['dist'] = $centos ? 'centos' : 'redhat';
$ret['ver'] = $matches[1];
}
}
@@ -171,6 +174,8 @@ class SystemUtil
'debian', 'ubuntu', 'Deepin',
// rhel-like
'redhat',
// centos
'centos',
// alpine
'alpine',
// arch

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class grpc extends LinuxLibraryBase
{
use \SPC\builder\unix\library\grpc;
public const NAME = 'grpc';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class libaom extends LinuxLibraryBase
{
use \SPC\builder\unix\library\libaom;
public const NAME = 'libaom';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class libde265 extends LinuxLibraryBase
{
use \SPC\builder\unix\library\libde265;
public const NAME = 'libde265';
}

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class libheif extends LinuxLibraryBase
{
use \SPC\builder\unix\library\libheif;
public const NAME = 'libheif';
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace SPC\builder\linux\library;
class librdkafka extends LinuxLibraryBase
{
// TODO: Linux is buggy, see https://github.com/confluentinc/librdkafka/discussions/4495
use \SPC\builder\unix\library\librdkafka;
public const NAME = 'librdkafka';
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*
@@ -68,6 +69,7 @@ class openssl extends LinuxLibraryBase
"{$env} ./Configure no-shared {$extra} " .
'--prefix=/ ' .
'--libdir=lib ' .
'--openssldir=/etc/ssl ' .
'-static ' .
"{$zlib_extra}" .
'no-legacy ' .

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class grpc extends MacOSLibraryBase
{
use \SPC\builder\unix\library\grpc;
public const NAME = 'grpc';
}

View File

@@ -56,7 +56,7 @@ class imap extends MacOSLibraryBase
->exec('chmod +x src/osdep/unix/drivers')
->exec('chmod +x src/osdep/unix/mkauths')
->exec(
"yes | make osx {$ssl_options} EXTRACFLAGS='-Wimplicit-function-declaration -Wno-incompatible-function-pointer-types {$out}'"
"echo y | make osx {$ssl_options} EXTRACFLAGS='-Wno-implicit-function-declaration -Wno-incompatible-function-pointer-types {$out}'"
);
try {
shell()

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class libaom extends MacOSLibraryBase
{
use \SPC\builder\unix\library\libaom;
public const NAME = 'libaom';
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class libde265 extends MacOSLibraryBase
{
use \SPC\builder\unix\library\libde265;
public const NAME = 'libde265';
}

View File

@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\store\FileSystem;
class libheif extends MacOSLibraryBase
{
use \SPC\builder\unix\library\libheif;
public const NAME = 'libheif';
public function patchBeforeBuild(): bool
{
if (!str_contains(file_get_contents($this->source_dir . '/CMakeLists.txt'), 'libbrotlienc')) {
FileSystem::replaceFileStr(
$this->source_dir . '/CMakeLists.txt',
'list(APPEND REQUIRES_PRIVATE "libbrotlidec")',
'list(APPEND REQUIRES_PRIVATE "libbrotlidec")' . "\n" . ' list(APPEND REQUIRES_PRIVATE "libbrotlienc")'
);
return true;
}
return false;
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace SPC\builder\macos\library;
class librdkafka extends MacOSLibraryBase
{
use \SPC\builder\unix\library\librdkafka;
public const NAME = 'librdkafka';
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*
@@ -53,7 +54,7 @@ class openssl extends MacOSLibraryBase
"./Configure no-shared {$extra} " .
'--prefix=/ ' . // use prefix=/
"--libdir={$lib} " .
'--openssldir=/System/Library/OpenSSL ' .
'--openssldir=/etc/ssl ' .
"darwin64-{$this->builder->getOption('arch')}-cc"
)
->exec('make clean')

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*

View File

@@ -12,6 +12,7 @@ use SPC\exception\WrongUsageException;
use SPC\store\Config;
use SPC\store\FileSystem;
use SPC\util\DependencyUtil;
use SPC\util\SPCConfigUtil;
abstract class UnixBuilderBase extends BuilderBase
{
@@ -128,6 +129,7 @@ abstract class UnixBuilderBase extends BuilderBase
foreach ($this->libs as $lib) {
$lib->calcDependency();
}
$this->lib_list = $sorted_libraries;
}
/**
@@ -170,6 +172,32 @@ abstract class UnixBuilderBase extends BuilderBase
}
}
}
// sanity check for embed
if (($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED) {
logger()->info('running embed sanity check');
$sample_file_path = SOURCE_PATH . '/embed-test';
if (!is_dir($sample_file_path)) {
@mkdir($sample_file_path);
}
// copy embed test files
copy(ROOT_DIR . '/src/globals/common-tests/embed.c', $sample_file_path . '/embed.c');
copy(ROOT_DIR . '/src/globals/common-tests/embed.php', $sample_file_path . '/embed.php');
$util = new SPCConfigUtil($this);
$config = $util->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
$lens = "{$config['cflags']} {$config['ldflags']} {$config['libs']}";
if (PHP_OS_FAMILY === 'Linux') {
$lens .= ' -static';
}
[$ret, $out] = shell()->cd($sample_file_path)->execWithResult(getenv('CC') . ' -o embed embed.c ' . $lens);
if ($ret !== 0) {
throw new RuntimeException('embed failed sanity check: build failed. Error message: ' . implode("\n", $out));
}
[$ret, $output] = shell()->cd($sample_file_path)->execWithResult('./embed');
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
throw new RuntimeException('embed failed sanity check: run failed. Error message: ' . implode("\n", $output));
}
}
}
/**

View File

@@ -19,6 +19,7 @@ trait gettext
'--disable-java ' .
'--disable-c+ ' .
$extra .
'--with-included-gettext ' .
'--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' .
'--prefix=' . BUILD_ROOT_PATH
)

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\store\FileSystem;
trait grpc
{
protected function build(): void
{
shell()->cd($this->source_dir)
->exec('EXTRA_DEFINES=GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK EMBED_OPENSSL=false CXXFLAGS="-L' . BUILD_LIB_PATH . ' -I' . BUILD_INCLUDE_PATH . '" make static -j' . $this->builder->concurrency);
copy($this->source_dir . '/libs/opt/libgrpc.a', BUILD_LIB_PATH . '/libgrpc.a');
copy($this->source_dir . '/libs/opt/libboringssl.a', BUILD_LIB_PATH . '/libboringssl.a');
if (!file_exists(BUILD_LIB_PATH . '/libcares.a')) {
copy($this->source_dir . '/libs/opt/libcares.a', BUILD_LIB_PATH . '/libcares.a');
}
FileSystem::copyDir($this->source_dir . '/include/grpc', BUILD_INCLUDE_PATH . '/grpc');
FileSystem::copyDir($this->source_dir . '/include/grpc++', BUILD_INCLUDE_PATH . '/grpc++');
FileSystem::copyDir($this->source_dir . '/include/grpcpp', BUILD_INCLUDE_PATH . '/grpcpp');
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait libaom
{
/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build(): void
{
// CMake needs a clean build directory
FileSystem::resetDir($this->source_dir . '/builddir');
// Start build
shell()->cd($this->source_dir . '/builddir')
->exec(
'cmake ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DAOM_TARGET_CPU=generic ' .
'..'
)
->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install');
$this->patchPkgconfPrefix(['aom.pc']);
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait libde265
{
/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build(): void
{
// CMake needs a clean build directory
FileSystem::resetDir($this->source_dir . '/build');
// Start build
shell()->cd($this->source_dir . '/build')
->exec(
'cmake ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DENABLE_SDL=OFF ' . // Disable SDL, currently not supported
'..'
)
->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install');
$this->patchPkgconfPrefix(['libde265.pc']);
}
}

View File

@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait libheif
{
/**
* @throws RuntimeException
* @throws FileSystemException
*/
protected function build(): void
{
// CMake needs a clean build directory
FileSystem::resetDir($this->source_dir . '/build');
// Start build
shell()->cd($this->source_dir . '/build')
->exec(
'cmake ' .
'--preset=release ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DWITH_EXAMPLES=OFF ' .
'-DWITH_GDK_PIXBUF=OFF ' .
'-DBUILD_TESTING=OFF ' .
'-DWITH_LIBSHARPYUV=ON ' . // optional: libwebp
'-DENABLE_PLUGIN_LOADING=OFF ' .
'..'
)
->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install');
$this->patchPkgconfPrefix(['libheif.pc']);
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
trait librdkafka
{
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
$builddir = BUILD_ROOT_PATH;
$zstd_option = $this->builder->getLib('zstd') ? ("STATIC_LIB_libzstd={$builddir}/lib/libzstd.a ") : '';
shell()->cd($this->source_dir)
->exec(
$zstd_option .
'./configure ' .
'--enable-static --disable-shared --disable-curl --disable-sasl --disable-valgrind --disable-zlib --disable-ssl ' .
($zstd_option == '' ? '--disable-zstd ' : '') .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$builddir}");
$this->patchPkgconfPrefix(['rdkafka.pc', 'rdkafka-static.pc', 'rdkafka++.pc', 'rdkafka++-static.pc']);
// remove dynamic libs
shell()
->exec("rm -rf {$builddir}/lib/*.so.*")
->exec("rm -rf {$builddir}/lib/*.so")
->exec("rm -rf {$builddir}/lib/*.dylib");
}
}

View File

@@ -15,10 +15,18 @@ trait libtiff
*/
protected function build(): void
{
// zlib
$extra_libs = '--enable-zlib --with-zlib-include-dir=' . BUILD_ROOT_PATH . '/include --with-zlib-lib-dir=' . BUILD_ROOT_PATH . '/lib';
// libjpeg
$extra_libs .= ' --enable-jpeg --disable-old-jpeg --disable-jpeg12 --with-jpeg-include-dir=' . BUILD_ROOT_PATH . '/include --with-jpeg-lib-dir=' . BUILD_ROOT_PATH . '/lib';
// We disabled lzma, zstd, webp, libdeflate by default to reduce the size of the binary
$extra_libs .= ' --disable-lzma --disable-zstd --disable-webp --disable-libdeflate';
$shell = shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static --disable-shared ' .
"{$extra_libs} " .
'--disable-cxx ' .
'--prefix='
);

View File

@@ -248,6 +248,7 @@ class WindowsBuilder extends BuilderBase
foreach ($this->libs as $lib) {
$lib->calcDependency();
}
$this->lib_list = $sorted_libraries;
}
/**

View File

@@ -181,7 +181,9 @@ class BuildCliCommand extends BuildCommand
// compile stopwatch :P
$time = round(microtime(true) - START_TIME, 3);
logger()->info('Build complete, used ' . $time . ' s !');
logger()->info('');
logger()->info(' Build complete, used ' . $time . ' s !');
logger()->info('');
// ---------- When using bin/spc-alpine-docker, the build root path is different from the host system ----------
$build_root_path = BUILD_ROOT_PATH;

View File

@@ -30,7 +30,7 @@ class DownloadCommand extends BaseCommand
$this->addArgument('sources', InputArgument::REQUIRED, 'The sources will be compiled, comma separated');
$this->addOption('shallow-clone', null, null, 'Clone shallow');
$this->addOption('with-openssl11', null, null, 'Use openssl 1.1');
$this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format (default 8.2)', '8.2');
$this->addOption('with-php', null, InputOption::VALUE_REQUIRED, 'version in major.minor format (default 8.3)', '8.3');
$this->addOption('clean', null, null, 'Clean old download cache and source before fetch');
$this->addOption('all', 'A', null, 'Fetch all sources that static-php-cli needed');
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace SPC\command;
use SPC\exception\RuntimeException;
use SPC\util\SPCConfigUtil;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
#[AsCommand('spc-config', 'Build dependencies')]
class SPCConfigCommand extends BuildCommand
{
protected bool $no_motd = true;
public function configure(): void
{
$this->addArgument('extensions', InputArgument::OPTIONAL, 'The extensions will be compiled, comma separated');
$this->addOption('with-libs', null, InputOption::VALUE_REQUIRED, 'add additional libraries, comma separated', '');
$this->addOption('with-suggested-libs', 'L', null, 'Build with suggested libs for selected exts and libs');
$this->addOption('with-suggested-exts', 'E', null, 'Build with suggested extensions for selected exts');
$this->addOption('includes', null, null, 'Add additional include path');
$this->addOption('libs', null, null, 'Add additional libs path');
}
/**
* @throws RuntimeException
*/
public function handle(): int
{
// transform string to array
$libraries = array_map('trim', array_filter(explode(',', $this->getOption('with-libs'))));
// transform string to array
$extensions = $this->getArgument('extensions') ? $this->parseExtensionList($this->getArgument('extensions')) : [];
$include_suggest_ext = $this->getOption('with-suggested-exts');
$include_suggest_lib = $this->getOption('with-suggested-libs');
$util = new SPCConfigUtil(null, $this->input);
$config = $util->config($extensions, $libraries, $include_suggest_ext, $include_suggest_lib);
if ($this->getOption('includes')) {
$this->output->writeln($config['cflags']);
} elseif ($this->getOption('libs')) {
$this->output->writeln("{$config['ldflags']} {$config['libs']}");
} else {
$this->output->writeln("{$config['cflags']} {$config['ldflags']} {$config['libs']}");
}
return 0;
}
}

View File

@@ -19,9 +19,9 @@ class SwitchPhpVersionCommand extends BaseCommand
$this->addArgument(
'php-major-version',
InputArgument::REQUIRED,
'PHP major version (supported: 7.4, 8.0, 8.1, 8.2, 8.3)',
'PHP major version (supported: 7.4, 8.0, 8.1, 8.2, 8.3, 8.4)',
null,
fn () => ['7.4', '8.0', '8.1', '8.2', '8.3']
fn () => ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
);
$this->no_motd = true;
@@ -31,7 +31,7 @@ class SwitchPhpVersionCommand extends BaseCommand
public function handle(): int
{
$php_ver = $this->input->getArgument('php-major-version');
if (!in_array($php_ver, ['7.4', '8.0', '8.1', '8.2', '8.3'])) {
if (!in_array($php_ver, ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4'])) {
// match x.y.z
preg_match('/^\d+\.\d+\.\d+$/', $php_ver, $matches);
if (!$matches) {

View File

@@ -57,7 +57,7 @@ class LinuxToolCheckList
$required = match ($distro['dist']) {
'alpine' => self::TOOLS_ALPINE,
'redhat' => self::TOOLS_RHEL,
'redhat', 'centos' => self::TOOLS_RHEL,
'arch' => self::TOOLS_ARCH,
default => self::TOOLS_DEBIAN,
};
@@ -72,6 +72,7 @@ class LinuxToolCheckList
'ubuntu',
'alpine',
'redhat',
'centos',
'Deepin',
'arch',
'debian' => CheckResult::fail(implode(', ', $missing) . ' not installed on your system', 'install-linux-tools', [$distro, $missing]),
@@ -121,13 +122,14 @@ class LinuxToolCheckList
'ubuntu', 'debian', 'Deepin' => 'apt-get install -y',
'alpine' => 'apk add',
'redhat' => 'dnf install -y',
'centos' => 'yum install -y',
'arch' => 'pacman -S --noconfirm',
default => throw new RuntimeException('Current linux distro does not have an auto-install script for musl packages yet.'),
};
$prefix = '';
if (get_current_user() !== 'root') {
if (($user = exec('whoami')) !== 'root') {
$prefix = 'sudo ';
logger()->warning('Current user is not root, using sudo for running command');
logger()->warning('Current user (' . $user . ') is not root, using sudo for running command');
}
try {
$is_debian = in_array($distro['dist'], ['debian', 'ubuntu', 'Deepin']);

View File

@@ -0,0 +1,7 @@
<?php
declare(strict_types=1);
namespace SPC\exception;
class InterruptException extends \Exception {}

View File

@@ -28,7 +28,7 @@ class Downloader
logger()->debug("finding {$name} source from bitbucket tag");
$data = json_decode(self::curlExec(
url: "https://api.bitbucket.org/2.0/repositories/{$source['repo']}/refs/tags",
retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0)
retry: self::getRetryTime()
), true);
$ver = $data['values'][0]['name'];
if (!$ver) {
@@ -38,7 +38,7 @@ class Downloader
$headers = self::curlExec(
url: $url,
method: 'HEAD',
retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0)
retry: self::getRetryTime()
);
preg_match('/^content-disposition:\s+attachment;\s*filename=("?)(?<filename>.+\.tar\.gz)\1/im', $headers, $matches);
if ($matches) {
@@ -66,7 +66,7 @@ class Downloader
$data = json_decode(self::curlExec(
url: "https://api.github.com/repos/{$source['repo']}/{$type}",
hooks: [[CurlHook::class, 'setupGithubToken']],
retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0)
retry: self::getRetryTime()
), true);
if (($source['prefer-stable'] ?? false) === false) {
@@ -85,7 +85,7 @@ class Downloader
url: $url,
method: 'HEAD',
hooks: [[CurlHook::class, 'setupGithubToken']],
retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0)
retry: self::getRetryTime()
);
preg_match('/^content-disposition:\s+attachment;\s*filename=("?)(?<filename>.+\.tar\.gz)\1/im', $headers, $matches);
if ($matches) {
@@ -108,11 +108,11 @@ class Downloader
*/
public static function getLatestGithubRelease(string $name, array $source, bool $match_result = true): array
{
logger()->debug("finding {$name} from github releases assests");
logger()->debug("finding {$name} from github releases assets");
$data = json_decode(self::curlExec(
url: "https://api.github.com/repos/{$source['repo']}/releases",
hooks: [[CurlHook::class, 'setupGithubToken']],
retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0)
retry: self::getRetryTime()
), true);
$url = null;
foreach ($data as $release) {
@@ -149,7 +149,7 @@ class Downloader
public static function getFromFileList(string $name, array $source): array
{
logger()->debug("finding {$name} source from file list");
$page = self::curlExec($source['url'], retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0));
$page = self::curlExec($source['url'], retry: self::getRetryTime());
preg_match_all($source['regex'], $page, $matches);
if (!$matches) {
throw new DownloaderException("Failed to get {$name} version");
@@ -194,7 +194,7 @@ class Downloader
}
};
self::registerCancelEvent($cancel_func);
self::curlDown(url: $url, path: FileSystem::convertPath(DOWNLOAD_PATH . "/{$filename}"), retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0));
self::curlDown(url: $url, path: FileSystem::convertPath(DOWNLOAD_PATH . "/{$filename}"), retry: self::getRetryTime());
self::unregisterCancelEvent();
logger()->debug("Locking {$filename}");
self::lockSource($name, ['source_type' => 'archive', 'filename' => $filename, 'move_path' => $move_path, 'lock_as' => $lock_as]);
@@ -347,7 +347,7 @@ class Downloader
$pkg['url'],
$pkg['rev'],
$pkg['extract'] ?? null,
intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0),
self::getRetryTime(),
SPC_LOCK_PRE_BUILT
);
break;
@@ -451,7 +451,7 @@ class Downloader
$source['url'],
$source['rev'],
$source['path'] ?? null,
intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0),
self::getRetryTime(),
$lock_as
);
break;
@@ -567,7 +567,7 @@ class Downloader
}
if ($retry > 0) {
logger()->notice('Retrying curl download ...');
self::curlDown($url, $path, $method, $used_headers, retry: intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0));
self::curlDown($url, $path, $method, $used_headers, retry: $retry - 1);
return;
}
throw $e;
@@ -601,4 +601,9 @@ class Downloader
pcntl_signal(2, SIG_IGN);
}
}
private static function getRetryTime(): int
{
return intval(getenv('SPC_RETRY_TIME') ? getenv('SPC_RETRY_TIME') : 0);
}
}

View File

@@ -367,6 +367,9 @@ class FileSystem
}
}
}
if (is_link($dir)) {
return unlink($dir);
}
return rmdir($dir);
}

View File

@@ -6,6 +6,7 @@ namespace SPC\store;
use SPC\builder\BuilderBase;
use SPC\builder\linux\LinuxBuilder;
use SPC\builder\linux\SystemUtil;
use SPC\builder\unix\UnixBuilderBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
@@ -25,6 +26,9 @@ class SourcePatcher
FileSystem::addSourceExtractHook('pdo_sqlsrv', [SourcePatcher::class, 'patchSQLSRVWin32']);
FileSystem::addSourceExtractHook('yaml', [SourcePatcher::class, 'patchYamlWin32']);
FileSystem::addSourceExtractHook('libyaml', [SourcePatcher::class, 'patchLibYaml']);
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchImapLicense']);
FileSystem::addSourceExtractHook('ext-imagick', [SourcePatcher::class, 'patchImagickWith84']);
FileSystem::addSourceExtractHook('libaom', [SourcePatcher::class, 'patchLibaomForAlpine']);
}
/**
@@ -370,6 +374,36 @@ class SourcePatcher
return true;
}
/**
* Patch imap license file for PHP < 8.4
*/
public static function patchImapLicense(): bool
{
if (!file_exists(SOURCE_PATH . '/php-src/ext/imap/LICENSE') && is_dir(SOURCE_PATH . '/php-src/ext/imap')) {
file_put_contents(SOURCE_PATH . '/php-src/ext/imap/LICENSE', file_get_contents(ROOT_DIR . '/src/globals/extra/Apache_LICENSE'));
return true;
}
return false;
}
/**
* Patch imagick for PHP 8.4
*/
public static function patchImagickWith84(): bool
{
SourcePatcher::patchFile('imagick_php84.patch', SOURCE_PATH . '/php-src/ext/imagick');
return true;
}
public static function patchLibaomForAlpine(): bool
{
if (PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist()) {
SourcePatcher::patchFile('libaom_posix_implict.patch', SOURCE_PATH . '/libaom');
return true;
}
return false;
}
/**
* Patch cli SAPI Makefile for Windows.
*
@@ -416,7 +450,7 @@ class SourcePatcher
return true;
}
if ($ver_id < 80200) {
self::patchFile('spc_fix_libxml2_12_php81.patch', SOURCE_PATH . '/php-src');
// self::patchFile('spc_fix_libxml2_12_php81.patch', SOURCE_PATH . '/php-src');
self::patchFile('spc_fix_alpine_build_php80.patch', SOURCE_PATH . '/php-src');
return true;
}

View File

@@ -19,12 +19,8 @@ class PhpSource extends CustomSourceBase
*/
public function fetch(bool $force = false, ?array $config = null, int $lock_as = SPC_LOCK_SOURCE): void
{
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.1';
if ($major === '8.4') {
Downloader::downloadSource('php-src', ['type' => 'url', 'url' => 'https://downloads.php.net/~saki/php-8.4.0RC1.tar.xz'], $force);
} else {
Downloader::downloadSource('php-src', self::getLatestPHPInfo($major), $force);
}
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.3';
Downloader::downloadSource('php-src', self::getLatestPHPInfo($major), $force);
}
/**

View File

@@ -41,7 +41,7 @@ class GlobalEnvManager
self::putenv('PKG_CONFIG=' . BUILD_BIN_PATH . '/pkg-config');
self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig');
if ($builder instanceof BuilderBase) {
self::putenv('SPC_PHP_DEFAULT_OPTIMIZE_CFLAGS=' . ($builder->getOption('no-strip') ? '-g -O0' : '-g -Os'));
self::putenv('SPC_PHP_DEFAULT_OPTIMIZE_CFLAGS=' . ($builder->getOption('no-strip') ? '-g -O0' : '-g -fstack-protector-strong -fpic -fpie -Os -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'));
}
}

View File

@@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
namespace SPC\util;
use SPC\builder\BuilderBase;
use SPC\builder\BuilderProvider;
use SPC\builder\macos\MacOSBuilder;
use SPC\store\Config;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\InputInterface;
class SPCConfigUtil
{
public function __construct(private ?BuilderBase $builder = null, ?InputInterface $input = null)
{
if ($builder === null) {
$this->builder = BuilderProvider::makeBuilderByInput($input ?? new ArgvInput());
}
}
public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false): array
{
[$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions, $libraries, $include_suggest_ext, $include_suggest_lib);
ob_start();
$this->builder->proveLibs($libraries);
$this->builder->proveExts($extensions);
ob_get_clean();
$ldflags = $this->getLdflagsString();
$libs = $this->getLibsString($libraries);
$cflags = $this->getIncludesString();
// embed
$libs = '-lphp -lc ' . $libs;
$extra_env = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS');
if (is_string($extra_env)) {
$libs .= ' ' . $extra_env;
}
// c++
if ($this->builder->hasCpp()) {
$libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++';
}
return [
'cflags' => $cflags,
'ldflags' => $ldflags,
'libs' => $libs,
];
}
private function getIncludesString(): string
{
$base = BUILD_INCLUDE_PATH;
$php_embed_includes = [
"-I{$base}",
"-I{$base}/php",
"-I{$base}/php/main",
"-I{$base}/php/TSRM",
"-I{$base}/php/Zend",
"-I{$base}/php/ext",
];
return implode(' ', $php_embed_includes);
}
private function getLdflagsString(): string
{
return '-L' . BUILD_LIB_PATH;
}
private function getLibsString(array $libraries): string
{
$short_name = [];
foreach (array_reverse($libraries) as $library) {
$libs = Config::getLib($library, 'static-libs', []);
foreach ($libs as $lib) {
$short_name[] = $this->getShortLibName($lib);
}
if (PHP_OS_FAMILY !== 'Darwin') {
continue;
}
foreach (Config::getLib($library, 'frameworks', []) as $fw) {
$ks = '-framework ' . $fw;
if (!in_array($ks, $short_name)) {
$short_name[] = $ks;
}
}
}
// patch: imagick (imagemagick wrapper) for linux needs -lgomp
if (in_array('imagemagick', $libraries) && PHP_OS_FAMILY === 'Linux') {
$short_name[] = '-lgomp';
}
return implode(' ', $short_name);
}
private function getShortLibName(string $lib): string
{
if (!str_starts_with($lib, 'lib') || !str_ends_with($lib, '.a')) {
return BUILD_LIB_PATH . '/' . $lib;
}
// get short name
return '-l' . substr($lib, 3, -2);
}
}

View File

@@ -62,6 +62,9 @@ class UnixShell
logger()->debug(ConsoleColor::blue('[EXEC] ') . ConsoleColor::gray($cmd));
}
logger()->debug('Executed at: ' . debug_backtrace()[0]['file'] . ':' . debug_backtrace()[0]['line']);
if ($this->cd !== null) {
$cmd = 'cd ' . escapeshellarg($this->cd) . ' && ' . $cmd;
}
exec($cmd, $out, $code);
return [$code, $out];
}

View File

@@ -0,0 +1,17 @@
#include <sapi/embed/php_embed.h>
int main(int argc,char **argv){
PHP_EMBED_START_BLOCK(argc,argv)
zend_file_handle file_handle;
zend_stream_init_filename(&file_handle,"embed.php");
if(php_execute_script(&file_handle) == FAILURE){
php_printf("Failed to execute PHP script.\n");
}
PHP_EMBED_END_BLOCK()
return 0;
}

View File

@@ -0,0 +1,4 @@
<?php
declare(strict_types=1);
echo 'hello' . PHP_EOL;

View File

@@ -0,0 +1,5 @@
<?php
declare(strict_types=1);
assert(function_exists('ast\parse_code'));

View File

@@ -5,7 +5,6 @@ declare(strict_types=1);
assert(function_exists('gettext'));
assert(function_exists('bindtextdomain'));
assert(function_exists('textdomain'));
assert(function_exists('bind_textdomain_codeset'));
if (!is_dir('locale/en_US/LC_MESSAGES/')) {
mkdir('locale/en_US/LC_MESSAGES/', 0755, true);
@@ -19,7 +18,6 @@ setlocale(LC_ALL, 'en_US');
$domain = 'test';
bindtextdomain($domain, 'locale/');
bind_textdomain_codeset($domain, 'UTF-8');
textdomain($domain);
assert(gettext(json_decode('"\u793a\u4f8b"', true)) === 'Example');

View File

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

View File

@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
assert(class_exists('Imagick'));
assert(Imagick::queryFormats('AVIF') !== []);
assert(Imagick::queryFormats('HEIF') !== []);
assert(Imagick::queryFormats('HEIC') !== []);
assert(Imagick::queryFormats('WEBP') !== []);
assert(Imagick::queryFormats('JPEG') !== []);
assert(Imagick::queryFormats('PNG') !== []);
assert(Imagick::queryFormats('TIFF') !== []);

View File

@@ -4,3 +4,4 @@ declare(strict_types=1);
assert(function_exists('openssl_digest'));
assert(openssl_digest('123456', 'md5') === 'e10adc3949ba59abbe56e057f20f883e');
assert(file_get_contents('https://example.com/') !== false);

View File

@@ -6,7 +6,6 @@ assert(function_exists('swoole_cpu_num'));
assert(function_exists('swoole_string'));
assert(class_exists('Swoole\Coroutine'));
assert(class_exists('Swoole\Coroutine\Http2\Client'));
assert(class_exists('Swoole\Coroutine\Redis'));
assert(class_exists('Swoole\Coroutine\WaitGroup'));
assert(class_exists('Swoole\Http2\Request'));
assert(constant('SWOOLE_VERSION'));

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
use Psr\Log\LoggerInterface;
use SPC\builder\BuilderBase;
use SPC\builder\BuilderProvider;
use SPC\exception\InterruptException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\UnixShell;
@@ -125,6 +126,11 @@ function patch_point(): string
return BuilderProvider::getBuilder()->getPatchPoint();
}
function patch_point_interrupt(int $retcode, string $msg = ''): InterruptException
{
return new InterruptException(message: $msg, code: $retcode);
}
// ------- function f_* part -------
// f_ means standard function wrapper

View File

@@ -0,0 +1,40 @@
From 65e27f2bc02e7e8f1bf64e26e359e42a1331fca1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= <mvorisek@mvorisek.cz>
Date: Wed, 25 Sep 2024 10:56:28 +0200
Subject: [PATCH] Fix removed "php_strtolower" for PHP 8.4
---
imagick.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/imagick.c b/imagick.c
index 1b765389..ebab7ae7 100644
--- a/imagick.c
+++ b/imagick.c
@@ -610,7 +610,7 @@ static zval *php_imagick_read_property(zend_object *object, zend_string *member,
if (format) {
retval = rv;
ZVAL_STRING(retval, format);
- php_strtolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
+ zend_str_tolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
IMAGICK_FREE_MAGICK_MEMORY(format);
} else {
retval = rv;
@@ -683,7 +683,7 @@ static zval *php_imagick_read_property(zval *object, zval *member, int type, voi
if (format) {
retval = rv;
ZVAL_STRING(retval, format);
- php_strtolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
+ zend_str_tolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
IMAGICK_FREE_MAGICK_MEMORY(format);
} else {
retval = rv;
@@ -766,7 +766,7 @@ static zval *php_imagick_read_property(zval *object, zval *member, int type, con
if (format) {
ZVAL_STRING(retval, format, 1);
- php_strtolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
+ zend_str_tolower(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
IMAGICK_FREE_MAGICK_MEMORY(format);
} else {
ZVAL_STRING(retval, "", 1);

View File

@@ -0,0 +1,13 @@
https://bugs.gentoo.org/869419
POSIX_C_SOURCE is needed for ftello.
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -269,6 +269,7 @@ add_library(aom_rtcd OBJECT ${AOM_RTCD_SOURCES})
add_dependencies(aom_rtcd aom_version)
if(ENABLE_EXAMPLES)
+ add_definitions(-D_POSIX_C_SOURCE=200112L)
add_library(aom_encoder_stats OBJECT ${AOM_ENCODER_STATS_SOURCES})
set(AOM_LIB_TARGETS ${AOM_LIB_TARGETS} aom_encoder_stats)
endif()

View File

@@ -13,18 +13,15 @@ declare(strict_types=1);
// test php version
$test_php_version = [
'8.0',
'8.1',
'8.2',
'8.3',
'8.4',
];
// test os (macos-13, macos-14, ubuntu-latest, windows-latest are available)
$test_os = [
'macos-14',
'ubuntu-latest',
'macos-13',
'windows-latest',
'ubuntu-latest',
];
// whether enable thread safe
@@ -36,12 +33,12 @@ $no_strip = false;
$upx = false;
// prefer downloading pre-built packages to speed up the build process
$prefer_pre_built = true;
$prefer_pre_built = false;
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
$extensions = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => '',
'Windows' => 'amqp,apcu,bcmath,bz2,calendar,ctype,curl,dba,dom,ds,exif,ffi,fileinfo,filter,ftp,gd,iconv,igbinary,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,rar,redis,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,swow,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yac,yaml,zip,zlib',
'Linux', 'Darwin' => 'imagick',
'Windows' => 'ast',
};
// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`).
@@ -54,7 +51,7 @@ $with_libs = match (PHP_OS_FAMILY) {
// You can use `common`, `bulk`, `minimal` or `none`.
// note: combination is only available for *nix platform. Windows must use `none` combination
$base_combination = match (PHP_OS_FAMILY) {
'Linux', 'Darwin' => 'bulk',
'Linux', 'Darwin' => 'minimal',
'Windows' => 'none',
};
@@ -116,14 +113,13 @@ if ($argv[1] === 'download_cmd') {
}
// generate build command
if ($argv[1] === 'build_cmd') {
if ($argv[1] === 'build_cmd' || $argv[1] === 'build_embed_cmd') {
$build_cmd = 'build ';
$build_cmd .= quote2($final_extensions) . ' ';
$build_cmd .= $zts ? '--enable-zts ' : '';
$build_cmd .= $no_strip ? '--no-strip ' : '';
$build_cmd .= $upx ? '--with-upx-pack ' : '';
$build_cmd .= $final_libs === '' ? '' : ('--with-libs=' . quote2($final_libs) . ' ');
$build_cmd .= '--build-cli --build-micro ';
$build_cmd .= str_starts_with($argv[2], 'windows-') ? '' : '--build-fpm ';
$build_cmd .= '--debug ';
}
@@ -141,6 +137,7 @@ echo match ($argv[1]) {
'prefer_pre_built' => $prefer_pre_built ? '--prefer-pre-built' : '',
'download_cmd' => $down_cmd,
'build_cmd' => $build_cmd,
'build_embed_cmd' => $build_cmd,
default => '',
};
@@ -152,9 +149,16 @@ if ($argv[1] === 'download_cmd') {
}
} elseif ($argv[1] === 'build_cmd') {
if (str_starts_with($argv[2], 'windows-')) {
passthru('powershell.exe -file .\bin\spc.ps1 ' . $build_cmd, $retcode);
passthru('powershell.exe -file .\bin\spc.ps1 ' . $build_cmd . ' --build-cli --build-micro', $retcode);
} else {
passthru('./bin/spc ' . $build_cmd, $retcode);
passthru('./bin/spc ' . $build_cmd . ' --build-cli --build-micro', $retcode);
}
} elseif ($argv[1] === 'build_embed_cmd') {
if (str_starts_with($argv[2], 'windows-')) {
// windows does not accept embed SAPI
passthru('powershell.exe -file .\bin\spc.ps1 ' . $build_cmd . ' --build-cli', $retcode);
} else {
passthru('./bin/spc ' . $build_cmd . ' --build-embed', $retcode);
}
}

View File

@@ -246,6 +246,7 @@ class BuilderTest extends TestCase
public function testEmitPatchPointNotExists()
{
$this->expectOutputRegex('/failed to run/');
$this->expectException(RuntimeException::class);
$this->builder->setOption('with-added-patch', ['/tmp/patch-point.not_exsssists.php']);
$this->builder->emitPatchPoint('not-exists');
}