Compare commits

..

1 Commits

Author SHA1 Message Date
crazywhalecc
ee3be6f374 add pocketmine support 2023-12-21 21:57:03 +08:00
207 changed files with 2350 additions and 9919 deletions

2
.github/FUNDING.yml vendored
View File

@@ -10,6 +10,4 @@ liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
# noinspection YAMLSchemaValidation
buy_me_a_coffee: crazywhalecc
custom: 'https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md' # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] custom: 'https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md' # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -45,30 +45,14 @@ jobs:
name: build ${{ inputs.version }} on ${{ inputs.operating-system }} name: build ${{ inputs.version }} on ${{ inputs.operating-system }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
# 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 # Cache downloaded source
- id: cache-download - id: cache-download
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: downloads path: downloads
key: php-${{ env.INPUT_HASH }} key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
# With or without debug # With or without debug
- if: inputs.debug == true - if: inputs.debug == true
@@ -91,31 +75,31 @@ jobs:
# Upload cli executable # Upload cli executable
- if: ${{ inputs.build-cli == true }} - if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: php-${{ inputs.version }}-linux-${{ inputs.operating-system }} name: php-${{ inputs.version }}-linux-${{ inputs.operating-system }}
path: buildroot/bin/php path: buildroot/bin/php
# Upload micro self-extracted executable # Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }} - if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: micro-${{ inputs.version }}-linux-${{ inputs.operating-system }} name: micro-${{ inputs.version }}-linux-${{ inputs.operating-system }}
path: buildroot/bin/micro.sfx path: buildroot/bin/micro.sfx
# Upload fpm executable # Upload fpm executable
- if: ${{ inputs.build-fpm == true }} - if: ${{ inputs.build-fpm == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: php-fpm-${{ inputs.version }}-linux-${{ inputs.operating-system }} name: php-fpm-${{ inputs.version }}-linux-${{ inputs.operating-system }}
path: buildroot/bin/php-fpm path: buildroot/bin/php-fpm
# Upload extensions metadata # Upload extensions metadata
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: license-files name: license-files
path: buildroot/license/ path: buildroot/license/
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: build-meta name: build-meta
path: | path: |

View File

@@ -39,11 +39,11 @@ jobs:
name: build ${{ inputs.version }} on Linux x86_64 name: build ${{ inputs.version }} on Linux x86_64
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
# Cache composer dependencies # Cache composer dependencies
- id: cache-composer-deps - id: cache-composer-deps
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: vendor path: vendor
key: composer-dependencies key: composer-dependencies
@@ -52,17 +52,12 @@ jobs:
- if: steps.cache-composer-deps.outputs.cache-hit != 'true' - if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev --classmap-authoritative 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 # Cache downloaded source
- id: cache-download - id: cache-download
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: downloads path: downloads
key: php-${{ env.INPUT_HASH }} key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
# With or without debug # With or without debug
- if: inputs.debug == true - if: inputs.debug == true
@@ -85,31 +80,31 @@ jobs:
# Upload cli executable # Upload cli executable
- if: ${{ inputs.build-cli == true }} - if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }} name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php path: buildroot/bin/php
# Upload micro self-extracted executable # Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }} - if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }} name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/micro.sfx path: buildroot/bin/micro.sfx
# Upload fpm executable # Upload fpm executable
- if: ${{ inputs.build-fpm == true }} - if: ${{ inputs.build-fpm == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }} name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php-fpm path: buildroot/bin/php-fpm
# Upload extensions metadata # Upload extensions metadata
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: license-files name: license-files
path: buildroot/license/ path: buildroot/license/
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: build-meta name: build-meta
path: | path: |

View File

@@ -1,132 +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
debug:
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
# 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 }}
# 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

@@ -37,26 +37,18 @@ env:
jobs: jobs:
build: build:
name: build ${{ inputs.version }} on macOS x86_64 name: build ${{ inputs.version }} on macOS x86_64
runs-on: macos-13 runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
# Install macOS missing packages and mark os suffix # Install macOS missing packages and mark os suffix
- run: | - run: |
brew install automake gzip brew install automake gzip
echo "SPC_BUILD_OS=macos" >> $GITHUB_ENV 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 # Cache composer dependencies
- id: cache-composer-deps - id: cache-composer-deps
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: vendor path: vendor
key: composer-dependencies key: composer-dependencies
@@ -65,17 +57,12 @@ jobs:
- if: steps.cache-composer-deps.outputs.cache-hit != 'true' - if: steps.cache-composer-deps.outputs.cache-hit != 'true'
run: composer update --no-dev --classmap-authoritative 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 # Cache downloaded source
- id: cache-download - id: cache-download
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: downloads path: downloads
key: php-${{ env.INPUT_HASH }} key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
# With or without debug # With or without debug
- if: inputs.debug == true - if: inputs.debug == true
@@ -98,31 +85,31 @@ jobs:
# Upload cli executable # Upload cli executable
- if: ${{ inputs.build-cli == true }} - if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }} name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php path: buildroot/bin/php
# Upload micro self-extracted executable # Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }} - if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }} name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/micro.sfx path: buildroot/bin/micro.sfx
# Upload fpm executable # Upload fpm executable
- if: ${{ inputs.build-fpm == true }} - if: ${{ inputs.build-fpm == true }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }} name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
path: buildroot/bin/php-fpm path: buildroot/bin/php-fpm
# Upload extensions metadata # Upload extensions metadata
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: license-files name: license-files
path: buildroot/license/ path: buildroot/license/
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v3
with: with:
name: build-meta name: build-meta
path: | path: |

View File

@@ -1,108 +0,0 @@
name: CI on x86_64 Windows
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
extensions:
description: extensions to compile (comma separated)
required: true
type: string
debug:
type: boolean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
build:
name: build ${{ inputs.version }} on Windows x86_64
runs-on: windows-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
shell: bash
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" >> $env:GITHUB_ENV
# With target select: cli, micro or both
- if: ${{ inputs.build-cli == true }}
run: echo "SPC_BUILD_CLI=--build-cli" >> $env:GITHUB_ENV
- if: ${{ inputs.build-micro == true }}
run: echo "SPC_BUILD_MICRO=--build-micro" >> $env:GITHUB_ENV
- run: ./bin/spc doctor
# 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 }}
# 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 }}
path: buildroot/bin/php.exe
# Upload micro self-extracted executable
- if: ${{ inputs.build-micro == true }}
uses: actions/upload-artifact@v4
with:
name: micro-${{ inputs.version }}
path: buildroot/bin/micro.sfx
# 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

40
.github/workflows/download-cache.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: archive download sources weekly
on:
workflow_dispatch:
schedule:
- cron: "* 14 * * 5"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
download:
name: cache download sources
runs-on: ubuntu-latest
strategy:
matrix:
php-version: [ "8.0", "8.1", "8.2", "8.3" ]
steps:
- uses: actions/checkout@v3
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v3
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
# 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=${{ matrix.php-version }} --all --debug
# Upload downloaded files
- uses: actions/upload-artifact@v3
with:
name: download-files-${{ matrix.php-version }}
path: downloads/

View File

@@ -1,8 +1,6 @@
name: Build SPC Binary name: Upload SPC Binary (Release)
on: on:
push:
branches: [ "main" ]
release: release:
types: types:
- published - published
@@ -10,119 +8,40 @@ on:
jobs: jobs:
build-release-artifacts: build-release-artifacts:
name: "Build SPC Binary" name: "Upload SPC Binary (Release)"
runs-on: macos-14 runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
php-version:
- "8.2"
micro-version:
- "8.2.18"
operating-system: operating-system:
- "linux-x86_64" - "linux-x86_64"
- "macos-x86_64" - "macos-x86_64"
- "linux-aarch64" - "linux-aarch64"
- "macos-aarch64" - "macos-aarch64"
- "windows-x64"
steps: steps:
- name: "Checkout" - name: "Checkout"
uses: "actions/checkout@v4" uses: "actions/checkout@v4"
- if: inputs.debug == true - name: Reuse static-php-cli-hosted artifacts
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV uses: dawidd6/action-download-artifact@v2
- name: "Install PHP for official runners"
uses: "shivammathur/setup-php@v2"
with: with:
coverage: none repo: static-php/static-php-cli-hosted
tools: composer:v2 branch: master
php-version: "${{ matrix.php-version }}" workflow: build-spc-release.yml
ini-values: memory_limit=-1 name: "spc-${{ matrix.operating-system }}"
- name: "Get Composer Cache Directory"
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: "Cache Composer dependencies"
uses: "actions/cache@v4"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-${{ matrix.php-version }}-locked-composer-${{ hashFiles('**/composer.lock') }}"
restore-keys: |
php-${{ matrix.php-version }}-locked-composer
- name: "Install Locked Dependencies"
run: "composer install --no-interaction --no-progress"
- name: "Build PHAR File"
run: "composer build:phar"
- name: "Download minimal combination"
run: |
if [ "${{ matrix.operating-system }}" = "windows-x64" ]; then
curl https://dl.static-php.dev/static-php-cli/windows/spc-min/php-${{ matrix.micro-version }}-micro-win.zip -o tmp.zip
unzip tmp.zip
else
curl https://dl.static-php.dev/static-php-cli/minimal/php-${{ matrix.micro-version }}-micro-${{ matrix.operating-system }}.tar.gz -o tmp.tgz
tar -zxvf tmp.tgz
fi
- name: "Generate Executable"
run: |
bin/spc micro:combine spc.phar -M micro.sfx -O spc -I "memory_limit=2G"
if [ "${{ matrix.operating-system }}" = "windows-x64" ]; then
mv spc spc.exe
else
chmod +x spc
fi
if [ "${{ matrix.operating-system }}" = "macos-aarch64" ] || [ "${{ matrix.operating-system }}" = "macos-x86_64" ]; then
sudo xattr -cr ./spc
fi
- name: "Archive Executable" - name: "Archive Executable"
run: | run: |
if [ "${{ matrix.operating-system }}" != "windows-x64" ]; then tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
if [ "${{ matrix.operating-system }}" == "macos-aarch64" ]; then
./spc dev:extensions
fi
else
echo "filename=spc-${{ matrix.operating-system }}.exe" >> $GITHUB_ENV
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
fi
- name: "Copy file"
run: |
if [ "${{ matrix.operating-system }}" != "windows-x64" ]; then
mkdir dist/ && cp ${{ env.filename }} dist/ && cp spc dist/spc-$OS
else
mkdir dist/ && cp spc.exe dist/${{ env.filename }}
echo "SUFFIX=.exe" >> $GITHUB_ENV
fi
- name: upload binaries to release - name: upload binaries to release
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v1
if: ${{startsWith(github.ref, 'refs/tags/') }} if: ${{startsWith(github.ref, 'refs/tags/') }}
with: with:
files: dist/${{ env.filename }} files: ${{ env.filename }}
- name: "Deploy to Self-Hosted Server"
if: github.repository == 'crazywhalecc/static-php-cli'
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.DEPLOY_SERVER_SECRET_KEY }}
ARGS: "-rltgoDzvO"
SOURCE: "dist/"
REMOTE_HOST: ${{ secrets.DEPLOY_SERVER_HOST }}
REMOTE_PORT: ${{ secrets.DEPLOY_SERVER_PORT }}
REMOTE_USER: ${{ secrets.DEPLOY_SERVER_USER }}
TARGET: ${{ secrets.DEPLOY_SERVER_TARGET_SPC_NIGHTLY }}
- name: "Upload Artifact" - name: "Upload Artifact"
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v3
with: with:
path: spc${{ env.SUFFIX }} path: spc
name: spc-${{ matrix.operating-system }}${{ env.SUFFIX }} name: spc-${{ matrix.operating-system }}

View File

@@ -2,10 +2,7 @@ name: Tests
on: on:
push: push:
branches: branches: [ "main" ]
- main
paths:
- 'src/globals/test-extensions.php'
pull_request: pull_request:
branches: [ "main" ] branches: [ "main" ]
@@ -48,7 +45,7 @@ jobs:
- name: "Cache Composer packages" - name: "Cache Composer packages"
id: composer-cache id: composer-cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: vendor path: vendor
key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }}
@@ -86,7 +83,7 @@ jobs:
- name: "Cache Composer packages" - name: "Cache Composer packages"
id: composer-cache id: composer-cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: vendor path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
@@ -113,9 +110,7 @@ jobs:
- "8.3" - "8.3"
os: os:
- ubuntu-latest - ubuntu-latest
- macos-13 - macos-latest
- windows-latest
- macos-14
fail-fast: false fail-fast: false
steps: steps:
- name: "Checkout" - name: "Checkout"
@@ -129,61 +124,23 @@ jobs:
extensions: curl, openssl, mbstring extensions: curl, openssl, mbstring
ini-values: memory_limit=-1 ini-values: memory_limit=-1
- name: "Use test token if exists" - name: "Cache Composer packages"
if: matrix.os != 'windows-latest'
run: |
if [ "${{ secrets.TEST_GH_TOKEN }}" != "" ]; then
echo "GITHUB_TOKEN=${{ secrets.TEST_GH_TOKEN }}" >> $GITHUB_ENV
fi
- name: "Cache composer packages"
id: composer-cache id: composer-cache
uses: actions/cache@v4 uses: actions/cache@v3
with: with:
path: vendor path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: | restore-keys: |
${{ runner.os }}-php- ${{ runner.os }}-php-
# Cache downloaded source
- id: cache-download
uses: actions/cache@v4
with:
path: downloads
key: php-${{ matrix.php }}-dependencies
- name: "Install Dependencies" - name: "Install Dependencies"
run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: "Run Build Tests (doctor)" - name: "Run Build Tests (doctor)"
run: bin/spc doctor --auto-fix run: bin/spc doctor --auto-fix
- name: "Prepare UPX for Windows"
if: matrix.os == 'windows-latest'
run: |
bin/spc install-pkg upx
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV
- name: "Prepare UPX for Linux"
if: matrix.os == 'ubunut-latest'
run: |
bin/spc install-pkg upx
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV
- name: "Run Build Tests (download)" - name: "Run Build Tests (download)"
uses: nick-fields/retry@v3 run: bin/spc download --for-extensions="$(php src/globals/test-extensions.php)" --with-php=${{ matrix.php }} --debug
with:
timeout_minutes: 10
max_attempts: 3
retry_on: error
command: |
bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --for-libs="$(php src/globals/test-extensions.php libs)" --with-php=${{ matrix.php }} --ignore-cache-sources=php-src,libcares --debug --retry=3
- name: "Run Build Tests (build, *nix)" - name: "Run Build Tests (build)"
if: matrix.os != 'windows-latest' run: bin/spc build "$(php src/globals/test-extensions.php)" --build-cli --build-micro --build-fpm --debug
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug
- name: "Run Build Tests (build, windows)"
if: matrix.os == 'windows-latest'
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $env:UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug

View File

@@ -1,68 +0,0 @@
name: Update Docs Config
on:
push:
branches:
- main
paths:
- 'config/**.json'
jobs:
update-docs-config:
name: "Update Docs Config"
runs-on: ubuntu-latest
if: github.repository == 'crazywhalecc/static-php-cli'
steps:
- name: "Checkout static-php-cli"
uses: actions/checkout@v4
- name: "Checkout static-php-cli-docs"
uses: actions/checkout@v4
with:
repository: static-php/static-php-cli-docs
ref: master
token: ${{ secrets.DOCS_REPO_TOKEN }}
path: static-php-cli-docs
- name: "Set up Git"
run: |
git config --global user.email "actions@github.com"
git config --global user.name "GitHub Actions"
- name: "Copy Config Files"
run: cp -r config/* static-php-cli-docs/docs/.vitepress/config/
- name: "Install PHP for official runners"
uses: "shivammathur/setup-php@v2"
with:
coverage: none
tools: composer:v2
php-version: 8.2
ini-values: memory_limit=-1
- name: "Get Composer Cache Directory"
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: "Cache Composer dependencies"
uses: "actions/cache@v4"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-8.2-locked-composer-${{ hashFiles('**/composer.lock') }}"
restore-keys: |
php-8.2-locked-composer
- name: "Install Locked Dependencies"
run: "composer install --no-interaction --no-progress"
- name: "Generate Extension Support List"
run: |
bin/spc dev:gen-ext-docs > static-php-cli-docs/docs/extensions.md
- name: "Commit and Push Changes"
run: |
cd static-php-cli-docs
git add -A
git commit -m "Sync config files from main"
git push origin master

10
.gitignore vendored
View File

