mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-13 11:55:36 +08:00
Compare commits
32 Commits
fix/protob
...
57dd174aff
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57dd174aff | ||
|
|
80effd029f | ||
|
|
1c79cc9f61 | ||
|
|
491eb5c2f2 | ||
|
|
8632a4e005 | ||
|
|
4b44c3adf7 | ||
|
|
a950498fd4 | ||
|
|
48294c9c5f | ||
|
|
ce155987ad | ||
|
|
32a98bb8a1 | ||
|
|
8cec136656 | ||
|
|
8ec50c88ca | ||
|
|
5ec194efb2 | ||
|
|
b8f63ec3b9 | ||
|
|
125d6ca772 | ||
|
|
cedd58443d | ||
|
|
467c7ae667 | ||
|
|
0c30fc2039 | ||
|
|
28b336c666 | ||
|
|
884d7bf56a | ||
|
|
9c8b525f89 | ||
|
|
6cb2b3f28c | ||
|
|
9a954bd75f | ||
|
|
730d304ca2 | ||
|
|
768fd0d4a0 | ||
|
|
ac5f1919b4 | ||
|
|
cc7f9fb44f | ||
|
|
91e089d74a | ||
|
|
14ce15c85e | ||
|
|
fc617134ca | ||
|
|
ff8863d5a1 | ||
|
|
fc053253e7 |
@@ -1,16 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
indent_size = 2
|
||||
|
||||
[*.{yml,yaml,vue,ts}]
|
||||
indent_size = 2
|
||||
6
.github/FUNDING.yml
vendored
6
.github/FUNDING.yml
vendored
@@ -1,9 +1,9 @@
|
||||
# These are supported funding model platforms
|
||||
|
||||
github: [crazywhalecc]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
# ko_fi: crazywhalecc # Replace with a single Ko-fi username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
@@ -11,5 +11,5 @@ issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
|
||||
# noinspection YAMLSchemaValidation
|
||||
buy_me_a_coffee: # crazywhalecc
|
||||
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']
|
||||
|
||||
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
17
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Build PHP or library failed, download failed, doesn't seem to work...
|
||||
title: ''
|
||||
labels: bug
|
||||
body:
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: |
|
||||
Please tell us what you do, what you get and what you expected.
|
||||
Provide with some step-by-step instructions to reproduce the issue.
|
||||
If possible, attach a screenshot or log files in ./log directory.
|
||||
validations:
|
||||
required: true
|
||||
---
|
||||
8
.github/ISSUE_TEMPLATE/feature_request.md
vendored
8
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,8 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: new feature
|
||||
assignees: crazywhalecc
|
||||
|
||||
---
|
||||
10
.github/ISSUE_TEMPLATE/something-want-to-know.md
vendored
10
.github/ISSUE_TEMPLATE/something-want-to-know.md
vendored
@@ -1,10 +0,0 @@
|
||||
---
|
||||
name: Something want to know
|
||||
about: Describe your question about static-php, we will reply ASAP
|
||||
title: ''
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
||||
11
.github/pull_request_template.md
vendored
11
.github/pull_request_template.md
vendored
@@ -7,11 +7,6 @@
|
||||
> If your PR involves the changes mentioned below and completed the action, please tick the corresponding option.
|
||||
> If a modification is not involved, please skip it directly.
|
||||
|
||||
- If you modified `*.php` or `*.json`, run them locally to ensure your changes are valid:
|
||||
- [ ] `composer cs-fix`
|
||||
- [ ] `composer analyse`
|
||||
- [ ] `composer test`
|
||||
- [ ] `bin/spc dev:sort-config`
|
||||
- If it's an extension or dependency update, please ensure the following:
|
||||
- [ ] Add your test combination to `src/globals/test-extensions.php`.
|
||||
- [ ] If adding new or fixing bugs, add commit message containing `extension test` or `test extensions` to trigger full test suite.
|
||||
- [ ] If it's an extension or dependency update, make sure adding related extensions in `src/global/test-extensions.php`.
|
||||
- [ ] If you changed the behavior of static-php-cli, update docs in `./docs/`.
|
||||
- [ ] If you updated `config/xxx.json` content, run `bin/spc dev:sort-config xxx`.
|
||||
|
||||
130
.github/workflows/build-linux-arm.yml
vendored
Normal file
130
.github/workflows/build-linux-arm.yml
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
name: CI on arm linux
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
operating-system:
|
||||
required: true
|
||||
description: Compile target arch (Linux only)
|
||||
type: choice
|
||||
options:
|
||||
- aarch64
|
||||
version:
|
||||
required: true
|
||||
description: php version to compile
|
||||
default: '8.2'
|
||||
type: choice
|
||||
options:
|
||||
- '8.3'
|
||||
- '8.2'
|
||||
- '8.1'
|
||||
- '8.0'
|
||||
- '7.4'
|
||||
build-cli:
|
||||
description: build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: build fpm binary
|
||||
type: boolean
|
||||
extensions:
|
||||
description: extensions to compile (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
prefer-pre-built:
|
||||
description: prefer pre-built binaries (reduce build time)
|
||||
type: boolean
|
||||
default: true
|
||||
debug:
|
||||
description: enable debug logs
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build ${{ inputs.version }} on ${{ inputs.operating-system }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Cache composer dependencies
|
||||
- id: cache-composer-deps
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: composer-dependencies
|
||||
|
||||
# If there's no Composer cache, install dependencies
|
||||
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
|
||||
run: composer update --no-dev --classmap-authoritative
|
||||
|
||||
- name: Generate hashed key for download cache
|
||||
run: |
|
||||
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
|
||||
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ env.INPUT_HASH }}
|
||||
|
||||
# With or without debug
|
||||
- if: inputs.debug == true
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
- if: inputs.prefer-pre-built == true
|
||||
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
|
||||
|
||||
# With target select: cli, micro or both
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
|
||||
|
||||
# If there's no dependencies cache, fetch sources, with or without debug
|
||||
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||
run: SPC_USE_ARCH=${{ inputs.operating-system }} ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
|
||||
|
||||
# Run build command
|
||||
- run: SPC_USE_ARCH=${{ inputs.operating-system }} ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-${{ inputs.version }}-linux-${{ inputs.operating-system }}
|
||||
path: buildroot/bin/php
|
||||
|
||||
# Upload micro self-extracted executable
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: micro-${{ inputs.version }}-linux-${{ inputs.operating-system }}
|
||||
path: buildroot/bin/micro.sfx
|
||||
|
||||
# Upload fpm executable
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-fpm-${{ inputs.version }}-linux-${{ inputs.operating-system }}
|
||||
path: buildroot/bin/php-fpm
|
||||
|
||||
# Upload extensions metadata
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: license-files
|
||||
path: buildroot/license/
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-meta
|
||||
path: |
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
125
.github/workflows/build-linux-x86_64.yml
vendored
Normal file
125
.github/workflows/build-linux-x86_64.yml
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
name: CI on x86_64 linux
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
description: php version to compile
|
||||
default: '8.2'
|
||||
type: choice
|
||||
options:
|
||||
- '8.3'
|
||||
- '8.2'
|
||||
- '8.1'
|
||||
- '8.0'
|
||||
- '7.4'
|
||||
build-cli:
|
||||
description: build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: build fpm binary
|
||||
type: boolean
|
||||
extensions:
|
||||
description: extensions to compile (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
prefer-pre-built:
|
||||
description: prefer pre-built binaries (reduce build time)
|
||||
type: boolean
|
||||
default: true
|
||||
debug:
|
||||
description: enable debug logs
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build ${{ inputs.version }} on Linux x86_64
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Cache composer dependencies
|
||||
- id: cache-composer-deps
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: composer-dependencies
|
||||
|
||||
# If there's no Composer cache, install dependencies
|
||||
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
|
||||
run: composer update --no-dev --classmap-authoritative
|
||||
|
||||
- name: Generate hashed key for download cache
|
||||
run: |
|
||||
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
|
||||
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ env.INPUT_HASH }}
|
||||
|
||||
# With or without debug
|
||||
- if: inputs.debug == true
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
- if: inputs.prefer-pre-built == true
|
||||
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
|
||||
|
||||
# With target select: cli, micro or both
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
|
||||
|
||||
# If there's no dependencies cache, fetch sources, with or without debug
|
||||
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||
run: CACHE_API_EXEC=yes ./bin/spc-alpine-docker download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
|
||||
|
||||
# Run build command
|
||||
- run: ./bin/spc-alpine-docker build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php
|
||||
|
||||
# Upload micro self-extracted executable
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/micro.sfx
|
||||
|
||||
# Upload fpm executable
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php-fpm
|
||||
|
||||
# Upload extensions metadata
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: license-files
|
||||
path: buildroot/license/
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-meta
|
||||
path: |
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
|
||||
139
.github/workflows/build-macos-aarch64.yml
vendored
Normal file
139
.github/workflows/build-macos-aarch64.yml
vendored
Normal file
@@ -0,0 +1,139 @@
|
||||
name: CI on arm64 macOS
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
description: php version to compile
|
||||
default: '8.2'
|
||||
type: choice
|
||||
options:
|
||||
- '8.3'
|
||||
- '8.2'
|
||||
- '8.1'
|
||||
- '8.0'
|
||||
- '7.4'
|
||||
build-cli:
|
||||
description: build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: build fpm binary
|
||||
type: boolean
|
||||
extensions:
|
||||
description: extensions to compile (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
prefer-pre-built:
|
||||
description: prefer pre-built binaries (reduce build time)
|
||||
type: boolean
|
||||
default: true
|
||||
debug:
|
||||
description: enable debug logs
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build ${{ inputs.version }} on macOS arm64
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Install macOS missing packages and mark os suffix
|
||||
- run: |
|
||||
brew install automake gzip
|
||||
echo "SPC_BUILD_OS=macos" >> $GITHUB_ENV
|
||||
|
||||
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
tools: pecl, composer
|
||||
extensions: curl, openssl, mbstring, tokenizer
|
||||
ini-values: memory_limit=-1
|
||||
|
||||
|
||||
# Cache composer dependencies
|
||||
- id: cache-composer-deps
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: composer-dependencies
|
||||
|
||||
# If there's no Composer cache, install dependencies
|
||||
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
|
||||
run: composer update --no-dev --classmap-authoritative
|
||||
|
||||
- name: Generate hashed key for download cache
|
||||
run: |
|
||||
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
|
||||
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ env.INPUT_HASH }}
|
||||
|
||||
# With or without debug
|
||||
- if: inputs.debug == true
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
- if: inputs.prefer-pre-built == true
|
||||
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
|
||||
|
||||
# With target select: cli, micro or both
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
|
||||
|
||||
# If there's no dependencies cache, fetch sources, with or without debug
|
||||
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||
run: ./bin/spc download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
|
||||
|
||||
# Run build command
|
||||
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php
|
||||
|
||||
# Upload micro self-extracted executable
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/micro.sfx
|
||||
|
||||
# Upload fpm executable
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php-fpm
|
||||
|
||||
# Upload extensions metadata
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: license-files
|
||||
path: buildroot/license/
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-meta
|
||||
path: |
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
138
.github/workflows/build-macos-x86_64.yml
vendored
Normal file
138
.github/workflows/build-macos-x86_64.yml
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
name: CI on x86_64 macOS
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
required: true
|
||||
description: php version to compile
|
||||
default: '8.2'
|
||||
type: choice
|
||||
options:
|
||||
- '8.3'
|
||||
- '8.2'
|
||||
- '8.1'
|
||||
- '8.0'
|
||||
- '7.4'
|
||||
build-cli:
|
||||
description: build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: build fpm binary
|
||||
type: boolean
|
||||
extensions:
|
||||
description: extensions to compile (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
prefer-pre-built:
|
||||
description: prefer pre-built binaries (reduce build time)
|
||||
type: boolean
|
||||
default: true
|
||||
debug:
|
||||
description: enable debug logs
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build ${{ inputs.version }} on macOS x86_64
|
||||
runs-on: macos-13
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# Install macOS missing packages and mark os suffix
|
||||
- run: |
|
||||
brew install automake gzip
|
||||
echo "SPC_BUILD_OS=macos" >> $GITHUB_ENV
|
||||
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
tools: pecl, composer
|
||||
extensions: curl, openssl, mbstring, tokenizer
|
||||
ini-values: memory_limit=-1
|
||||
|
||||
# Cache composer dependencies
|
||||
- id: cache-composer-deps
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: composer-dependencies
|
||||
|
||||
# If there's no Composer cache, install dependencies
|
||||
- if: steps.cache-composer-deps.outputs.cache-hit != 'true'
|
||||
run: composer update --no-dev --classmap-authoritative
|
||||
|
||||
- name: Generate hashed key for download cache
|
||||
run: |
|
||||
INPUT_HASH=$(echo "${{ runner.os }}-${{ inputs.version }}-${{ inputs.extensions }}" | sha256sum | awk '{print $1}')
|
||||
echo "INPUT_HASH=${INPUT_HASH}" >> $GITHUB_ENV
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ env.INPUT_HASH }}
|
||||
|
||||
# With or without debug
|
||||
- if: inputs.debug == true
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
- if: inputs.prefer-pre-built == true
|
||||
run: echo "SPC_PRE_BUILT=--prefer-pre-built" >> $env:GITHUB_ENV
|
||||
|
||||
# With target select: cli, micro or both
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
run: echo "SPC_BUILD_CLI=--build-cli" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
run: echo "SPC_BUILD_MICRO=--build-micro" >> $GITHUB_ENV
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
run: echo "SPC_BUILD_FPM=--build-fpm" >> $GITHUB_ENV
|
||||
|
||||
# If there's no dependencies cache, fetch sources, with or without debug
|
||||
- if: steps.cache-download.outputs.cache-hit != 'true'
|
||||
run: ./bin/spc download --with-php=${{ inputs.version }} --for-extensions=${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_PRE_BUILT }}
|
||||
|
||||
# Run build command
|
||||
- run: ./bin/spc build ${{ inputs.extensions }} ${{ env.SPC_BUILD_DEBUG }} ${{ env.SPC_BUILD_CLI }} ${{ env.SPC_BUILD_MICRO }} ${{ env.SPC_BUILD_FPM }}
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php
|
||||
|
||||
# Upload micro self-extracted executable
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: micro-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/micro.sfx
|
||||
|
||||
# Upload fpm executable
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-fpm-${{ inputs.version }}-${{ env.SPC_BUILD_OS }}
|
||||
path: buildroot/bin/php-fpm
|
||||
|
||||
# Upload extensions metadata
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: license-files
|
||||
path: buildroot/license/
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-meta
|
||||
path: |
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
|
||||
335
.github/workflows/build-unix.yml
vendored
335
.github/workflows/build-unix.yml
vendored
@@ -1,335 +0,0 @@
|
||||
name: "CI on Unix"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
description: Build target OS
|
||||
default: 'linux-x86_64'
|
||||
type: choice
|
||||
options:
|
||||
- 'linux-x86_64'
|
||||
- 'linux-aarch64'
|
||||
- 'linux-x86_64-glibc'
|
||||
- 'linux-aarch64-glibc'
|
||||
- 'macos-x86_64'
|
||||
- 'macos-aarch64'
|
||||
php-version:
|
||||
required: true
|
||||
description: PHP version to compile
|
||||
default: '8.4'
|
||||
type: choice
|
||||
options:
|
||||
- '8.4'
|
||||
- '8.3'
|
||||
- '8.2'
|
||||
- '8.1'
|
||||
extensions:
|
||||
description: Extensions to build (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
shared-extensions:
|
||||
description: Shared extensions to build (optional, comma separated)
|
||||
type: string
|
||||
extra-libs:
|
||||
description: Extra libraries to build (optional, comma separated)
|
||||
type: string
|
||||
build-cli:
|
||||
description: Build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: Build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: Build fpm binary
|
||||
type: boolean
|
||||
build-frankenphp:
|
||||
description: Build frankenphp binary (requires ZTS)
|
||||
type: boolean
|
||||
default: false
|
||||
enable-zts:
|
||||
description: Enable ZTS
|
||||
type: boolean
|
||||
default: false
|
||||
prefer-pre-built:
|
||||
description: Prefer pre-built binaries (reduce build time)
|
||||
type: boolean
|
||||
default: true
|
||||
with-suggested-libs:
|
||||
description: Build with suggested libs
|
||||
type: boolean
|
||||
default: false
|
||||
debug:
|
||||
description: Show full build logs
|
||||
type: boolean
|
||||
no-strip:
|
||||
description: Keep debug symbols for debugging
|
||||
type: boolean
|
||||
default: false
|
||||
workflow_call:
|
||||
inputs:
|
||||
os:
|
||||
required: true
|
||||
description: Build target OS
|
||||
default: 'linux-x86_64'
|
||||
type: string
|
||||
php-version:
|
||||
required: true
|
||||
description: PHP version to compile
|
||||
default: '8.4'
|
||||
type: string
|
||||
extensions:
|
||||
description: Extensions to build (comma separated)
|
||||
required: true
|
||||
type: string
|
||||
shared-extensions:
|
||||
description: Shared extensions to build (optional, comma separated)
|
||||
type: string
|
||||
extra-libs:
|
||||
description: Extra libraries to build (optional, comma separated)
|
||||
type: string
|
||||
build-cli:
|
||||
description: Build cli binary
|
||||
default: true
|
||||
type: boolean
|
||||
build-micro:
|
||||
description: Build phpmicro binary
|
||||
type: boolean
|
||||
build-fpm:
|
||||
description: Build fpm binary
|
||||
type: boolean
|
||||
build-frankenphp:
|
||||
description: Build frankenphp binary (requires ZTS)
|
||||
type: boolean
|
||||
default: false
|
||||
enable-zts:
|
||||
description: Enable ZTS
|
||||
type: boolean
|
||||
default: false
|
||||
prefer-pre-built:
|
||||
description: Prefer pre-built binaries (reduce build time)
|
||||
type: boolean
|
||||
default: true
|
||||
with-suggested-libs:
|
||||
description: Include suggested libs
|
||||
type: boolean
|
||||
default: false
|
||||
debug:
|
||||
description: Show full build logs
|
||||
type: boolean
|
||||
no-strip:
|
||||
description: Keep debug symbols for debugging
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
jobs:
|
||||
define-build:
|
||||
name: "Define Build Scripts"
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
run: ${{ steps.gendef.outputs.run }}
|
||||
download: ${{ steps.gendef.outputs.download }}
|
||||
build: ${{ steps.gendef.outputs.build }}
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Define"
|
||||
id: gendef
|
||||
run: |
|
||||
case "${{ inputs.os }}" in
|
||||
linux-x86_64)
|
||||
DOWN_CMD="./bin/spc-alpine-docker download"
|
||||
BUILD_CMD="./bin/spc-alpine-docker build"
|
||||
RUNS_ON="ubuntu-latest"
|
||||
;;
|
||||
linux-aarch64)
|
||||
DOWN_CMD="./bin/spc-alpine-docker download"
|
||||
BUILD_CMD="./bin/spc-alpine-docker build"
|
||||
RUNS_ON="ubuntu-24.04-arm"
|
||||
;;
|
||||
linux-x86_64-glibc)
|
||||
DOWN_CMD="./bin/spc-gnu-docker download"
|
||||
BUILD_CMD="./bin/spc-gnu-docker build"
|
||||
RUNS_ON="ubuntu-22.04"
|
||||
;;
|
||||
linux-aarch64-glibc)
|
||||
DOWN_CMD="./bin/spc-gnu-docker download"
|
||||
BUILD_CMD="./bin/spc-gnu-docker build"
|
||||
RUNS_ON="ubuntu-22.04-arm"
|
||||
;;
|
||||
macos-x86_64)
|
||||
DOWN_CMD="composer update --no-dev --classmap-authoritative && ./bin/spc doctor --auto-fix && ./bin/spc download"
|
||||
BUILD_CMD="./bin/spc build"
|
||||
RUNS_ON="macos-15-intel"
|
||||
;;
|
||||
macos-aarch64)
|
||||
DOWN_CMD="composer update --no-dev --classmap-authoritative && ./bin/spc doctor --auto-fix && ./bin/spc download"
|
||||
BUILD_CMD="./bin/spc build"
|
||||
RUNS_ON="macos-15"
|
||||
;;
|
||||
esac
|
||||
STATIC_EXTS="${{ inputs.extensions }}"
|
||||
SHARED_EXTS="${{ inputs['shared-extensions'] }}"
|
||||
BUILD_FRANKENPHP="${{ inputs['build-frankenphp'] }}"
|
||||
ENABLE_ZTS="${{ inputs['enable-zts'] }}"
|
||||
ALL_EXTS="$STATIC_EXTS"
|
||||
if [ -n "$SHARED_EXTS" ]; then
|
||||
ALL_EXTS="$ALL_EXTS,$SHARED_EXTS"
|
||||
fi
|
||||
DOWN_CMD="$DOWN_CMD --with-php=${{ inputs.php-version }} --for-extensions=$ALL_EXTS --ignore-cache-sources=php-src"
|
||||
BUILD_CMD="$BUILD_CMD $STATIC_EXTS"
|
||||
if [ -n "$SHARED_EXTS" ]; then
|
||||
BUILD_CMD="$BUILD_CMD --build-shared=$SHARED_EXTS"
|
||||
fi
|
||||
if [ -n "${{ inputs.extra-libs }}" ]; then
|
||||
DOWN_CMD="$DOWN_CMD --for-libs=${{ inputs.extra-libs }}"
|
||||
BUILD_CMD="$BUILD_CMD --with-libs=${{ inputs.extra-libs }}"
|
||||
fi
|
||||
if [ ${{ inputs.debug }} == true ]; then
|
||||
DOWN_CMD="$DOWN_CMD --debug"
|
||||
BUILD_CMD="$BUILD_CMD --debug"
|
||||
fi
|
||||
if [ ${{ inputs.prefer-pre-built }} == true ]; then
|
||||
DOWN_CMD="$DOWN_CMD --prefer-pre-built"
|
||||
fi
|
||||
if [ ${{ inputs.with-suggested-libs }} == true ]; then
|
||||
BUILD_CMD="$BUILD_CMD --with-suggested-libs"
|
||||
fi
|
||||
if [ ${{ inputs.build-cli }} == true ]; then
|
||||
BUILD_CMD="$BUILD_CMD --build-cli"
|
||||
fi
|
||||
if [ ${{ inputs.build-micro }} == true ]; then
|
||||
BUILD_CMD="$BUILD_CMD --build-micro"
|
||||
fi
|
||||
if [ ${{ inputs.build-fpm }} == true ]; then
|
||||
BUILD_CMD="$BUILD_CMD --build-fpm"
|
||||
fi
|
||||
if [ "$BUILD_FRANKENPHP" = "true" ]; then
|
||||
BUILD_CMD="$BUILD_CMD --build-frankenphp"
|
||||
fi
|
||||
if [ "$ENABLE_ZTS" = "true" ]; then
|
||||
BUILD_CMD="$BUILD_CMD --enable-zts"
|
||||
fi
|
||||
echo 'download='"$DOWN_CMD" >> "$GITHUB_OUTPUT"
|
||||
echo 'build='"$BUILD_CMD" >> "$GITHUB_OUTPUT"
|
||||
echo 'run='"$RUNS_ON" >> "$GITHUB_OUTPUT"
|
||||
build:
|
||||
name: "Build ${{ inputs.version }} on ${{ inputs.os }}"
|
||||
runs-on: ${{ needs.define-build.outputs.run }}
|
||||
needs: define-build
|
||||
timeout-minutes: 240
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
tools: pecl, composer
|
||||
extensions: curl, openssl, mbstring
|
||||
ini-values: memory_limit=-1
|
||||
env:
|
||||
phpts: nts
|
||||
|
||||
- if: ${{ inputs['build-frankenphp'] == true }}
|
||||
name: "Install go-xcaddy for FrankenPHP"
|
||||
run: |
|
||||
case "${{ inputs.os }}" in
|
||||
linux-x86_64|linux-aarch64)
|
||||
./bin/spc-alpine-docker install-pkg go-xcaddy
|
||||
;;
|
||||
linux-x86_64-glibc|linux-aarch64-glibc)
|
||||
./bin/spc-gnu-docker install-pkg go-xcaddy
|
||||
;;
|
||||
macos-x86_64|macos-aarch64)
|
||||
composer update --no-dev --classmap-authoritative
|
||||
./bin/spc doctor --auto-fix
|
||||
./bin/spc install-pkg go-xcaddy
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS for go-xcaddy install: ${{ inputs.os }}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Cache downloaded source
|
||||
- id: cache-download
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-dependencies-${{ inputs.os }}
|
||||
- name: "Download sources"
|
||||
run: ${{ needs.define-build.outputs.download }}
|
||||
- name: "Build PHP"
|
||||
run: ${{ needs.define-build.outputs.build }}
|
||||
# - name: Setup tmate session
|
||||
# if: ${{ failure() }}
|
||||
# uses: mxschmitt/action-tmate@v3
|
||||
|
||||
# Upload debug logs
|
||||
- if: ${{ inputs.debug && failure() }}
|
||||
name: "Upload build logs on failure"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: spc-logs-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: log/*.log
|
||||
|
||||
# Upload cli executable
|
||||
- if: ${{ inputs.build-cli == true }}
|
||||
name: "Upload PHP cli SAPI"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-cli-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: buildroot/bin/php
|
||||
|
||||
# Upload micro self-extracted executable
|
||||
- if: ${{ inputs.build-micro == true }}
|
||||
name: "Upload PHP micro SAPI"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-micro-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: buildroot/bin/micro.sfx
|
||||
|
||||
# Upload fpm executable
|
||||
- if: ${{ inputs.build-fpm == true }}
|
||||
name: "Upload PHP fpm SAPI"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-fpm-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: buildroot/bin/php-fpm
|
||||
|
||||
# Upload frankenphp executable
|
||||
- if: ${{ inputs['build-frankenphp'] == true }}
|
||||
name: "Upload FrankenPHP SAPI"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-frankenphp-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: buildroot/bin/frankenphp
|
||||
|
||||
# Upload extensions metadata
|
||||
- if: ${{ inputs['shared-extensions'] != '' }}
|
||||
name: "Upload shared extensions"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: php-shared-ext-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: |
|
||||
buildroot/modules/*.so
|
||||
- uses: actions/upload-artifact@v4
|
||||
name: "Upload License Files"
|
||||
with:
|
||||
name: license-files-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: buildroot/license/
|
||||
- uses: actions/upload-artifact@v4
|
||||
name: "Upload Build Metadata"
|
||||
with:
|
||||
name: build-meta-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: |
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
4
.github/workflows/build-windows-x86_64.yml
vendored
4
.github/workflows/build-windows-x86_64.yml
vendored
@@ -6,14 +6,14 @@ on:
|
||||
version:
|
||||
required: true
|
||||
description: php version to compile
|
||||
default: '8.4'
|
||||
default: '8.2'
|
||||
type: choice
|
||||
options:
|
||||
- '8.4'
|
||||
- '8.3'
|
||||
- '8.2'
|
||||
- '8.1'
|
||||
- '8.0'
|
||||
- '7.4'
|
||||
build-cli:
|
||||
description: build cli binary
|
||||
default: true
|
||||
|
||||
139
.github/workflows/ext-matrix-tests.yml
vendored
139
.github/workflows/ext-matrix-tests.yml
vendored
@@ -1,139 +0,0 @@
|
||||
name: "Extension Matrix Tests"
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: "${{ matrix.extension }} (PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }})"
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
if: contains(github.event.head_commit.message, 'extension test') || contains(github.event.head_commit.message, 'test extensions')
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
extension:
|
||||
- amqp
|
||||
- apcu
|
||||
- bcmath
|
||||
- bz2
|
||||
- calendar
|
||||
- ctype
|
||||
- curl
|
||||
- dba
|
||||
- dom
|
||||
- ds
|
||||
- event
|
||||
- exif
|
||||
- filter
|
||||
- fileinfo
|
||||
- ftp
|
||||
- gd
|
||||
- gettext
|
||||
- gmp
|
||||
- iconv
|
||||
- igbinary
|
||||
- imagick
|
||||
- imap
|
||||
- intl
|
||||
- ldap
|
||||
- mbstring,mbregex
|
||||
- memcache
|
||||
- mysqli,mysqlnd,pdo_mysql
|
||||
- opcache
|
||||
- openssl
|
||||
- pcntl
|
||||
- password-argon2
|
||||
- pcntl
|
||||
- pdo
|
||||
- pgsql,pdo_pgsql
|
||||
- phar
|
||||
- posix
|
||||
- rar
|
||||
- protobuf
|
||||
- readline
|
||||
- redis
|
||||
- session
|
||||
- shmop
|
||||
- simdjson
|
||||
- simplexml,xml
|
||||
- snappy
|
||||
- soap
|
||||
- sockets
|
||||
- sodium
|
||||
- sqlite3,pdo_sqlite
|
||||
- sqlsrv
|
||||
- ssh2
|
||||
- swoole
|
||||
- swoole,swoole-hook-pgsql,swoole-hook-mysql,swoole-hook-sqlite,swoole-hook-odbc
|
||||
- swow
|
||||
- sysvmsg,sysvsem,sysvshm
|
||||
- tidy
|
||||
- tokenizer
|
||||
- uuid
|
||||
- uv
|
||||
- xhprof
|
||||
- xlswriter
|
||||
- xmlwriter,xmlreader
|
||||
- xsl
|
||||
- yac
|
||||
- yaml
|
||||
- zip
|
||||
- zlib
|
||||
- zstd
|
||||
php-version:
|
||||
- "8.4"
|
||||
operating-system:
|
||||
- "ubuntu-latest"
|
||||
#- "macos-15-intel"
|
||||
#- "debian-arm64-self-hosted"
|
||||
- "macos-15"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v4"
|
||||
|
||||
- name: OS type
|
||||
id: os-type
|
||||
run: |
|
||||
OS=""
|
||||
if [ "${{ matrix.operating-system }}" = "ubuntu-latest" ]; then
|
||||
OS="linux-x86_64"
|
||||
elif [ "${{ matrix.operating-system }}" = "macos-15-intel" ]; then
|
||||
OS="macos-x86_64"
|
||||
elif [ "${{ matrix.operating-system }}" = "debian-arm64-self-hosted" ]; then
|
||||
OS="linux-aarch64"
|
||||
elif [ "${{ matrix.operating-system }}" = "macos-15" ]; then
|
||||
OS="macos-aarch64"
|
||||
fi
|
||||
echo "OS=$OS" >> $GITHUB_ENV
|
||||
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
tools: pecl, composer
|
||||
extensions: curl, openssl, mbstring
|
||||
ini-values: memory_limit=-1
|
||||
env:
|
||||
phpts: nts
|
||||
|
||||
- name: "Install Dependencies"
|
||||
run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
|
||||
- id: cache-download
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-${{ matrix.php-version }}-dependencies-for-tests
|
||||
|
||||
# If there's no dependencies cache, fetch sources
|
||||
- name: "Download sources"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./bin/spc download --with-php=${{ matrix.php-version }} --for-extensions=${{ matrix.extension }} --debug --ignore-cache-sources=php-src
|
||||
|
||||
- name: "Build library: ${{ matrix.library }}"
|
||||
run: |
|
||||
SPC_USE_SUDO=yes ./bin/spc doctor --auto-fix
|
||||
./bin/spc build --build-cli --build-micro --build-fpm ${{ matrix.extension }} --debug --with-suggested-libs --with-suggested-exts
|
||||
75
.github/workflows/release-build.yml
vendored
75
.github/workflows/release-build.yml
vendored
@@ -3,18 +3,14 @@ name: Build SPC Binary
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
paths:
|
||||
- '.github/workflows/release-build.yml'
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
PHP_VERSION: 8.4
|
||||
MICRO_VERSION: 8.4.11
|
||||
PHP_VERSION: 8.2
|
||||
MICRO_VERSION: 8.2.18
|
||||
|
||||
jobs:
|
||||
build-release-artifacts:
|
||||
@@ -27,7 +23,7 @@ jobs:
|
||||
os: "ubuntu-latest"
|
||||
filename: "spc-linux-x86_64.tar.gz"
|
||||
- name: "macos-x86_64"
|
||||
os: "macos-15-intel"
|
||||
os: "macos-13"
|
||||
filename: "spc-macos-x86_64.tar.gz"
|
||||
- name: "linux-aarch64"
|
||||
os: "ubuntu-latest"
|
||||
@@ -46,13 +42,12 @@ jobs:
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
|
||||
- name: "Install PHP for official runners"
|
||||
uses: shivammathur/setup-php@v2
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: none
|
||||
tools: composer:v2
|
||||
php-version: "${{ env.PHP_VERSION }}"
|
||||
ini-values: memory_limit=-1
|
||||
extensions: curl, openssl, mbstring
|
||||
|
||||
- name: "Get Composer Cache Directory"
|
||||
id: composer-cache
|
||||
@@ -76,10 +71,10 @@ jobs:
|
||||
- name: "Download Minimal Combination"
|
||||
run: |
|
||||
if [ "${{ matrix.operating-system.name }}" = "windows-x64" ]; then
|
||||
curl -fsSL https://dl.static-php.dev/static-php-cli/windows/spc-min/php-${{ env.MICRO_VERSION }}-micro-win.zip -o tmp.zip
|
||||
curl https://dl.static-php.dev/static-php-cli/windows/spc-min/php-${{ env.MICRO_VERSION }}-micro-win.zip -o tmp.zip
|
||||
unzip tmp.zip
|
||||
else
|
||||
curl -fsSL https://dl.static-php.dev/static-php-cli/minimal/php-${{ env.MICRO_VERSION }}-micro-${{ matrix.operating-system.name }}.tar.gz -o tmp.tgz
|
||||
curl https://dl.static-php.dev/static-php-cli/minimal/php-${{ env.MICRO_VERSION }}-micro-${{ matrix.operating-system.name }}.tar.gz -o tmp.tgz
|
||||
tar -zxvf tmp.tgz
|
||||
fi
|
||||
|
||||
@@ -120,56 +115,20 @@ jobs:
|
||||
with:
|
||||
files: dist/${{ matrix.operating-system.filename }}
|
||||
|
||||
- name: "Deploy to self-hosted OSS"
|
||||
# only run this step if the repository is static-php-cli and the branch is main
|
||||
if: github.repository == 'crazywhalecc/static-php-cli' && github.ref == 'refs/heads/main'
|
||||
uses: static-php/upload-s3-action@v1.0.0
|
||||
with:
|
||||
aws_key_id: ${{ secrets.AWS_KEY_ID }}
|
||||
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
aws_bucket: ${{ secrets.AWS_BUCKET }}
|
||||
source_dir: "dist/"
|
||||
destination_dir: static-php-cli/spc-bin/nightly/
|
||||
endpoint: ${{ secrets.AWS_ENDPOINT }}
|
||||
- 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"
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: spc${{ env.SUFFIX }}
|
||||
name: spc-${{ matrix.operating-system.name }}${{ env.SUFFIX }}
|
||||
test-spc:
|
||||
name: "Test SPC Binary for ${{ matrix.operating-system.name }}"
|
||||
runs-on: ${{ matrix.operating-system.os }}
|
||||
needs: [build-release-artifacts]
|
||||
strategy:
|
||||
matrix:
|
||||
operating-system:
|
||||
- name: "linux-x86_64"
|
||||
os: "ubuntu-latest"
|
||||
- name: "macos-x86_64"
|
||||
os: "macos-15-intel"
|
||||
- name: "linux-aarch64"
|
||||
os: "ubuntu-24.04-arm"
|
||||
- name: "macos-aarch64"
|
||||
os: "macos-15"
|
||||
- name: "windows-x64"
|
||||
os: "windows-latest"
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Download Artifact"
|
||||
uses: actions/download-artifact@v4
|
||||
env:
|
||||
SUFFIX: ${{ matrix.operating-system.name == 'windows-x64' && '.exe' || '' }}
|
||||
with:
|
||||
name: spc-${{ matrix.operating-system.name }}${{ env.SUFFIX }}
|
||||
|
||||
- name: "Chmod"
|
||||
if: matrix.operating-system.name != 'windows-x64'
|
||||
run: chmod +x spc
|
||||
|
||||
- name: "Run SPC Tests"
|
||||
env:
|
||||
SUFFIX: ${{ matrix.operating-system.name == 'windows-x64' && '.exe' || '' }}
|
||||
run: ./spc${{ env.SUFFIX }} dev:extensions
|
||||
|
||||
111
.github/workflows/tests.yml
vendored
111
.github/workflows/tests.yml
vendored
@@ -1,9 +1,13 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/globals/test-extensions.php'
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
types: [ opened, synchronize, reopened ]
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'config/**'
|
||||
@@ -13,7 +17,8 @@ on:
|
||||
- 'box.json'
|
||||
- '.php-cs-fixer.php'
|
||||
|
||||
permissions: read-all
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -29,7 +34,7 @@ jobs:
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.4'
|
||||
php-version: '8.1'
|
||||
extensions: curl, openssl, mbstring
|
||||
ini-values: memory_limit=-1
|
||||
tools: pecl, composer, php-cs-fixer
|
||||
@@ -47,12 +52,10 @@ jobs:
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.4'
|
||||
php-version: '8.1'
|
||||
extensions: curl, openssl, mbstring
|
||||
ini-values: memory_limit=-1
|
||||
tools: composer
|
||||
env:
|
||||
phpts: zts
|
||||
|
||||
- name: "Cache Composer packages"
|
||||
id: composer-cache
|
||||
@@ -76,7 +79,9 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- php: '8.4'
|
||||
- php: '8.1'
|
||||
- php: '8.2'
|
||||
- php: '8.3'
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
@@ -97,66 +102,43 @@ jobs:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php
|
||||
${{ runner.os }}-php-
|
||||
|
||||
- name: "Install Dependencies"
|
||||
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
|
||||
- name: "Run PHPUnit Tests"
|
||||
run: SPC_LIBC=glibc vendor/bin/phpunit tests/ --no-coverage
|
||||
|
||||
define-matrix:
|
||||
name: "Define Matrix"
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
php: ${{ steps.gendef.outputs.php }}
|
||||
os: ${{ steps.gendef.outputs.os }}
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
extensions: curl, openssl, mbstring
|
||||
|
||||
- name: Define
|
||||
id: gendef
|
||||
run: |
|
||||
PHP_VERSIONS=$(php src/globals/test-extensions.php php)
|
||||
OS_VERSIONS=$(php src/globals/test-extensions.php os)
|
||||
echo 'php='"$PHP_VERSIONS" >> "$GITHUB_OUTPUT"
|
||||
echo 'os='"$OS_VERSIONS" >> "$GITHUB_OUTPUT"
|
||||
|
||||
vendor/bin/phpunit tests/ --no-coverage
|
||||
|
||||
build:
|
||||
name: "Build PHP Test (PHP ${{ matrix.php }} ${{ matrix.os }})"
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [define-matrix, php-cs-fixer, phpstan, phpunit]
|
||||
timeout-minutes: 120
|
||||
strategy:
|
||||
matrix:
|
||||
php: ${{ fromJSON(needs.define-matrix.outputs.php) }}
|
||||
os: ${{ fromJSON(needs.define-matrix.outputs.os) }}
|
||||
php:
|
||||
- "8.0"
|
||||
- "8.1"
|
||||
- "8.2"
|
||||
- "8.3"
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macos-13
|
||||
- windows-latest
|
||||
- macos-14
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: "Update runner packages"
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
|
||||
run: sudo apt-get update && sudo apt-get install -y ca-certificates
|
||||
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: "Setup PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
php-version: 8.2
|
||||
tools: pecl, composer
|
||||
extensions: curl, openssl, mbstring
|
||||
ini-values: memory_limit=-1
|
||||
env:
|
||||
phpts: nts
|
||||
|
||||
- name: "Cache composer packages"
|
||||
id: composer-cache
|
||||
@@ -172,43 +154,40 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: php-dependencies-${{ matrix.os }}
|
||||
key: php-${{ matrix.php }}-dependencies
|
||||
|
||||
- name: "Install Dependencies"
|
||||
run: composer update -vvv --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist --no-plugins
|
||||
run: composer update -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
|
||||
- name: "Run Build Tests (doctor)"
|
||||
run: php src/globals/test-extensions.php doctor_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
run: bin/spc doctor --auto-fix
|
||||
|
||||
- name: "Prepare UPX for Windows"
|
||||
if: ${{ startsWith(matrix.os, 'windows-') }}
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: |
|
||||
php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
bin/spc install-pkg upx
|
||||
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV
|
||||
|
||||
- name: "Prepare UPX for Linux"
|
||||
if: ${{ startsWith(matrix.os, 'ubuntu-') }}
|
||||
if: matrix.os == 'ubunut-latest'
|
||||
run: |
|
||||
php src/globals/test-extensions.php install_upx_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
bin/spc install-pkg upx
|
||||
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV
|
||||
|
||||
- name: "Run Build Tests (download)"
|
||||
run: php src/globals/test-extensions.php download_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
run: |
|
||||
bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --for-libs="$(php src/globals/test-extensions.php libs)" --with-php=${{ matrix.php }} --ignore-cache-sources=php-src --debug --retry=5 --shallow-clone
|
||||
|
||||
- name: "Run Build Tests (build)"
|
||||
run: php src/globals/test-extensions.php build_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
- name: "Download pre-built libraries for pkg-config"
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: |
|
||||
bin/spc del-download pkg-config
|
||||
bin/spc download pkg-config --prefer-pre-built --debug
|
||||
|
||||
- name: "Run Build Tests (build - embed for non-windows)"
|
||||
if: ${{ !startsWith(matrix.os, 'windows-') }}
|
||||
run: php src/globals/test-extensions.php build_embed_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
- name: "Run Build Tests (build, *nix)"
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug
|
||||
|
||||
- name: "Upload logs"
|
||||
if: ${{ always() && hashFiles('log/**') != '' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-logs-${{ matrix.os }}-${{ matrix.php }}
|
||||
path: log
|
||||
|
||||
# - name: Setup tmate session
|
||||
# if: ${{ failure() }}
|
||||
# uses: mxschmitt/action-tmate@v3
|
||||
- name: "Run Build Tests (build, windows)"
|
||||
if: matrix.os == 'windows-latest'
|
||||
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $env:UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --debug --enable-micro-win32
|
||||
8
.github/workflows/vitepress-deploy.yml
vendored
8
.github/workflows/vitepress-deploy.yml
vendored
@@ -21,6 +21,7 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: yarn
|
||||
|
||||
- run: yarn install --frozen-lockfile
|
||||
@@ -31,13 +32,12 @@ jobs:
|
||||
cp -r config/* docs/.vitepress/config/
|
||||
|
||||
- name: "Install PHP for official runners"
|
||||
uses: shivammathur/setup-php@v2
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
with:
|
||||
coverage: none
|
||||
tools: composer:v2
|
||||
php-version: 8.4
|
||||
php-version: 8.2
|
||||
ini-values: memory_limit=-1
|
||||
extensions: curl, openssl, mbstring
|
||||
|
||||
- name: "Get Composer Cache Directory"
|
||||
id: composer-cache
|
||||
@@ -58,8 +58,6 @@ jobs:
|
||||
- name: "Generate Extension Support List"
|
||||
run: |
|
||||
bin/spc dev:gen-ext-docs > docs/extensions.md
|
||||
bin/spc dev:gen-ext-dep-docs > docs/deps-map-ext.md
|
||||
bin/spc dev:gen-lib-dep-docs > docs/deps-map-lib.md
|
||||
|
||||
- name: Build
|
||||
run: yarn docs:build
|
||||
|
||||
30
.gitignore
vendored
30
.gitignore
vendored
@@ -5,28 +5,22 @@ docker/extensions/
|
||||
docker/source/
|
||||
|
||||
# Vendor files
|
||||
/vendor/**
|
||||
/vendor/
|
||||
|
||||
# default source extract directory
|
||||
/source/**
|
||||
|
||||
# built by shared embed tests
|
||||
/locale/
|
||||
/source/
|
||||
|
||||
# default source download directory
|
||||
/downloads/**
|
||||
/downloads/
|
||||
|
||||
# default source build root directory
|
||||
/buildroot/**
|
||||
/buildroot/
|
||||
|
||||
# default package root directory
|
||||
/pkgroot/**
|
||||
|
||||
# Windows PHP SDK binary tools
|
||||
/php-sdk-binary-tools/**
|
||||
/pkgroot/
|
||||
|
||||
# default pack:lib and release directory
|
||||
/dist/**
|
||||
/dist/
|
||||
packlib_files.txt
|
||||
|
||||
# tools cache files
|
||||
@@ -37,7 +31,7 @@ packlib_files.txt
|
||||
/bin/*
|
||||
!/bin/spc*
|
||||
!/bin/setup-runtime*
|
||||
!/bin/docker-entrypoint.sh
|
||||
!/bin/spc-alpine-docker
|
||||
|
||||
# exclude windows build tools
|
||||
/php-sdk-binary-tools/
|
||||
@@ -51,13 +45,3 @@ packlib_files.txt
|
||||
/docs/.vitepress/cache/
|
||||
package-lock.json
|
||||
pnpm-lock.yaml
|
||||
|
||||
# craft
|
||||
craft.yml
|
||||
|
||||
# SPC logs
|
||||
log/
|
||||
|
||||
# spc.phar
|
||||
spc.phar
|
||||
spc.exe
|
||||
|
||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setUnsupportedPhpVersionAllowed(true)
|
||||
->setRules([
|
||||
'@PSR12' => true,
|
||||
'@Symfony' => true,
|
||||
@@ -65,10 +64,7 @@ return (new PhpCsFixer\Config())
|
||||
'php_unit_test_class_requires_covers' => false,
|
||||
'phpdoc_var_without_name' => false,
|
||||
'fully_qualified_strict_types' => false,
|
||||
'operator_linebreak' => false,
|
||||
'php_unit_data_provider_method_order' => false,
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()->in([__DIR__ . '/src', __DIR__ . '/tests/SPC'])
|
||||
)
|
||||
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect());
|
||||
);
|
||||
|
||||
372
README-zh.md
372
README-zh.md
@@ -5,168 +5,290 @@
|
||||
[](https://github.com/crazywhalecc/static-php-cli/releases)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
|
||||
[](https://static-php.dev/zh/guide/extensions.html)
|
||||
|
||||
**static-php-cli** 是一个用于构建静态、独立 PHP 运行时的强大工具,支持众多流行扩展。
|
||||
**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。
|
||||
|
||||
目前 static-php-cli 支持 `cli`、`fpm`、`embed` 和 `micro` SAPI。
|
||||
|
||||
**static-php-cli**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。
|
||||
|
||||
## 特性
|
||||
|
||||
- :elephant: **支持多 PHP 版本** - 支持 PHP 8.1, 8.2, 8.3, 8.4, 8.5
|
||||
- :handbag: **单文件 PHP 可执行文件** - 构建零依赖的独立 PHP
|
||||
- :hamburger: **phpmicro 集成** - 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自解压可执行文件(将 PHP 二进制文件和源代码合并为一个文件)
|
||||
- :pill: **智能环境检查器** - 自动构建环境检查器,具备自动修复功能
|
||||
- :zap: **跨平台支持** - 支持 Linux、macOS、FreeBSD 和 Windows
|
||||
- :wrench: **可配置补丁** - 可自定义的源代码补丁系统
|
||||
- :books: **智能依赖管理** - 自动处理构建依赖
|
||||
- 📦 **自包含工具** - 提供使用 [box](https://github.com/box-project/box) 构建的 `spc` 可执行文件
|
||||
- :fire: **广泛的扩展支持** - 支持 75+ 流行 [扩展](https://static-php.dev/zh/guide/extensions.html)
|
||||
- :floppy_disk: **UPX 压缩** - 减小二进制文件大小 30-50%(仅 Linux/Windows)
|
||||
static-php-cli(简称 `spc`)有许多特性:
|
||||
|
||||
**单文件独立 php-cli:**
|
||||
- :handbag: 构建独立的单文件 PHP 解释器,无需任何依赖
|
||||
- :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:**
|
||||
|
||||
<img width="700" alt="out1" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/01a2e60f-13b0-4242-a645-f7afa4936396">
|
||||
|
||||
**使用 phpmicro 将 PHP 代码与 PHP 解释器结合:**
|
||||
**使用 phpmicro 打包 PHP 代码:**
|
||||
|
||||
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 下载 spc 二进制文件
|
||||
|
||||
```bash
|
||||
# Linux x86_64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
|
||||
# Linux aarch64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
# macOS x86_64 (Intel)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
# macOS aarch64 (Apple)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
|
||||
# Windows (x86_64, win10 build 17063 或更高版本,请先安装 VS2022)
|
||||
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
|
||||
```
|
||||
|
||||
对于 macOS 和 Linux,请先添加执行权限:
|
||||
|
||||
```bash
|
||||
chmod +x ./spc
|
||||
```
|
||||
|
||||
### 2. 构建静态 PHP
|
||||
|
||||
首先,创建一个 `craft.yml` 文件,并从 [扩展列表](https://static-php.dev/zh/guide/extensions.html) 或 [命令生成器](https://static-php.dev/zh/guide/cli-generator.html) 中指定要包含的扩展:
|
||||
|
||||
```yml
|
||||
# PHP 版本支持:8.1, 8.2, 8.3, 8.4, 8.5
|
||||
php-version: 8.4
|
||||
# 在此处放置您的扩展列表
|
||||
extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
|
||||
sapi:
|
||||
- cli
|
||||
- micro
|
||||
- fpm
|
||||
download-options:
|
||||
prefer-pre-built: true
|
||||
```
|
||||
|
||||
运行命令:
|
||||
|
||||
```bash
|
||||
./spc craft
|
||||
|
||||
# 输出完整控制台日志
|
||||
./spc craft --debug
|
||||
```
|
||||
|
||||
### 3. 静态 PHP 使用
|
||||
|
||||
现在您可以将 static-php-cli 构建的二进制文件复制到另一台机器上,无需依赖即可运行:
|
||||
|
||||
```
|
||||
# php-cli
|
||||
buildroot/bin/php -v
|
||||
|
||||
# phpmicro
|
||||
echo '<?php echo "Hello world!\n";' > a.php
|
||||
./spc micro:combine a.php -O my-app
|
||||
./my-app
|
||||
|
||||
# php-fpm
|
||||
buildroot/bin/php-fpm -v
|
||||
```
|
||||
|
||||
## 文档
|
||||
|
||||
当前 README 包含基本用法。有关 static-php-cli 的所有功能,
|
||||
请访问 <https://static-php.dev>。
|
||||
目前 README 编写了基本用法。有关 static-php-cli 所有的功能,请点击这里查看文档:<https://static-php.dev>。
|
||||
|
||||
## 直接下载
|
||||
|
||||
如果您不想构建或想先测试,可以从 [Actions](https://github.com/static-php/static-php-cli-hosted/actions/workflows/build-php-bulk.yml) 下载示例预编译工件,或从自托管服务器下载。
|
||||
如果你不想自行编译 PHP,可以从本项目现有的示例 Action 下载 Artifact,也可以从自托管的服务器下载。
|
||||
|
||||
以下是几个具有不同扩展组合的预编译静态 PHP 二进制文件,
|
||||
您可以根据需要直接下载。
|
||||
- [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/):common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 7.5MB 左右。
|
||||
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/):bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 25MB 左右。
|
||||
- [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/):minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 3MB 左右。
|
||||
|
||||
| 组合名称 | 扩展数量 | 系统 | 备注 |
|
||||
|----------------------------------------------------------------------|----------------------------------------------------------------------------|--------------|--------------------|
|
||||
| [common](https://dl.static-php.dev/static-php-cli/common/) | [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) | Linux, macOS | 二进制文件大小约为 7.5MB |
|
||||
| [bulk](https://dl.static-php.dev/static-php-cli/bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | 二进制文件大小约为 25MB |
|
||||
| [gnu-bulk](https://dl.static-php.dev/static-php-cli/gnu-bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | 使用 glibc 的 bulk 组合 |
|
||||
| [minimal](https://dl.static-php.dev/static-php-cli/minimal/) | [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) | Linux, macOS | 二进制文件大小约为 3MB |
|
||||
| [spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/) | [5](https://dl.static-php.dev/static-php-cli/windows/spc-min/README.txt) | Windows | 二进制文件大小约为 3MB |
|
||||
| [spc-max](https://dl.static-php.dev/static-php-cli/windows/spc-max/) | [40+](https://dl.static-php.dev/static-php-cli/windows/spc-max/README.txt) | Windows | 二进制文件大小约为 8.5MB |
|
||||
> Linux 和 Windows 默认启用了 UPX 压缩,可减小 30~50% 的 PHP 二进制体积。
|
||||
> macOS 当前不支持 UPX,所以上述预编译的 macOS 版本体积可能较大。
|
||||
|
||||
> Linux 和 Windows 支持对二进制文件进行 UPX 压缩,可以将二进制文件大小减少 30% 到 50%。
|
||||
> macOS 不支持 UPX 压缩,因此 mac 的预构建二进制文件大小较大。
|
||||
对于 Windows 系统,目前支持的扩展较少,故仅提供 SPC 自身运行的最小扩展组合的 `cli` 和 `micro`:[扩展组合 - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/)。
|
||||
|
||||
## 使用 static-php-cli 构建 PHP
|
||||
|
||||
### 编译环境需求
|
||||
|
||||
- PHP >= 8.1(这是 spc 自身需要的版本,不是支持的构建版本)
|
||||
- 扩展:`mbstring,tokenizer,phar`
|
||||
- 系统安装了 `curl` 和 `git`
|
||||
|
||||
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
|
||||
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含上面提到的扩展和 PHP 版本大于等于 8.1 即可。
|
||||
|
||||
下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
|
||||
|
||||
| | x86_64 | aarch64 |
|
||||
|---------|----------------------|----------------------|
|
||||
| macOS | :octocat: :computer: | :octocat: :computer: |
|
||||
| Linux | :octocat: :computer: | :octocat: :computer: |
|
||||
| Windows | :octocat: :computer: | |
|
||||
| FreeBSD | :computer: | :computer: |
|
||||
|
||||
当前支持编译的 PHP 版本:
|
||||
|
||||
> :warning: 支持,但 static-php-cli 作者可能不再提供补丁修复
|
||||
>
|
||||
> :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: | |
|
||||
|
||||
### 支持的扩展
|
||||
|
||||
请先根据下方扩展列表选择你要编译的扩展。
|
||||
|
||||
- [扩展支持列表](https://static-php.dev/zh/guide/extensions.html)
|
||||
- [编译命令生成器](https://static-php.dev/zh/guide/cli-generator.html)
|
||||
|
||||
> 如果这里没有你需要的扩展,可以提交 Issue。
|
||||
|
||||
### 在线构建(使用 GitHub Actions)
|
||||
|
||||
上方直接下载的二进制不能满足需求时,可使用 GitHub Action 可以轻松构建静态编译的 PHP,
|
||||
同时自行定义要编译的扩展。
|
||||
使用 GitHub Action 可以方便地构建一个静态编译的 PHP,同时可以自行定义要编译的扩展。
|
||||
|
||||
1. Fork 本项目。
|
||||
2. 进入项目的 Actions 并选择 `CI`。
|
||||
3. 选择 `Run workflow`,填入您要编译的 PHP 版本、目标类型和扩展列表。(扩展用逗号分隔,例如 `bcmath,curl,mbstring`)
|
||||
4. 等待一段时间后,进入相应的任务并获取 `Artifacts`。
|
||||
2. 进入项目的 Actions,选择 CI。
|
||||
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`)
|
||||
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`。
|
||||
|
||||
如果您启用 `debug`,构建时将输出所有日志,包括编译日志,以便故障排除。
|
||||
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
|
||||
|
||||
### 本地构建(使用 spc 二进制)
|
||||
|
||||
该项目提供了 static-php-cli 的二进制文件:`spc`。
|
||||
您可以使用 `spc` 二进制文件,无需安装任何运行时(用起来就像 golang 程序)。
|
||||
目前,`spc` 二进制文件提供的平台有 Linux 和 macOS。
|
||||
|
||||
使用以下命令从自托管服务器下载:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
如果您的系统上尚未安装 php,我们建议你使用内置的 setup-runtime 自动安装 PHP 和 Composer。
|
||||
|
||||
```bash
|
||||
cd static-php-cli
|
||||
chmod +x bin/setup-runtime
|
||||
# it will download static php (from self-hosted server) and composer (from getcomposer)
|
||||
bin/setup-runtime
|
||||
# initialize composer deps
|
||||
bin/composer install
|
||||
# chmod
|
||||
chmod +x bin/spc
|
||||
bin/spc --version
|
||||
```
|
||||
|
||||
### 开始构建 PHP
|
||||
|
||||
下面是使用 static-php-cli 的基础用法:
|
||||
|
||||
> 如果你使用的是打包好的 `spc` 二进制,你需要将下列命令的 `./bin/spc` 替换为 `./spc`。
|
||||
|
||||
```bash
|
||||
# 检查环境依赖,并根据尝试自动安装缺失的编译工具
|
||||
./bin/spc doctor --auto-fix
|
||||
|
||||
# 拉取所有依赖库
|
||||
./bin/spc download --all
|
||||
# 只拉取编译指定扩展需要的所有依赖(推荐)
|
||||
./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
|
||||
./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
|
||||
```
|
||||
|
||||
其中,目前支持构建 cli,micro,fpm 和 embed,使用以下参数的一个或多个来指定编译的 SAPI:
|
||||
|
||||
- `--build-cli`:构建 cli 二进制
|
||||
- `--build-micro`:构建 phpmicro 自执行二进制
|
||||
- `--build-fpm`:构建 fpm
|
||||
- `--build-embed`:构建 embed(libphp)
|
||||
- `--build-all`:构建所有
|
||||
|
||||
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
|
||||
|
||||
```bash
|
||||
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
|
||||
./bin/spc download --all --debug
|
||||
```
|
||||
|
||||
## 不同 SAPI 的使用
|
||||
|
||||
### 使用 cli
|
||||
|
||||
> php-cli 是一个静态的二进制文件,类似 Go、Rust 语言编译后的单个可移植的二进制文件。
|
||||
|
||||
采用参数 `--build-cli` 或`--build-all` 参数时,最后编译结果会输出一个 `./php` 的二进制文件,此文件可分发、可直接使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,名称为 `php`,拷贝出来即可。
|
||||
|
||||
```bash
|
||||
cd buildroot/bin/
|
||||
./php -v # 检查版本
|
||||
./php -m # 检查编译的扩展
|
||||
./php your_code.php # 运行代码
|
||||
./php your_project.phar # 运行打包为 phar 单文件的项目
|
||||
```
|
||||
|
||||
### 使用 micro
|
||||
|
||||
> phpmicro 是一个提供自执行二进制 PHP 的项目,本项目依赖 phpmicro 进行编译自执行二进制。详见 [dixyes/phpmicro](https://github.com/dixyes/phpmicro)。
|
||||
|
||||
采用项目参数 `--build-micro` 或 `--build-all` 时,最后编译结果会输出一个 `./micro.sfx` 的文件,此文件需要配合你的 PHP 源码使用。
|
||||
该文件编译后会存放在 `buildroot/bin/` 目录中,拷贝出来即可。
|
||||
|
||||
使用时应准备好你的项目源码文件,可以是单个 PHP 文件,也可以是 Phar 文件。
|
||||
|
||||
```bash
|
||||
echo "<?php echo 'Hello world' . PHP_EOL;" > code.php
|
||||
cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
./single-app
|
||||
```
|
||||
|
||||
如果打包 PHAR 文件,仅需把 code.php 更换为 phar 文件路径即可。
|
||||
你可以使用 [box-project/box](https://github.com/box-project/box) 将你的 CLI 项目打包为 Phar,
|
||||
然后将它与 phpmicro 结合,生成独立可执行的二进制文件。
|
||||
|
||||
```bash
|
||||
# 使用 static-php-cli 生成的 micro.sfx 结合,也可以直接使用 cat 命令结合它们
|
||||
bin/spc micro:combine my-app.phar
|
||||
cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
|
||||
|
||||
# 使用 micro:combine 结合可以将 INI 选项注入到二进制中
|
||||
bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
|
||||
```
|
||||
|
||||
> 有些情况下的 phar 文件或 PHP 项目可能无法在 micro 环境下运行。
|
||||
|
||||
### 使用 fpm
|
||||
|
||||
采用项目参数 `--build-fpm` 或 `--build-all` 时,最后编译结果会输出一个 `./php-fpm` 的文件。
|
||||
该文件存放在 `buildroot/bin/` 目录,拷贝出来即可使用。
|
||||
|
||||
在正常的 Linux 发行版和 macOS 系统中,安装 php-fpm 后包管理会自动生成默认的 fpm 配置文件。
|
||||
因为 php-fpm 必须指定配置文件才可启动,本项目编译的 php-fpm 不会带任何配置文件,所以需自行编写 `php-fpm.conf` 和 `pool.conf` 配置文件。
|
||||
|
||||
指定 `php-fpm.conf` 可以使用命令参数 `-y`,例如:`./php-fpm -y php-fpm.conf`。
|
||||
|
||||
### 使用 embed
|
||||
|
||||
采用项目参数 `--build-embed` 或 `--build-all` 时,最后编译结果会输出一个 `libphp.a`、`php-config` 以及一系列头文件,存放在 `buildroot/`,你可以在你的其他代码中引入它们。
|
||||
|
||||
如果你知道 [embed SAPI](https://github.com/php/php-src/tree/master/sapi/embed),你应该知道如何使用它。对于有可能编译用到引入其他库的问题,你可以使用 `buildroot/bin/php-config` 来获取编译时的配置。
|
||||
|
||||
另外,有关如何使用此功能的高级示例,请查看[如何使用它构建 FrankenPHP 的静态版本](https://github.com/dunglas/frankenphp/blob/main/docs/static.md)。
|
||||
|
||||
## 贡献
|
||||
|
||||
如果您需要的扩展缺失,可以创建 issue。
|
||||
如果您熟悉本项目,也欢迎发起 pull request。
|
||||
如果缺少你需要的扩展,可发起 Issue。如果你对本项目较熟悉,也欢迎为本项目发起 Pull Request。
|
||||
|
||||
如果您想贡献文档,请直接编辑 `docs/` 目录。
|
||||
另外,添加新扩展的贡献方式,可以参考下方 `进阶`。
|
||||
|
||||
现在有一个 [static-php](https://github.com/static-php) 组织,用于存储与项目相关的仓库。
|
||||
如果你想贡献文档内容,请直接修改 `docs/` 目录。
|
||||
|
||||
## 赞助本项目
|
||||
|
||||
您可以从 [GitHub Sponsor](https://github.com/crazywhalecc) 赞助我或我的项目。您捐赠的一部分将用于维护 **static-php.dev** 服务器。
|
||||
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。你捐赠的一部分将会被用于维护 **static-php.dev** 服务器。
|
||||
|
||||
**特别感谢以下赞助商**:
|
||||
## 开源协议
|
||||
|
||||
<a href="https://beyondco.de/"><img src="/docs/public/images/beyondcode-seeklogo.png" width="300" alt="Beyond Code Logo" /></a>
|
||||
|
||||
<a href="https://nativephp.com/"><img src="/docs/public/images/nativephp-logo.svg" width="300" alt="NativePHP Logo" /></a>
|
||||
|
||||
## 开源许可证
|
||||
|
||||
本项目本身基于 MIT 许可证,
|
||||
一些新添加的扩展和依赖可能来自其他项目,
|
||||
这些代码文件的头部也会给出额外的许可证和作者说明。
|
||||
|
||||
这些是类似的项目:
|
||||
本项目采用 MIT License 许可开源,下面是类似的项目:
|
||||
|
||||
- [dixyes/lwmbs](https://github.com/dixyes/lwmbs)
|
||||
- [swoole/swoole-cli](https://github.com/swoole/swoole-cli)
|
||||
|
||||
本项目使用了 [dixyes/lwmbs](https://github.com/dixyes/lwmbs) 的一些代码,例如 Windows 静态构建目标和 libiconv 支持。
|
||||
lwmbs 基于 [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2) 许可证。
|
||||
该项目使用了 [dixyes/lwmbs](https://github.com/dixyes/lwmbs) 中的一些代码,例如 Windows 静态构建目标和 libiconv 库支持。
|
||||
lwmbs 使用 [Mulan PSL 2](http://license.coscl.org.cn/MulanPSL2) 许可进行分发。对应文件有关于作者和许可的特殊说明,除此之外,均使用 MIT 授权许可。
|
||||
|
||||
由于本项目的特殊性,
|
||||
项目编译过程中会使用许多其他开源项目,如 curl 和 protobuf,
|
||||
它们都有自己的开源许可证。
|
||||
|
||||
请在编译后使用 `bin/spc dump-license` 命令导出项目中使用的开源许可证,
|
||||
并遵守相应项目的 LICENSE。
|
||||
因本项目的特殊性,使用项目编译过程中会使用很多其他开源项目,例如 curl、protobuf 等,它们都有各自的开源协议。
|
||||
请在编译完成后,使用命令 `bin/spc dump-license` 导出项目使用项目的开源协议,并遵守对应项目的 LICENSE。
|
||||
|
||||
337
README.md
337
README.md
@@ -5,22 +5,29 @@
|
||||
[](https://github.com/crazywhalecc/static-php-cli/releases)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/actions/workflows/tests.yml)
|
||||
[](https://github.com/crazywhalecc/static-php-cli/blob/main/LICENSE)
|
||||
[](https://static-php.dev/en/guide/extensions.html)
|
||||
|
||||
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
|
||||
with popular extensions.
|
||||
|
||||
Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed` and `micro` SAPI.
|
||||
|
||||
**static-php-cli** also has the ability to package PHP projects
|
||||
along with the PHP interpreter into one single executable file.
|
||||
|
||||
## Features
|
||||
|
||||
- :elephant: Support multiple PHP versions - PHP 8.1, 8.2, 8.3, 8.4, 8.5
|
||||
- :handbag: Build single-file PHP executable with zero dependencies
|
||||
- :hamburger:Build **[phpmicro](https://github.com/dixyes/phpmicro)** self-extracting executables (combines PHP binary and source code into one file)
|
||||
- :pill: Automatic build environment checker with auto-fix capabilities
|
||||
static-php-cli (you can call it `spc`) has a lot of features:
|
||||
|
||||
- :handbag: Build single-file php executable, without any dependencies
|
||||
- :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 patching
|
||||
- :books: Intelligent dependency management
|
||||
- 📦 Self-contained `spc` executable (built with [box](https://github.com/box-project/box))
|
||||
- :fire: Support 100+ popular [extensions](https://static-php.dev/en/guide/extensions.html)
|
||||
- :floppy_disk: UPX compression support (reduces binary size by 30-50%)
|
||||
- :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:**
|
||||
|
||||
@@ -30,72 +37,6 @@ with popular extensions.
|
||||
|
||||
<img width="700" alt="out2" src="https://github.com/crazywhalecc/static-php-cli/assets/20330940/46b7128d-fb72-4169-957e-48564c3ff3e2">
|
||||
|
||||
## Quickstart
|
||||
|
||||
### 1. Download spc binary
|
||||
|
||||
```bash
|
||||
# For Linux x86_64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-x86_64
|
||||
# For Linux aarch64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
# macOS x86_64 (Intel)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
# macOS aarch64 (Apple)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
|
||||
# Windows (x86_64, win10 build 17063 or later, please install VS2022 first)
|
||||
curl.exe -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
|
||||
```
|
||||
|
||||
For macOS and Linux, add execute permission first:
|
||||
|
||||
```bash
|
||||
chmod +x ./spc
|
||||
```
|
||||
|
||||
### 2. Build Static PHP
|
||||
|
||||
First, create a `craft.yml` file and specify which extensions you want to include from [extension list](https://static-php.dev/en/guide/extensions.html) or [command generator](https://static-php.dev/en/guide/cli-generator.html):
|
||||
|
||||
```yml
|
||||
# PHP version support: 8.1, 8.2, 8.3, 8.4, 8.5
|
||||
php-version: 8.4
|
||||
# Put your extension list here
|
||||
extensions: "apcu,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,gd,iconv,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,readline,redis,session,simplexml,sockets,sodium,sqlite3,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib"
|
||||
sapi:
|
||||
- cli
|
||||
- micro
|
||||
- fpm
|
||||
download-options:
|
||||
prefer-pre-built: true
|
||||
```
|
||||
|
||||
Run command:
|
||||
|
||||
```bash
|
||||
./spc craft
|
||||
|
||||
# Output full console log
|
||||
./spc craft --debug
|
||||
```
|
||||
|
||||
### 3. Static PHP usage
|
||||
|
||||
Now you can copy binaries built by static-php-cli to another machine and run with no dependencies:
|
||||
|
||||
```
|
||||
# php-cli
|
||||
buildroot/bin/php -v
|
||||
|
||||
# phpmicro
|
||||
echo '<?php echo "Hello world!\n";' > a.php
|
||||
./spc micro:combine a.php -O my-app
|
||||
./my-app
|
||||
|
||||
# php-fpm
|
||||
buildroot/bin/php-fpm -v
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
The current README contains basic usage. For all the features of static-php-cli,
|
||||
@@ -108,22 +49,69 @@ If you don't want to build or want to test first, you can download example pre-c
|
||||
Below are several precompiled static-php binaries with different extension combinations,
|
||||
which can be downloaded directly according to your needs.
|
||||
|
||||
| Combination | Extension Count | OS | Comment |
|
||||
|----------------------------------------------------------------------|----------------------------------------------------------------------------|--------------|--------------------------------|
|
||||
| [common](https://dl.static-php.dev/static-php-cli/common/) | [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) | Linux, macOS | The binary size is about 7.5MB |
|
||||
| [bulk](https://dl.static-php.dev/static-php-cli/bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | The binary size is about 25MB |
|
||||
| [gnu-bulk](https://dl.static-php.dev/static-php-cli/gnu-bulk/) | [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) | Linux, macOS | Using shared glibc |
|
||||
| [minimal](https://dl.static-php.dev/static-php-cli/minimal/) | [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) | Linux, macOS | The binary size is about 3MB |
|
||||
| [spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/) | [5](https://dl.static-php.dev/static-php-cli/windows/spc-min/README.txt) | Windows | The binary size is about 3MB |
|
||||
| [spc-max](https://dl.static-php.dev/static-php-cli/windows/spc-max/) | [40+](https://dl.static-php.dev/static-php-cli/windows/spc-max/README.txt) | Windows | The binary size is about 8.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 7.5MB.
|
||||
- [Extension-Combination - bulk](https://dl.static-php.dev/static-php-cli/bulk/): `bulk` contains [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) extensions and is about 25MB in size.
|
||||
- [Extension-Combination - minimal](https://dl.static-php.dev/static-php-cli/minimal/): `minimal` contains [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) extensions and is about 3MB in size.
|
||||
|
||||
> Linux and Windows supports UPX compression for binaries, which can reduce the size of the binary by 30% to 50%.
|
||||
> macOS does not support UPX compression, so the size of the pre-built binaries for mac is larger.
|
||||
|
||||
For Windows systems, there are currently fewer extensions supported,
|
||||
so only `cli` and `micro` that run the minimum extension combination of SPC itself are provided: [Extension-Combination - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/).
|
||||
|
||||
## Build
|
||||
|
||||
### Compilation Requirements
|
||||
|
||||
You can say I made a PHP builder written in PHP, pretty funny.
|
||||
But static-php-cli runtime only requires an environment above PHP 8.1 and extensions mentioned below.
|
||||
|
||||
- PHP >= 8.1 (This is the version required by spc itself, not the build version)
|
||||
- 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.
|
||||
|
||||
| | x86_64 | aarch64 |
|
||||
|---------|----------------------|----------------------|
|
||||
| macOS | :octocat: :computer: | :octocat: :computer: |
|
||||
| Linux | :octocat: :computer: | :octocat: :computer: |
|
||||
| Windows | :octocat: :computer: | |
|
||||
| FreeBSD | :computer: | :computer: |
|
||||
|
||||
Currently supported PHP versions for compilation:
|
||||
|
||||
> :warning: supported but not maintained by static-php-cli authors
|
||||
>
|
||||
> :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
|
||||
|
||||
Please first select the extension you want to compile based on the extension list below.
|
||||
|
||||
- [Supported Extension List](https://static-php.dev/en/guide/extensions.html)
|
||||
- [Command Generator](https://static-php.dev/en/guide/cli-generator.html)
|
||||
|
||||
> If an extension you need is missing, you can submit an issue.
|
||||
|
||||
Here is the current planned roadmap for extension support: [#152](https://github.com/crazywhalecc/static-php-cli/issues/152) .
|
||||
|
||||
### Build Online (using GitHub Actions)
|
||||
|
||||
When the above direct download binaries cannot meet your needs,
|
||||
you can 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.
|
||||
|
||||
1. Fork me.
|
||||
@@ -133,6 +121,177 @@ 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.
|
||||
|
||||
### Build Locally (using SPC binary)
|
||||
|
||||
This project provides a binary file of static-php-cli: `spc`.
|
||||
You can use `spc` binary instead of installing any runtime like golang app.
|
||||
Currently, the platforms supported by `spc` binary are Linux and macOS.
|
||||
|
||||
Download from self-hosted nightly builds using commands below:
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
```bash
|
||||
cd static-php-cli
|
||||
chmod +x bin/setup-runtime
|
||||
# it will download static php (from self-hosted server) and composer (from getcomposer)
|
||||
bin/setup-runtime
|
||||
# initialize composer deps
|
||||
bin/composer install
|
||||
# chmod
|
||||
chmod +x bin/spc
|
||||
bin/spc --version
|
||||
```
|
||||
|
||||
### Start Building PHP
|
||||
|
||||
Basic usage for building php 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.
|
||||
|
||||
```bash
|
||||
# Check system tool dependencies, auto-fix them if possible
|
||||
./bin/spc doctor --auto-fix
|
||||
|
||||
# fetch all libraries
|
||||
./bin/spc download --all
|
||||
# only fetch necessary sources by needed extensions (recommended)
|
||||
./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
|
||||
./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:
|
||||
|
||||
- `--build-cli`: build static cli executable
|
||||
- `--build-micro`: build static phpmicro self-extracted executable
|
||||
- `--build-fpm`: build static fpm binary
|
||||
- `--build-embed`: build embed (libphp)
|
||||
- `--build-all`: build all
|
||||
|
||||
If anything goes wrong, use `--debug` option to display full terminal output:
|
||||
|
||||
```bash
|
||||
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
|
||||
./bin/spc download --all --debug
|
||||
```
|
||||
|
||||
## Different SAPI Usage
|
||||
|
||||
### Use cli
|
||||
|
||||
> php-cli is a single static binary, you can use it like normal php installed on your system.
|
||||
|
||||
When using the parameter `--build-cli` or `--build-all`,
|
||||
the final compilation result will output a binary file named `./php`,
|
||||
which can be distributed and used directly.
|
||||
This file will be located in the directory `buildroot/bin/`, copy it out for use.
|
||||
|
||||
```bash
|
||||
cd buildroot/bin/
|
||||
./php -v # check version
|
||||
./php -m # check extensions
|
||||
./php your_code.php # run your php code
|
||||
./php your_project.phar # run your phar (project archive)
|
||||
```
|
||||
|
||||
### Use micro
|
||||
|
||||
> phpmicro is a SelF-extracted eXecutable SAPI module,
|
||||
> provided by [phpmicro](https://github.com/dixyes/phpmicro) project.
|
||||
> But this project is using a [fork](https://github.com/static-php/phpmicro) of phpmicro, because we need to add some features to it.
|
||||
> It can put php runtime and your source code together.
|
||||
|
||||
When using the parameter `--build-all` or `--build-micro`,
|
||||
the final compilation result will output a file named `./micro.sfx`,
|
||||
which needs to be used with your PHP source code like `code.php`.
|
||||
This file will be located in the path `buildroot/bin/micro.sfx`, simply copy it out for use.
|
||||
|
||||
Prepare your project source code, which can be a single PHP file or a Phar file, for use.
|
||||
|
||||
```bash
|
||||
echo "<?php echo 'Hello world' . PHP_EOL;" > code.php
|
||||
cat micro.sfx code.php > single-app && chmod +x single-app
|
||||
./single-app
|
||||
```
|
||||
|
||||
If you package a PHAR file, just replace `code.php` with the phar file path.
|
||||
You can use [box-project/box](https://github.com/box-project/box) to package your CLI project as Phar,
|
||||
It is then combined with phpmicro to produce a standalone executable binary.
|
||||
|
||||
```bash
|
||||
# Use the micro.sfx generated by static-php-cli to combine,
|
||||
bin/spc micro:combine my-app.phar
|
||||
# or you can directly use the cat command to combine them.
|
||||
cat buildroot/bin/micro.sfx my-app.phar > my-app && chmod +x my-app
|
||||
|
||||
# Use micro:combine combination to inject INI options into the binary.
|
||||
bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=system" --output my-app-2
|
||||
```
|
||||
|
||||
> In some cases, PHAR files may not run in a micro environment. Overall, micro is not production ready.
|
||||
|
||||
### Use fpm
|
||||
|
||||
When using the parameter `--build-all` or `--build-fpm`,
|
||||
the final compilation result will output a file named `./php-fpm`,
|
||||
This file will be located in the path `buildroot/bin/`, simply copy it out for use.
|
||||
|
||||
In common Linux distributions and macOS systems, the package manager will automatically generate a default fpm configuration file after installing php-fpm.
|
||||
Because php-fpm must specify a configuration file before running, the php-fpm compiled by this project will not have any configuration files, so you need to write `php-fpm.conf` and `pool.conf` configuration files yourself.
|
||||
|
||||
Specifying `php-fpm.conf` can use the command parameter `-y`, for example: `./php-fpm -y php-fpm.conf`.
|
||||
|
||||
### Use embed
|
||||
|
||||
When using the project parameters `--build-embed` or `--build-all`,
|
||||
the final compilation result will output a `libphp.a`, `php-config` and a series of header files,
|
||||
stored in `buildroot/`. You can introduce them in your other projects.
|
||||
|
||||
If you know [embed SAPI](https://github.com/php/php-src/tree/master/sapi/embed), you should know how to use it.
|
||||
You may require the introduction of other libraries during compilation,
|
||||
you can use `buildroot/bin/php-config` to obtain the compile-time configuration.
|
||||
|
||||
For an advanced example of how to use this feature, take a look at [how to use it to build a static version of FrankenPHP](https://github.com/dunglas/frankenphp/blob/main/docs/static.md).
|
||||
|
||||
## Contribution
|
||||
|
||||
If the extension you need is missing, you can create an issue.
|
||||
@@ -144,13 +303,7 @@ Now there is a [static-php](https://github.com/static-php) organization, which i
|
||||
|
||||
## Sponsor this project
|
||||
|
||||
You can sponsor me or my project from [GitHub Sponsor](https://github.com/crazywhalecc). A portion of your donation will be used to maintain the **static-php.dev** server.
|
||||
|
||||
**Special thanks to sponsors below**:
|
||||
|
||||
<a href="https://beyondco.de/"><img src="/docs/public/images/beyondcode-seeklogo.png" width="300" alt="Beyond Code Logo" /></a>
|
||||
|
||||
<a href="https://nativephp.com/"><img src="/docs/public/images/nativephp-logo.svg" width="300" alt="NativePHP Logo" /></a>
|
||||
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.
|
||||
|
||||
## Open-Source License
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
TARGET_DIR="/app/pkgroot/$(uname -m)-linux"
|
||||
BACKUP_DIR="/app/pkgroot-private"
|
||||
# copy private pkgroot to pkgroot if pkgroot is empty
|
||||
if [ ! -d "$TARGET_DIR" ] || [ -z "$(ls -A "$TARGET_DIR")" ]; then
|
||||
echo "* Copying private pkgroot to pkgroot ..."
|
||||
rm -rf "$TARGET_DIR"
|
||||
cp -r "$BACKUP_DIR" "$TARGET_DIR"
|
||||
fi
|
||||
exec "$@"
|
||||
@@ -25,7 +25,7 @@ __DIR__=$(cd "$(dirname "$0")" && pwd)
|
||||
__PROJECT__=$(cd "${__DIR__}"/../ && pwd)
|
||||
|
||||
# set download dir
|
||||
__PHP_RUNTIME_URL__="https://dl.static-php.dev/static-php-cli/bulk/php-8.4.12-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://getcomposer.org/download/latest-stable/composer.phar"
|
||||
|
||||
# use china mirror
|
||||
@@ -45,7 +45,7 @@ done
|
||||
|
||||
case "$mirror" in
|
||||
china)
|
||||
__PHP_RUNTIME_URL__="https://dl.static-php.dev/static-php-cli/bulk/php-8.4.12-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"
|
||||
;;
|
||||
|
||||
@@ -61,7 +61,7 @@ test -f "${__PROJECT__}"/downloads/runtime.tar.gz || { echo "Downloading $__PHP_
|
||||
test -f "${__DIR__}"/php || { tar -xf "${__PROJECT__}"/downloads/runtime.tar.gz -C "${__DIR__}"/ ; }
|
||||
chmod +x "${__DIR__}"/php
|
||||
# download composer
|
||||
test -f "${__DIR__}"/composer || { echo "Downloading Composer from $__COMPOSER_URL__" && curl -#fSL -o "${__DIR__}"/composer "$__COMPOSER_URL__" ; }
|
||||
test -f "${__DIR__}"/composer || curl -#fSL -o "${__DIR__}"/composer "$__COMPOSER_URL__"
|
||||
chmod +x "${__DIR__}"/composer
|
||||
# sanity check for php and composer
|
||||
"${__DIR__}"/php -v >/dev/null || { echo "Failed to run php" && exit 1; }
|
||||
|
||||
@@ -51,11 +51,10 @@ if ($action -eq 'add-path') {
|
||||
}
|
||||
|
||||
# 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/archives/php-8.4.4-nts-Win32-vs17-x64.zip"
|
||||
Write-Host "Downloading PHP from: " -NoNewline
|
||||
Write-Host $PHPRuntimeUrl -ForegroundColor Cyan
|
||||
$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
|
||||
|
||||
10
bin/spc
10
bin/spc
@@ -4,11 +4,6 @@
|
||||
use SPC\ConsoleApplication;
|
||||
use SPC\exception\ExceptionHandler;
|
||||
|
||||
// Load custom php if exists
|
||||
if (PHP_OS_FAMILY !== 'Windows' && PHP_BINARY !== (__DIR__ . '/php') && file_exists(__DIR__ . '/php') && is_executable(__DIR__ . '/php')) {
|
||||
pcntl_exec(__DIR__ . '/php', $argv);
|
||||
}
|
||||
|
||||
if (file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
|
||||
// Current: ./bin (git/project mode)
|
||||
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||
@@ -22,11 +17,6 @@ if (PHP_OS_FAMILY === 'Windows' && Phar::running()) {
|
||||
exec('CHCP 65001');
|
||||
}
|
||||
|
||||
// Print deprecation notice on PHP < 8.4, use red and highlight background
|
||||
if (PHP_VERSION_ID < 80400) {
|
||||
echo "\e[43mDeprecation Notice: PHP < 8.4 is deprecated, please upgrade your PHP version.\e[0m\n";
|
||||
}
|
||||
|
||||
try {
|
||||
(new ConsoleApplication())->run();
|
||||
} catch (Exception $e) {
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# This file is using docker to run commands
|
||||
SPC_DOCKER_VERSION=v6
|
||||
|
||||
# Detect docker can run
|
||||
if ! which docker >/dev/null; then
|
||||
echo "Docker is not installed, please install docker first !"
|
||||
exit 1
|
||||
echo "Docker is not installed, please install docker first !"
|
||||
exit 1
|
||||
fi
|
||||
DOCKER_EXECUTABLE="docker"
|
||||
# shellcheck disable=SC2046
|
||||
@@ -24,48 +21,27 @@ if [ $(id -u) -ne 0 ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# Convert uname to gnu arch
|
||||
CURRENT_ARCH=$(uname -m)
|
||||
if [ "$CURRENT_ARCH" = "arm64" ]; then
|
||||
CURRENT_ARCH=aarch64
|
||||
fi
|
||||
if [ -z "$SPC_USE_ARCH" ]; then
|
||||
SPC_USE_ARCH=$CURRENT_ARCH
|
||||
fi
|
||||
# parse SPC_USE_ARCH
|
||||
case $SPC_USE_ARCH in
|
||||
x86_64|amd64)
|
||||
|
||||
|
||||
# to check if qemu-docker run
|
||||
if [ "$SPC_USE_ARCH" = "" ]; then
|
||||
SPC_USE_ARCH=x86_64
|
||||
if [ "$CURRENT_ARCH" != "x86_64" ]; then
|
||||
PLATFORM_ARG="--platform linux/amd64"
|
||||
ALPINE_FROM=multiarch/alpine:x86_64-edge
|
||||
fi
|
||||
fi
|
||||
case $SPC_USE_ARCH in
|
||||
x86_64)
|
||||
ALPINE_FROM=alpine:edge
|
||||
;;
|
||||
aarch64|arm64)
|
||||
SPC_USE_ARCH=aarch64
|
||||
if [ "$CURRENT_ARCH" != "aarch64" ]; then
|
||||
PLATFORM_ARG="--platform linux/arm64"
|
||||
ALPINE_FROM=multiarch/alpine:aarch64-edge
|
||||
fi
|
||||
aarch64)
|
||||
ALPINE_FROM=multiarch/alpine:aarch64-edge
|
||||
# shellcheck disable=SC2039
|
||||
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
|
||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
|
||||
;;
|
||||
*)
|
||||
echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
# if ALPINE_FROM is not set, use alpine:3.21
|
||||
if [ -z "$ALPINE_FROM" ]; then
|
||||
ALPINE_FROM=alpine:3.21
|
||||
fi
|
||||
if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then
|
||||
echo "* Using different arch needs to setup qemu-static for docker !"
|
||||
ALPINE_FROM=multiarch/alpine:$SPC_USE_ARCH-edge
|
||||
if [ "$(uname -s)" = "Linux" ]; then
|
||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
|
||||
fi
|
||||
else
|
||||
ALPINE_FROM=alpine:3.21
|
||||
fi
|
||||
|
||||
if [ "$SPC_USE_MIRROR" = "yes" ]; then
|
||||
SPC_USE_MIRROR="RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories"
|
||||
@@ -74,9 +50,9 @@ else
|
||||
fi
|
||||
|
||||
# Detect docker env is setup
|
||||
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION; then
|
||||
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-$SPC_USE_ARCH; then
|
||||
echo "Docker container does not exist. Building docker image ..."
|
||||
$DOCKER_EXECUTABLE build $PLATFORM_ARG -t cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
|
||||
$DOCKER_EXECUTABLE build -t cwcc-spc-$SPC_USE_ARCH -f- . <<EOF
|
||||
FROM $ALPINE_FROM
|
||||
$SPC_USE_MIRROR
|
||||
RUN apk update; \
|
||||
@@ -103,32 +79,26 @@ RUN apk update; \
|
||||
linux-headers \
|
||||
m4 \
|
||||
make \
|
||||
php82 \
|
||||
php82-common \
|
||||
php82-pcntl \
|
||||
php82-phar \
|
||||
php82-posix \
|
||||
php82-sodium \
|
||||
php82-tokenizer \
|
||||
php82-dom \
|
||||
php82-xml \
|
||||
php82-xmlwriter \
|
||||
composer \
|
||||
pkgconfig \
|
||||
re2c \
|
||||
wget \
|
||||
xz \
|
||||
gettext-dev \
|
||||
binutils-gold
|
||||
|
||||
RUN curl -#fSL https://dl.static-php.dev/static-php-cli/bulk/php-8.4.4-cli-linux-\$(uname -m).tar.gz | tar -xz -C /usr/local/bin && \
|
||||
chmod +x /usr/local/bin/php
|
||||
|
||||
RUN curl -#fSL https://getcomposer.org/download/latest-stable/composer.phar -o /usr/local/bin/composer && \
|
||||
chmod +x /usr/local/bin/composer
|
||||
xz
|
||||
|
||||
WORKDIR /app
|
||||
ADD ./src /app/src
|
||||
COPY ./composer.* /app/
|
||||
ADD ./bin /app/bin
|
||||
RUN composer install --no-dev
|
||||
ADD ./config /app/config
|
||||
RUN bin/spc doctor --auto-fix
|
||||
RUN bin/spc install-pkg upx
|
||||
|
||||
RUN mv /app/pkgroot/\$(uname -m)-linux /app/pkgroot-private
|
||||
ADD bin/docker-entrypoint.sh /bin/docker-entrypoint.sh
|
||||
RUN chmod +x /bin/docker-entrypoint.sh
|
||||
ENTRYPOINT ["/bin/docker-entrypoint.sh"]
|
||||
RUN composer install --no-dev --classmap-authoritative
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -139,89 +109,6 @@ else
|
||||
INTERACT=''
|
||||
fi
|
||||
|
||||
# Mounting volumes
|
||||
MOUNT_LIST=""
|
||||
# shellcheck disable=SC2089
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/config:/app/config"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/src:/app/src"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/buildroot:/app/buildroot"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/source:/app/source"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/dist:/app/dist"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/downloads:/app/downloads"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/log:/app/log"
|
||||
if [ -f "$(pwd)/craft.yml" ]; then
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/craft.yml:/app/craft.yml"
|
||||
fi
|
||||
|
||||
# Environment variable passthrough
|
||||
ENV_LIST=""
|
||||
ENV_LIST="$ENV_LIST -e SPC_FIX_DEPLOY_ROOT="$(pwd)""
|
||||
if [ ! -z "$GITHUB_TOKEN" ]; then
|
||||
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
|
||||
fi
|
||||
|
||||
# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
|
||||
FRANKENPHP_APP_PATH=""
|
||||
NEW_ARGS=()
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--with-frankenphp-app=*)
|
||||
FRANKENPHP_APP_PATH="${1#*=}"
|
||||
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||
shift
|
||||
;;
|
||||
--with-frankenphp-app)
|
||||
if [ -n "${2:-}" ]; then
|
||||
FRANKENPHP_APP_PATH="$2"
|
||||
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||
shift 2
|
||||
else
|
||||
NEW_ARGS+=("$1")
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
NEW_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Normalize the path and add mount if provided
|
||||
if [ -n "$FRANKENPHP_APP_PATH" ]; then
|
||||
# expand ~ to $HOME
|
||||
if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
|
||||
FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
|
||||
fi
|
||||
# make absolute if relative
|
||||
case "$FRANKENPHP_APP_PATH" in
|
||||
/*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
|
||||
*) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
|
||||
esac
|
||||
MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
|
||||
fi
|
||||
|
||||
# Run docker
|
||||
# shellcheck disable=SC2068
|
||||
# shellcheck disable=SC2086
|
||||
# shellcheck disable=SC2090
|
||||
if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
|
||||
echo "* Debug mode enabled, run docker in interactive mode."
|
||||
echo "* You can use 'exit' to exit the docker container."
|
||||
echo "* You can use 'bin/spc' like normal builds."
|
||||
echo "*"
|
||||
echo "* Mounted directories:"
|
||||
echo "* ./config: $(pwd)/config"
|
||||
echo "* ./src: $(pwd)/src"
|
||||
echo "* ./buildroot: $(pwd)/buildroot"
|
||||
echo "* ./source: $(pwd)/source"
|
||||
echo "* ./dist: $(pwd)/dist"
|
||||
echo "* ./downloads: $(pwd)/downloads"
|
||||
echo "* ./pkgroot: $(pwd)/pkgroot"
|
||||
echo "*"
|
||||
set -ex
|
||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
||||
else
|
||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
|
||||
fi
|
||||
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" -v "$(pwd)"/config:/app/config -v "$(pwd)"/src:/app/src -v "$(pwd)"/buildroot:/app/buildroot -v "$(pwd)"/source:/app/source -v "$(pwd)"/dist:/app/dist -v "$(pwd)"/downloads:/app/downloads cwcc-spc-$SPC_USE_ARCH bin/spc $@
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# This file is using docker to run commands
|
||||
SPC_DOCKER_VERSION=v6
|
||||
|
||||
# Detect docker can run
|
||||
if ! which docker >/dev/null; then
|
||||
echo "Docker is not installed, please install docker first !"
|
||||
exit 1
|
||||
fi
|
||||
DOCKER_EXECUTABLE="docker"
|
||||
# shellcheck disable=SC2046
|
||||
if [ $(id -u) -ne 0 ]; then
|
||||
if ! docker info > /dev/null 2>&1; then
|
||||
if [ "$SPC_USE_SUDO" != "yes" ] && [ "$SPC_DOCKER_DEBUG" != "yes" ]; then
|
||||
echo "Docker command requires sudo"
|
||||
# shellcheck disable=SC2039
|
||||
echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
|
||||
exit 1
|
||||
fi
|
||||
DOCKER_EXECUTABLE="sudo docker"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Convert uname to gnu arch
|
||||
CURRENT_ARCH=$(uname -m)
|
||||
if [ "$CURRENT_ARCH" = "arm64" ]; then
|
||||
CURRENT_ARCH=aarch64
|
||||
fi
|
||||
if [ -z "$SPC_USE_ARCH" ]; then
|
||||
SPC_USE_ARCH=$CURRENT_ARCH
|
||||
fi
|
||||
# parse SPC_USE_ARCH
|
||||
case $SPC_USE_ARCH in
|
||||
x86_64|amd64)
|
||||
SPC_USE_ARCH=x86_64
|
||||
SPC_USE_ARCH_DOCKER=amd64
|
||||
if [ "$CURRENT_ARCH" != "x86_64" ]; then
|
||||
PLATFORM_ARG="--platform linux/amd64"
|
||||
fi
|
||||
;;
|
||||
aarch64|arm64)
|
||||
SPC_USE_ARCH=aarch64
|
||||
SPC_USE_ARCH_DOCKER=arm64
|
||||
if [ "$CURRENT_ARCH" != "aarch64" ]; then
|
||||
PLATFORM_ARG="--platform linux/arm64"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
# detect if we need to use qemu-static
|
||||
if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then
|
||||
if [ "$(uname -s)" = "Linux" ]; then
|
||||
echo "* Using different arch needs to setup qemu-static for docker !"
|
||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static --reset -p yes > /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect docker env is setup
|
||||
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION; then
|
||||
echo "Docker container does not exist. Building docker image ..."
|
||||
$DOCKER_EXECUTABLE buildx build $PLATFORM_ARG -t cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
|
||||
FROM centos:7
|
||||
RUN sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo && \
|
||||
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
|
||||
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
|
||||
RUN yum clean all && \
|
||||
yum makecache && \
|
||||
yum update -y && \
|
||||
localedef -c -i en_US -f UTF-8 en_US.UTF-8
|
||||
|
||||
RUN yum install -y centos-release-scl
|
||||
|
||||
RUN if [ "$SPC_USE_ARCH" = "aarch64" ]; then \
|
||||
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo ; \
|
||||
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl.repo ; \
|
||||
else \
|
||||
sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo ; \
|
||||
fi
|
||||
RUN sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
|
||||
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo && \
|
||||
sed -i 's|http://|https://|g' /etc/yum.repos.d/*.repo
|
||||
|
||||
RUN yum update -y && \
|
||||
yum install -y devtoolset-10-gcc-* devtoolset-10-libatomic-devel
|
||||
RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc
|
||||
RUN source /etc/bashrc
|
||||
RUN yum install -y which
|
||||
|
||||
RUN curl -o cmake.tgz -#fSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$SPC_USE_ARCH.tar.gz && \
|
||||
mkdir /cmake && \
|
||||
tar -xzf cmake.tgz -C /cmake --strip-components 1
|
||||
|
||||
WORKDIR /app
|
||||
COPY ./composer.* /app/
|
||||
ADD ./bin/setup-runtime /app/bin/setup-runtime
|
||||
ADD ./bin/spc /app/bin/spc
|
||||
RUN /app/bin/setup-runtime
|
||||
ADD ./src /app/src
|
||||
RUN /app/bin/php /app/bin/composer install --no-dev
|
||||
ENV SPC_LIBC=glibc
|
||||
ENV PATH="/app/bin:/cmake/bin:/opt/rh/devtoolset-10/root/usr/bin:\$PATH"
|
||||
|
||||
ADD ./config /app/config
|
||||
RUN CC=gcc bin/spc doctor --auto-fix --debug
|
||||
RUN bin/spc install-pkg upx
|
||||
RUN if [ -f /app/buildroot/bin/re2c ]; then \
|
||||
cp /app/buildroot/bin/re2c /usr/local/bin/re2c ;\
|
||||
fi
|
||||
|
||||
RUN curl -o make.tgz -fsSL https://ftp.gnu.org/gnu/make/make-4.4.tar.gz && \
|
||||
tar -zxvf make.tgz && \
|
||||
cd make-4.4 && \
|
||||
./configure && \
|
||||
make && \
|
||||
make install && \
|
||||
ln -sf /usr/local/bin/make /usr/bin/make
|
||||
|
||||
RUN curl -o automake.tgz -fsSL https://ftp.gnu.org/gnu/automake/automake-1.17.tar.xz && \
|
||||
tar -xvf automake.tgz && \
|
||||
cd automake-1.17 && \
|
||||
./configure && \
|
||||
make && \
|
||||
make install && \
|
||||
ln -sf /usr/local/bin/automake /usr/bin/automake
|
||||
|
||||
RUN mv /app/pkgroot/\$(uname -m)-linux /app/pkgroot-private
|
||||
ADD bin/docker-entrypoint.sh /bin/docker-entrypoint.sh
|
||||
RUN chmod +x /bin/docker-entrypoint.sh
|
||||
ENTRYPOINT ["/bin/docker-entrypoint.sh"]
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Check if in ci (local terminal can execute with -it)
|
||||
if [ -t 0 ]; then
|
||||
INTERACT=-it
|
||||
else
|
||||
INTERACT=''
|
||||
fi
|
||||
|
||||
# Mounting volumes
|
||||
MOUNT_LIST=""
|
||||
# shellcheck disable=SC2089
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/config:/app/config"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/src:/app/src"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/buildroot:/app/buildroot"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/source:/app/source"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/dist:/app/dist"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/downloads:/app/downloads"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot"
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/log:/app/log"
|
||||
if [ -f "$(pwd)/craft.yml" ]; then
|
||||
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/craft.yml:/app/craft.yml"
|
||||
fi
|
||||
|
||||
# Apply env in temp env file
|
||||
echo 'SPC_DEFAULT_C_FLAGS=-fPIC' > /tmp/spc-gnu-docker.env
|
||||
echo 'SPC_LIBC=glibc' >> /tmp/spc-gnu-docker.env
|
||||
|
||||
# Environment variable passthrough
|
||||
ENV_LIST=""
|
||||
ENV_LIST="$ENV_LIST -e SPC_FIX_DEPLOY_ROOT="$(pwd)""
|
||||
if [ ! -z "$GITHUB_TOKEN" ]; then
|
||||
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
|
||||
fi
|
||||
|
||||
# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
|
||||
FRANKENPHP_APP_PATH=""
|
||||
NEW_ARGS=()
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--with-frankenphp-app=*)
|
||||
FRANKENPHP_APP_PATH="${1#*=}"
|
||||
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||
shift
|
||||
;;
|
||||
--with-frankenphp-app)
|
||||
if [ -n "${2:-}" ]; then
|
||||
FRANKENPHP_APP_PATH="$2"
|
||||
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||
shift 2
|
||||
else
|
||||
NEW_ARGS+=("$1")
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
NEW_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Normalize the path and add mount if provided
|
||||
if [ -n "$FRANKENPHP_APP_PATH" ]; then
|
||||
# expand ~ to $HOME
|
||||
if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
|
||||
FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
|
||||
fi
|
||||
# make absolute if relative
|
||||
case "$FRANKENPHP_APP_PATH" in
|
||||
/*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
|
||||
*) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
|
||||
esac
|
||||
MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
|
||||
fi
|
||||
|
||||
# Run docker
|
||||
# shellcheck disable=SC2068
|
||||
# shellcheck disable=SC2086
|
||||
# shellcheck disable=SC2090
|
||||
|
||||
if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
|
||||
echo "* Debug mode enabled, run docker in interactive mode."
|
||||
echo "* You can use 'exit' to exit the docker container."
|
||||
echo "* You can use 'bin/spc' like normal builds."
|
||||
echo "*"
|
||||
echo "* Mounted directories:"
|
||||
echo "* ./config: $(pwd)/config"
|
||||
echo "* ./src: $(pwd)/src"
|
||||
echo "* ./buildroot: $(pwd)/buildroot"
|
||||
echo "* ./source: $(pwd)/source"
|
||||
echo "* ./dist: $(pwd)/dist"
|
||||
echo "* ./downloads: $(pwd)/downloads"
|
||||
echo "* ./pkgroot: $(pwd)/pkgroot"
|
||||
echo "*"
|
||||
set -ex
|
||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --privileged --rm -it $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
||||
else
|
||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
|
||||
fi
|
||||
@@ -9,23 +9,20 @@
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">= 8.3",
|
||||
"php": ">= 8.1",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-zlib": "*",
|
||||
"laravel/prompts": "^0.1.12",
|
||||
"symfony/console": "^5.4 || ^6 || ^7",
|
||||
"symfony/process": "^7.2",
|
||||
"symfony/yaml": "^7.2",
|
||||
"zhamao/logger": "^1.1.3"
|
||||
"zhamao/logger": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"captainhook/captainhook-phar": "^5.23",
|
||||
"captainhook/hook-installer": "^1.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.60",
|
||||
"humbug/box": "^4.5.0 || ^4.6.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.25",
|
||||
"humbug/box": "^4.5",
|
||||
"nunomaduro/collision": "^7.8",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^10.3 || ^9.5"
|
||||
"phpunit/phpunit": "^10.3 || ^9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
3564
composer.lock
generated
3564
composer.lock
generated
File diff suppressed because it is too large
Load Diff
159
config/env.ini
159
config/env.ini
@@ -1,159 +0,0 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; static-php-cli (spc) env configuration
|
||||
;
|
||||
; This file is used to set default env vars for static-php-cli build.
|
||||
; As dynamic build process, some of these vars can be overwritten by CLI options.
|
||||
; And you can also overwrite these vars by setting them in your shell environment.
|
||||
; The value should be changed only if you know what you are doing. Otherwise, please leave them as default.
|
||||
;
|
||||
; We need to use some pre-defined internal env vars, like `BUILD_ROOT_PATH`, `DOWNLOAD_PATH`, etc.
|
||||
; Please note that these vars cannot be defined in this file, they should only be defined before static-php-cli running.
|
||||
;
|
||||
; Here's a list of env vars, these variables will be defined if not defined:
|
||||
;
|
||||
; BUILD_ROOT_PATH: the root path of the build process. (default: `$(pwd)/buildroot`)
|
||||
; BUILD_INCLUDE_PATH: the path of the include files. (default: `$BUILD_ROOT_PATH/include`)
|
||||
; BUILD_LIB_PATH: the path of the lib files. (default: `$BUILD_ROOT_PATH/lib`)
|
||||
; BUILD_BIN_PATH: the path of the bin files. (default: `$BUILD_ROOT_PATH/bin`)
|
||||
; BUILD_MODULES_PATH: the path of the php modules (shared extensions) files. (default: `$BUILD_ROOT_PATH/modules`)
|
||||
; PKG_ROOT_PATH: the root path of the package files. (default: `$(pwd)/pkgroot/$GNU_ARCH-{darwin|linux|windows}`)
|
||||
; SOURCE_PATH: the path of the source files. (default: `$(pwd)/source`)
|
||||
; DOWNLOAD_PATH: the path of the download files. (default: `$(pwd)/downloads`)
|
||||
; PATH: (*nix only) static-php-cli will add `$BUILD_BIN_PATH` to PATH.
|
||||
; PKG_CONFIG_PATH: (*nix only) static-php-cli will set `$BUILD_LIB_PATH/pkgconfig` to PKG_CONFIG_PATH.
|
||||
;
|
||||
; Here's a list of env vars, these variables is defined in SPC and cannot be changed anywhere:
|
||||
;
|
||||
; SPC_VERSION: the version of static-php-cli.
|
||||
; WORKING_DIR: the working directory of the build process. (default: `$(pwd)`)
|
||||
; ROOT_DIR: the root directory of static-php-cli. (default: `/path/to/static-php-cli`, when running in phar or micro mode: `phar://path/to/spc.phar`)
|
||||
; CPU_COUNT: the count of the CPU cores. (default: `$(nproc)`)
|
||||
; SPC_ARCH: the arch of the current system, for some libraries needed `--host=XXX` args. (default: `$(uname -m)`, e.g. `x86_64`, `aarch64`, `arm64`)
|
||||
; GNU_ARCH: the GNU arch of the current system. (default: `$(uname -m)`, e.g. `x86_64`, `aarch64`)
|
||||
; MAC_ARCH: the MAC arch of the current system. (default: `$(uname -m)`, e.g. `x86_64`, `arm64`)
|
||||
; PKG_CONFIG: (*nix only) static-php-cli will set `$BUILD_BIN_PATH/pkg-config` to PKG_CONFIG.
|
||||
; SPC_LINUX_DEFAULT_CC: (linux only) the default compiler for linux. (For alpine linux: `gcc`, default: `$GNU_ARCH-linux-musl-gcc`)
|
||||
; SPC_LINUX_DEFAULT_CXX: (linux only) the default c++ compiler for linux. (For alpine linux: `g++`, default: `$GNU_ARCH-linux-musl-g++`)
|
||||
; SPC_LINUX_DEFAULT_AR: (linux only) the default archiver for linux. (For alpine linux: `ar`, default: `$GNU_ARCH-linux-musl-ar`)
|
||||
; SPC_EXTRA_PHP_VARS: (linux only) the extra vars for building php, used in `configure` and `make` command.
|
||||
|
||||
[global]
|
||||
; Build concurrency for make -jN, default is CPU_COUNT, this value are used in every libs.
|
||||
SPC_CONCURRENCY=${CPU_COUNT}
|
||||
; Ignore PHP version check before building some extensions
|
||||
SPC_SKIP_PHP_VERSION_CHECK="no"
|
||||
; Ignore some check item for bin/spc doctor command, comma separated (e.g. SPC_SKIP_DOCTOR_CHECK_ITEMS="if homebrew has installed")
|
||||
SPC_SKIP_DOCTOR_CHECK_ITEMS=""
|
||||
; extra modules that xcaddy will include in the FrankenPHP build
|
||||
SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
|
||||
; The display message for php version output (PHP >= 8.4 available)
|
||||
PHP_BUILD_PROVIDER="static-php-cli ${SPC_VERSION}"
|
||||
|
||||
; EXTENSION_DIR where the built php will look for extension when a .ini instructs to load them
|
||||
; only useful for builds targeting not pure-static linking
|
||||
; default paths
|
||||
; Ubuntu/Debian: /usr/lib/php/{PHP_VERSION}/
|
||||
; RHEL: /usr/lib64/php/modules
|
||||
; Alpine: /usr/lib/php{PHP_VERSION}/modules
|
||||
; where {PHP_VERSION} is 84 for php 8.4
|
||||
; EXTENSION_DIR=
|
||||
|
||||
[windows]
|
||||
; build target: win7-static
|
||||
SPC_TARGET=native-windows
|
||||
; php-sdk-binary-tools path
|
||||
PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools"
|
||||
; upx executable path
|
||||
UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe"
|
||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||
SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static,win32_api
|
||||
|
||||
[linux]
|
||||
; Linux can use different build toolchains.
|
||||
; - musl (default, when SPC_LIBC=musl): used for general linux distros, can build `musl` (statically linked) only.
|
||||
; - zig (will become default): usable on all Linux distros, can build `-musl`, `arch-linux-musl -dynamic` and `arch-linux-gnu` targets. Can specify version such as `x86_64-linux-gnu.2.17`.
|
||||
; - musl-native: used for alpine linux, can build `musl` and `musl -dynamic` target.
|
||||
; - gnu-native: used for general linux distros, can build gnu target for the installed glibc version only.
|
||||
|
||||
; option to specify the target, superceded by SPC_TARGET if set
|
||||
SPC_LIBC=musl
|
||||
; uncomment to link libc dynamically on musl
|
||||
; SPC_MUSL_DYNAMIC=true
|
||||
|
||||
; Recommended: specify your target here. Zig toolchain will be used.
|
||||
; examples:
|
||||
; `native-native-gnu` - links against glibc, current OS version
|
||||
; `native-native-gnu.2.17` - links against glibc, version 2.17
|
||||
; `native-native` - links against system libc dynamically
|
||||
; `native-native-musl` - links against musl libc statically
|
||||
; `native-native-musl -dynamic` - links against musl libc dynamically
|
||||
; SPC_TARGET=
|
||||
|
||||
; compiler environments
|
||||
CC=${SPC_LINUX_DEFAULT_CC}
|
||||
CXX=${SPC_LINUX_DEFAULT_CXX}
|
||||
AR=${SPC_LINUX_DEFAULT_AR}
|
||||
LD=${SPC_LINUX_DEFAULT_LD}
|
||||
; default compiler flags, used in CMake toolchain file, openssl and pkg-config build
|
||||
SPC_DEFAULT_C_FLAGS="-fPIC -Os"
|
||||
SPC_DEFAULT_CXX_FLAGS="-fPIC -Os"
|
||||
SPC_DEFAULT_LD_FLAGS=""
|
||||
; upx executable path
|
||||
UPX_EXEC=${PKG_ROOT_PATH}/bin/upx
|
||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||
SPC_MICRO_PATCHES=cli_checks,disable_huge_page
|
||||
|
||||
; *** default build command for building php ***
|
||||
; buildconf command
|
||||
SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
|
||||
; configure command
|
||||
SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --disable-shared --enable-static --disable-all --disable-phpdbg --with-pic"
|
||||
|
||||
; *** default build vars for building php ***
|
||||
; embed type for php, static (libphp.a) or shared (libphp.so)
|
||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||
; EXTRA_CFLAGS for `configure` and `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE ${SPC_DEFAULT_C_FLAGS}"
|
||||
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
|
||||
|
||||
; optional, path to openssl conf. This affects where openssl will look for the default CA.
|
||||
; default on Debian/Alpine: /etc/ssl, default on RHEL: /etc/pki/tls
|
||||
OPENSSLDIR=""
|
||||
|
||||
[macos]
|
||||
; build target: macho or macho (possibly we could support macho-universal in the future)
|
||||
; Currently we do not support universal and cross-compilation for macOS.
|
||||
SPC_TARGET=native-macos
|
||||
; compiler environments
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
AR=ar
|
||||
LD=ld
|
||||
; default compiler flags, used in CMake toolchain file, openssl and pkg-config build
|
||||
SPC_DEFAULT_C_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os"
|
||||
SPC_DEFAULT_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os"
|
||||
SPC_DEFAULT_LD_FLAGS=""
|
||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||
SPC_MICRO_PATCHES=cli_checks,macos_iconv
|
||||
|
||||
; *** default build command for building php ***
|
||||
; buildconf command
|
||||
SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
|
||||
; configure command
|
||||
SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-phpdbg"
|
||||
|
||||
; *** default build vars for building php ***
|
||||
; embed type for php, static (libphp.a) or shared (libphp.dylib)
|
||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||
; EXTRA_CFLAGS for `configure` and `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -Werror=unknown-warning-option ${SPC_DEFAULT_C_FLAGS}"
|
||||
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
|
||||
; minimum compatible macOS version (LLVM vars, availability not guaranteed)
|
||||
MACOSX_DEPLOYMENT_TARGET=12.0
|
||||
|
||||
[freebsd]
|
||||
; compiler environments
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
440
config/ext.json
440
config/ext.json
@@ -17,24 +17,12 @@
|
||||
"type": "external",
|
||||
"source": "apcu"
|
||||
},
|
||||
"ast": {
|
||||
"type": "external",
|
||||
"source": "ast"
|
||||
},
|
||||
"bcmath": {
|
||||
"type": "builtin"
|
||||
},
|
||||
"brotli": {
|
||||
"type": "external",
|
||||
"source": "ext-brotli",
|
||||
"arg-type": "enable",
|
||||
"lib-depends": [
|
||||
"brotli"
|
||||
]
|
||||
},
|
||||
"bz2": {
|
||||
"type": "builtin",
|
||||
"arg-type-unix": "with-path",
|
||||
"arg-type-unix": "with-prefix",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"bzip2"
|
||||
@@ -43,14 +31,6 @@
|
||||
"calendar": {
|
||||
"type": "builtin"
|
||||
},
|
||||
"com_dotnet": {
|
||||
"support": {
|
||||
"BSD": "no",
|
||||
"Linux": "no",
|
||||
"Darwin": "no"
|
||||
},
|
||||
"type": "builtin"
|
||||
},
|
||||
"ctype": {
|
||||
"type": "builtin"
|
||||
},
|
||||
@@ -73,13 +53,6 @@
|
||||
"qdbm"
|
||||
]
|
||||
},
|
||||
"dio": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "dio"
|
||||
},
|
||||
"dom": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
@@ -108,14 +81,6 @@
|
||||
},
|
||||
"type": "wip"
|
||||
},
|
||||
"ev": {
|
||||
"type": "external",
|
||||
"source": "ev",
|
||||
"arg-type-windows": "with",
|
||||
"ext-depends": [
|
||||
"sockets"
|
||||
]
|
||||
},
|
||||
"event": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
@@ -135,20 +100,12 @@
|
||||
"sockets"
|
||||
]
|
||||
},
|
||||
"excimer": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-excimer"
|
||||
},
|
||||
"exif": {
|
||||
"type": "builtin"
|
||||
},
|
||||
"ffi": {
|
||||
"support": {
|
||||
"Linux": "partial",
|
||||
"Linux": "no",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"notes": true,
|
||||
@@ -201,7 +158,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"gettext"
|
||||
]
|
||||
@@ -227,43 +184,17 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"gmp"
|
||||
]
|
||||
},
|
||||
"gmssl": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-gmssl",
|
||||
"lib-depends": [
|
||||
"gmssl"
|
||||
]
|
||||
},
|
||||
"grpc": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-grpc",
|
||||
"arg-type-unix": "enable-path",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"grpc",
|
||||
"zlib",
|
||||
"openssl",
|
||||
"libcares"
|
||||
]
|
||||
},
|
||||
"iconv": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends-unix": [
|
||||
"libiconv"
|
||||
@@ -274,21 +205,17 @@
|
||||
},
|
||||
"igbinary": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "igbinary",
|
||||
"ext-suggests": [
|
||||
"session",
|
||||
"apcu"
|
||||
]
|
||||
"source": "igbinary"
|
||||
},
|
||||
"imagick": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"notes": true,
|
||||
"type": "external",
|
||||
"source": "ext-imagick",
|
||||
"arg-type": "custom",
|
||||
@@ -302,8 +229,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"notes": true,
|
||||
"type": "external",
|
||||
"source": "ext-imap",
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"imap"
|
||||
@@ -323,14 +249,12 @@
|
||||
},
|
||||
"intl": {
|
||||
"support": {
|
||||
"Windows": "no",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"lib-depends-unix": [
|
||||
"lib-depends": [
|
||||
"icu"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"icu-static-win"
|
||||
]
|
||||
},
|
||||
"ldap": {
|
||||
@@ -339,7 +263,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"ldap"
|
||||
],
|
||||
@@ -359,42 +283,11 @@
|
||||
"arg-type": "none",
|
||||
"ext-depends": [
|
||||
"xml"
|
||||
],
|
||||
"build-with-php": true,
|
||||
"target": [
|
||||
"static"
|
||||
]
|
||||
},
|
||||
"lz4": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-lz4",
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"liblz4"
|
||||
]
|
||||
},
|
||||
"maxminddb": {
|
||||
"support": {
|
||||
"BSD": "wip",
|
||||
"Windows": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-maxminddb",
|
||||
"arg-type": "with",
|
||||
"lib-depends": [
|
||||
"libmaxminddb"
|
||||
]
|
||||
},
|
||||
"mbregex": {
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"target": [
|
||||
"static"
|
||||
],
|
||||
"ext-depends": [
|
||||
"mbstring"
|
||||
],
|
||||
@@ -424,15 +317,18 @@
|
||||
"type": "external",
|
||||
"source": "ext-memcache",
|
||||
"arg-type": "custom",
|
||||
"lib-depends": [
|
||||
"zlib"
|
||||
],
|
||||
"ext-depends": [
|
||||
"zlib",
|
||||
"session"
|
||||
]
|
||||
},
|
||||
"memcached": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
"BSD": "wip",
|
||||
"Linux": "no"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "memcached",
|
||||
@@ -441,21 +337,9 @@
|
||||
"lib-depends": [
|
||||
"libmemcached"
|
||||
],
|
||||
"lib-depends-unix": [
|
||||
"libmemcached",
|
||||
"fastlz"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"zstd"
|
||||
],
|
||||
"ext-depends": [
|
||||
"session",
|
||||
"zlib"
|
||||
],
|
||||
"ext-suggests": [
|
||||
"igbinary",
|
||||
"msgpack",
|
||||
"session"
|
||||
]
|
||||
},
|
||||
"mongodb": {
|
||||
@@ -471,28 +355,11 @@
|
||||
"openssl",
|
||||
"zstd",
|
||||
"zlib"
|
||||
],
|
||||
"frameworks": [
|
||||
"CoreFoundation",
|
||||
"Security"
|
||||
]
|
||||
},
|
||||
"msgpack": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "msgpack",
|
||||
"arg-type-unix": "with",
|
||||
"arg-type-windows": "enable",
|
||||
"ext-depends": [
|
||||
"session"
|
||||
]
|
||||
},
|
||||
"mysqli": {
|
||||
"type": "builtin",
|
||||
"arg-type": "with",
|
||||
"build-with-php": true,
|
||||
"ext-depends": [
|
||||
"mysqlnd"
|
||||
]
|
||||
@@ -500,45 +367,10 @@
|
||||
"mysqlnd": {
|
||||
"type": "builtin",
|
||||
"arg-type-windows": "with",
|
||||
"build-with-php": true,
|
||||
"lib-depends": [
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"mysqlnd_ed25519": {
|
||||
"type": "external",
|
||||
"source": "mysqlnd_ed25519",
|
||||
"arg-type": "enable",
|
||||
"target": [
|
||||
"shared"
|
||||
],
|
||||
"ext-depends": [
|
||||
"mysqlnd"
|
||||
],
|
||||
"lib-depends": [
|
||||
"libsodium"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"mysqlnd_parsec": {
|
||||
"type": "external",
|
||||
"source": "mysqlnd_parsec",
|
||||
"arg-type": "enable",
|
||||
"target": [
|
||||
"shared"
|
||||
],
|
||||
"ext-depends": [
|
||||
"mysqlnd"
|
||||
],
|
||||
"lib-depends": [
|
||||
"libsodium"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"oci8": {
|
||||
"type": "wip",
|
||||
"support": {
|
||||
@@ -549,29 +381,15 @@
|
||||
},
|
||||
"notes": true
|
||||
},
|
||||
"odbc": {
|
||||
"support": {
|
||||
"BSD": "wip",
|
||||
"Windows": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type-unix": "custom",
|
||||
"lib-depends-unix": [
|
||||
"unixodbc"
|
||||
]
|
||||
},
|
||||
"opcache": {
|
||||
"type": "builtin",
|
||||
"arg-type-unix": "custom",
|
||||
"arg-type-windows": "enable",
|
||||
"zend-extension": true
|
||||
"arg-type": "custom"
|
||||
},
|
||||
"openssl": {
|
||||
"notes": true,
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"arg-type-windows": "with",
|
||||
"build-with-php": true,
|
||||
"lib-depends": [
|
||||
"openssl",
|
||||
"zlib"
|
||||
@@ -580,13 +398,6 @@
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"opentelemetry": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "opentelemetry"
|
||||
},
|
||||
"parallel": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
@@ -606,10 +417,9 @@
|
||||
},
|
||||
"notes": true,
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libargon2",
|
||||
"openssl"
|
||||
"libargon2"
|
||||
]
|
||||
},
|
||||
"pcntl": {
|
||||
@@ -619,13 +429,6 @@
|
||||
"type": "builtin",
|
||||
"unix-only": true
|
||||
},
|
||||
"pcov": {
|
||||
"type": "external",
|
||||
"source": "pcov",
|
||||
"target": [
|
||||
"shared"
|
||||
]
|
||||
},
|
||||
"pdo": {
|
||||
"type": "builtin"
|
||||
},
|
||||
@@ -637,36 +440,19 @@
|
||||
"mysqlnd"
|
||||
]
|
||||
},
|
||||
"pdo_odbc": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"lib-depends-unix": [
|
||||
"unixodbc"
|
||||
],
|
||||
"ext-depends": [
|
||||
"pdo",
|
||||
"odbc"
|
||||
]
|
||||
},
|
||||
"pdo_pgsql": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type-windows": "custom",
|
||||
"arg-type": "with-prefix",
|
||||
"ext-depends": [
|
||||
"pdo",
|
||||
"pgsql"
|
||||
],
|
||||
"lib-depends-unix": [
|
||||
"lib-depends": [
|
||||
"postgresql"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"postgresql-win"
|
||||
]
|
||||
},
|
||||
"pdo_sqlite": {
|
||||
@@ -697,16 +483,14 @@
|
||||
},
|
||||
"pgsql": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"notes": true,
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"lib-depends-unix": [
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"postgresql"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"postgresql-win"
|
||||
]
|
||||
},
|
||||
"phar": {
|
||||
@@ -740,35 +524,20 @@
|
||||
"source": "rar",
|
||||
"cpp-extension": true
|
||||
},
|
||||
"rdkafka": {
|
||||
"support": {
|
||||
"BSD": "wip",
|
||||
"Windows": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-rdkafka",
|
||||
"arg-type": "custom",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"librdkafka"
|
||||
]
|
||||
},
|
||||
"readline": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libedit"
|
||||
],
|
||||
"target": [
|
||||
"static"
|
||||
"readline"
|
||||
]
|
||||
},
|
||||
"redis": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
@@ -776,21 +545,18 @@
|
||||
"arg-type": "custom",
|
||||
"ext-suggests": [
|
||||
"session",
|
||||
"igbinary",
|
||||
"msgpack"
|
||||
"igbinary"
|
||||
],
|
||||
"lib-suggests-unix": [
|
||||
"lib-suggests": [
|
||||
"zstd",
|
||||
"liblz4"
|
||||
]
|
||||
},
|
||||
"session": {
|
||||
"type": "builtin",
|
||||
"build-with-php": true
|
||||
"type": "builtin"
|
||||
},
|
||||
"shmop": {
|
||||
"type": "builtin",
|
||||
"build-with-php": true
|
||||
"type": "builtin"
|
||||
},
|
||||
"simdjson": {
|
||||
"type": "external",
|
||||
@@ -808,8 +574,7 @@
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml"
|
||||
],
|
||||
"build-with-php": true
|
||||
]
|
||||
},
|
||||
"snappy": {
|
||||
"support": {
|
||||
@@ -823,31 +588,21 @@
|
||||
"lib-depends": [
|
||||
"snappy"
|
||||
],
|
||||
"ext-suggests": [
|
||||
"ext-suggest": [
|
||||
"apcu"
|
||||
]
|
||||
},
|
||||
"snmp": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type-unix": "with",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"net-snmp"
|
||||
]
|
||||
},
|
||||
"soap": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"libxml",
|
||||
"session"
|
||||
"lib-depends": [
|
||||
"libxml2"
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml"
|
||||
]
|
||||
},
|
||||
"sockets": {
|
||||
@@ -855,6 +610,7 @@
|
||||
},
|
||||
"sodium": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
@@ -881,9 +637,8 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type-windows": "with",
|
||||
"build-with-php": true,
|
||||
"lib-depends": [
|
||||
"sqlite"
|
||||
]
|
||||
@@ -908,12 +663,12 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-ssh2",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libssh2"
|
||||
],
|
||||
"ext-depends": [
|
||||
"ext-depends-windows": [
|
||||
"openssl",
|
||||
"zlib"
|
||||
]
|
||||
@@ -935,23 +690,14 @@
|
||||
"nghttp2",
|
||||
"zlib"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"zstd"
|
||||
],
|
||||
"lib-suggests-linux": [
|
||||
"zstd",
|
||||
"liburing"
|
||||
],
|
||||
"ext-depends": [
|
||||
"openssl",
|
||||
"curl"
|
||||
],
|
||||
"ext-suggests": [
|
||||
"sockets",
|
||||
"swoole-hook-pgsql",
|
||||
"swoole-hook-mysql",
|
||||
"swoole-hook-sqlite",
|
||||
"swoole-hook-odbc"
|
||||
"swoole-hook-sqlite"
|
||||
]
|
||||
},
|
||||
"swoole-hook-mysql": {
|
||||
@@ -961,33 +707,16 @@
|
||||
},
|
||||
"notes": true,
|
||||
"type": "addon",
|
||||
"arg-type": "none",
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"mysqlnd",
|
||||
"pdo",
|
||||
"pdo_mysql",
|
||||
"swoole"
|
||||
"pdo_mysql"
|
||||
],
|
||||
"ext-suggests": [
|
||||
"mysqli"
|
||||
]
|
||||
},
|
||||
"swoole-hook-odbc": {
|
||||
"support": {
|
||||
"Windows": "no",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"notes": true,
|
||||
"type": "addon",
|
||||
"arg-type": "none",
|
||||
"ext-depends": [
|
||||
"pdo",
|
||||
"swoole"
|
||||
],
|
||||
"lib-depends": [
|
||||
"unixodbc"
|
||||
]
|
||||
},
|
||||
"swoole-hook-pgsql": {
|
||||
"support": {
|
||||
"Windows": "no",
|
||||
@@ -996,11 +725,10 @@
|
||||
},
|
||||
"notes": true,
|
||||
"type": "addon",
|
||||
"arg-type": "none",
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"pgsql",
|
||||
"pdo",
|
||||
"swoole"
|
||||
"pdo"
|
||||
]
|
||||
},
|
||||
"swoole-hook-sqlite": {
|
||||
@@ -1010,11 +738,10 @@
|
||||
},
|
||||
"notes": true,
|
||||
"type": "addon",
|
||||
"arg-type": "none",
|
||||
"arg-type": "custom",
|
||||
"ext-depends": [
|
||||
"sqlite3",
|
||||
"pdo",
|
||||
"swoole"
|
||||
"pdo"
|
||||
]
|
||||
},
|
||||
"swow": {
|
||||
@@ -1062,22 +789,13 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"tidy"
|
||||
]
|
||||
},
|
||||
"tokenizer": {
|
||||
"type": "builtin",
|
||||
"build-with-php": true
|
||||
},
|
||||
"trader": {
|
||||
"support": {
|
||||
"BSD": "wip",
|
||||
"Windows": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-trader"
|
||||
"type": "builtin"
|
||||
},
|
||||
"uuid": {
|
||||
"support": {
|
||||
@@ -1086,7 +804,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-uuid",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libuuid"
|
||||
]
|
||||
@@ -1098,7 +816,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-uv",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libuv"
|
||||
],
|
||||
@@ -1107,19 +825,14 @@
|
||||
]
|
||||
},
|
||||
"xdebug": {
|
||||
"type": "external",
|
||||
"source": "xdebug",
|
||||
"target": [
|
||||
"shared"
|
||||
],
|
||||
"type": "builtin",
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "no",
|
||||
"Darwin": "partial",
|
||||
"Linux": "partial"
|
||||
"Darwin": "no",
|
||||
"Linux": "no"
|
||||
},
|
||||
"notes": true,
|
||||
"zend-extension": true
|
||||
"notes": true
|
||||
},
|
||||
"xhprof": {
|
||||
"support": {
|
||||
@@ -1131,11 +844,11 @@
|
||||
"source": "xhprof",
|
||||
"ext-depends": [
|
||||
"ctype"
|
||||
],
|
||||
"build-with-php": true
|
||||
]
|
||||
},
|
||||
"xlswriter": {
|
||||
"support": {
|
||||
"Windows": "wip",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
@@ -1162,8 +875,7 @@
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"iconv"
|
||||
],
|
||||
"build-with-php": true
|
||||
]
|
||||
},
|
||||
"xmlreader": {
|
||||
"support": {
|
||||
@@ -1177,8 +889,7 @@
|
||||
"ext-depends-windows": [
|
||||
"xml",
|
||||
"dom"
|
||||
],
|
||||
"build-with-php": true
|
||||
]
|
||||
},
|
||||
"xmlwriter": {
|
||||
"support": {
|
||||
@@ -1191,8 +902,7 @@
|
||||
],
|
||||
"ext-depends-windows": [
|
||||
"xml"
|
||||
],
|
||||
"build-with-php": true
|
||||
]
|
||||
},
|
||||
"xsl": {
|
||||
"support": {
|
||||
@@ -1200,7 +910,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-path",
|
||||
"arg-type": "with-prefix",
|
||||
"lib-depends": [
|
||||
"libxslt"
|
||||
],
|
||||
@@ -1209,14 +919,6 @@
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
"xz": {
|
||||
"type": "external",
|
||||
"source": "ext-xz",
|
||||
"arg-type": "with",
|
||||
"lib-depends": [
|
||||
"xz"
|
||||
]
|
||||
},
|
||||
"yac": {
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
@@ -1224,9 +926,6 @@
|
||||
"type": "external",
|
||||
"source": "yac",
|
||||
"arg-type-unix": "custom",
|
||||
"lib-depends-unix": [
|
||||
"fastlz"
|
||||
],
|
||||
"ext-depends-unix": [
|
||||
"igbinary"
|
||||
]
|
||||
@@ -1237,7 +936,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "yaml",
|
||||
"arg-type-unix": "with-path",
|
||||
"arg-type-unix": "with-prefix",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libyaml"
|
||||
@@ -1247,9 +946,8 @@
|
||||
"support": {
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-zip",
|
||||
"arg-type": "custom",
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type-windows": "enable",
|
||||
"lib-depends-unix": [
|
||||
"libzip"
|
||||
@@ -1271,10 +969,6 @@
|
||||
"arg-type-windows": "enable",
|
||||
"lib-depends": [
|
||||
"zlib"
|
||||
],
|
||||
"build-with-php": true,
|
||||
"target": [
|
||||
"static"
|
||||
]
|
||||
},
|
||||
"zstd": {
|
||||
|
||||
1746
config/lib.json
1746
config/lib.json
File diff suppressed because it is too large
Load Diff
@@ -1,16 +1,4 @@
|
||||
{
|
||||
"go-xcaddy-aarch64-linux": {
|
||||
"type": "custom"
|
||||
},
|
||||
"go-xcaddy-aarch64-macos": {
|
||||
"type": "custom"
|
||||
},
|
||||
"go-xcaddy-x86_64-linux": {
|
||||
"type": "custom"
|
||||
},
|
||||
"go-xcaddy-x86_64-macos": {
|
||||
"type": "custom"
|
||||
},
|
||||
"musl-toolchain-aarch64-linux": {
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/aarch64-musl-toolchain.tgz"
|
||||
@@ -21,42 +9,10 @@
|
||||
},
|
||||
"nasm-x86_64-win": {
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/nasm/nasm-2.16.01-win64.zip",
|
||||
"url": "https://www.nasm.us/pub/nasm/releasebuilds/2.16.01/win64/nasm-2.16.01-win64.zip",
|
||||
"extract-files": {
|
||||
"nasm.exe": "{php_sdk_path}/bin/nasm.exe",
|
||||
"ndisasm.exe": "{php_sdk_path}/bin/ndisasm.exe"
|
||||
}
|
||||
},
|
||||
"pkg-config-aarch64-linux": {
|
||||
"type": "ghrel",
|
||||
"repo": "static-php/static-php-cli-hosted",
|
||||
"match": "pkg-config-aarch64-linux-musl-1.2.5.txz",
|
||||
"extract-files": {
|
||||
"bin/pkg-config": "{pkg_root_path}/bin/pkg-config"
|
||||
}
|
||||
},
|
||||
"pkg-config-aarch64-macos": {
|
||||
"type": "ghrel",
|
||||
"repo": "static-php/static-php-cli-hosted",
|
||||
"match": "pkg-config-aarch64-darwin.txz",
|
||||
"extract-files": {
|
||||
"bin/pkg-config": "{pkg_root_path}/bin/pkg-config"
|
||||
}
|
||||
},
|
||||
"pkg-config-x86_64-linux": {
|
||||
"type": "ghrel",
|
||||
"repo": "static-php/static-php-cli-hosted",
|
||||
"match": "pkg-config-x86_64-linux-musl-1.2.5.txz",
|
||||
"extract-files": {
|
||||
"bin/pkg-config": "{pkg_root_path}/bin/pkg-config"
|
||||
}
|
||||
},
|
||||
"pkg-config-x86_64-macos": {
|
||||
"type": "ghrel",
|
||||
"repo": "static-php/static-php-cli-hosted",
|
||||
"match": "pkg-config-x86_64-darwin.txz",
|
||||
"extract-files": {
|
||||
"bin/pkg-config": "{pkg_root_path}/bin/pkg-config"
|
||||
"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": {
|
||||
@@ -84,22 +40,7 @@
|
||||
"repo": "upx/upx",
|
||||
"match": "upx.+-win64\\.zip",
|
||||
"extract-files": {
|
||||
"upx.exe": "{pkg_root_path}/bin/upx.exe"
|
||||
"upx-*-win64/upx.exe": "{pkg_root_path}/bin/upx.exe"
|
||||
}
|
||||
},
|
||||
"zig-aarch64-linux": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-aarch64-macos": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-x86_64-linux": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-x86_64-macos": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-x86_64-win": {
|
||||
"type": "custom"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"repo": "static-php/static-php-cli-hosted",
|
||||
"prefer-stable": true,
|
||||
"match-pattern-linux": "{name}-{arch}-{os}-{libc}-{libcver}.txz",
|
||||
"match-pattern-macos": "{name}-{arch}-{os}.txz",
|
||||
"match-pattern-windows": "{name}-{arch}-{os}.tgz"
|
||||
}
|
||||
"match-pattern": "{name}-{arch}-{os}.txz",
|
||||
"suffix": "txz"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,219 +0,0 @@
|
||||
<template>
|
||||
<div class="contributors-container">
|
||||
<div class="contributors-header">
|
||||
<h2>Contributors</h2>
|
||||
<p class="contributors-description">
|
||||
Thanks to all the amazing people who have contributed to this project!
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div v-if="loading" class="loading-state">
|
||||
<div class="spinner"></div>
|
||||
<p>Loading contributors...</p>
|
||||
</div>
|
||||
|
||||
<div v-else-if="error" class="error-state">
|
||||
<p>{{ error }}</p>
|
||||
</div>
|
||||
|
||||
<div v-else class="contributors-grid">
|
||||
<a
|
||||
v-for="contributor in contributors"
|
||||
:key="contributor.id"
|
||||
:href="contributor.html_url"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="contributor-card"
|
||||
:title="contributor.login"
|
||||
>
|
||||
<img
|
||||
:src="contributor.avatar_url"
|
||||
:alt="contributor.login"
|
||||
class="contributor-avatar"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="contributor-name">{{ contributor.login }}</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
|
||||
interface Contributor {
|
||||
id: number;
|
||||
login: string;
|
||||
avatar_url: string;
|
||||
html_url: string;
|
||||
contributions: number;
|
||||
}
|
||||
|
||||
const contributors = ref<Contributor[]>([]);
|
||||
const loading = ref(true);
|
||||
const error = ref('');
|
||||
|
||||
const fetchContributors = async () => {
|
||||
try {
|
||||
loading.value = true;
|
||||
error.value = '';
|
||||
|
||||
const response = await fetch(
|
||||
'https://api.github.com/repos/crazywhalecc/static-php-cli/contributors?per_page=24'
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch contributors');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
contributors.value = data;
|
||||
} catch (err) {
|
||||
error.value = 'Failed to load contributors. Please try again later.';
|
||||
console.error('Error fetching contributors:', err);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchContributors();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.contributors-container {
|
||||
margin: 48px auto;
|
||||
padding: 32px 24px;
|
||||
max-width: 1152px;
|
||||
background: linear-gradient(135deg, var(--vp-c-bg-soft) 0%, var(--vp-c-bg) 100%);
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.contributors-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.contributors-header h2 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 8px 0;
|
||||
background: linear-gradient(120deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.contributors-description {
|
||||
font-size: 0.95rem;
|
||||
color: var(--vp-c-text-2);
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.loading-state,
|
||||
.error-state {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
color: var(--vp-c-text-2);
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 0 auto 16px;
|
||||
border: 4px solid var(--vp-c-divider);
|
||||
border-top-color: var(--vp-c-brand-1);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.contributors-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.contributor-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
background: var(--vp-c-bg);
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.contributor-card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
||||
border-color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.contributor-avatar {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--vp-c-divider);
|
||||
transition: all 0.3s ease;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.contributor-card:hover .contributor-avatar {
|
||||
border-color: var(--vp-c-brand-1);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.contributor-name {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
word-break: break-word;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.contributors-container {
|
||||
margin: 32px 16px;
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.contributors-header h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.contributors-description {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.contributors-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.contributor-card {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.contributor-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.contributor-name {
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,79 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<header class="DocSearch-SearchBar" style="padding: 0">
|
||||
<form class="DocSearch-Form searchinput">
|
||||
<input class="DocSearch-Input" v-model="filterText" placeholder="Filter name..." @input="doFilter" />
|
||||
</form>
|
||||
</header>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Extension Name</th>
|
||||
<th>Linux</th>
|
||||
<th>macOS</th>
|
||||
<th>FreeBSD</th>
|
||||
<th>Windows</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="item in filterData">
|
||||
<td v-if="!item.notes">{{ item.name }}</td>
|
||||
<td v-else>
|
||||
<a :href="'./extension-notes.html#' + item.name">{{ item.name }}</a>
|
||||
</td>
|
||||
<td>{{ item.linux }}</td>
|
||||
<td>{{ item.macos }}</td>
|
||||
<td>{{ item.freebsd }}</td>
|
||||
<td>{{ item.windows }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-if="filterData.length === 0" style="margin: 0 4px 20px 4px; color: var(--vp-c-text-2); font-size: 14px">
|
||||
No result, please try another keyword.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "SearchTable"
|
||||
}
|
||||
</script>
|
||||
|
||||
<script setup>
|
||||
import {ref} from "vue";
|
||||
import ext from '../../../config/ext.json';
|
||||
|
||||
// 将 ext 转换为列表,方便后续操作
|
||||
const data = ref([]);
|
||||
for (const [name, item] of Object.entries(ext)) {
|
||||
data.value.push({
|
||||
name,
|
||||
linux: item.support?.Linux === undefined ? 'yes' : (item.support?.Linux === 'wip' ? '' : item.support?.Linux),
|
||||
macos: item.support?.Darwin === undefined ? 'yes' : (item.support?.Darwin === 'wip' ? '' : item.support?.Darwin),
|
||||
freebsd: item.support?.BSD === undefined ? 'yes' : (item.support?.BSD === 'wip' ? '' : item.support?.BSD),
|
||||
windows: item.support?.Windows === undefined ? 'yes' : (item.support?.Windows === 'wip' ? '' : item.support?.Windows),
|
||||
notes: item.notes === true,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const filterData = ref(data.value);
|
||||
const filterText = ref('');
|
||||
|
||||
const doFilter = () => {
|
||||
if (filterText.value === '') {
|
||||
filterData.value = data.value;
|
||||
return;
|
||||
}
|
||||
filterData.value = data.value.filter(item => {
|
||||
return item.name.toLowerCase().includes(filterText.value.toLowerCase());
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.searchinput {
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
}
|
||||
</style>
|
||||
@@ -4,7 +4,7 @@ import sidebarZh from "./sidebar.zh";
|
||||
|
||||
// https://vitepress.dev/reference/site-config
|
||||
export default {
|
||||
title: "Static PHP",
|
||||
title: "static-php-cli",
|
||||
description: "Build single static PHP binary, with PHP project together, with popular extensions included.",
|
||||
locales: {
|
||||
en: {
|
||||
@@ -44,22 +44,9 @@ export default {
|
||||
},
|
||||
themeConfig: {
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
logo: '/images/static-php_nobg.png',
|
||||
nav: [],
|
||||
socialLinks: [
|
||||
{icon: 'github', link: 'https://github.com/crazywhalecc/static-php-cli'}
|
||||
],
|
||||
footer: {
|
||||
message: 'Released under the MIT License.',
|
||||
copyright: 'Copyright © 2023-present crazywhalecc'
|
||||
},
|
||||
search: {
|
||||
provider: 'algolia',
|
||||
options: {
|
||||
appId: 'IHJHUB1SF1',
|
||||
apiKey: '8266d31cc2ffbd0e059f1c6e5bdaf8fc',
|
||||
indexName: 'static-php docs',
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,53 @@
|
||||
export default {
|
||||
'/en/guide/': [
|
||||
{
|
||||
text: 'Basic Build Guides',
|
||||
items: [
|
||||
{text: 'Guide', link: '/en/guide/'},
|
||||
{text: 'Build (Local)', link: '/en/guide/manual-build'},
|
||||
{text: 'Build (CI)', link: '/en/guide/action-build'},
|
||||
{text: 'Supported Extensions', link: '/en/guide/extensions'},
|
||||
{text: 'Extension Notes', link: '/en/guide/extension-notes'},
|
||||
{text: 'Build Command Generator', link: '/en/guide/cli-generator'},
|
||||
{text: 'Environment Variables', link: '/en/guide/env-vars', collapsed: true,},
|
||||
{text: 'Dependency Table', link: '/en/guide/deps-map'},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Extended Build Guides',
|
||||
items: [
|
||||
{text: 'Troubleshooting', link: '/en/guide/troubleshooting'},
|
||||
{text: 'Build on Windows', link: '/en/guide/build-on-windows'},
|
||||
{text: 'Build with GNU libc', link: '/en/guide/build-with-glibc'},
|
||||
],
|
||||
}
|
||||
],
|
||||
'/en/develop/': [
|
||||
{
|
||||
text: 'Development',
|
||||
items: [
|
||||
{text: 'Get Started', link: '/en/develop/'},
|
||||
{text: 'Project Structure', link: '/en/develop/structure'},
|
||||
{text: 'PHP Source Modification', link: '/en/develop/php-src-changes'},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Module',
|
||||
items: [
|
||||
{text: 'Doctor ', link: '/en/develop/doctor-module'},
|
||||
{text: 'Source', link: '/en/develop/source-module'},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Extra',
|
||||
items: [
|
||||
{text: 'Compilation Tools', link: '/en/develop/system-build-tools'},
|
||||
{text: 'craft.yml Configuration', link: '/zh/develop/craft-yml'},
|
||||
]
|
||||
}
|
||||
],
|
||||
'/en/contributing/': [
|
||||
{
|
||||
text: 'Contributing',
|
||||
items: [
|
||||
{text: 'Contributing', link: '/en/contributing/'},
|
||||
],
|
||||
}
|
||||
],
|
||||
'/en/guide/': [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
{text: 'Guide', link: '/en/guide/'},
|
||||
{text: 'Actions Build', link: '/en/guide/action-build'},
|
||||
{text: 'Manual Build', link: '/en/guide/manual-build'},
|
||||
{text: 'Extension List', link: '/en/guide/extensions'},
|
||||
{text: 'Extension Notes', link: '/en/guide/extension-notes'},
|
||||
{text: 'Command Generator', link: '/en/guide/cli-generator'},
|
||||
{text: 'Environment Variables', link: '/en/guide/env-vars', collapsed: true,},
|
||||
]
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{text: 'Troubleshooting', link: '/en/guide/troubleshooting'},
|
||||
{text: 'Build on Windows', link: '/en/guide/build-on-windows'},
|
||||
],
|
||||
}
|
||||
],
|
||||
'/en/develop/': [
|
||||
{
|
||||
text: 'Development',
|
||||
items: [
|
||||
{text: 'Get Started', link: '/en/develop/'},
|
||||
{text: 'Project Structure', link: '/en/develop/structure'},
|
||||
{text: 'PHP Source Modification', link: '/en/develop/php-src-changes'},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Module',
|
||||
items: [
|
||||
{text: 'Doctor ', link: '/en/develop/doctor-module'},
|
||||
{text: 'Source', link: '/en/develop/source-module'},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Extra',
|
||||
items: [
|
||||
{text: 'Compilation Tools', link: '/en/develop/system-build-tools'},
|
||||
]
|
||||
}
|
||||
],
|
||||
'/en/contributing/': [
|
||||
{
|
||||
text: 'Contributing',
|
||||
items: [
|
||||
{text: 'Contributing', link: '/en/contributing/'},
|
||||
],
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
@@ -1,57 +1,53 @@
|
||||
export default {
|
||||
'/zh/guide/': [
|
||||
{
|
||||
text: '构建指南',
|
||||
items: [
|
||||
{text: '指南', link: '/zh/guide/'},
|
||||
{text: '本地构建', link: '/zh/guide/manual-build'},
|
||||
{text: 'Actions 构建', link: '/zh/guide/action-build'},
|
||||
{text: '扩展列表', link: '/zh/guide/extensions'},
|
||||
{text: '扩展注意事项', link: '/zh/guide/extension-notes'},
|
||||
{text: '编译命令生成器', link: '/zh/guide/cli-generator'},
|
||||
{text: '环境变量列表', link: '/zh/guide/env-vars'},
|
||||
{text: '依赖关系图表', link: '/zh/guide/deps-map'},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '扩展构建指南',
|
||||
items: [
|
||||
{text: '故障排除', link: '/zh/guide/troubleshooting'},
|
||||
{text: '在 Windows 上构建', link: '/zh/guide/build-on-windows'},
|
||||
{text: '构建 GNU libc 兼容的二进制', link: '/zh/guide/build-with-glibc'},
|
||||
],
|
||||
}
|
||||
],
|
||||
'/zh/develop/': [
|
||||
{
|
||||
text: '开发指南',
|
||||
items: [
|
||||
{text: '开发简介', link: '/zh/develop/'},
|
||||
{text: '项目结构简介', link: '/zh/develop/structure'},
|
||||
{text: '对 PHP 源码的修改', link: '/zh/develop/php-src-changes'},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '模块',
|
||||
items: [
|
||||
{text: 'Doctor 环境检查工具', link: '/zh/develop/doctor-module'},
|
||||
{text: '资源模块', link: '/zh/develop/source-module'},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '其他',
|
||||
items: [
|
||||
{text: '系统编译工具', link: '/zh/develop/system-build-tools'},
|
||||
{text: 'craft.yml 配置详解', link: '/zh/develop/craft-yml'},
|
||||
]
|
||||
}
|
||||
],
|
||||
'/zh/contributing/': [
|
||||
{
|
||||
text: '贡献指南',
|
||||
items: [
|
||||
{text: '贡献指南', link: '/zh/contributing/'},
|
||||
],
|
||||
}
|
||||
],
|
||||
'/zh/guide/': [
|
||||
{
|
||||
text: '构建指南',
|
||||
items: [
|
||||
{text: '指南', link: '/zh/guide/'},
|
||||
{text: 'Actions 构建', link: '/zh/guide/action-build'},
|
||||
{text: '本地构建', link: '/zh/guide/manual-build'},
|
||||
{text: '扩展列表', link: '/zh/guide/extensions'},
|
||||
{text: '扩展注意事项', link: '/zh/guide/extension-notes'},
|
||||
{text: '编译命令生成器', link: '/zh/guide/cli-generator'},
|
||||
{text: '环境变量列表', link: '/zh/guide/env-vars'},
|
||||
]
|
||||
},
|
||||
{
|
||||
items: [
|
||||
{text: '故障排除', link: '/zh/guide/troubleshooting'},
|
||||
{text: '在 Windows 上构建', link: '/zh/guide/build-on-windows'},
|
||||
],
|
||||
}
|
||||
],
|
||||
'/zh/develop/': [
|
||||
{
|
||||
text: '开发指南',
|
||||
items: [
|
||||
{ text: '开发简介', link: '/zh/develop/' },
|
||||
{ text: '项目结构简介', link: '/zh/develop/structure' },
|
||||
{text: '对 PHP 源码的修改', link: '/zh/develop/php-src-changes'},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: '模块',
|
||||
items: [
|
||||
{ text: 'Doctor 环境检查工具', link: '/zh/develop/doctor-module' },
|
||||
{ text: '资源模块', link: '/zh/develop/source-module' },
|
||||
]
|
||||
},
|
||||
{
|
||||
text: '其他',
|
||||
items: [
|
||||
{text: '系统编译工具', link: '/zh/develop/system-build-tools'},
|
||||
]
|
||||
}
|
||||
],
|
||||
'/zh/contributing/': [
|
||||
{
|
||||
text: '贡献指南',
|
||||
items: [
|
||||
{text: '贡献指南', link: '/zh/contributing/'},
|
||||
],
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import {inBrowser, useData} from "vitepress";
|
||||
import {watchEffect} from "vue";
|
||||
import './style.css';
|
||||
|
||||
export default {
|
||||
...DefaultTheme,
|
||||
@@ -14,4 +13,4 @@ export default {
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
/** override default styles */
|
||||
.vp-sponsor-grid-image {
|
||||
max-height:36px !important;
|
||||
max-width: 1000px !important;
|
||||
}
|
||||
|
||||
|
||||
.vp-doc .contributors-header h2 {
|
||||
padding-top: 0;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.vp-doc .sponsors-header h2 {
|
||||
padding-top: 0;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.dark .VPImage.logo {
|
||||
filter: contrast(0.7);
|
||||
}
|
||||
|
||||
.dark .VPImage.image-src {
|
||||
filter: contrast(0.7);
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
```yaml
|
||||
# PHP version to build (default: 8.4)
|
||||
php-version: 8.4
|
||||
# [REQUIRED] Static PHP extensions to build (list or comma-separated are both accepted)
|
||||
extensions: bcmath,fileinfo,phar,zlib,sodium,posix,pcntl
|
||||
# Extra libraries to build (list or comma-separated are both accepted)
|
||||
libs: [ ]
|
||||
# [REQUIRED] Build SAPIs (list or comma-separated are both accepted)
|
||||
sapi: cli,micro,fpm
|
||||
# Show full console output (default: false)
|
||||
debug: false
|
||||
# Build options (same as `build` command options, all options are optional)
|
||||
build-options:
|
||||
# Before build, remove all old build files and sources (default: false)
|
||||
with-clean: false
|
||||
# Build with all suggested libraries (default: false)
|
||||
with-suggested-libs: false
|
||||
# Build with all suggested extensions (default: false)
|
||||
with-suggested-exts: false
|
||||
# Build extra shared extensions (list or comma-separated are both accepted)
|
||||
build-shared: [ ]
|
||||
# Build without stripping the binary (default: false)
|
||||
no-strip: false
|
||||
# Disable Opcache JIT (default: false)
|
||||
disable-opcache-jit: false
|
||||
# PHP configuration options (same as --with-config-file-path)
|
||||
with-config-file-path: ""
|
||||
# PHP configuration options (same as --with-config-file-scan-dir)
|
||||
with-config-file-scan-dir: ""
|
||||
# Hardcoded INI options for cli and micro SAPI (e.g. "memory_limit=4G", list accepted)
|
||||
with-hardcoded-ini: [ ]
|
||||
# Pretend micro SAPI as cli SAPI to avoid some frameworks to limit the usage of micro SAPI
|
||||
with-micro-fake-cli: false
|
||||
# Additional patch point injection files (e.g. "path/to/patch.php", list accepted)
|
||||
with-added-patch: [ ]
|
||||
# Ignore micro extension tests (if you are using micro SAPI, default: false)
|
||||
without-micro-ext-test: false
|
||||
# UPX pack the binary (default: false)
|
||||
with-upx-pack: false
|
||||
# Set the micro.exe program icon (only for Windows, default: "")
|
||||
with-micro-logo: ""
|
||||
# Set micro SAPI as win32 mode, without this, micro SAPI will be compiled as a console application (only for Windows, default: false)
|
||||
enable-micro-win32: false
|
||||
|
||||
# Build options for shared extensions (list or comma-separated are both accepted)
|
||||
shared-extensions: [ ]
|
||||
|
||||
# Download options
|
||||
download-options:
|
||||
# Use custom url for specified sources, format: "{source-name}:{url}" (e.g. "php-src:https://example.com/php-8.4.0.tar.gz")
|
||||
custom-url: [ ]
|
||||
# Use custom git repo for specified sources, format: "{source-name}:{branch}:{url}" (e.g. "php-src:master:https://github.com/php/php-src.git")
|
||||
custom-git: [ ]
|
||||
# Retries count for downloading sources (default: 5)
|
||||
retry: 5
|
||||
# Use pre-built libraries if available (default: false)
|
||||
prefer-pre-built: true
|
||||
# Do not download from alternative sources (default: false)
|
||||
no-alt: false
|
||||
|
||||
craft-options:
|
||||
doctor: true
|
||||
download: true
|
||||
build: true
|
||||
|
||||
# Extra environment variables
|
||||
extra-env:
|
||||
# e.g. Use github token to avoid rate limit
|
||||
GITHUB_TOKEN: your-github-token
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
# craft.yml Configuration
|
||||
|
||||
<!--@include: ../../deps-craft-yml.md-->
|
||||
@@ -24,8 +24,7 @@ The following is the source download configuration corresponding to the `libeven
|
||||
"type": "ghrel",
|
||||
"repo": "libevent/libevent",
|
||||
"match": "libevent.+\\.tar\\.gz",
|
||||
"provide-pre-built": true,
|
||||
"license": {
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
@@ -36,7 +35,6 @@ The following is the source download configuration corresponding to the `libeven
|
||||
The most important field here is `type`. Currently, the types it supports are:
|
||||
|
||||
- `url`: Directly use URL to download, for example: `https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gz`.
|
||||
- `pie`: Download PHP extensions from Packagist using the PIE (PHP Installer for Extensions) standard.
|
||||
- `ghrel`: Use the GitHub Release API to download, download the artifacts uploaded from the latest version released by maintainers.
|
||||
- `ghtar`: Use the GitHub Release API to download.
|
||||
Different from `ghrel`, `ghtar` is downloaded from the `source code (tar.gz)` in the latest Release of the project.
|
||||
@@ -57,8 +55,6 @@ Each source file in source.json has the following params:
|
||||
- `license`: the open source license of the source code, see **Open Source License** section below
|
||||
- `type`: must be one of the types mentioned above
|
||||
- `path` (optional): release the source code to the specified directory instead of `source/{name}`
|
||||
- `provide-pre-built` (optional): whether to provide precompiled binary files.
|
||||
If `true`, it will automatically try to download precompiled binary files when running `bin/spc download`
|
||||
|
||||
::: tip
|
||||
The `path` parameter in `source.json` can specify a relative or absolute path. When specified as a relative path, the path is based on `source/`.
|
||||
@@ -90,37 +86,6 @@ Example (download the imagick extension and extract it to the extension storage
|
||||
}
|
||||
```
|
||||
|
||||
## Download type - pie
|
||||
|
||||
PIE (PHP Installer for Extensions) type sources refer to downloading PHP extensions from Packagist that follow the PIE standard.
|
||||
This method automatically fetches extension information from the Packagist repository and downloads the appropriate distribution file.
|
||||
|
||||
The parameters included are:
|
||||
|
||||
- `repo`: The Packagist vendor/package name, such as `vendor/package-name`
|
||||
|
||||
Example (download a PHP extension from Packagist using PIE):
|
||||
|
||||
```json
|
||||
{
|
||||
"ext-example": {
|
||||
"type": "pie",
|
||||
"repo": "vendor/example-extension",
|
||||
"path": "php-src/ext/example",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: tip
|
||||
The PIE download type will automatically detect the extension information from Packagist metadata,
|
||||
including the download URL, version, and distribution type.
|
||||
The extension must be marked as `type: php-ext` or contain `php-ext` metadata in its Packagist package definition.
|
||||
:::
|
||||
|
||||
## Download type - ghrel
|
||||
|
||||
ghrel will download files from Assets uploaded in GitHub Release.
|
||||
@@ -349,24 +314,3 @@ When an open source project has multiple licenses, multiple files can be specifi
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
When the license of an open source project uses different files between versions,
|
||||
`path` can be used as an array to list the possible license files:
|
||||
|
||||
```json
|
||||
{
|
||||
"redis": {
|
||||
"type": "git",
|
||||
"path": "php-src/ext/redis",
|
||||
"rev": "release/6.0.2",
|
||||
"url": "https://github.com/phpredis/phpredis",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": [
|
||||
"LICENSE",
|
||||
"COPYING"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -19,7 +19,7 @@ The project is mainly divided into several folders:
|
||||
|
||||
- `bin/`: used to store program entry files, including `bin/spc`, `bin/spc-alpine-docker`, `bin/setup-runtime`.
|
||||
- `config/`: Contains all the extensions and dependent libraries supported by the project,
|
||||
as well as the download link and download methods of these sources. It is divided into files: `lib.json`, `ext.json`, `source.json`, `pkg.json`, `pre-built.json` .
|
||||
as well as the download link and download methods of these sources. It is divided into files: `lib.json`, `ext.json`, `source.json`, `pkg.json` .
|
||||
- `src/`: The core code of the project, including the entire framework and commands for compiling various extensions and libraries.
|
||||
- `vendor/`: The directory that Composer depends on, you do not need to make any modifications to it.
|
||||
|
||||
|
||||
@@ -2,59 +2,35 @@
|
||||
|
||||
Here will be some questions that you may encounter easily. There are currently many, but I need to take time to organize them.
|
||||
|
||||
## What is the path of php.ini ?
|
||||
## Can statically compiled PHP install extensions?
|
||||
|
||||
On Linux, macOS and FreeBSD, the path of `php.ini` is `/usr/local/etc/php/php.ini`.
|
||||
On Windows, the path is `C:\windows\php.ini` or the current directory of `php.exe`.
|
||||
The directory where to look for `php.ini` can be changed on *nix using the manual build option `--with-config-file-path`.
|
||||
Because the principle of installing extensions in PHP under the traditional architecture is to install new extensions using `.so` type dynamic link libraries,
|
||||
and statically linked PHP compiled using this project cannot **directly** install new extensions using dynamic link libraries.
|
||||
|
||||
In addition, on Linux, macOS and FreeBSD, `.ini` files present in the `/usr/local/etc/php/conf.d` directory will also be loaded.
|
||||
On Windows, this path is empty by default.
|
||||
The directory can be changed using the manual build option `--with-config-file-scan-dir`.
|
||||
For the macOS platform, almost all binary files under macOS cannot be linked purely statically,
|
||||
and almost all binary files will link macOS system libraries: `/usr/lib/libresolv.9.dylib` and `/usr/lib/libSystem.B.dylib`.
|
||||
So under macOS system, statically compiled php binary files can be used under certain compilation conditions,
|
||||
and dynamic link extensions can be used at the same time:
|
||||
|
||||
`php.ini` will also be searched for in [the other standard locations](https://www.php.net/manual/configuration.file.php).
|
||||
|
||||
## Can statically-compiled PHP install extensions?
|
||||
|
||||
Because the principle of installing PHP extensions under the normal mode is to use `.so` type dynamic link library to install new extensions,
|
||||
and we use the static link PHP compiled by this project. However, static linking has different definitions in different operating systems.
|
||||
|
||||
First of all, for Linux systems, statically linked binaries will not link the system's dynamic link library.
|
||||
Purely statically linked binaries (`build with -all-static`) cannot load dynamic libraries, so new extensions cannot be added.
|
||||
At the same time, in pure static mode, you cannot use extensions such as `ffi` to load external `.so` modules.
|
||||
|
||||
You can use the command `ldd buildroot/bin/php` to check whether the binary you built under Linux is purely statically linked.
|
||||
|
||||
If you [build GNU libc based PHP](../guide/build-with-glibc), you can use the `ffi` extension to load external `.so` modules and load `.so` extensions with the same ABI.
|
||||
|
||||
For example, you can use the following command to build a static PHP binary dynamically linked with glibc,
|
||||
supporting FFI extensions and loading the `xdebug.so` extension of the same PHP version and the same TS type:
|
||||
1. Using the `--no-strip` parameter will not strip information such as debugging symbols from the binary file for use with external Zend extensions such as `Xdebug`.
|
||||
2. If you want to compile some Zend extensions, use Homebrew, MacPorts, source code compilation, and install a normal version of PHP on your operating system.
|
||||
3. Use the `phpize && ./configure && make` command to compile the extensions you want to use.
|
||||
4. Copy the extension file `xxxx.so` to the outside, use the statically compiled PHP binary, for example to use the Xdebug extension: `cd buildroot/bin/ && ./php -d "zend_extension=/path/to/xdebug.so"`.
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker download --for-extensions=ffi,xml --with-php=8.4
|
||||
bin/spc-gnu-docker build ffi,xml --build-cli --debug
|
||||
|
||||
buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" --ri xdebug
|
||||
# build statically linked php-cli but not stripped
|
||||
bin/spc build ffi --build-cli --no-strip
|
||||
```
|
||||
|
||||
For macOS platform, almost all binaries under macOS cannot be truly purely statically linked, and almost all binaries will link macOS system libraries: `/usr/lib/libresolv.9.dylib` and `/usr/lib/libSystem.B.dylib`.
|
||||
So on macOS, you can **directly** use SPC to build statically compiled PHP binaries with dynamically linked extensions:
|
||||
|
||||
1. Build shared extension `xxx.so` using: `--build-shared=XXX` option. e.g. `bin/spc build bcmath,zlib --build-shared=xdebug --build-cli`
|
||||
2. You will get `buildroot/modules/xdebug.so` and `buildroot/bin/php`.
|
||||
3. The `xdebug.so` file could be used for php that version and thread-safe are the same.
|
||||
|
||||
For the Windows platform, since officially built extensions (such as `php_yaml.dll`) force the use of the `php8.dll` dynamic library as a link, and statically built PHP does not include any dynamic libraries other than system libraries,
|
||||
php.exe built by static-php cannot load officially built dynamic extensions. Since static-php-cli does not yet support building dynamic extensions, there is currently no way to load dynamic extensions with static-php.
|
||||
|
||||
However, Windows can normally use the `FFI` extension to load other dll files and call them.
|
||||
For the Linux platform, the current compilation result is a purely statically linked binary file,
|
||||
and new extensions cannot be installed using a dynamic link library.
|
||||
|
||||
## Can it support Oracle database extension?
|
||||
|
||||
Some extensions that rely on closed source libraries, such as `oci8`, `sourceguardian`, etc.,
|
||||
they do not provide purely statically compiled dependent library files (`.a`), only dynamic dependent library files (`.so`).
|
||||
These extensions cannot be compiled into static-php-cli using source code, so this project may never support these extensions.
|
||||
However, in theory you can access and use such extensions under macOS and Linux according to the above questions.
|
||||
These extensions cannot be compiled into static-php-cli from source, so this project may never support them.
|
||||
However, in theory, you can access and use such extensions under macOS according to the above questions.
|
||||
|
||||
If you have a need for such extensions, or most people have needs for these closed-source extensions,
|
||||
see the discussion on [standalone-php-cli](https://github.com/crazywhalecc/static-php-cli/discussions/58). Welcome to leave a message.
|
||||
@@ -87,8 +63,6 @@ such as Swoole Compiler, Source Guardian, etc.
|
||||
|
||||
## Unable to use ssl
|
||||
|
||||
**Update: This issue has been fixed in the latest version of static-php-cli, which now reads the system's certificate file by default. If you still have problems, try the solution below.**
|
||||
|
||||
When using curl, pgsql, etc. to request an HTTPS website or establish an SSL connection, there may be an `error:80000002:system library::No such file or directory` error.
|
||||
This error is caused by statically compiled PHP without specifying `openssl.cafile` via `php.ini`.
|
||||
|
||||
@@ -98,11 +72,3 @@ For Linux systems, you can download the [cacert.pem](https://curl.se/docs/caextr
|
||||
For the certificate locations of different distros, please refer to [Golang docs](https://go.dev/src/crypto/x509/root_linux.go).
|
||||
|
||||
> INI configuration `openssl.cafile` cannot be set dynamically using the `ini_set()` function, because `openssl.cafile` is a `PHP_INI_SYSTEM` type configuration and can only be set in the `php.ini` file.
|
||||
|
||||
## Why don't we support older versions of PHP?
|
||||
|
||||
Because older versions of PHP have many problems, such as security issues, performance issues, and functional issues.
|
||||
In addition, many older versions of PHP are not compatible with the latest dependency libraries,
|
||||
which is one of the reasons why older versions of PHP are not supported.
|
||||
|
||||
You can use older versions compiled earlier by static-php-cli, such as PHP 8.0, but earlier versions will not be explicitly supported.
|
||||
|
||||
@@ -16,10 +16,8 @@ while also defining the extensions to compile.
|
||||
|
||||
1. Fork project.
|
||||
2. Go to the Actions of the project and select `CI`.
|
||||
3. Select `Run workflow`, fill in the PHP version you want to compile, the target type, and the list of static extensions. (comma separated, e.g. `bcmath,curl,mbstring`)
|
||||
4. If you need shared extensions (for example `xdebug`), set `shared-extensions` (comma separated, e.g. `xdebug`).
|
||||
5. If you need FrankenPHP, enable `build-frankenphp` and also enable `enable-zts`.
|
||||
6. After waiting for about a period of time, enter the corresponding task and get `Artifacts`.
|
||||
3. Select `Run workflow`, fill in the PHP version you want to compile, the target type, and the list of extensions. (extensions comma separated, e.g. `bcmath,curl,mbstring`)
|
||||
4. After waiting for about a period of time, enter the corresponding task and get `Artifacts`.
|
||||
|
||||
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
|
||||
|
||||
|
||||
@@ -74,12 +74,6 @@ bin/setup-runtime -action add-path
|
||||
bin/setup-runtime -action remove-path
|
||||
```
|
||||
|
||||
Finally, now that you have PHP and Composer installed, you need to install static-php-cli's Composer dependencies:
|
||||
|
||||
```shell
|
||||
composer install
|
||||
```
|
||||
|
||||
### Install other Tools (automatic)
|
||||
|
||||
For `php-sdk-binary-tools`, `strawberry-perl`, and `nasm`,
|
||||
@@ -165,8 +159,7 @@ You can try to use the following commands:
|
||||
|
||||
- `--with-clean`: clean up old make files before compiling PHP
|
||||
- `--enable-zts`: Make compiled PHP thread-safe version (default is NTS version)
|
||||
- `--with-libs=XXX,YYY`: Compile the specified dependent library before compiling PHP, and activate some extension optional functions
|
||||
- `--with-config-file-scan-dir=XXX`: Set the directory to scan for `.ini` files after reading `php.ini` (Check [here](../faq/index.html#what-is-the-path-of-php-ini) for default paths)
|
||||
- `--with-libs=XXX,YYY`: Compile the specified dependent library before compiling PHP, and activate some extension optional functions
|
||||
- `-I xxx=yyy`: Hard compile INI options into PHP before compiling (support multiple options, alias is `--with-hardcoded-ini`)
|
||||
- `--with-micro-fake-cli`: When compiling micro, let micro's `PHP_SAPI` pretend to be `cli` (for compatibility with some programs that check `PHP_SAPI`)
|
||||
- `--disable-opcache-jit`: Disable opcache jit (enabled by default)
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
# Build glibc Compatible Linux Binary
|
||||
|
||||
## Why Build glibc Compatible Binary
|
||||
|
||||
Currently, the binaries built by static-php-cli on Linux by default are based on musl-libc (statically linked).
|
||||
musl-libc is a lightweight libc implementation
|
||||
that aims to be compatible with glibc and provides good support for pure static linking.
|
||||
This means that the compiled static PHP executable can be used on almost any Linux distribution without worrying about the versions of libc, libstdc++, etc.
|
||||
|
||||
However, there are some issues with pure static linking of musl-libc binaries on Linux:
|
||||
|
||||
- The `dl()` function in PHP cannot be used to load dynamic libraries and external PHP extensions.
|
||||
- The FFI extension in PHP cannot be used.
|
||||
- In some extreme cases, performance issues may occur. See [musl-libc performance issues](https://github.com/php/php-src/issues/13648).
|
||||
|
||||
Different Linux distributions use different default libc.
|
||||
For example, Alpine Linux uses musl libc, while most Linux distributions use glibc.
|
||||
However, even so, we cannot directly use any distribution using glibc to build portable static binaries because glibc has some issues:
|
||||
|
||||
- Binaries built with gcc and other tools on newer versions of distributions cannot run on older versions of distributions.
|
||||
- glibc is not recommended to be statically linked because some of its features require the support of dynamic libraries.
|
||||
|
||||
However, we can use Docker to solve this problem.
|
||||
The final output is a binary **dynamically linked with glibc** and some necessary libraries,
|
||||
but **statically linked with all other dependencies**.
|
||||
|
||||
1. Use an older version of a Linux distribution (such as CentOS 7.x), which has an older version of glibc but can run on most modern Linux distributions.
|
||||
2. Build the static binary of PHP in this container so that it can run on most modern Linux distributions.
|
||||
|
||||
> Using glibc static binaries can run on most modern Linux distributions but cannot run on musl libc distributions, such as CentOS 6, Alpine Linux, etc.
|
||||
|
||||
## Build glibc Compatible Linux Binary
|
||||
|
||||
The latest version of static-php-cli includes the `bin/spc-gnu-docker` script,
|
||||
which can create a CentOS 7.x (glibc-2.17) Docker container with one click and build a glibc compatible PHP static binary in the container.
|
||||
|
||||
Then, run the following command once.
|
||||
The first run will take a long time because it needs to download the CentOS 7.x image and some build tools.
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker
|
||||
```
|
||||
|
||||
After the image is built, you will see the same command help menu as `bin/spc`, which means the container is ready.
|
||||
|
||||
After the container is ready, you can refer to the [local build](./manual-build) section to build your PHP static binary.
|
||||
Just replace `bin/spc` or `./spc` with `bin/spc-gnu-docker`.
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker build bcmath,ctype,openssl,pdo,phar,posix,session,tokenizer,xml,zip --build-cli --debug
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
In rare cases, glibc-based static PHP may encounter segment faults and other errors, but there are currently few examples.
|
||||
If you encounter any issues, please submit an issue.
|
||||
|
||||
glibc build is an extended feature and is not part of the default static-php support.
|
||||
If you have related issues or requirements, please indicate that you are building based on glibc when submitting an issue.
|
||||
|
||||
If you need to build glibc-based binaries without using Docker,
|
||||
please refer to the `bin/spc-gnu-docker` script to manually create a similar environment.
|
||||
|
||||
Please keep in mind that we only support glibc build with `bin/spc-gnu-docker`. Compilation on RHEL 9 & 10 has been tested and is stable, but if you run into issues, we may choose not to fix them.
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
<script setup lang="ts">
|
||||
import CliGenerator from "../../.vitepress/components/CliGenerator.vue";
|
||||
</script>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
outline: 'deep'
|
||||
---
|
||||
|
||||
# Dependency Table
|
||||
|
||||
When compiling PHP, each extension and library has dependencies, which may be required or optional.
|
||||
You can choose whether to include these optional dependencies.
|
||||
|
||||
For example, when compiling the `gd` extension under Linux,
|
||||
the `zlib,libpng` libraries and the `zlib` extension are forced to be compiled,
|
||||
while the `libavif,libwebp,libjpeg,freetype` libraries are optional libraries and will not be compiled by default
|
||||
unless specified by the `--with-libs=avif,webp,jpeg,freetype` option.
|
||||
|
||||
- For optional extensions (optional features of extensions), you need to specify them manually at compile time, for example, to enable igbinary support for Redis: `bin/spc build redis,igbinary`.
|
||||
- For optional libraries, you need to compile and specify them through the `--with-libs=XXX` option.
|
||||
- If you want to enable all optional extensions, you can use `bin/spc build redis --with-suggested-exts`.
|
||||
- If you want to enable all optional libraries, you can use `--with-suggested-libs`.
|
||||
|
||||
## Extension Dependency Table
|
||||
|
||||
<!--@include: ../../deps-map-ext.md-->
|
||||
|
||||
## Library Dependency Table
|
||||
|
||||
<!--@include: ../../deps-map-lib.md-->
|
||||
@@ -1,23 +1,12 @@
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
# Environment variables
|
||||
|
||||
All environment variables mentioned in the list on this page have default values unless otherwise noted.
|
||||
You can override the default values by setting these environment variables.
|
||||
|
||||
## Environment variables list
|
||||
|
||||
Starting from version 2.3.5, we have centralized the environment variables in the `config/env.ini` file.
|
||||
You can set environment variables by modifying this file.
|
||||
|
||||
We divide the environment variables supported by static-php-cli into three types:
|
||||
|
||||
- Global internal environment variables: declared after static-php-cli starts, you can use `getenv()` to get them internally in static-php-cli, and you can override them before starting static-php-cli.
|
||||
- Fixed environment variables: declared after static-php-cli starts, you can only use `getenv()` to get them, but you cannot override them through shell scripts.
|
||||
- Config file environment variables: declared before static-php-cli build, you can set these environment variables by modifying the `config/env.ini` file or through shell scripts.
|
||||
|
||||
You can read the comments for each parameter in [config/env.ini](https://github.com/crazywhalecc/static-php-cli/blob/main/config/env.ini) to understand its purpose.
|
||||
|
||||
## Custom environment variables
|
||||
|
||||
Generally, you don't need to modify any of the following environment variables as they are already set to optimal values.
|
||||
However, if you have special needs, you can set these environment variables to meet your needs
|
||||
(for example, you need to debug PHP performance under different compilation parameters).
|
||||
@@ -33,28 +22,91 @@ bin/spc build mbstring,pcntl --build-cli
|
||||
SPC_CONCURRENCY=4 bin/spc build mbstring,pcntl --build-cli
|
||||
```
|
||||
|
||||
Or, if you need to modify an environment variable for a long time, you can modify the `config/env.ini` file.
|
||||
## General environment variables
|
||||
|
||||
`config/env.ini` is divided into three sections, `[global]` is globally effective, `[windows]`, `[macos]`, `[linux]` are only effective for the corresponding operating system.
|
||||
General environment variables can be used by all build targets.
|
||||
|
||||
For example, if you need to modify the `./configure` command for compiling PHP, you can find the `SPC_CMD_PREFIX_PHP_CONFIGURE` environment variable in the `config/env.ini` file, and then modify its value.
|
||||
| var name | default value | comment |
|
||||
|------------------------------|---------------------------|-------------------------------------------------|
|
||||
| `BUILD_ROOT_PATH` | `{pwd}/buildroot` | The root directory of the build target |
|
||||
| `BUILD_LIB_PATH` | `{pwd}/buildroot/lib` | The root directory of compilation libraries |
|
||||
| `BUILD_INCLUDE_PATH` | `{pwd}/buildroot/include` | Header file directory for compiling libraries |
|
||||
| `BUILD_BIN_PATH` | `{pwd}/buildroot/bin` | Compiled binary file directory |
|
||||
| `PKG_ROOT_PATH` | `{pwd}/pkgroot` | Directory where precompiled tools are installed |
|
||||
| `SOURCE_PATH` | `{pwd}/source` | The source code extract directory |
|
||||
| `DOWNLOAD_PATH` | `{pwd}/downloads` | Downloaded file directory |
|
||||
| `SPC_CONCURRENCY` | Depends on CPU cores | Number of parallel compilations |
|
||||
| `SPC_SKIP_PHP_VERSION_CHECK` | empty | Skip PHP version check when set to `yes` |
|
||||
|
||||
If your build conditions are more complex and require multiple `env.ini` files to switch,
|
||||
we recommend that you use the `config/env.custom.ini` file.
|
||||
In this way, you can specify your environment variables by writing additional override items
|
||||
without modifying the default `config/env.ini` file.
|
||||
## OS specific variables
|
||||
|
||||
```ini
|
||||
; This is an example of `config/env.custom.ini` file,
|
||||
; we modify the `SPC_CONCURRENCY` and linux default CFLAGS passing to libs and PHP
|
||||
[global]
|
||||
SPC_CONCURRENCY=4
|
||||
These environment variables are system-specific and will only take effect on a specific OS.
|
||||
|
||||
[linux]
|
||||
SPC_DEFAULT_C_FLAGS="-O3"
|
||||
```
|
||||
### Windows
|
||||
|
||||
## Library environment variables (Unix only)
|
||||
| var name | default value | comment |
|
||||
|----------------|------------------------------|---------------------------|
|
||||
| `PHP_SDK_PATH` | `{pwd}\php-sdk-binary-tools` | PHP SDK tools path |
|
||||
| `UPX_EXEC` | `$PKG_ROOT_PATH\bin\upx.exe` | UPX compression tool path |
|
||||
|
||||
### macOS
|
||||
|
||||
| var name | default value | comment |
|
||||
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------|
|
||||
| `CC` | `clang` | C Compiler |
|
||||
| `CXX` | `clang++` | C++ Compiler |
|
||||
| `SPC_DEFAULT_C_FLAGS` | `--target=arm64-apple-darwin` or `--target=x86_64-apple-darwin` | Default C flags (not the same as `CFLAGS`) |
|
||||
| `SPC_DEFAULT_CXX_FLAGS` | `--target=arm64-apple-darwin` or `--target=x86_64-apple-darwin` | Default C flags (not the same as `CPPFLAGS`) |
|
||||
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | PHP `buildconf` command prefix |
|
||||
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | PHP `configure` command prefix |
|
||||
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | PHP `make` command prefix |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS -Werror=unknown-warning-option` | `CFLAGS` variable of PHP `configure` command |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | `CPPFLAGS` variable of PHP `configure` command |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | `LDFLAGS` variable of PHP `configure` command |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os` or `-g -O0` (the latter when using `--no-strip`) | `EXTRA_CFLAGS` variable of PHP `make` command |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | `-lresolv` | Extra `EXTRA_LIBS` variables for PHP `make` command |
|
||||
|
||||
### Linux
|
||||
|
||||
| var name | default value | comment |
|
||||
|----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------|
|
||||
| `UPX_EXEC` | `$PKG_ROOT_PATH/bin/upx` | UPX compression tool path |
|
||||
| `GNU_ARCH` | `x86_64` or `aarch64` | CPU architecture |
|
||||
| `CC` | Alpine: `gcc`, Other: `$GNU_ARCH-linux-musl-gcc` | C Compiler |
|
||||
| `CXX` | Alpine: `g++`, Other: `$GNU_ARCH-linux-musl-g++` | C++ Compiler |
|
||||
| `AR` | Alpine: `ar`, Other: `$GNU_ARCH-linux-musl-ar` | Static library tools |
|
||||
| `LD` | `ld.gold` | Linker |
|
||||
| `PATH` | `/usr/local/musl/bin:/usr/local/musl/$GNU_ARCH-linux-musl/bin:$PATH` | System PATH |
|
||||
| `SPC_DEFAULT_C_FLAGS` | empty | Default C flags |
|
||||
| `SPC_DEFAULT_CXX_FLAGS` | empty | Default C++ flags |
|
||||
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | PHP `buildconf` command prefix |
|
||||
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `LD_LIBRARY_PATH={ld_lib_path} ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | PHP `configure` command prefix |
|
||||
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | PHP `make` command prefix |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS` | `CFLAGS` variable of PHP `configure` command |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | `CPPFLAGS` variable of PHP `configure` command |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | `LDFLAGS` variable of PHP `configure` command |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_LIBS` | `-ldl -lpthread` | `LIBS` variable of PHP `configure` command |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os -fno-ident -fPIE` or `-g -O0 -fno-ident -fPIE` (the latter when using `--no-strip`) | `EXTRA_CFLAGS` variable of PHP `make` command |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | empty | Extra `EXTRA_LIBS` variables for PHP `make` command |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM` | `-all-static` (when using `clang`: `-Xcompiler -fuse-ld=lld -all-static`) | Additional `LDFLAGS` variable for `make` command |
|
||||
| `SPC_NO_MUSL_PATH` | empty | Whether to not insert the PATH of the musl toolchain (not inserted when the value is `yes`) |
|
||||
> `{ld_lib_path}` value is `/usr/local/musl/$GNU_ARCH-linux-musl/lib`。
|
||||
|
||||
### FreeBSD
|
||||
|
||||
Due to the small number of users of the FreeBSD system, we do not provide environment variables for the FreeBSD system for the time being.
|
||||
|
||||
### Unix
|
||||
|
||||
For Unix systems such as macOS, Linux, FreeBSD, etc., the following environment variables are common.
|
||||
|
||||
| var name | default value | comment |
|
||||
|-------------------|------------------------------|----------------------------|
|
||||
| `PATH` | `$BUILD_BIN_PATH:$PATH` | System PATH |
|
||||
| `PKG_CONFIG_PATH` | `$BUILD_LIB_PATH/pkgconfig` | pkg-config search path |
|
||||
| `PKG_CONFIG` | `$BUILD_BIN_PATH/pkg-config` | pkg-config executable path |
|
||||
|
||||
## Library Environment variables (Unix only)
|
||||
|
||||
Starting from 2.2.0, static-php-cli supports custom environment variables for all compilation dependent library commands of macOS, Linux, FreeBSD and other Unix systems.
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ which will be listed one by one here.
|
||||
|
||||
## curl
|
||||
|
||||
HTTP3 support is not enabled by default, compile with `--with-libs="nghttp2,nghttp3,ngtcp2"` to enable HTTP3 support for PHP >= 8.4.
|
||||
|
||||
When using curl to request HTTPS, there may be an `error:80000002:system library::No such file or directory` error.
|
||||
For details on the solution, see [FAQ - Unable to use ssl](../faq/#unable-to-use-ssl).
|
||||
|
||||
@@ -46,27 +44,15 @@ If you use `swoole,swoole-hook-sqlite`, you will enable the coroutine mode of Sw
|
||||
swoole-hook-sqlite conflicts with the `pdo_sqlite` extension. If you want to use Swoole and `pdo_sqlite`, please delete the pdo_sqlite extension and enable `swoole` and `swoole-hook-sqlite`.
|
||||
This extension contains an implementation of the coroutine environment for `pdo_sqlite`.
|
||||
|
||||
## swoole-hook-odbc
|
||||
|
||||
swoole-hook-odbc is not an extension, it's a Hook feature of Swoole.
|
||||
If you use `swoole,swoole-hook-odbc`, you will enable the coroutine mode of Swoole's `odbc` extension.
|
||||
|
||||
swoole-hook-odbc conflicts with the `pdo_odbc` extension. If you want to use Swoole and `pdo_odbc`, please delete the `pdo_odbc` extension and enable `swoole` and `swoole-hook-odbc`.
|
||||
This extension contains an implementation of the coroutine environment for `pdo_odbc`.
|
||||
|
||||
## swow
|
||||
|
||||
1. Only PHP 8.0+ is supported.
|
||||
|
||||
## imagick
|
||||
|
||||
1. OpenMP support is disabled, this is recommended by the maintainers and also the case system packages.
|
||||
1. Only PHP version >= 8.0 is supported.
|
||||
|
||||
## imap
|
||||
|
||||
1. Kerberos is not supported
|
||||
2. ext-imap is not thread safe due to the underlying c-client. It's not possible to use it in `--enable-zts` builds.
|
||||
3. The extension was dropped from php 8.4, we recommend you look for an alternative implementation, such as [Webklex/php-imap](https://github.com/Webklex/php-imap)
|
||||
2. ext-imap is not thread safe due to the underlying c-client. It's not possible to use it in --enable-zts builds.
|
||||
3. Because the extension may be dropped from php, we recommend you look for an alternative implementation, such as [Webklex/php-imap](https://github.com/Webklex/php-imap)
|
||||
|
||||
## gd
|
||||
|
||||
@@ -90,9 +76,11 @@ and this extension cannot be compiled into php by static linking, so it cannot b
|
||||
|
||||
## xdebug
|
||||
|
||||
1. Xdebug is only buildable as a shared extension. On Linux, you'll need to use a SPC_TARGET like `native-native -dynamic` or `native-native-gnu`.
|
||||
2. When using Linux/glibc or macOS, you can compile Xdebug as a shared extension using --build-shared="xdebug".
|
||||
The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`.
|
||||
1. Xdebug is a Zend extension. The functions of Xdebug depend on PHP's Zend engine and underlying code.
|
||||
If you want to statically compile it into PHP, you may need a huge amount of patch code, which is not feasible.
|
||||
2. The macOS platform can compile an xdebug extension under PHP compiled on the same platform,
|
||||
extract the `xdebug.so` file, and then use the `--no-strip` parameter in static-php-cli to retain the debug symbol table and add the `ffi` extension.
|
||||
The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`.
|
||||
|
||||
## xml
|
||||
|
||||
@@ -130,13 +118,13 @@ For details on the solution, see [FAQ - Unable to use ssl](../faq/#unable-to-use
|
||||
|
||||
## password-argon2
|
||||
|
||||
1. password-argon2 is not a standard extension. The algorithm `PASSWORD_ARGON2ID` for the `password_hash` function needs libsodium or libargon2 to work.
|
||||
2. using password-argon2 enables multithread support for this.
|
||||
1. password-argon2 is not a standard extension, it is an additional algorithm for the `password_hash` function.
|
||||
2. On Linux systems, `password-argon2` dependency `libargon2` conflicts with the `libsodium` library.
|
||||
|
||||
## ffi
|
||||
|
||||
1. Due to the limitation of musl libc's static linkage, you cannot use ffi because dynamic libraries cannot be loaded.
|
||||
If you need to use the ffi extension, see [Compile PHP with GNU libc](./build-with-glibc).
|
||||
1. Linux not supported yet: Due to limitations of the Linux system, although the ffi extension can be compiled successfully, it cannot be used to load other `so` extensions.
|
||||
The prerequisite for Linux to support loading `so` extensions is dynamic compilation, but dynamic compilation conflicts with the purpose of this project.
|
||||
2. macOS supports the ffi extension, but errors will occur when some kernels do not contain debugging symbols.
|
||||
3. Windows x64 supports the ffi extension.
|
||||
|
||||
@@ -159,10 +147,5 @@ Parallel is only supported on PHP 8.0 ZTS and above.
|
||||
|
||||
## spx
|
||||
|
||||
1. SPX does not support Windows, and the official repository does not support static compilation. static-php-cli uses a [modified version](https://github.com/static-php/php-spx).
|
||||
|
||||
## mimalloc
|
||||
|
||||
1. This is not technically an extension, but a library.
|
||||
2. Building with `--with-libs="mimalloc"` on Linux or macOS will override the default allocator.
|
||||
3. This is experimental for now, but is recommended in threaded environments.
|
||||
1. The [SPX extension](https://github.com/NoiseByNorthwest/php-spx) only supports NTS mode.
|
||||
2. SPX does not support Windows, and the official repository does not support static compilation. static-php-cli uses a [modified version](https://github.com/static-php/php-spx).
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
<script setup>
|
||||
import SearchTable from "../../.vitepress/components/SearchTable.vue";
|
||||
</script>
|
||||
|
||||
# Extensions
|
||||
|
||||
> - `yes`: supported
|
||||
@@ -9,7 +5,7 @@ import SearchTable from "../../.vitepress/components/SearchTable.vue";
|
||||
> - `no` with issue link: confirmed to be unavailable due to issue
|
||||
> - `partial` with issue link: supported but not perfect due to issue
|
||||
|
||||
<search-table />
|
||||
<!--@include: ../../extensions.md-->
|
||||
|
||||
::: tip
|
||||
If an extension you need is missing, you can create a [Feature Request](https://github.com/crazywhalecc/static-php-cli/issues).
|
||||
@@ -18,6 +14,14 @@ Some extensions or libraries that the extension depends on will have some option
|
||||
For example, the gd library optionally supports libwebp, freetype, etc.
|
||||
If you only use `bin/spc build gd --build-cli` they will not be included (static-php-cli defaults to the minimum dependency principle).
|
||||
|
||||
For more information about optional libraries, see [Extensions, Library Dependency Map](./deps-map).
|
||||
For optional libraries, you can also select an extension from the [Command Generator](./cli-generator) and then select optional libraries.
|
||||
You can use `--with-libs=` to add these libraries when compiling.
|
||||
When the dependent libraries of this compilation include them, gd will automatically use them to enable these features.
|
||||
(For example: `bin/spc build gd --with-libs=libwebp,freetype --build-cli`)
|
||||
|
||||
Alternatively you can use `--with-suggested-exts` and `--with-suggested-libs` to enable all optional dependencies of these extensions and libraries.
|
||||
(For example: `bin/spc build gd --with-suggested-libs --build-cli`)
|
||||
|
||||
If you don't know whether an extension has optional features,
|
||||
you can check the [spc configuration file](https://github.com/crazywhalecc/static-php-cli/tree/main/config)
|
||||
or use the command `bin/spc dev:extensions` (library dependency is `lib-suggests`, extension dependency is `ext-suggests`).
|
||||
:::
|
||||
|
||||
@@ -5,10 +5,14 @@ currently supporting Linux and macOS systems.
|
||||
|
||||
In the guide section, you will learn how to use static php cli to build standalone PHP programs.
|
||||
|
||||
- [Build (local)](./manual-build)
|
||||
- [Build (GitHub Actions)](./action-build)
|
||||
- [GitHub Action Build](./action-build)
|
||||
- [Manual Build](./manual-build)
|
||||
- [Supported Extensions](./extensions)
|
||||
|
||||
::: tip
|
||||
If you are a native English speaker, some corrections to the documentation are welcome.
|
||||
:::
|
||||
|
||||
## Compilation Environment
|
||||
|
||||
The following is the architecture support situation, where :gear: represents support for GitHub Action build,
|
||||
@@ -21,30 +25,19 @@ The following is the architecture support situation, where :gear: represents sup
|
||||
| Windows | :gear: :computer: | |
|
||||
| FreeBSD | :computer: | :computer: |
|
||||
|
||||
Current supported PHP versions for compilation:
|
||||
Among them, Linux is currently only tested on Ubuntu, Debian, and Alpine distributions,
|
||||
and other distributions have not been tested, which cannot guarantee successful compilation.
|
||||
For untested distributions, local compilation can be done using methods such as Docker to avoid environmental issues.
|
||||
|
||||
> :warning: Partial support, there may be issues with new beta versions and old versions.
|
||||
>
|
||||
> :heavy_check_mark: Supported
|
||||
>
|
||||
> :x: Not supported
|
||||
There are two architectures for macOS: `x86_64` and `Arm`, but binaries compiled on one architecture cannot be directly used on the other architecture.
|
||||
Rosetta 2 cannot guarantee that programs compiled with `Arm` architecture can fully run on `x86_64` environment.
|
||||
|
||||
| PHP Version | Status | Comment |
|
||||
|-------------|--------------------|-------------------------------------------------------------------------------------------------------------------------|
|
||||
| 7.2 | :x: | |
|
||||
| 7.3 | :x: | phpmicro and many extensions do not support 7.3, 7.4 versions |
|
||||
| 7.4 | :x: | phpmicro and many extensions do not support 7.3, 7.4 versions |
|
||||
| 8.0 | :warning: | PHP official has stopped maintaining 8.0, we no longer handle 8.0 related backport support |
|
||||
| 8.1 | :warning: | PHP official only provides security updates for 8.1, we no longer handle 8.1 related backport support after 8.5 release |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
| 8.4 | :heavy_check_mark: | |
|
||||
| 8.5 (beta) | :warning: | PHP 8.5 is currently in beta stage |
|
||||
Windows currently only supports the x86_64 architecture, and does not support 32-bit x86 or arm64 architecture.
|
||||
|
||||
> This table shows the support status of static-php-cli for building corresponding versions, not the PHP official support status for that version.
|
||||
## Supported PHP Version
|
||||
|
||||
## PHP Support Versions
|
||||
|
||||
Currently, static-php-cli supports PHP versions 8.2 ~ 8.5, and theoretically supports PHP 8.1 and earlier versions, just select the earlier version when downloading.
|
||||
However, due to some extensions and special components that have stopped supporting earlier versions of PHP, static-php-cli will not explicitly support earlier versions.
|
||||
Currently, static php cli supports PHP versions 8.0 to 8.3, and theoretically supports PHP 7.4 and earlier versions.
|
||||
Simply select the earlier version when downloading.
|
||||
However, due to some extensions and special components that have stopped supporting earlier versions of PHP,
|
||||
static-php-cli will not explicitly support earlier versions.
|
||||
We recommend that you compile the latest PHP version possible for a better experience.
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
outline: 'deep'
|
||||
---
|
||||
|
||||
# Build (Linux, macOS, FreeBSD)
|
||||
|
||||
This section covers the build process for Linux, macOS, and FreeBSD. If you want to build on Windows,
|
||||
@@ -18,15 +14,15 @@ Here's how to download from self-hosted server:
|
||||
```bash
|
||||
# Download from self-hosted nightly builds (sync with main branch)
|
||||
# For Linux x86_64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-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 -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
# macOS x86_64 (Intel)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
# macOS aarch64 (Apple)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
|
||||
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 -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
|
||||
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
|
||||
@@ -61,6 +57,56 @@ cd static-php-cli
|
||||
composer update
|
||||
```
|
||||
|
||||
### Use System PHP
|
||||
|
||||
Below are some example commands for installing PHP and Composer in the system.
|
||||
It is recommended to search for the specific installation method yourself or ask the AI search engine to obtain the answer,
|
||||
which will not be elaborated here.
|
||||
|
||||
```bash
|
||||
# [macOS], need install Homebrew first. See https://brew.sh/
|
||||
# Remember change your composer executable path. For M1/M2 Chip mac, "/opt/homebrew/bin/", for Intel mac, "/usr/local/bin/". Or add it to your own path.
|
||||
brew install php wget
|
||||
wget https://getcomposer.org/download/latest-stable/composer.phar -O /path/to/your/bin/composer && chmod +x /path/to/your/bin/composer
|
||||
|
||||
# [Debian], you need to make sure your php version >= 8.1 and composer >= 2.0
|
||||
sudo apt install php-cli composer php-tokenizer
|
||||
|
||||
# [Alpine]
|
||||
apk add bash file wget xz php81 php81-common php81-pcntl php81-tokenizer php81-phar php81-posix php81-xml composer
|
||||
```
|
||||
|
||||
::: tip
|
||||
Currently, some versions of Ubuntu install older PHP versions,
|
||||
so no installation commands are provided. If necessary, it is recommended to add software sources such as ppa first,
|
||||
and then install the latest version of PHP and tokenizer, XML, and phar extensions.
|
||||
|
||||
Older versions of Debian may have an older (<= 7.4) version of PHP installed by default, it is recommended to upgrade Debian first.
|
||||
:::
|
||||
|
||||
### Use Docker
|
||||
|
||||
If you don't want to install PHP and Composer runtime environment on your system, you can use the built-in Docker environment build script.
|
||||
|
||||
```bash
|
||||
# To use directly, replace `bin/spc` with `bin/spc-alpine-docker` in all used commands
|
||||
bin/spc-alpine-docker
|
||||
```
|
||||
|
||||
The first time the command is executed, `docker build` will be used to build a Docker image.
|
||||
The default built Docker image is the `x86_64` architecture, and the image name is `cwcc-spc-x86_64`.
|
||||
|
||||
If you want to build `aarch64` static-php-cli in `x86_64` environment,
|
||||
you can use qemu to emulate the arm image to run Docker, but the speed will be very slow.
|
||||
Use command: `SPC_USE_ARCH=aarch64 bin/spc-alpine-docker`.
|
||||
|
||||
If it prompts that sudo is required to run after running,
|
||||
execute the following command once to grant static-php-cli permission to execute sudo:
|
||||
|
||||
```bash
|
||||
export SPC_USE_SUDO=yes
|
||||
```
|
||||
|
||||
### Use Precompiled Static PHP Binaries
|
||||
|
||||
If you don't want to use Docker and install PHP in the system,
|
||||
@@ -87,109 +133,17 @@ This script will download two files in total: `bin/php` and `bin/composer`. Afte
|
||||
it is equivalent to installing PHP in the system, you can directly Use commands such as `composer`, `php -v`, or directly use `bin/spc`.
|
||||
2. Direct call, such as executing static-php-cli command: `bin/php bin/spc --help`, executing Composer: `bin/php bin/composer update`.
|
||||
|
||||
### Use Docker
|
||||
|
||||
If you don't want to install PHP and Composer runtime environment on your system, you can use the built-in Docker environment build script.
|
||||
|
||||
```bash
|
||||
# To use directly, replace `bin/spc` with `bin/spc-alpine-docker` in all used commands
|
||||
bin/spc-alpine-docker
|
||||
```
|
||||
|
||||
The first time the command is executed, `docker build` will be used to build a Docker image.
|
||||
The default built Docker image is the `x86_64` architecture, and the image name is `cwcc-spc-x86_64`.
|
||||
|
||||
If you want to build `aarch64` static-php-cli in `x86_64` environment,
|
||||
you can use qemu to emulate the arm image to run Docker, but the speed will be very slow.
|
||||
Use command: `SPC_USE_ARCH=aarch64 bin/spc-alpine-docker`.
|
||||
|
||||
If it prompts that sudo is required to run after running,
|
||||
execute the following command once to grant static-php-cli permission to execute sudo:
|
||||
|
||||
```bash
|
||||
export SPC_USE_SUDO=yes
|
||||
```
|
||||
|
||||
### Use System PHP
|
||||
|
||||
Below are some example commands for installing PHP and Composer in the system.
|
||||
It is recommended to search for the specific installation method yourself or ask the AI search engine to obtain the answer,
|
||||
which will not be elaborated here.
|
||||
|
||||
```bash
|
||||
# [macOS], need install Homebrew first. See https://brew.sh/
|
||||
# Remember change your composer executable path. For M1/M2 Chip mac, "/opt/homebrew/bin/", for Intel mac, "/usr/local/bin/". Or add it to your own path.
|
||||
brew install php wget
|
||||
wget https://getcomposer.org/download/latest-stable/composer.phar -O /path/to/your/bin/composer && chmod +x /path/to/your/bin/composer
|
||||
|
||||
# [Debian], you need to make sure your php version >= 8.1 and composer >= 2.0
|
||||
sudo apt install php-cli composer php-tokenizer
|
||||
|
||||
# [Alpine]
|
||||
apk add bash file wget xz php81 php81-common php81-pcntl php81-tokenizer php81-phar php81-posix php81-xml composer
|
||||
```
|
||||
|
||||
::: tip
|
||||
Currently, some versions of Ubuntu install older PHP versions,
|
||||
so no installation commands are provided. If necessary, it is recommended to add software sources such as ppa first,
|
||||
and then install the latest version of PHP and tokenizer, XML, and phar extensions.
|
||||
|
||||
Older versions of Debian may have an older (<= 7.4) version of PHP installed by default, it is recommended to upgrade Debian first.
|
||||
:::
|
||||
|
||||
## Build with craft (recommended)
|
||||
|
||||
Using `bin/spc craft`, you can use a configuration file and a command to automatically check the environment, download source code, build dependency libraries, build PHP and extensions, etc.
|
||||
|
||||
You need to write a `craft.yml` file and save it in the current working directory. `craft.yml` can be generated by [command generator](./cli-generator) or written manually.
|
||||
|
||||
For manual writing, please refer to the comments in [craft.yml configuration](../develop/craft-yml.md) to write it.
|
||||
Let's assume that you compile an extension combination and choose PHP 8.4, outputting `cli` and `fpm`:
|
||||
|
||||
```yaml
|
||||
# path/to/craft.yml
|
||||
php-version: 8.4
|
||||
extensions: bcmath,posix,phar,zlib,openssl,curl,fileinfo,tokenizer
|
||||
sapi:
|
||||
- cli
|
||||
- fpm
|
||||
```
|
||||
|
||||
Then use the `bin/spc craft` command to compile:
|
||||
|
||||
```bash
|
||||
bin/spc craft --debug
|
||||
```
|
||||
|
||||
If the build is successful, you will see the `buildroot/bin` directory in the current directory, which contains the compiled PHP binary file, or the corresponding SAPI.
|
||||
|
||||
- cli: The build result is `buildroot/bin/php.exe` on Windows and `buildroot/bin/php` on other platforms.
|
||||
- fpm: The build result is `buildroot/bin/php-fpm`.
|
||||
- micro: The build result is `buildroot/bin/micro.sfx`. If you need to further package it with PHP code, please refer to [Packaging micro binary](./manual-build#command-micro-combine).
|
||||
- embed: See [Using embed](./manual-build#embed-usage).
|
||||
- frankenphp: The build result is `buildroot/bin/frankenphp`.
|
||||
|
||||
If the build fails, you can use the `--debug` parameter to view detailed error information,
|
||||
or use the `--with-clean` to clear the old compilation results and recompile.
|
||||
|
||||
If the build still fails to use the above method, please submit an issue and attach your `craft.yml` and `./log` archive.
|
||||
|
||||
## Step-by-step build command
|
||||
|
||||
If you have customized requirements, or the need to download and compile PHP and dependent libraries separately, you can use the `bin/spc` command to execute step by step.
|
||||
|
||||
### Command download - Download dependency packages
|
||||
## Command - download
|
||||
|
||||
Use the command `bin/spc download` to download the source code required for compilation,
|
||||
including php-src and the source code of various dependent libraries.
|
||||
|
||||
```bash
|
||||
# Download all dependencies, defaults to php 8.4
|
||||
# Download all dependencies
|
||||
bin/spc download --all
|
||||
|
||||
# Download all dependent packages, and specify the main version of PHP to download, optional: 8.1, 8.2, 8.3, 8.4
|
||||
# Also supports specific version of php release: 8.3.10, 8.2.22, etc.
|
||||
bin/spc download --all --with-php=8.3
|
||||
# Download all dependent packages, and specify the main version of PHP to download, optional: 7.3, 7.4, 8.0, 8.1, 8.2, 8.3
|
||||
bin/spc download --all --with-php=8.2
|
||||
|
||||
# Show download progress bar while downloading (curl)
|
||||
bin/spc download --all --debug
|
||||
@@ -203,9 +157,6 @@ bin/spc download php-src,micro,zstd,ext-zstd
|
||||
# Download only extensions and libraries to be compiled (use extensions, including suggested libraries)
|
||||
bin/spc download --for-extensions=openssl,swoole,zip,pcntl,zstd
|
||||
|
||||
# Download resources, prefer to download dependencies with pre-built packages (reduce the time to compile dependencies)
|
||||
bin/spc download --for-extensions="curl,pcntl,xml,mbstring" --prefer-pre-built
|
||||
|
||||
# Download only the extensions and dependent libraries to be compiled (use extensions, excluding suggested libraries)
|
||||
bin/spc download --for-extensions=openssl,swoole,zip,pcntl --without-suggestions
|
||||
|
||||
@@ -216,7 +167,7 @@ bin/spc download --for-libs=liblz4,libevent --for-extensions=pcntl,rar,xml
|
||||
bin/spc download --for-libs=liblz4,libevent --without-suggestions
|
||||
|
||||
# When downloading sources, ignore some source caches (always force download, e.g. switching PHP version)
|
||||
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3.10
|
||||
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3
|
||||
|
||||
# Set retry times (default is 0)
|
||||
bin/spc download --all --retry=2
|
||||
@@ -242,27 +193,14 @@ Also, it is available when downloading with the `--for-extensions` option.
|
||||
|
||||
|
||||
```bash
|
||||
# Specifying to download a alpha version of PHP 8.5
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz"
|
||||
# Specifying to download a beta version of PHP8.3
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"
|
||||
|
||||
# Specifying to download an older version of the curl library
|
||||
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
|
||||
```
|
||||
|
||||
If the source you download is not a link, but a git repository, you can use `-G` or `--custom-git` to rewrite the download link,
|
||||
so that the downloader can force the use of the specified git repository to download packages from this source.
|
||||
The usage method is `{source-name}:{branch}:{url}`, which can rewrite the download link of multiple libraries at the same time.
|
||||
It is also available when downloading with the `--for-extensions` option.
|
||||
|
||||
```bash
|
||||
# Specifying to download the source code of the PHP extension from the specified branch of the git repository
|
||||
bin/spc download --for-extensions=redis -G "php-src:master:https://github.com/php/php-src.git"
|
||||
|
||||
# Download the latest code from the master branch of the swoole-src repository instead of PECL release version
|
||||
bin/spc download --for-extensions=swoole -G "swoole:master:https://github.com/swoole/swoole-src.git"
|
||||
```
|
||||
|
||||
### Command - doctor
|
||||
## Command - doctor
|
||||
|
||||
If you can run `bin/spc` normally but cannot compile static PHP or dependent libraries normally,
|
||||
you can run `bin/spc doctor` first to check whether the system itself lacks dependencies.
|
||||
@@ -275,13 +213,13 @@ bin/spc doctor
|
||||
bin/spc doctor --auto-fix
|
||||
```
|
||||
|
||||
### Command - build
|
||||
## Command - build
|
||||
|
||||
Use the build command to start building the static php binary.
|
||||
Before executing the `bin/spc build` command, be sure to use the `download` command to download sources.
|
||||
It is recommended to use `doctor` to check the environment.
|
||||
|
||||
#### Basic build
|
||||
### Basic build
|
||||
|
||||
You need to go to [Extension List](./extensions) or [Command Generator](./cli-generator) to select the extension you want to add,
|
||||
and then use the command `bin/spc build` to compile.
|
||||
@@ -289,10 +227,8 @@ You need to specify a compilation target, choose from the following parameters:
|
||||
|
||||
- `--build-cli`: Build a cli sapi (command line interface, which can execute PHP code on the command line)
|
||||
- `--build-fpm`: Build a fpm sapi (php-fpm, used in conjunction with other traditional fpm architecture software such as nginx)
|
||||
- `--build-cgi`: Build a cgi sapi (cgi, rarely used)
|
||||
- `--build-micro`: Build a micro sapi (used to build a standalone executable binary containing PHP code)
|
||||
- `--build-embed`: Build an embed sapi (used to embed into other C language programs)
|
||||
- `--build-frankenphp`: Build a [FrankenPHP](https://github.com/php/frankenphp) executable
|
||||
- `--build-all`: build all above sapi
|
||||
|
||||
```bash
|
||||
@@ -319,18 +255,27 @@ If you want to build multiple versions of PHP and don't want to build other depe
|
||||
you can use `switch-php-version` to quickly switch to another version and compile after compiling one version:
|
||||
|
||||
```shell
|
||||
# switch to 8.4
|
||||
bin/spc switch-php-version 8.4
|
||||
# switch to 8.3
|
||||
bin/spc switch-php-version 8.3
|
||||
# build
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
# switch to 8.1
|
||||
bin/spc switch-php-version 8.1
|
||||
# switch to 8.0
|
||||
bin/spc switch-php-version 8.0
|
||||
# build
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
```
|
||||
:::
|
||||
|
||||
#### Build Options
|
||||
### Debug
|
||||
|
||||
If you encounter problems during the compilation process, or want to view each executing shell command,
|
||||
you can use `--debug` to enable debug mode and view all terminal logs:
|
||||
|
||||
```bash
|
||||
bin/spc build mysqlnd,pdo_mysql --build-all --debug
|
||||
```
|
||||
|
||||
### Build Options
|
||||
|
||||
During the compilation process, in some special cases,
|
||||
the compiler and the content of the compilation directory need to be intervened.
|
||||
@@ -340,10 +285,8 @@ You can try to use the following commands:
|
||||
- `--cxx=XXX`: Specifies the execution command of the C++ language compiler (Linux defaults to `g++`, macOS defaults to `clang++`)
|
||||
- `--with-clean`: clean up old make files before compiling PHP
|
||||
- `--enable-zts`: Make compiled PHP thread-safe version (default is NTS version)
|
||||
- `--no-strip`: Do not run `strip` after compiling the PHP library to trim the binary file to reduce its size
|
||||
- `--no-strip`: Do not run `strip` after compiling the PHP library to trim the binary file to reduce its size (the macOS binary file without trim can use dynamically linked third-party extensions)
|
||||
- `--with-libs=XXX,YYY`: Compile the specified dependent library before compiling PHP, and activate some extended optional functions (such as libavif of the gd library, etc.)
|
||||
- `--with-config-file-path=XXX`: Set the path in which to look for `php.ini` (Check [here](../faq/index.html#what-is-the-path-of-php-ini) for default paths)
|
||||
- `--with-config-file-scan-dir=XXX`: Set the directory to scan for `.ini` files after reading `php.ini` (Check [here](../faq/index.html#what-is-the-path-of-php-ini) for default paths)
|
||||
- `-I xxx=yyy`: Hard compile INI options into PHP before compiling (support multiple options, alias is `--with-hardcoded-ini`)
|
||||
- `--with-micro-fake-cli`: When compiling micro, let micro's `PHP_SAPI` pretend to be `cli` (for compatibility with some programs that check `PHP_SAPI`)
|
||||
- `--disable-opcache-jit`: Disable opcache jit (enabled by default)
|
||||
@@ -352,7 +295,6 @@ You can try to use the following commands:
|
||||
- `--with-suggested-exts`: Add `ext-suggests` as dependencies when compiling
|
||||
- `--with-suggested-libs`: Add `lib-suggests` as dependencies when compiling
|
||||
- `--with-upx-pack`: Use UPX to reduce the size of the binary file after compilation (you need to use `bin/spc install-pkg upx` to install upx first)
|
||||
- `--build-shared=XXX,YYY`: compile the specified extension into a shared library (the default is to compile into a static library)
|
||||
|
||||
For hardcoding INI options, it works for cli, micro, embed sapi. Here is a simple example where we preset a larger `memory_limit` and disable the `system` function:
|
||||
|
||||
@@ -360,15 +302,6 @@ For hardcoding INI options, it works for cli, micro, embed sapi. Here is a simpl
|
||||
bin/spc build bcmath,pcntl,posix --build-all -I "memory_limit=4G" -I "disable_functions=system"
|
||||
```
|
||||
|
||||
## Debug
|
||||
|
||||
If you encounter problems during the compilation process, or want to view each executing shell command,
|
||||
you can use `--debug` to enable debug mode and view all terminal logs:
|
||||
|
||||
```bash
|
||||
bin/spc build mysqlnd,pdo_mysql --build-all --debug
|
||||
```
|
||||
|
||||
## Command - micro:combine
|
||||
|
||||
Use the `micro:combine` command to build the compiled `micro.sfx` and your code (`.php` or `.phar` file) into an executable binary.
|
||||
@@ -445,31 +378,6 @@ manually unpack and copy the package to a specified location, and we can use com
|
||||
bin/spc extract php-src,libxml2
|
||||
```
|
||||
|
||||
## Command - dump-extensions
|
||||
|
||||
Use the command `bin/spc dump-extensions` to export required extensions of the current project.
|
||||
|
||||
```bash
|
||||
# Print the extension list of the project, pass in the root directory of the project containing composer.json
|
||||
bin/spc dump-extensions /path/to/your/project/
|
||||
|
||||
# Print the extension list of the project, excluding development dependencies
|
||||
bin/spc dump-extensions /path-to/tour/project/ --no-dev
|
||||
|
||||
# Output in the extension list format acceptable to the spc command (comma separated)
|
||||
bin/spc dump-extensions /path-to/tour/project/ --format=text
|
||||
|
||||
# Output as a JSON list
|
||||
bin/spc dump-extensions /path-to/tour/project/ --format=json
|
||||
|
||||
# When the project does not have any extensions, output the specified extension combination instead of returning failure
|
||||
bin/spc dump-extensions /path-to/your/project/ --no-ext-output=mbstring,posix,pcntl,phar
|
||||
|
||||
# Do not exclude extensions not supported by spc when outputting
|
||||
bin/spc dump-extensions /path/to/your/project/ --no-spc-filter
|
||||
```
|
||||
It should be noted that the project directory must contain the `vendor/installed.json` and `composer.lock` files, otherwise they cannot be found normally.
|
||||
|
||||
## Dev Command - dev
|
||||
|
||||
Debug commands refer to a collection of commands that can assist in outputting some information
|
||||
@@ -480,8 +388,6 @@ when you use static-php-cli to build PHP or modify and enhance the static-php-cl
|
||||
- `dev:sort-config`: Sort the list of configuration files in the `config/` directory in alphabetical order
|
||||
- `dev:lib-ver <lib-name>`: Read the version from the source code of the dependency library (only available for specific dependency libraries)
|
||||
- `dev:ext-ver <ext-name>`: Read the corresponding version from the source code of the extension (only available for specific extensions)
|
||||
- `dev:pack-lib <lib-name>`: Package the specified library into a tar.gz file (maintainer only)
|
||||
- `dev:gen-ext-docs`: Generate extension documentation (maintainer only)
|
||||
|
||||
```bash
|
||||
# output all extensions information
|
||||
@@ -512,8 +418,6 @@ When `bin/spc doctor` automatically repairs the Windows environment, tools such
|
||||
Here is an example of installing the tool:
|
||||
|
||||
- Download and install UPX (Linux and Windows only): `bin/spc install-pkg upx`
|
||||
- Download and install nasm (Windows only): `bin/spc install-pkg nasm`
|
||||
- Download and install go-xcaddy: `bin/spc install-pkg go-xcaddy`
|
||||
|
||||
## Command - del-download
|
||||
|
||||
@@ -549,24 +453,22 @@ otherwise it will be executed repeatedly in other events.
|
||||
|
||||
The following are the supported `patch_point` event names and corresponding locations:
|
||||
|
||||
| Event name | Event description |
|
||||
|---------------------------------|----------------------------------------------------------------------------------------------------|
|
||||
| before-libs-extract | Triggered before the dependent libraries extracted |
|
||||
| after-libs-extract | Triggered after the compiled dependent libraries extracted |
|
||||
| before-php-extract | Triggered before PHP source code extracted |
|
||||
| after-php-extract | Triggered after PHP source code extracted |
|
||||
| before-micro-extract | Triggered before phpmicro extract |
|
||||
| after-micro-extract | Triggered after phpmicro extracted |
|
||||
| before-exts-extract | Triggered before the extension (to be compiled) extracted to the PHP source directory |
|
||||
| after-exts-extract | Triggered after the extension extracted to the PHP source directory |
|
||||
| before-library[*name*]-build | Triggered before the library named `name` is compiled (such as `before-library[postgresql]-build`) |
|
||||
| after-library[*name*]-build | Triggered after the library named `name` is compiled |
|
||||
| after-shared-ext[*name*]-build | Triggered after the shared extension named `name` is compiled |
|
||||
| before-shared-ext[*name*]-build | Triggered before the shared extension named `name` is compiled |
|
||||
| before-php-buildconf | Triggered before compiling PHP command `./buildconf` |
|
||||
| before-php-configure | Triggered before compiling PHP command `./configure` |
|
||||
| before-php-make | Triggered before compiling PHP command `make` |
|
||||
| before-sanity-check | Triggered after compiling PHP but before running extended checks |
|
||||
| Event name | Event description |
|
||||
|------------------------------|----------------------------------------------------------------------------------------------------|
|
||||
| before-libs-extract | Triggered before the dependent libraries extracted |
|
||||
| after-libs-extract | Triggered after the compiled dependent libraries extracted |
|
||||
| before-php-extract | Triggered before PHP source code extracted |
|
||||
| after-php-extract | Triggered after PHP source code extracted |
|
||||
| before-micro-extract | Triggered before phpmicro extract |
|
||||
| after-micro-extract | Triggered after phpmicro extracted |
|
||||
| before-exts-extract | Triggered before the extension (to be compiled) extracted to the PHP source directory |
|
||||
| after-exts-extract | Triggered after the extension extracted to the PHP source directory |
|
||||
| before-library[*name*]-build | Triggered before the library named `name` is compiled (such as `before-library[postgresql]-build`) |
|
||||
| after-library[*name*]-build | Triggered after the library named `name` is compiled |
|
||||
| before-php-buildconf | Triggered before compiling PHP command `./buildconf` |
|
||||
| before-php-configure | Triggered before compiling PHP command `./configure` |
|
||||
| before-php-make | Triggered before compiling PHP command `make` |
|
||||
| before-sanity-check | Triggered after compiling PHP but before running extended checks |
|
||||
|
||||
The following is a simple example of temporarily modifying the PHP source code.
|
||||
Enable the CLI function to search for the `php.ini` configuration in the current working directory:
|
||||
@@ -621,85 +523,3 @@ Commonly used objects and functions using the `-P` function are:
|
||||
static-php-cli has many open methods, which cannot be listed in the docs,
|
||||
but as long as it is a `public function` and is not marked as `@internal`, it theoretically can be called.
|
||||
:::
|
||||
|
||||
## Multiple builds
|
||||
|
||||
If you need to build multiple times locally, the following method can save you time downloading resources and compiling.
|
||||
|
||||
- If you only switch the PHP version without changing the dependent libraries, you can use `bin/spc switch-php-version` to quickly switch the PHP version, and then re-run the same `build` command.
|
||||
- If you want to rebuild once, but do not re-download the source code, you can first `rm -rf buildroot source` to delete the compilation directory and source code directory, and then rebuild.
|
||||
- If you want to update a version of a dependency, you can use `bin/spc del-download <source-name>` to delete the specified source code, and then use `download <source-name>` to download it again.
|
||||
- If you want to update all dependent versions, you can use `bin/spc download --clean` to delete all downloaded sources, and then download them again.
|
||||
|
||||
## embed usage
|
||||
|
||||
If you want to embed static-php into other C language programs, you can use `--build-embed` to build an embed version of PHP.
|
||||
|
||||
```bash
|
||||
bin/spc build {your extensions} --build-embed --debug
|
||||
```
|
||||
|
||||
Under normal circumstances, PHP embed will generate `php-config` after compilation.
|
||||
For static-php, we provide `spc-config` to obtain the parameters during compilation.
|
||||
In addition, when using embed SAPI (libphp.a), you need to use the same compiler as libphp, otherwise there will be a link error.
|
||||
|
||||
Here is the basic usage of spc-config:
|
||||
|
||||
```bash
|
||||
# output all flags and options
|
||||
bin/spc spc-config curl,zlib,phar,openssl
|
||||
|
||||
# output libs
|
||||
bin/spc spc-config curl,zlib,phar,openssl --libs
|
||||
|
||||
# output includes
|
||||
bin/spc spc-config curl,zlib,phar,openssl --includes
|
||||
```
|
||||
|
||||
By default, static-php uses the following compilers on different systems:
|
||||
|
||||
- macOS: `clang`
|
||||
- Linux (Alpine Linux): `gcc`
|
||||
- Linux (glibc based distros, x86_64): `/usr/local/musl/bin/x86_64-linux-musl-gcc`
|
||||
- Linux (glibc based distros, aarch64): `/usr/local/musl/bin/aarch64-linux-musl-gcc`
|
||||
- FreeBSD: `clang`
|
||||
|
||||
Here is an example of using embed SAPI:
|
||||
|
||||
```c
|
||||
// embed.c
|
||||
#include <sapi/embed/php_embed.h>
|
||||
|
||||
int main(int argc,char **argv){
|
||||
|
||||
PHP_EMBED_START_BLOCK(argc,argv)
|
||||
|
||||
zend_file_handle file_handle;
|
||||
|
||||
zend_stream_init_filename(&file_handle,"embed.php");
|
||||
|
||||
if(php_execute_script(&file_handle) == FAILURE){
|
||||
php_printf("Failed to execute PHP script.\n");
|
||||
}
|
||||
|
||||
PHP_EMBED_END_BLOCK()
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```php
|
||||
<?php
|
||||
// embed.php
|
||||
echo "Hello world!\n";
|
||||
```
|
||||
|
||||
```bash
|
||||
# compile in debian/ubuntu x86_64
|
||||
/usr/local/musl/bin/x86_64-linux-musl-gcc embed.c $(bin/spc spc-config bcmath,zlib) -static -o embed
|
||||
# compile in macOS/FreeBSD
|
||||
clang embed.c $(bin/spc spc-config bcmath,zlib) -o embed
|
||||
|
||||
./embed
|
||||
# out: Hello world!
|
||||
```
|
||||
|
||||
@@ -8,15 +8,8 @@ here will describe how to check the errors by yourself and report Issue.
|
||||
Problems with downloading resources are one of the most common problems with spc.
|
||||
The main reason is that the addresses used for SPC download resources are generally the official website of the corresponding project or GitHub, etc.,
|
||||
and these websites may occasionally go down and block IP addresses.
|
||||
After encountering a download failure,
|
||||
you can try to call the download command multiple times.
|
||||
|
||||
When downloading extensions, you may eventually see errors like `curl: (56) The requested URL returned error: 403` which are often caused by github rate limiting.
|
||||
You can verify this by adding `--debug` to the command and will see something like `[DEBU] Running command (no output) : curl -sfSL "https://api.github.com/repos/openssl/openssl/releases"`.
|
||||
|
||||
To fix this, [create](https://github.com/settings/tokens) a personal access token on GitHub and set it as an environment variable `GITHUB_TOKEN=<XXX>`.
|
||||
|
||||
If you confirm that the address is indeed inaccessible,
|
||||
Currently, version 2.0.0 has not added an automatic retry mechanism, so after encountering a download failure,
|
||||
you can try to call the download command multiple times. If you confirm that the address is indeed inaccessible,
|
||||
you can submit an Issue or PR to update the url or download type.
|
||||
|
||||
## Doctor Can't Fix Something
|
||||
@@ -38,5 +31,3 @@ and then determine the command that reported the error.
|
||||
The error terminal output is very important for fixing compilation errors.
|
||||
When submitting an issue, please upload the last error fragment of the terminal log (or the entire terminal log output),
|
||||
and include the `spc` command and parameters used.
|
||||
|
||||
If you are rebuilding, please refer to the [Local Build - Multiple Builds](./manual-build#multiple-builds) section.
|
||||
|
||||
125
docs/en/index.md
125
docs/en/index.md
@@ -3,14 +3,11 @@
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: "Static PHP"
|
||||
name: "static-php-cli"
|
||||
tagline: "Build standalone PHP binary on Linux, macOS, FreeBSD, Windows, with PHP project together, with popular extensions included."
|
||||
image:
|
||||
src: /images/static-php_nobg.png
|
||||
alt: Static PHP CLI Logo
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Get Started
|
||||
text: Guide
|
||||
link: ./guide/
|
||||
|
||||
features:
|
||||
@@ -22,121 +19,3 @@ features:
|
||||
details: static-php-cli comes with dependency management and supports installation of different types of PHP extensions.
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import {VPSponsors} from "vitepress/theme";
|
||||
import Contributors from '../.vitepress/components/Contributors.vue';
|
||||
|
||||
const sponsors = [
|
||||
{ name: 'Beyond Code', img: '/images/beyondcode-seeklogo.png', url: 'https://beyondco.de/' },
|
||||
{ name: 'NativePHP', img: '/images/nativephp-logo.svg', url: 'https://nativephp.com/' },
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="sponsors-section">
|
||||
<div class="sponsors-header">
|
||||
<h2>Special Sponsors</h2>
|
||||
<p class="sponsors-description">
|
||||
Thank you to our amazing sponsors for supporting this project!
|
||||
</p>
|
||||
</div>
|
||||
<VPSponsors :data="sponsors"/>
|
||||
</div>
|
||||
|
||||
<style scoped>
|
||||
.sponsors-section {
|
||||
margin: 48px auto;
|
||||
padding: 32px 24px;
|
||||
max-width: 1152px;
|
||||
background: linear-gradient(135deg, var(--vp-c-bg-soft) 0%, var(--vp-c-bg) 100%);
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.sponsors-section:hover {
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.sponsors-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.sponsors-header h2 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 8px 0;
|
||||
background: linear-gradient(120deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.sponsors-description {
|
||||
font-size: 0.95rem;
|
||||
color: var(--vp-c-text-2);
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sponsors-section {
|
||||
margin: 32px 16px;
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.sponsors-header h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.sponsors-description {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hero logo styling */
|
||||
:deep(.VPImage.image-src) {
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--vp-c-bg-soft) 0%, var(--vp-c-default-soft) 100%);
|
||||
padding: 40px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
:deep(.VPImage.image-src:hover) {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Dark mode adjustments for logo */
|
||||
.dark :deep(.VPImage.image-src) {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.dark :deep(.VPImage.image-src:hover) {
|
||||
opacity: 1;
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
/* Additional styling for the logo image itself */
|
||||
:deep(.VPImage.image-src img) {
|
||||
max-height: 280px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
:deep(.VPImage.image-src) {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
:deep(.VPImage.image-src img) {
|
||||
max-height: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<Contributors />
|
||||
|
||||
126
docs/index.md
126
docs/index.md
@@ -3,11 +3,8 @@
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: "Static PHP"
|
||||
name: "static-php-cli"
|
||||
tagline: "Build standalone PHP binary on Linux, macOS, FreeBSD, Windows, with PHP project together, with popular extensions included."
|
||||
image:
|
||||
src: /images/static-php_nobg.png
|
||||
alt: Static PHP CLI Logo
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Get Started
|
||||
@@ -24,124 +21,3 @@ features:
|
||||
- title: Dependency Management
|
||||
details: static-php-cli comes with dependency management and supports installation of different types of PHP extensions.
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import {VPSponsors} from "vitepress/theme";
|
||||
import Contributors from './.vitepress/components/Contributors.vue';
|
||||
|
||||
const sponsors = [
|
||||
{ name: 'Beyond Code', img: '/images/beyondcode-seeklogo.png', url: 'https://beyondco.de/' },
|
||||
{ name: 'NativePHP', img: '/images/nativephp-logo.svg', url: 'https://nativephp.com/' },
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="sponsors-section">
|
||||
<div class="sponsors-header">
|
||||
<h2>Special Sponsors</h2>
|
||||
<p class="sponsors-description">
|
||||
Thank you to our amazing sponsors for supporting this project!
|
||||
</p>
|
||||
</div>
|
||||
<VPSponsors :data="sponsors"/>
|
||||
</div>
|
||||
|
||||
<style scoped>
|
||||
.sponsors-section {
|
||||
margin: 48px auto;
|
||||
padding: 32px 24px;
|
||||
max-width: 1152px;
|
||||
background: linear-gradient(135deg, var(--vp-c-bg-soft) 0%, var(--vp-c-bg) 100%);
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.sponsors-section:hover {
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.sponsors-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.sponsors-header h2 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 8px 0;
|
||||
background: linear-gradient(120deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.sponsors-description {
|
||||
font-size: 0.95rem;
|
||||
color: var(--vp-c-text-2);
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sponsors-section {
|
||||
margin: 32px 16px;
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.sponsors-header h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.sponsors-description {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hero logo styling */
|
||||
:deep(.VPImage.image-src) {
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--vp-c-bg-soft) 0%, var(--vp-c-default-soft) 100%);
|
||||
padding: 40px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
:deep(.VPImage.image-src:hover) {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Dark mode adjustments for logo */
|
||||
.dark :deep(.VPImage.image-src) {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.dark :deep(.VPImage.image-src:hover) {
|
||||
opacity: 1;
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
/* Additional styling for the logo image itself */
|
||||
:deep(.VPImage.image-src img) {
|
||||
max-height: 280px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
:deep(.VPImage.image-src) {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
:deep(.VPImage.image-src img) {
|
||||
max-height: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<Contributors />
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 29 KiB |
@@ -1,6 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764 100">
|
||||
<path fill="#505b93" d="M29.5,98.4H0V1.2h29.5V98.4z"/>
|
||||
<path fill="#00aaa6" d="M96.7,98.4H67.2V1.2h29.5V98.4z"/>
|
||||
<path fill="#272d48" d="M96.7,98.4H29.5V1.2L96.7,98.4z"/>
|
||||
<path fill="#272d48" d="M102.6,54.5c0-6.2,1.3-11.8,4.1-16.7c2.7-5,6.7-8.8,11.9-11.6c5.2-2.8,11.4-4.2,18.6-4.2c1.1,0,2.8,0.1,5.2,0.3 c4.9,0.4,9.1,1.3,12.5,2.8c3.4,1.5,6.4,3.4,9.1,5.9v-7.2h25.8v74.7h-25.8v-7.2c-2.5,2.6-5.6,4.6-9.4,6.1c-3.8,1.5-7.9,2.4-12.1,2.6 c-0.9,0.1-2.3,0.1-4.1,0.1c-7.2,0-13.4-1.4-18.8-4.1c-5.4-2.7-9.5-6.6-12.4-11.5c-2.9-4.9-4.3-10.5-4.3-16.6V54.5z M128.4,63.9 c0,9.2,5.9,13.8,17.7,13.8c11.8,0,17.7-4.6,17.7-13.8v-5.6c0-9.3-5.9-14-17.7-14c-11.8,0-17.7,4.7-17.7,14V63.9z M208.3,98.4V47h-12.8V23.7l12.8-0.2V1.2h25.9l0.1,22.4h18.3V47h-18.4v51.4 M287.3,98.4h-25.9V23.6h25.9V98.4z M351,98.4H325l-31-74.8H320L338,68l18-44.5h25.9L351,98.4z M454.9,87.6c-4.1,4.2-8.8,7.3-14.1,9.3c-5.3,2-11.8,2.9-19.5,2.9c-8,0-15.1-1.4-21.3-4.2 c-6.2-2.8-11.1-6.7-14.7-11.6c-3.5-5-5.3-10.6-5.3-17V54.6c0-6.5,1.7-12.2,5.2-17.1c3.4-4.9,8.2-8.7,14.2-11.3c6-2.7,12.7-4,20-4 c8,0,15,1.5,21.2,4.3c6.1,2.9,10.9,7,14.4,12.4c3.4,5.4,5.2,11.6,5.2,18.7c0,1.7-0.2,4.2-0.7,7.7l-54.2,0.1v2.1 c0,4.1,1.5,7.3,4.4,9.4c2.9,2.2,6.9,3.2,11.8,3.2c4.6,0,8.5-0.6,11.8-1.8c3.2-1.2,6.4-3.5,9.4-6.8L454.9,87.6z M434.4,51.4 c0-3.1-1.4-5.5-4.2-7.1c-2.8-1.6-6.4-2.4-10.8-2.4s-7.9,0.8-10.5,2.4c-2.6,1.6-3.8,4-3.8,7.1H434.4z M466,98.4V1.2h56c9.9,0,17.8,1.9,23.7,5.6c5.9,3.7,10,8.2,12.2,13.3c2.3,5.1,3.4,10.1,3.4,15 c0,4.8-1.2,9.7-3.5,14.7c-2.3,5-6.4,9.2-12.2,12.8c-5.8,3.6-13.7,5.4-23.7,5.4h-30.2v30.5H466z M522,44.6c9,0,13.6-3.3,13.6-9.9 c0-6.9-4.6-10.3-13.7-10.3h-30.1v20.2H522z M593,98.4h-25.8V1.2H593v38h43.9v-38h25.8v97.2h-25.8V59.9H593V98.4z M668.6,98.4V1.2h56c9.9,0,17.8,1.9,23.7,5.6c5.9,3.7,10,8.2,12.2,13.3c2.3,5.1,3.4,10.1,3.4,15 c0,4.8-1.2,9.7-3.5,14.7c-2.3,5-6.4,9.2-12.2,12.8c-5.8,3.6-13.7,5.4-23.7,5.4h-30.2v30.5H668.6z M724.6,44.6c9,0,13.6-3.3,13.6-9.9 c0-6.9-4.6-10.3-13.7-10.3h-30.1v20.2H724.6z M291.1,20.2h-33.5V0h33.5V20.2z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 965 KiB |
@@ -4,48 +4,45 @@
|
||||
|
||||
## 贡献方法
|
||||
|
||||
如果你有代码或文档要贡献,以下是你需要首先了解的内容。
|
||||
如果你有代码或文档想要贡献,需要先了解以下内容。
|
||||
|
||||
1. 你要贡献什么类型的代码?(新扩展、修复 Bug、安全问题、项目框架优化、文档)
|
||||
2. 如果你贡献了新文件或新片段,你的代码是否经过 `php-cs-fixer` 和 `phpstan` 的检查?
|
||||
3. 在贡献代码前是否充分阅读了 [开发指南](../develop/)?
|
||||
|
||||
如果你能回答上述问题并对代码进行了修改,可以及时在项目 GitHub 仓库发起 Pull Request。
|
||||
代码审查完成后,可以根据建议修改代码,或直接合并到主分支。
|
||||
如果你可以回答以上问题,并已经对代码做出了修改,可以及时在项目 GitHub 仓库发起 Pull Request。待代码审查完毕后,可根据建议修改代码,或直接合并到主分支。
|
||||
|
||||
## 贡献类型
|
||||
|
||||
本项目的主要目的是编译静态链接的 PHP 二进制文件,命令行处理功能基于 `symfony/console` 编写。
|
||||
在开发之前,如果你对它不够熟悉,请先查看 [symfony/console 文档](https://symfony.com/doc/current/components/console.html)。
|
||||
本项目主要用途是编译静态链接的 PHP 二进制,基于 `symfony/console` 编写了命令行处理功能。在开发之前,如果你对它不够熟悉,
|
||||
可以先查看 [symfony/console 文档](https://symfony.com/doc/current/components/console.html)。
|
||||
|
||||
### 安全更新
|
||||
### 安全问题
|
||||
|
||||
因为本项目基本上是一个本地运行的 PHP 项目,一般来说不会有远程攻击。
|
||||
但如果你发现此类问题,请**不要**在 GitHub 仓库提交 PR 或 Issue,
|
||||
你需要通过 [邮件](mailto:admin@zhamao.me) 联系项目维护者(crazywhalecc)。
|
||||
因为本项目基本上是属于本地运行的 PHP 项目,一般来说不会存在远程攻击行为。但如果你发现了此类问题,请**不要**在 GitHub 仓库提交 PR 或 Issue,
|
||||
你需要通过 [邮件](mailto:admin@zhamao.me) 的方式联系项目维护者(crazywhalecc)。
|
||||
|
||||
### 修复 Bug
|
||||
|
||||
修复 Bug 一般不涉及项目结构和框架的修改,所以如果你能定位到错误代码并直接修复它,请直接提交 PR。
|
||||
修复 Bug 一般不涉及项目结构和框架的修改,所以如果你可以定位到错误代码并直接修复它,请直接提交 PR。
|
||||
|
||||
### 新扩展
|
||||
|
||||
对于添加新扩展,你需要了解项目的一些基本结构以及如何根据现有逻辑添加新扩展。
|
||||
这将在本页的下一节中详细介绍。
|
||||
对于添加一个新扩展来说,你需要先了解一些本项目的基本结构,以及如何根据现有的逻辑添加新扩展。在本页的下一章节将会详细介绍。
|
||||
总的来说,你需要:
|
||||
|
||||
1. 评估扩展是否可以内联编译到 PHP 中。
|
||||
2. 评估扩展的依赖库(如果有)是否可以静态编译。
|
||||
3. 编写不同平台的库编译命令。
|
||||
4. 验证扩展及其依赖项与现有扩展和依赖项兼容。
|
||||
5. 验证扩展在 `cli`、`micro`、`fpm`、`embed` SAPIs 中正常工作。
|
||||
6. 编写文档并添加你的扩展。
|
||||
3. 写出扩展的依赖库在不同平台编译命令。
|
||||
4. 验证扩展及其依赖库能否与现有扩展和依赖库兼容。
|
||||
5. 验证扩展在 `cli`、`micro`、`fpm`、`embed` 几种 SAPI 中均正常工作。
|
||||
6. 编写文档,加入你的扩展。
|
||||
|
||||
### 项目框架优化
|
||||
|
||||
如果你已经熟悉 `symfony/console` 的工作原理,并同时要对项目的框架进行一些修改或优化,请先了解以下事情:
|
||||
|
||||
1. 添加扩展不属于项目框架优化,但如果你在添加新扩展时发现必须优化框架,则需要先修改框架本身,然后再添加扩展。
|
||||
2. 对于一些大规模逻辑修改(例如涉及 LibraryBase、Extension 对象等的修改),建议先提交 Issue 或 Draft PR 进行讨论。
|
||||
3. 在项目早期,它是一个纯私有开发项目,代码中有一些中文注释。项目国际化后,你可以提交 PR 将这些注释翻译为英语。
|
||||
4. 请不要在代码中提交更多无用的代码片段,例如大量未使用的变量、方法、类以及多次重写的代码。
|
||||
1. 加入扩展不属于项目框架优化,但如果你在加入新的扩展时发现不得不优化框架,则需先对框架本身进行修改,然后再加入扩展。
|
||||
2. 对于一些大规模逻辑修改(例如涉及 LibraryBase、Extension 对象等的修改)时,建议先提交 Issue 或 Draft PR 进行讨论方案。
|
||||
3. 项目早期为纯中文开发项目,代码中存在一部分中文的注释。国际化项目后你可以提交 PR 将这些注释翻译为英语。
|
||||
4. 请不要在代码中提交包含较多无用的代码片段,例如大量未被使用的变量、方法、类、重复写了很多次的代码。
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
# craft.yml 配置
|
||||
|
||||
<!--@include: ../../deps-craft-yml.md-->
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
开发本项目需要安装部署 PHP 环境,以及一些 PHP 项目常用的扩展和 Composer。
|
||||
|
||||
项目的开发环境和运行环境几乎完全一致。你可以参照 **手动构建** 部分安装系统 PHP 或使用本项目预构建的静态 PHP 作为环境。这里不再赘述。
|
||||
项目的开发环境和运行环境几乎完全一致,你可以参照 **指南-本地构建** 部分安装系统 PHP 或使用本项目预构建的静态 PHP 作为环境,这里不再赘述。
|
||||
|
||||
抛开用途,本项目本身其实就是一个 `php-cli` 程序,你可以将它当作一个正常的 PHP 项目进行编辑和开发,同时你需要了解不同系统的 Shell 命令行。
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
curl,dom,filter,mbstring,openssl,pcntl,phar,posix,sodium,tokenizer,xml,xmlwriter
|
||||
```
|
||||
|
||||
static-php-cli 项目本身不需要这么多扩展,但在开发过程中,你会用到 Composer 和 PHPUnit 等工具,它们需要这些扩展。
|
||||
static-php-cli 项目本身不需要这么多扩展,但在开发过程中,你会用到 Composer、PHPUnit 等工具,它们需要这些扩展。
|
||||
|
||||
> 对于 static-php-cli 自身构建的 micro 自执行二进制,仅需要 `pcntl,posix,mbstring,tokenizer,phar`。
|
||||
|
||||
## 开始开发
|
||||
|
||||
继续向下查看项目结构文档,你可以学习 `static-php-cli` 是如何工作的。
|
||||
继续向下查看项目结构的文档,你可以从中了解 `static-php-cli` 是如何运作的。
|
||||
|
||||
@@ -18,7 +18,6 @@ static-php-cli 的下载资源模块是一个主要的功能,它包含了所
|
||||
"type": "ghrel",
|
||||
"repo": "libevent/libevent",
|
||||
"match": "libevent.+\\.tar\\.gz",
|
||||
"provide-pre-built": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
@@ -30,7 +29,6 @@ static-php-cli 的下载资源模块是一个主要的功能,它包含了所
|
||||
这里最主要的字段是 `type`,目前它支持的类型有:
|
||||
|
||||
- `url`: 直接使用 URL 下载,例如:`https://download.libsodium.org/libsodium/releases/libsodium-1.0.18.tar.gz`。
|
||||
- `pie`: 使用 PIE(PHP Installer for Extensions)标准从 Packagist 下载 PHP 扩展。
|
||||
- `ghrel`: 使用 GitHub Release API 下载,即从 GitHub 项目发布的最新版本中上传的附件下载。
|
||||
- `ghtar`: 使用 GitHub Release API 下载,与 `ghrel` 不同的是,`ghtar` 是从项目的最新 Release 中找 `source code (tar.gz)` 下载的。
|
||||
- `ghtagtar`: 使用 GitHub Release API 下载,与 `ghtar` 相比,`ghtagtar` 可以从 `tags` 列表找最新的,并下载 `tar.gz` 格式的源码(因为有些项目只使用了 `tag` 发布版本)。
|
||||
@@ -46,7 +44,6 @@ source.json 中每个源文件拥有以下字段:
|
||||
- `license`: 源代码的开源许可证,见下方 **开源许可证** 章节
|
||||
- `type`: 必须为上面提到的类型之一
|
||||
- `path`(可选): 释放源码到指定目录而非 `source/{name}`
|
||||
- `provide-pre-built`(可选): 是否提供预编译的二进制文件,如果为 `true`,则会在 `bin/spc download` 时尝试自动下载预编译的二进制文件
|
||||
|
||||
::: tip
|
||||
`source.json` 中的 `path` 参数可指定相对路径或绝对路径。当指定为相对路径时,路径基于 `source/`。
|
||||
@@ -78,36 +75,6 @@ url 类型的资源指的是从 URL 直接下载文件。
|
||||
}
|
||||
```
|
||||
|
||||
## 下载类型 - pie
|
||||
|
||||
PIE(PHP Installer for Extensions)类型的资源是从 Packagist 下载遵循 PIE 标准的 PHP 扩展。
|
||||
该方法会自动从 Packagist 仓库获取扩展信息,并下载相应的分发文件。
|
||||
|
||||
包含的参数有:
|
||||
|
||||
- `repo`: Packagist 的 vendor/package 名称,如 `vendor/package-name`
|
||||
|
||||
例子(使用 PIE 从 Packagist 下载 PHP 扩展):
|
||||
|
||||
```json
|
||||
{
|
||||
"ext-example": {
|
||||
"type": "pie",
|
||||
"repo": "vendor/example-extension",
|
||||
"path": "php-src/ext/example",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: tip
|
||||
PIE 下载类型会自动从 Packagist 元数据中检测扩展信息,包括下载 URL、版本和分发类型。
|
||||
扩展必须在其 Packagist 包定义中标记为 `type: php-ext` 或包含 `php-ext` 元数据。
|
||||
:::
|
||||
|
||||
## 下载类型 - ghrel
|
||||
|
||||
ghrel 会从 GitHub Release 中上传的 Assets 下载文件。首先使用 GitHub Release API 获取最新版本,然后根据正则匹配方式下载相应的文件。
|
||||
@@ -328,23 +295,3 @@ pkg.json 存放的是非源码类型的文件资源,例如 musl-toolchain、UP
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
当一个开源项目的许可证在不同版本间使用不同的文件,`path` 参数可以使用数组将可能的许可证文件列出:
|
||||
|
||||
```json
|
||||
{
|
||||
"redis": {
|
||||
"type": "git",
|
||||
"path": "php-src/ext/redis",
|
||||
"rev": "release/6.0.2",
|
||||
"url": "https://github.com/phpredis/phpredis",
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": [
|
||||
"LICENSE",
|
||||
"COPYING"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -14,7 +14,7 @@ static-php-cli 主要包含三种逻辑组件:资源、依赖库、扩展。
|
||||
项目主要分为几个文件夹:
|
||||
|
||||
- `bin/`: 用于存放程序入口文件,包含 `bin/spc`、`bin/spc-alpine-docker`、`bin/setup-runtime`。
|
||||
- `config/`: 包含了所有项目支持的扩展、依赖库以及这些资源下载的地址、下载方式等,:`lib.json`、`ext.json`、`source.json`、`pkg.json`、`pre-built.json`。
|
||||
- `config/`: 包含了所有项目支持的扩展、依赖库以及这些资源下载的地址、下载方式等,分为四个文件:`lib.json`、`ext.json`、`source.json`、`pkg.json`。
|
||||
- `src/SPC/`: 项目的核心代码,包含了整个框架以及编译各种扩展和库的命令。
|
||||
- `src/globals/`: 项目的全局方法和常量、运行时需要的测试文件(例如:扩展的可用性检查代码)。
|
||||
- `vendor/`: Composer 依赖的目录,你无需对它做出任何修改。
|
||||
|
||||
@@ -2,95 +2,60 @@
|
||||
|
||||
这里将会编写一些你容易遇到的问题。目前有很多,但是我需要花时间来整理一下。
|
||||
|
||||
## php.ini 的路径是什么?
|
||||
## 静态编译的 PHP 可以安装扩展吗
|
||||
|
||||
在 Linux、macOS 和 FreeBSD 上,`php.ini` 的路径是 `/usr/local/etc/php/php.ini`。
|
||||
在 Windows 中,路径是 `C:\windows\php.ini` 或 `php.exe` 所在的当前目录。
|
||||
可以在 *nix 系统中使用手动构建选项 `--with-config-file-path` 来更改查找 `php.ini` 的目录。
|
||||
因为传统架构下的 PHP 安装扩展的原理是使用 `.so` 类型的动态链接的库方式安装新扩展,而使用本项目编译的静态链接的 PHP 无法**直接**使用动态链接库安装新扩展。
|
||||
|
||||
此外,在 Linux、macOS 和 FreeBSD 上,`/usr/local/etc/php/conf.d` 目录中的 `.ini` 文件也会被加载。
|
||||
在 Windows 中,该路径默认为空。
|
||||
可以使用手动构建选项 `--with-config-file-scan-dir` 更改该目录。
|
||||
对于 macOS 平台来说,macOS 下的几乎所有二进制文件都无法真正纯静态链接,几乎所有二进制文件都会链接 macOS 的系统库:`/usr/lib/libresolv.9.dylib` 和 `/usr/lib/libSystem.B.dylib`。
|
||||
所以在 macOS 系统下,在特定的编译条件下可以使用静态编译的 php 二进制文件,同时使用动态链接的扩展:
|
||||
|
||||
PHP 默认也会从 [其他标准位置](https://www.php.net/manual/zh/configuration.file.php) 中搜索 `php.ini`。
|
||||
|
||||
## 静态编译的 PHP 可以安装扩展吗?
|
||||
|
||||
因为传统架构下的 PHP 安装扩展的原理是使用 `.so` 类型的动态链接的库方式安装新扩展,而使用本项目编译的静态链接的 PHP。但是静态链接在不同操作系统有不同的定义。
|
||||
|
||||
首先,对于 Linux 系统,静态链接的二进制文件不会链接系统的动态链接库。纯静态链接的二进制文件(`-all-static`)无法加载动态库,因此无法添加新扩展。
|
||||
同时,在纯静态模式下,你也不能使用 `ffi` 等扩展来加载外部 `.so` 模块。
|
||||
|
||||
你可以使用命令 `ldd buildroot/bin/php` 来检查你在 Linux 下构建的二进制文件是否为纯静态链接。
|
||||
|
||||
如果你 [构建基于 GNU libc 的 PHP](../guide/build-with-glibc),你可以使用 `ffi` 扩展来加载外部 `.so` 模块,并加载具有相同 ABI 的 `.so` 扩展。
|
||||
|
||||
例如,你可以使用以下命令构建一个与 glibc 动态链接的静态 PHP 二进制文件,支持 FFI 扩展并加载相同 PHP 版本和相同 TS 类型的 `xdebug.so` 扩展:
|
||||
1. 使用 `--no-strip` 参数,将不会对二进制文件去除调试符号等信息,以供使用 `Xdebug` 等外部 Zend 扩展。
|
||||
2. 如果要编译某些 Zend 扩展,使用 Homebrew、MacPorts、源码编译的形式,在所在的操作系统安装一个普通版本的 PHP。
|
||||
3. 使用 `phpize && ./configure && make` 命令编译想要使用的扩展。
|
||||
4. 将扩展文件 `xxxx.so` 拷贝到外部,使用静态编译的 PHP 二进制,例如使用 Xdebug 扩展:`cd buildroot/bin/ && ./php -d "zend_extension=/path/to/xdebug.so"`。
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker download --for-extensions=ffi,xml --with-php=8.4
|
||||
bin/spc-gnu-docker build ffi,xml --build-cli --debug
|
||||
|
||||
buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" --ri xdebug
|
||||
# 构建静态 php-cli
|
||||
bin/spc build ffi --build-cli --no-strip
|
||||
```
|
||||
|
||||
对于 macOS 平台,macOS 下的几乎所有二进制文件都无法真正纯静态链接,几乎所有二进制文件都会链接 macOS 系统库:`/usr/lib/libresolv.9.dylib` 和 `/usr/lib/libSystem.B.dylib`。
|
||||
因此,在 macOS 上,你可以**直接**使用 SPC 构建具有动态链接扩展的静态编译 PHP 二进制文件:
|
||||
对于 Linux 平台来说,目前的编译结果为纯静态链接的二进制文件,无法使用动态链接库安装新扩展。
|
||||
|
||||
1. 使用 `--build-shared=XXX` 选项构建共享扩展 `xxx.so`。例如:`bin/spc build bcmath,zlib --build-shared=xdebug --build-cli`
|
||||
2. 你将获得 `buildroot/modules/xdebug.so` 和 `buildroot/bin/php`。
|
||||
3. `xdebug.so` 文件可用于版本和线程安全相同的 php。
|
||||
|
||||
对于 Windows 平台,由于官方构建的扩展(如 `php_yaml.dll`)强制使用了 `php8.dll` 动态库作为链接,静态构建的 PHP 不包含任何系统库以外的动态库,
|
||||
所以 Windows 下无法加载官方构建的动态扩展。 由于 static-php-cli 还暂未支持构建动态扩展,所以目前还没有让 static-php 加载动态扩展的方法。
|
||||
|
||||
不过,Windows 可以正常使用 `FFI` 扩展加载其他的 dll 文件并调用。
|
||||
|
||||
## 可以支持 Oracle 数据库扩展吗?
|
||||
## 可以支持 Oracle 数据库扩展吗
|
||||
|
||||
部分依赖库闭源的扩展,如 `oci8`、`sourceguardian` 等,它们没有提供纯静态编译的依赖库文件(`.a`),仅提供了动态依赖库文件(`.so`),
|
||||
这些扩展无法使用源码的形式编译到 static-php-cli 中,所以本项目可能永远也不会支持这些扩展。不过,理论上你可以根据上面的问题在 macOS 和 Linux 下接入和使用这类扩展。
|
||||
这些扩展无法使用源码的形式编译到 static-php-cli 中,所以本项目可能永远也不会支持这些扩展。不过,理论上你可以根据上面的问题在 macOS 下接入和使用这类扩展。
|
||||
|
||||
如果你对此类扩展有需求,或者大部分人都对这些闭源扩展使用有需求,
|
||||
可以看看有关 [standalone-php-cli](https://github.com/crazywhalecc/static-php-cli/discussions/58) 的讨论。欢迎留言。
|
||||
|
||||
## 支持 Windows 吗?
|
||||
## 支持 Windows 吗
|
||||
|
||||
该项目目前支持 Windows,但支持的扩展数量较少。Windows 支持并不完美。主要有以下问题:
|
||||
该项目目前已支持 Windows,但支持的扩展数量较少,Windows 的支持并不完美,主要有以下几个问题:
|
||||
|
||||
1. Windows 的编译过程与 *nix 不同,使用的工具链也不同。用于编译每个扩展依赖库的编译工具也几乎完全不同。
|
||||
2. Windows 版本的需求也会根据所有使用本项目的人的需求推进。如果很多人需要,我会尽快支持相关扩展。
|
||||
1. Windows 的编译流程与 *nix 不同,使用的工具链也不同,编译各个扩展的依赖库使用的编译工具也几乎完全不同。
|
||||
2. Windows 版本的需求也会根据所有使用本项目的人的需求推进,如果有很多人需要,我会尽快支持相关扩展。
|
||||
|
||||
## 我可以使用 micro 保护我的源代码吗?
|
||||
## 使用 micro 可以保护我的源码吗
|
||||
|
||||
不可以。micro.sfx 本质上是将 php 和 php 代码合并为一个文件,没有编译或加密 PHP 代码的过程。
|
||||
不可以。micro.sfx 本质上是将 php 和 php 代码结合为一个文件,没有 PHP 代码编译或加密的过程。
|
||||
首先 php-src 是 PHP 代码的官方解释器,而且现在市面上还没有一个能兼容主流分支的 PHP 编译器。
|
||||
之前我在网上看到有一个项目是 BPC(Binary PHP Compiler?)可以把 PHP 编译为二进制,但是限制也是很多很多。
|
||||
|
||||
首先,php-src 是 PHP 代码的官方解释器,市场上没有与主流分支兼容的 PHP 编译器。
|
||||
我在网上看到一个名为 BPC(Binary PHP Compiler?)的项目可以将 PHP 编译为二进制,但有很多限制。
|
||||
加密保护代码的方向和编译也不是一回事,编译过后也可以通过逆向工程等方式拿到代码,真正保护还是通过加壳、加密代码等手段进行。
|
||||
|
||||
加密和保护代码的方向与编译不同。编译后,也可以通过逆向工程等方法获得代码。真正的保护仍然通过打包和加密代码等手段进行。
|
||||
|
||||
因此,本项目(static-php-cli)和相关项目(lwmbs、swoole-cli)都提供了 php-src 源代码的便捷编译工具。
|
||||
本项目和相关项目引用的 phpmicro 只是 PHP 的 sapi 接口封装,而不是 PHP 代码的编译工具。
|
||||
PHP 代码的编译器是一个完全不同的项目,因此不考虑额外的情况。
|
||||
如果你对加密感兴趣,可以考虑使用现有的加密技术,如 Swoole Compiler、Source Guardian 等。
|
||||
所以本项目(static-php-cli)、相关项目(lwmbs、swoole-cli)都是提供一个对 php-src 源码的便捷编译工具,
|
||||
本项目和相关项目引用的 phpmicro 也仅仅是 PHP 的 sapi 接口封装,而不是 PHP 代码的编译工具。
|
||||
PHP 代码的编译器是完全不同的项目,因此不会考虑额外的情况。如果你对加密感兴趣,可以考虑使用现有的加密技术,如 Swoole Compiler、Source Guardian 等。
|
||||
|
||||
## 无法使用 ssl
|
||||
|
||||
**更新:该问题已在最新版本的 static-php-cli 中修复,现在默认读取系统的证书文件。如果你仍然遇到问题,请尝试下面的解决方案。**
|
||||
使用 curl、pgsql 等 请求 HTTPS 网站或建立 SSL 连接时,可能存在 `error:80000002:system library::No such file or directory` 错误,
|
||||
这个错误是由于静态编译的 PHP 未通过 `php.ini` 指定 `openssl.cafile` 导致的。
|
||||
|
||||
使用 curl、pgsql 等请求 HTTPS 网站或建立 SSL 连接时,可能会出现 `error:80000002:system library::No such file or directory` 错误。
|
||||
此错误是由于静态编译的 PHP 未通过 `php.ini` 指定 `openssl.cafile` 导致的。
|
||||
|
||||
你可以通过在使用 PHP 前指定 `php.ini` 并在 INI 中添加 `openssl.cafile=/path/to/your-cert.pem` 来解决此问题。
|
||||
你可以在使用 PHP 前指定 `php.ini`,并在 INI 内添加 `openssl.cafile=/path/to/your-cert.pem` 来解决这个问题。
|
||||
|
||||
对于 Linux 系统,你可以从 curl 官方网站下载 [cacert.pem](https://curl.se/docs/caextract.html) 文件,也可以使用系统自带的证书文件。
|
||||
有关不同发行版的证书位置,请参考 [Golang 文档](https://go.dev/src/crypto/x509/root_linux.go)。
|
||||
有关不同发行版的证书位置,可参考 [Go 标准库](https://go.dev/src/crypto/x509/root_linux.go)。
|
||||
|
||||
> INI 配置 `openssl.cafile` 不能使用 `ini_set()` 函数动态设置,因为 `openssl.cafile` 是 `PHP_INI_SYSTEM` 类型的配置,只能在 `php.ini` 文件中设置。
|
||||
|
||||
## 为什么不支持旧版本的 PHP?
|
||||
|
||||
因为旧版本的 PHP 有很多问题,如安全问题、性能问题和功能问题。此外,许多旧版本的 PHP 与最新的依赖库不兼容,这也是不支持旧版本 PHP 的原因之一。
|
||||
|
||||
你可以使用 static-php-cli 早期编译的旧版本,如 PHP 8.0,但不会明确支持早期版本。
|
||||
> INI 配置 `openssl.cafile` 不可以使用 `ini_set()` 函数动态设置,因为 `openssl.cafile` 是一个 `PHP_INI_SYSTEM` 类型的配置,只能在 `php.ini` 文件中设置。
|
||||
@@ -5,7 +5,6 @@ Action 构建指的是直接使用 GitHub Action 进行编译。
|
||||
如果你不想自行编译,可以从本项目现有的 Action 下载 Artifact,也可以从自托管的服务器下载:[进入](https://dl.static-php.dev/static-php-cli/common/)
|
||||
|
||||
> 自托管的二进制也是由 Action 构建而来,[项目仓库地址](https://github.com/static-php/static-php-cli-hosted)。
|
||||
> 包含的扩展有:bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip
|
||||
|
||||
## 构建方法
|
||||
|
||||
@@ -14,9 +13,7 @@ Action 构建指的是直接使用 GitHub Action 进行编译。
|
||||
1. Fork 本项目。
|
||||
2. 进入项目的 Actions,选择 CI 开头的 Workflow(根据你需要的操作系统选择)。
|
||||
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`)
|
||||
4. 如果需要共享扩展(例如 `xdebug`),请设置 `shared-extensions`(使用英文逗号分割,例如 `xdebug`)。
|
||||
5. 如果需要 FrankenPHP,请启用 `build-frankenphp`,同时也需要启用 `enable-zts`。
|
||||
6. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`。
|
||||
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`。
|
||||
|
||||
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
|
||||
|
||||
|
||||
@@ -146,7 +146,6 @@ bin/spc build "openssl" --build-cli --debug
|
||||
- `--with-clean`: 编译 PHP 前先清理旧的 make 产生的文件
|
||||
- `--enable-zts`: 让编译的 PHP 为线程安全版本(默认为 NTS 版本)
|
||||
- `--with-libs=XXX,YYY`: 编译 PHP 前先编译指定的依赖库,激活部分扩展的可选功能
|
||||
- `--with-config-file-scan-dir=XXX`: 读取 `php.ini` 后扫描 `.ini` 文件的目录(在 [这里](../faq/index.html#php-ini-的路径是什么) 查看默认路径)
|
||||
- `-I xxx=yyy`: 编译前将 INI 选项硬编译到 PHP 内(支持多个选项,别名是 `--with-hardcoded-ini`)
|
||||
- `--with-micro-fake-cli`: 在编译 micro 时,让 micro 的 SAPI 伪装为 `cli`(用于兼容一些检查 `PHP_SAPI` 的程序)
|
||||
- `--disable-opcache-jit`: 禁用 opcache jit(默认启用)
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# 构建 glibc 兼容的 Linux 二进制
|
||||
|
||||
## 为什么要构建 glibc 兼容的二进制
|
||||
|
||||
目前,static-php-cli 在默认条件下在 Linux 系统构建的二进制都是基于 musl-libc(静态链接)的。
|
||||
musl-libc 是一个轻量级的 libc 实现,它的目标是与 glibc 兼容,并且提供良好的纯静态链接支持。
|
||||
这意味着,编译出来的静态 PHP 可执行文件在几乎任何 Linux 发行版都可以使用,而不需要考虑 libc、libstdc++ 等库的版本问题。
|
||||
|
||||
但是,Linux 系统的纯静态链接 musl-libc 二进制文件存在以下问题:
|
||||
|
||||
- 无法使用 PHP 的 `dl()` 函数加载动态链接库和外部 PHP 扩展。
|
||||
- 无法使用 PHP 的 FFI 扩展。
|
||||
- 部分极端情况下,可能会出现性能问题,参见 [musl-libc 的性能问题](https://github.com/php/php-src/issues/13648)。
|
||||
|
||||
对于不同的 Linux 发行版,它们使用的默认 libc 可能不同,比如 Alpine Linux 使用 musl libc,而大多数 Linux 发行版使用 glibc。
|
||||
但即便如此,我们也不能直接使用任意的发行版和 glibc 构建便携的静态二进制文件,因为 glibc 有一些问题:
|
||||
|
||||
- 基于新版本的发行版在使用 gcc 等工具构建的二进制,无法在旧版本的发行版上运行。
|
||||
- glibc 不推荐被静态链接,因为它的一些特性需要动态链接库的支持。
|
||||
|
||||
但是,我们可以使用 Docker 容器来解决这个问题,最终输出的结果是一个动态链接 glibc 和一些必要库的二进制,但它静态链接所有其他依赖。
|
||||
|
||||
1. 使用一个旧版本的 Linux 发行版(如 CentOS 7.x),它的 glibc 版本比较旧,但是可以在大多数现代 Linux 发行版上运行。
|
||||
2. 在这个容器中构建 PHP 的静态二进制文件,这样就可以在大多数现代 Linux 发行版上运行了。
|
||||
|
||||
> 使用 glibc 的静态二进制文件,可以在大多数现代 Linux 发行版上运行,但是不能在 musl libc 的发行版上运行,如 CentOS 6、Alpine Linux 等。
|
||||
|
||||
## 构建 glibc 兼容的 Linux 二进制
|
||||
|
||||
最新版的 static-php-cli 内置了 `bin/spc-gnu-docker` 脚本,可以一键创建一个 CentOS 7.x (glibc-2.17) 的 Docker 容器,并在容器中构建 glibc 兼容的 PHP 静态二进制文件。
|
||||
|
||||
然后,先运行一次以下命令。首次运行时时间较长,因为需要下载 CentOS 7.x 的镜像和一些编译工具。
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker
|
||||
```
|
||||
|
||||
构建镜像完成后,你将看到和 `bin/spc` 一样的命令帮助菜单,这时说明容器已经准备好了。
|
||||
|
||||
在容器准备好后,你可以参考 [本地构建](./manual-build) 章节的内容,构建你的 PHP 静态二进制文件。仅需要把 `bin/spc` 或 `./spc` 替换为 `bin/spc-gnu-docker` 即可。
|
||||
|
||||
```bash
|
||||
bin/spc-gnu-docker build bcmath,ctype,openssl,pdo,phar,posix,session,tokenizer,xml,zip --build-cli --debug
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
极少数情况下,基于 glibc 的静态 PHP 可能会出现 segment fault 等错误,但目前例子较少,如果遇到问题请提交 issue。
|
||||
|
||||
glibc 构建为扩展的特性,不属于默认 static-php 的支持范围。如果有相关问题或需求,请在提交 Issue 时注明你是基于 glibc 构建的。
|
||||
|
||||
如果你需要不使用 Docker 构建基于 glibc 的二进制,请参考 `bin/spc-gnu-docker` 脚本,手动构建一个类似的环境。
|
||||
|
||||
请注意,我们仅支持使用 bin/spc-gnu-docker 构建的 glibc 版本。已在 RHEL 9 和 10 上进行了编译测试并验证其稳定性,但如果您遇到问题,我们可能不会进行修复。
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
<script setup lang="ts">
|
||||
import CliGenerator from "../../.vitepress/components/CliGenerator.vue";
|
||||
</script>
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
outline: 'deep'
|
||||
---
|
||||
|
||||
# 依赖关系图表
|
||||
|
||||
在编译 PHP 时,每个扩展、库都有依赖关系,这些依赖关系可能是必需的,也可能是可选的。在编译 PHP 时,可以选择是否包含这些可选的依赖关系。
|
||||
|
||||
例如,在 Linux 下编译 `gd` 扩展时,会强制编译 `zlib,libpng` 库和 `zlib` 扩展,而 `libavif,libwebp,libjpeg,freetype` 库都是可选的库,默认不会编译,除非通过 `--with-libs=avif,webp,jpeg,freetype` 选项指定。
|
||||
|
||||
- 对于可选扩展(扩展的可选特性),需手动在编译时指定,例如启用 Redis 的 igbinary 支持:`bin/spc build redis,igbinary`。
|
||||
- 对于可选库,需通过 `--with-libs=XXX` 选项编译指定。
|
||||
- 如果想启用所有的可选扩展,可以使用 `bin/spc build redis --with-suggested-exts` 参数。
|
||||
- 如果想启用所有的可选库,可以使用 `--with-suggested-libs` 参数。
|
||||
|
||||
## 扩展的依赖图
|
||||
|
||||
<!--@include: ../../deps-map-ext.md-->
|
||||
|
||||
## 库的依赖表
|
||||
|
||||
<!--@include: ../../deps-map-lib.md-->
|
||||
@@ -1,21 +1,11 @@
|
||||
# 环境变量
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
|
||||
# 环境变量列表
|
||||
|
||||
本页面的环境变量列表中所提到的所有环境变量都具有默认值,除非另有说明。你可以通过设置这些环境变量来覆盖默认值。
|
||||
|
||||
## 环境变量列表
|
||||
|
||||
在 2.3.5 版本之后,我们将环境变量集中到了 `config/env.ini` 文件中,你可以通过修改这个文件来设置环境变量。
|
||||
|
||||
我们将 static-php-cli 支持的环境变量分为三种:
|
||||
|
||||
- 全局内部环境变量:在 static-php-cli 启动后即声明,你可以在 static-php-cli 的内部使用 `getenv()` 来获取他们,也可以在启动 static-php-cli 前覆盖。
|
||||
- 固定环境变量:在 static-php-cli 启动后声明,你仅可使用 `getenv()` 获取,但无法通过 shell 脚本对其覆盖。
|
||||
- 配置文件环境变量:在 static-php-cli 构建前声明,你可以通过修改 `config/env.ini` 文件或通过 shell 脚本来设置这些环境变量。
|
||||
|
||||
你可以阅读 [config/env.ini](https://github.com/crazywhalecc/static-php-cli/blob/main/config/env.ini) 中每项参数的注释来了解其作用(仅限英文版)。
|
||||
|
||||
## 自定义环境变量
|
||||
|
||||
一般情况下,你不需要修改任何以下环境变量,因为它们已经被设置为最佳值。
|
||||
但是,如果你有特殊需求,你可以通过设置这些环境变量来满足你的需求(比如你需要调试不同编译参数下的 PHP 性能表现)。
|
||||
|
||||
@@ -30,24 +20,89 @@ bin/spc build mbstring,pcntl --build-cli
|
||||
SPC_CONCURRENCY=4 bin/spc build mbstring,pcntl --build-cli
|
||||
```
|
||||
|
||||
或者,如果你需要长期修改某个环境变量,你可以通过修改 `config/env.ini` 文件来实现。
|
||||
## 通用环境变量
|
||||
|
||||
`config/env.ini` 分为三段,其中 `[global]` 全局有效,`[windows]`、`[macos]`、`[linux]` 仅对应的操作系统有效。
|
||||
通用环境变量是所有构建目标都可以使用的环境变量。
|
||||
|
||||
例如,你需要修改编译 PHP 的 `./configure` 命令,你可以在 `config/env.ini` 文件中找到 `SPC_CMD_PREFIX_PHP_CONFIGURE` 环境变量,然后修改其值即可。
|
||||
| var name | default value | comment |
|
||||
|------------------------------|---------------------------|-----------------------------|
|
||||
| `BUILD_ROOT_PATH` | `{pwd}/buildroot` | 编译目标的根目录 |
|
||||
| `BUILD_LIB_PATH` | `{pwd}/buildroot/lib` | 编译依赖库的根目录 |
|
||||
| `BUILD_INCLUDE_PATH` | `{pwd}/buildroot/include` | 编译依赖库的头文件目录 |
|
||||
| `BUILD_BIN_PATH` | `{pwd}/buildroot/bin` | 编译依赖库的二进制文件目录 |
|
||||
| `PKG_ROOT_PATH` | `{pwd}/pkgroot` | 闭源或预编译工具下载后安装的目录 |
|
||||
| `SOURCE_PATH` | `{pwd}/source` | 编译项目的源码解压缩目录 |
|
||||
| `DOWNLOAD_PATH` | `{pwd}/downloads` | 下载的文件存放目录 |
|
||||
| `SPC_CONCURRENCY` | 取决于当前 CPU 核心数量 | 并行编译的数量 |
|
||||
| `SPC_SKIP_PHP_VERSION_CHECK` | 空 | 设置为 `yes` 时,跳过扩展对 PHP 版本的检查 |
|
||||
|
||||
但如果你的构建条件比较复杂,需要多种 env.ini 进行切换,我们推荐你使用 `config/env.custom.ini` 文件,这样你可以在不修改默认的 `config/env.ini` 文件的情况下,
|
||||
通过写入额外的重载项目指定你的环境变量。
|
||||
## 系统特定变量
|
||||
|
||||
```ini
|
||||
; This is an example of `config/env.custom.ini` file,
|
||||
; we modify the `SPC_CONCURRENCY` and linux default CFLAGS passing to libs and PHP
|
||||
[global]
|
||||
SPC_CONCURRENCY=4
|
||||
这些环境变量是特定于系统的,它们只在特定的系统上才会生效。
|
||||
|
||||
[linux]
|
||||
SPC_DEFAULT_C_FLAGS="-O3"
|
||||
```
|
||||
### Windows
|
||||
|
||||
| var name | default value | comment |
|
||||
|----------------|------------------------------|-----------------|
|
||||
| `PHP_SDK_PATH` | `{pwd}\php-sdk-binary-tools` | PHP SDK 工具的安装目录 |
|
||||
| `UPX_EXEC` | `$PKG_ROOT_PATH\bin\upx.exe` | UPX 压缩工具的路径 |
|
||||
|
||||
### macOS
|
||||
|
||||
| var name | default value | comment |
|
||||
|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|
|
||||
| `CC` | `clang` | C 编译器 |
|
||||
| `CXX` | `clang++` | C++ 编译器 |
|
||||
| `SPC_DEFAULT_C_FLAGS` | `--target=arm64-apple-darwin` 或 `--target=x86_64-apple-darwin` | 默认 C 编译标志(与 `CFLAGS` 不同) |
|
||||
| `SPC_DEFAULT_CXX_FLAGS` | `--target=arm64-apple-darwin` 或 `--target=x86_64-apple-darwin` | 默认 C++ 编译标志(与 `CXXFLAGS` 不同) |
|
||||
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | 编译 PHP `buildconf` 命令前缀 |
|
||||
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | 编译 PHP `configure` 命令前缀 |
|
||||
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | 编译 PHP `make` 命令前缀 |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS -Werror=unknown-warning-option` | PHP `configure` 命令的 `CFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | PHP `configure` 命令的 `CPPFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | PHP `configure` 命令的 `LDFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os` 或 `-g -O0`(当使用 `--no-strip` 时为后者) | PHP `make` 命令的 `EXTRA_CFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | `-lresolv` | PHP `make` 命令的额外 `EXTRA_LIBS` 变量 |
|
||||
|
||||
### Linux
|
||||
|
||||
| var name | default value | comment |
|
||||
|----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------|
|
||||
| `UPX_EXEC` | `$PKG_ROOT_PATH/bin/upx` | UPX 压缩工具的路径 |
|
||||
| `GNU_ARCH` | `x86_64` 或 `aarch64` | 当前环境的 CPU 架构 |
|
||||
| `CC` | Alpine: `gcc`, Other: `$GNU_ARCH-linux-musl-gcc` | C 编译器 |
|
||||
| `CXX` | Alpine: `g++`, Other: `$GNU_ARCH-linux-musl-g++` | C++ 编译器 |
|
||||
| `AR` | Alpine: `ar`, Other: `$GNU_ARCH-linux-musl-ar` | 静态库工具 |
|
||||
| `LD` | `ld.gold` | 链接器 |
|
||||
| `PATH` | `/usr/local/musl/bin:/usr/local/musl/$GNU_ARCH-linux-musl/bin:$PATH` | 系统 PATH |
|
||||
| `SPC_DEFAULT_C_FLAGS` | empty | 默认 C 编译标志 |
|
||||
| `SPC_DEFAULT_CXX_FLAGS` | empty | 默认 C++ 编译标志 |
|
||||
| `SPC_CMD_PREFIX_PHP_BUILDCONF` | `./buildconf --force` | 编译 PHP `buildconf` 命令前缀 |
|
||||
| `SPC_CMD_PREFIX_PHP_CONFIGURE` | `LD_LIBRARY_PATH={ld_lib_path} ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg` | 编译 PHP `configure` 命令前缀 |
|
||||
| `SPC_CMD_PREFIX_PHP_MAKE` | `make -j$SPC_CONCURRENCY` | 编译 PHP `make` 命令前缀 |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS` | `$SPC_DEFAULT_C_FLAGS` | PHP `configure` 命令的 `CFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS` | `-I$BUILD_INCLUDE_PATH` | PHP `configure` 命令的 `CPPFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS` | `-L$BUILD_LIB_PATH` | PHP `configure` 命令的 `LDFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_CONFIGURE_LIBS` | `-ldl -lpthread` | PHP `configure` 命令的 `LIBS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS` | `-g0 -Os -fno-ident -fPIE` 或 `-g -O0 -fno-ident -fPIE`(当使用 `--no-strip` 时为后者) | PHP `make` 命令的 `EXTRA_CFLAGS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS` | empty | PHP `make` 命令的额外 `EXTRA_LIBS` 变量 |
|
||||
| `SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM` | `-all-static`(当使用 `clang` 时:`-Xcompiler -fuse-ld=lld -all-static`) | `make` 命令的额外 `LDFLAGS` 变量(用于编译程序) |
|
||||
| `SPC_NO_MUSL_PATH` | empty | 是否不插入 musl 工具链的 PATH(值为 `yes` 时不插入) |
|
||||
> `{ld_lib_path}` 值为 `/usr/local/musl/$GNU_ARCH-linux-musl/lib`。
|
||||
|
||||
### FreeBSD
|
||||
|
||||
因 FreeBSD 系统的用户较少,我们暂时不提供 FreeBSD 系统的环境变量。
|
||||
|
||||
### Unix
|
||||
|
||||
对于 macOS、Linux、FreeBSD 等 Unix 系统,以下环境变量是通用的。
|
||||
|
||||
| var name | default value | comment |
|
||||
|-------------------|------------------------------|------------------|
|
||||
| `PATH` | `$BUILD_BIN_PATH:$PATH` | 系统 PATH |
|
||||
| `PKG_CONFIG_PATH` | `$BUILD_LIB_PATH/pkgconfig` | pkg-config 的搜索路径 |
|
||||
| `PKG_CONFIG` | `$BUILD_BIN_PATH/pkg-config` | pkg-config 命令路径 |
|
||||
|
||||
## 编译依赖库的环境变量(仅限 Unix 系统)
|
||||
|
||||
@@ -83,7 +138,6 @@ openssl_CFLAGS="-O0"
|
||||
| `ldap_LDFLAGS` | `-L$BUILD_LIB_PATH` |
|
||||
| `openssl_CFLAGS` | Linux: `$SPC_DEFAULT_C_FLAGS`, Other: empty |
|
||||
| others... | empty |
|
||||
|
||||
:::
|
||||
|
||||
下表是支持自定义以上三种变量的依赖库名称列表:
|
||||
@@ -107,6 +161,5 @@ openssl_CFLAGS="-O0"
|
||||
::: tip
|
||||
因为给每个库适配自定义环境变量是一项特别繁琐的工作,且大部分情况下你都不需要这些库的自定义环境变量,所以我们目前只支持了部分库的自定义环境变量。
|
||||
|
||||
如果你需要自定义环境变量的库不在上方列表,可以通过 [GitHub Issue](https://github.com/crazywhalecc/static-php-cli/issues)
|
||||
来提出需求。
|
||||
如果你需要自定义环境变量的库不在上方列表,可以通过 [GitHub Issue](https://github.com/crazywhalecc/static-php-cli/issues) 来提出需求。
|
||||
:::
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
## curl
|
||||
|
||||
HTTP3 支持默认未启用,需在编译时添加 `--with-libs="nghttp2,nghttp3,ngtcp2"` 以启用 PHP 8.4 及以上版本的 HTTP3 支持。
|
||||
|
||||
使用 curl 请求 HTTPS 时,可能存在 `error:80000002:system library::No such file or directory` 错误,
|
||||
解决办法详见 [FAQ - 无法使用 ssl](../faq/#无法使用-ssl)。
|
||||
|
||||
@@ -43,27 +41,15 @@ swoole-hook-sqlite 不是一个扩展,而是 Swoole 的 Hook 特性。
|
||||
swoole-hook-sqlite 与 `pdo_sqlite` 扩展冲突。如需使用 Swoole 和 `pdo_sqlite`,请删除 pdo_sqlite 扩展,启用 `swoole` 和 `swoole-hook-sqlite` 即可。
|
||||
该扩展包含了 `pdo_sqlite` 的协程环境的实现。
|
||||
|
||||
## swoole-hook-odbc
|
||||
|
||||
swoole-hook-odbc 不是一个扩展,而是 Swoole 的 Hook 特性。
|
||||
如果你在编译时添加了 `swoole,swoole-hook-odbc`,你将启用 Swoole 的 `odbc` 扩展的协程模式。
|
||||
|
||||
swoole-hook-odbc 与 `pdo_odbc` 扩展冲突。如需使用 Swoole 和 `pdo_odbc`,请删除 `pdo_odbc` 扩展,启用 `swoole` 和 `swoole-hook-odbc` 即可。
|
||||
该扩展包含了 `pdo_odbc` 的协程环境的实现。
|
||||
|
||||
## swow
|
||||
|
||||
1. swow 仅支持 PHP 8.0+ 版本。
|
||||
|
||||
## imagick
|
||||
|
||||
1. OpenMP 支持已被禁用,这是维护者推荐的做法,系统软件包也是如此配置。
|
||||
1. swow 仅支持 PHP >= 8.0 版本。
|
||||
|
||||
## imap
|
||||
|
||||
1. 该扩展目前不支持 Kerberos。
|
||||
2. 由于底层的 c-client、ext-imap 不是线程安全的。 无法在 `--enable-zts` 构建中使用它。
|
||||
3. 该扩展已在 PHP 8.4 中被移除,因此我们建议您寻找替代实现,例如 [Webklex/php-imap](https://github.com/Webklex/php-imap)。
|
||||
3. 由于该扩展可能会从未来的 PHP 中删除,因此我们建议您寻找替代实现,例如 [Webklex/php-imap](https://github.com/Webklex/php-imap)。
|
||||
|
||||
## gd
|
||||
|
||||
@@ -84,9 +70,9 @@ bin/spc build gd --with-libs=freetype,libjpeg,libavif,libwebp --build-cli
|
||||
|
||||
## xdebug
|
||||
|
||||
1. Xdebug 只能作为共享扩展进行构建。您需要使用除了 `musl-static` 外的其他 `SPC_TARGET` 构建目标。
|
||||
2. 使用 Linux/glibc 或 macOS 时,您可以使用 `--build-shared=xdebug` 将 Xdebug 编译为共享扩展。
|
||||
编译后的 `./php` 二进制文件可以通过指定 INI 文件进行配置和运行,例如 `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`。
|
||||
1. Xdebug 是一个 Zend 扩展,Xdebug 的功能依赖于 PHP 的 Zend 引擎和底层代码,如果要将其静态编译到 PHP 中,可能需要巨量的 patch 代码,这是不可行的。
|
||||
2. macOS 平台可以通过在相同平台编译的 PHP 下编译一个 xdebug 扩展,并提取其中的 `xdebug.so` 文件,再在 static-php-cli 中使用 `--no-strip` 参数保留调试符号表,同时加入 `ffi` 扩展。
|
||||
编译的 `./php` 二进制可以通过指定 INI 配置并运行,例如`./php -d 'zend_extension=xdebug.so' your-code.php`。
|
||||
|
||||
## xml
|
||||
|
||||
@@ -122,15 +108,14 @@ pgsql 16.2 修复了这个 Bug,现在正常工作了。
|
||||
|
||||
## password-argon2
|
||||
|
||||
1. password-argon2不是一个标准的扩展。`password_hash` 函数的 `PASSWORD_ARGON2ID` 算法需要 libsodium 或 libargon2 才能工作。
|
||||
2. 使用 password-argon2 可以为此启用多线程支持。
|
||||
1. password-argon2不是一个标准的扩展,它是 `password_hash` 函数的额外算法。
|
||||
2. 在Linux系统,password-argon2 的依赖库 `libargon2` 与 `libsodium` 库冲突。
|
||||
|
||||
## ffi
|
||||
|
||||
1. 由于 musl libc 静态链接的限制,无法加载动态库,因此无法使用 ffi。
|
||||
如果您需要使用 ffi 扩展,请参阅 [使用 GNU libc 编译 PHP](./build-with-glibc)。
|
||||
2. macOS 支持 ffi 扩展,但某些内核不包含调试符号时会出现错误。
|
||||
3. Windows x64 支持 ffi 扩展。
|
||||
1. 因为 Linux 系统的限制,虽然可以成功编译 ffi 扩展,但无法使用它加载其他 `so` 扩展。Linux 支持加载 so 扩展的前提是非静态编译,但动态编译和本项目的目的冲突。
|
||||
2. macOS 支持 ffi 扩展,但是部分内核下不包含调试符号时会出现错误。
|
||||
3. Windows 支持 ffi 扩展。
|
||||
|
||||
## xhprof
|
||||
|
||||
@@ -147,12 +132,7 @@ event 扩展在 macOS 系统下编译后暂无法使用 `openpty` 特性。相
|
||||
|
||||
parallel 扩展只支持 PHP 8.0 及以上版本,并只支持 ZTS 构建(`--enable-zts`)。
|
||||
|
||||
## spx
|
||||
# spx
|
||||
|
||||
1. SPX 目前不支持 Windows,且官方仓库也不支持静态编译,static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。
|
||||
|
||||
## mimalloc
|
||||
|
||||
1. 从技术上讲,这不是扩展,而是一个库。
|
||||
2. 在 Linux 或 macOS 上使用 `--with-libs="mimalloc"` 进行构建将覆盖默认分配器。
|
||||
3. 目前,这还处于实验阶段,但建议在线程环境中使用。
|
||||
1. [SPX 扩展](https://github.com/NoiseByNorthwest/php-spx) 只支持非线程模式。
|
||||
2. SPX 目前不支持 Windows,且官方仓库也不支持静态编译,static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
<script setup>
|
||||
import SearchTable from "../../.vitepress/components/SearchTable.vue";
|
||||
</script>
|
||||
|
||||
# 扩展列表
|
||||
|
||||
> - `yes`: 已支持
|
||||
@@ -9,8 +5,7 @@ import SearchTable from "../../.vitepress/components/SearchTable.vue";
|
||||
> - `no` with issue link: 确定不支持或无法支持
|
||||
> - `partial` with issue link: 已支持,但是无法完美工作
|
||||
|
||||
|
||||
<search-table />
|
||||
<!--@include: ../../extensions.md-->
|
||||
|
||||
::: tip
|
||||
如果缺少您需要的扩展,您可以创建 [功能请求](https://github.com/crazywhalecc/static-php-cli/issues)。
|
||||
@@ -18,5 +13,12 @@ import SearchTable from "../../.vitepress/components/SearchTable.vue";
|
||||
有些扩展或扩展依赖的库会有一些可选的特性,例如 gd 库可选支持 libwebp、freetype 等。
|
||||
如果你只使用 `bin/spc build gd --build-cli` 是不会包含它们(static-php-cli 默认为最小依赖原则)。
|
||||
|
||||
有关编译可选库,请参考 [扩展、库的依赖关系图表](./deps-map)。对于可选的库,你也可以从 [编译命令生成器](./cli-generator) 中选择扩展后展开选择可选库。
|
||||
你可以在编译时使用 `--with-libs=` 加入这些库,当本次编译的依赖库中包含它们,gd 会自动依赖它们启用这些特性。
|
||||
(如:`bin/spc build gd --with-libs=libwebp,freetype --build-cli`)
|
||||
|
||||
或者你也可以使用 `--with-suggested-exts` 和 `--with-suggested-libs` 启用这些扩展和库所有可选的依赖。
|
||||
(如:`bin/spc build gd --with-suggested-libs --build-cli`)
|
||||
|
||||
如果你不知道某个扩展是否有可选特性,可以通过查看 [spc 配置文件](https://github.com/crazywhalecc/static-php-cli/tree/main/config)
|
||||
或使用命令 `bin/spc dev:extensions` 查看(库依赖为 `lib-suggests`,扩展依赖为 `ext-suggests`)。
|
||||
:::
|
||||
|
||||
@@ -4,8 +4,8 @@ static-php-cli 是一个用于构建静态编译的 PHP 二进制的工具,目
|
||||
|
||||
在指南章节中,你将了解到如何使用 static-php-cli 构建独立的 php 程序。
|
||||
|
||||
- [本地构建](./manual-build)
|
||||
- [Action 构建](./action-build)
|
||||
- [本地构建](./manual-build)
|
||||
- [扩展列表](./extensions)
|
||||
|
||||
## 编译环境
|
||||
@@ -19,30 +19,16 @@ static-php-cli 是一个用于构建静态编译的 PHP 二进制的工具,目
|
||||
| Windows | :gear: :computer: | |
|
||||
| FreeBSD | :computer: | :computer: |
|
||||
|
||||
当前支持编译的 PHP 版本:
|
||||
其中,Linux 目前仅在 Ubuntu、Debian、Alpine 发行版测试通过,其他发行版未进行测试,不能保证编译成功。
|
||||
对于未经过测试的发行版,可以使用 Docker 等方式本地编译,避免环境导致的问题。
|
||||
|
||||
> :warning: 部分支持,对于新的测试版和旧版本可能存在问题。
|
||||
>
|
||||
> :heavy_check_mark: 支持
|
||||
>
|
||||
> :x: 不支持
|
||||
macOS 下支持 x86_64 和 Arm 两种架构,但在其中一个架构上编译的二进制无法直接在另一个架构上使用。
|
||||
Rosetta 2 不能保证 Arm 架构编译的程序可以完全运行在 x86_64 环境下。
|
||||
|
||||
| PHP Version | Status | Comment |
|
||||
|-------------|--------------------|---------------------------------------------------------|
|
||||
| 7.2 | :x: | |
|
||||
| 7.3 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 7.4 | :x: | phpmicro 和许多扩展不支持 7.3、7.4 版本 |
|
||||
| 8.0 | :warning: | PHP 官方已停止 8.0 的维护,我们不再处理 8.0 相关的 backport 支持 |
|
||||
| 8.1 | :warning: | PHP 官方仅对 8.1 提供安全更新,在 8.5 发布后我们不再处理 8.1 相关的 backport 支持 |
|
||||
| 8.2 | :heavy_check_mark: | |
|
||||
| 8.3 | :heavy_check_mark: | |
|
||||
| 8.4 | :heavy_check_mark: | |
|
||||
| 8.5 (beta) | :warning: | PHP 8.5 目前处于 beta 阶段 |
|
||||
|
||||
> 这个表格的支持状态是 static-php-cli 对构建对应版本的支持情况,不是 PHP 官方对该版本的支持情况。
|
||||
Windows 目前只支持 x86_64 架构,不支持 32 位 x86、不支持 arm64 架构。
|
||||
|
||||
## PHP 支持版本
|
||||
|
||||
目前,static-php-cli 对 PHP 8.2 ~ 8.5 版本是支持的,对于 PHP 8.1 及更早版本理论上支持,只需下载时选择早期版本即可。
|
||||
目前,static-php-cli 对 PHP 7.4 ~ 8.3 版本是支持的,对于 PHP 7.4 及更早版本理论上支持,只需下载时选择早期版本即可。
|
||||
但由于部分扩展和特殊组件已对早期版本的 PHP 停止了支持,所以 static-php-cli 不会明确支持早期版本。
|
||||
我们推荐你编译尽可能新的 PHP 版本,以获得更好的体验。
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
---
|
||||
outline: 'deep'
|
||||
---
|
||||
|
||||
# 本地构建(Linux、macOS、FreeBSD)
|
||||
|
||||
本章节为 Linux、macOS、FreeBSD 的构建过程,如果你要在 Windows 上构建,请到 [在 Windows 上构建](./build-on-windows)。
|
||||
@@ -15,15 +11,15 @@ outline: 'deep'
|
||||
```bash
|
||||
# Download from self-hosted nightly builds (sync with main branch)
|
||||
# For Linux x86_64
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-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 -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-aarch64
|
||||
# macOS x86_64 (Intel)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-x86_64
|
||||
# macOS aarch64 (Apple)
|
||||
curl -fsSL -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-macos-aarch64
|
||||
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 -fsSL -o spc.exe https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-windows-x64.exe
|
||||
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
|
||||
@@ -54,28 +50,28 @@ cd static-php-cli
|
||||
composer update
|
||||
```
|
||||
|
||||
### 使用预编译静态 PHP 二进制运行 static-php-cli
|
||||
### 使用系统 PHP 环境
|
||||
|
||||
如果你不想使用 Docker、在系统内安装 PHP,可以直接下载本项目自身编译好的 php 二进制 cli 程序。使用流程如下:
|
||||
|
||||
使用命令部署环境,此脚本会从 [自托管的服务器](https://dl.static-php.dev/static-php-cli/) 下载一个当前操作系统的 php-cli 包,
|
||||
并从 [getcomposer](https://getcomposer.org/download/latest-stable/composer.phar) 或 [Aliyun(镜像)](https://mirrors.aliyun.com/composer/composer.phar) 下载 Composer。
|
||||
|
||||
::: tip
|
||||
使用预编译静态 PHP 二进制目前仅支持 Linux 和 macOS。FreeBSD 环境因为缺少自动化构建环境,所以暂不支持。
|
||||
:::
|
||||
下面是系统安装 PHP、Composer 的一些示例命令。具体安装方式建议自行搜索或询问 AI 搜索引擎获取答案,这里不多赘述。
|
||||
|
||||
```bash
|
||||
bin/setup-runtime
|
||||
# [macOS], 需要先安装 Homebrew. See https://brew.sh/
|
||||
# Remember change your composer executable path. For M1/M2 Chip mac, "/opt/homebrew/bin/", for Intel mac, "/usr/local/bin/". Or add it to your own path.
|
||||
brew install php wget
|
||||
wget https://getcomposer.org/download/latest-stable/composer.phar -O /path/to/your/bin/composer && chmod +x /path/to/your/bin/composer
|
||||
|
||||
# 对于中国大陆地区等网络环境特殊的用户,可使用镜像站加快下载速度
|
||||
bin/setup-runtime --mirror china
|
||||
# [Debian], you need to make sure your php version >= 8.1 and composer >= 2.0
|
||||
sudo apt install php-cli composer php-tokenizer
|
||||
|
||||
# [Alpine]
|
||||
apk add bash file wget xz php81 php81-common php81-pcntl php81-tokenizer php81-phar php81-posix php81-xml composer
|
||||
```
|
||||
|
||||
此脚本总共会下载两个文件:`bin/php` 和 `bin/composer`,下载完成后,有两种使用方式:
|
||||
::: tip
|
||||
目前 Ubuntu 部分版本的 apt 安装的 php 版本较旧,故不提供安装命令。如有需要,建议先添加 ppa 等软件源后,安装最新版的 PHP 以及 tokenizer、xml、phar 扩展。
|
||||
|
||||
1. 将 `bin/` 目录添加到 PATH 路径中:`export PATH="/path/to/your/static-php-cli/bin:$PATH"`,添加路径后,相当于系统安装了 PHP,可直接使用 `composer`、`php -v` 等命令,也可以直接使用 `bin/spc`。
|
||||
2. 直接调用,比如执行 static-php-cli 命令:`bin/php bin/spc --help`,执行 Composer:`bin/php bin/composer update`。
|
||||
较老版本的 Debian 默认安装的可能为旧版本(<= 7.4)版本的 PHP,建议先升级 Debian。
|
||||
:::
|
||||
|
||||
### 使用 Docker 环境
|
||||
|
||||
@@ -96,66 +92,30 @@ bin/spc-alpine-docker
|
||||
export SPC_USE_SUDO=yes
|
||||
```
|
||||
|
||||
### 使用系统 PHP 环境
|
||||
### 使用预编译静态 PHP 二进制
|
||||
|
||||
下面是系统安装 PHP、Composer 的一些示例命令。具体安装方式建议自行搜索或询问 AI 搜索引擎获取答案,这里不多赘述。
|
||||
如果你不想使用 Docker、在系统内安装 PHP,可以直接下载本项目自身编译好的 php 二进制 cli 程序。使用流程如下:
|
||||
|
||||
```bash
|
||||
# [macOS], 需要先安装 Homebrew. See https://brew.sh/
|
||||
# Remember change your composer executable path. For M1/M2 Chip mac, "/opt/homebrew/bin/", for Intel mac, "/usr/local/bin/". Or add it to your own path.
|
||||
brew install php wget
|
||||
wget https://getcomposer.org/download/latest-stable/composer.phar -O /path/to/your/bin/composer && chmod +x /path/to/your/bin/composer
|
||||
使用命令部署环境,此脚本会从 [自托管的服务器](https://dl.static-php.dev/static-php-cli/) 下载一个当前操作系统的 php-cli 包,
|
||||
并从 [getcomposer](https://getcomposer.org/download/latest-stable/composer.phar) 或 [Aliyun(镜像)](https://mirrors.aliyun.com/composer/composer.phar) 下载 Composer。
|
||||
|
||||
# [Debian], you need to make sure your php version >= 8.4 and composer >= 2.0
|
||||
sudo apt install php-cli composer php-tokenizer
|
||||
```
|
||||
|
||||
::: tip
|
||||
目前 Ubuntu 部分版本的 apt 安装的 php 版本较旧,故不提供安装命令。如有需要,建议先添加 ppa 等软件源后,安装最新版的 PHP 以及 tokenizer、xml、phar 扩展。
|
||||
|
||||
较老版本的 Debian 默认安装的可能为旧版本(<= 8.3)版本的 PHP,建议先升级 Debian 或使用 Docker 或自带的静态二进制环境。
|
||||
::: tip
|
||||
使用预编译静态 PHP 二进制目前仅支持 Linux 和 macOS。FreeBSD 环境因为缺少自动化构建环境,所以暂不支持。
|
||||
:::
|
||||
|
||||
## 使用 craft 构建(推荐)
|
||||
|
||||
使用 `bin/spc craft` 可以使用一个配置文件,一个命令实现自动检查环境、下载源代码、构建依赖库、构建 PHP 及扩展等。
|
||||
|
||||
你需要编写一个 `craft.yml` 文件,存放在当前工作目录下。`craft.yml` 可以由 [命令生成器](./cli-generator) 生成,或者手动编写。
|
||||
|
||||
手动编写可参考 [craft.yml 配置](../develop/craft-yml.md) 中的注释来编写。我们下面假设你编译一个扩展组合,并选用 PHP 8.4,输出 `cli` 和 `fpm`:
|
||||
|
||||
```yaml
|
||||
# path/to/craft.yml
|
||||
php-version: 8.4
|
||||
extensions: bcmath,posix,phar,zlib,openssl,curl,fileinfo,tokenizer
|
||||
sapi:
|
||||
- cli
|
||||
- fpm
|
||||
```
|
||||
|
||||
然后使用 `bin/spc craft` 命令来编译:
|
||||
|
||||
```bash
|
||||
bin/spc craft --debug
|
||||
bin/setup-runtime
|
||||
|
||||
# 对于中国大陆地区等网络环境特殊的用户,可使用镜像站加快下载速度
|
||||
bin/setup-runtime --mirror china
|
||||
```
|
||||
|
||||
如果构建成功,你会在当前目录下看到 `buildroot/bin` 目录,里面包含了编译好的 PHP 二进制文件,或相应的 SAPI。
|
||||
此脚本总共会下载两个文件:`bin/php` 和 `bin/composer`,下载完成后,有两种使用方式:
|
||||
|
||||
- cli: Windows 下构建结果为 `buildroot/bin/php.exe`,其他平台为 `buildroot/bin/php`。
|
||||
- fpm: 构建结果为 `buildroot/bin/php-fpm`。
|
||||
- micro: 构建结果为 `buildroot/bin/micro.sfx`,如需进一步与 PHP 代码打包,请查看 [打包 micro 二进制](./manual-build#命令-micro-combine-打包-micro-二进制)。
|
||||
- embed: 参见 [embed 使用](./manual-build#embed-使用)。
|
||||
- frankenphp: 构建结果为 `buildroot/bin/frankenphp`。
|
||||
1. 将 `bin/` 目录添加到 PATH 路径中:`export PATH="/path/to/your/static-php-cli/bin:$PATH"`,添加路径后,相当于系统安装了 PHP,可直接使用 `composer`、`php -v` 等命令,也可以直接使用 `bin/spc`。
|
||||
2. 直接调用,比如执行 static-php-cli 命令:`bin/php bin/spc --help`,执行 Composer:`bin/php bin/composer update`。
|
||||
|
||||
如果中途构建出错,你可以使用 `--debug` 参数查看详细的错误信息,或者使用 `--with-clean` 参数清除旧的编译结果,重新编译。
|
||||
|
||||
如使用以上方式仍构建失败,请提交一个 issue,附上你的 `craft.yml` 文件、`log/` 目录的压缩包。
|
||||
|
||||
## 分步构建命令
|
||||
|
||||
如果你有定制化需求,或分开下载、编译 PHP 和依赖库的需求,可以使用 `bin/spc` 命令分步执行。
|
||||
|
||||
### 命令 download - 下载依赖包
|
||||
## 命令 download - 下载依赖包
|
||||
|
||||
使用命令 `bin/spc download` 可以下载编译需要的源代码,包括 php-src 以及依赖的各种库的源码。
|
||||
|
||||
@@ -172,17 +132,14 @@ bin/spc download --for-libs=liblz4,libevent --for-extensions=pcntl,rar,xml
|
||||
# 仅下载要编译的库(包括其依赖,使用库名,不包含可选库)
|
||||
bin/spc download --for-libs=liblz4,libevent --without-suggestions
|
||||
|
||||
# 下载资源时,忽略部分资源的缓存,强制下载(如切换特定 PHP 版本)
|
||||
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3.10
|
||||
|
||||
# 下载资源时,优先下载有预编译包的依赖库(减少编译依赖的时间)
|
||||
bin/spc download --for-extensions="curl,pcntl,xml,mbstring" --prefer-pre-built
|
||||
# 下载资源时,忽略部分资源的缓存,强制下载(如切换 PHP 版本)
|
||||
bin/spc download --for-extensions=curl,pcntl,xml --ignore-cache-sources=php-src --with-php=8.3
|
||||
|
||||
# 下载所有依赖包
|
||||
bin/spc download --all
|
||||
|
||||
# 下载所有依赖包,并指定下载的 PHP 主版本,可选:8.1,8.2,8.3,8.4,也可以使用特定的版本,如 8.3.10。
|
||||
bin/spc download --all --with-php=8.3
|
||||
# 下载所有依赖包,并指定下载的 PHP 主版本,可选:7.3,7.4,8.0,8.1,8.2,8.3。
|
||||
bin/spc download --all --with-php=8.2
|
||||
|
||||
# 下载时显示下载进度条(curl)
|
||||
bin/spc download --all --debug
|
||||
@@ -209,25 +166,14 @@ bin/spc download --from-zip=/path/to/your/download.zip
|
||||
让下载器强制使用你指定的链接下载此 source 的包。使用方法为 `{source-name}:{url}` 即可,可同时重写多个库的下载地址。在使用 `--for-extensions` 选项下载时同样可用。
|
||||
|
||||
```bash
|
||||
# 例如:指定下载 Alpha 版的 PHP8.5
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~edorian/php-8.5.0alpha2.tar.xz"
|
||||
# 例如:指定下载测试版的 PHP8.3
|
||||
bin/spc download --all -U "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"
|
||||
|
||||
# 指定下载旧版本的 curl 库
|
||||
bin/spc download --all -U "curl:https://curl.se/download/curl-7.88.1.tar.gz"
|
||||
```
|
||||
|
||||
如果你下载的资源不是链接,而是一个 Git 仓库,你可以使用 `-G` 或 `--custom-git` 重写下载链接,让下载器强制使用你指定的 Git 仓库下载此 source 的包。
|
||||
使用方法为 `{source-name}:{branch}:{url}` 即可,可同时重写多个库的下载地址。在使用 `--for-extensions` 选项下载时同样可用。
|
||||
|
||||
```bash
|
||||
# 例如:下载 master 分支的 php-src
|
||||
bin/spc download --for-extensions=redis,phar -G "php-src:master:https://github.com/php/php-src.git"
|
||||
|
||||
# 从 swoole-src 仓库下载 master 分支的最新代码,而不是发行版
|
||||
bin/spc download --for-extensions=swoole -G "swoole:master:https://github.com/swoole/swoole-src.git"
|
||||
```
|
||||
|
||||
### 命令 doctor - 环境检查
|
||||
## 命令 doctor - 环境检查
|
||||
|
||||
如果你可以正常运行 `bin/spc` 但无法正常编译静态的 PHP 或依赖库,可以先运行 `bin/spc doctor` 检查系统自身是否缺少依赖。
|
||||
|
||||
@@ -239,20 +185,18 @@ bin/spc doctor
|
||||
bin/spc doctor --auto-fix
|
||||
```
|
||||
|
||||
### 命令 build - 编译 PHP
|
||||
## 命令 build - 编译 PHP
|
||||
|
||||
使用 build 命令可以开始构建静态 php 二进制,在执行 `bin/spc build` 命令前,务必先使用 `download` 命令下载资源,建议使用 `doctor` 检查环境。
|
||||
|
||||
#### 基本用法
|
||||
### 基本用法
|
||||
|
||||
你需要先到 [扩展列表](./extensions) 或 [命令生成器](./cli-generator) 选择你要加入的扩展,然后使用命令 `bin/spc build` 进行编译。你需要指定一个编译目标,从如下参数中选择:
|
||||
|
||||
- `--build-cli`: 构建一个 cli sapi(命令行界面,可在命令行执行 PHP 代码)
|
||||
- `--build-fpm`: 构建一个 fpm sapi(php-fpm,用于和其他传统的 fpm 架构的软件如 nginx 配合使用)
|
||||
- `--build-cgi`: 构建一个 cgi sapi(cgi,可用于传统的 cgi 架构的软件如 apache 配合使用)
|
||||
- `--build-micro`: 构建一个 micro sapi(用于构建一个包含 PHP 代码的独立可执行二进制)
|
||||
- `--build-embed`: 构建一个 embed sapi(用于嵌入到其他 C 语言程序中)
|
||||
- `--build-frankenphp`: 构建一个 [frankenphp](https://github.com/php/frankenphp) 二进制
|
||||
- `--build-all`: 构建以上所有 sapi
|
||||
|
||||
```bash
|
||||
@@ -278,18 +222,26 @@ bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
如果你想构建多个版本的 PHP,且不想每次都重复构建其他依赖库,可以使用 `switch-php-version` 在编译好一个版本后快速切换至另一个版本并编译:
|
||||
|
||||
```shell
|
||||
# switch to 8.4
|
||||
bin/spc switch-php-version 8.4
|
||||
# switch to 8.3
|
||||
bin/spc switch-php-version 8.3
|
||||
# build
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
# switch to 8.1
|
||||
bin/spc switch-php-version 8.1
|
||||
# switch to 8.0
|
||||
bin/spc switch-php-version 8.0
|
||||
# build
|
||||
bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
```
|
||||
:::
|
||||
|
||||
#### 编译运行选项
|
||||
### 调试
|
||||
|
||||
如果你在编译过程中遇到了问题,或者想查看每个执行的 shell 命令,可以使用 `--debug` 开启 debug 模式,查看所有终端日志:
|
||||
|
||||
```bash
|
||||
bin/spc build mysqlnd,pdo_mysql --build-all --debug
|
||||
```
|
||||
|
||||
### 编译运行选项
|
||||
|
||||
在编译过程中,有些特殊情况需要对编译器、编译目录的内容进行干预,可以尝试使用以下命令:
|
||||
|
||||
@@ -297,10 +249,8 @@ bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
- `--cxx=XXX`: 指定 C++ 语言编译器的执行命令(Linux 默认 `g++`,macOS 默认 `clang++`)
|
||||
- `--with-clean`: 编译 PHP 前先清理旧的 make 产生的文件
|
||||
- `--enable-zts`: 让编译的 PHP 为线程安全版本(默认为 NTS 版本)
|
||||
- `--no-strip`: 编译 PHP 库后不运行 `strip` 裁剪二进制文件缩小体积
|
||||
- `--no-strip`: 编译 PHP 库后不运行 `strip` 裁剪二进制文件缩小体积(不裁剪的 macOS 二进制文件可使用动态链接的第三方扩展)
|
||||
- `--with-libs=XXX,YYY`: 编译 PHP 前先编译指定的依赖库,激活部分扩展的可选功能(例如 gd 库的 libavif 等)
|
||||
- `--with-config-file-path=XXX`: 查找 `php.ini` 的路径(在 [这里](../faq/index.html#php-ini-的路径是什么) 查看默认路径)
|
||||
- `--with-config-file-scan-dir=XXX`: 读取 `php.ini` 后扫描 `.ini` 文件的目录(在 [这里](../faq/index.html#php-ini-的路径是什么) 查看默认路径)
|
||||
- `-I xxx=yyy`: 编译前将 INI 选项硬编译到 PHP 内(支持多个选项,别名是 `--with-hardcoded-ini`)
|
||||
- `--with-micro-fake-cli`: 在编译 micro 时,让 micro 的 SAPI 伪装为 `cli`(用于兼容一些检查 `PHP_SAPI` 的程序)
|
||||
- `--disable-opcache-jit`: 禁用 opcache jit(默认启用)
|
||||
@@ -309,7 +259,6 @@ bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
- `--with-suggested-exts`: 编译时将 `ext-suggests` 也作为编译依赖加入
|
||||
- `--with-suggested-libs`: 编译时将 `lib-suggests` 也作为编译依赖加入
|
||||
- `--with-upx-pack`: 编译后使用 UPX 减小二进制文件体积(需先使用 `bin/spc install-pkg upx` 安装 upx)
|
||||
- `--build-shared=XXX,YYY`: 编译时将指定的扩展编译为共享库(默认编译为静态库)
|
||||
|
||||
硬编码 INI 选项适用于 cli、micro、embed。有关硬编码 INI 选项,下面是一个简单的例子,我们预设一个更大的 `memory_limit`,并且禁用 `system` 函数:
|
||||
|
||||
@@ -377,14 +326,6 @@ memory_limit=1G
|
||||
|
||||
如果要打包 phar,只需要将 `a.php` 替换为打包好的 phar 文件即可。但要注意,phar 下的 micro.sfx 需要额外注意路径问题,见 [Developing - Phar 路径问题](../develop/structure#phar-应用目录问题)
|
||||
|
||||
## 调试
|
||||
|
||||
如果你在编译过程中遇到了问题,或者想查看每个执行的 shell 命令,可以使用 `--debug` 开启 debug 模式,查看所有终端日志:
|
||||
|
||||
```bash
|
||||
bin/spc build mysqlnd,pdo_mysql --build-all --debug
|
||||
```
|
||||
|
||||
## 命令 extract - 手动解压某个库
|
||||
|
||||
使用命令 `bin/spc extract` 可以解包和拷贝编译需要的源代码,包括 php-src 以及依赖的各种库的源码(需要自己指定要解包的库名)。
|
||||
@@ -396,32 +337,6 @@ bin/spc build mysqlnd,pdo_mysql --build-all --debug
|
||||
bin/spc extract php-src,libxml2
|
||||
```
|
||||
|
||||
## 命令 dump-extensions - 导出项目扩展依赖
|
||||
|
||||
使用命令 `bin/spc dump-extensions` 可以导出当前项目的扩展依赖。
|
||||
|
||||
```bash
|
||||
# 打印项目的扩展列表,传入项目包含composer.json的根目录
|
||||
bin/spc dump-extensions /path/to/your/project/
|
||||
|
||||
# 打印项目的扩展列表,不包含开发依赖
|
||||
bin/spc dump-extensions /path-to/tour/project/ --no-dev
|
||||
|
||||
# 输出为 spc 命令可接受的扩展列表格式(逗号分割)
|
||||
bin/spc dump-extensions /path-to/tour/project/ --format=text
|
||||
|
||||
# 输出为 JSON 列表
|
||||
bin/spc dump-extensions /path-to/tour/project/ --format=json
|
||||
|
||||
# 当项目没有任何扩展时,输出指定扩展组合,而不是返回失败
|
||||
bin/spc dump-extensions /path-to/your/project/ --no-ext-output=mbstring,posix,pcntl,phar
|
||||
|
||||
# 输出时不排除 spc 不支持的扩展
|
||||
bin/spc dump-extensions /path/to/your/project/ --no-spc-filter
|
||||
```
|
||||
|
||||
需要注意的是,项目的目录下必须包含 `vendor/installed.json` 和 `composer.lock` 文件,否则无法正常获取。
|
||||
|
||||
## 调试命令 dev - 调试命令集合
|
||||
|
||||
调试命令指的是你在使用 static-php-cli 构建 PHP 或改造、增强 static-php-cli 项目本身的时候,可以辅助输出一些信息的命令集合。
|
||||
@@ -431,8 +346,6 @@ bin/spc dump-extensions /path/to/your/project/ --no-spc-filter
|
||||
- `dev:sort-config`: 对 `config/` 目录下的配置文件的列表按照字母表排序
|
||||
- `dev:lib-ver <lib-name>`: 从依赖库的源码中读取版本(仅特定依赖库可用)
|
||||
- `dev:ext-ver <ext-name>`: 从扩展的源码中读取对应版本(仅特定扩展可用)
|
||||
- `dev:pack-lib <lib-name>`: 打包指定的依赖库(仅发布者可用)
|
||||
- `dev:gen-ext-docs`: 生成扩展文档(仅发布者可用)
|
||||
|
||||
```bash
|
||||
# 输出所有扩展
|
||||
@@ -460,8 +373,6 @@ bin/spc dev:sort-config ext
|
||||
下面是安装工具的示例:
|
||||
|
||||
- 下载安装 UPX(仅限 Linux 和 Windows): `bin/spc install-pkg upx`
|
||||
- 下载安装 nasm(仅限 Windows): `bin/spc install-pkg nasm`
|
||||
- 下载安装 go-xcaddy: `bin/spc install-pkg go-xcaddy`
|
||||
|
||||
## 命令 del-download - 删除已下载的资源
|
||||
|
||||
@@ -500,8 +411,6 @@ bin/spc dev:sort-config ext
|
||||
| after-exts-extract | 在要编译的扩展解压到 PHP 源码目录后触发 |
|
||||
| before-library[*name*]-build | 在名称为 `name` 的库编译前触发(如 `before-library[postgresql]-build`) |
|
||||
| after-library[*name*]-build | 在名称为 `name` 的库编译后触发 |
|
||||
| after-shared-ext[*name*]-build | 在名称为 `name` 的共享扩展编译后触发(如 `after-shared-ext[redis]-build`) |
|
||||
| before-shared-ext[*name*]-build | 在名称为 `name` 的共享扩展编译前触发 |
|
||||
| before-php-buildconf | 在编译 PHP 命令 `./buildconf` 前触发 |
|
||||
| before-php-configure | 在编译 PHP 命令 `./configure` 前触发 |
|
||||
| before-php-make | 在编译 PHP 命令 `make` 前触发 |
|
||||
@@ -557,84 +466,3 @@ memory_limit => 8G => 8G
|
||||
::: tip
|
||||
static-php-cli 开放的方法非常多,文档中无法一一列举,但只要是 `public function` 并且不被标注为 `@internal`,均可调用。
|
||||
:::
|
||||
|
||||
## 多次构建
|
||||
|
||||
如果你在本地要多次构建,以下方法可以为你节省下载资源、编译的时间。
|
||||
|
||||
- 仅切换 PHP 版本,不更换依赖库版本时,可以使用 `bin/spc switch-php-version` 快速切换 PHP 版本,然后重新运行同样的 `build` 命令。
|
||||
- 如果你想重新构建一次,但不重新下载源码,可以先 `rm -rf buildroot source` 删除编译目录和源码目录,然后重新构建。
|
||||
- 如果你想更新某个依赖的版本,可以使用 `bin/spc del-download <source-name>` 删除指定的源码,然后使用 `download <source-name>` 重新下载。
|
||||
- 如果你想更新所有依赖的版本,可以使用 `bin/spc download --clean` 删除所有下载的源码,然后重新下载。
|
||||
|
||||
## embed 使用
|
||||
|
||||
如果你想将 static-php 嵌入到其他 C 语言程序中,可以使用 `--build-embed` 构建一个 embed 版本的 PHP。
|
||||
|
||||
```bash
|
||||
bin/spc build {your extensions} --build-embed --debug
|
||||
```
|
||||
|
||||
在通常的情况下,PHP embed 编译后会生成 `php-config`。对于 static-php,我们提供了 `spc-config`,用于获取编译时的参数。
|
||||
另外,在使用 embed SAPI(libphp.a)时,你需要使用和编译 libphp 相同的编译器,否则会出现链接错误。
|
||||
|
||||
下面是 spc-config 的基本用法:
|
||||
|
||||
```bash
|
||||
# output all flags and options
|
||||
bin/spc spc-config curl,zlib,phar,openssl
|
||||
|
||||
# output libs
|
||||
bin/spc spc-config curl,zlib,phar,openssl --libs
|
||||
|
||||
# output includes
|
||||
bin/spc spc-config curl,zlib,phar,openssl --includes
|
||||
```
|
||||
|
||||
默认情况下,static-php 在不同系统使用的编译器分别是:
|
||||
|
||||
- macOS: `clang`
|
||||
- Linux (Alpine Linux): `gcc`
|
||||
- Linux (glibc based distros, x86_64): `/usr/local/musl/bin/x86_64-linux-musl-gcc`
|
||||
- Linux (glibc based distros, aarch64): `/usr/local/musl/bin/aarch64-linux-musl-gcc`
|
||||
- FreeBSD: `clang`
|
||||
|
||||
下面是一个使用 embed SAPI 的例子:
|
||||
|
||||
```c
|
||||
// embed.c
|
||||
#include <sapi/embed/php_embed.h>
|
||||
|
||||
int main(int argc,char **argv){
|
||||
|
||||
PHP_EMBED_START_BLOCK(argc,argv)
|
||||
|
||||
zend_file_handle file_handle;
|
||||
|
||||
zend_stream_init_filename(&file_handle,"embed.php");
|
||||
|
||||
if(php_execute_script(&file_handle) == FAILURE){
|
||||
php_printf("Failed to execute PHP script.\n");
|
||||
}
|
||||
|
||||
PHP_EMBED_END_BLOCK()
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
```php
|
||||
<?php
|
||||
// embed.php
|
||||
echo "Hello world!\n";
|
||||
```
|
||||
|
||||
```bash
|
||||
# compile in debian/ubuntu x86_64
|
||||
/usr/local/musl/bin/x86_64-linux-musl-gcc embed.c $(bin/spc spc-config bcmath,zlib) -static -o embed
|
||||
# compile in macOS/FreeBSD
|
||||
clang embed.c $(bin/spc spc-config bcmath,zlib) -o embed
|
||||
|
||||
./embed
|
||||
# out: Hello world!
|
||||
```
|
||||
|
||||
@@ -5,27 +5,16 @@
|
||||
## 下载失败问题
|
||||
|
||||
下载资源问题是 spc 最常见的问题之一。主要是由于 spc 下载资源使用的地址一般均为对应项目的官方网站或 GitHub 等,而这些网站可能偶尔会宕机、屏蔽 IP 地址。
|
||||
在遇到下载失败后,可以多次尝试调用下载命令。
|
||||
目前 2.0.0 版本还没有加入自动重试机制,所以在遇到下载失败后,可以多次尝试调用下载命令。如果确认地址确实无法正常访问,可以提交 Issue 或 PR 更新地址。
|
||||
|
||||
当下载资源时,你可能最终会看到类似 `curl: (56) The requested URL returned error: 403` 的错误,这通常是由于 GitHub 限制导致的。
|
||||
你可以通过在命令中添加 `--debug` 来验证,会看到类似 `[DEBU] Running command (no output) : curl -sfSL "https://api.github.com/repos/openssl/openssl/releases"` 的输出。
|
||||
|
||||
要解决这个问题,可以在 GitHub 上 [创建](https://github.com/settings/tokens) 一个个人访问令牌,并将其设置为环境变量 `GITHUB_TOKEN=<XXX>`。
|
||||
|
||||
如果确认地址确实无法正常访问,可以提交 Issue 或 PR 更新地址或下载类型。
|
||||
|
||||
## Doctor 无法修复某些问题
|
||||
## doctor 无法修复
|
||||
|
||||
在绝大部分情况下,doctor 模块都可以对缺失的系统环境进行自动修复和安装,但也存在特殊的环境无法正常使用自动修复功能。
|
||||
|
||||
由于系统限制(例如,Windows 下无法自动安装 Visual Studio 等软件),自动修复功能无法用于某些项目。
|
||||
在遇到无法自动修复功能时,如果遇到 `Some check items can not be fixed` 字样,则表明无法自动修复。
|
||||
请根据终端显示的方法提交 Issue 或自行修复环境。
|
||||
部分项目由于系统局限(如 Windows 下无法自动安装 Visual Studio 等软件),无法使用自动修复功能。
|
||||
在遇到无法自动修复功能时,如果遇到 `Some check items can not be fixed` 字样,则表明无法自动修复,请根据终端显示的方法提交 Issue 或自行修复环境。
|
||||
|
||||
## 编译错误
|
||||
|
||||
遇到编译错误时,如果没有开启 `--debug` 日志,请先开启调试日志,然后确定报错的命令。
|
||||
报错的终端输出对于修复编译错误非常重要。
|
||||
在提交 Issue 时,请上传终端日志的最后报错片段(或整个终端日志输出),并且包含使用的 `spc` 命令和参数。
|
||||
|
||||
如果你是重复构建,请参考 [本地构建 - 多次构建](./manual-build#多次构建) 章节。
|
||||
报错的终端输出对于修复编译错误非常重要,请在提交 Issue 时一并将终端日志的最后报错片段(或整个终端日志输出)上传,并且包含使用的 `spc` 命令和参数。
|
||||
|
||||
138
docs/zh/index.md
138
docs/zh/index.md
@@ -3,140 +3,18 @@
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: "Static PHP"
|
||||
name: "static-php-cli"
|
||||
tagline: "在 Linux、macOS、FreeBSD、Windows 上与 PHP 项目一起构建独立的 PHP 二进制文件,并包含流行的扩展。"
|
||||
image:
|
||||
src: /images/static-php_nobg.png
|
||||
alt: Static PHP CLI Logo
|
||||
actions:
|
||||
- theme: brand
|
||||
text: 开始使用
|
||||
text: 指南
|
||||
link: ./guide/
|
||||
|
||||
features:
|
||||
- title: 静态 CLI 二进制
|
||||
details: 您可以轻松地编译一个独立的 PHP 二进制文件以供通用使用,包括 CLI、FPM SAPI。
|
||||
- title: Micro 自解压可执行文件
|
||||
details: 您可以编译一个自解压的可执行文件,并将 PHP 源代码与二进制文件打包在一起。
|
||||
- title: 依赖管理
|
||||
details: static-php-cli 附带依赖项管理,支持安装不同类型的 PHP 扩展。
|
||||
- title: 静态二进制
|
||||
details: 您可以轻松地编译一个独立的 PHP 二进制文件以供嵌入程序使用。包括 cli、fpm、micro。
|
||||
- title: phpmicro 自执行二进制
|
||||
details: 您可以使用 micro SAPI 编译一个自解压的可执行文件,并将 PHP 代码与二进制文件打包为一个文件。
|
||||
- title: 依赖管理
|
||||
details: static-php-cli 附带依赖项管理,支持安装不同类型的 PHP 扩展和不同的依赖库。
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import {VPSponsors} from "vitepress/theme";
|
||||
import Contributors from '../.vitepress/components/Contributors.vue';
|
||||
|
||||
const sponsors = [
|
||||
{ name: 'Beyond Code', img: '/images/beyondcode-seeklogo.png', url: 'https://beyondco.de/' },
|
||||
{ name: 'NativePHP', img: '/images/nativephp-logo.svg', url: 'https://nativephp.com/' },
|
||||
];
|
||||
</script>
|
||||
|
||||
<div class="sponsors-section">
|
||||
<div class="sponsors-header">
|
||||
<h2>特别赞助商</h2>
|
||||
<p class="sponsors-description">
|
||||
感谢我们出色的赞助商对本项目的支持!
|
||||
</p>
|
||||
</div>
|
||||
<VPSponsors :data="sponsors"/>
|
||||
</div>
|
||||
|
||||
<style scoped>
|
||||
.sponsors-section {
|
||||
margin: 48px auto;
|
||||
padding: 32px 24px;
|
||||
max-width: 1152px;
|
||||
background: linear-gradient(135deg, var(--vp-c-bg-soft) 0%, var(--vp-c-bg) 100%);
|
||||
border-radius: 16px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.sponsors-section:hover {
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.sponsors-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.sponsors-header h2 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 8px 0;
|
||||
background: linear-gradient(120deg, var(--vp-c-brand-1), var(--vp-c-brand-2));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.sponsors-description {
|
||||
font-size: 0.95rem;
|
||||
color: var(--vp-c-text-2);
|
||||
margin: 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.sponsors-section {
|
||||
margin: 32px 16px;
|
||||
padding: 24px 16px;
|
||||
}
|
||||
|
||||
.sponsors-header h2 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.sponsors-description {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hero logo styling */
|
||||
:deep(.VPImage.image-src) {
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, var(--vp-c-bg-soft) 0%, var(--vp-c-default-soft) 100%);
|
||||
padding: 40px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
:deep(.VPImage.image-src:hover) {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* Dark mode adjustments for logo */
|
||||
.dark :deep(.VPImage.image-src) {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.dark :deep(.VPImage.image-src:hover) {
|
||||
opacity: 1;
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
/* Additional styling for the logo image itself */
|
||||
:deep(.VPImage.image-src img) {
|
||||
max-height: 280px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
:deep(.VPImage.image-src) {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
:deep(.VPImage.image-src img) {
|
||||
max-height: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<Contributors />
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vitepress": "^2.0.0-alpha.5",
|
||||
"vitepress": "^1.0.0-rc.35",
|
||||
"vue": "^3.2.47"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,15 @@ parameters:
|
||||
paths:
|
||||
- ./src/
|
||||
ignoreErrors:
|
||||
- '#Constant .* not found#'
|
||||
- '#Unsafe usage of new static#'
|
||||
- '#class Fiber#'
|
||||
- '#Attribute class JetBrains\\PhpStorm\\ArrayShape does not exist#'
|
||||
- '#Function Swoole\\Coroutine\\run not found.#'
|
||||
- '#Static call to instance method ZM\\Logger\\ConsoleColor#'
|
||||
- '#Constant GNU_ARCH not found#'
|
||||
dynamicConstantNames:
|
||||
- PHP_OS_FAMILY
|
||||
excludePaths:
|
||||
analyseAndScan:
|
||||
- ./src/globals/ext-tests/swoole.php
|
||||
- ./src/globals/ext-tests/swoole.phpt
|
||||
- ./src/globals/test-extensions.php
|
||||
- ./src/globals/test-extensions.php
|
||||
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<phpunit
|
||||
bootstrap="tests/bootstrap.php"
|
||||
>
|
||||
<php>
|
||||
<env name="SPC_IGNORE_BAD_HASH" value="yes" force="true" />
|
||||
<env name="SPC_SKIP_TOOLCHAIN_CHECK" value="yes" force="true" />
|
||||
</php>
|
||||
</phpunit>
|
||||
@@ -4,28 +4,22 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC;
|
||||
|
||||
use SPC\command\BuildCliCommand;
|
||||
use SPC\command\BuildLibsCommand;
|
||||
use SPC\command\BuildPHPCommand;
|
||||
use SPC\command\CraftCommand;
|
||||
use SPC\command\DeleteDownloadCommand;
|
||||
use SPC\command\dev\AllExtCommand;
|
||||
use SPC\command\dev\EnvCommand;
|
||||
use SPC\command\dev\ExtVerCommand;
|
||||
use SPC\command\dev\GenerateExtDepDocsCommand;
|
||||
use SPC\command\dev\GenerateExtDocCommand;
|
||||
use SPC\command\dev\GenerateLibDepDocsCommand;
|
||||
use SPC\command\dev\LibVerCommand;
|
||||
use SPC\command\dev\PackLibCommand;
|
||||
use SPC\command\dev\PhpVerCommand;
|
||||
use SPC\command\dev\SortConfigCommand;
|
||||
use SPC\command\DoctorCommand;
|
||||
use SPC\command\DownloadCommand;
|
||||
use SPC\command\DumpExtensionsCommand;
|
||||
use SPC\command\DumpLicenseCommand;
|
||||
use SPC\command\ExtractCommand;
|
||||
use SPC\command\InstallPkgCommand;
|
||||
use SPC\command\MicroCombineCommand;
|
||||
use SPC\command\SPCConfigCommand;
|
||||
use SPC\command\SwitchPhpVersionCommand;
|
||||
use Symfony\Component\Console\Application;
|
||||
|
||||
@@ -34,21 +28,16 @@ use Symfony\Component\Console\Application;
|
||||
*/
|
||||
final class ConsoleApplication extends Application
|
||||
{
|
||||
public const string VERSION = '2.8.4';
|
||||
public const VERSION = '2.3.0';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct('static-php-cli', self::VERSION);
|
||||
|
||||
// Define internal env vars and constants
|
||||
require_once ROOT_DIR . '/src/globals/internal-env.php';
|
||||
|
||||
$this->addCommands(
|
||||
[
|
||||
// Craft command
|
||||
new CraftCommand(),
|
||||
// Common commands
|
||||
new BuildPHPCommand(),
|
||||
new BuildCliCommand(),
|
||||
new BuildLibsCommand(),
|
||||
new DoctorCommand(),
|
||||
new DownloadCommand(),
|
||||
@@ -58,8 +47,6 @@ final class ConsoleApplication extends Application
|
||||
new ExtractCommand(),
|
||||
new MicroCombineCommand(),
|
||||
new SwitchPhpVersionCommand(),
|
||||
new SPCConfigCommand(),
|
||||
new DumpExtensionsCommand(),
|
||||
|
||||
// Dev commands
|
||||
new AllExtCommand(),
|
||||
@@ -68,10 +55,7 @@ final class ConsoleApplication extends Application
|
||||
new ExtVerCommand(),
|
||||
new SortConfigCommand(),
|
||||
new GenerateExtDocCommand(),
|
||||
new GenerateExtDepDocsCommand(),
|
||||
new GenerateLibDepDocsCommand(),
|
||||
new PackLibCommand(),
|
||||
new EnvCommand(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,16 +4,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder;
|
||||
|
||||
use SPC\exception\BuildFailureException;
|
||||
use SPC\exception\InterruptException;
|
||||
use SPC\exception\ExceptionHandler;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\LockFile;
|
||||
use SPC\store\pkg\GoXcaddy;
|
||||
use SPC\store\SourceManager;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\util\AttributeMapper;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
abstract class BuilderBase
|
||||
{
|
||||
@@ -26,12 +24,6 @@ abstract class BuilderBase
|
||||
/** @var array<string, Extension> extensions */
|
||||
protected array $exts = [];
|
||||
|
||||
/** @var array<int, string> extension names */
|
||||
protected array $ext_list = [];
|
||||
|
||||
/** @var array<int, string> library names */
|
||||
protected array $lib_list = [];
|
||||
|
||||
/** @var bool compile libs only (just mark it) */
|
||||
protected bool $libs_only = false;
|
||||
|
||||
@@ -44,30 +36,33 @@ abstract class BuilderBase
|
||||
/**
|
||||
* Convert libraries to class
|
||||
*
|
||||
* @param array<string> $sorted_libraries Libraries to build (if not empty, must sort first)
|
||||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Set-Up libraries
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function setupLibs(): void
|
||||
{
|
||||
// build all libs
|
||||
foreach ($this->libs as $lib) {
|
||||
$starttime = microtime(true);
|
||||
$status = $lib->setup($this->getOption('rebuild', false));
|
||||
match ($status) {
|
||||
match ($lib->setup($this->getOption('rebuild', false))) {
|
||||
LIB_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] setup success, took ' . round(microtime(true) - $starttime, 2) . ' s'),
|
||||
LIB_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
|
||||
LIB_STATUS_BUILD_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
|
||||
LIB_STATUS_INSTALL_FAILED => logger()->error('lib [' . $lib::NAME . '] install failed'),
|
||||
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
|
||||
};
|
||||
if (in_array($status, [LIB_STATUS_BUILD_FAILED, LIB_STATUS_INSTALL_FAILED])) {
|
||||
throw new BuildFailureException('Library [' . $lib::NAME . '] setup failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,12 +115,33 @@ abstract class BuilderBase
|
||||
*
|
||||
* @return Extension[]
|
||||
*/
|
||||
public function getExts(bool $including_shared = true): array
|
||||
public function getExts(): array
|
||||
{
|
||||
if ($including_shared) {
|
||||
return $this->exts;
|
||||
return $this->exts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is a cpp extensions or libraries.
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function hasCpp(): bool
|
||||
{
|
||||
// judge cpp-extension
|
||||
$exts = array_keys($this->getExts());
|
||||
foreach ($exts as $ext) {
|
||||
if (Config::getExt($ext, 'cpp-extension', false) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return array_filter($this->exts, fn ($ext) => $ext->isBuildStatic());
|
||||
$libs = array_keys($this->getLibs());
|
||||
foreach ($libs as $lib) {
|
||||
if (Config::getLib($lib, 'cpp-library', false) === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,49 +157,29 @@ abstract class BuilderBase
|
||||
/**
|
||||
* Verify the list of "ext" extensions for validity and declare an Extension object to check the dependencies of the extensions.
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws \ReflectionException
|
||||
* @throws WrongUsageException
|
||||
* @internal
|
||||
*/
|
||||
public function proveExts(array $static_extensions, array $shared_extensions = [], bool $skip_check_deps = false, bool $skip_extract = false): void
|
||||
public function proveExts(array $extensions, bool $skip_check_deps = false): void
|
||||
{
|
||||
// judge ext
|
||||
foreach ($static_extensions as $ext) {
|
||||
// if extension does not support static build, throw exception
|
||||
if (!in_array('static', Config::getExtTarget($ext))) {
|
||||
throw new WrongUsageException('Extension [' . $ext . '] does not support static build!');
|
||||
}
|
||||
CustomExt::loadCustomExt();
|
||||
$this->emitPatchPoint('before-php-extract');
|
||||
SourceManager::initSource(sources: ['php-src']);
|
||||
$this->emitPatchPoint('after-php-extract');
|
||||
if ($this->getPHPVersionID() >= 80000) {
|
||||
$this->emitPatchPoint('before-micro-extract');
|
||||
SourceManager::initSource(sources: ['micro']);
|
||||
$this->emitPatchPoint('after-micro-extract');
|
||||
}
|
||||
foreach ($shared_extensions as $ext) {
|
||||
// if extension does not support shared build, throw exception
|
||||
if (!in_array('shared', Config::getExtTarget($ext)) && !in_array($ext, $shared_extensions)) {
|
||||
throw new WrongUsageException('Extension [' . $ext . '] does not support shared build!');
|
||||
}
|
||||
}
|
||||
if (!$skip_extract) {
|
||||
$this->emitPatchPoint('before-php-extract');
|
||||
SourceManager::initSource(sources: ['php-src'], source_only: true);
|
||||
$this->emitPatchPoint('after-php-extract');
|
||||
if ($this->getPHPVersionID() >= 80000) {
|
||||
$this->emitPatchPoint('before-micro-extract');
|
||||
SourceManager::initSource(sources: ['micro'], source_only: true);
|
||||
$this->emitPatchPoint('after-micro-extract');
|
||||
}
|
||||
$this->emitPatchPoint('before-exts-extract');
|
||||
SourceManager::initSource(exts: [...$static_extensions, ...$shared_extensions]);
|
||||
$this->emitPatchPoint('after-exts-extract');
|
||||
// patch micro
|
||||
SourcePatcher::patchMicro();
|
||||
}
|
||||
|
||||
foreach ([...$static_extensions, ...$shared_extensions] as $extension) {
|
||||
$class = AttributeMapper::getExtensionClassByName($extension) ?? Extension::class;
|
||||
/** @var Extension $ext */
|
||||
$this->emitPatchPoint('before-exts-extract');
|
||||
SourceManager::initSource(exts: $extensions);
|
||||
$this->emitPatchPoint('after-exts-extract');
|
||||
foreach ($extensions as $extension) {
|
||||
$class = CustomExt::getExtClass($extension);
|
||||
$ext = new $class($extension, $this);
|
||||
if (in_array($extension, $static_extensions)) {
|
||||
$ext->setBuildStatic();
|
||||
}
|
||||
if (in_array($extension, $shared_extensions)) {
|
||||
$ext->setBuildShared();
|
||||
}
|
||||
$this->addExt($ext);
|
||||
}
|
||||
|
||||
@@ -191,10 +187,9 @@ abstract class BuilderBase
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->getExts() as $ext) {
|
||||
foreach ($this->exts as $ext) {
|
||||
$ext->checkDependency();
|
||||
}
|
||||
$this->ext_list = [...$static_extensions, ...$shared_extensions];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,65 +199,19 @@ abstract class BuilderBase
|
||||
*/
|
||||
abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE);
|
||||
|
||||
/**
|
||||
* Test PHP
|
||||
*/
|
||||
abstract public function testPHP(int $build_target = BUILD_TARGET_NONE);
|
||||
|
||||
/**
|
||||
* Build shared extensions.
|
||||
*/
|
||||
public function buildSharedExts(): void
|
||||
{
|
||||
$lines = file(BUILD_BIN_PATH . '/php-config');
|
||||
$extension_dir_line = null;
|
||||
foreach ($lines as $key => $value) {
|
||||
if (str_starts_with($value, 'extension_dir=')) {
|
||||
$lines[$key] = 'extension_dir="' . BUILD_MODULES_PATH . '"' . PHP_EOL;
|
||||
$extension_dir_line = $value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
file_put_contents(BUILD_BIN_PATH . '/php-config', implode('', $lines));
|
||||
FileSystem::replaceFileStr(BUILD_LIB_PATH . '/php/build/phpize.m4', 'test "[$]$1" = "no" && $1=yes', '# test "[$]$1" = "no" && $1=yes');
|
||||
FileSystem::createDir(BUILD_MODULES_PATH);
|
||||
try {
|
||||
foreach ($this->getExts() as $ext) {
|
||||
if (!$ext->isBuildShared()) {
|
||||
continue;
|
||||
}
|
||||
$ext->buildShared();
|
||||
}
|
||||
} finally {
|
||||
FileSystem::replaceFileLineContainsString(BUILD_BIN_PATH . '/php-config', 'extension_dir=', $extension_dir_line);
|
||||
}
|
||||
FileSystem::replaceFileLineContainsString(BUILD_BIN_PATH . '/php-config', 'extension_dir=', $extension_dir_line);
|
||||
FileSystem::replaceFileStr(BUILD_LIB_PATH . '/php/build/phpize.m4', '# test "[$]$1" = "no" && $1=yes', 'test "[$]$1" = "no" && $1=yes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate extension enable arguments for configure.
|
||||
* e.g. --enable-mbstring
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function makeStaticExtensionArgs(): string
|
||||
public function makeExtensionArgs(): string
|
||||
{
|
||||
$ret = [];
|
||||
foreach ($this->getExts() as $ext) {
|
||||
$arg = null;
|
||||
if ($ext->isBuildShared() && !$ext->isBuildStatic()) {
|
||||
if (
|
||||
(Config::getExt($ext->getName(), 'type') === 'builtin' &&
|
||||
!file_exists(SOURCE_PATH . '/php-src/ext/' . $ext->getName() . '/config.m4')) ||
|
||||
Config::getExt($ext->getName(), 'build-with-php') === true
|
||||
) {
|
||||
$arg = $ext->getConfigureArg(true);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$arg ??= $ext->getConfigureArg();
|
||||
logger()->info($ext->getName() . ' is using ' . $arg);
|
||||
$ret[] = trim($arg);
|
||||
foreach ($this->exts as $ext) {
|
||||
logger()->info($ext->getName() . ' is using ' . $ext->getConfigureArg());
|
||||
$ret[] = trim($ext->getConfigureArg());
|
||||
}
|
||||
logger()->debug('Using configure: ' . implode(' ', $ret));
|
||||
return implode(' ', $ret);
|
||||
@@ -278,6 +227,9 @@ abstract class BuilderBase
|
||||
|
||||
/**
|
||||
* Get PHP Version ID from php-src/main/php_version.h
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getPHPVersionID(): int
|
||||
{
|
||||
@@ -290,25 +242,20 @@ abstract class BuilderBase
|
||||
return intval($match[1]);
|
||||
}
|
||||
|
||||
throw new WrongUsageException('PHP version file format is malformed, please remove "./source/php-src" dir and download/extract again');
|
||||
throw new RuntimeException('PHP version file format is malformed, please remove it and download again');
|
||||
}
|
||||
|
||||
public function getPHPVersion(bool $exception_on_failure = true): string
|
||||
public function getPHPVersion(): string
|
||||
{
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
|
||||
if (!$exception_on_failure) {
|
||||
return 'unknown';
|
||||
}
|
||||
throw new WrongUsageException('PHP source files are not available, you need to download them first');
|
||||
}
|
||||
$file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h');
|
||||
if (preg_match('/PHP_VERSION "(.*)"/', $file, $match) !== 0) {
|
||||
return $match[1];
|
||||
}
|
||||
if (!$exception_on_failure) {
|
||||
return 'unknown';
|
||||
}
|
||||
throw new WrongUsageException('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');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,13 +266,17 @@ abstract class BuilderBase
|
||||
public function getPHPVersionFromArchive(?string $file = null): false|string
|
||||
{
|
||||
if ($file === null) {
|
||||
$lock = LockFile::get('php-src');
|
||||
if ($lock === 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;
|
||||
}
|
||||
$file = LockFile::getLockFullPath($lock);
|
||||
}
|
||||
if (preg_match('/php-(\d+\.\d+\.\d+(?:RC\d+|alpha\d+|beta\d+)?)\.tar\.(?:gz|bz2|xz)/', $file, $match)) {
|
||||
if (preg_match('/php-(\d+\.\d+\.\d+)/', $file, $match)) {
|
||||
return $match[1];
|
||||
}
|
||||
return false;
|
||||
@@ -369,12 +320,6 @@ abstract class BuilderBase
|
||||
if (($type & BUILD_TARGET_EMBED) === BUILD_TARGET_EMBED) {
|
||||
$ls[] = 'embed';
|
||||
}
|
||||
if (($type & BUILD_TARGET_FRANKENPHP) === BUILD_TARGET_FRANKENPHP) {
|
||||
$ls[] = 'frankenphp';
|
||||
}
|
||||
if (($type & BUILD_TARGET_CGI) === BUILD_TARGET_CGI) {
|
||||
$ls[] = 'cgi';
|
||||
}
|
||||
return implode(', ', $ls);
|
||||
}
|
||||
|
||||
@@ -443,7 +388,7 @@ abstract class BuilderBase
|
||||
foreach ($this->libs as $lib) {
|
||||
$lib->validate();
|
||||
}
|
||||
foreach ($this->getExts() as $ext) {
|
||||
foreach ($this->exts as $ext) {
|
||||
$ext->validate();
|
||||
}
|
||||
}
|
||||
@@ -458,44 +403,43 @@ abstract class BuilderBase
|
||||
foreach ($patches as $patch) {
|
||||
try {
|
||||
if (!file_exists($patch)) {
|
||||
throw new WrongUsageException("Additional patch script file {$patch} not found!");
|
||||
throw new RuntimeException("Additional patch script file {$patch} not found!");
|
||||
}
|
||||
logger()->debug('Running additional patch script: ' . $patch);
|
||||
require $patch;
|
||||
} catch (InterruptException $e) {
|
||||
if ($e->getCode() === 0) {
|
||||
logger()->notice('Patch script ' . $patch . ' interrupted' . ($e->getMessage() ? (': ' . $e->getMessage()) : '.'));
|
||||
} else {
|
||||
logger()->error('Patch script ' . $patch . ' interrupted with error code [' . $e->getCode() . ']' . ($e->getMessage() ? (': ' . $e->getMessage()) : '.'));
|
||||
}
|
||||
exit($e->getCode());
|
||||
} catch (\Throwable $e) {
|
||||
logger()->critical('Patch script ' . $patch . ' failed to run.');
|
||||
throw $e;
|
||||
if ($this->getOption('debug')) {
|
||||
ExceptionHandler::getInstance()->handle($e);
|
||||
} else {
|
||||
logger()->critical('Please check with --debug option to see more details.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function checkBeforeBuildPHP(int $rule): void
|
||||
/**
|
||||
* Check if all libs are downloaded.
|
||||
* If not, throw exception.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function checkLibsSource(): void
|
||||
{
|
||||
if (($rule & BUILD_TARGET_FRANKENPHP) === BUILD_TARGET_FRANKENPHP) {
|
||||
if (!$this->getOption('enable-zts')) {
|
||||
throw new WrongUsageException('FrankenPHP SAPI requires ZTS enabled PHP, build with `--enable-zts`!');
|
||||
}
|
||||
// frankenphp doesn't support windows, BSD is currently not supported by static-php-cli
|
||||
if (!in_array(PHP_OS_FAMILY, ['Linux', 'Darwin'])) {
|
||||
throw new WrongUsageException('FrankenPHP SAPI is only available on Linux and macOS!');
|
||||
}
|
||||
// frankenphp needs package go-xcaddy installed
|
||||
if (!GoXcaddy::isInstalled()) {
|
||||
global $argv;
|
||||
throw new WrongUsageException("FrankenPHP SAPI requires the go-xcaddy package, please install it first: {$argv[0]} install-pkg go-xcaddy");
|
||||
}
|
||||
// frankenphp needs libxml2 lib on macos, see: https://github.com/php/frankenphp/blob/main/frankenphp.go#L17
|
||||
if (PHP_OS_FAMILY === 'Darwin' && !$this->getLib('libxml2')) {
|
||||
throw new WrongUsageException('FrankenPHP SAPI for macOS requires libxml2 library, please include the `xml` extension in your build.');
|
||||
$not_downloaded = [];
|
||||
foreach ($this->libs as $lib) {
|
||||
if (!file_exists($lib->getSourceDir())) {
|
||||
$not_downloaded[] = $lib::NAME;
|
||||
}
|
||||
}
|
||||
if ($not_downloaded !== []) {
|
||||
throw new RuntimeException(
|
||||
'"' . implode(', ', $not_downloaded) .
|
||||
'" totally ' . count($not_downloaded) .
|
||||
' source' . (count($not_downloaded) === 1 ? '' : 's') .
|
||||
' not downloaded, maybe you need to "fetch" ' . (count($not_downloaded) === 1 ? 'it' : 'them') . ' first?'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -505,7 +449,7 @@ abstract class BuilderBase
|
||||
{
|
||||
$php = "<?php\n\necho '[micro-test-start]' . PHP_EOL;\n";
|
||||
|
||||
foreach ($this->getExts(false) as $ext) {
|
||||
foreach ($this->getExts() as $ext) {
|
||||
$ext_name = $ext->getDistName();
|
||||
if (!empty($ext_name)) {
|
||||
$php .= "echo 'Running micro with {$ext_name} test' . PHP_EOL;\n";
|
||||
|
||||
@@ -8,7 +8,8 @@ use SPC\builder\freebsd\BSDBuilder;
|
||||
use SPC\builder\linux\LinuxBuilder;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\builder\windows\WindowsBuilder;
|
||||
use SPC\exception\ExceptionHandler;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
|
||||
@@ -19,6 +20,11 @@ class BuilderProvider
|
||||
{
|
||||
private static ?BuilderBase $builder = null;
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function makeBuilderByInput(InputInterface $input): BuilderBase
|
||||
{
|
||||
ini_set('memory_limit', '4G');
|
||||
@@ -30,13 +36,12 @@ class BuilderProvider
|
||||
'BSD' => new BSDBuilder($input->getOptions()),
|
||||
default => throw new WrongUsageException('Current OS "' . PHP_OS_FAMILY . '" is not supported yet'),
|
||||
};
|
||||
|
||||
// bind the builder to ExceptionHandler
|
||||
ExceptionHandler::bindBuilder(self::$builder);
|
||||
|
||||
return self::$builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function getBuilder(): BuilderBase
|
||||
{
|
||||
if (self::$builder === null) {
|
||||
|
||||
@@ -4,86 +4,71 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder;
|
||||
|
||||
use SPC\builder\unix\UnixBuilderBase;
|
||||
use SPC\exception\EnvironmentException;
|
||||
use SPC\exception\SPCException;
|
||||
use SPC\exception\ValidationException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class Extension
|
||||
{
|
||||
protected array $dependencies = [];
|
||||
|
||||
protected bool $build_shared = false;
|
||||
|
||||
protected bool $build_static = false;
|
||||
|
||||
protected string $source_dir;
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function __construct(protected string $name, protected BuilderBase $builder)
|
||||
{
|
||||
$ext_type = Config::getExt($this->name, 'type');
|
||||
$unix_only = Config::getExt($this->name, 'unix-only', false);
|
||||
$windows_only = Config::getExt($this->name, 'windows-only', false);
|
||||
if (PHP_OS_FAMILY !== 'Windows' && $windows_only) {
|
||||
throw new EnvironmentException("{$ext_type} extension {$name} is not supported on Linux and macOS platform");
|
||||
throw new RuntimeException("{$ext_type} extension {$name} is not supported on Linux and macOS platform");
|
||||
}
|
||||
if (PHP_OS_FAMILY === 'Windows' && $unix_only) {
|
||||
throw new EnvironmentException("{$ext_type} extension {$name} is not supported on Windows platform");
|
||||
throw new RuntimeException("{$ext_type} extension {$name} is not supported on Windows platform");
|
||||
}
|
||||
// set source_dir for builtin
|
||||
if ($ext_type === 'builtin') {
|
||||
$this->source_dir = SOURCE_PATH . '/php-src/ext/' . $this->name;
|
||||
} elseif ($ext_type === 'external') {
|
||||
$source = Config::getExt($this->name, 'source');
|
||||
if ($source === null) {
|
||||
throw new ValidationException("{$ext_type} extension {$name} source not found", validation_module: "Extension [{$name}] loader");
|
||||
}
|
||||
$source_path = Config::getSource($source)['path'] ?? null;
|
||||
$source_path = $source_path === null ? SOURCE_PATH . '/' . $source : SOURCE_PATH . '/' . $source_path;
|
||||
$this->source_dir = $source_path;
|
||||
} else {
|
||||
$this->source_dir = SOURCE_PATH . '/php-src';
|
||||
}
|
||||
}
|
||||
|
||||
public function getFrameworks(): array
|
||||
{
|
||||
return Config::getExt($this->getName(), 'frameworks', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取开启该扩展的 PHP 编译添加的参数
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getConfigureArg(bool $shared = false): string
|
||||
public function getConfigureArg(): string
|
||||
{
|
||||
return match (PHP_OS_FAMILY) {
|
||||
'Windows' => $this->getWindowsConfigureArg($shared),
|
||||
'Darwin',
|
||||
'Linux',
|
||||
'BSD' => $this->getUnixConfigureArg($shared),
|
||||
default => throw new WrongUsageException(PHP_OS_FAMILY . ' build is not supported yet'),
|
||||
};
|
||||
$arg = $this->getEnableArg();
|
||||
switch (PHP_OS_FAMILY) {
|
||||
case 'Windows':
|
||||
$arg .= $this->getWindowsConfigureArg();
|
||||
break;
|
||||
case 'Darwin':
|
||||
case 'Linux':
|
||||
case 'BSD':
|
||||
$arg .= $this->getUnixConfigureArg();
|
||||
break;
|
||||
}
|
||||
return $arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ext 的 arg-type 获取对应开启的参数,一般都是 --enable-xxx 和 --with-xxx
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getEnableArg(bool $shared = false): string
|
||||
public function getEnableArg(): string
|
||||
{
|
||||
$escapedPath = str_replace("'", '', escapeshellarg(BUILD_ROOT_PATH)) !== BUILD_ROOT_PATH || str_contains(BUILD_ROOT_PATH, ' ') ? escapeshellarg(BUILD_ROOT_PATH) : BUILD_ROOT_PATH;
|
||||
$_name = str_replace('_', '-', $this->name);
|
||||
return match ($arg_type = Config::getExt($this->name, 'arg-type', 'enable')) {
|
||||
'enable' => '--enable-' . $_name . ($shared ? '=shared' : '') . ' ',
|
||||
'enable-path' => '--enable-' . $_name . '=' . ($shared ? 'shared,' : '') . $escapedPath . ' ',
|
||||
'with' => '--with-' . $_name . ($shared ? '=shared' : '') . ' ',
|
||||
'with-path' => '--with-' . $_name . '=' . ($shared ? 'shared,' : '') . $escapedPath . ' ',
|
||||
'enable' => '--enable-' . $_name . ' ',
|
||||
'with' => '--with-' . $_name . ' ',
|
||||
'with-prefix' => '--with-' . $_name . '="' . BUILD_ROOT_PATH . '" ',
|
||||
'none', 'custom' => '',
|
||||
default => throw new WrongUsageException("argType does not accept {$arg_type}, use [enable/with/with-path] ."),
|
||||
default => throw new WrongUsageException("argType does not accept {$arg_type}, use [enable/with/with-prefix] ."),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -96,12 +81,15 @@ class Extension
|
||||
fn ($x) => $x->getStaticLibFiles(),
|
||||
$this->getLibraryDependencies(recursive: true)
|
||||
);
|
||||
$libs = implode(' ', $ret);
|
||||
return deduplicate_flags($libs);
|
||||
return implode(' ', $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查下依赖就行了,作用是导入依赖给 Extension 对象,今后可以对库依赖进行选择性处理
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function checkDependency(): static
|
||||
{
|
||||
@@ -138,21 +126,20 @@ class Extension
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(bool $shared = false): string
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
return $this->getEnableArg();
|
||||
return '';
|
||||
// Windows is not supported yet
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
return $this->getEnableArg($shared);
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before ./buildconf
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
* If you need to patch some code, overwrite this and return true
|
||||
*/
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
@@ -161,185 +148,64 @@ class Extension
|
||||
|
||||
/**
|
||||
* Patch code before ./configure
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
* If you need to patch some code, overwrite this and return true
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before ./configure.bat for Windows
|
||||
*/
|
||||
public function patchBeforeWindowsConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before make
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
* If you need to patch some code, overwrite this and return true
|
||||
*/
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
if (SPCTarget::getTargetOS() === 'Linux' && $this->isBuildShared() && ($objs = getenv('SPC_EXTRA_RUNTIME_OBJECTS'))) {
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/Makefile',
|
||||
"/^(shared_objects_{$this->getName()}\\s*=.*)$/m",
|
||||
"$1 {$objs}",
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before shared extension phpize
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function patchBeforeSharedPhpize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before shared extension ./configure
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeSharedConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before shared extension make
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeSharedMake(): bool
|
||||
{
|
||||
$config = (new SPCConfigUtil($this->builder))->getExtensionConfig($this);
|
||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||
$lstdcpp = str_contains($sharedLibs, '-l:libstdc++.a') ? '-l:libstdc++.a' : null;
|
||||
$lstdcpp ??= str_contains($sharedLibs, '-lstdc++') ? '-lstdc++' : '';
|
||||
|
||||
$makefileContent = file_get_contents($this->source_dir . '/Makefile');
|
||||
if (preg_match('/^(.*_SHARED_LIBADD\s*=\s*)(.*)$/m', $makefileContent, $matches)) {
|
||||
$prefix = $matches[1];
|
||||
$currentLibs = trim($matches[2]);
|
||||
$newLibs = trim("{$currentLibs} {$staticLibs} {$lstdcpp}");
|
||||
$deduplicatedLibs = deduplicate_flags($newLibs);
|
||||
|
||||
FileSystem::replaceFileRegex(
|
||||
$this->source_dir . '/Makefile',
|
||||
'/^(.*_SHARED_LIBADD\s*=.*)$/m',
|
||||
$prefix . $deduplicatedLibs
|
||||
);
|
||||
}
|
||||
|
||||
if ($objs = getenv('SPC_EXTRA_RUNTIME_OBJECTS')) {
|
||||
FileSystem::replaceFileRegex(
|
||||
$this->source_dir . '/Makefile',
|
||||
"/^(shared_objects_{$this->getName()}\\s*=.*)$/m",
|
||||
"$1 {$objs}",
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* returns a command line string with all required shared extensions to load
|
||||
* i.e.; pdo_pgsql would return:
|
||||
*
|
||||
* `-d "extension=pgsql" -d "extension=pdo_pgsql"`
|
||||
*/
|
||||
public function getSharedExtensionLoadString(): string
|
||||
{
|
||||
$loaded = [];
|
||||
$order = [];
|
||||
|
||||
$resolve = function ($extension) use (&$resolve, &$loaded, &$order) {
|
||||
if (!$extension instanceof Extension) {
|
||||
return;
|
||||
}
|
||||
if (isset($loaded[$extension->getName()])) {
|
||||
return;
|
||||
}
|
||||
$loaded[$extension->getName()] = true;
|
||||
|
||||
foreach ($extension->dependencies as $dependency) {
|
||||
$resolve($dependency);
|
||||
}
|
||||
|
||||
$order[] = $extension;
|
||||
};
|
||||
|
||||
$resolve($this);
|
||||
|
||||
$ret = '';
|
||||
foreach ($order as $ext) {
|
||||
if ($ext instanceof self && $ext->isBuildShared()) {
|
||||
if (Config::getExt($ext->getName(), 'type', false) === 'addon') {
|
||||
continue;
|
||||
}
|
||||
if (Config::getExt($ext->getName(), 'zend-extension', false) === true) {
|
||||
$ret .= " -d \"zend_extension={$ext->getName()}\"";
|
||||
} else {
|
||||
$ret .= " -d \"extension={$ext->getName()}\"";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($ret !== '') {
|
||||
$ret = ' -d "extension_dir=' . BUILD_MODULES_PATH . '"' . $ret;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function runCliCheckUnix(): void
|
||||
{
|
||||
// Run compile check if build target is cli
|
||||
// If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php
|
||||
$sharedExtensions = $this->getSharedExtensionLoadString();
|
||||
[$ret] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n' . $sharedExtensions . ' --ri "' . $this->getDistName() . '"');
|
||||
// If check failed, throw RuntimeException
|
||||
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false);
|
||||
if ($ret !== 0) {
|
||||
throw new ValidationException(
|
||||
"extension {$this->getName()} failed compile check: php-cli returned {$ret}",
|
||||
validation_module: 'Extension ' . $this->getName() . ' sanity check'
|
||||
);
|
||||
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')) {
|
||||
// Trim additional content & escape special characters to allow inline usage
|
||||
$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')
|
||||
);
|
||||
|
||||
[$ret, $out] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n' . $sharedExtensions . ' -r "' . trim($test) . '"');
|
||||
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
|
||||
if ($ret !== 0) {
|
||||
throw new ValidationException(
|
||||
"extension {$this->getName()} failed sanity check. Code: {$ret}, output: " . implode("\n", $out),
|
||||
validation_module: 'Extension ' . $this->getName() . ' function check'
|
||||
);
|
||||
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
|
||||
[$ret] = cmd()->execWithResult(BUILD_BIN_PATH . '/php.exe -n --ri "' . $this->getDistName() . '"', false);
|
||||
// If check failed, throw RuntimeException
|
||||
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe --ri "' . $this->getDistName() . '"', false);
|
||||
if ($ret !== 0) {
|
||||
throw new ValidationException("extension {$this->getName()} failed compile check: php-cli returned {$ret}", validation_module: "Extension {$this->getName()} sanity check");
|
||||
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'))) {
|
||||
@@ -350,12 +216,9 @@ class Extension
|
||||
file_get_contents(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php'))
|
||||
);
|
||||
|
||||
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -n -r "' . trim($test) . '"');
|
||||
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -r "' . trim($test) . '"');
|
||||
if ($ret !== 0) {
|
||||
throw new ValidationException(
|
||||
"extension {$this->getName()} failed function check",
|
||||
validation_module: "Extension {$this->getName()} function check"
|
||||
);
|
||||
throw new RuntimeException('extension ' . $this->getName() . ' failed sanity check');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,109 +228,6 @@ class Extension
|
||||
// do nothing, just throw wrong usage exception if not valid
|
||||
}
|
||||
|
||||
/**
|
||||
* Build shared extension
|
||||
*/
|
||||
public function buildShared(array $visited = []): void
|
||||
{
|
||||
try {
|
||||
if (Config::getExt($this->getName(), 'type') === 'builtin' || Config::getExt($this->getName(), 'build-with-php') === true) {
|
||||
if (file_exists(BUILD_MODULES_PATH . '/' . $this->getName() . '.so')) {
|
||||
logger()->info('Shared extension [' . $this->getName() . '] was already built by php-src/configure (' . $this->getName() . '.so)');
|
||||
return;
|
||||
}
|
||||
if (Config::getExt($this->getName(), 'build-with-php') === true) {
|
||||
logger()->warning('Shared extension [' . $this->getName() . '] did not build with php-src/configure (' . $this->getName() . '.so)');
|
||||
logger()->warning('Try deleting your build and source folders and running `spc build`` again.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (file_exists(BUILD_MODULES_PATH . '/' . $this->getName() . '.so')) {
|
||||
logger()->info('Shared extension [' . $this->getName() . '] was already built, skipping (' . $this->getName() . '.so)');
|
||||
return;
|
||||
}
|
||||
if ((string) Config::getExt($this->getName(), 'type') === 'addon') {
|
||||
return;
|
||||
}
|
||||
logger()->info('Building extension [' . $this->getName() . '] as shared extension (' . $this->getName() . '.so)');
|
||||
foreach ($this->dependencies as $dependency) {
|
||||
if (!$dependency instanceof Extension) {
|
||||
continue;
|
||||
}
|
||||
if (!$dependency->isBuildStatic() && !in_array($dependency->getName(), $visited)) {
|
||||
logger()->info('extension ' . $this->getName() . ' requires extension ' . $dependency->getName());
|
||||
$dependency->buildShared([...$visited, $this->getName()]);
|
||||
}
|
||||
}
|
||||
$this->builder->emitPatchPoint('before-shared-ext[' . $this->getName() . ']-build');
|
||||
match (PHP_OS_FAMILY) {
|
||||
'Darwin', 'Linux' => $this->buildUnixShared(),
|
||||
default => throw new WrongUsageException(PHP_OS_FAMILY . ' build shared extensions is not supported yet'),
|
||||
};
|
||||
$this->builder->emitPatchPoint('after-shared-ext[' . $this->getName() . ']-build');
|
||||
} catch (SPCException $e) {
|
||||
$e->bindExtensionInfo(['extension_name' => $this->getName()]);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build shared extension for Unix
|
||||
*/
|
||||
public function buildUnixShared(): void
|
||||
{
|
||||
$env = $this->getSharedExtensionEnv();
|
||||
if ($this->patchBeforeSharedPhpize()) {
|
||||
logger()->info("Extension [{$this->getName()}] patched before shared phpize");
|
||||
}
|
||||
|
||||
// prepare configure args
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->appendEnv($this->getExtraEnv())
|
||||
->exec(BUILD_BIN_PATH . '/phpize');
|
||||
|
||||
if ($this->patchBeforeSharedConfigure()) {
|
||||
logger()->info("Extension [{$this->getName()}] patched before shared configure");
|
||||
}
|
||||
|
||||
$phpvars = getenv('SPC_EXTRA_PHP_VARS') ?: '';
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->appendEnv($this->getExtraEnv())
|
||||
->exec(
|
||||
'./configure ' . $this->getUnixConfigureArg(true) .
|
||||
' --with-php-config=' . BUILD_BIN_PATH . '/php-config ' .
|
||||
"--enable-shared --disable-static {$phpvars}"
|
||||
);
|
||||
|
||||
if ($this->patchBeforeSharedMake()) {
|
||||
logger()->info("Extension [{$this->getName()}] patched before shared make");
|
||||
}
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->appendEnv($this->getExtraEnv())
|
||||
->exec('make clean')
|
||||
->exec('make -j' . $this->builder->concurrency)
|
||||
->exec('make install');
|
||||
|
||||
// process *.so file
|
||||
$soFile = BUILD_MODULES_PATH . '/' . $this->getName() . '.so';
|
||||
$soDest = $soFile;
|
||||
preg_match('/-release\s+(\S*)/', getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), $matches);
|
||||
if (!empty($matches[1])) {
|
||||
$soDest = str_replace('.so', '-' . $matches[1] . '.so', $soFile);
|
||||
}
|
||||
if (!file_exists($soFile)) {
|
||||
throw new ValidationException("extension {$this->getName()} build failed: {$soFile} not found", validation_module: "Extension {$this->getName()} build");
|
||||
}
|
||||
/** @var UnixBuilderBase $builder */
|
||||
$builder = $this->builder;
|
||||
$builder->deployBinary($soFile, $soDest, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current extension version
|
||||
*
|
||||
@@ -478,38 +238,39 @@ class Extension
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setBuildStatic(): void
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function addLibraryDependency(string $name, bool $optional = false): void
|
||||
{
|
||||
if (!in_array('static', Config::getExtTarget($this->name))) {
|
||||
throw new WrongUsageException("Extension [{$this->name}] does not support static build!");
|
||||
$depLib = $this->builder->getLib($name);
|
||||
if (!$depLib) {
|
||||
if (!$optional) {
|
||||
throw new RuntimeException("extension {$this->name} requires library {$name}");
|
||||
}
|
||||
logger()->info("enabling {$this->name} without library {$name}");
|
||||
} else {
|
||||
$this->dependencies[] = $depLib;
|
||||
}
|
||||
$this->build_static = true;
|
||||
}
|
||||
|
||||
public function setBuildShared(): void
|
||||
{
|
||||
if (!in_array('shared', Config::getExtTarget($this->name))) {
|
||||
throw new WrongUsageException("Extension [{$this->name}] does not support shared build!");
|
||||
}
|
||||
$this->build_shared = true;
|
||||
}
|
||||
|
||||
public function isBuildShared(): bool
|
||||
{
|
||||
return $this->build_shared;
|
||||
}
|
||||
|
||||
public function isBuildStatic(): bool
|
||||
{
|
||||
return $this->build_static;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the library dependencies that current extension depends on.
|
||||
*
|
||||
* @param bool $recursive Whether it includes dependencies recursively
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function getLibraryDependencies(bool $recursive = false): array
|
||||
protected function addExtensionDependency(string $name, bool $optional = false): void
|
||||
{
|
||||
$depExt = $this->builder->getExt($name);
|
||||
if (!$depExt) {
|
||||
if (!$optional) {
|
||||
throw new RuntimeException("{$this->name} requires extension {$name}");
|
||||
}
|
||||
logger()->info("enabling {$this->name} without extension {$name}");
|
||||
} else {
|
||||
$this->dependencies[] = $depExt;
|
||||
}
|
||||
}
|
||||
|
||||
private function getLibraryDependencies(bool $recursive = false): array
|
||||
{
|
||||
$ret = array_filter($this->dependencies, fn ($x) => $x instanceof LibraryBase);
|
||||
if (!$recursive) {
|
||||
@@ -523,12 +284,12 @@ class Extension
|
||||
$added = 0;
|
||||
foreach ($ret as $depName => $dep) {
|
||||
foreach ($dep->getDependencies(true) as $depdepName => $depdep) {
|
||||
if (!array_key_exists($depdepName, $deps)) {
|
||||
if (!in_array($depdepName, array_keys($deps), true)) {
|
||||
$deps[$depdepName] = $depdep;
|
||||
++$added;
|
||||
}
|
||||
}
|
||||
if (!array_key_exists($depName, $deps)) {
|
||||
if (!in_array($depName, array_keys($deps), true)) {
|
||||
$deps[$depName] = $dep;
|
||||
}
|
||||
}
|
||||
@@ -536,82 +297,4 @@ class Extension
|
||||
|
||||
return $deps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the environment variables a shared extension needs to be built.
|
||||
* CFLAGS, CXXFLAGS, LDFLAGS and so on.
|
||||
*/
|
||||
protected function getSharedExtensionEnv(): array
|
||||
{
|
||||
$config = (new SPCConfigUtil($this->builder, ['no_php' => true]))->getExtensionConfig($this);
|
||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||
$preStatic = PHP_OS_FAMILY === 'Darwin' ? '' : '-Wl,--start-group ';
|
||||
$postStatic = PHP_OS_FAMILY === 'Darwin' ? '' : ' -Wl,--end-group ';
|
||||
return [
|
||||
'CFLAGS' => $config['cflags'],
|
||||
'CXXFLAGS' => $config['cflags'],
|
||||
'LDFLAGS' => $config['ldflags'],
|
||||
'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'),
|
||||
'LIBS' => clean_spaces("{$preStatic} {$staticLibs} {$postStatic} {$sharedLibs}"),
|
||||
'LD_LIBRARY_PATH' => BUILD_LIB_PATH,
|
||||
];
|
||||
}
|
||||
|
||||
protected function addLibraryDependency(string $name, bool $optional = false): void
|
||||
{
|
||||
$depLib = $this->builder->getLib($name);
|
||||
if (!$depLib) {
|
||||
if (!$optional) {
|
||||
throw new WrongUsageException("extension {$this->name} requires library {$name}");
|
||||
}
|
||||
logger()->info("enabling {$this->name} without library {$name}");
|
||||
} else {
|
||||
$this->dependencies[$name] = $depLib;
|
||||
}
|
||||
}
|
||||
|
||||
protected function addExtensionDependency(string $name, bool $optional = false): void
|
||||
{
|
||||
$depExt = $this->builder->getExt($name);
|
||||
if (!$depExt) {
|
||||
if (!$optional) {
|
||||
throw new WrongUsageException("{$this->name} requires extension {$name} which is not included");
|
||||
}
|
||||
logger()->info("enabling {$this->name} without extension {$name}");
|
||||
} else {
|
||||
$this->dependencies[$name] = $depExt;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getExtraEnv(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a given string of library flags into static and shared libraries.
|
||||
*
|
||||
* @param string $allLibs A space-separated string of library flags (e.g., -lxyz).
|
||||
* @return array an array containing two elements: the first is a space-separated string
|
||||
* of static library flags, and the second is a space-separated string
|
||||
* of shared library flags
|
||||
*/
|
||||
protected function splitLibsIntoStaticAndShared(string $allLibs): array
|
||||
{
|
||||
$staticLibString = '';
|
||||
$sharedLibString = '';
|
||||
$libs = explode(' ', $allLibs);
|
||||
foreach ($libs as $lib) {
|
||||
$staticLib = BUILD_LIB_PATH . '/lib' . str_replace('-l', '', $lib) . '.a';
|
||||
if (str_starts_with($lib, BUILD_LIB_PATH . '/lib') && str_ends_with($lib, '.a')) {
|
||||
$staticLib = $lib;
|
||||
}
|
||||
if ($lib === '-lphp' || !file_exists($staticLib)) {
|
||||
$sharedLibString .= " {$lib}";
|
||||
} else {
|
||||
$staticLibString .= " {$lib}";
|
||||
}
|
||||
}
|
||||
return [trim($staticLibString), trim($sharedLibString)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder;
|
||||
|
||||
use SPC\exception\SPCException;
|
||||
use SPC\exception\SPCInternalException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\LockFile;
|
||||
use SPC\store\SourceManager;
|
||||
use SPC\util\GlobalValueTrait;
|
||||
|
||||
abstract class LibraryBase
|
||||
{
|
||||
use GlobalValueTrait;
|
||||
|
||||
/** @var string */
|
||||
public const NAME = 'unknown';
|
||||
|
||||
@@ -27,25 +22,31 @@ abstract class LibraryBase
|
||||
|
||||
protected bool $patched = false;
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct(?string $source_dir = null)
|
||||
{
|
||||
if (static::NAME === 'unknown') {
|
||||
throw new SPCInternalException('Please set the NAME constant in ' . static::class);
|
||||
throw new RuntimeException('no unknown!!!!!');
|
||||
}
|
||||
$this->source_dir = $source_dir ?? (SOURCE_PATH . DIRECTORY_SEPARATOR . Config::getLib(static::NAME, 'source'));
|
||||
$this->source_dir = $source_dir ?? (SOURCE_PATH . '/' . static::NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to install or build this library.
|
||||
* @param bool $force If true, force install or build
|
||||
* @param bool $force If true, force install or build
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function setup(bool $force = false): int
|
||||
{
|
||||
$lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? [];
|
||||
$source = Config::getLib(static::NAME, 'source');
|
||||
// if source is locked as pre-built, we just tryInstall it
|
||||
$pre_built_name = Downloader::getPreBuiltLockName($source);
|
||||
if (($lock = LockFile::get($pre_built_name)) && $lock['lock_as'] === SPC_DOWNLOAD_PRE_BUILT) {
|
||||
return $this->tryInstall($lock, $force);
|
||||
if (isset($lock[$source]) && ($lock[$source]['lock_as'] ?? SPC_LOCK_SOURCE) === SPC_LOCK_PRE_BUILT) {
|
||||
return $this->tryInstall($lock[$source]['filename'], $force);
|
||||
}
|
||||
return $this->tryBuild($force);
|
||||
}
|
||||
@@ -101,6 +102,10 @@ abstract class LibraryBase
|
||||
|
||||
/**
|
||||
* Calculate dependencies for current library.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function calcDependency(): void
|
||||
{
|
||||
@@ -108,7 +113,7 @@ abstract class LibraryBase
|
||||
/*
|
||||
Rules:
|
||||
If it is a Windows system, try the following dependencies in order: lib-depends-windows, lib-depends-win, lib-depends.
|
||||
If it is a macOS system, try the following dependencies in order: lib-depends-macos, lib-depends-unix, lib-depends.
|
||||
If it is a macOS system, try the following dependencies in order: lib-depends-darwin, lib-depends-unix, lib-depends.
|
||||
If it is a Linux system, try the following dependencies in order: lib-depends-linux, lib-depends-unix, lib-depends.
|
||||
*/
|
||||
foreach (Config::getLib(static::NAME, 'lib-depends', []) as $dep_name) {
|
||||
@@ -121,6 +126,9 @@ abstract class LibraryBase
|
||||
|
||||
/**
|
||||
* Get config static libs.
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getStaticLibs(): array
|
||||
{
|
||||
@@ -129,6 +137,9 @@ abstract class LibraryBase
|
||||
|
||||
/**
|
||||
* Get config headers.
|
||||
*
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
@@ -136,31 +147,40 @@ abstract class LibraryBase
|
||||
}
|
||||
|
||||
/**
|
||||
* Get binary files.
|
||||
* @throws WrongUsageException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function getBinaryFiles(): array
|
||||
public function tryInstall(string $install_file, bool $force_install = false): int
|
||||
{
|
||||
return Config::getLib(static::NAME, 'bin', []);
|
||||
}
|
||||
|
||||
public function tryInstall(array $lock, bool $force_install = false): int
|
||||
{
|
||||
$install_file = $lock['filename'];
|
||||
if ($force_install) {
|
||||
logger()->info('Installing required library [' . static::NAME . '] from pre-built binaries');
|
||||
|
||||
// Extract files
|
||||
try {
|
||||
FileSystem::extractPackage($install_file, $lock['source_type'], DOWNLOAD_PATH . '/' . $install_file, BUILD_ROOT_PATH);
|
||||
FileSystem::extractPackage($install_file, DOWNLOAD_PATH . '/' . $install_file, BUILD_ROOT_PATH);
|
||||
$this->install();
|
||||
return LIB_STATUS_OK;
|
||||
} catch (SPCException $e) {
|
||||
} catch (FileSystemException|RuntimeException $e) {
|
||||
logger()->error('Failed to extract pre-built library [' . static::NAME . ']: ' . $e->getMessage());
|
||||
return LIB_STATUS_INSTALL_FAILED;
|
||||
}
|
||||
}
|
||||
if (!$this->isLibraryInstalled()) {
|
||||
return $this->tryInstall($lock, true);
|
||||
foreach ($this->getStaticLibs() as $name) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
||||
$this->tryInstall($install_file, true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
foreach ($this->getHeaders() as $name) {
|
||||
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
||||
$this->tryInstall($install_file, true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
// pkg-config is treated specially. If it is pkg-config, check if the pkg-config binary exists
|
||||
if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
|
||||
$this->tryInstall($install_file, true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
return LIB_STATUS_ALREADY;
|
||||
}
|
||||
@@ -171,6 +191,10 @@ abstract class LibraryBase
|
||||
* BUILD_STATUS_OK if build success
|
||||
* BUILD_STATUS_ALREADY if already built
|
||||
* BUILD_STATUS_FAILED if build failed
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function tryBuild(bool $force_build = false): int
|
||||
{
|
||||
@@ -179,33 +203,56 @@ abstract class LibraryBase
|
||||
}
|
||||
// force means just build
|
||||
if ($force_build) {
|
||||
$type = Config::getLib(static::NAME, 'type', 'lib');
|
||||
logger()->info('Building required ' . $type . ' [' . static::NAME . ']');
|
||||
logger()->info('Building required library [' . static::NAME . ']');
|
||||
|
||||
// extract first if not exists
|
||||
if (!is_dir($this->source_dir)) {
|
||||
$this->getBuilder()->emitPatchPoint('before-library[' . static::NAME . ']-extract');
|
||||
SourceManager::initSource(libs: [static::NAME], source_only: true);
|
||||
$this->getBuilder()->emitPatchPoint('after-library[' . static::NAME . ']-extract');
|
||||
$this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-extract');
|
||||
SourceManager::initSource(libs: [static::NAME]);
|
||||
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-extract');
|
||||
}
|
||||
|
||||
if (!$this->patched && $this->patchBeforeBuild()) {
|
||||
file_put_contents($this->source_dir . '/.spc.patched', 'PATCHED!!!');
|
||||
}
|
||||
$this->getBuilder()->emitPatchPoint('before-library[' . static::NAME . ']-build');
|
||||
$this->getBuilder()->emitPatchPoint('before-library[ ' . static::NAME . ']-build');
|
||||
$this->build();
|
||||
$this->installLicense();
|
||||
$this->getBuilder()->emitPatchPoint('after-library[' . static::NAME . ']-build');
|
||||
$this->getBuilder()->emitPatchPoint('after-library[ ' . static::NAME . ']-build');
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
|
||||
if (!$this->isLibraryInstalled()) {
|
||||
return $this->tryBuild(true);
|
||||
// check if these libraries exist, if not, invoke compilation and return the result status
|
||||
foreach ($this->getStaticLibs() as $name) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
||||
$this->tryBuild(true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
// header files the same
|
||||
foreach ($this->getHeaders() as $name) {
|
||||
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
||||
$this->tryBuild(true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
// pkg-config is treated specially. If it is pkg-config, check if the pkg-config binary exists
|
||||
if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
|
||||
$this->tryBuild(true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
// if all the files exist at this point, skip the compilation process
|
||||
return LIB_STATUS_ALREADY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch before build, overwrite this and return true to patch libs.
|
||||
*/
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function validate(): void
|
||||
{
|
||||
// do nothing, just throw wrong usage exception if not valid
|
||||
@@ -231,97 +278,22 @@ abstract class LibraryBase
|
||||
// do something before pack, default do nothing. overwrite this method to do something (e.g. modify pkg-config file)
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before build
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before ./buildconf
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before ./configure
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before windows configure.bat
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeWindowsConfigure(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before make
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch php-config after embed was built
|
||||
* Example: imap requires -lcrypt
|
||||
*/
|
||||
public function patchPhpConfig(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build this library.
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
abstract protected function build();
|
||||
|
||||
protected function install(): void
|
||||
{
|
||||
// replace placeholders if BUILD_ROOT_PATH/.spc-extract-placeholder.json exists
|
||||
$replace_item_file = BUILD_ROOT_PATH . '/.spc-extract-placeholder.json';
|
||||
if (!file_exists($replace_item_file)) {
|
||||
return;
|
||||
}
|
||||
$replace_items = json_decode(file_get_contents($replace_item_file), true);
|
||||
if (!is_array($replace_items)) {
|
||||
throw new SPCInternalException("Invalid placeholder file: {$replace_item_file}");
|
||||
}
|
||||
$placeholders = get_pack_replace();
|
||||
// replace placeholders in BUILD_ROOT_PATH
|
||||
foreach ($replace_items as $item) {
|
||||
$filepath = BUILD_ROOT_PATH . "/{$item}";
|
||||
FileSystem::replaceFileStr(
|
||||
$filepath,
|
||||
array_values($placeholders),
|
||||
array_keys($placeholders),
|
||||
);
|
||||
}
|
||||
// remove placeholder file
|
||||
unlink($replace_item_file);
|
||||
// do something after extracting pre-built files, default do nothing. overwrite this method to do something
|
||||
}
|
||||
|
||||
/**
|
||||
* Add lib dependency
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function addLibraryDependency(string $name, bool $optional = false): void
|
||||
{
|
||||
@@ -331,7 +303,7 @@ abstract class LibraryBase
|
||||
return;
|
||||
}
|
||||
if (!$optional) {
|
||||
throw new WrongUsageException(static::NAME . " requires library {$name} but it is not included");
|
||||
throw new RuntimeException(static::NAME . " requires library {$name}");
|
||||
}
|
||||
logger()->debug('enabling ' . static::NAME . " without {$name}");
|
||||
}
|
||||
@@ -346,75 +318,20 @@ abstract class LibraryBase
|
||||
*/
|
||||
protected function installLicense(): void
|
||||
{
|
||||
FileSystem::createDir(BUILD_ROOT_PATH . '/source-licenses/' . $this->getName());
|
||||
$source = Config::getLib($this->getName(), 'source');
|
||||
FileSystem::createDir(BUILD_ROOT_PATH . "/source-licenses/{$source}");
|
||||
$license_files = Config::getSource($source)['license'] ?? [];
|
||||
if (is_assoc_array($license_files)) {
|
||||
$license_files = [$license_files];
|
||||
}
|
||||
foreach ($license_files as $index => $license) {
|
||||
if ($license['type'] === 'text') {
|
||||
FileSystem::writeFile(BUILD_ROOT_PATH . "/source-licenses/{$source}/{$index}.txt", $license['text']);
|
||||
FileSystem::writeFile(BUILD_ROOT_PATH . '/source-licenses/' . $this->getName() . "/{$index}.txt", $license['text']);
|
||||
continue;
|
||||
}
|
||||
if ($license['type'] === 'file') {
|
||||
copy($this->source_dir . '/' . $license['path'], BUILD_ROOT_PATH . "/source-licenses/{$source}/{$index}.txt");
|
||||
copy($this->source_dir . '/' . $license['path'], BUILD_ROOT_PATH . '/source-licenses/' . $this->getName() . "/{$index}.txt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function isLibraryInstalled(): bool
|
||||
{
|
||||
if ($pkg_configs = Config::getLib(static::NAME, 'pkg-configs', [])) {
|
||||
$pkg_config_path = getenv('PKG_CONFIG_PATH') ?: '';
|
||||
$search_paths = array_unique(array_filter(explode(is_unix() ? ':' : ';', $pkg_config_path)));
|
||||
|
||||
foreach ($pkg_configs as $name) {
|
||||
$found = false;
|
||||
foreach ($search_paths as $path) {
|
||||
if (file_exists($path . "/{$name}.pc")) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// allow using system dependencies if pkg_config_path is explicitly defined
|
||||
if (count($search_paths) > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
foreach (Config::getLib(static::NAME, 'static-libs', []) as $name) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach (Config::getLib(static::NAME, 'headers', []) as $name) {
|
||||
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$pkg_config_path = getenv('PKG_CONFIG_PATH') ?: '';
|
||||
$search_paths = array_filter(explode(is_unix() ? ':' : ';', $pkg_config_path));
|
||||
foreach (Config::getLib(static::NAME, 'pkg-configs', []) as $name) {
|
||||
$found = false;
|
||||
foreach ($search_paths as $path) {
|
||||
if (file_exists($path . "/{$name}.pc")) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach (Config::getLib(static::NAME, 'bin', []) as $name) {
|
||||
if (!file_exists(BUILD_BIN_PATH . "/{$name}")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder;
|
||||
|
||||
/**
|
||||
* Interface for library implementations
|
||||
*
|
||||
* This interface defines the basic contract that all library classes must implement.
|
||||
* It provides a common way to identify and work with different library types.
|
||||
*/
|
||||
interface LibraryInterface
|
||||
{
|
||||
/**
|
||||
* Get the name of the library
|
||||
*
|
||||
* @return string The library name
|
||||
*/
|
||||
public function getName(): string;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ class amqp extends Extension
|
||||
{
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
$patched = parent::patchBeforeMake();
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp.h', '/^#warning.*/m', '');
|
||||
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_framing.h', '/^#warning.*/m', '');
|
||||
@@ -21,15 +20,15 @@ class amqp extends Extension
|
||||
FileSystem::replaceFileRegex(BUILD_INCLUDE_PATH . '\amqp_tcp_socket.h', '/^#warning.*/m', '');
|
||||
return true;
|
||||
}
|
||||
return $patched;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
return '--with-amqp' . ($shared ? '=shared' : '') . ' --with-librabbitmq-dir=' . BUILD_ROOT_PATH;
|
||||
return '--with-amqp --with-librabbitmq-dir=' . BUILD_ROOT_PATH;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg($shared = false): string
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
return '--with-amqp';
|
||||
}
|
||||
|
||||
@@ -6,12 +6,18 @@ 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('bz2')]
|
||||
class bz2 extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('com_dotnet')]
|
||||
class com_dotnet extends Extension
|
||||
{
|
||||
public function getWindowsConfigureArg(bool $shared = false): string
|
||||
{
|
||||
return '--enable-com-dotnet=yes';
|
||||
}
|
||||
}
|
||||
@@ -5,21 +5,23 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\linux\LinuxBuilder;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\builder\windows\WindowsBuilder;
|
||||
use SPC\exception\PatchException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('curl')]
|
||||
class curl extends Extension
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
logger()->info('patching before-configure for curl checks');
|
||||
$file1 = "AC_DEFUN([PHP_CHECK_LIBRARY], [\n $3\n])";
|
||||
$files = FileSystem::readFile($this->source_dir . '/config.m4');
|
||||
$files = FileSystem::readFile(SOURCE_PATH . '/php-src/ext/curl/config.m4');
|
||||
$file2 = 'AC_DEFUN([PHP_CHECK_LIBRARY], [
|
||||
save_old_LDFLAGS=$LDFLAGS
|
||||
ac_stuff="$5"
|
||||
@@ -38,92 +40,18 @@ class curl extends Extension
|
||||
$4
|
||||
])dnl
|
||||
])';
|
||||
file_put_contents($this->source_dir . '/config.m4', $file1 . "\n" . $files . "\n" . $file2);
|
||||
file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
$frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : '';
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-lcurl/', $this->getLibFilesString() . $frameworks);
|
||||
$this->patchBeforeSharedConfigure();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
$patched = parent::patchBeforeMake();
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||
if ($this->builder instanceof WindowsBuilder && !str_contains($extra_libs, 'secur32.lib')) {
|
||||
$extra_libs .= ' secur32.lib';
|
||||
putenv('SPC_EXTRA_LIBS=' . trim($extra_libs));
|
||||
return true;
|
||||
}
|
||||
return $patched;
|
||||
}
|
||||
|
||||
public function patchBeforeSharedConfigure(): bool
|
||||
{
|
||||
$file = $this->source_dir . '/config.m4';
|
||||
$content = FileSystem::readFile($file);
|
||||
|
||||
// Inject patch before it
|
||||
$patch = ' save_LIBS="$LIBS"
|
||||
LIBS="$LIBS $CURL_LIBS"
|
||||
';
|
||||
// Check if already patched
|
||||
if (str_contains($content, $patch)) {
|
||||
return false; // Already patched
|
||||
}
|
||||
|
||||
// Match the line containing PHP_CHECK_LIBRARY for curl
|
||||
$pattern = '/(PHP_CHECK_LIBRARY\(\[curl],\s*\[curl_easy_perform],)/';
|
||||
|
||||
// Restore LIBS after the check — append this just after the macro block
|
||||
$restore = '
|
||||
LIBS="$save_LIBS"';
|
||||
|
||||
// Apply patch
|
||||
$patched = preg_replace_callback($pattern, function ($matches) use ($patch) {
|
||||
return $patch . $matches[1];
|
||||
}, $content, 1);
|
||||
|
||||
// Inject restore after the matching PHP_CHECK_LIBRARY block
|
||||
$patched = preg_replace(
|
||||
'/(PHP_CHECK_LIBRARY\(\[curl],\s*\[curl_easy_perform],.*?\)\n)/s',
|
||||
"$1{$restore}\n",
|
||||
$patched,
|
||||
1
|
||||
);
|
||||
|
||||
if ($patched === null) {
|
||||
throw new PatchException('shared extension curl patcher', 'Failed to patch config.m4 due to a regex error');
|
||||
}
|
||||
|
||||
FileSystem::writeFile($file, $patched);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function buildUnixShared(): void
|
||||
{
|
||||
if (!$this->builder instanceof LinuxBuilder) {
|
||||
parent::buildUnixShared();
|
||||
return;
|
||||
}
|
||||
|
||||
FileSystem::replaceFileStr(
|
||||
$this->source_dir . '/config.m4',
|
||||
['$ext_dir/phar.1', '$ext_dir/phar.phar.1'],
|
||||
['${ext_dir}phar.1', '${ext_dir}phar.phar.1']
|
||||
);
|
||||
try {
|
||||
parent::buildUnixShared();
|
||||
} finally {
|
||||
FileSystem::replaceFileStr(
|
||||
$this->source_dir . '/config.m4',
|
||||
['${ext_dir}phar.1', '${ext_dir}phar.phar.1'],
|
||||
['$ext_dir/phar.1', '$ext_dir/phar.phar.1']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ use SPC\util\CustomExt;
|
||||
#[CustomExt('dba')]
|
||||
class dba extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$qdbm = $this->builder->getLib('qdbm') ? (' --with-qdbm=' . BUILD_ROOT_PATH) : '';
|
||||
return '--enable-dba' . ($shared ? '=shared' : '') . $qdbm;
|
||||
return '--enable-dba' . $qdbm;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg(bool $shared = false): string
|
||||
public function getWindowsConfigureArg(): string
|
||||
{
|
||||
$qdbm = $this->builder->getLib('qdbm') ? ' --with-qdbm' : '';
|
||||
return '--with-dba' . $qdbm;
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('dio')]
|
||||
class dio extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/ext/dio/php_dio.h')) {
|
||||
FileSystem::writeFile(SOURCE_PATH . '/php-src/ext/dio/php_dio.h', FileSystem::readFile(SOURCE_PATH . '/php-src/ext/dio/src/php_dio.h'));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('dom')]
|
||||
class dom extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
{
|
||||
$arg = '--enable-dom' . ($shared ? '=shared' : '');
|
||||
$arg .= ' --with-libxml="' . BUILD_ROOT_PATH . '"';
|
||||
return $arg;
|
||||
}
|
||||
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/win32/build/config.w32', 'dllmain.c ', '');
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getWindowsConfigureArg($shared = false): string
|
||||
{
|
||||
return '--with-dom';
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ use SPC\util\CustomExt;
|
||||
#[CustomExt('enchant')]
|
||||
class enchant extends Extension
|
||||
{
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
public function getUnixConfigureArg(): string
|
||||
{
|
||||
$glibs = [
|
||||
'/Users/jerry/project/git-project/static-php-cli/buildroot/lib/libgio-2.0.a',
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user