Compare commits

...

81 Commits

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

* Add swoole test

* Use github source for libcares

* Add libcares missing file patch

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

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

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

* prevent file_get_contents memory insufficience

* update README

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

* cleanup code, support newer phpmicro

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

* fix windows sanity check for newer phpmicro

* fix windows sanity check for newer phpmicro

* test

* test

* test

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

* Add tests
2024-05-29 14:30:31 +08:00
Jerry Ma
968b3acbce Add gen-ext-docs command (#462) 2024-05-29 13:53:08 +08:00
Jerry Ma
5d2bd93bd7 Remove dll before sanity check (#459) 2024-05-21 18:09:41 +08:00
Jerry Ma
4ba92b08ca Add extension version and env check method (#458) 2024-05-21 14:56:54 +08:00
Jerry Ma
11076b1355 Add comomand: switch-php-version (#457)
* add switch-php-version command

* update README direct download description
2024-05-21 14:54:08 +08:00
Jerry Ma
71770a0a5f Add xattr command to prevent macOS GateKeeper block (#453)
* Add xattr command to prevent macOS GateKeeper block

* test

* test

* test: disable build tests

* test

* test

* test

* update

* update
2024-05-17 19:41:02 +08:00
crazywhalecc
98d3766fe8 Add xattr command to prevent macOS GateKeeper block 2024-05-17 16:42:26 +08:00
Jerry Ma
1fdb6b439e Add compression for spc.phar and spc.exe (#452) 2024-05-17 16:34:59 +08:00
Jerry Ma
3136d6edc1 Put extension and library compatibility checks before compilation (#451) 2024-05-16 13:01:11 +08:00
Jerry Ma
3e84becf77 Fix php74 upx bug (#450)
* fix php74 cannot compile with no-strip or with-upx-pack (including lint some code)

* use captainhook installer instead of plugin composer

* use captainhook installer instead of plugin composer

* add [no build test] flag

* update actions/cache version [no build test]

* test update actions/cache version

* test update actions/cache version

* test update actions/cache version
2024-05-16 10:51:31 +08:00
Jerry Ma
1632c25223 Add extension parallel support (#444)
* Add extension parallel support

* add parallel windows support

* add parallel test

* add zts limit for parallel

* sort config

* add parallel test

* add dev-php test

* use macos-13 instead of macos-latest

* revert dev-php tests
2024-05-11 14:46:36 +08:00
crazywhalecc
e6c308c242 imap ext fix 2024-05-06 15:52:55 +08:00
crazywhalecc
3fcb7ebf03 update spc binary php version 2024-05-06 14:25:24 +08:00
Jerry Ma
7416b8079b Fix dependency util suggest calculate bug (#441)
* fix dependency util suggest calculate bug

* fix dependency util suggest calculate bug
2024-05-06 14:23:32 +08:00
Jerry Ma
bde18054e5 Fix micro upx compress bug (#440)
* triple compression for micro with upx

* place debug info first
2024-05-06 14:12:40 +08:00
Jerry Ma
954f8f4ddc fix ncurses 6.5 build (#439) 2024-05-06 14:11:50 +08:00
Jerry Ma
0fee628842 Fix xz build on macOS and Linux (#438)
* fix xz build

* add xz tests
2024-05-06 12:55:38 +08:00
Jerry Ma
69e6d82e83 add linux env var: SPC_NO_MUSL_PATH (#437) 2024-05-06 12:32:43 +08:00
crazywhalecc
e1e6270d86 update README 2024-05-06 12:08:35 +08:00
Simon Hamp
30af182aff Windows build GitHub Action (#420)
* Create build-windows-x86_64.yml

* Update build-windows-x86_64.yml

* Fix CLI param

* Fix env writing in Powershell

* Run doctor first, per docs

* Fix file paths

* Generate an acceptable cache key

* Change shell

* Improve cache key generation

* Update upload-artifact action

* Update actions

* Attempt to fix cache key storage

* Remove FPM build option
2024-05-06 11:59:02 +08:00
Jerry Ma
3ecc603770 Fix ncurses pkg-config bug temporarily (#432)
* Fix ncurses pkg-config bug temporarily

* Add tests
2024-04-30 13:57:44 +08:00
Simon Hamp
15c2935d48 Update actions (#428)
* Update action versions

* Use same dependency cache key naming logic

Bring consistency across the whole pipeline
2024-04-29 21:24:47 +08:00
Simon Hamp
7a8e0a7e67 Fix Intel Mac build action (#427)
* Fix Intel Mac build action

* Use x64 build server

* Use macos-13 runner
2024-04-29 09:12:03 +08:00
Jerry Ma
d98d6aeffb Fix FreeBSD pkg-config linking issue (#426) 2024-04-26 16:03:03 +08:00
Jerry Ma
aaa4510f25 Fix linux imagick openmp linking issue (#424) 2024-04-26 11:00:33 +08:00
Jerry Ma
b14894fab7 Fix windows UPX_EXEC env var missing (#423) 2024-04-25 16:48:31 +08:00
Jerry Ma
1a87ce4194 Fix windows nghttp2 dynamic linking bug (#422)
* fix windows nghttp2 dynamic linking bug

* add tests for fixing windows nghttp2 dynamic linking bug
2024-04-25 15:55:08 +08:00
Kévin Dunglas
6b96feb538 fix: use C++ 17 compiler for ICU (#414)
* fix: use C++ 17 compiler for ICU

* wip

* hack CXX env var to force C++17

* test intl

* test intl

* add retry for CI test download

* patch

* separate intl with newer icu c++ patch

---------

Co-authored-by: crazywhalecc <jesse2061@outlook.com>
2024-04-22 15:58:08 +08:00
Jerry Ma
21dbb8af46 change SPC_CONCURRENCT order 2024-04-14 01:15:07 +08:00
crazywhalecc
4d227ca7ef fix macOS build libpng error with old option mode 2024-04-14 01:15:07 +08:00
crazywhalecc
3a2683bb0c fix LinuxBuilder with env manager 2024-04-14 01:15:07 +08:00
crazywhalecc
bd8f91d466 add env manager 2024-04-14 01:15:07 +08:00
crazywhalecc
254844b5ec add Archlinux doctor support 2024-04-13 16:30:15 +08:00
Jerry Ma
4cb1764439 Fix libuuid build source (#411)
* fix libuuid build source

* fix libuuid build source tests
2024-04-12 21:05:51 +08:00
crazywhalecc
847535721c add macOS brew arch check for doctor 2024-04-12 16:34:58 +08:00
Jerry Ma
e3c542d9df add qdbm for dba (#409)
* add qdbm for dba

* add windows support for dba-qdbm

* fix test scripts

* fix test scripts
2024-04-12 15:53:38 +08:00
Jerry Ma
b4ed4ea956 Add ext yac (#407)
* add ext yac

* enable yac for windows

* enable yac test for windows

* correct
2024-04-12 01:43:27 +08:00
Jerry Ma
99aadd3e73 fix openssl build with corrupted pkg-config file (#406)
* fix openssl build with corrupted pkg-config file

* add test

* fix linux openssl

* add exec exit error counter for postgresql
2024-04-12 00:49:15 +08:00
Jerry Ma
c77dc1af6c Add extension simdjson support (#402)
* add extension simdjson support

* add extension simdjson tests

* fix windows build for simdjson
2024-04-02 16:57:59 +08:00
Jerry Ma
9fd56987ef Add extension ds support (#401)
* add extension ds

* add ds tests
2024-04-02 15:54:28 +08:00
crazywhalecc
1e494a2213 bump version 2024-04-02 15:06:54 +08:00
Jerry Ma
da6d9ffb4b Cmake version check (#400)
* add cmake version checker for doctor

* fix linux distro checker message
2024-04-02 15:05:49 +08:00
Jerry Ma
d3a001d808 use old xz mirror, fix CVE-2024-3094 (#399)
* use old xz mirror, fix CVE-2024-3094

* add test
2024-04-02 11:31:29 +08:00
Jerry Ma
d445668d9f trigger tests and nightly builds 2024-03-31 15:36:38 +08:00
Jerry Ma
32f14e16c8 fix pkg-config build for macOS sonoma (#391)
* fix pkg-config build for macOS sonoma

* cs fix

* bump version to 2.1.6 [skip ci]
2024-03-20 21:50:05 +08:00
Jerry Ma
46984b6df1 Fix latest libsodium compatibility (#388)
* fix #384

* bypass password-argon2 micro sanity check

* ignore funding yaml schema [skip ci]

* test linux compatibility for libargon2 and libsodium

* update composer.json to prevent smart-aleck composer [skip ci]
2024-03-16 22:37:39 +08:00
Kévin Dunglas
96c3e6b935 fix: false postive with binutils-gold 2024-03-16 18:53:53 +08:00
Jerry Ma
8092f1e481 Update FUNDING.yml 2024-03-15 22:44:05 +08:00
crazywhalecc
632f904f30 fix install-pkg different arch cache bug 2024-03-15 14:27:51 +08:00
crazywhalecc
8358a985b3 fix retry for windows 2024-03-10 17:09:49 +08:00
crazywhalecc
e21b5676e7 add --retry for download command 2024-03-10 17:09:49 +08:00
crazywhalecc
94b3afe6bc add pdo_sqlsrv for macOS and Linux 2024-03-10 15:30:51 +08:00
crazywhalecc
e4d8e5e4d2 fix ncurses build command 2024-03-10 11:53:33 +08:00
crazywhalecc
88796bc017 update tests 2024-03-10 11:53:33 +08:00
crazywhalecc
e23daaa355 enhancement for download command 2024-03-10 11:53:33 +08:00
crazywhalecc
71017361b5 fix libxml2 build on RHEL/CentOS bug 2024-03-08 14:18:33 +08:00
crazywhalecc
d202de3f50 fix libxml2 build on RHEL/CentOS bug 2024-03-08 14:11:04 +08:00
Jerry Ma
03510073c6 Fix windows curl build (#368)
* fix curl on windows build needs nghttp2.dll bug

* add curl on windows tests

* cs fix

* fix curl headers

* exit powershell properly

* reproduce zend_mm_heap corrupted

* reproduce zend_mm_heap corrupted

* reproduce zend_mm_heap corrupted

* add for-libs option for download

* add for-libs option for download

* add for-libs option for download
2024-03-05 21:43:09 +08:00
Jerry Ma
8e58592a6e Fix swoole compile bug on Linux (#367)
* swoole ci test

* swoole ci test

* fix swoole (disable-thread-context)

* restore pgsql ver

* bump version to 2.1.4
2024-03-04 15:31:39 +08:00
Jerry Ma
96dd5ba87b Add amqp/librabbitmq support for linux, macos, windows (#366)
* add amqp/librabbitmq support for linux, macos, windows

* add test for amqp
2024-03-04 10:40:23 +08:00
Jerry Ma
d4c0290195 Fix libuuid random bug when make clean (#364)
* fix libuuid random bug when `make clean`

* test

* test [skip ci]
2024-03-01 21:27:51 +08:00
Jerry Ma
f5d1df5407 add uuid/libuuid for linux and macos (#363) 2024-03-01 20:10:48 +08:00
Jerry Ma
9664709f21 Add libtiff support (#361)
* add libtiff support

* fix command option not working on *nix

* fix test with libs ext test
2024-03-01 19:19:47 +08:00
Jerry Ma
b46655ecfe Add custom Windows micro logo support (#358)
* add custom windows micro logo option `--with-micro-logo`

* bump version 2.1.2
2024-02-29 15:35:02 +08:00
Jerry Ma
842e0add29 Add ffi support for windows x64 (#357)
* add ffi support for windows x64

* add ffi test
2024-02-29 15:34:06 +08:00
crazywhalecc
254764761d bump version to 2.1.1 2024-02-26 20:11:09 +08:00
Jerry Ma
5f6c1a0f40 update postgresql version to 16.2 (#355)
* update postgresql version to 16.2

* add tests

* add tests
2024-02-26 19:55:47 +08:00
crazywhalecc
d5dcd193cf update generated spc binary 2024-02-26 00:19:30 +08:00
Jerry Ma
5012da96be Update ConsoleApplication.php 2024-02-23 11:42:10 +08:00
Jerry Ma
df0e37cd0f Add mbregex support for windows (#351)
* add mbregex support for windows

* cs fix

* fix curl http2 support
2024-02-23 11:41:35 +08:00
Jerry Ma
4ab7b6bfdc Add sqlite support for Windows (#350)
* add sqlite support

* cs fix
2024-02-23 11:14:51 +08:00
Jerry Ma
f498250001 Add multiple XML related extensions support for Windows (#349)
* update libxml2 version

* use msys2 tar.exe instead of system32/tar.exe

* add iconv, xml, dom, xmlreader, xmlwriter, soap, libxml, simplexml support

* add test

* add sysvshm support

* add quote

* add debug

* use mingw target

* fix windows tar

* fix windows tar

* fix windows tar

* fix windows tar

* fix windows tar [skip ci]
2024-02-23 00:56:28 +08:00
Jerry Ma
3945ac037b Add curl and ssh2 support for windows (#348)
* add curl and ssh2 support for windows

* add curl and ssh2 test for windows

* cs fix

* update README [skip ci]

* update README [skip ci]

* update README [skip ci]

* update README [skip ci]

* update README [skip ci]
2024-02-22 14:37:10 +08:00
crazywhalecc
b0d8b00fcc optimize pkg-config build process 2024-02-20 15:45:00 +08:00
crazywhalecc
62b0bf8af0 fix no-strip not working for linux micro 2024-02-20 10:56:39 +08:00
crazywhalecc
905e080770 fix upx linux build 2024-02-19 15:29:43 +08:00
147 changed files with 5230 additions and 1202 deletions

2
.github/FUNDING.yml vendored
View File

@@ -10,4 +10,6 @@ liberapay: # Replace with a single Liberapay username
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
custom: 'https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md' # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

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

View File

@@ -39,11 +39,11 @@ jobs:
name: build ${{ inputs.version }} on Linux x86_64
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: vendor
key: composer-dependencies
@@ -52,12 +52,17 @@ jobs:
- 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@v3
uses: actions/cache@v4
with:
path: downloads
key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
key: php-${{ env.INPUT_HASH }}
# With or without debug
- if: inputs.debug == true
@@ -80,31 +85,31 @@ jobs:
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v3
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@v3
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@v3
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@v3
- uses: actions/upload-artifact@v4
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: build-meta
path: |

View File

@@ -39,7 +39,7 @@ jobs:
name: build ${{ inputs.version }} on macOS arm64
runs-on: macos-14
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Install macOS missing packages and mark os suffix
- run: |
@@ -58,7 +58,7 @@ jobs:
# Cache composer dependencies
- id: cache-composer-deps
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: vendor
key: composer-dependencies
@@ -67,12 +67,17 @@ jobs:
- 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@v3
uses: actions/cache@v4
with:
path: downloads
key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
key: php-${{ env.INPUT_HASH }}
# With or without debug
- if: inputs.debug == true
@@ -95,31 +100,31 @@ jobs:
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v3
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@v3
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@v3
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@v3
- uses: actions/upload-artifact@v4
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: build-meta
path: |

View File

@@ -37,18 +37,26 @@ env:
jobs:
build:
name: build ${{ inputs.version }} on macOS x86_64
runs-on: macos-latest
runs-on: macos-13
steps:
- uses: actions/checkout@v3
- 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@v3
uses: actions/cache@v4
with:
path: vendor
key: composer-dependencies
@@ -57,12 +65,17 @@ jobs:
- 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@v3
uses: actions/cache@v4
with:
path: downloads
key: php-${{ inputs.version }}-dependencies-${{ inputs.extensions }}
key: php-${{ env.INPUT_HASH }}
# With or without debug
- if: inputs.debug == true
@@ -85,31 +98,31 @@ jobs:
# Upload cli executable
- if: ${{ inputs.build-cli == true }}
uses: actions/upload-artifact@v3
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@v3
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@v3
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@v3
- uses: actions/upload-artifact@v4
with:
name: license-files
path: buildroot/license/
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: build-meta
path: |

View File

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

View File

@@ -11,13 +11,13 @@ on:
jobs:
build-release-artifacts:
name: "Build SPC Binary"
runs-on: ubuntu-latest
runs-on: macos-14
strategy:
matrix:
php-version:
- "8.2"
micro-version:
- "8.2.16"
- "8.2.18"
operating-system:
- "linux-x86_64"
- "macos-x86_64"
@@ -45,7 +45,7 @@ jobs:
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: "Cache Composer dependencies"
uses: "actions/cache@v3"
uses: "actions/cache@v4"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-${{ matrix.php-version }}-locked-composer-${{ hashFiles('**/composer.lock') }}"
@@ -70,12 +70,15 @@ jobs:
- name: "Generate Executable"
run: |
bin/spc micro:combine spc.phar -M micro.sfx -O spc -I "memory_limit=2G"
if [ "${{ matrix.operating-system }}" = "windows-x64" ]; then
cat micro.sfx spc.phar > spc.exe
mv spc spc.exe
else
cat micro.sfx spc.phar > spc
chmod +x spc
fi
if [ "${{ matrix.operating-system }}" = "macos-aarch64" ] || [ "${{ matrix.operating-system }}" = "macos-x86_64" ]; then
sudo xattr -cr ./spc
fi
- name: "Archive Executable"
run: |
@@ -83,7 +86,7 @@ jobs:
tar -czf spc-${{ matrix.operating-system }}.tar.gz spc
echo "filename=spc-${{ matrix.operating-system }}.tar.gz" >> $GITHUB_ENV
echo "OS=${{ matrix.operating-system }}" >> $GITHUB_ENV
if [ "${{ matrix.operating-system }}" == "linux-x86_64" ]; then
if [ "${{ matrix.operating-system }}" == "macos-aarch64" ]; then
./spc dev:extensions
fi
else
@@ -119,7 +122,7 @@ jobs:
TARGET: ${{ secrets.DEPLOY_SERVER_TARGET_SPC_NIGHTLY }}
- name: "Upload Artifact"
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
path: spc${{ env.SUFFIX }}
name: spc-${{ matrix.operating-system }}${{ env.SUFFIX }}

View File

@@ -48,7 +48,7 @@ jobs:
- name: "Cache Composer packages"
id: composer-cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }}
@@ -86,7 +86,7 @@ jobs:
- name: "Cache Composer packages"
id: composer-cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
@@ -113,7 +113,7 @@ jobs:
- "8.3"
os:
- ubuntu-latest
- macos-latest
- macos-13
- windows-latest
- macos-14
fail-fast: false
@@ -136,9 +136,9 @@ jobs:
echo "GITHUB_TOKEN=${{ secrets.TEST_GH_TOKEN }}" >> $GITHUB_ENV
fi
- name: "Cache Composer packages"
- name: "Cache composer packages"
id: composer-cache
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
@@ -147,7 +147,7 @@ jobs:
# Cache downloaded source
- id: cache-download
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: downloads
key: php-${{ matrix.php }}-dependencies
@@ -158,13 +158,32 @@ jobs:
- name: "Run Build Tests (doctor)"
run: bin/spc doctor --auto-fix
- name: "Prepare UPX for Windows"
if: matrix.os == 'windows-latest'
run: |
bin/spc install-pkg upx
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $env:GITHUB_ENV
- name: "Prepare UPX for Linux"
if: matrix.os == 'ubunut-latest'
run: |
bin/spc install-pkg upx
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV
- name: "Run Build Tests (download)"
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 3
retry_on: error
command: bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --with-php=${{ matrix.php }} --debug
command: |
bin/spc download --for-extensions="$(php src/globals/test-extensions.php extensions)" --for-libs="$(php src/globals/test-extensions.php libs)" --with-php=${{ matrix.php }} --ignore-cache-sources=php-src,libcares --debug --retry=3
- name: "Run Build Tests (build)"
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php libs_cmd) --build-cli --build-micro --build-fpm --debug
- name: "Run Build Tests (build, *nix)"
if: matrix.os != 'windows-latest'
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug
- name: "Run Build Tests (build, windows)"
if: matrix.os == 'windows-latest'
run: bin/spc build "$(php src/globals/test-extensions.php extensions)" $(php src/globals/test-extensions.php zts) $(php src/globals/test-extensions.php no_strip) $env:UPX_CMD --with-libs="$(php src/globals/test-extensions.php libs)" --build-cli --build-micro --build-fpm --debug

View File

@@ -15,9 +15,6 @@ jobs:
steps:
- name: "Checkout static-php-cli"
uses: actions/checkout@v4
with:
ref: main
path: static-php-cli
- name: "Checkout static-php-cli-docs"
uses: actions/checkout@v4
@@ -33,7 +30,35 @@ jobs:
git config --global user.name "GitHub Actions"
- name: "Copy Config Files"
run: cp -r static-php-cli/config/* static-php-cli-docs/docs/.vitepress/config/
run: cp -r config/* static-php-cli-docs/docs/.vitepress/config/
- name: "Install PHP for official runners"
uses: "shivammathur/setup-php@v2"
with:
coverage: none
tools: composer:v2
php-version: 8.2
ini-values: memory_limit=-1
- name: "Get Composer Cache Directory"
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: "Cache Composer dependencies"
uses: "actions/cache@v4"
with:
path: "${{ steps.composer-cache.outputs.dir }}"
key: "php-8.2-locked-composer-${{ hashFiles('**/composer.lock') }}"
restore-keys: |
php-8.2-locked-composer
- name: "Install Locked Dependencies"
run: "composer install --no-interaction --no-progress"
- name: "Generate Extension Support List"
run: |
bin/spc dev:gen-ext-docs > static-php-cli-docs/docs/extensions.md
- name: "Commit and Push Changes"
run: |

View File

@@ -20,7 +20,7 @@ static-php-cli简称 `spc`)有许多特性:
- :handbag: 构建独立的单文件 PHP 解释器,无需任何依赖
- :hamburger: 构建 **[phpmicro](https://github.com/dixyes/phpmicro)** 自执行二进制(将 PHP 代码和 PHP 解释器打包为一个文件)
- :pill: 提供一键检查和修复编译环境的 Doctor 模块
- :zap: 支持多个系统:`Linux``macOS``FreeBSD`[`Windows (WIP)`](https://github.com/crazywhalecc/static-php-cli/pull/301)
- :zap: 支持多个系统:`Linux``macOS``FreeBSD``Windows`
- :wrench: 高度自定义的代码 patch 功能
- :books: 自带编译依赖管理
- 📦 提供由自身编译的独立 `spc` 二进制(使用 spc 和 [box](https://github.com/box-project/box) 构建)
@@ -43,20 +43,25 @@ static-php-cli简称 `spc`)有许多特性:
如果你不想自行编译 PHP可以从本项目现有的示例 Action 下载 Artifact也可以从自托管的服务器下载。
- [扩展组合 - common](https://dl.static-php.dev/static-php-cli/common/)common 组合包含了约 [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) 个常用扩展,体积为 22MB 左右。
- [扩展组合 - bulk](https://dl.static-php.dev/static-php-cli/bulk/)bulk 组合包含了 [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) 个扩展,体积为 70MB 左右。
- [扩展组合 - minimal](https://dl.static-php.dev/static-php-cli/minimal/)minimal 组合包含了 [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) 个扩展,体积为 6MB 左右。
- [扩展组合 - 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 左右。
> Linux 和 Windows 默认启用了 UPX 压缩,可减小 30~50% 的 PHP 二进制体积。
> macOS 当前不支持 UPX所以上述预编译的 macOS 版本体积可能较大。
对于 Windows 系统,目前支持的扩展较少,故仅提供 SPC 自身运行的最小扩展组合的 `cli``micro`[扩展组合 - spc-min](https://dl.static-php.dev/static-php-cli/windows/spc-min/)。
## 使用 static-php-cli 构建 PHP
### 编译环境需求
- PHP >= 8.1(这是 spc 自身需要的版本,不是支持的构建版本)
- 扩展:`mbstring,pcntl,posix,tokenizer,phar`
- 扩展:`mbstring,tokenizer,phar`
- 系统安装了 `curl``git`
是的,本项目采用 PHP 编写,编译前需要一个 PHP 环境,比较滑稽。
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含 mbstring、pcntl 扩展和 PHP 版本大于等于 8.1 即可。
但本项目默认可通过自身构建的 micro 和 static-php 二进制运行,其他只需要包含上面提到的扩展和 PHP 版本大于等于 8.1 即可。
下面是架构支持情况,:octocat: 代表支持 GitHub Action 构建,:computer: 代表支持本地构建,空 代表暂不支持。
@@ -64,10 +69,26 @@ static-php-cli简称 `spc`)有许多特性:
|---------|----------------------|----------------------|
| macOS | :octocat: :computer: | :octocat: :computer: |
| Linux | :octocat: :computer: | :octocat: :computer: |
| Windows | | |
| Windows | :octocat: :computer: | |
| FreeBSD | :computer: | :computer: |
前支持编译的 PHP 版本为:`7.3``7.4``8.0``8.1``8.2``8.3`
前支持编译的 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: | |
### 支持的扩展
@@ -107,10 +128,16 @@ curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-a
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 x perm
# 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)。
@@ -149,14 +176,16 @@ bin/spc --version
# 拉取所有依赖库
./bin/spc download --all
# 只拉取编译指定扩展需要的所有依赖(推荐)
./bin/spc download --for-extensions=openssl,pcntl,mbstring,pdo_sqlite
./bin/spc download --for-extensions="openssl,pcntl,mbstring,pdo_sqlite"
# 下载编译不同版本的 PHP (--with-php=x.y推荐 7.3 ~ 8.3)
./bin/spc download --for-extensions=openssl,curl,mbstring --with-php=8.1
./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
./bin/spc build "curl,phar" --enable-zts --build-cli
# 编译后使用 UPX 减小可执行文件体积 (--with-upx-pack) (至少压缩至原来的 30~50%)
./bin/spc build "curl,phar" --enable-zts --build-cli --with-upx-pack
```
其中,目前支持构建 climicrofpm 和 embed使用以下参数的一个或多个来指定编译的 SAPI
@@ -170,7 +199,7 @@ bin/spc --version
如果出现了任何错误,可以使用 `--debug` 参数来展示完整的输出日志,以供排查错误:
```bash
./bin/spc build openssl,pcntl,mbstring --debug --build-all
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
./bin/spc download --all --debug
```

View File

@@ -49,20 +49,26 @@ 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.
- [Extension-Combination - common](https://dl.static-php.dev/static-php-cli/common/): `common` contains about [30+](https://dl.static-php.dev/static-php-cli/common/README.txt) commonly used extensions, and the size is about 22MB.
- [Extension-Combination - bulk](https://dl.static-php.dev/static-php-cli/bulk/): `bulk` contains [50+](https://dl.static-php.dev/static-php-cli/bulk/README.txt) extensions and is about 70MB in size.
- [Extension-Combination - minimal](https://dl.static-php.dev/static-php-cli/minimal/): `minimal` contains [5](https://dl.static-php.dev/static-php-cli/minimal/README.txt) extensions and is about 6MB in size.
- [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
- PHP >= 8.1 (This is the version required by spc itself, not the build version)
- Extension: `mbstring,pcntl,posix,tokenizer,phar`
- Supported OS with `curl` and `git` installed
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 `mbstring`, `pcntl` extension.
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.
@@ -71,10 +77,26 @@ Here is the supported OS and arch, where :octocat: represents support for GitHub
|---------|----------------------|----------------------|
| macOS | :octocat: :computer: | :octocat: :computer: |
| Linux | :octocat: :computer: | :octocat: :computer: |
| Windows | :computer: | |
| Windows | :octocat: :computer: | |
| FreeBSD | :computer: | :computer: |
Currently supported PHP versions for compilation are: `7.3`, `7.4`, `8.0`, `8.1`, `8.2`, `8.3`.
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
@@ -117,10 +139,16 @@ curl -o spc https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-linux-a
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 x perm
# 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).
@@ -150,7 +178,7 @@ bin/spc --version
Basic usage for building php with some extensions:
> If you are using the packaged `spc` binary, you need to replace `bin/spc` with `./spc` in the following commands.
> 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
@@ -159,14 +187,16 @@ Basic usage for building php with some extensions:
# 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
./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
./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
./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
./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:
@@ -180,7 +210,7 @@ Now we support `cli`, `micro`, `fpm` and `embed` SAPI. You can use one or more o
If anything goes wrong, use `--debug` option to display full terminal output:
```bash
./bin/spc build openssl,pcntl,mbstring --debug --build-all
./bin/spc build "openssl,pcntl,mbstring" --debug --build-all
./bin/spc download --all --debug
```

View File

@@ -9,3 +9,4 @@ if (-not(Test-Path $PHP_Exec)) {
}
& "$PHP_Exec" ("bin/spc") @args
exit $LASTEXITCODE

View File

@@ -4,6 +4,7 @@
"blacklist": [
".github"
],
"compression": "GZ",
"directories": [
"config",
"src",

View File

@@ -16,8 +16,8 @@
"zhamao/logger": "^1.0"
},
"require-dev": {
"captainhook/captainhook": "^5.10",
"captainhook/plugin-composer": "^5.3",
"captainhook/captainhook-phar": "^5.23",
"captainhook/hook-installer": "^1.0",
"friendsofphp/php-cs-fixer": "^3.25",
"humbug/box": "^4.5",
"nunomaduro/collision": "^7.8",
@@ -50,9 +50,17 @@
"config": {
"allow-plugins": {
"phpstan/extension-installer": true,
"captainhook/plugin-composer": true
"captainhook/hook-installer": true,
"captainhook/plugin-composer": true,
"captainhook/captainhook-phar": true
},
"optimize-autoloader": true,
"sort-packages": true
}
},
"funding": [
{
"type": "other",
"url": "https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md"
}
]
}

1688
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,18 @@
{
"amqp": {
"support": {
"BSD": "wip"
},
"type": "external",
"arg-type": "custom",
"source": "amqp",
"lib-depends": [
"librabbitmq"
],
"ext-depends-windows": [
"openssl"
]
},
"apcu": {
"type": "external",
"source": "apcu"
@@ -7,6 +21,9 @@
"type": "builtin"
},
"bz2": {
"support": {
"Windows": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -20,26 +37,58 @@
"type": "builtin"
},
"curl": {
"notes": true,
"type": "builtin",
"arg-type": "with",
"lib-depends": [
"curl"
],
"ext-depends-windows": [
"zlib",
"openssl"
]
},
"dba": {
"type": "builtin",
"arg-type-windows": "with"
"arg-type": "custom",
"lib-suggests": [
"qdbm"
]
},
"dom": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "custom",
"arg-type-windows": "with",
"lib-depends": [
"libxml2",
"zlib"
],
"ext-depends-windows": [
"xml"
]
},
"ds": {
"type": "external",
"source": "ext-ds"
},
"enchant": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Darwin": "wip",
"Linux": "wip"
},
"type": "wip"
},
"event": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external",
"source": "ext-event",
"arg-type": "custom",
@@ -57,10 +106,18 @@
"type": "builtin"
},
"ffi": {
"support": {
"Linux": "no",
"BSD": "wip"
},
"notes": true,
"arg-type": "custom",
"type": "builtin",
"lib-depends": [
"lib-depends-unix": [
"libffi"
],
"lib-depends-windows": [
"libffi-win"
]
},
"fileinfo": {
@@ -76,6 +133,11 @@
]
},
"gd": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin",
"arg-type": "custom",
"arg-type-windows": "with",
@@ -94,6 +156,10 @@
]
},
"gettext": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -101,6 +167,12 @@
]
},
"glfw": {
"support": {
"Windows": "wip",
"BSD": "no",
"Linux": "no"
},
"notes": true,
"type": "external",
"arg-type": "custom",
"source": "ext-glfw",
@@ -110,6 +182,10 @@
"lib-depends-windows": []
},
"gmp": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -117,17 +193,32 @@
]
},
"iconv": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
"arg-type-windows": "with",
"lib-depends-unix": [
"libiconv"
],
"lib-depends-windows": [
"libiconv-win"
]
},
"igbinary": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "igbinary"
},
"imagick": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-imagick",
"arg-type": "custom",
@@ -136,26 +227,44 @@
]
},
"imap": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin",
"arg-type": "custom",
"lib-depends": [
"imap"
],
"lib-suggests": [
"ext-suggests": [
"openssl"
]
},
"inotify": {
"support": {
"Windows": "no",
"BSD": "wip",
"Darwin": "no"
},
"type": "external",
"source": "inotify"
},
"intl": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin",
"lib-depends": [
"icu"
]
},
"ldap": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -169,6 +278,16 @@
"openssl"
]
},
"libxml": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "none",
"ext-depends": [
"xml"
]
},
"mbregex": {
"type": "builtin",
"arg-type": "custom",
@@ -183,7 +302,21 @@
"type": "builtin",
"arg-type": "custom"
},
"mcrypt": {
"type": "wip",
"support": {
"Windows": "no",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"memcache": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-memcache",
"arg-type": "custom",
@@ -195,6 +328,11 @@
]
},
"memcached": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Linux": "no"
},
"type": "external",
"source": "memcached",
"arg-type": "custom",
@@ -208,6 +346,12 @@
]
},
"mongodb": {
"support": {
"Darwin": "no",
"BSD": "wip",
"Windows": "wip"
},
"notes": true,
"type": "external",
"source": "mongodb",
"arg-type": "custom",
@@ -232,11 +376,22 @@
"zlib"
]
},
"oci8": {
"type": "wip",
"support": {
"Windows": "wip",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"opcache": {
"type": "builtin",
"arg-type": "custom"
},
"openssl": {
"notes": true,
"type": "builtin",
"arg-type": "custom",
"arg-type-windows": "with",
@@ -248,7 +403,24 @@
"zlib"
]
},
"parallel": {
"support": {
"BSD": "wip"
},
"notes": true,
"type": "external",
"source": "parallel",
"arg-type-windows": "with",
"lib-depends-windows": [
"pthreads4w"
]
},
"password-argon2": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -256,6 +428,9 @@
]
},
"pcntl": {
"support": {
"Windows": "no"
},
"type": "builtin",
"unix-only": true
},
@@ -271,6 +446,10 @@
]
},
"pdo_pgsql": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"ext-depends": [
@@ -282,6 +461,9 @@
]
},
"pdo_sqlite": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with",
"ext-depends": [
@@ -292,7 +474,25 @@
"sqlite"
]
},
"pdo_sqlsrv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "pdo_sqlsrv",
"arg-type": "with",
"ext-depends": [
"pdo",
"sqlsrv"
]
},
"pgsql": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -306,19 +506,36 @@
]
},
"posix": {
"support": {
"Windows": "no"
},
"type": "builtin",
"unix-only": true
},
"protobuf": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "protobuf"
},
"rar": {
"support": {
"Windows": "wip",
"BSD": "wip",
"Darwin": "partial"
},
"notes": true,
"type": "external",
"source": "rar",
"cpp-extension": true
},
"readline": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -326,6 +543,10 @@
]
},
"redis": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "redis",
"arg-type": "custom",
@@ -344,15 +565,29 @@
"shmop": {
"type": "builtin"
},
"simdjson": {
"type": "external",
"source": "ext-simdjson",
"cpp-extension": true
},
"simplexml": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "custom",
"arg-type-windows": "with",
"lib-depends": [
"libxml2"
],
"ext-depends-windows": [
"xml"
]
},
"snappy": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-snappy",
"cpp-extension": true,
@@ -365,16 +600,26 @@
]
},
"soap": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "custom",
"lib-depends": [
"libxml2"
],
"ext-depends-windows": [
"xml"
]
},
"sockets": {
"type": "builtin"
},
"sodium": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with",
"lib-depends": [
@@ -382,13 +627,21 @@
]
},
"sqlite3": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"arg-type-windows": "with",
"lib-depends": [
"sqlite"
]
},
"sqlsrv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "sqlsrv",
"lib-depends": [
@@ -400,14 +653,27 @@
"cpp-extension": true
},
"ssh2": {
"support": {
"BSD": "wip"
},
"type": "external",
"source": "ext-ssh2",
"arg-type": "with-prefix",
"arg-type-windows": "with",
"lib-depends": [
"libssh2"
],
"ext-depends-windows": [
"openssl",
"zlib"
]
},
"swoole": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "external",
"source": "swoole",
"arg-type": "custom",
@@ -430,6 +696,11 @@
]
},
"swoole-hook-mysql": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "addon",
"arg-type": "custom",
"ext-depends": [
@@ -442,6 +713,12 @@
]
},
"swoole-hook-pgsql": {
"support": {
"Windows": "no",
"BSD": "wip",
"Darwin": "partial"
},
"notes": true,
"type": "addon",
"arg-type": "custom",
"ext-depends": [
@@ -450,6 +727,11 @@
]
},
"swoole-hook-sqlite": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"notes": true,
"type": "addon",
"arg-type": "custom",
"ext-depends": [
@@ -458,6 +740,11 @@
]
},
"swow": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external",
"source": "swow",
"arg-type": "custom",
@@ -471,18 +758,32 @@
]
},
"sysvmsg": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin",
"unix-only": true
},
"sysvsem": {
"support": {
"Windows": "no",
"BSD": "wip"
},
"type": "builtin",
"unix-only": true
},
"sysvshm": {
"type": "builtin",
"unix-only": true
"support": {
"BSD": "wip"
},
"type": "builtin"
},
"tidy": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -492,7 +793,23 @@
"tokenizer": {
"type": "builtin"
},
"uuid": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-uuid",
"arg-type": "with-prefix",
"lib-depends": [
"libuuid"
]
},
"uv": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-uv",
"arg-type": "with-prefix",
@@ -503,7 +820,22 @@
"sockets"
]
},
"xdebug": {
"type": "builtin",
"support": {
"Windows": "wip",
"BSD": "no",
"Darwin": "no",
"Linux": "no"
},
"notes": true
},
"xhprof": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"notes": true,
"type": "external",
"source": "xhprof",
"ext-depends": [
@@ -511,6 +843,10 @@
]
},
"xlswriter": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "xlswriter",
"arg-type": "custom",
@@ -520,28 +856,52 @@
]
},
"xml": {
"support": {
"BSD": "wip"
},
"notes": true,
"type": "builtin",
"arg-type": "custom",
"arg-type-windows": "with",
"lib-depends": [
"libxml2"
],
"ext-depends-windows": [
"iconv"
]
},
"xmlreader": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "custom",
"lib-depends": [
"libxml2"
],
"ext-depends-windows": [
"xml",
"dom"
]
},
"xmlwriter": {
"support": {
"BSD": "wip"
},
"type": "builtin",
"arg-type": "custom",
"lib-depends": [
"libxml2"
],
"ext-depends-windows": [
"xml"
]
},
"xsl": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"lib-depends": [
@@ -552,7 +912,22 @@
"dom"
]
},
"yac": {
"support": {
"BSD": "wip"
},
"type": "external",
"source": "yac",
"arg-type-unix": "custom",
"ext-depends-unix": [
"igbinary"
]
},
"yaml": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "yaml",
"arg-type": "with-prefix",
@@ -561,6 +936,10 @@
]
},
"zip": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "builtin",
"arg-type": "with-prefix",
"arg-type-windows": "enable",
@@ -577,6 +956,10 @@
]
},
"zstd": {
"support": {
"Windows": "wip",
"BSD": "wip"
},
"type": "external",
"source": "ext-zstd",
"arg-type": "custom",

View File

@@ -36,7 +36,7 @@
"libcurl.a"
],
"static-libs-windows": [
"libcurl.lib"
"libcurl_a.lib"
],
"headers": [
"curl"
@@ -45,19 +45,21 @@
"openssl",
"zlib"
],
"lib-suggests": [
"lib-depends-windows": [
"openssl",
"zlib",
"libssh2",
"nghttp2"
],
"lib-suggests-unix": [
"libssh2",
"brotli",
"nghttp2",
"zstd"
],
"lib-suggests-windows": [
"zlib",
"libssh2",
"brotli",
"nghttp2",
"zstd",
"openssl"
"zstd"
],
"frameworks": [
"CoreFoundation",
@@ -145,7 +147,8 @@
"libpng",
"libjpeg",
"libwebp",
"freetype"
"freetype",
"libtiff"
],
"lib-suggests": [
"zstd",
@@ -231,6 +234,17 @@
"ffitarget.h"
]
},
"libffi-win": {
"source": "libffi-win",
"static-libs-windows": [
"libffi.lib"
],
"headers-windows": [
"ffi.h",
"ffitarget.h",
"fficonfig.h"
]
},
"libiconv": {
"source": "libiconv",
"static-libs-unix": [
@@ -243,6 +257,13 @@
"localcharset.h"
]
},
"libiconv-win": {
"source": "libiconv-win",
"static-libs-windows": [
"libiconv.lib",
"libiconv_a.lib"
]
},
"libjpeg": {
"source": "libjpeg",
"static-libs-unix": [
@@ -284,6 +305,18 @@
"zlib"
]
},
"librabbitmq": {
"source": "librabbitmq",
"static-libs-unix": [
"librabbitmq.a"
],
"static-libs-windows": [
"rabbitmq.4.lib"
],
"lib-depends": [
"openssl"
]
},
"libsodium": {
"source": "libsodium",
"static-libs-unix": [
@@ -310,6 +343,21 @@
"zlib"
]
},
"libtiff": {
"source": "libtiff",
"static-libs-unix": [
"libtiff.a"
]
},
"libuuid": {
"source": "libuuid",
"static-libs-unix": [
"libuuid.a"
],
"headers": [
"uuid/uuid.h"
]
},
"libuv": {
"source": "libuv",
"static-libs-unix": [
@@ -332,21 +380,25 @@
"libxml2.a"
],
"static-libs-windows": [
[
"libxml2s.lib",
"libxml2_a.lib"
]
"libxml2s.lib",
"libxml2_a.lib"
],
"headers": [
"libxml2"
],
"lib-depends": [
"lib-depends-unix": [
"libiconv"
],
"lib-suggests": [
"lib-suggests-unix": [
"xz",
"icu",
"zlib"
],
"lib-depends-windows": [
"libiconv-win"
],
"lib-suggests-windows": [
"zlib"
]
},
"libxslt": {
@@ -427,10 +479,8 @@
"libonig.a"
],
"static-libs-windows": [
[
"onig.lib",
"onig_a.lib"
]
"onig.lib",
"onig_a.lib"
],
"headers": [
"oniggnu.h",
@@ -478,6 +528,24 @@
"zstd"
]
},
"pthreads4w": {
"source": "pthreads4w",
"static-libs-windows": [
"libpthreadVC3.lib"
]
},
"qdbm": {
"source": "qdbm",
"static-libs-unix": [
"libqdbm.a"
],
"static-libs-windows": [
"qdbm_a.lib"
],
"headers-windows": [
"depot.h"
]
},
"readline": {
"source": "readline",
"static-libs-unix": [
@@ -507,7 +575,10 @@
"static-libs-unix": [
"libsqlite3.a"
],
"headers-unix": [
"static-libs-windows": [
"libsqlite3_a.lib"
],
"headers": [
"sqlite3.h",
"sqlite3ext.h"
]

View File

@@ -6,6 +6,16 @@
"path": "LICENSE"
}
},
"amqp": {
"type": "url",
"url": "https://pecl.php.net/get/amqp",
"path": "php-src/ext/amqp",
"filename": "amqp.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"apcu": {
"type": "url",
"url": "https://pecl.php.net/get/APCu",
@@ -42,6 +52,16 @@
"path": "COPYING"
}
},
"ext-ds": {
"type": "url",
"url": "https://pecl.php.net/get/ds",
"path": "php-src/ext/ds",
"filename": "ds.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-event": {
"type": "url",
"url": "https://bitbucket.org/osmanov/pecl-event/get/3.0.8.tar.gz",
@@ -80,6 +100,16 @@
"path": "LICENSE"
}
},
"ext-simdjson": {
"type": "url",
"url": "https://pecl.php.net/get/simdjson",
"path": "php-src/ext/simdjson",
"filename": "simdjson.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-snappy": {
"type": "git",
"path": "php-src/ext/snappy",
@@ -100,6 +130,16 @@
"path": "LICENSE"
}
},
"ext-uuid": {
"type": "url",
"url": "https://pecl.php.net/get/uuid",
"path": "php-src/ext/uuid",
"filename": "uuid.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"ext-uv": {
"type": "url",
"url": "https://pecl.php.net/get/uv",
@@ -204,7 +244,7 @@
"libargon2": {
"type": "git",
"rev": "master",
"url": "https://github.com/mpociot/phc-winner-argon2",
"url": "https://github.com/static-php/phc-winner-argon2",
"license": {
"type": "file",
"path": "LICENSE"
@@ -219,9 +259,14 @@
}
},
"libcares": {
"type": "filelist",
"url": "https://c-ares.org/download/",
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/",
"type": "ghrel",
"repo": "c-ares/c-ares",
"match": "c-ares-.+\\.tar\\.gz",
"alt": {
"type": "filelist",
"url": "https://c-ares.org/download/",
"regex": "/href=\"\\/download\\/(?<file>c-ares-(?<version>[^\"]+)\\.tar\\.gz)\"/"
},
"license": {
"type": "file",
"path": "LICENSE.md"
@@ -245,6 +290,15 @@
"path": "LICENSE"
}
},
"libffi-win": {
"type": "git",
"rev": "master",
"url": "https://github.com/static-php/libffi-win.git",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"libiconv": {
"type": "filelist",
"url": "https://ftp.gnu.org/gnu/libiconv/",
@@ -254,6 +308,15 @@
"path": "COPYING"
}
},
"libiconv-win": {
"type": "git",
"rev": "master",
"url": "https://github.com/static-php/libiconv-win.git",
"license": {
"type": "file",
"path": "source/COPYING"
}
},
"libjpeg": {
"type": "ghtar",
"repo": "libjpeg-turbo/libjpeg-turbo",
@@ -289,6 +352,15 @@
"path": "LICENSE"
}
},
"librabbitmq": {
"type": "git",
"url": "https://github.com/alanxz/rabbitmq-c.git",
"rev": "master",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"libsodium": {
"type": "ghrel",
"repo": "jedisct1/libsodium",
@@ -307,6 +379,24 @@
"path": "COPYING"
}
},
"libtiff": {
"type": "filelist",
"url": "https://download.osgeo.org/libtiff/",
"regex": "/href=\"(?<file>tiff-(?<version>[^\"]+)\\.tar\\.xz)\"/",
"license": {
"type": "file",
"path": "LICENSE.md"
}
},
"libuuid": {
"type": "git",
"url": "https://github.com/static-php/libuuid.git",
"rev": "master",
"license": {
"type": "file",
"path": "COPYING"
}
},
"libuv": {
"type": "ghtar",
"repo": "libuv/libuv",
@@ -331,7 +421,7 @@
},
"libxml2": {
"type": "url",
"url": "https://github.com/GNOME/libxml2/archive/refs/tags/v2.9.14.tar.gz",
"url": "https://github.com/GNOME/libxml2/archive/refs/tags/v2.12.5.tar.gz",
"license": {
"type": "file",
"path": "Copyright"
@@ -378,7 +468,7 @@
"type": "git",
"path": "php-src/sapi/micro",
"rev": "master",
"url": "https://github.com/static-php/phpmicro",
"url": "https://github.com/easysoft/phpmicro",
"license": {
"type": "file",
"path": "LICENSE"
@@ -430,6 +520,26 @@
"path": "LICENSE.txt"
}
},
"parallel": {
"type": "url",
"url": "https://pecl.php.net/get/parallel",
"path": "php-src/ext/parallel",
"filename": "parallel.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"pdo_sqlsrv": {
"type": "url",
"url": "https://pecl.php.net/get/pdo_sqlsrv",
"path": "php-src/ext/pdo_sqlsrv",
"filename": "pdo_sqlsrv.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"pkg-config": {
"type": "url",
"url": "https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz",
@@ -440,7 +550,7 @@
},
"postgresql": {
"type": "url",
"url": "https://ftp.postgresql.org/pub/source/v16.1/postgresql-16.1.tar.gz",
"url": "https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.bz2",
"license": {
"type": "file",
"path": "COPYRIGHT"
@@ -456,6 +566,24 @@
"path": "LICENSE"
}
},
"pthreads4w": {
"type": "git",
"rev": "master",
"url": "https://git.code.sf.net/p/pthreads4w/code",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"qdbm": {
"type": "git",
"url": "https://github.com/static-php/qdbm.git",
"rev": "main",
"license": {
"type": "file",
"path": "COPYING"
}
},
"rar": {
"type": "git",
"url": "https://github.com/static-php/php-rar.git",
@@ -571,14 +699,23 @@
}
},
"xz": {
"type": "ghrel",
"repo": "tukaani-project/xz",
"match": "xz-.+\\.tar\\.gz",
"type": "url",
"url": "https://fossies.org/linux/misc/xz-5.4.6.tar.xz",
"license": {
"type": "file",
"path": "COPYING"
}
},
"yac": {
"type": "url",
"url": "https://pecl.php.net/get/yac",
"path": "php-src/ext/yac",
"filename": "yac.tgz",
"license": {
"type": "file",
"path": "LICENSE"
}
},
"yaml": {
"type": "git",
"path": "php-src/ext/yaml",

View File

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

View File

@@ -8,6 +8,7 @@ use SPC\command\BuildCliCommand;
use SPC\command\BuildLibsCommand;
use SPC\command\DeleteDownloadCommand;
use SPC\command\dev\AllExtCommand;
use SPC\command\dev\GenerateExtDocCommand;
use SPC\command\dev\PhpVerCommand;
use SPC\command\dev\SortConfigCommand;
use SPC\command\DoctorCommand;
@@ -16,16 +17,15 @@ use SPC\command\DumpLicenseCommand;
use SPC\command\ExtractCommand;
use SPC\command\InstallPkgCommand;
use SPC\command\MicroCombineCommand;
use SPC\command\SwitchPhpVersionCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\HelpCommand;
use Symfony\Component\Console\Command\ListCommand;
/**
* static-php-cli console app entry
*/
final class ConsoleApplication extends Application
{
public const VERSION = '2.1.0-beta.4';
public const VERSION = '2.2.2';
public function __construct()
{
@@ -33,6 +33,7 @@ final class ConsoleApplication extends Application
$this->addCommands(
[
// Common commands
new BuildCliCommand(),
new BuildLibsCommand(),
new DoctorCommand(),
@@ -42,17 +43,14 @@ final class ConsoleApplication extends Application
new DumpLicenseCommand(),
new ExtractCommand(),
new MicroCombineCommand(),
new SwitchPhpVersionCommand(),
// Dev commands
new AllExtCommand(),
new PhpVerCommand(),
new SortConfigCommand(),
new GenerateExtDocCommand(),
]
);
}
protected function getDefaultCommands(): array
{
return [new HelpCommand(), new ListCommand()];
}
}

View File

@@ -9,6 +9,7 @@ use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\Config;
use SPC\store\FileSystem;
use SPC\store\SourceManager;
use SPC\util\CustomExt;
@@ -33,7 +34,7 @@ abstract class BuilderBase
protected string $patch_point = '';
/**
* Build libraries
* Convert libraries to class
*
* @param array<string> $sorted_libraries Libraries to build (if not empty, must sort first)
* @throws FileSystemException
@@ -41,7 +42,27 @@ abstract class BuilderBase
* @throws WrongUsageException
* @internal
*/
abstract public function buildLibs(array $sorted_libraries);
abstract public function proveLibs(array $sorted_libraries);
/**
* Build libraries
*
* @throws FileSystemException
* @throws RuntimeException
* @throws WrongUsageException
*/
public function buildLibs(): void
{
// build all libs
foreach ($this->libs as $lib) {
match ($lib->tryBuild($this->getOption('rebuild', false))) {
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
BUILD_STATUS_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
};
}
}
/**
* Add library to build.
@@ -255,6 +276,24 @@ abstract class BuilderBase
return false;
}
public function getMicroVersion(): false|string
{
$file = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/php_micro.h');
if (!file_exists($file)) {
return false;
}
$content = file_get_contents($file);
$ver = '';
preg_match('/#define PHP_MICRO_VER_MAJ (\d)/m', $content, $match);
$ver .= $match[1] . '.';
preg_match('/#define PHP_MICRO_VER_MIN (\d)/m', $content, $match);
$ver .= $match[1] . '.';
preg_match('/#define PHP_MICRO_VER_PAT (\d)/m', $content, $match);
$ver .= $match[1];
return $ver;
}
/**
* Get build type name string to display.
*
@@ -335,6 +374,19 @@ abstract class BuilderBase
return $this->patch_point;
}
/**
* Validate libs and exts can be compiled successfully in current environment
*/
public function validateLibsAndExts(): void
{
foreach ($this->libs as $lib) {
$lib->validate();
}
foreach ($this->exts as $ext) {
$ext->validate();
}
}
public function emitPatchPoint(string $point_name): void
{
$this->patch_point = $point_name;
@@ -401,4 +453,26 @@ abstract class BuilderBase
$php .= "echo '[micro-test-end]';\n";
return $php;
}
protected function getMicroTestTasks(): array
{
return [
'micro_ext_test' => [
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests()),
'conditions' => [
function ($ret) { return $ret === 0; },
function ($ret, $out) {
$raw_out = trim(implode('', $out));
return str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
},
],
],
'micro_zend_bug_test' => [
'content' => ($this->getOption('without-micro-ext-test') ? '<?php echo "hello";' : file_get_contents(ROOT_DIR . '/src/globals/common-tests/micro_zend_mm_heap_corrupted.txt')),
'conditions' => [
function ($ret) { return $ret === 0; },
],
],
];
}
}

View File

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

View File

@@ -170,19 +170,19 @@ class Extension
public function runCliCheckUnix(): void
{
// Run compile check if build target is cli
// If you need to run some check, overwrite this or add your assert in src/globals/tests/{extension_name}.php
// If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php
// If check failed, throw RuntimeException
[$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (file_exists(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')) {
if (file_exists(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php')) {
// Trim additional content & escape special characters to allow inline usage
$test = str_replace(
['<?php', 'declare(strict_types=1);', "\n", '"', '$'],
['', '', '', '\"', '\$'],
file_get_contents(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php')
file_get_contents(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php')
);
[$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -r "' . trim($test) . '"');
@@ -201,19 +201,19 @@ class Extension
public function runCliCheckWindows(): void
{
// Run compile check if build target is cli
// If you need to run some check, overwrite this or add your assert in src/globals/tests/{extension_name}.php
// If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php
// If check failed, throw RuntimeException
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe --ri "' . $this->getDistName() . '"', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret);
}
if (file_exists(FileSystem::convertPath(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php'))) {
if (file_exists(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php'))) {
// Trim additional content & escape special characters to allow inline usage
$test = str_replace(
['<?php', 'declare(strict_types=1);', "\n", '"', '$'],
['', '', '', '\"', '\$'],
file_get_contents(FileSystem::convertPath(ROOT_DIR . '/src/globals/tests/' . $this->getName() . '.php'))
['', '', '', '\"', '$'],
file_get_contents(FileSystem::convertPath(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php'))
);
[$ret] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php.exe -r "' . trim($test) . '"');
@@ -223,6 +223,11 @@ class Extension
}
}
public function validate(): void
{
// do nothing, just throw wrong usage exception if not valid
}
/**
* @throws RuntimeException
*/

View File

@@ -177,6 +177,11 @@ abstract class LibraryBase
return false;
}
public function validate(): void
{
// do nothing, just throw wrong usage exception if not valid
}
/**
* Get current builder object.
*/
@@ -206,4 +211,9 @@ abstract class LibraryBase
}
logger()->debug('enabling ' . static::NAME . " without {$name}");
}
protected function getSnakeCaseName(): string
{
return str_replace('-', '_', static::NAME);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -31,4 +31,16 @@ class mbregex extends Extension
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !');
}
}
public function runCliCheckWindows(): void
{
[$ret, $out] = cmd()->execWithResult(BUILD_ROOT_PATH . '/bin/php --ri "mbstring"', false);
if ($ret !== 0) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli does not contain mbstring !');
}
$out = implode("\n", $out);
if (!str_contains($out, 'regex')) {
throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !');
}
}
}

View File

@@ -15,6 +15,8 @@ class mbstring extends Extension
$arg = '--enable-mbstring';
if ($this->builder->getExt('mbregex') === null) {
$arg .= ' --disable-mbregex';
} else {
$arg .= ' --enable-mbregex';
}
return $arg;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,8 +15,8 @@ class swoole extends Extension
// enable swoole
$arg = '--enable-swoole';
// commonly-used feature: coroutine-time, thread-context
$arg .= ' --enable-swoole-coro-time --enable-thread-context';
// commonly-used feature: coroutine-time, disable-thread-context
$arg .= ' --enable-swoole-coro-time --disable-thread-context';
// required feature: curl, openssl (but curl hook is buggy for php 8.0)
$arg .= $this->builder->getPHPVersionID() >= 80100 ? ' --enable-swoole-curl' : ' --disable-swoole-curl';

View File

@@ -17,12 +17,16 @@ class swoole_hook_pgsql extends Extension
return 'swoole';
}
public function getUnixConfigureArg(): string
public function validate(): void
{
// pdo_pgsql need to be disabled
if ($this->builder->getExt('pdo_pgsql') !== null) {
throw new WrongUsageException('swoole-hook-pgsql provides pdo_pgsql, if you enable pgsql hook for swoole, you must remove pdo_pgsql extension.');
}
}
public function getUnixConfigureArg(): string
{
// enable swoole pgsql hook
return '--enable-swoole-pgsql';
}

View File

@@ -17,12 +17,16 @@ class swoole_hook_sqlite extends Extension
return 'swoole';
}
public function getUnixConfigureArg(): string
public function validate(): void
{
// pdo_pgsql need to be disabled
if ($this->builder->getExt('pdo_sqlite') !== null) {
throw new WrongUsageException('swoole-hook-sqlite provides pdo_sqlite, if you enable sqlite hook for swoole, you must remove pdo_sqlite extension.');
}
}
public function getUnixConfigureArg(): string
{
// enable swoole pgsql hook
return '--enable-swoole-sqlite';
}

View File

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

View File

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

View File

@@ -6,6 +6,7 @@ namespace SPC\builder\extension;
use SPC\builder\Extension;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\util\CustomExt;
#[CustomExt('xml')]
@@ -33,4 +34,25 @@ class xml extends Extension
$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(): string
{
$arg = match ($this->name) {
'xml' => '--with-xml',
'soap' => '--enable-soap',
'xmlreader' => '--enable-xmlreader',
'xmlwriter' => '--enable-xmlwriter',
'dom' => '--with-dom',
'simplexml' => '--with-simplexml',
default => throw new RuntimeException('Not accept non-xml extension'),
};
$arg .= ' --with-libxml';
return $arg;
}
}

View File

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

View File

@@ -28,7 +28,7 @@ class BSDBuilder extends UnixBuilderBase
// ---------- set necessary options ----------
// set C Compiler (default: clang)
f_putenv('CC=' . $this->getOption('cc', 'clang'));
// set C++ Composer (default: clang++)
// set C++ Compiler (default: clang++)
f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
// set PATH
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
@@ -86,7 +86,8 @@ class BSDBuilder extends UnixBuilderBase
SourcePatcher::patchBeforeConfigure($this);
$json_74 = $this->getPHPVersionID() < 80000 ? '--enable-json ' : '';
$zts = $this->getOption('enable-zts', false) ? '--enable-zts --disable-zend-signals ' : '';
$zts_enable = $this->getPHPVersionID() < 80000 ? '--enable-maintainer-zts --disable-zend-signals' : '--enable-zts --disable-zend-signals';
$zts = $this->getOption('enable-zts', false) ? $zts_enable : '';
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
@@ -180,7 +181,7 @@ class BSDBuilder extends UnixBuilderBase
}
if ($this->getExt('phar')) {
$this->phar_patched = true;
SourcePatcher::patchMicro(['phar']);
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
}
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
@@ -201,7 +202,7 @@ class BSDBuilder extends UnixBuilderBase
$this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
SourcePatcher::unpatchMicroPhar();
}
}

View File

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

View File

@@ -220,6 +220,8 @@ class SystemUtil
'redhat',
// alpine
'alpine',
// arch
'arch', 'manjaro',
];
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -28,6 +28,7 @@ class libxml2 extends LinuxLibraryBase
'cmake ' .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
'-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DIconv_IS_BUILT_IN=OFF ' .

View File

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

View File

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

View File

@@ -11,6 +11,7 @@ use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
use SPC\store\SourcePatcher;
use SPC\util\GlobalEnvManager;
class MacOSBuilder extends UnixBuilderBase
{
@@ -26,28 +27,15 @@ class MacOSBuilder extends UnixBuilderBase
{
$this->options = $options;
// ---------- set necessary options ----------
// set C Compiler (default: clang)
f_putenv('CC=' . $this->getOption('cc', 'clang'));
// set C++ Composer (default: clang++)
f_putenv('CXX=' . $this->getOption('cxx', 'clang++'));
// set PATH
f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
// set PKG_CONFIG
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
// set PKG_CONFIG_PATH
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig/');
// apply global environment variables
GlobalEnvManager::init($this);
// set arch (default: current)
$this->setOptionIfNotExist('arch', php_uname('m'));
$this->setOptionIfNotExist('gnu-arch', arch2gnu($this->getOption('arch')));
// ---------- set necessary compile environments ----------
// ---------- set necessary compile vars ----------
// concurrency
$this->concurrency = SystemUtil::getCpuCount();
$this->concurrency = intval(getenv('SPC_CONCURRENCY'));
// cflags
$this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
$this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('arch'));
$this->arch_c_flags = getenv('SPC_DEFAULT_C_FLAGS');
$this->arch_cxx_flags = getenv('SPC_DEFAULT_CXX_FLAGS');
// cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->getOption('arch'), $this->arch_c_flags);
@@ -123,24 +111,25 @@ class MacOSBuilder extends UnixBuilderBase
*/
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
// ---------- Update extra-libs ----------
$extra_libs = $this->getOption('extra-libs', '');
// add macOS frameworks
$extra_libs .= (empty($extra_libs) ? '' : ' ') . $this->getFrameworks(true);
// add libc++, some extensions or libraries need it (C++ cannot be linked statically)
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : '');
// bloat means force-load all static libraries, even if they are not used
if (!$this->getOption('bloat', false)) {
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
} else {
logger()->info('bloat linking');
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Wl,-force_load,{$x}", array_filter($this->getAllStaticLibFiles())));
}
$this->setOption('extra-libs', $extra_libs);
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
$this->emitPatchPoint('before-php-buildconf');
SourcePatcher::patchBeforeBuildconf($this);
shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force');
shell()->cd(SOURCE_PATH . '/php-src')->exec(getenv('SPC_CMD_PREFIX_PHP_BUILDCONF'));
$this->emitPatchPoint('before-php-configure');
SourcePatcher::patchBeforeConfigure($this);
@@ -155,9 +144,9 @@ class MacOSBuilder extends UnixBuilderBase
// prepare build php envs
$envs_build_php = SystemUtil::makeEnvVarString([
'CFLAGS' => " {$this->arch_c_flags} -Werror=unknown-warning-option ",
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
'CPPFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS'),
'LDFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS'),
]);
if ($this->getLib('postgresql')) {
@@ -170,14 +159,7 @@ class MacOSBuilder extends UnixBuilderBase
shell()->cd(SOURCE_PATH . '/php-src')
->exec(
'./configure ' .
'--prefix= ' .
'--with-valgrind=no ' . // Not detect memory leak
'--enable-shared=no ' .
'--enable-static=yes ' .
'--disable-all ' .
'--disable-cgi ' .
'--disable-phpdbg ' .
getenv('SPC_CMD_PREFIX_PHP_CONFIGURE') . ' ' .
($enableCli ? '--enable-cli ' : '--disable-cli ') .
($enableFpm ? '--enable-fpm ' : '--disable-fpm ') .
($enableEmbed ? '--enable-embed=static ' : '--disable-embed ') .
@@ -227,10 +209,10 @@ class MacOSBuilder extends UnixBuilderBase
*/
protected function buildCli(): void
{
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars());
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} {$vars} cli");
$shell->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} cli");
if (!$this->getOption('no-strip', false)) {
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
}
@@ -251,26 +233,25 @@ class MacOSBuilder extends UnixBuilderBase
}
if ($this->getExt('phar')) {
$this->phar_patched = true;
SourcePatcher::patchMicro(['phar']);
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
}
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
$vars = [
// with debug information, optimize for size, remove identifiers, patch fake cli for micro
'EXTRA_CFLAGS' => '-g -Os -fno-ident' . $enable_fake_cli,
];
$vars = $this->getBuildVars($vars);
if (!$this->getOption('no-strip', false)) {
$vars = $this->getMakeExtraVars();
// patch fake cli for micro
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
if ($this->getOption('no-strip', false)) {
$vars['STRIP'] = 'dsymutil -f ';
}
$vars = SystemUtil::makeEnvVarString($vars);
shell()->cd(SOURCE_PATH . '/php-src')
->exec("make -j{$this->concurrency} {$vars} micro");
shell()->cd(SOURCE_PATH . '/php-src')->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . " {$vars} micro");
$this->deployBinary(BUILD_TARGET_MICRO);
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
SourcePatcher::unpatchMicroPhar();
}
}
@@ -282,10 +263,10 @@ class MacOSBuilder extends UnixBuilderBase
*/
protected function buildFpm(): void
{
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars());
$shell = shell()->cd(SOURCE_PATH . '/php-src');
$shell->exec("make -j{$this->concurrency} {$vars} fpm");
$shell->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . " {$vars} fpm");
if (!$this->getOption('no-strip', false)) {
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm');
}
@@ -299,11 +280,10 @@ class MacOSBuilder extends UnixBuilderBase
*/
protected function buildEmbed(): void
{
$vars = SystemUtil::makeEnvVarString($this->getBuildVars());
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars());
shell()
->cd(SOURCE_PATH . '/php-src')
->exec('make INSTALL_ROOT=' . BUILD_ROOT_PATH . " -j{$this->concurrency} {$vars} install")
shell()->cd(SOURCE_PATH . '/php-src')
->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install")
// Workaround for https://github.com/php/php-src/issues/12082
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o')
->exec('mkdir ' . BUILD_ROOT_PATH . '/lib/php-o')
@@ -314,14 +294,11 @@ class MacOSBuilder extends UnixBuilderBase
->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o');
}
private function getBuildVars($input = []): array
private function getMakeExtraVars(): array
{
$optimization = $this->getOption('no-strip', false) ? '-g -O0' : '-g0 -Os';
$cflags = isset($input['EXTRA_CFLAGS']) && $input['EXTRA_CFLAGS'] ? " {$input['EXTRA_CFLAGS']}" : '';
$libs = isset($input['EXTRA_LIBS']) && $input['EXTRA_LIBS'] ? " {$input['EXTRA_LIBS']}" : '';
return [
'EXTRA_CFLAGS' => "{$optimization} {$cflags} " . $this->getOption('x-extra-cflags'),
'EXTRA_LIBS' => "{$this->getOption('extra-libs')} -lresolv {$libs} " . $this->getOption('x-extra-libs'),
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'),
];
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -29,6 +29,7 @@ class libxml2 extends MacOSLibraryBase
// '--debug-find ' .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
'-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' .

View File

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

View File

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

View File

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

View File

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

View File

@@ -90,7 +90,7 @@ abstract class UnixBuilderBase extends BuilderBase
return $extra;
}
public function buildLibs(array $sorted_libraries): void
public function proveLibs(array $sorted_libraries): void
{
// search all supported libs
$support_lib_list = [];
@@ -137,16 +137,6 @@ abstract class UnixBuilderBase extends BuilderBase
SourceManager::initSource(libs: $sorted_libraries);
$this->emitPatchPoint('after-libs-extract');
// build all libs
foreach ($this->libs as $lib) {
match ($lib->tryBuild($this->getOption('rebuild', false))) {
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
BUILD_STATUS_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
};
}
}
/**
@@ -172,22 +162,20 @@ abstract class UnixBuilderBase extends BuilderBase
// sanity check for phpmicro
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if (file_exists(SOURCE_PATH . '/hello.exe')) {
@unlink(SOURCE_PATH . '/hello.exe');
}
file_put_contents(
SOURCE_PATH . '/hello.exe',
file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') .
($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests())
);
chmod(SOURCE_PATH . '/hello.exe', 0755);
[$ret, $output2] = shell()->execWithResult(SOURCE_PATH . '/hello.exe');
$raw_out = trim(implode('', $output2));
$condition[0] = $ret === 0;
$condition[1] = str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
foreach ($condition as $k => $v) {
if (!$v) {
throw new RuntimeException("micro failed sanity check with condition[{$k}], ret[{$ret}], out[{$raw_out}]");
$test_task = $this->getMicroTestTasks();
foreach ($test_task as $task_name => $task) {
$test_file = SOURCE_PATH . '/' . $task_name . '.exe';
if (file_exists($test_file)) {
@unlink($test_file);
}
file_put_contents($test_file, file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx') . $task['content']);
chmod($test_file, 0755);
[$ret, $out] = shell()->execWithResult($test_file);
foreach ($task['conditions'] as $condition => $closure) {
if (!$closure($ret, $out)) {
$raw_out = trim(implode('', $out));
throw new RuntimeException("micro failed sanity check: {$task_name}, condition [{$condition}], ret[{$ret}], out[{$raw_out}]");
}
}
}
}

View File

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

View File

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

View File

@@ -51,10 +51,11 @@ trait curl
FileSystem::resetDir($this->source_dir . '/build');
// compile
shell()->cd($this->source_dir . '/build')
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ../CMakeLists.txt')
->exec("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF -DBUILD_LIBCURL_DOCS=OFF {$extra} ..")
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->execWithEnv("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF -DBUILD_LIBCURL_DOCS=OFF {$extra} ..")
->execWithEnv("make -j{$this->builder->concurrency}")
->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH);
// patch pkgconf
$this->patchPkgconfPrefix(['libcurl.pc']);
shell()->cd(BUILD_LIB_PATH . '/cmake/CURL/')

View File

@@ -26,15 +26,16 @@ trait freetype
$suggested .= ' ';
shell()->cd($this->source_dir)
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->exec('sh autogen.sh')
->exec(
->execWithEnv(
'./configure ' .
'--enable-static --disable-shared --without-harfbuzz --prefix= ' .
$suggested
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->execWithEnv('make clean')
->execWithEnv("make -j{$this->builder->concurrency}")
->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['freetype2.pc']);
FileSystem::replaceFileStr(
BUILD_ROOT_PATH . '/lib/pkgconfig/freetype2.pc',

View File

@@ -11,7 +11,8 @@ trait gettext
$extra = $this->builder->getLib('ncurses') ? ('--with-libncurses-prefix=' . BUILD_ROOT_PATH . ' ') : '';
$extra .= $this->builder->getLib('libxml2') ? ('--with-libxml2-prefix=' . BUILD_ROOT_PATH . ' ') : '';
shell()->cd($this->source_dir)
->exec(
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
@@ -21,8 +22,8 @@ trait gettext
'--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' .
'--prefix=' . BUILD_ROOT_PATH
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install');
->execWithEnv('make clean')
->execWithEnv("make -j{$this->builder->concurrency}")
->execWithEnv('make install');
}
}

View File

@@ -16,13 +16,14 @@ trait gmp
protected function build(): void
{
shell()->cd($this->source_dir)
->exec(
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv(
'./configure ' .
'--enable-static --disable-shared ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->execWithEnv('make clean')
->execWithEnv("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['gmp.pc']);
}

View File

@@ -19,7 +19,7 @@ trait imagemagick
protected function build(): void
{
// TODO: imagemagick build with bzip2 failed with bugs, we need to fix it in the future
$extra = '--without-jxl --without-x --disable-openmp --without-bzlib ';
$extra = '--without-jxl --without-x --enable-openmp --without-bzlib ';
$required_libs = '';
$optional_libs = [
'libzip' => 'zip',
@@ -39,15 +39,18 @@ trait imagemagick
}
}
$ldflags = $this instanceof LinuxLibraryBase ? ('LDFLAGS="-static" ') : '';
$ldflags = $this instanceof LinuxLibraryBase ? ('-static') : '';
// libxml iconv patch
$required_libs .= $this instanceof MacOSLibraryBase ? (' -liconv') : '';
$required_libs .= $this instanceof MacOSLibraryBase ? ('-liconv') : '';
shell()->cd($this->source_dir)
->exec(
'PKG_CONFIG="$PKG_CONFIG --static" ' .
$ldflags .
"LIBS='{$required_libs}' " .
->setEnv([
'CFLAGS' => $this->getLibExtraCFlags(),
'LDFLAGS' => $this->getLibExtraLdFlags() ?: $ldflags,
'LIBS' => $this->getLibExtraLibs() ?: $required_libs,
'PKG_CONFIG' => '$PKG_CONFIG --static',
])
->execWithEnv(
'./configure ' .
'--enable-static --disable-shared ' .
$extra .

View File

@@ -25,9 +25,15 @@ trait ldap
$alt .= $this->builder->getLib('libsodium') ? '--with-argon2=libsodium ' : '--enable-argon2=no ';
f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config');
f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig');
$ldflags = '-L' . BUILD_LIB_PATH;
shell()->cd($this->source_dir)
->exec(
$this->builder->makeAutoconfFlags(AUTOCONF_LDFLAGS | AUTOCONF_CPPFLAGS) .
->setEnv([
'CFLAGS' => $this->getLibExtraCFlags(),
'LDFLAGS' => $this->getLibExtraLdFlags() ?: $ldflags,
'LIBS' => $this->getLibExtraLibs(),
])
->execWithEnv(
$this->builder->makeAutoconfFlags(AUTOCONF_CPPFLAGS) .
' ./configure ' .
'--enable-static ' .
'--disable-shared ' .

View File

@@ -11,9 +11,10 @@ trait libargon2
protected function build()
{
shell()->cd($this->source_dir)
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->exec("make PREFIX='' clean")
->exec("make -j{$this->builder->concurrency} PREFIX=''")
->exec("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH);
->execWithEnv("make -j{$this->builder->concurrency} PREFIX=''")
->execWithEnv("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['libargon2.pc']);

View File

@@ -22,9 +22,10 @@ trait libavif
FileSystem::resetDir($this->source_dir . '/build');
// Start build
shell()->cd($this->source_dir . '/build')
->exec("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF ..")
->exec("cmake --build . -j {$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF ..")
->execWithEnv("cmake --build . -j {$this->builder->concurrency}")
->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH);
// patch pkgconfig
$this->patchPkgconfPrefix(['libavif.pc']);
$this->cleanLaFiles();

View File

@@ -5,17 +5,29 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait libcares
{
public function patchBeforeBuild(): bool
{
if (!file_exists($this->source_dir . '/src/lib/thirdparty/apple/dnsinfo.h')) {
FileSystem::createDir($this->source_dir . '/src/lib/thirdparty/apple');
copy(ROOT_DIR . '/src/globals/extra/libcares_dnsinfo.h', $this->source_dir . '/src/lib/thirdparty/apple/dnsinfo.h');
return true;
}
return false;
}
/**
* @throws RuntimeException
*/
protected function build(): void
{
shell()->cd($this->source_dir)
->exec('./configure --prefix=' . BUILD_ROOT_PATH . ' --enable-static --disable-shared --disable-tests')
->exec("make -j {$this->builder->concurrency}")
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv('./configure --prefix=' . BUILD_ROOT_PATH . ' --enable-static --disable-shared --disable-tests')
->execWithEnv("make -j {$this->builder->concurrency}")
->exec('make install');
}
}

View File

@@ -20,7 +20,8 @@ trait libevent
FileSystem::resetDir($this->source_dir . '/build');
// Start build
shell()->cd($this->source_dir . '/build')
->exec(
->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv(
'cmake ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
@@ -33,7 +34,7 @@ trait libevent
'-DEVENT__DISABLE_SAMPLES=ON ' .
'..'
)
->exec("cmake --build . -j {$this->builder->concurrency}")
->execWithEnv("cmake --build . -j {$this->builder->concurrency}")
->exec('make install');
}
}

View File

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

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
trait libtiff
{
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static --disable-shared ' .
'--disable-cxx ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['libtiff-4.pc']);
}
}

View File

@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait libuuid
{
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
FileSystem::resetDir($this->source_dir . '/build');
shell()->cd($this->source_dir . '/build')
->exec(
'cmake ' .
"{$this->builder->makeCmakeArgs()} " .
'..'
)
->exec("cmake --build . -j {$this->builder->concurrency}");
copy($this->source_dir . '/build/libuuid.a', BUILD_LIB_PATH . '/libuuid.a');
FileSystem::createDir(BUILD_INCLUDE_PATH . '/uuid');
copy($this->source_dir . '/uuid.h', BUILD_INCLUDE_PATH . '/uuid/uuid.h');
$pc = FileSystem::readFile($this->source_dir . '/uuid.pc.in');
$pc = str_replace([
'@prefix@',
'@exec_prefix@',
'@libdir@',
'@includedir@',
'@LIBUUID_VERSION@',
], [
BUILD_ROOT_PATH,
'${prefix}',
'${prefix}/lib',
'${prefix}/include',
'1.0.3',
], $pc);
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/uuid.pc', $pc);
}
}

View File

@@ -17,13 +17,13 @@ trait ncurses
'--with-curses-h ' .
'--enable-pc-files ' .
'--enable-echo ' .
// '--enable-widec ' .
'--disable-widec ' .
'--with-normal ' .
'--with-ticlib ' .
'--without-tests ' .
'--without-dlsym ' .
'--without-debug ' .
'-enable-symlinks' .
'-enable-symlinks ' .
'--bindir=' . BUILD_ROOT_PATH . '/bin ' .
'--includedir=' . BUILD_ROOT_PATH . '/include ' .
'--libdir=' . BUILD_ROOT_PATH . '/lib ' .

View File

@@ -8,19 +8,18 @@ trait pkgconfig
{
protected function build(): void
{
$macos_env = "CFLAGS='{$this->builder->arch_c_flags} -Wimplicit-function-declaration' ";
$linux_env = 'LDFLAGS=--static ';
$cflags = PHP_OS_FAMILY !== 'Linux' ? "{$this->builder->arch_c_flags} -Wimplicit-function-declaration -Wno-int-conversion" : '';
$ldflags = PHP_OS_FAMILY !== 'Linux' ? '' : '--static';
shell()->cd($this->source_dir)
->exec(
match (PHP_OS_FAMILY) {
'Darwin' => $macos_env,
default => $linux_env,
} .
->setEnv(['CFLAGS' => $this->getLibExtraCFlags() ?: $cflags, 'LDFLAGS' => $this->getLibExtraLdFlags() ?: $ldflags, 'LIBS' => $this->getLibExtraLibs()])
->execWithEnv(
'./configure ' .
'--disable-shared ' .
'--enable-static ' .
'--with-internal-glib ' .
'--disable-host-tool ' .
'--with-pic ' .
'--prefix=' . BUILD_ROOT_PATH . ' ' .
'--without-sysroot ' .
'--without-system-include-path ' .
@@ -28,7 +27,8 @@ trait pkgconfig
'--without-pc-path'
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install');
->execWithEnv("make -j{$this->builder->concurrency}")
->execWithEnv('make install-exec');
shell()->exec('strip ' . BUILD_ROOT_PATH . '/bin/pkg-config');
}
}

View File

@@ -27,26 +27,31 @@ trait postgresql
'libxslt' => 'libxslt',
'icu' => 'icu-i18n',
];
$error_exec_cnt = 0;
foreach ($optional_packages as $lib => $pkg) {
if ($this->getBuilder()->getLib($lib)) {
$packages .= ' ' . $pkg;
$output = shell()->execWithResult("pkg-config --static {$pkg}");
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
logger()->info(var_export($output[1], true));
}
}
$output = shell()->execWithResult("pkg-config --cflags-only-I --static {$packages}");
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
if (!empty($output[1][0])) {
$cppflags = $output[1][0];
$envs .= " CPPFLAGS=\"{$cppflags}\"";
}
$output = shell()->execWithResult("pkg-config --libs-only-L --static {$packages}");
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
if (!empty($output[1][0])) {
$ldflags = $output[1][0];
$envs .= $this instanceof MacOSLibraryBase ? " LDFLAGS=\"{$ldflags}\" " : " LDFLAGS=\"{$ldflags} -static\" ";
}
$output = shell()->execWithResult("pkg-config --libs-only-l --static {$packages}");
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
if (!empty($output[1][0])) {
$libs = $output[1][0];
$libcpp = '';
@@ -55,14 +60,23 @@ trait postgresql
}
$envs .= " LIBS=\"{$libs}{$libcpp}\" ";
}
if ($error_exec_cnt > 0) {
throw new RuntimeException('Failed to get pkg-config information!');
}
FileSystem::resetDir($this->source_dir . '/build');
# 有静态链接配置 参考文件: src/interfaces/libpq/Makefile
shell()->cd($this->source_dir . '/build')
->exec('sed -i.backup "s/invokes exit\'; exit 1;/invokes exit\';/" ../src/interfaces/libpq/Makefile')
->exec('sed -i.backup "278 s/^/# /" ../src/Makefile.shlib')
->exec('sed -i.backup "402 s/^/# /" ../src/Makefile.shlib');
$version = $this->getVersion();
// 16.1 workaround
if (version_compare($version, '16.1') >= 0) {
# 有静态链接配置 参考文件: src/interfaces/libpq/Makefile
shell()->cd($this->source_dir . '/build')
->exec('sed -i.backup "s/invokes exit\'; exit 1;/invokes exit\';/" ../src/interfaces/libpq/Makefile')
->exec('sed -i.backup "278 s/^/# /" ../src/Makefile.shlib')
->exec('sed -i.backup "402 s/^/# /" ../src/Makefile.shlib');
} else {
throw new RuntimeException('Unsupported version for postgresql: ' . $version . ' !');
}
// configure
shell()->cd($this->source_dir . '/build')
@@ -101,4 +115,17 @@ trait postgresql
->exec("rm -rf {$builddir}/lib/*.so")
->exec("rm -rf {$builddir}/lib/*.dylib");
}
private function getVersion(): string
{
try {
$file = FileSystem::readFile($this->source_dir . '/meson.build');
if (preg_match("/^\\s+version:\\s?'(.*)'/m", $file, $match)) {
return $match[1];
}
return 'unknown';
} catch (FileSystemException) {
return 'unknown';
}
}
}

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
trait qdbm
{
/**
* @throws FileSystemException
* @throws RuntimeException
*/
protected function build(): void
{
shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static --disable-shared ' .
'--prefix='
)
->exec('make clean');
FileSystem::replaceFileRegex($this->source_dir . '/Makefile', '/MYLIBS = libqdbm.a.*/m', 'MYLIBS = libqdbm.a');
shell()->cd($this->source_dir)
->exec("make -j{$this->builder->concurrency}" . ($this instanceof MacOSLibraryBase ? ' mac' : ''))
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
$this->patchPkgconfPrefix(['qdbm.pc']);
}
}

View File

@@ -20,7 +20,6 @@ trait xz
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$this->builder->getOption('gnu-arch')}-unknown-linux " .
'--disable-scripts ' .
'--disable-doc ' .
'--with-libiconv ' .

View File

@@ -13,6 +13,7 @@ use SPC\store\FileSystem;
use SPC\store\SourceManager;
use SPC\store\SourcePatcher;
use SPC\util\DependencyUtil;
use SPC\util\GlobalEnvManager;
class WindowsBuilder extends BuilderBase
{
@@ -33,6 +34,8 @@ class WindowsBuilder extends BuilderBase
{
$this->options = $options;
GlobalEnvManager::init($this);
// ---------- set necessary options ----------
// set sdk (require visual studio 16 or 17)
$vs = SystemUtil::findVisualStudio()['version'];
@@ -42,10 +45,13 @@ class WindowsBuilder extends BuilderBase
$this->zts = $this->getOption('enable-zts', false);
// set concurrency
$this->concurrency = SystemUtil::getCpuCount();
$this->concurrency = intval(getenv('SPC_CONCURRENCY'));
// make cmake toolchain
$this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile();
f_mkdir(BUILD_INCLUDE_PATH, recursive: true);
f_mkdir(BUILD_LIB_PATH, recursive: true);
}
/**
@@ -56,9 +62,10 @@ class WindowsBuilder extends BuilderBase
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
{
// ---------- Update extra-libs ----------
$extra_libs = $this->getOption('extra-libs', '');
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
$this->setOption('extra-libs', $extra_libs);
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
$enableMicro = ($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO;
@@ -73,16 +80,26 @@ class WindowsBuilder extends BuilderBase
$zts = $this->zts ? '--enable-zts=yes ' : '--enable-zts=no ';
// with-upx-pack for phpmicro
$makefile = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.w32');
if ($this->getOption('with-upx-pack', false)) {
if (!file_exists($makefile . '.originfile')) {
copy($makefile, $makefile . '.originfile');
FileSystem::replaceFileStr($makefile, '$(MICRO_SFX):', "_MICRO_UPX = {$this->getOption('upx-exec')} --best $(MICRO_SFX)\n$(MICRO_SFX):");
FileSystem::replaceFileStr($makefile, '@$(_MICRO_MT)', "@$(_MICRO_MT)\n\t@$(_MICRO_UPX)");
if ($enableMicro && version_compare($this->getMicroVersion(), '0.2.0') < 0) {
$makefile = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.w32');
if ($this->getOption('with-upx-pack', false)) {
if (!file_exists($makefile . '.originfile')) {
copy($makefile, $makefile . '.originfile');
FileSystem::replaceFileStr($makefile, '$(MICRO_SFX):', '_MICRO_UPX = ' . getenv('UPX_EXEC') . " --best $(MICRO_SFX)\n$(MICRO_SFX):");
FileSystem::replaceFileStr($makefile, '@$(_MICRO_MT)', "@$(_MICRO_MT)\n\t@$(_MICRO_UPX)");
}
} elseif (file_exists($makefile . '.originfile')) {
copy($makefile . '.originfile', $makefile);
unlink($makefile . '.originfile');
}
} elseif (file_exists($makefile . '.originfile')) {
copy($makefile . '.originfile', $makefile);
unlink($makefile . '.originfile');
}
if (($logo = $this->getOption('with-micro-logo')) !== null) {
// realpath
$logo = realpath($logo);
$micro_logo = '--enable-micro-logo=' . $logo . ' ';
} else {
$micro_logo = '';
}
cmd()->cd(SOURCE_PATH . '\php-src')
@@ -94,7 +111,7 @@ class WindowsBuilder extends BuilderBase
'--with-extra-includes=' . BUILD_INCLUDE_PATH . ' ' .
'--with-extra-libs=' . BUILD_LIB_PATH . ' ' .
($enableCli ? '--enable-cli=yes ' : '--enable-cli=no ') .
($enableMicro ? '--enable-micro=yes ' : '--enable-micro=no ') .
($enableMicro ? ('--enable-micro=yes ' . $micro_logo) : '--enable-micro=no ') .
($enableEmbed ? '--enable-embed=yes ' : '--enable-embed=no ') .
"{$this->makeExtensionArgs()} " .
$zts .
@@ -176,19 +193,21 @@ class WindowsBuilder extends BuilderBase
// phar patch for micro
if ($this->getExt('phar')) {
$this->phar_patched = true;
SourcePatcher::patchMicro(['phar']);
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
}
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_micro_wrapper.bat --task-args micro");
if ($this->phar_patched) {
SourcePatcher::patchMicro(['phar'], true);
try {
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_micro_wrapper.bat --task-args micro");
} finally {
if ($this->phar_patched) {
SourcePatcher::unpatchMicroPhar();
}
}
$this->deployBinary(BUILD_TARGET_MICRO);
}
public function buildLibs(array $sorted_libraries): void
public function proveLibs(array $sorted_libraries): void
{
// search all supported libs
$support_lib_list = [];
@@ -225,16 +244,6 @@ class WindowsBuilder extends BuilderBase
// extract sources
SourceManager::initSource(libs: $sorted_libraries);
// build all libs
foreach ($this->libs as $lib) {
match ($lib->tryBuild($this->getOption('rebuild', false))) {
BUILD_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] build success'),
BUILD_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
BUILD_STATUS_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
};
}
}
/**
@@ -254,6 +263,12 @@ class WindowsBuilder extends BuilderBase
*/
public function sanityCheck(mixed $build_target): void
{
// remove all .dll from `buildroot/bin/`
logger()->debug('Removing all .dll files from buildroot/bin/');
$dlls = glob(BUILD_BIN_PATH . '\*.dll');
foreach ($dlls as $dll) {
@unlink($dll);
}
// sanity check for php-cli
if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) {
logger()->info('running cli sanity check');
@@ -270,22 +285,20 @@ class WindowsBuilder extends BuilderBase
// sanity check for phpmicro
if (($build_target & BUILD_TARGET_MICRO) === BUILD_TARGET_MICRO) {
if (file_exists(SOURCE_PATH . '\hello.exe')) {
@unlink(SOURCE_PATH . '\hello.exe');
}
file_put_contents(
SOURCE_PATH . '\hello.exe',
file_get_contents(BUILD_ROOT_PATH . '\bin\micro.sfx') .
($this->getOption('without-micro-ext-test') ? '<?php echo "[micro-test-start][micro-test-end]";' : $this->generateMicroExtTests())
);
chmod(SOURCE_PATH . '\hello.exe', 0755);
[$ret, $output2] = cmd()->execWithResult(SOURCE_PATH . '\hello.exe');
$raw_out = trim(implode('', $output2));
$condition[0] = $ret === 0;
$condition[1] = str_starts_with($raw_out, '[micro-test-start]') && str_ends_with($raw_out, '[micro-test-end]');
foreach ($condition as $k => $v) {
if (!$v) {
throw new RuntimeException("micro failed sanity check with condition[{$k}], ret[{$ret}], out[{$raw_out}]");
$test_task = $this->getMicroTestTasks();
foreach ($test_task as $task_name => $task) {
$test_file = SOURCE_PATH . '/' . $task_name . '.exe';
if (file_exists($test_file)) {
@unlink($test_file);
}
file_put_contents($test_file, file_get_contents(BUILD_ROOT_PATH . '\bin\micro.sfx') . $task['content']);
chmod($test_file, 0755);
[$ret, $out] = cmd()->execWithResult($test_file);
foreach ($task['conditions'] as $condition => $closure) {
if (!$closure($ret, $out)) {
$raw_out = trim(implode('', $out));
throw new RuntimeException("micro failed sanity check: {$task_name}, condition [{$condition}], ret[{$ret}], out[{$raw_out}]");
}
}
}
}
@@ -307,9 +320,11 @@ class WindowsBuilder extends BuilderBase
default => throw new RuntimeException('Deployment does not accept type ' . $type),
};
// with-upx-pack for cli
if ($this->getOption('with-upx-pack', false) && $type === BUILD_TARGET_CLI) {
cmd()->exec($this->getOption('upx-exec') . ' --best ' . escapeshellarg($src));
// with-upx-pack for cli and micro
if ($this->getOption('with-upx-pack', false)) {
if ($type === BUILD_TARGET_CLI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) {
cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src));
}
}
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');

View File

@@ -8,6 +8,8 @@ use SPC\builder\BuilderBase;
use SPC\builder\LibraryBase;
use SPC\builder\windows\WindowsBuilder;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\FileSystem;
abstract class WindowsLibraryBase extends LibraryBase
@@ -22,6 +24,36 @@ abstract class WindowsLibraryBase extends LibraryBase
return $this->builder;
}
/**
* @throws RuntimeException
* @throws FileSystemException
* @throws WrongUsageException
*/
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string
{
$libs = [$this];
if ($recursive) {
array_unshift($libs, ...array_values($this->getDependencies(recursive: true)));
}
$sep = match ($style) {
'autoconf' => ' ',
'cmake' => ';',
default => throw new RuntimeException('style only support autoconf and cmake'),
};
$ret = [];
foreach ($libs as $lib) {
$libFiles = [];
foreach ($lib->getStaticLibs() as $name) {
$name = str_replace(' ', '\ ', FileSystem::convertPath(BUILD_LIB_PATH . "/{$name}"));
$name = str_replace('"', '\"', $name);
$libFiles[] = $name;
}
array_unshift($ret, implode($sep, $libFiles));
}
return implode($sep, $ret);
}
/**
* Create a nmake wrapper file.
*

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class curl extends WindowsLibraryBase
{
public const NAME = 'curl';
protected function build(): void
{
cmd()->cd($this->source_dir . '\winbuild')
->execWithWrapper(
$this->builder->makeSimpleWrapper('nmake'),
'/f Makefile.vc WITH_DEVEL=' . BUILD_ROOT_PATH . ' ' .
'WITH_PREFIX=' . BUILD_ROOT_PATH . ' ' .
'mode=static RTLIBCFG=static WITH_SSL=static WITH_NGHTTP2=static WITH_SSH2=static ENABLE_IPV6=yes WITH_ZLIB=static MACHINE=x64 DEBUG=no'
);
FileSystem::copyDir($this->source_dir . '\include\curl', BUILD_INCLUDE_PATH . '\curl');
}
}

View File

@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\builder\windows\SystemUtil;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
class libffi_win extends WindowsLibraryBase
{
public const NAME = 'libffi-win';
protected function build()
{
$vs_ver_dir = match (SystemUtil::findVisualStudio()['version']) {
'vs17' => '/win32/vs17_x64',
'vs16' => '/win32/vs16_x64',
default => throw new RuntimeException('Current VS version is not supported yet!'),
};
// start build
cmd()->cd($this->source_dir . $vs_ver_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('msbuild'),
'libffi-msvc.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'
);
FileSystem::createDir(BUILD_LIB_PATH);
FileSystem::createDir(BUILD_INCLUDE_PATH);
copy($this->source_dir . $vs_ver_dir . '\x64\Release\libffi.lib', BUILD_LIB_PATH . '\libffi.lib');
copy($this->source_dir . $vs_ver_dir . '\x64\Release\libffi.pdb', BUILD_LIB_PATH . '\libffi.pdb');
copy($this->source_dir . '\include\ffi.h', BUILD_INCLUDE_PATH . '\ffi.h');
FileSystem::replaceFileStr(BUILD_INCLUDE_PATH . '\ffi.h', '#define LIBFFI_H', "#define LIBFFI_H\n#define FFI_BUILDING");
copy($this->source_dir . '\src\x86\ffitarget.h', BUILD_INCLUDE_PATH . '\ffitarget.h');
copy($this->source_dir . '\fficonfig.h', BUILD_INCLUDE_PATH . '\fficonfig.h');
// copy($this->source_dir . '\msvc_build\out\static-Release\X64\libffi.lib', BUILD_LIB_PATH . '\libffi.lib');
// copy($this->source_dir . '\msvc_build\include\ffi.h', BUILD_INCLUDE_PATH . '\ffi.h');
// copy($this->source_dir . '\msvc_build\include\fficonfig.h', BUILD_INCLUDE_PATH . '\fficonfig.h');
// copy($this->source_dir . '\src\x86\ffitarget.h', BUILD_INCLUDE_PATH . '\ffitarget.h');
// FileSystem::replaceFileStr(BUILD_INCLUDE_PATH . '\ffi.h', '..\..\src\x86\ffitarget.h', 'ffitarget.h');
}
}

View File

@@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\builder\windows\SystemUtil;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
class libiconv_win extends WindowsLibraryBase
{
public const NAME = 'libiconv-win';
protected function build()
{
$vs_ver_dir = match (SystemUtil::findVisualStudio()['version']) {
'vs17' => '/MSVC17',
'vs16' => '/MSVC16',
default => throw new RuntimeException('Current VS version is not supported yet!'),
};
// start build
cmd()->cd($this->source_dir . $vs_ver_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('msbuild'),
'libiconv.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'
);
FileSystem::createDir(BUILD_LIB_PATH);
FileSystem::createDir(BUILD_INCLUDE_PATH);
copy($this->source_dir . $vs_ver_dir . '\x64\lib\libiconv.lib', BUILD_LIB_PATH . '\libiconv.lib');
copy($this->source_dir . $vs_ver_dir . '\x64\lib\libiconv_a.lib', BUILD_LIB_PATH . '\libiconv_a.lib');
copy($this->source_dir . '\source\include\iconv.h', BUILD_INCLUDE_PATH . '\iconv.h');
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class librabbitmq extends WindowsLibraryBase
{
public const NAME = 'librabbitmq';
protected function build(): void
{
// reset cmake
FileSystem::resetDir($this->source_dir . '\build');
// start build
cmd()->cd($this->source_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
'-B build ' .
'-A x64 ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DBUILD_STATIC_LIBS=ON ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
"--build build --config Release --target install -j{$this->builder->concurrency}"
);
rename(BUILD_LIB_PATH . '\librabbitmq.4.lib', BUILD_LIB_PATH . '\rabbitmq.4.lib');
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class libssh2 extends WindowsLibraryBase
{
public const NAME = 'libssh2';
protected function build(): void
{
$zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
// reset cmake
FileSystem::resetDir($this->source_dir . '\build');
// start build
cmd()->cd($this->source_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
'-B build ' .
'-A x64 ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DBUILD_STATIC_LIBS=ON ' .
'-DBUILD_TESTING=OFF ' .
"-DENABLE_ZLIB_COMPRESSION={$zlib} " .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
"--build build --config Release --target install -j{$this->builder->concurrency}"
);
}
}

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class libxml2 extends WindowsLibraryBase
{
public const NAME = 'libxml2';
protected function build(): void
{
$zlib = $this->builder->getLib('zlib') ? 'ON' : 'OFF';
// reset cmake
FileSystem::resetDir($this->source_dir . '\build');
// start build
cmd()->cd($this->source_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
'-B build ' .
'-A x64 ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DBUILD_STATIC_LIBS=ON ' .
"-DLIBXML2_WITH_ZLIB={$zlib} " .
'-DLIBXML2_WITH_PYTHON=OFF ' .
'-DLIBXML2_WITH_ICONV=ON ' .
'-DIconv_LIBRARY=' . BUILD_LIB_PATH . ' ' .
'-DIconv_INCLUDE_DIR=' . BUILD_INCLUDE_PATH . ' ' .
'-DLIBXML2_WITH_LZMA=OFF ' . // xz not supported yet
'-DLIBXML2_WITH_PROGRAMS=OFF ' .
'-DLIBXML2_WITH_TESTS=OFF ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
"--build build --config Release --target install -j{$this->builder->concurrency}"
);
copy(BUILD_LIB_PATH . '\libxml2s.lib', BUILD_LIB_PATH . '\libxml2_a.lib');
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class nghttp2 extends WindowsLibraryBase
{
public const NAME = 'nghttp2';
protected function build(): void
{
// reset cmake
FileSystem::resetDir($this->source_dir . '\build');
// start build
cmd()->cd($this->source_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
'-B build ' .
'-A x64 ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DENABLE_SHARED_LIB=OFF ' .
'-DENABLE_STATIC_LIB=ON ' .
'-DBUILD_STATIC_LIBS=ON ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DENABLE_STATIC_CRT=ON ' .
'-DENABLE_LIB_ONLY=ON ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
"--build build --config Release --target install -j{$this->builder->concurrency}"
);
}
}

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class onig extends WindowsLibraryBase
{
public const NAME = 'onig';
protected function build(): void
{
// reset cmake
FileSystem::resetDir($this->source_dir . '\build');
// start build
cmd()->cd($this->source_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
'-B build ' .
'-A x64 ' .
"-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " .
'-DCMAKE_BUILD_TYPE=Release ' .
'-DBUILD_SHARED_LIBS=OFF ' .
'-DBUILD_STATIC_LIBS=ON ' .
'-DMSVC_STATIC_RUNTIME=ON ' .
'-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' '
)
->execWithWrapper(
$this->builder->makeSimpleWrapper('cmake'),
"--build build --config Release --target install -j{$this->builder->concurrency}"
);
copy(BUILD_LIB_PATH . '/onig.lib', BUILD_LIB_PATH . '/onig_a.lib');
}
}

View File

@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
class pthreads4w extends WindowsLibraryBase
{
public const NAME = 'pthreads4w';
protected function build(): void
{
cmd()->cd($this->source_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper(
'nmake /E /nologo /f Makefile ' .
'DESTROOT=' . BUILD_ROOT_PATH . ' ' .
'XCFLAGS="/MT" ' . // no dll
'EHFLAGS="/I. /DHAVE_CONFIG_H /Os /Ob2 /D__PTW32_STATIC_LIB /D__PTW32_BUILD_INLINED"'
),
'pthreadVC3.inlined_static_stamp'
);
copy($this->source_dir . '\libpthreadVC3.lib', BUILD_LIB_PATH . '\libpthreadVC3.lib');
copy($this->source_dir . '\_ptw32.h', BUILD_INCLUDE_PATH . '\_ptw32.h');
copy($this->source_dir . '\pthread.h', BUILD_INCLUDE_PATH . '\pthread.h');
copy($this->source_dir . '\sched.h', BUILD_INCLUDE_PATH . '\sched.h');
copy($this->source_dir . '\semaphore.h', BUILD_INCLUDE_PATH . '\semaphore.h');
}
}

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
use SPC\store\FileSystem;
class qdbm extends WindowsLibraryBase
{
public const NAME = 'qdbm';
protected function build(): void
{
cmd()->cd($this->source_dir)
->execWithWrapper(
$this->builder->makeSimpleWrapper('nmake'),
'/f VCMakefile'
);
copy($this->source_dir . '\qdbm_a.lib', BUILD_LIB_PATH . '\qdbm_a.lib');
copy($this->source_dir . '\depot.h', BUILD_INCLUDE_PATH . '\depot.h');
// FileSystem::copyDir($this->source_dir . '\include\curl', BUILD_INCLUDE_PATH . '\curl');
}
}

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace SPC\builder\windows\library;
class sqlite extends WindowsLibraryBase
{
public const NAME = 'sqlite';
public function patchBeforeBuild(): bool
{
copy(ROOT_DIR . '/src/globals/extra/Makefile-sqlite', $this->source_dir . '/Makefile');
return true;
}
protected function build(): void
{
cmd()->cd($this->source_dir)->execWithWrapper($this->builder->makeSimpleWrapper('nmake'), 'PREFIX=' . BUILD_ROOT_PATH . ' install-static');
}
}

View File

@@ -25,7 +25,7 @@ abstract class BaseCommand extends Command
protected OutputInterface $output;
public function __construct(string $name = null)
public function __construct(?string $name = null)
{
parent::__construct($name);
$this->addOption('debug', null, null, 'Enable debug mode');
@@ -96,6 +96,8 @@ abstract class BaseCommand extends Command
});
if ($this->shouldExecute()) {
try {
// show raw argv list for logger()->debug
logger()->debug('argv: ' . implode(' ', $_SERVER['argv']));
return $this->handle();
} catch (WrongUsageException $e) {
$msg = explode("\n", $e->getMessage());
@@ -132,4 +134,14 @@ abstract class BaseCommand extends Command
{
return true;
}
protected function logWithResult(bool $result, string $success_msg, string $fail_msg): int
{
if ($result) {
logger()->info($success_msg);
return static::SUCCESS;
}
logger()->error($fail_msg);
return static::FAILURE;
}
}

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