@@ -16,21 +16,15 @@ docker/source/
# default source build root directory # default source build root directory
/buildroot/ /buildroot/
# default package root directory
/pkgroot/
# tools cache files # tools cache files
.php-cs-fixer.cache .php-cs-fixer.cache
.phpunit.result.cache .phpunit.result.cache
# exclude self-runtime # exclude self-runtime
/bin/* /bin/*
!/bin/spc* !/bin/spc
!/bin/setup-runtime* !/bin/setup-runtime
!/bin/spc-alpine-docker !/bin/spc-alpine-docker
# exclude windows build tools
/php-sdk-binary-tools/
# default test directory # default test directory
/tests/var/ /tests/var/

View File

@@ -63,7 +63,6 @@ return (new PhpCsFixer\Config())
'phpdoc_summary' => false, 'phpdoc_summary' => false,
'php_unit_test_class_requires_covers' => false, 'php_unit_test_class_requires_covers' => false,
'phpdoc_var_without_name' => false, 'phpdoc_var_without_name' => false,
'fully_qualified_strict_types' => false,
]) ])
->setFinder( ->setFinder(
PhpCsFixer\Finder::create()->in([__DIR__ . '/src', __DIR__ . '/tests/SPC']) PhpCsFixer\Finder::create()->in([__DIR__ . '/src', __DIR__ . '/tests/SPC'])

View File

@@ -1,96 +1,60 @@
# static-php-cli # static-php-cli
[![English readme](https://img.shields.io/badge/README-English%20%F0%9F%87%AC%F0%9F%87%A7-moccasin?style=flat-square)](README.md) Build single static PHP binary, with PHP project together, with popular extensions included.
[![Chinese readme](https://img.shields.io/badge/README-%E4%B8%AD%E6%96%87%20%F0%9F%87%A8%F0%9F%87%B3-moccasin?style=flat-square)](README-zh.md)
[![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases)
[![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
[![Extensions](https://img.shields.io/badge/Extension%20Counter-75+-yellow.svg?style=flat-square)](https://static-php.dev/zh/guide/extensions.html)
**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。 🌐 **[中文](README-zh.md)** | **[English](README.md)**
目前 static-php-cli 支持 `cli``fpm``embed``micro` SAPI 编译纯静态的 PHP Binary 二进制文件,带有各种扩展,让 PHP-cli 应用变得更便携cli SAPI
**static-php-cli**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。 <img width="600" alt="截屏2023-05-02 15 53 13" src="https://user-images.githubusercontent.com/20330940/235610282-23e58d68-bd35-4092-8465-171cff2d5ba8.png">
## 特性 同时可以使用 micro 二进制文件,将 PHP 源码和 PHP 二进制构建为一个文件分发micro SAPI
static-php-cli简称 `spc`)有许多特性: <img width="600" alt="截屏2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
- :handbag: 构建独立的单文件 PHP 解释器,无需任何依赖 > 该 SAPI 源自 [dixyes/phpmicro](https://github.com/dixyes/phpmicro) 的 [Fork 仓库](https://github.com/static-php/phpmicro)。
- :hamburger: 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自执行二进制(将 PHP 代码和 PHP 解释器打包为一个文件)
- :pill: 提供一键检查和修复编译环境的 Doctor 模块
- :zap: 支持多个系统:`Linux``macOS``FreeBSD``Windows`
- :wrench: 高度自定义的代码 patch 功能
- :books: 自带编译依赖管理
- 📦 提供由自身编译的独立 `spc` 二进制(使用 spc 和 [box](https://github.com/box-project/box) 构建)
- :fire: 支持大量 [扩展](https://static-php.dev/zh/guide/extensions.html)
- :floppy_disk: 整合 UPX 工具(减小二进制文件体积)
**静态 php-cli:** [![Version](https://img.shields.io/badge/Version-2.0--rc8-pink.svg?style=flat-square)]()
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)]()
[![](https://img.shields.io/github/actions/workflow/status/static-php/static-php-cli-hosted/build-php-common.yml?branch=refactor&label=Build%20Common%20Extensions&style=flat-square)](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-common.yml)
[![](https://img.shields.io/badge/Extension%20Counter-65+-yellow.svg?style=flat-square)]()
[![](https://img.shields.io/github/search/crazywhalecc/static-php-cli/TODO?label=TODO%20Counter&style=flat-square)]()
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396"> > 项目名称是 static-php-cli但其实支持 cli、fpm、micro 和 embed SAPI 😎
**使用 phpmicro 打包 PHP 代码:**
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
## 文档 ## 文档
目前 README 编写了基本用法。有关 static-php-cli 所有的功能,请点击这里查看文档:<https://static-php.dev>。 目前 README 编写了基本用法。有关 static-php-cli 所有的功能,请点击这里查看文档:<https://static-php.dev>。
## 直接下载 ## 自托管直接下载
如果你不想自行编译 PHP可以从本项目现有的示例 Action 下载 Artifact也可以从自托管的服务器下载。 如果你不想自行编译 PHP可以从本项目现有的示例 Action 下载 Artifact也可以从自托管的服务器下载。
- [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/)common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 7.5MB 左右。 - [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/)common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 22MB 左右。
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/)bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 25MB 左右。 - [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/)bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 70MB 左右。
- [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/)minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 3MB 左右。 - [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/)minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 6MB 左右。
> Linux 和 Windows 默认启用了 UPX 压缩,可减小 30~50% 的 PHP 二进制体积。
> macOS 当前不支持 UPX所以上述预编译的 macOS 版本体积可能较大。
对于 Windows 系统,目前支持的扩展较少,故仅提供 SPC 自身运行的最小扩展组合的 `cli``micro`[扩展组合 - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/)。
## 使用 static-php-cli 构建 PHP ## 使用 static-php-cli 构建 PHP
### 编译环境需求 ### 编译环境需求
- PHP >= 8.1(这是 spc 自身需要的版本,不是支持的构建版本)
- 扩展:`mbstring,tokenizer,phar`
- 系统安装了 `curl``git`
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。 是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含上面提到的扩展和 PHP 版本大于等于 8.1 即可。 但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。 下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
| | x86_64 | aarch64 | | | x86_64 | aarch64 |
|---------|----------------------|----------------------| |---------|----------------------|----------------------|
| macOS | :octocat: :computer: | :octocat: :computer: | | macOS | :octocat: :computer: | :computer: |
| Linux | :octocat: :computer: | :octocat: :computer: | | Linux | :octocat: :computer: | :octocat: :computer: |
| Windows | :octocat: :computer: | | | Windows | | |
| FreeBSD | :computer: | :computer: | | FreeBSD | :computer: | :computer: |
当前支持编译的 PHP 版本: > macOS-arm64 因 GitHub 暂未提供 arm runner如果要构建 arm 二进制,可以使用手动构建。
> :warning: 支持,但 static-php-cli 作者可能不再提供补丁修复 目前支持编译的 PHP 版本为:`7.3``7.4``8.0``8.1``8.2``8.3`
>
> :heavy_check_mark: 支持
>
> :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: | |
### 支持的扩展
请先根据下方扩展列表选择你要编译的扩展。 请先根据下方扩展列表选择你要编译的扩展。
@@ -99,7 +63,7 @@ static-php-cli简称 `spc`)有许多特性:
> 如果这里没有你需要的扩展,可以提交 Issue。 > 如果这里没有你需要的扩展,可以提交 Issue。
### 在线构建(使用 GitHub Actions ### 使用 Actions 构建
使用 GitHub Action 可以方便地构建一个静态编译的 PHP同时可以自行定义要编译的扩展。 使用 GitHub Action 可以方便地构建一个静态编译的 PHP同时可以自行定义要编译的扩展。
@@ -110,85 +74,72 @@ static-php-cli简称 `spc`)有许多特性:
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。 如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
### 本地构建(使用 spc 二进制) ### 手动构建(使用 SPC 二进制)
项目提供了 static-php-cli 的二进制文件`spc` 项目提供了一个 static-php-cli 的二进制文件,你可以直接下载对应平台的二进制文件,然后使用它来构建静态的 PHP。目前 `spc` 二进制支持的平台有 Linux 和 macOS
您可以使用 `spc` 二进制文件,无需安装任何运行时(用起来就像 golang 程序)。
目前,`spc` 二进制文件提供的平台有 Linux 和 macOS。
使用以下命令从自托管服务器下载 下面是从 GitHub Action 下载的方法
1. 进入 [GitHub Action](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml)。
2. 选择一个最新的构建任务,进入后选择 `Artifacts`,下载对应平台的二进制文件。
3. 解压 `.zip` 文件。解压后,为其添加执行权限:`chmod +x ./spc`
你也可以从自托管的服务器下载二进制文件:[进入](https://dl.static-php.dev/static-php-cli/spc-bin/nightly/)。
### 手动构建(使用源码)
先克隆本项目:
```bash ```bash
# Download from self-hosted nightly builds (sync with main branch)
# For Linux x86_64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
# Windows (x86_64, win10 build 17063 or later)
curl.exe -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
# Add execute perm (Linux and macOS only)
chmod +x ./spc
# Run (Linux and macOS)
./spc --version
# Run (Windows powershell)
.\spc.exe --version
```
自托管 `spc` 由 GitHub Actions 构建,你也可以从 Actions 直接下载:[此处](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml)。
### 本地构建(使用 git 源码)
```bash
# clone 仓库即可
git clone https://github.com/crazywhalecc/static-php-cli.git git clone https://github.com/crazywhalecc/static-php-cli.git
``` ```
如果您的系统上尚未安装 php我们建议你使用内置的 setup-runtime 自动安装 PHP 和 Composer 如果你本机没有安装 PHP你需要先使用包管理例如 brew、apt、yum、apk 等)安装 php
你也可以通过 `bin/setup-runtime` 命令下载静态编译好的 php-cli 和 Composer。下载的 php 和 Composer 将保存为 `bin/php``bin/composer`
```bash ```bash
cd static-php-cli cd static-php-cli
chmod +x bin/setup-runtime chmod +x bin/setup-runtime
# it will download static php (from self-hosted server) and composer (from getcomposer) ./bin/setup-runtime
bin/setup-runtime
# initialize composer deps # 使用独立的 php 运行 static-php-cli
bin/composer install ./bin/php bin/spc
# chmod
# 使用 composer
./bin/php bin/composer
# 初始化本项目
cd static-php-cli
composer update
chmod +x bin/spc chmod +x bin/spc
bin/spc --version
``` ```
### 开始构建 PHP ### 使用 static-php-cli 命令行程序
下面是使用 static-php-cli 的基础用法: 下面是使用 static-php-cli 编译静态 php 和 micro 的基础用法:
> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `./bin/spc` 替换为 `./spc`。 > 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `bin/spc` 替换为 `./spc`。
```bash ```bash
# 检查环境依赖,并根据尝试自动安装缺失的编译工具 # 检查环境依赖,并根据提示的命令安装缺失的编译工具
./bin/spc doctor --auto-fix ./bin/spc doctor
# 拉取所有依赖库 # 拉取所有依赖库
./bin/spc download --all ./bin/spc fetch --all
# 只拉取编译指定扩展需要的所有依赖(推荐) # 只拉取编译指定扩展需要的所有依赖
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite" ./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
# 下载编译不同版本的 PHP (--with-php=x.y推荐 7.3 ~ 8.3)
./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
# 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx # 构建包含 bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl 扩展的 php-cli 和 micro.sfx
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro ./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro
# 编译线程安全版本 (--enable-zts)
./bin/spc build "curl,phar" --enable-zts --build-cli
# 编译后使用 UPX 减小可执行文件体积 (--with-upx-pack) (至少压缩至原来的 30~50%)
./bin/spc build "curl,phar" --enable-zts --build-cli --with-upx-pack
``` ```
其中,目前支持构建 climicrofpm 和 embed使用以下参数的一个或多个来指定编译的 SAPI 你也可以使用参数 `--with-php=x.y` 来指定下载的 PHP 版本,目前支持 7.3 ~ 8.3
```bash
# 优先考虑使用 >= 8.0 的 PHP 版本,因为 phpmicro 不支持在 PHP7 中构建
./bin/spc download --with-php=8.2 --all
```
其中,目前支持构建 climicrofpm 三种静态二进制,使用以下参数的一个或多个来指定编译的 SAPI
- `--build-cli`:构建 cli 二进制 - `--build-cli`:构建 cli 二进制
- `--build-micro`:构建 phpmicro 自执行二进制 - `--build-micro`:构建 phpmicro 自执行二进制
@@ -199,10 +150,18 @@ bin/spc --version
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误: 如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
```bash ```bash
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all ./bin/spc build openssl,pcntl,mbstring --debug --build-all
./bin/spc download --all --debug ./bin/spc fetch --all --debug
``` ```
此外,默认编译的 PHP 为 NTS 版本。如需编译线程安全版本ZTS只需添加参数 `--enable-zts` 即可。
```bash
./bin/spc build openssl,pcntl --build-all --enable-zts
```
同时,你也可以使用参数 `--no-strip` 来关闭裁剪,关闭裁剪后可以使用 gdb 等工具调试,但这样会让静态二进制体积变大。
## 不同 SAPI 的使用 ## 不同 SAPI 的使用
### 使用 cli ### 使用 cli
@@ -278,17 +237,18 @@ bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=sys
## 赞助本项目 ## 赞助本项目
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。你捐赠的一部分将会被用于维护 **static-php.dev** 服务器。 你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。
## 开源协议 ## 开源协议
本项目采用 MIT License 许可开源,下面是类似的项目: 本项目依据旧版本惯例采用 MIT License 开源,部分扩展的集成编译命令参考或修改自以下项目:
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs) - [dixyes/lwmbs](https://github.com/dixyes/lwmbs)(木兰宽松许可证)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli) - [swoole/swoole-cli](https://github.com/swoole/swoole-cli)Apache 2.0 LICENSE、SWOOLE-CLI LICENSE
该项目使用了 [dixyes/lwmbs](https://github.com/dixyes/lwmbs) 中的一些代码,例如 Windows 静态构建目标和 libiconv 库支持。
lwmbs 使用 [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2) 许可进行分发。对应文件有关于作者和许可的特殊说明,除此之外,均使用 MIT 授权许可。
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。 因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。 请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
## 进阶
本项目重构分支为模块化编写。如果你对本项目感兴趣,想加入开发,可以参照文档的 [贡献指南](https://static-php.dev) 贡献代码或文档。

213
README.md
View File

@@ -1,41 +1,27 @@
# static-php-cli # static-php-cli
[![Chinese readme](https://img.shields.io/badge/README-%E4%B8%AD%E6%96%87%20%F0%9F%87%A8%F0%9F%87%B3-moccasin?style=flat-square)](README-zh.md) Build single static PHP binary, with PHP project together, with popular extensions included.
[![English readme](https://img.shields.io/badge/README-English%20%F0%9F%87%AC%F0%9F%87%A7-moccasin?style=flat-square)](README.md)
[![Releases](https://img.shields.io/packagist/v/crazywhalecc/static-php-cli?include_prereleases&label=Release&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/releases)
[![CI](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
[![Extensions](https://img.shields.io/badge/Extension%20Counter-75+-yellow.svg?style=flat-square)](https://static-php.dev/en/guide/extensions.html)
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime 🌐 **[中文](README-zh.md)** | **[English](README.md)**
with popular extensions.
Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed` and `micro` SAPI. The project name is static-php-cli, but it actually supports cli, fpm, micro and embed SAPI 😎
**static-php-cli** also has the ability to package PHP projects Compile a purely static php-cli binary file with various extensions to make PHP applications more portable! (cli SAPI)
along with the PHP interpreter into one single executable file.
## Features <img width="600" alt="2023-05-02 15 53 13" src="https://user-images.githubusercontent.com/20330940/235610282-23e58d68-bd35-4092-8465-171cff2d5ba8.png">
static-php-cli (you can call it `spc`) has a lot of features: You can also use the micro binary file to combine php binary and php source code into one for distribution! (micro SAPI)
- :handbag: Build single-file php executable, without any dependencies <img width="600" alt="2023-05-02 15 52 33" src="https://user-images.githubusercontent.com/20330940/235610318-2ef4e3f1-278b-4ca4-99f4-b38120efc395.png">
- :hamburger: Build **[phpmicro](https://github.com/dixyes/phpmicro)** self-extracted executable (glue php binary and php source code into one file)
- :pill: Automatic build environment checker (Doctor module)
- :zap: `Linux`, `macOS`, `FreeBSD`, `Windows` support
- :wrench: Configurable source code patches
- :books: Build dependency management
- 📦 Provide `spc` own standalone executable (built by spc and [box](https://github.com/box-project/box))
- :fire: Support many popular [extensions](https://static-php.dev/en/guide/extensions.html)
- :floppy_disk: UPX integration (significantly reduces binary size)
**Single-file standalone php-cli:** > This SAPI feature is from the [Fork](https://github.com/static-php/phpmicro) of [dixyes/phpmicro](https://github.com/dixyes/phpmicro).
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396"> [![Version](https://img.shields.io/badge/Version-2.0--rc8-pink.svg?style=flat-square)]()
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square)]()
[![](https://img.shields.io/github/actions/workflow/status/crazywhalecc/static-php-cli/tests.yml?branch=main&label=Build%20Test&style=flat-square)](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
**Combine PHP code with PHP interpreter using phpmicro:** [![](https://img.shields.io/badge/Extension%20Counter-65+-yellow.svg?style=flat-square)]([https://static-php.dev/](https://static-php.dev/en/guide/extensions.html))
[![](https://img.shields.io/github/search/crazywhalecc/static-php-cli/TODO?label=TODO%20Counter&style=flat-square)]()
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
## Documentation ## Documentation
@@ -44,59 +30,35 @@ see <https://static-php.dev> .
## Direct Download ## Direct Download
If you don't want to build or want to test first, you can download example pre-compiled artifact from [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml), or from self-hosted server. If you don't want to compile yourself, you can download example pre-compiled artifact from [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-common.yml), or from self-hosted server.
Below are several precompiled static-php binaries with different extension combinations, Below are several precompiled static-php binaries with different extension combinations,
which can be downloaded directly according to your needs. which can be downloaded directly according to your needs.
- [Extension-Combination - common](https://dl.static-php.dev/static-php-cli/common/): `common` contains about [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) commonly used extensions, and the size is about 7.5MB. - [Extension-Combination - common](https://dl.static-php.dev/static-php-cli/common/): `common` contains about [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) commonly used extensions, and the size is about 22MB.
- [Extension-Combination - bulk](https://dl.static-php.dev/static-php-cli/bulk/): `bulk` contains [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) extensions and is about 25MB in size. - [Extension-Combination - bulk](https://dl.static-php.dev/static-php-cli/bulk/): `bulk` contains [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) extensions and is about 70MB in size.
- [Extension-Combination - minimal](https://dl.static-php.dev/static-php-cli/minimal/): `minimal` contains [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) extensions and is about 3MB in size. - [Extension-Combination - minimal](https://dl.static-php.dev/static-php-cli/minimal/): `minimal` contains [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) extensions and is about 6MB in size.
> Linux and Windows supports UPX compression for binaries, which can reduce the size of the binary by 30% to 50%. ## Use static-php-cli to build PHP
> macOS does not support UPX compression, so the size of the pre-built binaries for mac is larger.
For Windows systems, there are currently fewer extensions supported,
so only `cli` and `micro` that run the minimum extension combination of SPC itself are provided: [Extension-Combination - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/).
## Build
### Compilation Requirements ### Compilation Requirements
You can say I made a PHP builder written in PHP, pretty funny. Yes, this project is written in PHP, pretty funny.
But static-php-cli runtime only requires an environment above PHP 8.1 and extensions mentioned below. But static-php-cli runtime only requires an environment above PHP 8.1 and `mbstring`, `pcntl` extension.
- PHP >= 8.1 (This is the version required by spc itself, not the build version) Here is the architecture support status, where :octocat: represents support for GitHub Action builds,
- Extension: `mbstring,tokenizer,phar`
- Supported OS with `curl` and `git` installed
Here is the supported OS and arch, where :octocat: represents support for GitHub Action builds,
:computer: represents support for local manual builds, and blank represents not currently supported. :computer: represents support for local manual builds, and blank represents not currently supported.
| | x86_64 | aarch64 | | | x86_64 | aarch64 |
|---------|----------------------|----------------------| |---------|----------------------|----------------------|
| macOS | :octocat: :computer: | :octocat: :computer: | | macOS | :octocat: :computer: | :computer: |
| Linux | :octocat: :computer: | :octocat: :computer: | | Linux | :octocat: :computer: | :octocat: :computer: |
| Windows | :octocat: :computer: | | | Windows | | |
| FreeBSD | :computer: | :computer: | | FreeBSD | :computer: | :computer: |
Currently supported PHP versions for compilation: > macOS-arm64 is not supported for GitHub Actions, if you are going to build on arm, you can build it manually on your own machine.
> :warning: supported but not maintained by static-php-cli authors Currently supported PHP versions for compilation are: `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`.
>
> :heavy_check_mark: supported
>
> :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: | |
### Supported Extensions ### Supported Extensions
@@ -109,7 +71,7 @@ Please first select the extension you want to compile based on the extension lis
Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) . Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
### Build Online (using GitHub Actions) ### GitHub Actions Build
Use GitHub Action to easily build a statically compiled PHP, Use GitHub Action to easily build a statically compiled PHP,
and at the same time define the extensions to be compiled by yourself. and at the same time define the extensions to be compiled by yourself.
@@ -121,85 +83,80 @@ and at the same time define the extensions to be compiled by yourself.
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting. If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
### Build Locally (using SPC binary) - When using ubuntu-latest, it will build linux-x86_64 binary.
- When using macos-latest, it will build macOS-x86_64 binary.
This project provides a binary file of static-php-cli: `spc`. ### Manual build (using SPC binary)
You can use `spc` binary instead of installing any runtime like golang app.
This project provides a binary file of static-php-cli.
You can directly download the binary file of the corresponding platform and then use it to build static PHP.
Currently, the platforms supported by `spc` binary are Linux and macOS. Currently, the platforms supported by `spc` binary are Linux and macOS.
Download from self-hosted nightly builds using commands below: Here's how to download from GitHub Actions:
1. Enter [GitHub Actions](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml) or [self-hosted nightly builds](https://dl.static-php.dev/static-php-cli/spc-bin/nightly/).
2. If you download from GHA, select the latest build task, select `Artifacts`, and download the binary file of the corresponding platform.
3. If you download from GHA, unzip the `.zip` file. After decompressing, add execution permissions to it: `chmod +x ./spc`.
4. If you download from self-hosted server, download `spc-$os-$arch` file and just use it (don't forget `chmod +x`).
> SPC single-file binary is built by phpmicro and box, and it doesn't need to install PHP. Just treat `spc` as a standalone executable.
### Manual build (using source code)
Clone repo first:
```bash ```bash
# Download from self-hosted nightly builds (sync with main branch)
# For Linux x86_64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
# For Linux aarch64
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
# macOS x86_64 (Intel)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
# macOS aarch64 (Apple)
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
# Windows (x86_64, win10 build 17063 or later)
curl.exe -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
# Add execute perm (Linux and macOS only)
chmod +x ./spc
# Run (Linux and macOS)
./spc --version
# Run (Windows powershell)
.\spc.exe --version
```
Self-hosted `spc` is built by GitHub Actions, you can also download from Actions artifacts [here](https://github.com/crazywhalecc/static-php-cli/actions/workflows/release-build.yml).
### Build Locally (using git source)
```bash
# just clone me!
git clone https://github.com/crazywhalecc/static-php-cli.git git clone https://github.com/crazywhalecc/static-php-cli.git
``` ```
If you have not installed php on your system, we recommend that you use the built-in setup-runtime to install PHP and Composer automatically. If you have not installed php on your system, you can use package management to install PHP (such as brew, apt, yum, apk etc.).
And you can also download single-file php binary and composer using command `bin/setup-runtime`.
The PHP runtime for static-php-cli itself will be downloaded at `bin/php`, and composer is at `bin/composer`.
```bash ```bash
cd static-php-cli cd static-php-cli
chmod +x bin/setup-runtime chmod +x bin/setup-runtime
# it will download static php (from self-hosted server) and composer (from getcomposer) # It will download php-cli from self-hosted server and composer from getcomposer.org
bin/setup-runtime ./bin/setup-runtime
# initialize composer deps
bin/composer install # Use this php runtime to run static-php-cli compiler
# chmod ./bin/php bin/spc
# Use composer
./bin/php bin/composer
# Initialize this project
cd static-php-cli
composer update
chmod +x bin/spc chmod +x bin/spc
bin/spc --version
``` ```
### Start Building PHP ### Use static-php-cli
Basic usage for building php with some extensions: Basic usage for building php and micro with some extensions:
> If you are using the packaged standalone `spc` binary, you need to replace `bin/spc` with `./spc` or `.\spc.exe` in the following commands. > If you are using the packaged `spc` binary, you need to replace `bin/spc` with `./spc` in the following commands.
```bash ```bash
# Check system tool dependencies, auto-fix them if possible # Check system tool dependencies, fix them if possible
./bin/spc doctor --auto-fix ./bin/spc doctor
# fetch all libraries # fetch all libraries
./bin/spc download --all ./bin/spc download --all
# only fetch necessary sources by needed extensions (recommended) # only fetch necessary sources by needed extensions
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite" ./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
# download different PHP version (--with-php=x.y, recommend 7.3 ~ 8.3)
./bin/spc download --for-extensions="openssl,curl,mbstring" --with-php=8.1
# with bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl extension, build both CLI and phpmicro SAPI # with bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl extension, build both CLI and phpmicro SAPI
./bin/spc build "bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl" --build-cli --build-micro ./bin/spc build bcmath,openssl,tokenizer,sqlite3,pdo_sqlite,ftp,curl --build-cli --build-micro
# build thread-safe (ZTS) version (--enable-zts)
./bin/spc build "curl,phar" --enable-zts --build-cli
# build, pack executable with UPX (--with-upx-pack) (reduce binary size for 30~50%)
./bin/spc build "curl,phar" --enable-zts --build-cli --with-upx-pack
``` ```
Now we support `cli`, `micro`, `fpm` and `embed` SAPI. You can use one or more of the following parameters to specify the compiled SAPI: You can also use the parameter `--with-php=x.y` to specify the downloaded PHP version, currently supports 7.4 ~ 8.3:
```bash
# Using PHP >= 8.0 is recommended, because PHP7 cannot use phpmicro
./bin/spc fetch --with-php=8.2 --all
```
Now we support `cli`, `micro`, `fpm`, you can use one or more of the following parameters to specify the compiled SAPI:
- `--build-cli`: build static cli executable - `--build-cli`: build static cli executable
- `--build-micro`: build static phpmicro self-extracted executable - `--build-micro`: build static phpmicro self-extracted executable
@@ -210,10 +167,18 @@ Now we support `cli`, `micro`, `fpm` and `embed` SAPI. You can use one or more o
If anything goes wrong, use `--debug` option to display full terminal output: If anything goes wrong, use `--debug` option to display full terminal output:
```bash ```bash
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all ./bin/spc build openssl,pcntl,mbstring --debug --build-all
./bin/spc download --all --debug ./bin/spc fetch --all --debug
``` ```
In addition, we build NTS (non-thread-safe) by default. If you are going to build ZTS version, just add `--enable-zts` option.
```bash
./bin/spc build openssl,pcntl --build-all --enable-zts
```
Adding option `--no-strip` can produce binaries with debug symbols, in order to debug (using gdb). Disabling strip will increase the size of static binary.
## Different SAPI Usage ## Different SAPI Usage
### Use cli ### Use cli
@@ -303,7 +268,7 @@ Now there is a [static-php](https://github.com/static-php) organization, which i
## Sponsor this project ## 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 my project on [this page](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md).
## Open-Source License ## Open-Source License
@@ -316,12 +281,10 @@ These are similar projects:
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs) - [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli) - [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
The project uses some code from [dixyes/lwmbs](https://github.com/dixyes/lwmbs), such as windows static build target and libiconv support.
lwmbs is licensed under the [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2).
Due to the special nature of this project, Due to the special nature of this project,
many other open source projects such as curl and protobuf will be used during the project compilation process, many other open source projects such as curl and protobuf will be used during the project compilation process,
and they all have their own open source licenses. and they all have their own open source licenses.
Please use the `bin/spc dump-license` command to export the open source licenses used in the project after compilation, Please use the `bin/spc dump-license` command to export the open source licenses used in the project after compilation,
and comply with the corresponding project's LICENSE. and comply with the corresponding project's LICENSE.

View File

@@ -35,6 +35,7 @@ while [ $# -gt 0 ]; do
case "$1" in case "$1" in
--mirror) --mirror)
mirror="$2" mirror="$2"
shift
;; ;;
--*) --*)
echo "Illegal option $1" echo "Illegal option $1"
@@ -46,7 +47,7 @@ done
case "$mirror" in case "$mirror" in
china) china)
__PHP_RUNTIME_URL__="https://dl.static-php.dev/static-php-cli/bulk/php-8.2.13-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz" __PHP_RUNTIME_URL__="https://dl.static-php.dev/static-php-cli/bulk/php-8.2.13-cli-${__OS_FIXED__}-${__ARCH__}.tar.gz"
__COMPOSER_URL__="https://mirrors.tencent.com/composer/composer.phar" __COMPOSER_URL__="https://mirrors.aliyun.com/composer/composer.phar"
;; ;;
esac esac

View File

@@ -1,115 +0,0 @@
param (
[string] ${action}
)
function AddToPath {
param (
[string]$pathToAdd
)
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
if ($currentPath -notlike "*$pathToAdd*") {
$newPath = $currentPath + ";$pathToAdd"
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
Write-Host "Added '$pathToAdd' to Path."
Write-Host "To remove path, use: " -NoNewline
Write-Host "bin/setup-runtime remove-path" -ForegroundColor Cyan
} else {
Write-Host "Path already exists."
}
}
function RemoveFromPath {
param (
[string]$pathToRemove
)
$currentPath = [System.Environment]::GetEnvironmentVariable('Path', 'User')
if ($currentPath -like "*$pathToRemove*") {
$newPath = $currentPath -replace [regex]::Escape(';' + $pathToRemove), ''
[System.Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
Write-Host "Removed Path '$pathToRemove'"
} else {
Write-Host "Path '$pathToRemove' not in Path"
}
}
# working dir
$WorkingDir = (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Definition))
if ($action -eq 'add-path') {
AddToPath ($WorkingDir + '\runtime')
exit 0
} elseif ($action -eq 'remove-path') {
RemoveFromPath ($WorkingDir + '\runtime')
exit 0
} elseif (-not($action -eq '')) {
Write-Host ("Invalid action: " + $action) -ForegroundColor Red
exit 1
}
# get php 8.1 specific version
$API = (Invoke-WebRequest -Uri "https://www.php.net/releases/index.php?json&version=8.1") | ConvertFrom-Json
# php windows download
$PHPRuntimeUrl = "https://windows.php.net/downloads/releases/php-" + $API.version + "-Win32-vs16-x64.zip"
$ComposerUrl = "https://getcomposer.org/download/latest-stable/composer.phar"
# create dir
New-Item -Path "downloads" -ItemType Directory -Force | Out-Null
# download php
if (-not(Test-Path "downloads\php.zip"))
{
Write-Host "Downloading PHP ..."
Invoke-WebRequest $PHPRuntimeUrl -OutFile "downloads\php.zip"
}
# extract php
New-Item -Path "runtime" -ItemType Directory -Force | Out-Null
Write-Host "Extracting php.zip ..."
Expand-Archive -Path "downloads/php.zip" -DestinationPath "runtime" -Force
# make php.ini
Move-Item -Path "runtime\php.ini-production" -Destination "runtime\php.ini" -Force
$OriginINI = Get-Content -Path "runtime\php.ini" -Raw
$OriginINI = $OriginINI -replace ';extension=openssl', 'extension=openssl'
$OriginINI = $OriginINI -replace ';extension=curl', 'extension=curl'
$OriginINI = $OriginINI -replace ';extension=mbstring', 'extension=mbstring'
$OriginINI = $OriginINI -replace ';extension=sodium', 'extension=sodium'
$OriginINI = $OriginINI -replace ';extension_dir = "./"', ('extension_dir = "' + (Split-Path -Parent $MyInvocation.MyCommand.Definition) + '\..\runtime\ext"')
$OriginINI | Set-Content -Path "runtime\php.ini"
# download composer
if (-not(Test-Path "runtime\composer.phar"))
{
Write-Host "Downloading composer ..."
Invoke-WebRequest $ComposerUrl -OutFile "downloads\composer.phar"
Move-Item -Path "downloads\composer.phar" -Destination "runtime\composer.phar" -Force
}
# create runtime\composer.ps1
$ComposerContent = '
$WorkingDir = (Split-Path -Parent $MyInvocation.MyCommand.Definition)
& ($WorkingDir + "\php.exe") (Join-Path $WorkingDir "\composer.phar") @args
'
$ComposerContent | Set-Content -Path 'runtime\composer.ps1' -Encoding UTF8
Write-Host "Successfully downloaded PHP and Composer !" -ForegroundColor Green
Write-Host "Use static-php-cli: " -NoNewline
Write-Host "bin/spc" -ForegroundColor Cyan
Write-Host "Use php: " -NoNewline
Write-Host "runtime/php" -ForegroundColor Cyan
Write-Host "Use composer: " -NoNewline
Write-Host "runtime/composer" -ForegroundColor Cyan
Write-Host ""
Write-Host "Don't forget installing composer dependencies '" -NoNewline
Write-Host "runtime/composer install" -ForegroundColor Cyan -NoNewline
Write-Host "' before using static-php-cli !"
Write-Host ""
Write-Host "If you want to use this PHP for quality tools (like phpstan, php-cs-fixer) or other project,"
Write-Host "or use PHP, Composer as system executable,"
Write-Host "use '" -NoNewline
Write-Host "bin/setup-runtime add-path" -ForegroundColor Cyan -NoNewline
Write-Host "' to add runtime dir in Path."

View File

@@ -4,13 +4,7 @@
use SPC\ConsoleApplication; use SPC\ConsoleApplication;
use SPC\exception\ExceptionHandler; use SPC\exception\ExceptionHandler;
if (file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { require_once __DIR__ . '/../vendor/autoload.php';
// Current: ./bin (git/project mode)
require_once dirname(__DIR__) . '/vendor/autoload.php';
} else {
// Current: ./vendor/crazywhalecc/static-php-cli/bin (composer library mode)
require_once dirname(__DIR__, 3) . '/autoload.php';
}
// 防止 Micro 打包状态下不支持中文的显示(虽然这个项目目前好像没输出过中文?) // 防止 Micro 打包状态下不支持中文的显示(虽然这个项目目前好像没输出过中文?)
if (PHP_OS_FAMILY === 'Windows' && Phar::running()) { if (PHP_OS_FAMILY === 'Windows' && Phar::running()) {
@@ -21,5 +15,4 @@ try {
(new ConsoleApplication())->run(); (new ConsoleApplication())->run();
} catch (Exception $e) { } catch (Exception $e) {
ExceptionHandler::getInstance()->handle($e); ExceptionHandler::getInstance()->handle($e);
exit(1);
} }

View File

@@ -1,12 +0,0 @@
$PHP_Exec = ".\runtime\php.exe"
if (-not(Test-Path $PHP_Exec)) {
$PHP_Exec = Get-Command php.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Definition
if (-not $PHP_Exec) {
Write-Host "Error: PHP not found, you need to install PHP on your system or use 'bin/setup-runtime'." -ForegroundColor Red
exit 1
}
}
& "$PHP_Exec" ("bin/spc") @args
exit $LASTEXITCODE

View File

@@ -4,7 +4,6 @@
"blacklist": [ "blacklist": [
".github" ".github"
], ],
"compression": "GZ",
"directories": [ "directories": [
"config", "config",
"src", "src",
@@ -15,5 +14,6 @@
"vendor/zhamao" "vendor/zhamao"
], ],
"git-commit-short": "git_commit_short", "git-commit-short": "git_commit_short",
"metadata": "ConsoleApplication::VERSION",
"output": "spc.phar" "output": "spc.phar"
} }

View File

@@ -11,18 +11,19 @@
"require": { "require": {
"php": ">= 8.1", "php": ">= 8.1",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-pcntl": "*",
"laravel/prompts": "^0.1.12", "laravel/prompts": "^0.1.12",
"symfony/console": "^5.4 || ^6 || ^7", "symfony/console": "^5.4 || ^6 || ^7",
"zhamao/logger": "^1.0" "zhamao/logger": "^1.0"
}, },
"require-dev": { "require-dev": {
"captainhook/captainhook-phar": "^5.23", "captainhook/captainhook": "^5.10",
"captainhook/hook-installer": "^1.0", "captainhook/plugin-composer": "^5.3",
"friendsofphp/php-cs-fixer": "^3.25", "friendsofphp/php-cs-fixer": "^3.25",
"humbug/box": "^4.5", "humbug/box": "^4.3",
"nunomaduro/collision": "^7.8", "nunomaduro/collision": "^7.8",
"phpstan/phpstan": "^1.10", "phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^10.3 || ^9" "phpunit/phpunit": "^10.3"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
@@ -50,17 +51,9 @@
"config": { "config": {
"allow-plugins": { "allow-plugins": {
"phpstan/extension-installer": true, "phpstan/extension-installer": true,
"captainhook/hook-installer": true, "captainhook/plugin-composer": true
"captainhook/plugin-composer": true,
"captainhook/captainhook-phar": true
}, },
"optimize-autoloader": true, "optimize-autoloader": true,
"sort-packages": true "sort-packages": true
}, }
"funding": [
{
"type": "other",
"url": "https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md"
}
]
} }

2483
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,18 +1,4 @@
{ {
"amqp": {
"support": {
"BSD": "wip"
},
"type": "external",
"arg-type": "custom",
"source": "amqp",
"lib-depends": [
"librabbitmq"
],
"ext-depends-windows": [
"openssl"
]
},
"apcu": { "apcu": {
"type": "external", "type": "external",
"source": "apcu" "source": "apcu"
@@ -21,9 +7,6 @@
"type": "builtin" "type": "builtin"
}, },
"bz2": { "bz2": {
"support": {
"Windows": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -33,62 +16,38 @@
"calendar": { "calendar": {
"type": "builtin" "type": "builtin"
}, },
"crypto": {
"type": "external",
"arg-type": "with",
"source": "ext-crypto",
"lib-depends": [
"openssl"
]
},
"ctype": { "ctype": {
"type": "builtin" "type": "builtin"
}, },
"curl": { "curl": {
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
"lib-depends": [ "lib-depends": [
"curl" "curl"
],
"ext-depends-windows": [
"zlib",
"openssl"
] ]
}, },
"dba": { "dba": {
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type-windows": "with"
"lib-suggests": [
"qdbm"
]
}, },
"dom": { "dom": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with", "arg-type-windows": "with",
"lib-depends": [ "lib-depends": [
"libxml2", "libxml2",
"zlib" "zlib"
],
"ext-depends-windows": [
"xml"
] ]
}, },
"ds": {
"type": "external",
"source": "ext-ds"
},
"enchant": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Darwin": "wip",
"Linux": "wip"
},
"type": "wip"
},
"event": { "event": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "ext-event", "source": "ext-event",
"arg-type": "custom", "arg-type": "custom",
@@ -106,18 +65,10 @@
"type": "builtin" "type": "builtin"
}, },
"ffi": { "ffi": {
"support": {
"Linux": "no",
"BSD": "wip"
},
"notes": true,
"arg-type": "custom", "arg-type": "custom",
"type": "builtin", "type": "builtin",
"lib-depends-unix": [ "lib-depends": [
"libffi" "libffi"
],
"lib-depends-windows": [
"libffi-win"
] ]
}, },
"fileinfo": { "fileinfo": {
@@ -133,11 +84,6 @@
] ]
}, },
"gd": { "gd": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with", "arg-type-windows": "with",
@@ -156,36 +102,21 @@
] ]
}, },
"gettext": { "gettext": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with",
"lib-depends": [ "lib-depends": [
"gettext" "gettext"
] ]
}, },
"glfw": { "glfw": {
"support": {
"Windows": "wip",
"BSD": "no",
"Linux": "no"
},
"notes": true,
"type": "external", "type": "external",
"arg-type": "custom", "arg-type": "custom",
"source": "ext-glfw", "source": "ext-glfw",
"lib-depends": [ "lib-depends": [
"glfw" "glfw"
], ]
"lib-depends-windows": []
}, },
"gmp": { "gmp": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -193,32 +124,17 @@
] ]
}, },
"iconv": { "iconv": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"arg-type-windows": "with", "lib-depends": [
"lib-depends-unix": [
"libiconv" "libiconv"
],
"lib-depends-windows": [
"libiconv-win"
] ]
}, },
"igbinary": { "igbinary": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "igbinary" "source": "igbinary"
}, },
"imagick": { "imagick": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-imagick", "source": "ext-imagick",
"arg-type": "custom", "arg-type": "custom",
@@ -227,44 +143,26 @@
] ]
}, },
"imap": { "imap": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
"imap" "imap"
], ],
"ext-suggests": [ "lib-suggests": [
"openssl" "openssl"
] ]
}, },
"inotify": { "inotify": {
"support": {
"Windows": "no",
"BSD": "wip",
"Darwin": "no"
},
"type": "external", "type": "external",
"source": "inotify" "source": "inotify"
}, },
"intl": { "intl": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"lib-depends": [ "lib-depends": [
"icu" "icu"
] ]
}, },
"ldap": { "ldap": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -278,14 +176,12 @@
"openssl" "openssl"
] ]
}, },
"libxml": { "leveldb": {
"support": { "type": "external",
"BSD": "wip" "arg-type": "with-prefix",
}, "source": "pmmp-leveldb",
"type": "builtin", "lib-depends": [
"arg-type": "none", "leveldb"
"ext-depends": [
"xml"
] ]
}, },
"mbregex": { "mbregex": {
@@ -302,21 +198,7 @@
"type": "builtin", "type": "builtin",
"arg-type": "custom" "arg-type": "custom"
}, },
"mcrypt": {
"type": "wip",
"support": {
"Windows": "no",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"memcache": { "memcache": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-memcache", "source": "ext-memcache",
"arg-type": "custom", "arg-type": "custom",
@@ -328,11 +210,6 @@
] ]
}, },
"memcached": { "memcached": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Linux": "no"
},
"type": "external", "type": "external",
"source": "memcached", "source": "memcached",
"arg-type": "custom", "arg-type": "custom",
@@ -346,12 +223,6 @@
] ]
}, },
"mongodb": { "mongodb": {
"support": {
"Darwin": "no",
"BSD": "wip",
"Windows": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "mongodb", "source": "mongodb",
"arg-type": "custom", "arg-type": "custom",
@@ -362,6 +233,10 @@
"zlib" "zlib"
] ]
}, },
"morton": {
"type": "external",
"source": "ext-morton"
},
"mysqli": { "mysqli": {
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
@@ -376,25 +251,13 @@
"zlib" "zlib"
] ]
}, },
"oci8": {
"type": "wip",
"support": {
"Windows": "wip",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"opcache": { "opcache": {
"type": "builtin", "type": "builtin",
"arg-type": "custom" "arg-type": "custom"
}, },
"openssl": { "openssl": {
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with",
"lib-depends": [ "lib-depends": [
"openssl", "openssl",
"zlib" "zlib"
@@ -403,24 +266,7 @@
"zlib" "zlib"
] ]
}, },
"parallel": {
"support": {
"BSD": "wip"
},
"notes": true,
"type": "external",
"source": "parallel",
"arg-type-windows": "with",
"lib-depends-windows": [
"pthreads4w"
]
},
"password-argon2": { "password-argon2": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -428,9 +274,6 @@
] ]
}, },
"pcntl": { "pcntl": {
"support": {
"Windows": "no"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
@@ -446,10 +289,6 @@
] ]
}, },
"pdo_pgsql": { "pdo_pgsql": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"ext-depends": [ "ext-depends": [
@@ -461,9 +300,6 @@
] ]
}, },
"pdo_sqlite": { "pdo_sqlite": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
"ext-depends": [ "ext-depends": [
@@ -474,25 +310,7 @@
"sqlite" "sqlite"
] ]
}, },
"pdo_sqlsrv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "pdo_sqlsrv",
"arg-type": "with",
"ext-depends": [
"pdo",
"sqlsrv"
]
},
"pgsql": { "pgsql": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -505,37 +323,37 @@
"zlib" "zlib"
] ]
}, },
"pmmp-chunkutils2": {
"type": "external",
"source": "pmmp-chunkutils2",
"arg-type": "custom",
"cpp-extension": true
},
"pmmpthread": {
"type": "external",
"source": "pmmpthread"
},
"posix": { "posix": {
"support": {
"Windows": "no"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
"protobuf": { "protobuf": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "protobuf" "source": "protobuf"
}, },
"pspell": {
"type": "builtin",
"arg-type": "with",
"lib-depends": [
"aspell"
]
},
"rar": { "rar": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Darwin": "partial"
},
"notes": true,
"type": "external", "type": "external",
"source": "rar", "source": "rar",
"cpp-extension": true "cpp-extension": true
}, },
"readline": { "readline": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -543,20 +361,11 @@
] ]
}, },
"redis": { "redis": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "redis", "source": "redis",
"arg-type": "custom", "arg-type": "custom",
"ext-suggests": [ "ext-suggests": [
"session", "session"
"igbinary"
],
"lib-suggests": [
"zstd",
"liblz4"
] ]
}, },
"session": { "session": {
@@ -565,29 +374,15 @@
"shmop": { "shmop": {
"type": "builtin" "type": "builtin"
}, },
"simdjson": {
"type": "external",
"source": "ext-simdjson",
"cpp-extension": true
},
"simplexml": { "simplexml": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with",
"lib-depends": [ "lib-depends": [
"libxml2" "libxml2"
],
"ext-depends-windows": [
"xml"
] ]
}, },
"snappy": { "snappy": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-snappy", "source": "ext-snappy",
"cpp-extension": true, "cpp-extension": true,
@@ -599,27 +394,24 @@
"apcu" "apcu"
] ]
}, },
"snmp": {
"type": "builtin",
"arg-type": "with",
"lib-depends": [
"net-snmp"
]
},
"soap": { "soap": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
"libxml2" "libxml2"
],
"ext-depends-windows": [
"xml"
] ]
}, },
"sockets": { "sockets": {
"type": "builtin" "type": "builtin"
}, },
"sodium": { "sodium": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with", "arg-type": "with",
"lib-depends": [ "lib-depends": [
@@ -627,124 +419,38 @@
] ]
}, },
"sqlite3": { "sqlite3": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"arg-type-windows": "with",
"lib-depends": [ "lib-depends": [
"sqlite" "sqlite"
] ]
}, },
"sqlsrv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "sqlsrv",
"lib-depends": [
"unixodbc"
],
"ext-depends-linux": [
"pcntl"
],
"cpp-extension": true
},
"ssh2": { "ssh2": {
"support": {
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-ssh2", "source": "ext-ssh2",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"arg-type-windows": "with",
"lib-depends": [ "lib-depends": [
"libssh2" "libssh2"
],
"ext-depends-windows": [
"openssl",
"zlib"
] ]
}, },
"swoole": { "swoole": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "swoole", "source": "swoole",
"arg-type": "custom", "arg-type": "custom",
"cpp-extension": true, "cpp-extension": true,
"unix-only": true,
"lib-depends": [ "lib-depends": [
"libcares", "openssl"
"brotli",
"nghttp2",
"zlib"
], ],
"ext-depends": [ "ext-depends": [
"openssl", "openssl"
"curl"
], ],
"ext-suggests": [ "ext-suggests": [
"swoole-hook-pgsql", "curl",
"swoole-hook-mysql", "pgsql"
"swoole-hook-sqlite"
]
},
"swoole-hook-mysql": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "addon",
"arg-type": "custom",
"ext-depends": [
"mysqlnd",
"pdo",
"pdo_mysql"
], ],
"ext-suggests": [ "unix-only": true
"mysqli"
]
},
"swoole-hook-pgsql": {
"support": {
"Windows": "no",
"BSD": "wip",
"Darwin": "partial"
},
"notes": true,
"type": "addon",
"arg-type": "custom",
"ext-depends": [
"pgsql",
"pdo"
]
},
"swoole-hook-sqlite": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "addon",
"arg-type": "custom",
"ext-depends": [
"sqlite3",
"pdo"
]
}, },
"swow": { "swow": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external", "type": "external",
"source": "swow", "source": "swow",
"arg-type": "custom", "arg-type": "custom",
@@ -758,32 +464,18 @@
] ]
}, },
"sysvmsg": { "sysvmsg": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
"sysvsem": { "sysvsem": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"unix-only": true "unix-only": true
}, },
"sysvshm": { "sysvshm": {
"support": { "type": "builtin",
"BSD": "wip" "unix-only": true
},
"type": "builtin"
}, },
"tidy": { "tidy": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -793,60 +485,7 @@
"tokenizer": { "tokenizer": {
"type": "builtin" "type": "builtin"
}, },
"uuid": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-uuid",
"arg-type": "with-prefix",
"lib-depends": [
"libuuid"
]
},
"uv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-uv",
"arg-type": "with-prefix",
"lib-depends": [
"libuv"
],
"ext-depends": [
"sockets"
]
},
"xdebug": {
"type": "builtin",
"support": {
"Windows": "wip",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"xhprof": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external",
"source": "xhprof",
"ext-depends": [
"ctype"
]
},
"xlswriter": { "xlswriter": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "xlswriter", "source": "xlswriter",
"arg-type": "custom", "arg-type": "custom",
@@ -856,52 +495,28 @@
] ]
}, },
"xml": { "xml": {
"support": {
"BSD": "wip"
},
"notes": true,
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"arg-type-windows": "with", "arg-type-windows": "with",
"lib-depends": [ "lib-depends": [
"libxml2" "libxml2"
],
"ext-depends-windows": [
"iconv"
] ]
}, },
"xmlreader": { "xmlreader": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
"libxml2" "libxml2"
],
"ext-depends-windows": [
"xml",
"dom"
] ]
}, },
"xmlwriter": { "xmlwriter": {
"support": {
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "custom", "arg-type": "custom",
"lib-depends": [ "lib-depends": [
"libxml2" "libxml2"
],
"ext-depends-windows": [
"xml"
] ]
}, },
"xsl": { "xsl": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"lib-depends": [ "lib-depends": [
@@ -912,22 +527,7 @@
"dom" "dom"
] ]
}, },
"yac": {
"support": {
"BSD": "wip"
},
"type": "external",
"source": "yac",
"arg-type-unix": "custom",
"ext-depends-unix": [
"igbinary"
]
},
"yaml": { "yaml": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "yaml", "source": "yaml",
"arg-type": "with-prefix", "arg-type": "with-prefix",
@@ -936,10 +536,6 @@
] ]
}, },
"zip": { "zip": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin", "type": "builtin",
"arg-type": "with-prefix", "arg-type": "with-prefix",
"arg-type-windows": "enable", "arg-type-windows": "enable",
@@ -956,10 +552,6 @@
] ]
}, },
"zstd": { "zstd": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external", "type": "external",
"source": "ext-zstd", "source": "ext-zstd",
"arg-type": "custom", "arg-type": "custom",

View File

@@ -2,14 +2,14 @@
"brotli": { "brotli": {
"source": "brotli", "source": "brotli",
"static-libs-unix": [ "static-libs-unix": [
"libbrotlidec.a", "libbrotlidec-static.a",
"libbrotlienc.a", "libbrotlienc-static.a",
"libbrotlicommon.a" "libbrotlicommon-static.a"
], ],
"static-libs-windows": [ "static-libs-windows": [
"brotlicommon.lib", "brotlicommon-static.lib",
"brotlienc.lib", "brotlienc-static.lib",
"brotlidec.lib" "brotlidec-static.lib"
], ],
"headers": [ "headers": [
"brotli" "brotli"
@@ -36,7 +36,7 @@
"libcurl.a" "libcurl.a"
], ],
"static-libs-windows": [ "static-libs-windows": [
"libcurl_a.lib" "libcurl.lib"
], ],
"headers": [ "headers": [
"curl" "curl"
@@ -45,21 +45,21 @@
"openssl", "openssl",
"zlib" "zlib"
], ],
"lib-depends-windows": [ "lib-suggests": [
"openssl",
"zlib",
"libssh2",
"nghttp2"
],
"lib-suggests-unix": [
"libssh2", "libssh2",
"brotli", "brotli",
"nghttp2", "nghttp2",
"zstd" "zstd"
], ],
"lib-suggests-windows": [ "lib-suggests-windows": [
"zlib",
"libssh2",
"brotli", "brotli",
"zstd" "nghttp2",
"zstd",
"openssl",
"idn2",
"psl"
], ],
"frameworks": [ "frameworks": [
"CoreFoundation", "CoreFoundation",
@@ -85,22 +85,6 @@
"brotli" "brotli"
] ]
}, },
"gettext": {
"source": "gettext",
"static-libs-unix": [
"libintl.a"
],
"lib-depends": [
"libiconv"
],
"lib-suggests": [
"ncurses",
"libxml2"
],
"frameworks": [
"CoreFoundation"
]
},
"glfw": { "glfw": {
"source": "ext-glfw", "source": "ext-glfw",
"static-libs-unix": [ "static-libs-unix": [
@@ -147,8 +131,7 @@
"libpng", "libpng",
"libjpeg", "libjpeg",
"libwebp", "libwebp",
"freetype", "freetype"
"libtiff"
], ],
"lib-suggests": [ "lib-suggests": [
"zstd", "zstd",
@@ -180,6 +163,13 @@
"libsodium" "libsodium"
] ]
}, },
"leveldb": {
"source": "leveldb",
"static-libs-unix": [
"libleveldb.a"
],
"cpp-library": true
},
"libargon2": { "libargon2": {
"source": "libargon2", "source": "libargon2",
"static-libs-unix": [ "static-libs-unix": [
@@ -192,18 +182,6 @@
"libavif.a" "libavif.a"
] ]
}, },
"libcares": {
"source": "libcares",
"static-libs-unix": [
"libcares.a"
],
"headers-unix": [
"ares.h",
"ares_dns.h",
"ares_nameser.h",
"ares_rules.h"
]
},
"libevent": { "libevent": {
"source": "libevent", "source": "libevent",
"static-libs-unix": [ "static-libs-unix": [
@@ -234,17 +212,6 @@
"ffitarget.h" "ffitarget.h"
] ]
}, },
"libffi-win": {
"source": "libffi-win",
"static-libs-windows": [
"libffi.lib"
],
"headers-windows": [
"ffi.h",
"ffitarget.h",
"fficonfig.h"
]
},
"libiconv": { "libiconv": {
"source": "libiconv", "source": "libiconv",
"static-libs-unix": [ "static-libs-unix": [
@@ -257,13 +224,6 @@
"localcharset.h" "localcharset.h"
] ]
}, },
"libiconv-win": {
"source": "libiconv-win",
"static-libs-windows": [
"libiconv.lib",
"libiconv_a.lib"
]
},
"libjpeg": { "libjpeg": {
"source": "libjpeg", "source": "libjpeg",
"static-libs-unix": [ "static-libs-unix": [
@@ -271,10 +231,10 @@
"libturbojpeg.a" "libturbojpeg.a"
] ]
}, },
"liblz4": { "libmcrypt": {
"source": "liblz4", "source": "libmcrypt",
"static-libs-unix": [ "static-libs-unix": [
"liblz4.a" "libmcrypt.a"
] ]
}, },
"libmemcached": { "libmemcached": {
@@ -305,18 +265,6 @@
"zlib" "zlib"
] ]
}, },
"librabbitmq": {
"source": "librabbitmq",
"static-libs-unix": [
"librabbitmq.a"
],
"static-libs-windows": [
"rabbitmq.4.lib"
],
"lib-depends": [
"openssl"
]
},
"libsodium": { "libsodium": {
"source": "libsodium", "source": "libsodium",
"static-libs-unix": [ "static-libs-unix": [
@@ -343,27 +291,6 @@
"zlib" "zlib"
] ]
}, },
"libtiff": {
"source": "libtiff",
"static-libs-unix": [
"libtiff.a"
]
},
"libuuid": {
"source": "libuuid",
"static-libs-unix": [
"libuuid.a"
],
"headers": [
"uuid/uuid.h"
]
},
"libuv": {
"source": "libuv",
"static-libs-unix": [
"libuv.a"
]
},
"libwebp": { "libwebp": {
"source": "libwebp", "source": "libwebp",
"static-libs-unix": [ "static-libs-unix": [
@@ -380,25 +307,25 @@
"libxml2.a" "libxml2.a"
], ],
"static-libs-windows": [ "static-libs-windows": [
"libxml2s.lib", [
"libxml2_a.lib" "libxml2s.lib",
"libxml2_a.lib"
]
], ],
"headers": [ "headers": [
"libxml2" "libxml2"
], ],
"lib-depends-unix": [ "lib-depends": [
"libiconv" "libiconv",
],
"lib-suggests-unix": [
"xz",
"icu",
"zlib" "zlib"
], ],
"lib-depends-windows": [ "lib-suggests": [
"libiconv-win" "xz",
"icu"
], ],
"lib-suggests-windows": [ "lib-suggests-windows": [
"zlib" "icu",
"xz"
] ]
}, },
"libxslt": { "libxslt": {
@@ -448,6 +375,12 @@
"openssl" "openssl"
] ]
}, },
"mcrypt": {
"source": "mcrypt",
"static-libs-unix": [
"libmcrypt.a"
]
},
"ncurses": { "ncurses": {
"source": "ncurses", "source": "ncurses",
"static-libs-unix": [ "static-libs-unix": [
@@ -479,8 +412,10 @@
"libonig.a" "libonig.a"
], ],
"static-libs-windows": [ "static-libs-windows": [
"onig.lib", [
"onig_a.lib" "onig.lib",
"onig_a.lib"
]
], ],
"headers": [ "headers": [
"oniggnu.h", "oniggnu.h",
@@ -528,24 +463,6 @@
"zstd" "zstd"
] ]
}, },
"pthreads4w": {
"source": "pthreads4w",
"static-libs-windows": [
"libpthreadVC3.lib"
]
},
"qdbm": {
"source": "qdbm",
"static-libs-unix": [
"libqdbm.a"
],
"static-libs-windows": [
"qdbm_a.lib"
],
"headers-windows": [
"depot.h"
]
},
"readline": { "readline": {
"source": "readline", "source": "readline",
"static-libs-unix": [ "static-libs-unix": [
@@ -575,10 +492,7 @@
"static-libs-unix": [ "static-libs-unix": [
"libsqlite3.a" "libsqlite3.a"
], ],
"static-libs-windows": [ "headers-unix": [
"libsqlite3_a.lib"
],
"headers": [
"sqlite3.h", "sqlite3.h",
"sqlite3ext.h" "sqlite3ext.h"
] ]
@@ -589,17 +503,6 @@
"libtidy.a" "libtidy.a"
] ]
}, },
"unixodbc": {
"source": "unixodbc",
"static-libs-unix": [
"libodbc.a",
"libodbccr.a",
"libodbcinst.a"
],
"lib-depends": [
"libiconv"
]
},
"xz": { "xz": {
"source": "xz", "source": "xz",
"static-libs-unix": [ "static-libs-unix": [

View File

@@ -1,46 +0,0 @@
{
"musl-toolchain-aarch64-linux": {
"type": "url",
"url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/aarch64-musl-toolchain.tgz"
},
"musl-toolchain-x86_64-linux": {
"type": "url",
"url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/x86_64-musl-toolchain.tgz"
},
"nasm-x86_64-win": {
"type": "url",
"url": "https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/nasm-2.16.01-win64.zip",
"extract-files": {
"nasm-2.16.01/nasm.exe": "{php_sdk_path}/bin/nasm.exe",
"nasm-2.16.01/ndisasm.exe": "{php_sdk_path}/bin/ndisasm.exe"
}
},
"strawberry-perl-x86_64-win": {
"type": "url",
"url": "https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip"
},
"upx-aarch64-linux": {
"type": "ghrel",
"repo": "upx/upx",
"match": "upx.+-arm64_linux\\.tar\\.xz",
"extract-files": {
"upx": "{pkg_root_path}/bin/upx"
}
},
"upx-x86_64-linux": {
"type": "ghrel",
"repo": "upx/upx",
"match": "upx.+-amd64_linux\\.tar\\.xz",
"extract-files": {
"upx": "{pkg_root_path}/bin/upx"
}
},
"upx-x86_64-win": {
"type": "ghrel",
"repo": "upx/upx",
"match": "upx.+-win64\\.zip",
"extract-files": {
"upx-*-win64/upx.exe": "{pkg_root_path}/bin/upx.exe"
}
}
}

View File

@@ -6,16 +6,6 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"amqp": {
"type": "url",
"url": "https://pecl.php.net/get/amqp",
"path": "php-src/ext/amqp",
"filename": "amqp.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"apcu": { "apcu": {
"type": "url", "type": "url",
"url": "https://pecl.php.net/get/APCu", "url": "https://pecl.php.net/get/APCu",
@@ -40,7 +30,7 @@
"regex": "/href=\"(?<file>bzip2-(?<version>[^\"]+)\\.tar\\.gz)\"/", "regex": "/href=\"(?<file>bzip2-(?<version>[^\"]+)\\.tar\\.gz)\"/",
"license": { "license": {
"type": "text", "type": "text",
"text": "This program, \"bzip2\", the associated library \"libbzip2\", and all documentation, are copyright (C) 1996-2010 Julian R Seward. All rights reserved. \n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nJulian Seward, jseward@bzip.org bzip2/libbzip2 version 1.0.6 of 6 September 2010\n\nPATENTS: To the best of my knowledge, bzip2 and libbzip2 do not use any patented algorithms. However, I do not have the resources to carry out a patent search. Therefore I cannot give any guarantee of the above statement." "text": "This program, \"bzip2\", the associated library \"libbzip2\", and all documentation, are copyright (C) 1996-2010 Julian R Seward. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n 2. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n 4. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nJulian Seward, jseward@bzip.org bzip2/libbzip2 version 1.0.6 of 6 September 2010\n\nPATENTS: To the best of my knowledge, bzip2 and libbzip2 do not use any patented algorithms. However, I do not have the resources to carry out a patent search. Therefore I cannot give any guarantee of the above statement."
} }
}, },
"curl": { "curl": {
@@ -52,11 +42,11 @@
"path": "COPYING" "path": "COPYING"
} }
}, },
"ext-ds": { "ext-crypto": {
"type": "url", "type": "git",
"url": "https://pecl.php.net/get/ds", "path": "php-src/ext/crypto",
"path": "php-src/ext/ds", "rev": "master",
"filename": "ds.tgz", "url": "https://github.com/bukka/php-crypto.git",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "LICENSE"
@@ -100,11 +90,11 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"ext-simdjson": { "ext-morton": {
"type": "url", "type": "git",
"url": "https://pecl.php.net/get/simdjson", "path": "php-src/ext/morton",
"path": "php-src/ext/simdjson", "rev": "master",
"filename": "simdjson.tgz", "url": "https://github.com/pmmp/ext-morton.git",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "LICENSE"
@@ -130,26 +120,6 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"ext-uuid": {
"type": "url",
"url": "https://pecl.php.net/get/uuid",
"path": "php-src/ext/uuid",
"filename": "uuid.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-uv": {
"type": "url",
"url": "https://pecl.php.net/get/uv",
"path": "php-src/ext/uv",
"filename": "uv.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-zstd": { "ext-zstd": {
"type": "git", "type": "git",
"path": "php-src/ext/zstd", "path": "php-src/ext/zstd",
@@ -169,15 +139,6 @@
"path": "LICENSE.TXT" "path": "LICENSE.TXT"
} }
}, },
"gettext": {
"type": "filelist",
"url": "https://ftp.gnu.org/pub/gnu/gettext/",
"regex": "/href=\"(?<file>gettext-(?<version>[^\"]+)\\.tar\\.xz)\"/",
"license": {
"type": "file",
"path": "COPYING"
}
},
"gmp": { "gmp": {
"type": "ghtagtar", "type": "ghtagtar",
"repo": "alisw/GMP", "repo": "alisw/GMP",
@@ -196,10 +157,9 @@
} }
}, },
"igbinary": { "igbinary": {
"type": "url", "type": "ghtar",
"url": "https://pecl.php.net/get/igbinary",
"path": "php-src/ext/igbinary", "path": "php-src/ext/igbinary",
"filename": "igbinary.tgz", "repo": "igbinary/igbinary",
"license": { "license": {
"type": "file", "type": "file",
"path": "COPYING" "path": "COPYING"
@@ -241,10 +201,19 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"leveldb": {
"type": "git",
"rev": "mojang-compatible",
"url": "https://github.com/pmmp/leveldb.git",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"libargon2": { "libargon2": {
"type": "git", "type": "git",
"rev": "master", "rev": "master",
"url": "https://github.com/static-php/phc-winner-argon2", "url": "https://github.com/mpociot/phc-winner-argon2",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "LICENSE"
@@ -258,20 +227,6 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"libcares": {
"type": "ghrel",
"repo": "c-ares/c-ares",
"match": "c-ares-.+\\.tar\\.gz",
"alt": {
"type": "filelist",
"url": "https://c-ares.org/download/",
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/"
},
"license": {
"type": "file",
"path": "LICENSE.md"
}
},
"libevent": { "libevent": {
"type": "ghrel", "type": "ghrel",
"repo": "libevent/libevent", "repo": "libevent/libevent",
@@ -290,15 +245,6 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"libffi-win": {
"type": "git",
"rev": "master",
"url": "https://github.com/static-php/libffi-win.git",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"libiconv": { "libiconv": {
"type": "filelist", "type": "filelist",
"url": "https://ftp.gnu.org/gnu/libiconv/", "url": "https://ftp.gnu.org/gnu/libiconv/",
@@ -308,15 +254,6 @@
"path": "COPYING" "path": "COPYING"
} }
}, },
"libiconv-win": {
"type": "git",
"rev": "master",
"url": "https://github.com/static-php/libiconv-win.git",
"license": {
"type": "file",
"path": "source/COPYING"
}
},
"libjpeg": { "libjpeg": {
"type": "ghtar", "type": "ghtar",
"repo": "libjpeg-turbo/libjpeg-turbo", "repo": "libjpeg-turbo/libjpeg-turbo",
@@ -325,13 +262,12 @@
"path": "LICENSE.md" "path": "LICENSE.md"
} }
}, },
"liblz4": { "libmcrypt": {
"type": "ghrel", "type": "url",
"repo": "lz4/lz4", "url": "https://downloads.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz",
"match": "lz4-.+\\.tar\\.gz",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "COPYING"
} }
}, },
"libmemcached": { "libmemcached": {
@@ -352,19 +288,9 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"librabbitmq": {
"type": "git",
"url": "https://github.com/alanxz/rabbitmq-c.git",
"rev": "master",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"libsodium": { "libsodium": {
"type": "ghrel", "type": "url",
"repo": "jedisct1/libsodium", "url": "https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gz",
"match": "libsodium-\\d+(\\.\\d+)*\\.tar\\.gz",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "LICENSE"
@@ -379,38 +305,6 @@
"path": "COPYING" "path": "COPYING"
} }
}, },
"libtiff": {
"type": "filelist",
"url": "https://download.osgeo.org/libtiff/",
"regex": "/href=\"(?<file>tiff-(?<version>[^\"]+)\\.tar\\.xz)\"/",
"license": {
"type": "file",
"path": "LICENSE.md"
}
},
"libuuid": {
"type": "git",
"url": "https://github.com/static-php/libuuid.git",
"rev": "master",
"license": {
"type": "file",
"path": "COPYING"
}
},
"libuv": {
"type": "ghtar",
"repo": "libuv/libuv",
"license": [
{
"type": "file",
"path": "LICENSE"
},
{
"type": "file",
"path": "LICENSE-extra"
}
]
},
"libwebp": { "libwebp": {
"type": "url", "type": "url",
"url": "https://github.com/webmproject/libwebp/archive/refs/tags/v1.3.2.tar.gz", "url": "https://github.com/webmproject/libwebp/archive/refs/tags/v1.3.2.tar.gz",
@@ -421,7 +315,7 @@
}, },
"libxml2": { "libxml2": {
"type": "url", "type": "url",
"url": "https://github.com/GNOME/libxml2/archive/refs/tags/v2.12.5.tar.gz", "url": "https://github.com/GNOME/libxml2/archive/refs/tags/v2.9.14.tar.gz",
"license": { "license": {
"type": "file", "type": "file",
"path": "Copyright" "path": "Copyright"
@@ -454,6 +348,14 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"mcrypt": {
"type": "url",
"url": "https://downloads.sourceforge.net/project/mcrypt/MCrypt/2.6.8/mcrypt-2.6.8.tar.gz",
"license": {
"type": "file",
"path": "COPYING"
}
},
"memcached": { "memcached": {
"type": "url", "type": "url",
"url": "https://pecl.php.net/get/memcached", "url": "https://pecl.php.net/get/memcached",
@@ -468,7 +370,7 @@
"type": "git", "type": "git",
"path": "php-src/sapi/micro", "path": "php-src/sapi/micro",
"rev": "master", "rev": "master",
"url": "https://github.com/easysoft/phpmicro", "url": "https://github.com/static-php/phpmicro",
"license": { "license": {
"type": "file", "type": "file",
"path": "LICENSE" "path": "LICENSE"
@@ -520,26 +422,6 @@
"path": "LICENSE.txt" "path": "LICENSE.txt"
} }
}, },
"parallel": {
"type": "url",
"url": "https://pecl.php.net/get/parallel",
"path": "php-src/ext/parallel",
"filename": "parallel.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"pdo_sqlsrv": {
"type": "url",
"url": "https://pecl.php.net/get/pdo_sqlsrv",
"path": "php-src/ext/pdo_sqlsrv",
"filename": "pdo_sqlsrv.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"pkg-config": { "pkg-config": {
"type": "url", "type": "url",
"url": "https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz", "url": "https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz",
@@ -548,9 +430,37 @@
"path": "COPYING" "path": "COPYING"
} }
}, },
"pmmp-chunkutils2": {
"type": "ghtar",
"path": "php-src/ext/chunkutils2",
"repo": "pmmp/ext-chunkutils2",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"pmmp-leveldb": {
"type": "git",
"path": "php-src/ext/leveldb",
"rev": "pmmp-mojang-compatible",
"url": "https://github.com/pmmp/php-leveldb.git",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"pmmpthread": {
"type": "ghtar",
"path": "php-src/ext/pmmpthread",
"repo": "pmmp/ext-pmmpthread",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"postgresql": { "postgresql": {
"type": "url", "type": "url",
"url": "https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.bz2", "url": "https://ftp.postgresql.org/pub/source/v16.1/postgresql-16.1.tar.gz",
"license": { "license": {
"type": "file", "type": "file",
"path": "COPYRIGHT" "path": "COPYRIGHT"
@@ -566,24 +476,6 @@
"path": "LICENSE" "path": "LICENSE"
} }
}, },
"pthreads4w": {
"type": "git",
"rev": "master",
"url": "https://git.code.sf.net/p/pthreads4w/code",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"qdbm": {
"type": "git",
"url": "https://github.com/static-php/qdbm.git",
"rev": "main",
"license": {
"type": "file",
"path": "COPYING"
}
},
"rar": { "rar": {
"type": "git", "type": "git",
"url": "https://github.com/static-php/php-rar.git", "url": "https://github.com/static-php/php-rar.git",
@@ -631,16 +523,6 @@
"text": "The author disclaims copyright to this source code. In place of\na legal notice, here is a blessing:\n\n * May you do good and not evil.\n * May you find forgiveness for yourself and forgive others.\n * May you share freely, never taking more than you give." "text": "The author disclaims copyright to this source code. In place of\na legal notice, here is a blessing:\n\n * May you do good and not evil.\n * May you find forgiveness for yourself and forgive others.\n * May you share freely, never taking more than you give."
} }
}, },
"sqlsrv": {
"type": "url",
"url": "https://pecl.php.net/get/sqlsrv",
"path": "php-src/ext/sqlsrv",
"filename": "sqlsrv.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"swoole": { "swoole": {
"type": "ghtar", "type": "ghtar",
"path": "php-src/ext/swoole", "path": "php-src/ext/swoole",
@@ -670,24 +552,6 @@
"path": "README/LICENSE.md" "path": "README/LICENSE.md"
} }
}, },
"unixodbc": {
"type": "url",
"url": "https://www.unixodbc.org/unixODBC-2.3.12.tar.gz",
"license": {
"type": "file",
"path": "COPYING"
}
},
"xhprof": {
"type": "url",
"url": "https://pecl.php.net/get/xhprof",
"path": "php-src/ext/xhprof-src",
"filename": "xhprof.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"xlswriter": { "xlswriter": {
"type": "url", "type": "url",
"url": "https://pecl.php.net/get/xlswriter", "url": "https://pecl.php.net/get/xlswriter",
@@ -699,23 +563,14 @@
} }
}, },
"xz": { "xz": {
"type": "url", "type": "filelist",
"url": "https://fossies.org/linux/misc/xz-5.4.6.tar.xz", "url": "https://tukaani.org/xz/",
"regex": "/href=\"(?<file>xz-(?<version>[^\"]+)\\.tar\\.xz)\"/",
"license": { "license": {
"type": "file", "type": "file",
"path": "COPYING" "path": "COPYING"
} }
}, },
"yac": {
"type": "url",
"url": "https://pecl.php.net/get/yac",
"path": "php-src/ext/yac",
"filename": "yac.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"yaml": { "yaml": {
"type": "git", "type": "git",
"path": "php-src/ext/yaml", "path": "php-src/ext/yaml",

View File

@@ -8,11 +8,5 @@ parameters:
- '#Unsafe usage of new static#' - '#Unsafe usage of new static#'
- '#class Fiber#' - '#class Fiber#'
- '#Attribute class JetBrains\\PhpStorm\\ArrayShape does not exist#' - '#Attribute class JetBrains\\PhpStorm\\ArrayShape does not exist#'
- '#Function Swoole\\Coroutine\\run not found.#'
dynamicConstantNames: dynamicConstantNames:
- PHP_OS_FAMILY - PHP_OS_FAMILY
excludePaths:
analyseAndScan:
- ./src/globals/ext-tests/swoole.php
- ./src/globals/ext-tests/swoole.phpt
- ./src/globals/test-extensions.php

View File

@@ -6,26 +6,24 @@ namespace SPC;
use SPC\command\BuildCliCommand; use SPC\command\BuildCliCommand;
use SPC\command\BuildLibsCommand; use SPC\command\BuildLibsCommand;
use SPC\command\DeleteDownloadCommand;
use SPC\command\dev\AllExtCommand; use SPC\command\dev\AllExtCommand;
use SPC\command\dev\GenerateExtDocCommand;
use SPC\command\dev\PhpVerCommand; use SPC\command\dev\PhpVerCommand;
use SPC\command\dev\SortConfigCommand; use SPC\command\dev\SortConfigCommand;
use SPC\command\DoctorCommand; use SPC\command\DoctorCommand;
use SPC\command\DownloadCommand; use SPC\command\DownloadCommand;
use SPC\command\DumpLicenseCommand; use SPC\command\DumpLicenseCommand;
use SPC\command\ExtractCommand; use SPC\command\ExtractCommand;
use SPC\command\InstallPkgCommand;
use SPC\command\MicroCombineCommand; use SPC\command\MicroCombineCommand;
use SPC\command\SwitchPhpVersionCommand;
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
/** /**
* static-php-cli console app entry * static-php-cli console app entry
*/ */
final class ConsoleApplication extends Application final class ConsoleApplication extends Application
{ {
public const VERSION = '2.2.2'; public const VERSION = '2.0.0-rc9';
public function __construct() public function __construct()
{ {
@@ -33,24 +31,24 @@ final class ConsoleApplication extends Application
$this->addCommands( $this->addCommands(
[ [
// Common commands
new BuildCliCommand(), new BuildCliCommand(),
new BuildLibsCommand(), new BuildLibsCommand(),
new DoctorCommand(), new DoctorCommand(),
new DownloadCommand(), new DownloadCommand(),
new InstallPkgCommand(),
new DeleteDownloadCommand(),
new DumpLicenseCommand(), new DumpLicenseCommand(),
new ExtractCommand(), new ExtractCommand(),
new MicroCombineCommand(), new MicroCombineCommand(),
new SwitchPhpVersionCommand(),
// Dev commands // Dev commands
new AllExtCommand(), new AllExtCommand(),
new PhpVerCommand(), new PhpVerCommand(),
new SortConfigCommand(), new SortConfigCommand(),
new GenerateExtDocCommand(),
] ]
); );
} }
protected function getDefaultCommands(): array
{
return [new HelpCommand(), new ListCommand()];
}
} }

View File

@@ -4,14 +4,14 @@ declare(strict_types=1);
namespace SPC\builder; namespace SPC\builder;
use SPC\exception\ExceptionHandler;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\Config; use SPC\store\Config;
use SPC\store\FileSystem; use SPC\store\FileSystem;
use SPC\store\SourceManager; use SPC\store\SourceExtractor;
use SPC\util\CustomExt; use SPC\util\CustomExt;
use SPC\util\DependencyUtil;
abstract class BuilderBase abstract class BuilderBase
{ {
@@ -30,29 +30,59 @@ abstract class BuilderBase
/** @var array<string, mixed> compile options */ /** @var array<string, mixed> compile options */
protected array $options = []; protected array $options = [];
/** @var string patch point name */
protected string $patch_point = '';
/**
* Convert libraries to class
*
* @param array<string> $sorted_libraries Libraries to build (if not empty, must sort first)
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
* @internal
*/
abstract public function proveLibs(array $sorted_libraries);
/** /**
* Build libraries * Build libraries
* *
* @param array<string> $libraries Libraries to build
* @throws FileSystemException * @throws FileSystemException
* @throws RuntimeException * @throws RuntimeException
* @throws WrongUsageException * @throws WrongUsageException
*/ */
public function buildLibs(): void public function buildLibs(array $libraries): void
{ {
// search all supported libs
$support_lib_list = [];
$classes = FileSystem::getClassesPsr4(
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
'SPC\\builder\\' . osfamily2dir() . '\\library'
);
foreach ($classes as $class) {
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {
$support_lib_list[$class::NAME] = $class;
}
}
// if no libs specified, compile all supported libs
if ($libraries === [] && $this->isLibsOnly()) {
$libraries = array_keys($support_lib_list);
}
// pkg-config must be compiled first, whether it is specified or not
if (!in_array('pkg-config', $libraries)) {
array_unshift($libraries, 'pkg-config');
}
// append dependencies
$libraries = DependencyUtil::getLibsByDeps($libraries);
// add lib object for builder
foreach ($libraries as $library) {
// if some libs are not supported (but in config "lib.json", throw exception)
if (!isset($support_lib_list[$library])) {
throw new WrongUsageException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
}
$lib = new ($support_lib_list[$library])($this);
$this->addLib($lib);
}
// calculate and check dependencies
foreach ($this->libs as $lib) {
$lib->calcDependency();
}
// extract sources
SourceExtractor::initSource(libs: $libraries);
// build all libs // build all libs
foreach ($this->libs as $lib) { foreach ($this->libs as $lib) {
match ($lib->tryBuild($this->getOption('rebuild', false))) { match ($lib->tryBuild($this->getOption('rebuild', false))) {
@@ -144,8 +174,6 @@ abstract class BuilderBase
/** /**
* Set libs only mode. * Set libs only mode.
*
* @internal
*/ */
public function setLibsOnly(bool $status = true): void public function setLibsOnly(bool $status = true): void
{ {
@@ -159,22 +187,15 @@ abstract class BuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws \ReflectionException * @throws \ReflectionException
* @throws WrongUsageException * @throws WrongUsageException
* @internal
*/ */
public function proveExts(array $extensions): void public function proveExts(array $extensions): void
{ {
CustomExt::loadCustomExt(); CustomExt::loadCustomExt();
$this->emitPatchPoint('before-php-extract'); SourceExtractor::initSource(sources: ['php-src']);
SourceManager::initSource(sources: ['php-src']);
$this->emitPatchPoint('after-php-extract');
if ($this->getPHPVersionID() >= 80000) { if ($this->getPHPVersionID() >= 80000) {
$this->emitPatchPoint('before-micro-extract'); SourceExtractor::initSource(sources: ['micro']);
SourceManager::initSource(sources: ['micro']);
$this->emitPatchPoint('after-micro-extract');
} }
$this->emitPatchPoint('before-exts-extract'); SourceExtractor::initSource(exts: $extensions);
SourceManager::initSource(exts: $extensions);
$this->emitPatchPoint('after-exts-extract');
foreach ($extensions as $extension) { foreach ($extensions as $extension) {
$class = CustomExt::getExtClass($extension); $class = CustomExt::getExtClass($extension);
$ext = new $class($extension, $this); $ext = new $class($extension, $this);
@@ -204,10 +225,9 @@ abstract class BuilderBase
{ {
$ret = []; $ret = [];
foreach ($this->exts as $ext) { foreach ($this->exts as $ext) {
logger()->info($ext->getName() . ' is using ' . $ext->getConfigureArg());
$ret[] = trim($ext->getConfigureArg()); $ret[] = trim($ext->getConfigureArg());
} }
logger()->debug('Using configure: ' . implode(' ', $ret)); logger()->info('Using configure: ' . implode(' ', $ret));
return implode(' ', $ret); return implode(' ', $ret);
} }
@@ -252,48 +272,6 @@ abstract class BuilderBase
throw new RuntimeException('PHP version file format is malformed, please remove it and download again'); throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
} }
/**
* Get PHP version from archive file name.
*
* @param null|string $file php-*.*.*.tar.gz filename, read from lockfile if empty
*/
public function getPHPVersionFromArchive(?string $file = null): false|string
{
if ($file === null) {
$lock = file_exists(DOWNLOAD_PATH . '/.lock.json') ? file_get_contents(DOWNLOAD_PATH . '/.lock.json') : false;
if ($lock === false) {
return false;
}
$lock = json_decode($lock, true);
$file = $lock['php-src']['filename'] ?? null;
if ($file === null) {
return false;
}
}
if (preg_match('/php-(\d+\.\d+\.\d+)/', $file, $match)) {
return $match[1];
}
return false;
}
public function getMicroVersion(): false|string
{
$file = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/php_micro.h');
if (!file_exists($file)) {
return false;
}
$content = file_get_contents($file);
$ver = '';
preg_match('/#define PHP_MICRO_VER_MAJ (\d)/m', $content, $match);
$ver .= $match[1] . '.';
preg_match('/#define PHP_MICRO_VER_MIN (\d)/m', $content, $match);
$ver .= $match[1] . '.';
preg_match('/#define PHP_MICRO_VER_PAT (\d)/m', $content, $match);
$ver .= $match[1];
return $ver;
}
/** /**
* Get build type name string to display. * Get build type name string to display.
* *
@@ -366,52 +344,6 @@ abstract class BuilderBase
return implode(' ', $env); return implode(' ', $env);
} }
/**
* Get builder patch point name.
*/
public function getPatchPoint(): string
{
return $this->patch_point;
}
/**
* Validate libs and exts can be compiled successfully in current environment
*/
public function validateLibsAndExts(): void
{
foreach ($this->libs as $lib) {
$lib->validate();
}
foreach ($this->exts as $ext) {
$ext->validate();
}
}
public function emitPatchPoint(string $point_name): void
{
$this->patch_point = $point_name;
if (($patches = $this->getOption('with-added-patch', [])) === []) {
return;
}
foreach ($patches as $patch) {
try {
if (!file_exists($patch)) {
throw new RuntimeException("Additional patch script file {$patch} not found!");
}
logger()->debug('Running additional patch script: ' . $patch);
require $patch;
} catch (\Throwable $e) {
logger()->critical('Patch script ' . $patch . ' failed to run.');
if ($this->getOption('debug')) {
ExceptionHandler::getInstance()->handle($e);
} else {
logger()->critical('Please check with --debug option to see more details.');
}
}
}
}
/** /**
* Check if all libs are downloaded. * Check if all libs are downloaded.
* If not, throw exception. * If not, throw exception.
@@ -435,44 +367,4 @@ abstract class BuilderBase
); );
} }
} }
/**
* Generate micro extension test php code.
*/
protected function generateMicroExtTests(): string
{
$php = "<?php\n\necho '[micro-test-start]' . PHP_EOL;\n";
foreach ($this->getExts() as $ext) {
$ext_name = $ext->getDistName();
if (!empty($ext_name)) {
$php .= "echo 'Running micro with {$ext_name} test' . PHP_EOL;\n";
$php .= "assert(extension_loaded('{$ext_name}'));\n\n";
}
}
$php .= "echo '[micro-test-end]';\n";
return $php;
}
protected function getMicroTestTasks(): array
{
return [
'micro_ext_test' => [
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests()),
'conditions' => [
function ($ret) { return $ret === 0; },
function ($ret, $out) {
$raw_out = trim(implode('', $out));
return str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
},
],
],
'micro_zend_bug_test' => [
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "hello";' : file_get_contents(ROOT_DIR . '/src/globals/common-tests/micro_zend_mm_heap_corrupted.txt')),
'conditions' => [
function ($ret) { return $ret === 0; },
],
],
];
}
} }

View File

@@ -7,7 +7,6 @@ namespace SPC\builder;
use SPC\builder\freebsd\BSDBuilder; use SPC\builder\freebsd\BSDBuilder;
use SPC\builder\linux\LinuxBuilder; use SPC\builder\linux\LinuxBuilder;
use SPC\builder\macos\MacOSBuilder; use SPC\builder\macos\MacOSBuilder;
use SPC\builder\windows\WindowsBuilder;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
@@ -18,8 +17,6 @@ use Symfony\Component\Console\Input\InputInterface;
*/ */
class BuilderProvider class BuilderProvider
{ {
private static ?BuilderBase $builder = null;
/** /**
* @throws FileSystemException * @throws FileSystemException
* @throws RuntimeException * @throws RuntimeException
@@ -27,26 +24,16 @@ class BuilderProvider
*/ */
public static function makeBuilderByInput(InputInterface $input): BuilderBase public static function makeBuilderByInput(InputInterface $input): BuilderBase
{ {
ini_set('memory_limit', '2G'); return match (PHP_OS_FAMILY) {
// 'Windows' => new WindowsBuilder(
self::$builder = match (PHP_OS_FAMILY) { // binary_sdk_dir: $input->getOption('with-sdk-binary-dir'),
'Windows' => new WindowsBuilder($input->getOptions()), // vs_ver: $input->getOption('vs-ver'),
// arch: $input->getOption('arch'),
// ),
'Darwin' => new MacOSBuilder($input->getOptions()), 'Darwin' => new MacOSBuilder($input->getOptions()),
'Linux' => new LinuxBuilder($input->getOptions()), 'Linux' => new LinuxBuilder($input->getOptions()),
'BSD' => new BSDBuilder($input->getOptions()), 'BSD' => new BSDBuilder($input->getOptions()),
default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'), default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'),
}; };
return self::$builder;
}
/**
* @throws WrongUsageException
*/
public static function getBuilder(): BuilderBase
{
if (self::$builder === null) {
throw new WrongUsageException('Builder has not been initialized');
}
return self::$builder;
} }
} }

View File

@@ -8,7 +8,6 @@ use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\Config; use SPC\store\Config;
use SPC\store\FileSystem;
class Extension class Extension
{ {
@@ -43,7 +42,7 @@ class Extension
$arg = $this->getEnableArg(); $arg = $this->getEnableArg();
switch (PHP_OS_FAMILY) { switch (PHP_OS_FAMILY) {
case 'Windows': case 'Windows':
$arg .= $this->getWindowsConfigureArg(); $arg = $this->getWindowsConfigureArg();
break; break;
case 'Darwin': case 'Darwin':
case 'Linux': case 'Linux':
@@ -165,69 +164,34 @@ class Extension
} }
/** /**
* Run compile check if build target is cli
* If you need to run some check, overwrite this or add your assert in src/globals/tests/{extension_name}.php
* If check failed, throw RuntimeException
*
* @throws RuntimeException * @throws RuntimeException
*/ */
public function runCliCheckUnix(): void public function runCliCheck(): void
{ {
// Run compile check if build target is cli
// If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php
// If check failed, throw RuntimeException
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false); [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
} }
if (file_exists(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php')) { if (file_exists(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')) {
// Trim additional content & escape special characters to allow inline usage // Trim additional content & escape special characters to allow inline usage
$test = str_replace( $test = str_replace(
['<?php', 'declare(strict_types=1);', "\n", '"', '$'], ['<?php', 'declare(strict_types=1);', "\n", '"', '$'],
['', '', '', '\"', '\$'], ['', '', '', '\"', '\$'],
file_get_contents(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php') file_get_contents(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')
); );
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"'); [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
if ($ret !== 0) {
if ($this->builder->getOption('debug')) {
var_dump($out);
}
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
}
}
}
/**
* @throws RuntimeException
*/
public function runCliCheckWindows(): void
{
// Run compile check if build target is cli
// If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php
// If check failed, throw RuntimeException
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (file_exists(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php'))) {
// Trim additional content & escape special characters to allow inline usage
$test = str_replace(
['<?php', 'declare(strict_types=1);', "\n", '"', '$'],
['', '', '', '\"', '$'],
file_get_contents(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php'))
);
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -r "' . trim($test) . '"');
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check'); throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
} }
} }
} }
public function validate(): void
{
// do nothing, just throw wrong usage exception if not valid
}
/** /**
* @throws RuntimeException * @throws RuntimeException
*/ */

View File

@@ -140,9 +140,7 @@ abstract class LibraryBase
if (!$this->patched && $this->patchBeforeBuild()) { if (!$this->patched && $this->patchBeforeBuild()) {
file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!'); file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!');
} }
$this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build');
$this->build(); $this->build();
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-build');
return BUILD_STATUS_OK; return BUILD_STATUS_OK;
} }
@@ -177,11 +175,6 @@ abstract class LibraryBase
return false; return false;
} }
public function validate(): void
{
// do nothing, just throw wrong usage exception if not valid
}
/** /**
* Get current builder object. * Get current builder object.
*/ */
@@ -211,9 +204,4 @@ abstract class LibraryBase
} }
logger()->debug('enabling ' . static::NAME . " without {$name}"); logger()->debug('enabling ' . static::NAME . " without {$name}");
} }
protected function getSnakeCaseName(): string
{
return str_replace('-', '_', static::NAME);
}
} }

View File

@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('amqp')]
class amqp extends Extension
{
public function patchBeforeMake(): bool
{
if (PHP_OS_FAMILY === 'Windows') {
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp.h', '/^#warning.*/m', '');
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_framing.h', '/^#warning.*/m', '');
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_ssl_socket.h', '/^#warning.*/m', '');
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_tcp_socket.h', '/^#warning.*/m', '');
return true;
}
return false;
}
public function getUnixConfigureArg(): string
{
return '--with-amqp --with-librabbitmq-dir=' . BUILD_ROOT_PATH;
}
public function getWindowsConfigureArg(): string
{
return '--with-amqp';
}
}

View File

@@ -1,24 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('dba')]
class dba extends Extension
{
public function getUnixConfigureArg(): string
{
$qdbm = $this->builder->getLib('qdbm') ? (' --with-qdbm=' . BUILD_ROOT_PATH) : '';
return '--enable-dba' . $qdbm;
}
public function getWindowsConfigureArg(): string
{
$qdbm = $this->builder->getLib('qdbm') ? ' --with-qdbm' : '';
return '--with-dba' . $qdbm;
}
}

View File

@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace SPC\builder\extension; namespace SPC\builder\extension;
use SPC\builder\Extension; use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\store\FileSystem; use SPC\store\FileSystem;
use SPC\util\CustomExt; use SPC\util\CustomExt;
@@ -35,16 +34,4 @@ class event extends Extension
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-levent_openssl/', $this->getLibFilesString()); FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-levent_openssl/', $this->getLibFilesString());
return true; return true;
} }
/**
* @throws FileSystemException
*/
public function patchBeforeMake(): bool
{
// Prevent event extension compile error on macOS
if ($this->builder instanceof MacOSBuilder) {
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_OPENPTY 1$/m', '');
}
return true;
}
} }

View File

@@ -14,9 +14,4 @@ class ffi extends Extension
{ {
return '--with-ffi --enable-zend-signals'; return '--with-ffi --enable-zend-signals';
} }
public function getWindowsConfigureArg(): string
{
return '--with-ffi';
}
} }

View File

@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\builder\macos\MacOSBuilder;
use SPC\exception\FileSystemException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('gettext')]
class gettext extends Extension
{
/**
* @throws FileSystemException
*/
public function patchBeforeBuildconf(): bool
{
if ($this->builder instanceof MacOSBuilder) {
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/gettext/config.m4', 'AC_CHECK_LIB($GETTEXT_CHECK_IN_LIB', 'AC_CHECK_LIB(intl');
}
return true;
}
/**
* @throws WrongUsageException
* @throws FileSystemException
*/
public function patchBeforeConfigure(): bool
{
if ($this->builder instanceof MacOSBuilder) {
$frameworks = ' ' . $this->builder->getFrameworks(true) . ' ';
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lintl', $this->getLibFilesString() . $frameworks);
}
return true;
}
}

View File

@@ -34,9 +34,4 @@ class glfw extends Extension
{ {
return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH; return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH;
} }
public function getWindowsConfigureArg(): string
{
return '--enable-glfw=static';
}
} }

View File

@@ -14,11 +14,11 @@ class imagick extends Extension
public function patchBeforeMake(): bool public function patchBeforeMake(): bool
{ {
// imagick may call omp_pause_all which requires -lgomp // imagick may call omp_pause_all which requires -lgomp
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; $extra_libs = $this->builder->getOption('extra-libs', '');
if ($this->builder instanceof LinuxBuilder) { if ($this->builder instanceof LinuxBuilder) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . '-lgomp '; $extra_libs .= ' -lgomp ';
} }
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); $this->builder->setOption('extra-libs', $extra_libs);
return true; return true;
} }

View File

@@ -14,15 +14,11 @@ class imap extends Extension
/** /**
* @throws WrongUsageException * @throws WrongUsageException
*/ */
public function validate(): void public function getUnixConfigureArg(): string
{ {
if ($this->builder->getOption('enable-zts')) { if ($this->builder->getOption('enable-zts')) {
throw new WrongUsageException('ext-imap is not thread safe, do not build it with ZTS builds'); throw new WrongUsageException('ext-imap is not thread safe, do not build it with ZTS builds');
} }
}
public function getUnixConfigureArg(): string
{
$arg = '--with-imap=' . BUILD_ROOT_PATH; $arg = '--with-imap=' . BUILD_ROOT_PATH;
if ($this->builder->getLib('openssl') !== null) { if ($this->builder->getLib('openssl') !== null) {
$arg .= ' --with-imap-ssl=' . BUILD_ROOT_PATH; $arg .= ' --with-imap-ssl=' . BUILD_ROOT_PATH;

View File

@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('intl')]
class intl extends Extension
{
public function patchBeforeBuildconf(): bool
{
// TODO: remove the following line when https://github.com/php/php-src/pull/14002 will be released
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/intl/config.m4', 'PHP_CXX_COMPILE_STDCXX(11', 'PHP_CXX_COMPILE_STDCXX(17');
// Also need to use clang++ -std=c++17 to force override the default C++ standard
if (is_string($env = getenv('CXX')) && !str_contains($env, 'std=c++17')) {
f_putenv('CXX=' . $env . ' -std=c++17');
} else {
f_putenv('CXX=clang++ -std=c++17');
}
return true;
}
}

View File

@@ -1,23 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('ldap')]
class ldap extends Extension
{
public function patchBeforeConfigure(): bool
{
$output = shell()->execWithResult('$PKG_CONFIG --libs-only-l --static ldap');
if (!empty($output[1][0])) {
$libs = $output[1][0];
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lldap ', $libs . ' ');
}
return true;
}
}

View File

@@ -11,11 +11,6 @@ use SPC\util\CustomExt;
#[CustomExt('mbregex')] #[CustomExt('mbregex')]
class mbregex extends Extension class mbregex extends Extension
{ {
public function getDistName(): string
{
return 'mbstring';
}
public function getConfigureArg(): string public function getConfigureArg(): string
{ {
return ''; return '';
@@ -24,23 +19,11 @@ class mbregex extends Extension
/** /**
* mbregex is not an extension, we need to overwrite the default check. * mbregex is not an extension, we need to overwrite the default check.
*/ */
public function runCliCheckUnix(): void public function runCliCheck(): void
{ {
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring" | grep regex', false); [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring" | grep regex', false);
if ($ret !== 0) { if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !'); throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !');
} }
} }
public function runCliCheckWindows(): void
{
[$ret, $out] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring"', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli does not contain mbstring !');
}
$out = implode("\n", $out);
if (!str_contains($out, 'regex')) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !');
}
}
} }

View File

@@ -10,13 +10,11 @@ use SPC\util\CustomExt;
#[CustomExt('mbstring')] #[CustomExt('mbstring')]
class mbstring extends Extension class mbstring extends Extension
{ {
public function getConfigureArg(): string public function getUnixConfigureArg(): string
{ {
$arg = '--enable-mbstring'; $arg = '--enable-mbstring';
if ($this->builder->getExt('mbregex') === null) { if ($this->builder->getExt('mbregex') === null) {
$arg .= ' --disable-mbregex'; $arg .= ' --disable-mbregex';
} else {
$arg .= ' --enable-mbregex';
} }
return $arg; return $arg;
} }

View File

@@ -16,15 +16,11 @@ class opcache extends Extension
* @throws WrongUsageException * @throws WrongUsageException
* @throws RuntimeException * @throws RuntimeException
*/ */
public function validate(): void
{
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
throw new WrongUsageException('Statically compiled PHP with Zend Opcache only available for PHP >= 8.0 !');
}
}
public function getUnixConfigureArg(): string public function getUnixConfigureArg(): string
{ {
if ($this->builder->getPHPVersionID() < 80000) {
throw new WrongUsageException('Statically compiled PHP with Zend Opcache only available for PHP >= 8.0 !');
}
return '--enable-opcache'; return '--enable-opcache';
} }

View File

@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\WrongUsageException;
use SPC\util\CustomExt;
#[CustomExt('parallel')]
class parallel extends Extension
{
public function validate(): void
{
if (!$this->builder->getOption('enable-zts')) {
throw new WrongUsageException('ext-parallel must be built with ZTS builds. Use "--enable-zts" option!');
}
}
}

View File

@@ -11,12 +11,7 @@ use SPC\util\CustomExt;
#[CustomExt('password-argon2')] #[CustomExt('password-argon2')]
class password_argon2 extends Extension class password_argon2 extends Extension
{ {
public function getDistName(): string public function runCliCheck(): void
{
return '';
}
public function runCliCheckUnix(): void
{ {
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "assert(defined(\'PASSWORD_ARGON2I\'));"'); [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "assert(defined(\'PASSWORD_ARGON2I\'));"');
if ($ret !== 0) { if ($ret !== 0) {

View File

@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('pmmp-chunkutils2')]
class pmmp_chunkutils2 extends Extension
{
public function getDistName(): string
{
return 'chunkutils2';
}
public function getUnixConfigureArg(): string
{
return '--enable-chunkutils2';
}
}

View File

@@ -1,19 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('protobuf')]
class protobuf extends Extension
{
public function validate(): void
{
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
throw new \RuntimeException('The latest protobuf extension requires PHP 8.0 or later');
}
}
}

View File

@@ -13,14 +13,14 @@ class redis extends Extension
public function getUnixConfigureArg(): string public function getUnixConfigureArg(): string
{ {
$arg = '--enable-redis'; $arg = '--enable-redis';
$arg .= $this->builder->getExt('session') ? ' --enable-redis-session' : ' --disable-redis-session'; if (!$this->builder->getExt('session')) {
$arg .= $this->builder->getExt('igbinary') ? ' --enable-redis-igbinary' : ' --disable-redis-igbinary'; $arg .= ' --disable-redis-session';
} else {
$arg .= ' --enable-redis-session';
}
if ($this->builder->getLib('zstd')) { if ($this->builder->getLib('zstd')) {
$arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"'; $arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"';
} }
if ($this->builder->getLib('liblz4')) {
$arg .= ' --enable-redis-lz4 --with-liblz4="' . BUILD_ROOT_PATH . '"';
}
return $arg; return $arg;
} }
} }

View File

@@ -1,34 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('simdjson')]
class simdjson extends Extension
{
public function patchBeforeBuildconf(): bool
{
$php_ver = $this->builder->getPHPVersionID();
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/ext/simdjson/config.m4',
'/php_version=(`.*`)$/m',
'php_version=' . strval($php_ver)
);
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/simdjson/config.m4',
'if test -z "$PHP_CONFIG"; then',
'if false; then'
);
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/simdjson/config.w32',
"'yes',",
'PHP_SIMDJSON_SHARED,'
);
return true;
}
}

View File

@@ -12,31 +12,13 @@ class swoole extends Extension
{ {
public function getUnixConfigureArg(): string public function getUnixConfigureArg(): string
{ {
// enable swoole
$arg = '--enable-swoole'; $arg = '--enable-swoole';
// pgsql hook is buggy for static php
// commonly-used feature: coroutine-time, disable-thread-context $arg .= ' --disable-swoole-pgsql';
$arg .= ' --enable-swoole-coro-time --disable-thread-context'; $arg .= $this->builder->getLib('openssl') ? ' --enable-openssl' : ' --disable-openssl --without-openssl';
$arg .= $this->builder->getLib('brotli') ? (' --enable-brotli --with-brotli-dir=' . BUILD_ROOT_PATH) : ' --disable-brotli';
// required feature: curl, openssl (but curl hook is buggy for php 8.0) // swoole curl hook is buggy for php 8.0
$arg .= $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl'; $arg .= $this->builder->getExt('curl') && $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl';
$arg .= ' --enable-openssl';
// additional feature: c-ares, brotli, nghttp2 (can be disabled, but we enable it by default in config to support full network feature)
$arg .= $this->builder->getLib('libcares') ? ' --enable-cares' : '';
$arg .= $this->builder->getLib('brotli') ? (' --with-brotli-dir=' . BUILD_ROOT_PATH) : '';
$arg .= $this->builder->getLib('nghttp2') ? (' --with-nghttp2-dir=' . BUILD_ROOT_PATH) : '';
// additional feature: swoole-pgsql, it should depend on lib [postgresql], but it will lack of CFLAGS etc.
// so this is a tricky way (enable ext [pgsql,pdo] to add postgresql hook and pdo_pgsql support)
$arg .= $this->builder->getExt('swoole-hook-pgsql') ? '' : ' --disable-swoole-pgsql';
// enable this feature , need remove pdo_sqlite
// more info : https://wenda.swoole.com/detail/109023
$arg .= $this->builder->getExt('swoole-hook-sqlite') ? '' : ' --disable-swoole-sqlite';
// enable this feature , need stop pdo_*
// $arg .= $this->builder->getLib('unixodbc') ? ' --with-swoole-odbc=unixODBC,' : ' ';
return $arg; return $arg;
} }
} }

View File

@@ -1,41 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\util\CustomExt;
#[CustomExt('swoole-hook-mysql')]
class swoole_hook_mysql extends Extension
{
public function getDistName(): string
{
return 'swoole';
}
public function getUnixConfigureArg(): string
{
// pdo_mysql doesn't need to be disabled
// enable swoole-hook-mysql will enable mysqli, pdo, pdo_mysql, we don't need to add any additional options
return '';
}
public function runCliCheckUnix(): void
{
// skip if not enable swoole
if ($this->builder->getExt('swoole') === null) {
return;
}
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
$out = implode('', $out);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (!str_contains($out, 'mysqlnd')) {
throw new RuntimeException('swoole mysql hook is not enabled correctly.');
}
}
}

View File

@@ -1,49 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\CustomExt;
#[CustomExt('swoole-hook-pgsql')]
class swoole_hook_pgsql extends Extension
{
public function getDistName(): string
{
return 'swoole';
}
public function validate(): void
{
// pdo_pgsql need to be disabled
if ($this->builder->getExt('pdo_pgsql') !== null) {
throw new WrongUsageException('swoole-hook-pgsql provides pdo_pgsql, if you enable pgsql hook for swoole, you must remove pdo_pgsql extension.');
}
}
public function getUnixConfigureArg(): string
{
// enable swoole pgsql hook
return '--enable-swoole-pgsql';
}
public function runCliCheckUnix(): void
{
// skip if not enable swoole
if ($this->builder->getExt('swoole') === null) {
return;
}
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
$out = implode('', $out);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (!str_contains($out, 'coroutine_pgsql')) {
throw new RuntimeException('swoole pgsql hook is not enabled correctly.');
}
}
}

View File

@@ -1,49 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\CustomExt;
#[CustomExt('swoole-hook-sqlite')]
class swoole_hook_sqlite extends Extension
{
public function getDistName(): string
{
return 'swoole';
}
public function validate(): void
{
// pdo_pgsql need to be disabled
if ($this->builder->getExt('pdo_sqlite') !== null) {
throw new WrongUsageException('swoole-hook-sqlite provides pdo_sqlite, if you enable sqlite hook for swoole, you must remove pdo_sqlite extension.');
}
}
public function getUnixConfigureArg(): string
{
// enable swoole pgsql hook
return '--enable-swoole-sqlite';
}
public function runCliCheckUnix(): void
{
// skip if not enable swoole
if ($this->builder->getExt('swoole') === null) {
return;
}
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "swoole"', false);
$out = implode('', $out);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (!str_contains($out, 'coroutine_sqlite')) {
throw new RuntimeException('swoole sqlite hook is not enabled correctly.');
}
}
}

View File

@@ -11,13 +11,6 @@ use SPC\util\CustomExt;
#[CustomExt('swow')] #[CustomExt('swow')]
class swow extends Extension class swow extends Extension
{ {
public function validate(): void
{
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
throw new RuntimeException('The latest swow extension requires PHP 8.0 or later');
}
}
public function getUnixConfigureArg(): string public function getUnixConfigureArg(): string
{ {
$arg = '--enable-swow'; $arg = '--enable-swow';

View File

@@ -1,19 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\util\CustomExt;
#[CustomExt('uv')]
class uv extends Extension
{
public function validate(): void
{
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
throw new \RuntimeException('The latest uv extension requires PHP 8.0 or later');
}
}
}

View File

@@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('xhprof')]
class xhprof extends Extension
{
public function patchBeforeBuildconf(): bool
{
if (!is_link(SOURCE_PATH . '/php-src/ext/xhprof')) {
if (PHP_OS_FAMILY === 'Windows') {
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D xhprof xhprof-src\extension');
} else {
f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && ln -s xhprof-src/extension xhprof');
}
// patch config.m4
FileSystem::replaceFileStr(
SOURCE_PATH . '/php-src/ext/xhprof/config.m4',
'if test -f $phpincludedir/ext/pcre/php_pcre.h; then',
'if test -f $abs_srcdir/ext/pcre/php_pcre.h; then'
);
return true;
}
return false;
}
}

View File

@@ -6,7 +6,6 @@ namespace SPC\builder\extension;
use SPC\builder\Extension; use SPC\builder\Extension;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\util\CustomExt; use SPC\util\CustomExt;
#[CustomExt('xml')] #[CustomExt('xml')]
@@ -34,25 +33,4 @@ class xml extends Extension
$arg .= ' --with-libxml="' . BUILD_ROOT_PATH . '"'; $arg .= ' --with-libxml="' . BUILD_ROOT_PATH . '"';
return $arg; return $arg;
} }
public function patchBeforeBuildconf(): bool
{
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/win32/build/config.w32', 'dllmain.c ', '');
return true;
}
public function getWindowsConfigureArg(): string
{
$arg = match ($this->name) {
'xml' => '--with-xml',
'soap' => '--enable-soap',
'xmlreader' => '--enable-xmlreader',
'xmlwriter' => '--enable-xmlwriter',
'dom' => '--with-dom',
'simplexml' => '--with-simplexml',
default => throw new RuntimeException('Not accept non-xml extension'),
};
$arg .= ' --with-libxml';
return $arg;
}
} }

View File

@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('yac')]
class yac extends Extension
{
public function patchBeforeBuildconf(): bool
{
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/yac/storage/allocator/yac_allocator.h', 'defined(HAVE_SHM_MMAP_ANON)', 'defined(YAC_ALLOCATOR_H)');
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/yac/serializer/igbinary.c', '#ifdef YAC_ENABLE_IGBINARY', '#if 1');
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/yac/serializer/json.c', '#if YAC_ENABLE_JSON', '#if 1');
return true;
}
public function getUnixConfigureArg(): string
{
return '--enable-yac --enable-igbinary --enable-json';
}
}

View File

@@ -4,15 +4,19 @@ declare(strict_types=1);
namespace SPC\builder\freebsd; namespace SPC\builder\freebsd;
use SPC\builder\unix\UnixBuilderBase; use SPC\builder\BuilderBase;
use SPC\builder\traits\UnixBuilderTrait;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\FileSystem; use SPC\store\FileSystem;
use SPC\store\SourcePatcher; use SPC\store\SourcePatcher;
class BSDBuilder extends UnixBuilderBase class BSDBuilder extends BuilderBase
{ {
/** Unix compatible builder methods */
use UnixBuilderTrait;
/** @var bool Micro patch phar flag */ /** @var bool Micro patch phar flag */
private bool $phar_patched = false; private bool $phar_patched = false;
@@ -28,7 +32,7 @@ class BSDBuilder extends UnixBuilderBase
// ---------- set necessary options ---------- // ---------- set necessary options ----------
// set C Compiler (default: clang) // set C Compiler (default: clang)
f_putenv('CC=' . $this->getOption('cc', 'clang')); f_putenv('CC=' . $this->getOption('cc', 'clang'));
// set C++ Compiler (default: clang++) // set C++ Composer (default: clang++)
f_putenv('CXX=' . $this->getOption('cxx', 'clang++')); f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
// set PATH // set PATH
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH')); f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
@@ -77,17 +81,14 @@ class BSDBuilder extends UnixBuilderBase
} }
$this->setOption('extra-libs', $extra_libs); $this->setOption('extra-libs', $extra_libs);
$this->emitPatchPoint('before-php-buildconf');
SourcePatcher::patchBeforeBuildconf($this); SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force'); shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this); SourcePatcher::patchBeforeConfigure($this);
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : ''; $json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
$zts_enable = $this->getPHPVersionID() < 80000 ? '--enable-maintainer-zts --disable-zend-signals' : '--enable-zts --disable-zend-signals'; $zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
$zts = $this->getOption('enable-zts', false) ? $zts_enable : '';
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI; $enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM; $enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
@@ -114,7 +115,6 @@ class BSDBuilder extends UnixBuilderBase
$this->makeExtensionArgs() $this->makeExtensionArgs()
); );
$this->emitPatchPoint('before-php-make');
SourcePatcher::patchBeforeMake($this); SourcePatcher::patchBeforeMake($this);
$this->cleanMake(); $this->cleanMake();
@@ -140,7 +140,6 @@ class BSDBuilder extends UnixBuilderBase
} }
if (php_uname('m') === $this->getOption('arch')) { if (php_uname('m') === $this->getOption('arch')) {
$this->emitPatchPoint('before-sanity-check');
$this->sanityCheck($build_target); $this->sanityCheck($build_target);
} }
} }
@@ -151,7 +150,7 @@ class BSDBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws FileSystemException * @throws FileSystemException
*/ */
protected function buildCli(): void public function buildCli(): void
{ {
$vars = SystemUtil::makeEnvVarString([ $vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size 'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
@@ -174,14 +173,14 @@ class BSDBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws WrongUsageException * @throws WrongUsageException
*/ */
protected function buildMicro(): void public function buildMicro(): void
{ {
if ($this->getPHPVersionID() < 80000) { if ($this->getPHPVersionID() < 80000) {
throw new WrongUsageException('phpmicro only support PHP >= 8.0!'); throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
} }
if ($this->getExt('phar')) { if ($this->getExt('phar')) {
$this->phar_patched = true; $this->phar_patched = true;
SourcePatcher::patchMicroPhar($this->getPHPVersionID()); SourcePatcher::patchMicro(['phar']);
} }
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : ''; $enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
@@ -202,7 +201,7 @@ class BSDBuilder extends UnixBuilderBase
$this->deployBinary(BUILD_TARGET_MICRO); $this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) { if ($this->phar_patched) {
SourcePatcher::unpatchMicroPhar(); SourcePatcher::patchMicro(['phar'], true);
} }
} }
@@ -212,7 +211,7 @@ class BSDBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws FileSystemException * @throws FileSystemException
*/ */
protected function buildFpm(): void public function buildFpm(): void
{ {
$vars = SystemUtil::makeEnvVarString([ $vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size 'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
@@ -232,7 +231,7 @@ class BSDBuilder extends UnixBuilderBase
* *
* @throws RuntimeException * @throws RuntimeException
*/ */
protected function buildEmbed(): void public function buildEmbed(): void
{ {
$vars = SystemUtil::makeEnvVarString([ $vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size 'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size

View File

@@ -4,50 +4,79 @@ declare(strict_types=1);
namespace SPC\builder\linux; namespace SPC\builder\linux;
use SPC\builder\BuilderBase;
use SPC\builder\linux\library\LinuxLibraryBase; use SPC\builder\linux\library\LinuxLibraryBase;
use SPC\builder\unix\UnixBuilderBase; use SPC\builder\traits\UnixBuilderTrait;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\FileSystem; use SPC\store\FileSystem;
use SPC\store\SourcePatcher; use SPC\store\SourcePatcher;
use SPC\util\GlobalEnvManager;
class LinuxBuilder extends UnixBuilderBase class LinuxBuilder extends BuilderBase
{ {
/** Unix compatible builder methods */
use UnixBuilderTrait;
/** @var array Tune cflags */
public array $tune_c_flags;
/** @var bool Micro patch phar flag */ /** @var bool Micro patch phar flag */
private bool $phar_patched = false; private bool $phar_patched = false;
/** /**
* @throws FileSystemException * @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException * @throws WrongUsageException
*/ */
public function __construct(array $options = []) public function __construct(array $options = [])
{ {
$this->options = $options; $this->options = $options;
// check musl-cross make installed if we use musl-cross-make // ---------- set necessary options ----------
$arch = arch2gnu(php_uname('m')); // set C/C++ compilers (default: alpine: gcc, others: musl-cross-make)
if (SystemUtil::isMuslDist()) {
f_putenv("CC={$this->getOption('cc', 'gcc')}");
f_putenv("CXX={$this->getOption('cxx', 'g++')}");
f_putenv("AR={$this->getOption('ar', 'ar')}");
f_putenv("LD={$this->getOption('ld', 'ld.gold')}");
} else {
$arch = arch2gnu(php_uname('m'));
f_putenv("CC={$this->getOption('cc', "{$arch}-linux-musl-gcc")}");
f_putenv("CXX={$this->getOption('cxx', "{$arch}-linux-musl-g++")}");
f_putenv("AR={$this->getOption('ar', "{$arch}-linux-musl-ar")}");
f_putenv("LD={$this->getOption('ld', 'ld.gold')}");
f_putenv("PATH=/usr/local/musl/bin:/usr/local/musl/{$arch}-linux-musl/bin:" . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
// set library path, some libraries need it. (We cannot use `putenv` here, because cmake will be confused) // set library path, some libraries need it. (We cannot use `putenv` here, because cmake will be confused)
$this->setOptionIfNotExist('library_path', "LIBRARY_PATH=/usr/local/musl/{$arch}-linux-musl/lib"); $this->setOptionIfNotExist('library_path', "LIBRARY_PATH=/usr/local/musl/{$arch}-linux-musl/lib");
$this->setOptionIfNotExist('ld_library_path', "LD_LIBRARY_PATH=/usr/local/musl/{$arch}-linux-musl/lib"); $this->setOptionIfNotExist('ld_library_path', "LD_LIBRARY_PATH=/usr/local/musl/{$arch}-linux-musl/lib");
GlobalEnvManager::init($this); // check musl-cross make installed if we use musl-cross-make
if (str_ends_with(getenv('CC'), 'linux-musl-gcc') && !file_exists("/usr/local/musl/bin/{$arch}-linux-musl-gcc")) {
if (str_ends_with(getenv('CC'), 'linux-musl-gcc') && !file_exists("/usr/local/musl/bin/{$arch}-linux-musl-gcc")) { throw new WrongUsageException('musl-cross-make not installed, please install it first. (You can use `doctor` command to install it)');
throw new WrongUsageException('musl-cross-make not installed, please install it first. (You can use `doctor` command to install it)'); }
} }
// set PKG_CONFIG
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
// set PKG_CONFIG_PATH
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig');
// set arch (default: current)
$this->setOptionIfNotExist('arch', php_uname('m'));
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
// concurrency // concurrency
$this->concurrency = intval(getenv('SPC_CONCURRENCY')); $this->concurrency = SystemUtil::getCpuCount();
// cflags // cflags
$this->arch_c_flags = getenv('SPC_DEFAULT_C_FLAGS'); $this->arch_c_flags = SystemUtil::getArchCFlags(getenv('CC'), $this->getOption('arch'));
$this->arch_cxx_flags = getenv('SPC_DEFAULT_CXX_FLAGS'); $this->arch_cxx_flags = SystemUtil::getArchCFlags(getenv('CXX'), $this->getOption('arch'));
$this->tune_c_flags = SystemUtil::checkCCFlags(SystemUtil::getTuneCFlags($this->getOption('arch')), getenv('CC'));
// cmake toolchain // cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile( $this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile(
'Linux', 'Linux',
$arch, $this->getOption('arch'),
$this->arch_c_flags, $this->arch_c_flags,
getenv('CC'), getenv('CC'),
getenv('CXX'), getenv('CXX'),
@@ -92,9 +121,6 @@ class LinuxBuilder extends UnixBuilderBase
} }
/** /**
* Build PHP from source.
*
* @param int $build_target Build target, use `BUILD_TARGET_*` constants
* @throws RuntimeException * @throws RuntimeException
* @throws FileSystemException * @throws FileSystemException
* @throws WrongUsageException * @throws WrongUsageException
@@ -102,8 +128,8 @@ class LinuxBuilder extends UnixBuilderBase
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{ {
// ---------- Update extra-libs ---------- // ---------- Update extra-libs ----------
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; $extra_libs = $this->getOption('extra-libs', '');
// bloat means force-load all static libraries, even if they are not used // non-bloat linking
if (!$this->getOption('bloat', false)) { if (!$this->getOption('bloat', false)) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles()); $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
} else { } else {
@@ -111,15 +137,20 @@ class LinuxBuilder extends UnixBuilderBase
} }
// add libstdc++, some extensions or libraries need it // add libstdc++, some extensions or libraries need it
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : ''); $extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : '');
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); $this->setOption('extra-libs', $extra_libs);
$cflags = $this->arch_c_flags; $cflags = $this->arch_c_flags;
$this->emitPatchPoint('before-php-buildconf'); // prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => $cflags,
'LIBS' => '-ldl -lpthread',
]);
SourcePatcher::patchBeforeBuildconf($this); SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec(getenv('SPC_CMD_PREFIX_PHP_BUILDCONF')); shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this); SourcePatcher::patchBeforeConfigure($this);
$phpVersionID = $this->getPHPVersionID(); $phpVersionID = $this->getPHPVersionID();
@@ -134,70 +165,59 @@ class LinuxBuilder extends UnixBuilderBase
} }
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : ''; $disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';
$enable_cli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI; $enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
$enable_fpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM; $enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
$enable_micro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO; $enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
$enable_embed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED; $enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
// prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
'CPPFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS'),
'LDFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS'),
'LIBS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LIBS'),
]);
// process micro upx patch if micro sapi enabled
if ($enable_micro) {
if (version_compare($this->getMicroVersion(), '0.2.0') < 0) {
// for phpmicro 0.1.x
$this->processMicroUPXLegacy();
}
// micro latest needs do strip and upx pack later (strip, upx, cut binary manually supported)
}
shell()->cd(SOURCE_PATH . '/php-src') shell()->cd(SOURCE_PATH . '/php-src')
->exec( ->exec(
getenv('SPC_CMD_PREFIX_PHP_CONFIGURE') . ' ' . "{$this->getOption('ld_library_path')} " .
($enable_cli ? '--enable-cli ' : '--disable-cli ') . './configure ' .
($enable_fpm ? '--enable-fpm ' : '--disable-fpm ') . '--prefix= ' .
($enable_embed ? '--enable-embed=static ' : '--disable-embed ') . '--with-valgrind=no ' .
($enable_micro ? '--enable-micro=all-static ' : '--disable-micro ') . '--enable-shared=no ' .
'--enable-static=yes ' .
'--disable-all ' .
'--disable-cgi ' .
'--disable-phpdbg ' .
($enableCli ? '--enable-cli ' : '--disable-cli ') .
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
($enableMicro ? '--enable-micro=all-static ' : '--disable-micro ') .
$disable_jit . $disable_jit .
$json_74 . $json_74 .
$zts . $zts .
$maxExecutionTimers . $maxExecutionTimers .
$this->makeExtensionArgs() . $this->makeExtensionArgs() . ' ' .
' ' . $envs_build_php . ' ' $envs_build_php
); );
$this->emitPatchPoint('before-php-make');
SourcePatcher::patchBeforeMake($this); SourcePatcher::patchBeforeMake($this);
$this->cleanMake(); $this->cleanMake();
if ($enable_cli) { if ($enableCli) {
logger()->info('building cli'); logger()->info('building cli');
$this->buildCli(); $this->buildCli();
} }
if ($enable_fpm) { if ($enableFpm) {
logger()->info('building fpm'); logger()->info('building fpm');
$this->buildFpm(); $this->buildFpm();
} }
if ($enable_micro) { if ($enableMicro) {
logger()->info('building micro'); logger()->info('building micro');
$this->buildMicro(); $this->buildMicro();
} }
if ($enable_embed) { if ($enableEmbed) {
logger()->info('building embed'); logger()->info('building embed');
if ($enable_micro) { if ($enableMicro) {
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la'); FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Makefile', 'OVERALL_TARGET =', 'OVERALL_TARGET = libphp.la');
} }
$this->buildEmbed(); $this->buildEmbed();
} }
if (php_uname('m') === $this->getOption('arch')) { if (php_uname('m') === $this->getOption('arch')) {
$this->emitPatchPoint('before-sanity-check');
$this->sanityCheck($build_target); $this->sanityCheck($build_target);
} }
} }
@@ -208,18 +228,14 @@ class LinuxBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws FileSystemException * @throws FileSystemException
*/ */
protected function buildCli(): void public function buildCli(): void
{ {
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); $vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()->cd(SOURCE_PATH . '/php-src') shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} cli"); ->exec("make -j{$this->concurrency} {$vars} cli");
if ($this->getOption('with-upx-pack')) { if (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')
->exec('strip --strip-all php')
->exec(getenv('UPX_EXEC') . ' --best php');
} elseif (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')->exec('strip --strip-all php'); shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')->exec('strip --strip-all php');
} }
@@ -233,33 +249,31 @@ class LinuxBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws WrongUsageException * @throws WrongUsageException
*/ */
protected function buildMicro(): void public function buildMicro(): void
{ {
if ($this->getPHPVersionID() < 80000) { if ($this->getPHPVersionID() < 80000) {
throw new WrongUsageException('phpmicro only support PHP >= 8.0!'); throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
} }
if ($this->getExt('phar')) { if ($this->getExt('phar')) {
$this->phar_patched = true; $this->phar_patched = true;
SourcePatcher::patchMicroPhar($this->getPHPVersionID()); SourcePatcher::patchMicro(['phar']);
} }
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : ''; $vars = SystemUtil::makeEnvVarString($this->getBuildVars([
$vars = $this->getMakeExtraVars(); 'EXTRA_CFLAGS' => $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '',
]));
// patch fake cli for micro
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
$vars = SystemUtil::makeEnvVarString($vars);
shell()->cd(SOURCE_PATH . '/php-src') shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} micro"); ->exec("make -j{$this->concurrency} {$vars} micro");
$this->processMicroUPX(); if (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec('strip --strip-all micro.sfx');
}
$this->deployBinary(BUILD_TARGET_MICRO); $this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) { if ($this->phar_patched) {
SourcePatcher::unpatchMicroPhar(); SourcePatcher::patchMicro(['phar'], true);
} }
} }
@@ -269,20 +283,17 @@ class LinuxBuilder extends UnixBuilderBase
* @throws FileSystemException * @throws FileSystemException
* @throws RuntimeException * @throws RuntimeException
*/ */
protected function buildFpm(): void public function buildFpm(): void
{ {
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); $vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()->cd(SOURCE_PATH . '/php-src') shell()->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} fpm"); ->exec("make -j{$this->concurrency} {$vars} fpm");
if ($this->getOption('with-upx-pack')) { if (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')
->exec('strip --strip-all php-fpm')
->exec(getenv('UPX_EXEC') . ' --best php-fpm');
} elseif (!$this->getOption('no-strip', false)) {
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-all php-fpm'); shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-all php-fpm');
} }
$this->deployBinary(BUILD_TARGET_FPM); $this->deployBinary(BUILD_TARGET_FPM);
} }
@@ -291,87 +302,30 @@ class LinuxBuilder extends UnixBuilderBase
* *
* @throws RuntimeException * @throws RuntimeException
*/ */
protected function buildEmbed(): void public function buildEmbed(): void
{ {
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); $vars = SystemUtil::makeEnvVarString($this->getBuildVars());
shell()->cd(SOURCE_PATH . '/php-src') shell()
->cd(SOURCE_PATH . '/php-src')
->exec('sed -i "s|//lib|/lib|g" Makefile') ->exec('sed -i "s|//lib|/lib|g" Makefile')
->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install"); ->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install");
} }
private function getMakeExtraVars(): array private function getBuildVars($input = []): array
{ {
$use_lld = '';
if (str_ends_with(getenv('CC'), 'clang') && SystemUtil::findCommand('lld')) {
$use_lld = '-Xcompiler -fuse-ld=lld';
}
$optimization = $this->getOption('no-strip', false) ? '-g -O0' : '-g0 -Os';
$cflags = isset($input['EXTRA_CFLAGS']) && $input['EXTRA_CFLAGS'] ? " {$input['EXTRA_CFLAGS']}" : '';
$libs = isset($input['EXTRA_LIBS']) && $input['EXTRA_LIBS'] ? " {$input['EXTRA_LIBS']}" : '';
$ldflags = isset($input['EXTRA_LDFLAGS_PROGRAM']) && $input['EXTRA_LDFLAGS_PROGRAM'] ? " {$input['EXTRA_LDFLAGS_PROGRAM']}" : '';
return [ return [
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'), 'EXTRA_CFLAGS' => "{$optimization} -fno-ident -fPIE " . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", $this->tune_c_flags)) . $cflags,
'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'), 'EXTRA_LIBS' => $this->getOption('extra-libs', '') . $libs,
'EXTRA_LDFLAGS_PROGRAM' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM'), 'EXTRA_LDFLAGS_PROGRAM' => "{$use_lld} -all-static" . $ldflags,
]; ];
} }
/**
* Apply option --no-strip and --with-upx-pack for micro sapi (only for phpmicro 0.1.x)
*
* @throws FileSystemException
*/
private function processMicroUPXLegacy(): void
{
// upx pack and strip for micro
// but always restore Makefile.frag.bak first
if (file_exists(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak')) {
copy(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak', SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag');
}
if ($this->getOption('with-upx-pack', false)) {
// judge $(MAKE) micro_2s_objs SFX_FILESIZE=`$(STAT_SIZE) $(SAPI_MICRO_PATH)` count
// if 2, replace src/globals/extra/micro-triple-Makefile.frag file content
if (substr_count(FileSystem::readFile(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag'), '$(MAKE) micro_2s_objs SFX_FILESIZE=`$(STAT_SIZE) $(SAPI_MICRO_PATH)`') === 2) {
// bak first
copy(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag', SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.bak');
// replace Makefile.frag content
FileSystem::writeFile(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag', FileSystem::readFile(ROOT_DIR . '/src/globals/extra/micro-triple-Makefile.frag'));
}
// with upx pack always need strip
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
'/POST_MICRO_BUILD_COMMANDS=.*/',
'POST_MICRO_BUILD_COMMANDS=\$(STRIP) \$(MICRO_STRIP_FLAGS) \$(SAPI_MICRO_PATH) && ' . getenv('UPX_EXEC') . ' --best \$(SAPI_MICRO_PATH)',
);
} elseif (!$this->getOption('no-strip', false)) {
// not-no-strip means strip (default behavior)
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
'/POST_MICRO_BUILD_COMMANDS=.*/',
'POST_MICRO_BUILD_COMMANDS=\$(STRIP) \$(MICRO_STRIP_FLAGS) \$(SAPI_MICRO_PATH)',
);
} else {
// just no strip
FileSystem::replaceFileRegex(
SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag',
'/POST_MICRO_BUILD_COMMANDS=.*/',
'POST_MICRO_BUILD_COMMANDS=true',
);
}
}
private function processMicroUPX(): void
{
if (version_compare($this->getMicroVersion(), '0.2.0') >= 0 && !$this->getOption('no-strip', false)) {
shell()->exec('strip --strip-all ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx');
if ($this->getOption('with-upx-pack')) {
// strip first
shell()->exec(getenv('UPX_EXEC') . ' --best ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx');
// cut binary with readelf
[$ret, $out] = shell()->execWithResult('readelf -l ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx | awk \'/LOAD|GNU_STACK/ {getline; print $1, $2, $3, $4, $6, $7}\'');
$out[1] = explode(' ', $out[1]);
$offset = $out[1][0];
if ($ret !== 0 || !str_starts_with($offset, '0x')) {
throw new RuntimeException('Cannot find offset in readelf output');
}
$offset = hexdec($offset);
// remove upx extra wastes
file_put_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx', substr(file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx'), 0, $offset));
}
}
}
} }

View File

@@ -110,7 +110,11 @@ class SystemUtil
public static function getTuneCFlags(string $arch): array public static function getTuneCFlags(string $arch): array
{ {
return match ($arch) { return match ($arch) {
'x86_64', 'arm64', 'aarch64' => [], 'x86_64' => [
'-march=corei7',
'-mtune=core-avx2',
],
'arm64', 'aarch64' => [],
default => throw new RuntimeException('unsupported arch: ' . $arch), default => throw new RuntimeException('unsupported arch: ' . $arch),
}; };
} }
@@ -205,23 +209,4 @@ class SystemUtil
} }
return $ret; return $ret;
} }
/**
* Get fully-supported linux distros.
*
* @return string[] List of supported Linux distro name for doctor
*/
public static function getSupportedDistros(): array
{
return [
// debian-like
'debian', 'ubuntu', 'Deepin',
// rhel-like
'redhat',
// alpine
'alpine',
// arch
'arch', 'manjaro',
];
}
} }

View File

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

View File

@@ -11,7 +11,7 @@ class icu extends LinuxLibraryBase
protected function build(): void protected function build(): void
{ {
$cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1"'; $cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1"';
$cxxflags = 'CXXFLAGS="-std=c++17"'; $cxxflags = 'CXXFLAGS="-std=c++11"';
$ldflags = 'LDFLAGS="-static"'; $ldflags = 'LDFLAGS="-static"';
shell()->cd($this->source_dir . '/source') shell()->cd($this->source_dir . '/source')
->exec( ->exec(

View File

@@ -47,10 +47,6 @@ class imap extends LinuxLibraryBase
shell()->cd($this->source_dir) shell()->cd($this->source_dir)
->exec('make clean') ->exec('make clean')
->exec('touch ip6') ->exec('touch ip6')
->exec('chmod +x tools/an')
->exec('chmod +x tools/ua')
->exec('chmod +x src/osdep/unix/drivers')
->exec('chmod +x src/osdep/unix/mkauths')
->exec( ->exec(
"yes | make slx {$ssl_options}" "yes | make slx {$ssl_options}"
); );

View File

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

View File

@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace SPC\builder\linux\library; namespace SPC\builder\linux\library;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem; use SPC\store\FileSystem;
class libargon2 extends LinuxLibraryBase class libargon2 extends LinuxLibraryBase
@@ -14,6 +15,10 @@ class libargon2 extends LinuxLibraryBase
public function patchBeforeBuild(): bool public function patchBeforeBuild(): bool
{ {
// detect libsodium (The libargon2 conflicts with the libsodium library.)
if ($this->builder->getLib('libsodium') !== null) {
throw new WrongUsageException('libargon2 (required by password-argon2) conflicts with the libsodium library !');
}
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'LIBRARY_REL ?= lib/x86_64-linux-gnu', 'LIBRARY_REL ?= lib'); FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'LIBRARY_REL ?= lib/x86_64-linux-gnu', 'LIBRARY_REL ?= lib');
return true; return true;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,7 +18,7 @@ class libxml2 extends LinuxLibraryBase
*/ */
public function build(): void public function build(): void
{ {
$enable_zlib = $this->builder->getLib('zlib') ? ('ON -DZLIB_LIBRARY=' . BUILD_LIB_PATH . '/libz.a -DZLIB_INCLUDE_DIR=' . BUILD_INCLUDE_PATH) : 'OFF'; $enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF'; $enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF'; $enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
@@ -26,10 +26,7 @@ class libxml2 extends LinuxLibraryBase
shell()->cd($this->source_dir . '/build') shell()->cd($this->source_dir . '/build')
->exec( ->exec(
'cmake ' . 'cmake ' .
'-DCMAKE_BUILD_TYPE=Release ' . "{$this->builder->makeCmakeArgs()} " .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
'-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DBUILD_SHARED_LIBS=OFF ' . '-DBUILD_SHARED_LIBS=OFF ' .
'-DIconv_IS_BUILT_IN=OFF ' . '-DIconv_IS_BUILT_IN=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' . '-DLIBXML2_WITH_ICONV=ON ' .
@@ -42,7 +39,7 @@ class libxml2 extends LinuxLibraryBase
'..' '..'
) )
->exec("cmake --build . -j {$this->builder->concurrency}") ->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install'); ->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
FileSystem::replaceFileStr( FileSystem::replaceFileStr(
BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc', BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc',

View File

@@ -1,12 +1,72 @@
<?php <?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*
* lwmbs is licensed under Mulan PSL v2. You can use this
* software according to the terms and conditions of the
* Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
*/
declare(strict_types=1); declare(strict_types=1);
namespace SPC\builder\linux\library; namespace SPC\builder\linux\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
class nghttp2 extends LinuxLibraryBase class nghttp2 extends LinuxLibraryBase
{ {
use \SPC\builder\unix\library\nghttp2;
public const NAME = 'nghttp2'; public const NAME = 'nghttp2';
/**
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'zlib' => null,
'openssl' => null,
'libxml2' => null,
'libev' => null,
'libcares' => null,
'libngtcp2' => null,
'libnghttp3' => null,
'libbpf' => null,
'libevent-openssl' => null,
'jansson' => null,
'jemalloc' => null,
'systemd' => null,
'cunit' => null,
]);
[,,$destdir] = SEPARATED_PATH;
shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->getOption('gnu-arch')}-unknown-linux " .
'--enable-lib-only ' .
'--with-boost=no ' .
$args . ' ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
$this->patchPkgconfPrefix(['libnghttp2.pc']);
}
} }

View File

@@ -24,7 +24,6 @@ use SPC\builder\linux\SystemUtil;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
class openssl extends LinuxLibraryBase class openssl extends LinuxLibraryBase
{ {
@@ -42,7 +41,8 @@ class openssl extends LinuxLibraryBase
$extra = ''; $extra = '';
$ex_lib = '-ldl -pthread'; $ex_lib = '-ldl -pthread';
$env = "CC='" . getenv('CC') . ' -static -idirafter ' . BUILD_INCLUDE_PATH . $env = "CFLAGS='{$this->builder->arch_c_flags}'";
$env .= " CC='" . getenv('CC') . ' -static -idirafter ' . BUILD_INCLUDE_PATH .
' -idirafter /usr/include/ ' . ' -idirafter /usr/include/ ' .
' -idirafter /usr/include/' . $this->builder->getOption('arch') . '-linux-gnu/ ' . ' -idirafter /usr/include/' . $this->builder->getOption('arch') . '-linux-gnu/ ' .
"' "; "' ";
@@ -63,8 +63,7 @@ class openssl extends LinuxLibraryBase
$clang_postfix = SystemUtil::getCCType(getenv('CC')) === 'clang' ? '-clang' : ''; $clang_postfix = SystemUtil::getCCType(getenv('CC')) === 'clang' ? '-clang' : '';
shell()->cd($this->source_dir) shell()->cd($this->source_dir)
->setEnv(['CFLAGS' => $this->getLibExtraCFlags() ?: $this->builder->arch_c_flags, 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) ->exec(
->execWithEnv(
"{$env} ./Configure no-shared {$extra} " . "{$env} ./Configure no-shared {$extra} " .
'--prefix=/ ' . '--prefix=/ ' .
'--libdir=lib ' . '--libdir=lib ' .
@@ -74,18 +73,8 @@ class openssl extends LinuxLibraryBase
"linux-{$this->builder->getOption('arch')}{$clang_postfix}" "linux-{$this->builder->getOption('arch')}{$clang_postfix}"
) )
->exec('make clean') ->exec('make clean')
->execWithEnv("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") ->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
->exec("make install_sw DESTDIR={$destdir}"); ->exec("make install_sw DESTDIR={$destdir}");
$this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']); $this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']);
// patch for openssl 3.3.0+
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc'), 'prefix=')) {
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
}
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc'), 'prefix=')) {
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
}
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc'), 'prefix=')) {
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
}
} }
} }

View File

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

View File

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

View File

@@ -4,17 +4,20 @@ declare(strict_types=1);
namespace SPC\builder\macos; namespace SPC\builder\macos;
use SPC\builder\BuilderBase;
use SPC\builder\macos\library\MacOSLibraryBase; use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\builder\unix\UnixBuilderBase; use SPC\builder\traits\UnixBuilderTrait;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\FileSystem; use SPC\store\FileSystem;
use SPC\store\SourcePatcher; use SPC\store\SourcePatcher;
use SPC\util\GlobalEnvManager;
class MacOSBuilder extends UnixBuilderBase class MacOSBuilder extends BuilderBase
{ {
/** Unix compatible builder methods */
use UnixBuilderTrait;
/** @var bool Micro patch phar flag */ /** @var bool Micro patch phar flag */
private bool $phar_patched = false; private bool $phar_patched = false;
@@ -27,15 +30,28 @@ class MacOSBuilder extends UnixBuilderBase
{ {
$this->options = $options; $this->options = $options;
// apply global environment variables // ---------- set necessary options ----------
GlobalEnvManager::init($this); // set C Compiler (default: clang)
f_putenv('CC=' . $this->getOption('cc', 'clang'));
// set C++ Composer (default: clang++)
f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
// set PATH
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
// set PKG_CONFIG
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
// set PKG_CONFIG_PATH
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig/');
// ---------- set necessary compile vars ---------- // set arch (default: current)
$this->setOptionIfNotExist('arch', php_uname('m'));
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
// ---------- set necessary compile environments ----------
// concurrency // concurrency
$this->concurrency = intval(getenv('SPC_CONCURRENCY')); $this->concurrency = SystemUtil::getCpuCount();
// cflags // cflags
$this->arch_c_flags = getenv('SPC_DEFAULT_C_FLAGS'); $this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
$this->arch_cxx_flags = getenv('SPC_DEFAULT_CXX_FLAGS'); $this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
// cmake toolchain // cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch'), $this->arch_c_flags); $this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch'), $this->arch_c_flags);
@@ -111,27 +127,24 @@ class MacOSBuilder extends UnixBuilderBase
*/ */
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{ {
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
// ---------- Update extra-libs ---------- // ---------- Update extra-libs ----------
$extra_libs = $this->getOption('extra-libs', '');
// add macOS frameworks // add macOS frameworks
$extra_libs .= (empty($extra_libs) ? '' : ' ') . $this->getFrameworks(true); $extra_libs .= (empty($extra_libs) ? '' : ' ') . $this->getFrameworks(true);
// add libc++, some extensions or libraries need it (C++ cannot be linked statically) // add libc++, some extensions or libraries need it (C++ cannot be linked statically)
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : ''); $extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : '');
// bloat means force-load all static libraries, even if they are not used
if (!$this->getOption('bloat', false)) { if (!$this->getOption('bloat', false)) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles()); $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
} else { } else {
logger()->info('bloat linking'); logger()->info('bloat linking');
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles()))); $extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles())));
} }
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); $this->setOption('extra-libs', $extra_libs);
$this->emitPatchPoint('before-php-buildconf');
SourcePatcher::patchBeforeBuildconf($this); SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec(getenv('SPC_CMD_PREFIX_PHP_BUILDCONF')); shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this); SourcePatcher::patchBeforeConfigure($this);
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : ''; $json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
@@ -142,35 +155,26 @@ class MacOSBuilder extends UnixBuilderBase
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO; $enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
$enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED; $enableEmbed = ($build_target & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED;
// prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
'CPPFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS'),
'LDFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS'),
]);
if ($this->getLib('postgresql')) {
shell()
->cd(SOURCE_PATH . '/php-src')
->exec(
'sed -i.backup "s/ac_cv_func_explicit_bzero\" = xyes/ac_cv_func_explicit_bzero\" = x_fake_yes/" ./configure'
);
}
shell()->cd(SOURCE_PATH . '/php-src') shell()->cd(SOURCE_PATH . '/php-src')
->exec( ->exec(
getenv('SPC_CMD_PREFIX_PHP_CONFIGURE') . ' ' . './configure ' .
'--prefix= ' .
'--with-valgrind=no ' . // Not detect memory leak
'--enable-shared=no ' .
'--enable-static=yes ' .
"CFLAGS='{$this->arch_c_flags} -Werror=unknown-warning-option' " .
'--disable-all ' .
'--disable-cgi ' .
'--disable-phpdbg ' .
($enableCli ? '--enable-cli ' : '--disable-cli ') . ($enableCli ? '--enable-cli ' : '--disable-cli ') .
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') . ($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') . ($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
($enableMicro ? '--enable-micro ' : '--disable-micro ') . ($enableMicro ? '--enable-micro ' : '--disable-micro ') .
$json_74 . $json_74 .
$zts . $zts .
$this->makeExtensionArgs() . ' ' . $this->makeExtensionArgs()
$envs_build_php
); );
$this->emitPatchPoint('before-php-make');
SourcePatcher::patchBeforeMake($this); SourcePatcher::patchBeforeMake($this);
$this->cleanMake(); $this->cleanMake();
@@ -196,7 +200,6 @@ class MacOSBuilder extends UnixBuilderBase
} }
if (php_uname('m') === $this->getOption('arch')) { if (php_uname('m') === $this->getOption('arch')) {
$this->emitPatchPoint('before-sanity-check');
$this->sanityCheck($build_target); $this->sanityCheck($build_target);
} }
} }
@@ -207,12 +210,15 @@ class MacOSBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws FileSystemException * @throws FileSystemException
*/ */
protected function buildCli(): void public function buildCli(): void
{ {
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); $vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv", // link resolv library (macOS needs it)
]);
$shell = shell()->cd(SOURCE_PATH . '/php-src'); $shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} cli"); $shell->exec("make -j{$this->concurrency} {$vars} cli");
if (!$this->getOption('no-strip', false)) { if (!$this->getOption('no-strip', false)) {
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php'); $shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
} }
@@ -226,32 +232,34 @@ class MacOSBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws WrongUsageException * @throws WrongUsageException
*/ */
protected function buildMicro(): void public function buildMicro(): void
{ {
if ($this->getPHPVersionID() < 80000) { if ($this->getPHPVersionID() < 80000) {
throw new WrongUsageException('phpmicro only support PHP >= 8.0!'); throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
} }
if ($this->getExt('phar')) { if ($this->getExt('phar')) {
$this->phar_patched = true; $this->phar_patched = true;
SourcePatcher::patchMicroPhar($this->getPHPVersionID()); SourcePatcher::patchMicro(['phar']);
} }
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : ''; $enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
$vars = $this->getMakeExtraVars(); $vars = [
// with debug information, optimize for size, remove identifiers, patch fake cli for micro
// patch fake cli for micro 'EXTRA_CFLAGS' => '-g -Os -fno-ident' . $enable_fake_cli,
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli; // link resolv library (macOS needs it)
if ($this->getOption('no-strip', false)) { 'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv",
];
if (!$this->getOption('no-strip', false)) {
$vars['STRIP'] = 'dsymutil -f '; $vars['STRIP'] = 'dsymutil -f ';
} }
$vars = SystemUtil::makeEnvVarString($vars); $vars = SystemUtil::makeEnvVarString($vars);
shell()->cd(SOURCE_PATH . '/php-src')->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . " {$vars} micro"); shell()->cd(SOURCE_PATH . '/php-src')
->exec("make -j{$this->concurrency} {$vars} micro");
$this->deployBinary(BUILD_TARGET_MICRO); $this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) { if ($this->phar_patched) {
SourcePatcher::unpatchMicroPhar(); SourcePatcher::patchMicro(['phar'], true);
} }
} }
@@ -261,12 +269,15 @@ class MacOSBuilder extends UnixBuilderBase
* @throws RuntimeException * @throws RuntimeException
* @throws FileSystemException * @throws FileSystemException
*/ */
protected function buildFpm(): void public function buildFpm(): void
{ {
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); $vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv", // link resolv library (macOS needs it)
]);
$shell = shell()->cd(SOURCE_PATH . '/php-src'); $shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . " {$vars} fpm"); $shell->exec("make -j{$this->concurrency} {$vars} fpm");
if (!$this->getOption('no-strip', false)) { if (!$this->getOption('no-strip', false)) {
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm'); $shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm');
} }
@@ -278,12 +289,16 @@ class MacOSBuilder extends UnixBuilderBase
* *
* @throws RuntimeException * @throws RuntimeException
*/ */
protected function buildEmbed(): void public function buildEmbed(): void
{ {
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); $vars = SystemUtil::makeEnvVarString([
'EXTRA_CFLAGS' => '-g -Os', // with debug information, but optimize for size
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv", // link resolv library (macOS needs it)
]);
shell()->cd(SOURCE_PATH . '/php-src') shell()
->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install") ->cd(SOURCE_PATH . '/php-src')
->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install")
// Workaround for https://github.com/php/php-src/issues/12082 // Workaround for https://github.com/php/php-src/issues/12082
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o') ->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o')
->exec('mkdir ' . BUILD_ROOT_PATH . '/lib/php-o') ->exec('mkdir ' . BUILD_ROOT_PATH . '/lib/php-o')
@@ -293,12 +308,4 @@ class MacOSBuilder extends UnixBuilderBase
->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o') ->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o')
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o'); ->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o');
} }
private function getMakeExtraVars(): array
{
return [
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'),
];
}
} }

View File

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

View File

@@ -50,10 +50,6 @@ class imap extends MacOSLibraryBase
shell()->cd($this->source_dir) shell()->cd($this->source_dir)
->exec('make clean') ->exec('make clean')
->exec('touch ip6') ->exec('touch ip6')
->exec('chmod +x tools/an')
->exec('chmod +x tools/ua')
->exec('chmod +x src/osdep/unix/drivers')
->exec('chmod +x src/osdep/unix/mkauths')
->exec( ->exec(
"yes | EXTRACFLAGS='-Wimplicit-function-declaration -include $(xcrun --show-sdk-path)/usr/include/poll.h -include $(xcrun --show-sdk-path)/usr/include/time.h -include $(xcrun --show-sdk-path)/usr/include/utime.h' make osx {$ssl_options}" "yes | EXTRACFLAGS='-Wimplicit-function-declaration -include $(xcrun --show-sdk-path)/usr/include/poll.h -include $(xcrun --show-sdk-path)/usr/include/time.h -include $(xcrun --show-sdk-path)/usr/include/utime.h' make osx {$ssl_options}"
); );

View File

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

View File

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

View File

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

View File

@@ -35,7 +35,7 @@ class libpng extends MacOSLibraryBase
*/ */
protected function build(): void protected function build(): void
{ {
$optimizations = match (php_uname('m')) { $optimizations = match ($this->builder->getOption('arch')) {
'x86_64' => '--enable-intel-sse ', 'x86_64' => '--enable-intel-sse ',
'arm64' => '--enable-arm-neon ', 'arm64' => '--enable-arm-neon ',
default => '', default => '',
@@ -45,7 +45,7 @@ class libpng extends MacOSLibraryBase
->exec('chmod +x ./install-sh') ->exec('chmod +x ./install-sh')
->exec( ->exec(
'./configure ' . './configure ' .
'--host=' . arch2gnu(php_uname('m')) . '-apple-darwin ' . "--host={$this->builder->getOption('gnu-arch')}-apple-darwin " .
'--disable-shared ' . '--disable-shared ' .
'--enable-static ' . '--enable-static ' .
'--enable-hardware-optimizations ' . '--enable-hardware-optimizations ' .

View File

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

View File

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

View File

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

View File

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

View File

@@ -18,7 +18,7 @@ class libxml2 extends MacOSLibraryBase
*/ */
protected function build(): void protected function build(): void
{ {
$enable_zlib = $this->builder->getLib('zlib') ? ('ON -DZLIB_LIBRARY=' . BUILD_LIB_PATH . '/libz.a -DZLIB_INCLUDE_DIR=' . BUILD_INCLUDE_PATH) : 'OFF'; $enable_zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
$enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF'; $enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF';
$enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF'; $enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF';
@@ -27,10 +27,7 @@ class libxml2 extends MacOSLibraryBase
->exec( ->exec(
'cmake ' . 'cmake ' .
// '--debug-find ' . // '--debug-find ' .
'-DCMAKE_BUILD_TYPE=Release ' . "{$this->builder->makeCmakeArgs()} " .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
'-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DBUILD_SHARED_LIBS=OFF ' . '-DBUILD_SHARED_LIBS=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' . '-DLIBXML2_WITH_ICONV=ON ' .
"-DLIBXML2_WITH_ZLIB={$enable_zlib} " . "-DLIBXML2_WITH_ZLIB={$enable_zlib} " .
@@ -42,6 +39,6 @@ class libxml2 extends MacOSLibraryBase
'..' '..'
) )
->exec("cmake --build . -j {$this->builder->concurrency}") ->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install'); ->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
} }
} }

View File

@@ -20,9 +20,51 @@ declare(strict_types=1);
namespace SPC\builder\macos\library; namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
class nghttp2 extends MacOSLibraryBase class nghttp2 extends MacOSLibraryBase
{ {
use \SPC\builder\unix\library\nghttp2;
public const NAME = 'nghttp2'; public const NAME = 'nghttp2';
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'zlib' => null,
'openssl' => null,
'libxml2' => null,
'libev' => null,
'libcares' => null,
'libngtcp2' => null,
'libnghttp3' => null,
'libbpf' => null,
'libevent-openssl' => null,
'jansson' => null,
'jemalloc' => null,
'systemd' => null,
'cunit' => null,
]);
[,,$destdir] = SEPARATED_PATH;
shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->getOption('gnu-arch')}-apple-darwin " .
'--enable-lib-only ' .
'--with-boost=no ' .
$args . ' ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
$this->patchPkgconfPrefix(['libnghttp2.pc']);
}
} }

View File

@@ -23,7 +23,6 @@ namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
class openssl extends MacOSLibraryBase class openssl extends MacOSLibraryBase
{ {
@@ -48,7 +47,6 @@ class openssl extends MacOSLibraryBase
} }
shell()->cd($this->source_dir) shell()->cd($this->source_dir)
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->exec( ->exec(
"./Configure no-shared {$extra} " . "./Configure no-shared {$extra} " .
'--prefix=/ ' . // use prefix=/ '--prefix=/ ' . // use prefix=/
@@ -57,18 +55,8 @@ class openssl extends MacOSLibraryBase
"darwin64-{$this->builder->getOption('arch')}-cc" "darwin64-{$this->builder->getOption('arch')}-cc"
) )
->exec('make clean') ->exec('make clean')
->execWithEnv("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") ->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
->exec("make install_sw DESTDIR={$destdir}"); ->exec("make install_sw DESTDIR={$destdir}");
$this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']); $this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']);
// patch for openssl 3.3.0+
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc'), 'prefix=')) {
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
}
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc'), 'prefix=')) {
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/openssl.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
}
if (!str_contains($file = FileSystem::readFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc'), 'prefix=')) {
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
}
} }
} }

View File

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

View File

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

View File

@@ -1,4 +1,20 @@
<?php <?php
/**
* Copyright (c) 2022 Yun Dou <dixyes@gmail.com>
*
* lwmbs is licensed under Mulan PSL v2. You can use this
* software according to the terms and conditions of the
* Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
*/
declare(strict_types=1); declare(strict_types=1);

View File

@@ -0,0 +1,7 @@
<?php
declare(strict_types=1);
namespace SPC\builder\traits;
trait LibraryTrait {}

View File

@@ -2,19 +2,15 @@
declare(strict_types=1); declare(strict_types=1);
namespace SPC\builder\unix; namespace SPC\builder\traits;
use SPC\builder\BuilderBase;
use SPC\builder\linux\LinuxBuilder; use SPC\builder\linux\LinuxBuilder;
use SPC\exception\FileSystemException; use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException; use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException; use SPC\exception\WrongUsageException;
use SPC\store\Config;
use SPC\store\FileSystem; use SPC\store\FileSystem;
use SPC\store\SourceManager;
use SPC\util\DependencyUtil;
abstract class UnixBuilderBase extends BuilderBase trait UnixBuilderTrait
{ {
/** @var string cflags */ /** @var string cflags */
public string $arch_c_flags; public string $arch_c_flags;
@@ -53,6 +49,77 @@ abstract class UnixBuilderBase extends BuilderBase
return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles); return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles);
} }
/**
* Sanity check after build complete
*
* @throws RuntimeException
*/
public function sanityCheck(int $build_target): void
{
// sanity check for php-cli
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
logger()->info('running cli sanity check');
[$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"');
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
throw new RuntimeException('cli failed sanity check');
}
foreach ($this->exts as $ext) {
logger()->debug('testing ext: ' . $ext->getName());
$ext->runCliCheck();
}
}
// sanity check for phpmicro
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if (file_exists(SOURCE_PATH . '/hello.exe')) {
@unlink(SOURCE_PATH . '/hello.exe');
}
file_put_contents(
SOURCE_PATH . '/hello.exe',
file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') .
'<?php echo "hello";'
);
chmod(SOURCE_PATH . '/hello.exe', 0755);
[$ret, $output2] = shell()->execWithResult(SOURCE_PATH . '/hello.exe');
if ($ret !== 0 || trim($out = implode('', $output2)) !== 'hello') {
throw new RuntimeException('micro failed sanity check, ret[' . $ret . '], out[' . ($out ?? 'NULL') . ']');
}
}
}
/**
* 将编译好的二进制文件发布到 buildroot
*
* @param int $type 发布类型
* @throws RuntimeException
* @throws FileSystemException
*/
public function deployBinary(int $type): bool
{
$src = match ($type) {
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm',
default => throw new RuntimeException('Deployment does not accept type ' . $type),
};
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
FileSystem::createDir(BUILD_ROOT_PATH . '/bin');
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '/bin/'));
return true;
}
/**
* Run php clean
*
* @throws RuntimeException
*/
public function cleanMake(): void
{
logger()->info('cleaning up');
shell()->cd(SOURCE_PATH . '/php-src')->exec('make clean');
}
/** /**
* Return generic cmake options when configuring cmake projects * Return generic cmake options when configuring cmake projects
*/ */
@@ -89,127 +156,4 @@ abstract class UnixBuilderBase extends BuilderBase
} }
return $extra; return $extra;
} }
public function proveLibs(array $sorted_libraries): void
{
// search all supported libs
$support_lib_list = [];
$classes = FileSystem::getClassesPsr4(
ROOT_DIR . '/src/SPC/builder/' . osfamily2dir() . '/library',
'SPC\\builder\\' . osfamily2dir() . '\\library'
);
foreach ($classes as $class) {
if (defined($class . '::NAME') && $class::NAME !== 'unknown' && Config::getLib($class::NAME) !== null) {
$support_lib_list[$class::NAME] = $class;
}
}
// if no libs specified, compile all supported libs
if ($sorted_libraries === [] && $this->isLibsOnly()) {
$libraries = array_keys($support_lib_list);
$sorted_libraries = DependencyUtil::getLibs($libraries);
}
// pkg-config must be compiled first, whether it is specified or not
if (!in_array('pkg-config', $sorted_libraries)) {
array_unshift($sorted_libraries, 'pkg-config');
}
// add lib object for builder
foreach ($sorted_libraries as $library) {
// if some libs are not supported (but in config "lib.json", throw exception)
if (!isset($support_lib_list[$library])) {
throw new WrongUsageException('library [' . $library . '] is in the lib.json list but not supported to compile, but in the future I will support it!');
}
$lib = new ($support_lib_list[$library])($this);
$this->addLib($lib);
}
// calculate and check dependencies
foreach ($this->libs as $lib) {
$lib->calcDependency();
}
// patch point
$this->emitPatchPoint('before-libs-extract');
// extract sources
SourceManager::initSource(libs: $sorted_libraries);
$this->emitPatchPoint('after-libs-extract');
}
/**
* Sanity check after build complete
*
* @throws RuntimeException
*/
protected function sanityCheck(int $build_target): void
{
// sanity check for php-cli
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
logger()->info('running cli sanity check');
[$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "echo \"hello\";"');
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
throw new RuntimeException('cli failed sanity check');
}
foreach ($this->exts as $ext) {
logger()->debug('testing ext: ' . $ext->getName());
$ext->runCliCheckUnix();
}
}
// sanity check for phpmicro
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
$test_task = $this->getMicroTestTasks();
foreach ($test_task as $task_name => $task) {
$test_file = SOURCE_PATH . '/' . $task_name . '.exe';
if (file_exists($test_file)) {
@unlink($test_file);
}
file_put_contents($test_file, file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') . $task['content']);
chmod($test_file, 0755);
[$ret, $out] = shell()->execWithResult($test_file);
foreach ($task['conditions'] as $condition => $closure) {
if (!$closure($ret, $out)) {
$raw_out = trim(implode('', $out));
throw new RuntimeException("micro failed sanity check: {$task_name}, condition [{$condition}], ret[{$ret}], out[{$raw_out}]");
}
}
}
}
}
/**
* 将编译好的二进制文件发布到 buildroot
*
* @param int $type 发布类型
* @throws RuntimeException
* @throws FileSystemException
*/
protected function deployBinary(int $type): bool
{
$src = match ($type) {
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm',
default => throw new RuntimeException('Deployment does not accept type ' . $type),
};
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
FileSystem::createDir(BUILD_ROOT_PATH . '/bin');
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '/bin/'));
return true;
}
/**
* Run php clean
*
* @throws RuntimeException
*/
protected function cleanMake(): void
{
logger()->info('cleaning up');
shell()->cd(SOURCE_PATH . '/php-src')->exec('make clean');
}
} }

View File

@@ -12,6 +12,8 @@ use SPC\store\FileSystem;
trait UnixLibraryTrait trait UnixLibraryTrait
{ {
use LibraryTrait;
/** /**
* @throws RuntimeException * @throws RuntimeException
* @throws FileSystemException * @throws FileSystemException
@@ -48,7 +50,7 @@ trait UnixLibraryTrait
* @throws RuntimeException * @throws RuntimeException
* @throws WrongUsageException * @throws WrongUsageException
*/ */
public function makeAutoconfEnv(?string $prefix = null): string public function makeAutoconfEnv(string $prefix = null): string
{ {
if ($prefix === null) { if ($prefix === null) {
$prefix = str_replace('-', '_', strtoupper(static::NAME)); $prefix = str_replace('-', '_', strtoupper(static::NAME));
@@ -99,19 +101,4 @@ trait UnixLibraryTrait
} }
} }
} }
public function getLibExtraCFlags(): string
{
return getenv($this->getSnakeCaseName() . '_CFLAGS') ?: '';
}
public function getLibExtraLdFlags(): string
{
return getenv($this->getSnakeCaseName() . '_LDFLAGS') ?: '';
}
public function getLibExtraLibs(): string
{
return getenv($this->getSnakeCaseName() . '_LIBS') ?: '';
}
} }

View File

@@ -18,17 +18,19 @@ trait brotli
{ {
FileSystem::resetDir($this->source_dir . '/build-dir'); FileSystem::resetDir($this->source_dir . '/build-dir');
shell()->cd($this->source_dir . '/build-dir') shell()->cd($this->source_dir . '/build-dir')
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) ->exec(
->execWithEnv(
'cmake ' . 'cmake ' .
"{$this->builder->makeCmakeArgs()} " . "{$this->builder->makeCmakeArgs()} " .
'-DBUILD_SHARED_LIBS=OFF ' . '-DBUILD_SHARED_LIBS=OFF ' .
'..' '..'
) )
->execWithEnv("cmake --build . -j {$this->builder->concurrency}") ->exec("cmake --build . -j {$this->builder->concurrency}")
->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); ->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['libbrotlicommon.pc', 'libbrotlidec.pc', 'libbrotlienc.pc']); $this->patchPkgconfPrefix(['libbrotlicommon.pc', 'libbrotlidec.pc', 'libbrotlienc.pc']);
shell()->cd(BUILD_ROOT_PATH . '/lib')->exec('ln -sf libbrotlicommon.a libbrotli.a'); shell()->cd(BUILD_ROOT_PATH . '/lib')
->exec('ln -s libbrotlicommon.a libbrotlicommon-static.a')
->exec('ln -s libbrotlidec.a libbrotlidec-static.a')
->exec('ln -s libbrotlienc.a libbrotlienc-static.a');
foreach (FileSystem::scanDirFiles(BUILD_ROOT_PATH . '/lib/', false, true) as $filename) { foreach (FileSystem::scanDirFiles(BUILD_ROOT_PATH . '/lib/', false, true) as $filename) {
if (str_starts_with($filename, 'libbrotli') && (str_contains($filename, '.so') || str_ends_with($filename, '.dylib'))) { if (str_starts_with($filename, 'libbrotli') && (str_contains($filename, '.so') || str_ends_with($filename, '.dylib'))) {
unlink(BUILD_ROOT_PATH . '/lib/' . $filename); unlink(BUILD_ROOT_PATH . '/lib/' . $filename);

View File

@@ -9,9 +9,8 @@ trait bzip2
protected function build(): void protected function build(): void
{ {
shell()->cd($this->source_dir) shell()->cd($this->source_dir)
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) ->exec("make PREFIX='" . BUILD_ROOT_PATH . "' clean")
->execWithEnv("make PREFIX='" . BUILD_ROOT_PATH . "' clean") ->exec("make -j{$this->builder->concurrency} {$this->builder->getEnvString()} PREFIX='" . BUILD_ROOT_PATH . "' libbz2.a")
->execWithEnv("make -j{$this->builder->concurrency} {$this->builder->getEnvString()} PREFIX='" . BUILD_ROOT_PATH . "' libbz2.a")
->exec('cp libbz2.a ' . BUILD_LIB_PATH) ->exec('cp libbz2.a ' . BUILD_LIB_PATH)
->exec('cp bzlib.h ' . BUILD_INCLUDE_PATH); ->exec('cp bzlib.h ' . BUILD_INCLUDE_PATH);
} }

Some files were not shown because too many files have changed in this diff Show More