mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-18 04:44:53 +08:00
Merge branch 'refs/heads/main' into php-85
# Conflicts: # src/globals/test-extensions.php
This commit is contained in:
commit
fb106a3d41
4
.github/workflows/build-unix.yml
vendored
4
.github/workflows/build-unix.yml
vendored
@ -230,12 +230,12 @@ jobs:
|
||||
- uses: actions/upload-artifact@v4
|
||||
name: "Upload License Files"
|
||||
with:
|
||||
name: license-files
|
||||
name: license-files-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: buildroot/license/
|
||||
- uses: actions/upload-artifact@v4
|
||||
name: "Upload Build Metadata"
|
||||
with:
|
||||
name: build-meta
|
||||
name: build-meta-${{ inputs.php-version }}-${{ inputs.os }}
|
||||
path: |
|
||||
buildroot/build-extensions.json
|
||||
buildroot/build-libraries.json
|
||||
|
||||
9
.github/workflows/ext-matrix-tests.yml
vendored
9
.github/workflows/ext-matrix-tests.yml
vendored
@ -136,11 +136,4 @@ jobs:
|
||||
- name: "Build library: ${{ matrix.library }}"
|
||||
run: |
|
||||
SPC_USE_SUDO=yes ./bin/spc doctor --auto-fix
|
||||
if [ "${{ env.OS }}" = "linux-x86_64" ]; then
|
||||
./bin/spc install-pkg upx
|
||||
UPX=--with-upx-pack
|
||||
elif [ "${{ env.OS }}" = "linux-aarch64" ]; then
|
||||
./bin/spc install-pkg upx
|
||||
UPX=--with-upx-pack
|
||||
fi
|
||||
./bin/spc build --build-cli --build-micro --build-fpm ${{ matrix.extension }} --debug $UPX --with-suggested-libs --with-suggested-exts
|
||||
./bin/spc build --build-cli --build-micro --build-fpm ${{ matrix.extension }} --debug --with-suggested-libs --with-suggested-exts
|
||||
|
||||
5
.github/workflows/release-build.yml
vendored
5
.github/workflows/release-build.yml
vendored
@ -10,7 +10,7 @@ on:
|
||||
|
||||
env:
|
||||
PHP_VERSION: 8.4
|
||||
MICRO_VERSION: 8.4.4
|
||||
MICRO_VERSION: 8.4.10
|
||||
|
||||
jobs:
|
||||
build-release-artifacts:
|
||||
@ -42,12 +42,13 @@ jobs:
|
||||
run: echo "SPC_BUILD_DEBUG=--debug" >> $GITHUB_ENV
|
||||
|
||||
- name: "Install PHP for official runners"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
coverage: none
|
||||
tools: composer:v2
|
||||
php-version: "${{ env.PHP_VERSION }}"
|
||||
ini-values: memory_limit=-1
|
||||
extensions: curl, openssl, mbstring
|
||||
|
||||
- name: "Get Composer Cache Directory"
|
||||
id: composer-cache
|
||||
|
||||
5
.github/workflows/tests.yml
vendored
5
.github/workflows/tests.yml
vendored
@ -121,6 +121,7 @@ jobs:
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
extensions: curl, openssl, mbstring
|
||||
|
||||
- name: Define
|
||||
id: gendef
|
||||
@ -198,3 +199,7 @@ jobs:
|
||||
- name: "Run Build Tests (build - embed for non-windows)"
|
||||
if: ${{ !startsWith(matrix.os, 'windows-') }}
|
||||
run: php src/globals/test-extensions.php build_embed_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
|
||||
# - name: Setup tmate session
|
||||
# if: ${{ failure() }}
|
||||
# uses: mxschmitt/action-tmate@v3
|
||||
|
||||
3
.github/workflows/vitepress-deploy.yml
vendored
3
.github/workflows/vitepress-deploy.yml
vendored
@ -32,12 +32,13 @@ jobs:
|
||||
cp -r config/* docs/.vitepress/config/
|
||||
|
||||
- name: "Install PHP for official runners"
|
||||
uses: "shivammathur/setup-php@v2"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
coverage: none
|
||||
tools: composer:v2
|
||||
php-version: 8.4
|
||||
ini-values: memory_limit=-1
|
||||
extensions: curl, openssl, mbstring
|
||||
|
||||
- name: "Get Composer Cache Directory"
|
||||
id: composer-cache
|
||||
|
||||
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRiskyAllowed(true)
|
||||
->setUnsupportedPhpVersionAllowed(true)
|
||||
->setRules([
|
||||
'@PSR12' => true,
|
||||
'@Symfony' => true,
|
||||
|
||||
@ -86,7 +86,7 @@ RUN sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
|
||||
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
|
||||
|
||||
RUN yum update -y && \
|
||||
yum install -y devtoolset-10-gcc-*
|
||||
yum install -y devtoolset-10-gcc-* devtoolset-10-libatomic-devel
|
||||
RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc
|
||||
RUN source /etc/bashrc
|
||||
RUN yum install -y which
|
||||
|
||||
365
composer.lock
generated
365
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,6 @@
|
||||
; SPC_LINUX_DEFAULT_CXX: the default c++ compiler for linux. (For alpine linux: `g++`, default: `$GNU_ARCH-linux-musl-g++`)
|
||||
; SPC_LINUX_DEFAULT_AR: the default archiver for linux. (For alpine linux: `ar`, default: `$GNU_ARCH-linux-musl-ar`)
|
||||
|
||||
|
||||
[global]
|
||||
; Build concurrency for make -jN, default is CPU_COUNT, this value are used in every libs.
|
||||
SPC_CONCURRENCY=${CPU_COUNT}
|
||||
@ -63,6 +62,8 @@ PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools"
|
||||
UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe"
|
||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||
SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static
|
||||
; Windows static linking system libs
|
||||
SPC_EXTRA_LIBS=""
|
||||
|
||||
[linux]
|
||||
; Linux can use different build toolchain, but the toolchain can not be changed in this file:
|
||||
@ -87,7 +88,7 @@ LD=${SPC_LINUX_DEFAULT_LD}
|
||||
SPC_DEFAULT_C_FLAGS="-fPIC -Os"
|
||||
SPC_DEFAULT_CXX_FLAGS="-fPIC -Os"
|
||||
; extra libs for building php executable, used in `make` command for building php (this value may changed by extension build process, space separated)
|
||||
SPC_EXTRA_LIBS=
|
||||
SPC_EXTRA_LIBS=""
|
||||
; upx executable path
|
||||
UPX_EXEC=${PKG_ROOT_PATH}/bin/upx
|
||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||
@ -99,11 +100,11 @@ SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
|
||||
; configure command
|
||||
SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --disable-shared --enable-static --disable-all --disable-cgi --disable-phpdbg --with-pic"
|
||||
; make command
|
||||
SPC_CMD_PREFIX_PHP_MAKE="make -j${CPU_COUNT}"
|
||||
; embed type for php, static (libphp.a) or shared (libphp.so)
|
||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||
SPC_CMD_PREFIX_PHP_MAKE="make -j${SPC_CONCURRENCY}"
|
||||
|
||||
; *** default build vars for building php ***
|
||||
; embed type for php, static (libphp.a) or shared (libphp.so)
|
||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||
; CFLAGS for configuring php
|
||||
SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS} -fPIE"
|
||||
; CPPFLAGS for configuring php
|
||||
@ -113,13 +114,9 @@ SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS="-L${BUILD_LIB_PATH}"
|
||||
; LIBS for configuring php
|
||||
SPC_CMD_VAR_PHP_CONFIGURE_LIBS="-ldl -lpthread -lm"
|
||||
; EXTRA_CFLAGS for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE ${SPC_DEFAULT_C_FLAGS}"
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_DEFAULT_C_FLAGS} -g -fstack-protector-strong -fno-ident -fPIE"
|
||||
; EXTRA_LIBS for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm"
|
||||
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
|
||||
; EXTRA_LDFLAGS_PROGRAM for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -Wl,-O1 -pie"
|
||||
|
||||
[macos]
|
||||
; build target: macho or macho (possibly we could support macho-universal in the future)
|
||||
@ -132,7 +129,7 @@ CXX=clang++
|
||||
SPC_DEFAULT_C_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os"
|
||||
SPC_DEFAULT_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os"
|
||||
; extra libs for building php executable, used in `make` command for building php (this value may changed by extension build process, space separated)
|
||||
SPC_EXTRA_LIBS=
|
||||
SPC_EXTRA_LIBS=""
|
||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||
SPC_MICRO_PATCHES=cli_checks,macos_iconv
|
||||
|
||||
@ -142,9 +139,11 @@ SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
|
||||
; configure command
|
||||
SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg"
|
||||
; make command
|
||||
SPC_CMD_PREFIX_PHP_MAKE="make -j${CPU_COUNT}"
|
||||
SPC_CMD_PREFIX_PHP_MAKE="make -j${SPC_CONCURRENCY}"
|
||||
|
||||
; *** default build vars for building php ***
|
||||
; embed type for php, static (libphp.a) or shared (libphp.dylib)
|
||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||
; CFLAGS for configuring php
|
||||
SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS} -Werror=unknown-warning-option"
|
||||
; CPPFLAGS for configuring php
|
||||
@ -152,11 +151,9 @@ SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS="-I${BUILD_INCLUDE_PATH}"
|
||||
; LDFLAGS for configuring php
|
||||
SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS="-L${BUILD_LIB_PATH}"
|
||||
; EXTRA_CFLAGS for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie ${SPC_DEFAULT_C_FLAGS}"
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_DEFAULT_C_FLAGS} -g -fstack-protector-strong -fpic -fpie"
|
||||
; EXTRA_LIBS for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-lresolv"
|
||||
; embed type for php, static (libphp.a) or shared (libphp.dylib)
|
||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||
|
||||
[freebsd]
|
||||
; compiler environments
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
},
|
||||
"bz2": {
|
||||
"type": "builtin",
|
||||
"arg-type-unix": "with-prefix",
|
||||
"arg-type-unix": "with-path",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"bzip2"
|
||||
@ -185,7 +185,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"gettext"
|
||||
]
|
||||
@ -211,7 +211,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"gmp"
|
||||
]
|
||||
@ -233,7 +233,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "grpc",
|
||||
"arg-type-unix": "custom",
|
||||
"arg-type-unix": "enable-path",
|
||||
"cpp-extension": true,
|
||||
"lib-depends": [
|
||||
"grpc"
|
||||
@ -244,7 +244,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends-unix": [
|
||||
"libiconv"
|
||||
@ -320,7 +320,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"ldap"
|
||||
],
|
||||
@ -529,7 +529,7 @@
|
||||
},
|
||||
"notes": true,
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"libargon2"
|
||||
]
|
||||
@ -571,7 +571,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"arg-type-windows": "custom",
|
||||
"ext-depends": [
|
||||
"pdo",
|
||||
@ -674,7 +674,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"readline"
|
||||
],
|
||||
@ -785,7 +785,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"sqlite"
|
||||
@ -811,7 +811,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-ssh2",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libssh2"
|
||||
@ -937,7 +937,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"tidy"
|
||||
]
|
||||
@ -953,7 +953,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-uuid",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"libuuid"
|
||||
]
|
||||
@ -965,7 +965,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "ext-uv",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"libuv"
|
||||
],
|
||||
@ -1067,7 +1067,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"lib-depends": [
|
||||
"libxslt"
|
||||
],
|
||||
@ -1104,7 +1104,7 @@
|
||||
},
|
||||
"type": "external",
|
||||
"source": "yaml",
|
||||
"arg-type-unix": "with-prefix",
|
||||
"arg-type-unix": "with-path",
|
||||
"arg-type-windows": "with",
|
||||
"lib-depends": [
|
||||
"libyaml"
|
||||
@ -1115,7 +1115,7 @@
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "with-prefix",
|
||||
"arg-type": "with-path",
|
||||
"arg-type-windows": "enable",
|
||||
"lib-depends-unix": [
|
||||
"libzip"
|
||||
|
||||
130
config/lib.json
130
config/lib.json
@ -35,10 +35,10 @@
|
||||
},
|
||||
"brotli": {
|
||||
"source": "brotli",
|
||||
"static-libs-unix": [
|
||||
"libbrotlidec.a",
|
||||
"libbrotlienc.a",
|
||||
"libbrotlicommon.a"
|
||||
"pkg-configs": [
|
||||
"libbrotlicommon",
|
||||
"libbrotlidec",
|
||||
"libbrotlienc"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"brotlicommon.lib",
|
||||
@ -89,7 +89,8 @@
|
||||
"nghttp3",
|
||||
"ngtcp2",
|
||||
"zstd",
|
||||
"libcares"
|
||||
"libcares",
|
||||
"ldap"
|
||||
],
|
||||
"lib-suggests-windows": [
|
||||
"brotli",
|
||||
@ -185,14 +186,15 @@
|
||||
},
|
||||
"grpc": {
|
||||
"source": "grpc",
|
||||
"static-libs-unix": [
|
||||
"libgrpc.a",
|
||||
"libcares.a"
|
||||
"pkg-configs": [
|
||||
"grpc"
|
||||
],
|
||||
"lib-depends": [
|
||||
"zlib",
|
||||
"openssl"
|
||||
"openssl",
|
||||
"libcares"
|
||||
],
|
||||
"provide-pre-built": true,
|
||||
"frameworks": [
|
||||
"CoreFoundation"
|
||||
]
|
||||
@ -200,11 +202,10 @@
|
||||
"icu": {
|
||||
"source": "icu",
|
||||
"cpp-library": true,
|
||||
"static-libs-unix": [
|
||||
"libicui18n.a",
|
||||
"libicuio.a",
|
||||
"libicuuc.a",
|
||||
"libicudata.a"
|
||||
"pkg-configs": [
|
||||
"icu-uc",
|
||||
"icu-i18n",
|
||||
"icu-io"
|
||||
]
|
||||
},
|
||||
"icu-static-win": {
|
||||
@ -221,15 +222,16 @@
|
||||
},
|
||||
"imagemagick": {
|
||||
"source": "imagemagick",
|
||||
"static-libs-unix": [
|
||||
"libMagick++-7.Q16HDRI.a",
|
||||
"libMagickWand-7.Q16HDRI.a",
|
||||
"libMagickCore-7.Q16HDRI.a"
|
||||
"pkg-configs": [
|
||||
"Magick++-7.Q16HDRI",
|
||||
"MagickCore-7.Q16HDRI",
|
||||
"MagickWand-7.Q16HDRI"
|
||||
],
|
||||
"lib-depends": [
|
||||
"zlib",
|
||||
"libpng",
|
||||
"libjpeg",
|
||||
"libjxl",
|
||||
"libpng",
|
||||
"libwebp",
|
||||
"freetype",
|
||||
"libtiff",
|
||||
@ -252,11 +254,23 @@
|
||||
"openssl"
|
||||
]
|
||||
},
|
||||
"jbig": {
|
||||
"source": "jbig",
|
||||
"static-libs-unix": [
|
||||
"libjbig.a",
|
||||
"libjbig85.a"
|
||||
],
|
||||
"headers": [
|
||||
"jbig.h",
|
||||
"jbig85.h",
|
||||
"jbig_ar.h"
|
||||
]
|
||||
},
|
||||
"ldap": {
|
||||
"source": "ldap",
|
||||
"static-libs-unix": [
|
||||
"libldap.a",
|
||||
"liblber.a"
|
||||
"pkg-configs": [
|
||||
"ldap",
|
||||
"lber"
|
||||
],
|
||||
"lib-depends": [
|
||||
"openssl",
|
||||
@ -265,6 +279,13 @@
|
||||
"libsodium"
|
||||
]
|
||||
},
|
||||
"lerc": {
|
||||
"source": "lerc",
|
||||
"static-libs-unix": [
|
||||
"libLerc.a"
|
||||
],
|
||||
"cpp-library": true
|
||||
},
|
||||
"libacl": {
|
||||
"source": "libacl",
|
||||
"static-libs-unix": [
|
||||
@ -400,6 +421,21 @@
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"libjxl": {
|
||||
"source": "libjxl",
|
||||
"pkg-configs": [
|
||||
"libjxl",
|
||||
"libjxl_cms",
|
||||
"libjxl_threads",
|
||||
"libhwy"
|
||||
],
|
||||
"lib-depends": [
|
||||
"brotli",
|
||||
"libjpeg",
|
||||
"libpng",
|
||||
"libwebp"
|
||||
]
|
||||
},
|
||||
"liblz4": {
|
||||
"source": "liblz4",
|
||||
"static-libs-unix": [
|
||||
@ -485,9 +521,6 @@
|
||||
],
|
||||
"lib-depends": [
|
||||
"openssl"
|
||||
],
|
||||
"lib-suggests": [
|
||||
"zlib"
|
||||
]
|
||||
},
|
||||
"libtiff": {
|
||||
@ -498,6 +531,13 @@
|
||||
"lib-depends": [
|
||||
"zlib",
|
||||
"libjpeg"
|
||||
],
|
||||
"lib-suggests-unix": [
|
||||
"lerc",
|
||||
"libwebp",
|
||||
"jbig",
|
||||
"xz",
|
||||
"zstd"
|
||||
]
|
||||
},
|
||||
"libuuid": {
|
||||
@ -517,12 +557,12 @@
|
||||
},
|
||||
"libwebp": {
|
||||
"source": "libwebp",
|
||||
"static-libs-unix": [
|
||||
"libwebp.a",
|
||||
"libwebpdecoder.a",
|
||||
"libwebpdemux.a",
|
||||
"libwebpmux.a",
|
||||
"libsharpyuv.a"
|
||||
"pkg-configs": [
|
||||
"libwebp",
|
||||
"libwebpdecoder",
|
||||
"libwebpdemux",
|
||||
"libwebpmux",
|
||||
"libsharpyuv"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"libwebp.lib",
|
||||
@ -698,8 +738,8 @@
|
||||
"openssl": {
|
||||
"source": "openssl",
|
||||
"static-libs-unix": [
|
||||
"libssl.a",
|
||||
"libcrypto.a"
|
||||
"libcrypto.a",
|
||||
"libssl.a"
|
||||
],
|
||||
"static-libs-windows": [
|
||||
"libssl.lib",
|
||||
@ -714,10 +754,8 @@
|
||||
},
|
||||
"postgresql": {
|
||||
"source": "postgresql",
|
||||
"static-libs-unix": [
|
||||
"libpq.a",
|
||||
"libpgport.a",
|
||||
"libpgcommon.a"
|
||||
"pkg-configs": [
|
||||
"libpq"
|
||||
],
|
||||
"lib-depends": [
|
||||
"libiconv",
|
||||
@ -813,6 +851,15 @@
|
||||
"libiconv"
|
||||
]
|
||||
},
|
||||
"watcher": {
|
||||
"source": "watcher",
|
||||
"static-libs-unix": [
|
||||
"libwatcher-c.a"
|
||||
],
|
||||
"headers": [
|
||||
"wtr/watcher-c.h"
|
||||
]
|
||||
},
|
||||
"xz": {
|
||||
"source": "xz",
|
||||
"static-libs-unix": [
|
||||
@ -866,14 +913,5 @@
|
||||
"zstd.h",
|
||||
"zstd_errors.h"
|
||||
]
|
||||
},
|
||||
"watcher": {
|
||||
"source": "watcher",
|
||||
"static-libs-unix": [
|
||||
"libwatcher-c.a"
|
||||
],
|
||||
"headers": [
|
||||
"wtr/watcher-c.h"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"alt": false
|
||||
},
|
||||
"amqp": {
|
||||
"type": "url",
|
||||
@ -387,6 +388,19 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"jbig": {
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/jbig/jbigkit-2.1.tar.gz",
|
||||
"provide-pre-built": true,
|
||||
"alt": {
|
||||
"type": "url",
|
||||
"url": "https://www.cl.cam.ac.uk/~mgk25/jbigkit/download/jbigkit-2.1.tar.gz"
|
||||
},
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
}
|
||||
},
|
||||
"ldap": {
|
||||
"type": "filelist",
|
||||
"url": "https://www.openldap.org/software/download/OpenLDAP/openldap-release/",
|
||||
@ -396,6 +410,16 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"lerc": {
|
||||
"type": "ghtar",
|
||||
"repo": "Esri/lerc",
|
||||
"prefer-stable": true,
|
||||
"provide-pre-built": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"libacl": {
|
||||
"alt": {
|
||||
"type": "url",
|
||||
@ -533,6 +557,21 @@
|
||||
"path": "LICENSE.md"
|
||||
}
|
||||
},
|
||||
"libjxl": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/libjxl/libjxl",
|
||||
"rev": "main",
|
||||
"submodules": [
|
||||
"third_party/highway",
|
||||
"third_party/libjpeg-turbo",
|
||||
"third_party/sjpeg",
|
||||
"third_party/skcms"
|
||||
],
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"liblz4": {
|
||||
"type": "ghrel",
|
||||
"repo": "lz4/lz4",
|
||||
@ -596,6 +635,7 @@
|
||||
"repo": "libssh2/libssh2",
|
||||
"match": "libssh2.+\\.tar\\.gz",
|
||||
"prefer-stable": true,
|
||||
"provide-pre-built": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "COPYING"
|
||||
@ -605,7 +645,6 @@
|
||||
"type": "filelist",
|
||||
"url": "https://download.osgeo.org/libtiff/",
|
||||
"regex": "/href=\"(?<file>tiff-(?<version>[^\"]+)\\.tar\\.xz)\"/",
|
||||
"provide-pre-built": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "LICENSE.md"
|
||||
@ -998,6 +1037,15 @@
|
||||
"path": "COPYING"
|
||||
}
|
||||
},
|
||||
"watcher": {
|
||||
"type": "ghtar",
|
||||
"repo": "e-dant/watcher",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "license"
|
||||
}
|
||||
},
|
||||
"xdebug": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/xdebug",
|
||||
@ -1078,14 +1126,5 @@
|
||||
"type": "file",
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"watcher": {
|
||||
"type": "ghtar",
|
||||
"repo": "e-dant/watcher",
|
||||
"prefer-stable": true,
|
||||
"license": {
|
||||
"type": "file",
|
||||
"path": "license"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,13 +66,17 @@ abstract class BuilderBase
|
||||
// build all libs
|
||||
foreach ($this->libs as $lib) {
|
||||
$starttime = microtime(true);
|
||||
match ($lib->setup($this->getOption('rebuild', false))) {
|
||||
$status = $lib->setup($this->getOption('rebuild', false));
|
||||
match ($status) {
|
||||
LIB_STATUS_OK => logger()->info('lib [' . $lib::NAME . '] setup success, took ' . round(microtime(true) - $starttime, 2) . ' s'),
|
||||
LIB_STATUS_ALREADY => logger()->notice('lib [' . $lib::NAME . '] already built'),
|
||||
LIB_STATUS_BUILD_FAILED => logger()->error('lib [' . $lib::NAME . '] build failed'),
|
||||
LIB_STATUS_INSTALL_FAILED => logger()->error('lib [' . $lib::NAME . '] install failed'),
|
||||
default => logger()->warning('lib [' . $lib::NAME . '] build status unknown'),
|
||||
};
|
||||
if (in_array($status, [LIB_STATUS_BUILD_FAILED, LIB_STATUS_INSTALL_FAILED])) {
|
||||
throw new RuntimeException('Library [' . $lib::NAME . '] setup failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class Extension
|
||||
{
|
||||
@ -84,13 +83,15 @@ class Extension
|
||||
*/
|
||||
public function getEnableArg(bool $shared = false): string
|
||||
{
|
||||
$escapedPath = str_replace("'", '', escapeshellarg(BUILD_ROOT_PATH)) !== BUILD_ROOT_PATH || str_contains(BUILD_ROOT_PATH, ' ') ? escapeshellarg(BUILD_ROOT_PATH) : BUILD_ROOT_PATH;
|
||||
$_name = str_replace('_', '-', $this->name);
|
||||
return match ($arg_type = Config::getExt($this->name, 'arg-type', 'enable')) {
|
||||
'enable' => '--enable-' . $_name . ($shared ? '=shared' : '') . ' ',
|
||||
'enable-path' => '--enable-' . $_name . '=' . ($shared ? 'shared,' : '') . $escapedPath . ' ',
|
||||
'with' => '--with-' . $_name . ($shared ? '=shared' : '') . ' ',
|
||||
'with-prefix' => '--with-' . $_name . '=' . ($shared ? 'shared,' : '') . '"' . BUILD_ROOT_PATH . '" ',
|
||||
'with-path' => '--with-' . $_name . '=' . ($shared ? 'shared,' : '') . $escapedPath . ' ',
|
||||
'none', 'custom' => '',
|
||||
default => throw new WrongUsageException("argType does not accept {$arg_type}, use [enable/with/with-prefix] ."),
|
||||
default => throw new WrongUsageException("argType does not accept {$arg_type}, use [enable/with/with-path] ."),
|
||||
};
|
||||
}
|
||||
|
||||
@ -516,8 +517,7 @@ class Extension
|
||||
$sharedLibString = '';
|
||||
$staticLibString = '';
|
||||
$staticLibs = $this->getLibFilesString();
|
||||
$staticLibs = str_replace(BUILD_LIB_PATH . '/lib', '-l', $staticLibs);
|
||||
$staticLibs = str_replace('.a', '', $staticLibs);
|
||||
$staticLibs = str_replace([BUILD_LIB_PATH . '/lib', '.a'], ['-l', ''], $staticLibs);
|
||||
$staticLibs = explode('-l', $staticLibs . ' ' . $config['libs']);
|
||||
foreach ($staticLibs as $lib) {
|
||||
$lib = trim($lib);
|
||||
@ -533,8 +533,8 @@ class Extension
|
||||
$sharedLibString .= '-l' . $lib . ' ';
|
||||
}
|
||||
}
|
||||
// move static libstdc++ to shared if we are on non-full-static build target
|
||||
if (!SPCTarget::isStatic() && in_array(SPCTarget::getLibc(), SPCTarget::LIBC_LIST)) {
|
||||
// move -lstdc++ to static libraries because centos 7 the shared libstdc++ is incomplete
|
||||
if (str_contains((string) getenv('PATH'), 'rh/devtoolset-10')) {
|
||||
$staticLibString .= ' -lstdc++';
|
||||
$sharedLibString = str_replace('-lstdc++', '', $sharedLibString);
|
||||
}
|
||||
|
||||
@ -182,22 +182,8 @@ abstract class LibraryBase
|
||||
return LIB_STATUS_INSTALL_FAILED;
|
||||
}
|
||||
}
|
||||
foreach ($this->getStaticLibs() as $name) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
||||
$this->tryInstall($lock, true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
foreach ($this->getHeaders() as $name) {
|
||||
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
||||
$this->tryInstall($lock, true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
// pkg-config is treated specially. If it is pkg-config, check if the pkg-config binary exists
|
||||
if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) {
|
||||
$this->tryInstall($lock, true);
|
||||
return LIB_STATUS_OK;
|
||||
if (!$this->isLibraryInstalled()) {
|
||||
return $this->tryInstall($lock, true);
|
||||
}
|
||||
return LIB_STATUS_ALREADY;
|
||||
}
|
||||
@ -240,28 +226,8 @@ abstract class LibraryBase
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
|
||||
// check if these libraries exist, if not, invoke compilation and return the result status
|
||||
foreach ($this->getStaticLibs() as $name) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
||||
$this->tryBuild(true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
// header files the same
|
||||
foreach ($this->getHeaders() as $name) {
|
||||
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
||||
$this->tryBuild(true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
// current library is package and binary file is not exists
|
||||
if (Config::getLib(static::NAME, 'type', 'lib') === 'package') {
|
||||
foreach ($this->getBinaryFiles() as $name) {
|
||||
if (!file_exists(BUILD_BIN_PATH . "/{$name}")) {
|
||||
$this->tryBuild(true);
|
||||
return LIB_STATUS_OK;
|
||||
}
|
||||
}
|
||||
if (!$this->isLibraryInstalled()) {
|
||||
return $this->tryBuild(true);
|
||||
}
|
||||
// if all the files exist at this point, skip the compilation process
|
||||
return LIB_STATUS_ALREADY;
|
||||
@ -350,7 +316,27 @@ abstract class LibraryBase
|
||||
|
||||
protected function install(): void
|
||||
{
|
||||
// do something after extracting pre-built files, default do nothing. overwrite this method to do something
|
||||
// replace placeholders if BUILD_ROOT_PATH/.spc-extract-placeholder.json exists
|
||||
$replace_item_file = BUILD_ROOT_PATH . '/.spc-extract-placeholder.json';
|
||||
if (!file_exists($replace_item_file)) {
|
||||
return;
|
||||
}
|
||||
$replace_items = json_decode(file_get_contents($replace_item_file), true);
|
||||
if (!is_array($replace_items)) {
|
||||
throw new RuntimeException('Invalid placeholder file: ' . $replace_item_file);
|
||||
}
|
||||
$placeholders = get_pack_replace();
|
||||
// replace placeholders in BUILD_ROOT_PATH
|
||||
foreach ($replace_items as $item) {
|
||||
$filepath = BUILD_ROOT_PATH . "/{$item}";
|
||||
FileSystem::replaceFileStr(
|
||||
$filepath,
|
||||
array_values($placeholders),
|
||||
array_keys($placeholders),
|
||||
);
|
||||
}
|
||||
// remove placeholder file
|
||||
unlink($replace_item_file);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -397,4 +383,29 @@ abstract class LibraryBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function isLibraryInstalled(): bool
|
||||
{
|
||||
foreach (Config::getLib(static::NAME, 'static-libs', []) as $name) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/{$name}")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach (Config::getLib(static::NAME, 'headers', []) as $name) {
|
||||
if (!file_exists(BUILD_INCLUDE_PATH . "/{$name}")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach (Config::getLib(static::NAME, 'pkg-configs', []) as $name) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$name}.pc")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach (Config::getLib(static::NAME, 'bin', []) as $name) {
|
||||
if (!file_exists(BUILD_BIN_PATH . "/{$name}")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ namespace SPC\builder\extension;
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\linux\LinuxBuilder;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\builder\windows\WindowsBuilder;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
@ -57,6 +58,17 @@ class curl extends Extension
|
||||
return true;
|
||||
}
|
||||
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS');
|
||||
if ($this->builder instanceof WindowsBuilder && !str_contains($extra_libs, 'secur32.lib')) {
|
||||
$extra_libs .= ' secur32.lib';
|
||||
putenv('SPC_EXTRA_LIBS=' . trim($extra_libs));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function patchBeforeSharedConfigure(): bool
|
||||
{
|
||||
$file = $this->source_dir . '/config.m4';
|
||||
|
||||
@ -5,36 +5,47 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\builder\windows\WindowsBuilder;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
#[CustomExt('grpc')]
|
||||
class grpc extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
// soft link to the grpc source code
|
||||
if ($this->builder instanceof WindowsBuilder) {
|
||||
// not support windows yet
|
||||
throw new \RuntimeException('grpc extension does not support windows yet');
|
||||
}
|
||||
if (!is_link(SOURCE_PATH . '/php-src/ext/grpc')) {
|
||||
if (is_dir($this->builder->getLib('grpc')->getSourceDir() . '/src/php/ext/grpc')) {
|
||||
shell()->exec('ln -s ' . $this->builder->getLib('grpc')->getSourceDir() . '/src/php/ext/grpc ' . SOURCE_PATH . '/php-src/ext/grpc');
|
||||
} elseif (is_dir(BUILD_ROOT_PATH . '/grpc_php_ext_src')) {
|
||||
shell()->exec('ln -s ' . BUILD_ROOT_PATH . '/grpc_php_ext_src ' . SOURCE_PATH . '/php-src/ext/grpc');
|
||||
if (file_exists(SOURCE_PATH . '/php-src/ext/grpc')) {
|
||||
return false;
|
||||
}
|
||||
// soft link to the grpc source code
|
||||
if (is_dir($this->source_dir . '/src/php/ext/grpc')) {
|
||||
shell()->exec('ln -s ' . $this->source_dir . '/src/php/ext/grpc ' . SOURCE_PATH . '/php-src/ext/grpc');
|
||||
} else {
|
||||
throw new \RuntimeException('Cannot find grpc source code');
|
||||
}
|
||||
$macos = $this->builder instanceof MacOSBuilder ? "\n" . ' LDFLAGS="$LDFLAGS -framework CoreFoundation"' : '';
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/ext/grpc/config.m4', '/GRPC_LIBDIR=.*$/m', 'GRPC_LIBDIR=' . BUILD_LIB_PATH . $macos);
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/ext/grpc/config.m4', '/SEARCH_PATH=.*$/m', 'SEARCH_PATH="' . BUILD_ROOT_PATH . '"');
|
||||
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||
FileSystem::replaceFileRegex(
|
||||
SOURCE_PATH . '/php-src/ext/grpc/config.m4',
|
||||
'/GRPC_LIBDIR=.*$/m',
|
||||
'GRPC_LIBDIR=' . BUILD_LIB_PATH . "\n" . 'LDFLAGS="$LDFLAGS -framework CoreFoundation"'
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
public function patchBeforeConfigure(): bool
|
||||
{
|
||||
$util = new SPCConfigUtil($this->builder, ['libs_only_deps' => true]);
|
||||
$config = $util->config(['grpc']);
|
||||
$libs = $config['libs'];
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lgrpc', $libs);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function patchBeforeMake(): bool
|
||||
@ -43,9 +54,4 @@ class grpc extends Extension
|
||||
GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS=' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') . ' -Wno-strict-prototypes');
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
{
|
||||
return '--enable-grpc=' . BUILD_ROOT_PATH . '/grpc GRPC_LIB_SUBDIR=' . BUILD_LIB_PATH;
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,18 +63,6 @@ class BSDBuilder extends UnixBuilderBase
|
||||
*/
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||
{
|
||||
// ---------- Update extra-libs ----------
|
||||
$extra_libs = $this->getOption('extra-libs', '');
|
||||
// add libc++, some extensions or libraries need it (C++ cannot be linked statically)
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lc++ ' : '');
|
||||
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);
|
||||
|
||||
$this->emitPatchPoint('before-php-buildconf');
|
||||
SourcePatcher::patchBeforeBuildconf($this);
|
||||
|
||||
|
||||
@ -9,13 +9,4 @@ class curl extends BSDLibraryBase
|
||||
use \SPC\builder\unix\library\curl;
|
||||
|
||||
public const NAME = 'curl';
|
||||
|
||||
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string
|
||||
{
|
||||
$libs = parent::getStaticLibFiles($style, $recursive, $include_self);
|
||||
if ($this->builder->getLib('openssl')) {
|
||||
$this->builder->setOption('extra-libs', $this->builder->getOption('extra-libs') . ' /usr/lib/libpthread.a /usr/lib/libdl.a');
|
||||
}
|
||||
return $libs;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@ use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class LinuxBuilder extends UnixBuilderBase
|
||||
{
|
||||
@ -56,17 +58,6 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
*/
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||
{
|
||||
// ---------- Update extra-libs ----------
|
||||
$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 {
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', array_map(fn ($x) => "-Xcompiler {$x}", array_filter($this->getAllStaticLibFiles())));
|
||||
}
|
||||
// add libstdc++, some extensions or libraries need it
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : '');
|
||||
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
|
||||
$cflags = $this->arch_c_flags;
|
||||
f_putenv('CFLAGS=' . $cflags);
|
||||
|
||||
@ -106,7 +97,7 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
$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'),
|
||||
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
||||
'LIBS' => $mimallocLibs . getenv('SPC_CMD_VAR_PHP_CONFIGURE_LIBS'),
|
||||
]);
|
||||
|
||||
@ -308,11 +299,13 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
|
||||
private function getMakeExtraVars(): array
|
||||
{
|
||||
$config = (new SPCConfigUtil($this, ['libs_only_deps' => true, 'absolute_libs' => true]))->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
|
||||
$static = SPCTarget::isStatic() ? '-all-static' : '';
|
||||
$lib = BUILD_LIB_PATH;
|
||||
return [
|
||||
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
|
||||
'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'),
|
||||
'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'),
|
||||
'EXTRA_LDFLAGS_PROGRAM' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM'),
|
||||
'EXTRA_LIBS' => $config['libs'],
|
||||
'EXTRA_LDFLAGS_PROGRAM' => "-L{$lib} {$static} -pie",
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -9,13 +9,4 @@ class curl extends LinuxLibraryBase
|
||||
use \SPC\builder\unix\library\curl;
|
||||
|
||||
public const NAME = 'curl';
|
||||
|
||||
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string
|
||||
{
|
||||
$libs = parent::getStaticLibFiles($style, $recursive, $include_self);
|
||||
if ($this->builder->getLib('openssl')) {
|
||||
$libs .= ' -ldl -lpthread';
|
||||
}
|
||||
return $libs;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ class icu extends LinuxLibraryBase
|
||||
->exec("make -j{$this->builder->concurrency}")
|
||||
->exec('make install');
|
||||
|
||||
$this->patchPkgconfPrefix(['icu-i18n.pc', 'icu-io.pc', 'icu-uc.pc'], PKGCONF_PATCH_PREFIX);
|
||||
$this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX);
|
||||
FileSystem::removeDir(BUILD_LIB_PATH . '/icu');
|
||||
}
|
||||
}
|
||||
|
||||
12
src/SPC/builder/linux/library/jbig.php
Normal file
12
src/SPC/builder/linux/library/jbig.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class jbig extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\jbig;
|
||||
|
||||
public const NAME = 'jbig';
|
||||
}
|
||||
12
src/SPC/builder/linux/library/lerc.php
Normal file
12
src/SPC/builder/linux/library/lerc.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class lerc extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\lerc;
|
||||
|
||||
public const NAME = 'lerc';
|
||||
}
|
||||
12
src/SPC/builder/linux/library/libjxl.php
Normal file
12
src/SPC/builder/linux/library/libjxl.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
class libjxl extends LinuxLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\libjxl;
|
||||
|
||||
public const NAME = 'libjxl';
|
||||
}
|
||||
@ -67,8 +67,8 @@ class openssl extends LinuxLibraryBase
|
||||
shell()->cd($this->source_dir)->initializeEnv($this)
|
||||
->exec(
|
||||
"{$env} ./Configure no-shared {$extra} " .
|
||||
'--prefix=/ ' .
|
||||
'--libdir=lib ' .
|
||||
'--prefix=' . BUILD_ROOT_PATH . ' ' .
|
||||
'--libdir=' . BUILD_LIB_PATH . ' ' .
|
||||
'--openssldir=/etc/ssl ' .
|
||||
"{$zlib_extra}" .
|
||||
'no-legacy ' .
|
||||
@ -76,28 +76,19 @@ class openssl extends LinuxLibraryBase
|
||||
)
|
||||
->exec('make clean')
|
||||
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
||||
->exec("make install_sw DESTDIR={$destdir}");
|
||||
->exec('make install_sw');
|
||||
$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=${pcfiledir}/../..' . "\n" . $file);
|
||||
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=${pcfiledir}/../..' . "\n" . $file);
|
||||
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=${pcfiledir}/../..' . "\n" . $file);
|
||||
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
|
||||
}
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Libs.private: ${libdir}/libz.a');
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")');
|
||||
}
|
||||
|
||||
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string
|
||||
{
|
||||
$libFiles = parent::getStaticLibFiles($style, $recursive, $include_self);
|
||||
if (!str_contains('-ldl -lpthread', $libFiles)) {
|
||||
$libFiles .= ' -ldl -lpthread';
|
||||
}
|
||||
return $libFiles;
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
|
||||
class MacOSBuilder extends UnixBuilderBase
|
||||
{
|
||||
@ -88,21 +89,6 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
*/
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||
{
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||
// ---------- Update 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())));
|
||||
}
|
||||
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
|
||||
|
||||
$this->emitPatchPoint('before-php-buildconf');
|
||||
SourcePatcher::patchBeforeBuildconf($this);
|
||||
|
||||
@ -130,7 +116,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
$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'),
|
||||
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
||||
'LIBS' => $mimallocLibs . getenv('SPC_CMD_VAR_PHP_CONFIGURE_LIBS'),
|
||||
]);
|
||||
|
||||
@ -291,9 +277,11 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
|
||||
private function getMakeExtraVars(): array
|
||||
{
|
||||
$config = (new SPCConfigUtil($this, ['libs_only_deps' => true]))->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
|
||||
return [
|
||||
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
|
||||
'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'),
|
||||
'EXTRA_LDFLAGS_PROGRAM' => '-L' . BUILD_LIB_PATH,
|
||||
'EXTRA_LIBS' => $config['libs'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ class icu extends MacOSLibraryBase
|
||||
->exec("make -j{$this->builder->concurrency}")
|
||||
->exec('make install');
|
||||
|
||||
$this->patchPkgconfPrefix(['icu-i18n.pc', 'icu-io.pc', 'icu-uc.pc'], PKGCONF_PATCH_PREFIX);
|
||||
$this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX);
|
||||
FileSystem::removeDir(BUILD_LIB_PATH . '/icu');
|
||||
}
|
||||
}
|
||||
|
||||
12
src/SPC/builder/macos/library/jbig.php
Normal file
12
src/SPC/builder/macos/library/jbig.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
class jbig extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\jbig;
|
||||
|
||||
public const NAME = 'jbig';
|
||||
}
|
||||
12
src/SPC/builder/macos/library/lerc.php
Normal file
12
src/SPC/builder/macos/library/lerc.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
class lerc extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\lerc;
|
||||
|
||||
public const NAME = 'lerc';
|
||||
}
|
||||
12
src/SPC/builder/macos/library/libjxl.php
Normal file
12
src/SPC/builder/macos/library/libjxl.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\macos\library;
|
||||
|
||||
class libjxl extends MacOSLibraryBase
|
||||
{
|
||||
use \SPC\builder\unix\library\libjxl;
|
||||
|
||||
public const NAME = 'libjxl';
|
||||
}
|
||||
@ -37,8 +37,6 @@ class openssl extends MacOSLibraryBase
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
[$lib,,$destdir] = SEPARATED_PATH;
|
||||
|
||||
// lib:zlib
|
||||
$extra = '';
|
||||
$ex_lib = '';
|
||||
@ -52,24 +50,24 @@ class openssl extends MacOSLibraryBase
|
||||
shell()->cd($this->source_dir)->initializeEnv($this)
|
||||
->exec(
|
||||
"./Configure no-shared {$extra} " .
|
||||
'--prefix=/ ' . // use prefix=/
|
||||
"--libdir={$lib} " .
|
||||
'--prefix=' . BUILD_ROOT_PATH . ' ' . // use prefix=/
|
||||
'--libdir=lib ' .
|
||||
'--openssldir=/etc/ssl ' .
|
||||
"darwin64-{$arch}-cc"
|
||||
)
|
||||
->exec('make clean')
|
||||
->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")
|
||||
->exec("make install_sw DESTDIR={$destdir}");
|
||||
->exec('make install_sw');
|
||||
$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=${pcfiledir}/../..' . "\n" . $file);
|
||||
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=${pcfiledir}/../..' . "\n" . $file);
|
||||
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=${pcfiledir}/../..' . "\n" . $file);
|
||||
FileSystem::writeFile(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', 'prefix=' . BUILD_ROOT_PATH . "\n" . $file);
|
||||
}
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Libs.private: ${libdir}/libz.a');
|
||||
FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")');
|
||||
|
||||
@ -4,11 +4,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\traits;
|
||||
|
||||
use SPC\builder\LibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
|
||||
trait UnixLibraryTrait
|
||||
{
|
||||
@ -17,44 +18,13 @@ trait UnixLibraryTrait
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string
|
||||
public function getStaticLibFiles(bool $include_self = true): string
|
||||
{
|
||||
$libs = $include_self ? [$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 = [];
|
||||
/** @var LibraryBase $lib */
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function makeAutoconfEnv(?string $prefix = null): string
|
||||
{
|
||||
if ($prefix === null) {
|
||||
$prefix = str_replace('-', '_', strtoupper(static::NAME));
|
||||
}
|
||||
return $prefix . '_CFLAGS="-I' . BUILD_INCLUDE_PATH . '" ' .
|
||||
$prefix . '_LIBS="' . $this->getStaticLibFiles() . '"';
|
||||
$config = new SPCConfigUtil($this->builder, options: ['libs_only_deps' => true, 'absolute_libs' => true]);
|
||||
$res = $config->config(libraries: array_map(fn ($x) => $x->getName(), $libs));
|
||||
return $res['libs'];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,9 +34,12 @@ trait UnixLibraryTrait
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function patchPkgconfPrefix(array $files, int $patch_option = PKGCONF_PATCH_ALL, ?array $custom_replace = null): void
|
||||
public function patchPkgconfPrefix(array $files = [], int $patch_option = PKGCONF_PATCH_ALL, ?array $custom_replace = null): void
|
||||
{
|
||||
logger()->info('Patching library [' . static::NAME . '] pkgconfig');
|
||||
if ($files === [] && ($conf_pc = Config::getLib(static::NAME, 'pkg-configs', [])) !== []) {
|
||||
$files = array_map(fn ($x) => "{$x}.pc", $conf_pc);
|
||||
}
|
||||
foreach ($files as $name) {
|
||||
$realpath = realpath(BUILD_ROOT_PATH . '/lib/pkgconfig/' . $name);
|
||||
if ($realpath === false) {
|
||||
@ -75,7 +48,7 @@ trait UnixLibraryTrait
|
||||
logger()->debug('Patching ' . $realpath);
|
||||
// replace prefix
|
||||
$file = FileSystem::readFile($realpath);
|
||||
$file = ($patch_option & PKGCONF_PATCH_PREFIX) === PKGCONF_PATCH_PREFIX ? preg_replace('/^prefix\s*=.*$/m', 'prefix=${pcfiledir}/../..', $file) : $file;
|
||||
$file = ($patch_option & PKGCONF_PATCH_PREFIX) === PKGCONF_PATCH_PREFIX ? preg_replace('/^prefix\s*=.*$/m', 'prefix=' . BUILD_ROOT_PATH, $file) : $file;
|
||||
$file = ($patch_option & PKGCONF_PATCH_EXEC_PREFIX) === PKGCONF_PATCH_EXEC_PREFIX ? preg_replace('/^exec_prefix\s*=.*$/m', 'exec_prefix=${prefix}', $file) : $file;
|
||||
$file = ($patch_option & PKGCONF_PATCH_LIBDIR) === PKGCONF_PATCH_LIBDIR ? preg_replace('/^libdir\s*=.*$/m', 'libdir=${prefix}/lib', $file) : $file;
|
||||
$file = ($patch_option & PKGCONF_PATCH_INCLUDEDIR) === PKGCONF_PATCH_INCLUDEDIR ? preg_replace('/^includedir\s*=.*$/m', 'includedir=${prefix}/include', $file) : $file;
|
||||
|
||||
@ -5,9 +5,6 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\unix;
|
||||
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\freebsd\library\BSDLibraryBase;
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
@ -27,85 +24,6 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
/** @var string C++ flags */
|
||||
public string $arch_cxx_flags;
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function getAllStaticLibFiles(): array
|
||||
{
|
||||
$libs = [];
|
||||
|
||||
// reorder libs
|
||||
foreach ($this->libs as $lib) {
|
||||
foreach ($lib->getDependencies() as $dep) {
|
||||
$libs[] = $dep;
|
||||
}
|
||||
$libs[] = $lib;
|
||||
}
|
||||
|
||||
$libFiles = [];
|
||||
$libNames = [];
|
||||
// merge libs
|
||||
foreach ($libs as $lib) {
|
||||
if (!in_array($lib::NAME, $libNames, true)) {
|
||||
$libNames[] = $lib::NAME;
|
||||
array_unshift($libFiles, ...$lib->getStaticLibs());
|
||||
}
|
||||
}
|
||||
return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate configure flags
|
||||
*/
|
||||
public function makeAutoconfFlags(int $flag = AUTOCONF_ALL): string
|
||||
{
|
||||
$extra = '';
|
||||
// TODO: add auto pkg-config support
|
||||
if (($flag & AUTOCONF_LIBS) === AUTOCONF_LIBS) {
|
||||
$extra .= 'LIBS="' . BUILD_LIB_PATH . '" ';
|
||||
}
|
||||
if (($flag & AUTOCONF_CFLAGS) === AUTOCONF_CFLAGS) {
|
||||
$extra .= 'CFLAGS="-I' . BUILD_INCLUDE_PATH . '" ';
|
||||
}
|
||||
if (($flag & AUTOCONF_CPPFLAGS) === AUTOCONF_CPPFLAGS) {
|
||||
$extra .= 'CPPFLAGS="-I' . BUILD_INCLUDE_PATH . '" ';
|
||||
}
|
||||
if (($flag & AUTOCONF_LDFLAGS) === AUTOCONF_LDFLAGS) {
|
||||
$extra .= 'LDFLAGS="-L' . BUILD_LIB_PATH . '" ';
|
||||
}
|
||||
return $extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function makeAutoconfArgs(string $name, array $libSpecs): string
|
||||
{
|
||||
$ret = '';
|
||||
foreach ($libSpecs as $libName => $arr) {
|
||||
$lib = $this->getLib($libName);
|
||||
if ($lib === null && str_starts_with($libName, 'lib')) {
|
||||
$lib = $this->getLib(substr($libName, 3));
|
||||
}
|
||||
|
||||
$arr = $arr ?? [];
|
||||
|
||||
$disableArgs = $arr[0] ?? null;
|
||||
$prefix = $arr[1] ?? null;
|
||||
if ($lib instanceof LinuxLibraryBase || $lib instanceof MacOSLibraryBase || $lib instanceof BSDLibraryBase) {
|
||||
logger()->info("{$name} \033[32;1mwith\033[0;1m {$libName} support");
|
||||
$ret .= "--with-{$libName}=yes " . $lib->makeAutoconfEnv($prefix) . ' ';
|
||||
} else {
|
||||
logger()->info("{$name} \033[31;1mwithout\033[0;1m {$libName} support");
|
||||
$ret .= ($disableArgs ?? "--with-{$libName}=no") . ' ';
|
||||
}
|
||||
}
|
||||
return rtrim($ret);
|
||||
}
|
||||
|
||||
public function proveLibs(array $sorted_libraries): void
|
||||
{
|
||||
// search all supported libs
|
||||
@ -210,11 +128,22 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
}
|
||||
// if someone changed to --enable-embed=shared, we need to add LD_LIBRARY_PATH
|
||||
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
|
||||
$ext_path = 'LD_LIBRARY_PATH=' . BUILD_ROOT_PATH . '/lib:$LD_LIBRARY_PATH ';
|
||||
FileSystem::removeFileIfExists(BUILD_ROOT_PATH . '/lib/libphp.a');
|
||||
if (PHP_OS_FAMILY === 'Darwin') {
|
||||
$ext_path = 'DYLD_LIBRARY_PATH=' . BUILD_LIB_PATH . ':$DYLD_LIBRARY_PATH ';
|
||||
} else {
|
||||
$ext_path = 'LD_LIBRARY_PATH=' . BUILD_LIB_PATH . ':$LD_LIBRARY_PATH ';
|
||||
}
|
||||
FileSystem::removeFileIfExists(BUILD_LIB_PATH . '/libphp.a');
|
||||
} else {
|
||||
$ext_path = '';
|
||||
FileSystem::removeFileIfExists(BUILD_ROOT_PATH . '/lib/libphp.so');
|
||||
$suffix = PHP_OS_FAMILY === 'Darwin' ? 'dylib' : 'so';
|
||||
foreach (glob(BUILD_LIB_PATH . "/libphp*.{$suffix}") as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
[$ret, $out] = shell()->cd($sample_file_path)->execWithResult(getenv('CC') . ' -o embed embed.c ' . $lens);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('embed failed sanity check: build failed. Error message: ' . implode("\n", $out));
|
||||
}
|
||||
[$ret, $output] = shell()->cd($sample_file_path)->execWithResult($ext_path . './embed');
|
||||
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
|
||||
@ -229,8 +158,9 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
if (!file_exists($frankenphp)) {
|
||||
throw new RuntimeException('FrankenPHP binary not found: ' . $frankenphp);
|
||||
}
|
||||
$prefix = PHP_OS_FAMILY === 'Darwin' ? 'DYLD_' : 'LD_';
|
||||
[$ret, $output] = shell()
|
||||
->setEnv(['LD_LIBRARY_PATH' => BUILD_LIB_PATH])
|
||||
->setEnv(["{$prefix}LIBRARY_PATH" => BUILD_LIB_PATH])
|
||||
->execWithResult("{$frankenphp} version");
|
||||
if ($ret !== 0 || !str_contains(implode('', $output), 'FrankenPHP')) {
|
||||
throw new RuntimeException('FrankenPHP failed sanity check: ret[' . $ret . ']. out[' . implode('', $output) . ']');
|
||||
|
||||
@ -21,10 +21,10 @@ trait curl
|
||||
UnixCMakeExecutor::create($this)
|
||||
->optionalLib('openssl', '-DCURL_USE_OPENSSL=ON -DCURL_CA_BUNDLE=OFF -DCURL_CA_PATH=OFF -DCURL_CA_FALLBACK=ON', '-DCURL_USE_OPENSSL=OFF -DCURL_ENABLE_SSL=OFF')
|
||||
->optionalLib('brotli', ...cmake_boolean_args('CURL_BROTLI'))
|
||||
->optionalLib('libssh2', fn ($lib) => "-DLIBSSH2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DLIBSSH2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DCURL_USE_LIBSSH2=OFF')
|
||||
->optionalLib('nghttp2', fn ($lib) => "-DUSE_NGHTTP2=ON -DNGHTTP2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP2=OFF')
|
||||
->optionalLib('nghttp3', fn ($lib) => "-DUSE_NGHTTP3=ON -DNGHTTP3_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP3_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP3=OFF')
|
||||
->optionalLib('ngtcp2', fn ($lib) => "-DUSE_NGTCP2=ON -DNGNGTCP2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGNGTCP2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGTCP2=OFF')
|
||||
->optionalLib('libssh2', ...cmake_boolean_args('CURL_USE_LIBSSH2'))
|
||||
->optionalLib('nghttp2', ...cmake_boolean_args('USE_NGHTTP2'))
|
||||
->optionalLib('nghttp3', ...cmake_boolean_args('USE_NGHTTP3'))
|
||||
->optionalLib('ngtcp2', ...cmake_boolean_args('USE_NGTCP2'))
|
||||
->optionalLib('ldap', ...cmake_boolean_args('CURL_DISABLE_LDAP', true))
|
||||
->optionalLib('zstd', ...cmake_boolean_args('CURL_ZSTD'))
|
||||
->optionalLib('idn2', ...cmake_boolean_args('USE_LIBIDN2'))
|
||||
|
||||
@ -4,22 +4,55 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixCMakeExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait grpc
|
||||
{
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr(
|
||||
$this->source_dir . '/third_party/re2/util/pcre.h',
|
||||
["#define UTIL_PCRE_H_\n#include <stdint.h>", '#define UTIL_PCRE_H_'],
|
||||
['#define UTIL_PCRE_H_', "#define UTIL_PCRE_H_\n#include <stdint.h>"],
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
shell()->cd($this->source_dir)
|
||||
->exec('EXTRA_DEFINES=GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK EMBED_OPENSSL=false CXXFLAGS="-L' . BUILD_LIB_PATH . ' -I' . BUILD_INCLUDE_PATH . '" make static -j' . $this->builder->concurrency);
|
||||
copy($this->source_dir . '/libs/opt/libgrpc.a', BUILD_LIB_PATH . '/libgrpc.a');
|
||||
copy($this->source_dir . '/libs/opt/libboringssl.a', BUILD_LIB_PATH . '/libboringssl.a');
|
||||
if (!file_exists(BUILD_LIB_PATH . '/libcares.a')) {
|
||||
copy($this->source_dir . '/libs/opt/libcares.a', BUILD_LIB_PATH . '/libcares.a');
|
||||
$cmake = UnixCMakeExecutor::create($this)
|
||||
->setBuildDir("{$this->source_dir}/avoid_BUILD_file_conflict")
|
||||
->addConfigureArgs(
|
||||
'-DgRPC_INSTALL_BINDIR=' . BUILD_BIN_PATH,
|
||||
'-DgRPC_INSTALL_LIBDIR=' . BUILD_LIB_PATH,
|
||||
'-DgRPC_INSTALL_SHAREDIR=' . BUILD_ROOT_PATH . '/share/grpc',
|
||||
'-DCMAKE_C_FLAGS="-DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK -L' . BUILD_LIB_PATH . ' -I' . BUILD_INCLUDE_PATH . '"',
|
||||
'-DCMAKE_CXX_FLAGS="-DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK -L' . BUILD_LIB_PATH . ' -I' . BUILD_INCLUDE_PATH . '"',
|
||||
'-DgRPC_BUILD_CODEGEN=OFF',
|
||||
'-DgRPC_DOWNLOAD_ARCHIVES=OFF',
|
||||
'-DgRPC_BUILD_TESTS=OFF',
|
||||
// providers
|
||||
'-DgRPC_ZLIB_PROVIDER=package',
|
||||
'-DgRPC_CARES_PROVIDER=package',
|
||||
'-DgRPC_SSL_PROVIDER=package',
|
||||
);
|
||||
|
||||
if (PHP_OS_FAMILY === 'Linux' && SPCTarget::isStatic() && !SystemUtil::isMuslDist()) {
|
||||
$cmake->addConfigureArgs(
|
||||
'-DCMAKE_EXE_LINKER_FLAGS="-static-libgcc -static-libstdc++"',
|
||||
'-DCMAKE_SHARED_LINKER_FLAGS="-static-libgcc -static-libstdc++"',
|
||||
'-DCMAKE_CXX_STANDARD_LIBRARIES="-static-libgcc -static-libstdc++"',
|
||||
);
|
||||
}
|
||||
FileSystem::copyDir($this->source_dir . '/include/grpc', BUILD_INCLUDE_PATH . '/grpc');
|
||||
FileSystem::copyDir($this->source_dir . '/include/grpc++', BUILD_INCLUDE_PATH . '/grpc++');
|
||||
FileSystem::copyDir($this->source_dir . '/include/grpcpp', BUILD_INCLUDE_PATH . '/grpcpp');
|
||||
FileSystem::copyDir($this->source_dir . '/src/php/ext/grpc', BUILD_ROOT_PATH . '/grpc_php_ext_src');
|
||||
|
||||
$cmake->build();
|
||||
|
||||
$re2Content = file_get_contents($this->source_dir . '/third_party/re2/re2.pc');
|
||||
$re2Content = 'prefix=' . BUILD_ROOT_PATH . "\nexec_prefix=\${prefix}\n" . $re2Content;
|
||||
file_put_contents(BUILD_LIB_PATH . '/pkgconfig/re2.pc', $re2Content);
|
||||
$this->patchPkgconfPrefix(['grpc++.pc', 'grpc.pc', 'grpc++_unsecure.pc', 'grpc_unsecure.pc', 're2.pc']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ trait icu
|
||||
|
||||
protected function install(): void
|
||||
{
|
||||
parent::install();
|
||||
$icu_config = BUILD_ROOT_PATH . '/bin/icu-config';
|
||||
FileSystem::replaceFileStr($icu_config, '{BUILD_ROOT_PATH}', BUILD_ROOT_PATH);
|
||||
}
|
||||
|
||||
@ -32,9 +32,9 @@ trait imagemagick
|
||||
->optionalLib('zstd', ...ac_with_args('zstd'))
|
||||
->optionalLib('freetype', ...ac_with_args('freetype'))
|
||||
->optionalLib('bzip2', ...ac_with_args('bzlib'))
|
||||
->optionalLib('libjxl', ...ac_with_args('jxl'))
|
||||
->addConfigureArgs(
|
||||
'--disable-openmp',
|
||||
'--without-jxl',
|
||||
'--without-x',
|
||||
);
|
||||
|
||||
|
||||
35
src/SPC/builder/unix/library/jbig.php
Normal file
35
src/SPC/builder/unix/library/jbig.php
Normal 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 jbig
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
FileSystem::replaceFileStr($this->source_dir . '/Makefile', 'CFLAGS = -O2 -W -Wno-unused-result', 'CFLAGS = -O2 -W -Wno-unused-result -fPIC');
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
shell()->cd($this->source_dir)->initializeEnv($this)
|
||||
->exec("make -j{$this->builder->concurrency} {$this->builder->getEnvString()} lib")
|
||||
->exec('cp libjbig/libjbig.a ' . BUILD_LIB_PATH)
|
||||
->exec('cp libjbig/libjbig85.a ' . BUILD_LIB_PATH)
|
||||
->exec('cp libjbig/jbig.h ' . BUILD_INCLUDE_PATH)
|
||||
->exec('cp libjbig/jbig85.h ' . BUILD_INCLUDE_PATH)
|
||||
->exec('cp libjbig/jbig_ar.h ' . BUILD_INCLUDE_PATH);
|
||||
}
|
||||
}
|
||||
22
src/SPC/builder/unix/library/lerc.php
Normal file
22
src/SPC/builder/unix/library/lerc.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\util\executor\UnixCMakeExecutor;
|
||||
|
||||
trait lerc
|
||||
{
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
UnixCMakeExecutor::create($this)
|
||||
->build();
|
||||
}
|
||||
}
|
||||
@ -68,6 +68,7 @@ trait libevent
|
||||
|
||||
protected function install(): void
|
||||
{
|
||||
parent::install();
|
||||
FileSystem::replaceFileStr(
|
||||
BUILD_LIB_PATH . '/cmake/libevent/LibeventTargets-static.cmake',
|
||||
'{BUILD_ROOT_PATH}',
|
||||
|
||||
28
src/SPC/builder/unix/library/libjxl.php
Normal file
28
src/SPC/builder/unix/library/libjxl.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\util\executor\UnixCMakeExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait libjxl
|
||||
{
|
||||
protected function build(): void
|
||||
{
|
||||
UnixCMakeExecutor::create($this)
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_TOOLS=OFF')
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_EXAMPLES=OFF')
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_MANPAGES=OFF')
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_BENCHMARK=OFF')
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_PLUGINS=OFF')
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_SJPOEG=ON')
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_JNI=OFF')
|
||||
->addConfigureArgs('-DJPEGXL_ENABLE_TRANSCODE_JPEG=ON')
|
||||
->addConfigureArgs('-DJPEGXL_STATIC=' . (SPCTarget::isStatic() ? 'ON' : 'OFF'))
|
||||
->addConfigureArgs('-DJPEGXL_FORCE_SYSTEM_BROTLI=ON')
|
||||
->addConfigureArgs('-DBUILD_TESTING=OFF')
|
||||
->build();
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,9 @@ namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait libtiff
|
||||
{
|
||||
@ -16,7 +18,15 @@ trait libtiff
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
$libcpp = SPCTarget::getTargetOS() === 'Linux' ? '-lstdc++' : '-lc++';
|
||||
FileSystem::replaceFileStr($this->source_dir . '/configure', '-lwebp', '-lwebp -lsharpyuv');
|
||||
FileSystem::replaceFileStr($this->source_dir . '/configure', '-l"$lerc_lib_name"', '-l"$lerc_lib_name" ' . $libcpp);
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->optionalLib('lerc', '--enable-lerc', '--disable-lerc')
|
||||
->optionalLib('zstd', '--enable-zstd', '--disable-zstd')
|
||||
->optionalLib('libwebp', '--enable-webp', '--disable-webp')
|
||||
->optionalLib('xz', '--enable-lzma', '--disable-lzma')
|
||||
->optionalLib('jbig', '--enable-jbig', '--disable-jbig')
|
||||
->configure(
|
||||
// zlib deps
|
||||
'--enable-zlib',
|
||||
@ -24,16 +34,15 @@ trait libtiff
|
||||
"--with-zlib-lib-dir={$this->getLibDir()}",
|
||||
// libjpeg deps
|
||||
'--enable-jpeg',
|
||||
'--disable-old-jpeg',
|
||||
'--disable-jpeg12',
|
||||
"--with-jpeg-include-dir={$this->getIncludeDir()}",
|
||||
"--with-jpeg-lib-dir={$this->getLibDir()}",
|
||||
// We disabled lzma, zstd, webp, libdeflate by default to reduce the size of the binary
|
||||
'--disable-lzma',
|
||||
'--disable-zstd',
|
||||
'--disable-webp',
|
||||
'--disable-old-jpeg',
|
||||
'--disable-jpeg12',
|
||||
'--disable-libdeflate',
|
||||
'--disable-tools',
|
||||
'--disable-contrib',
|
||||
'--disable-cxx',
|
||||
'--without-x',
|
||||
)
|
||||
->make();
|
||||
$this->patchPkgconfPrefix(['libtiff-4.pc']);
|
||||
|
||||
@ -22,8 +22,7 @@ trait libwebp
|
||||
->addConfigureArgs('-DWEBP_BUILD_EXTRAS=ON')
|
||||
->build();
|
||||
// patch pkgconfig
|
||||
$this->patchPkgconfPrefix(['libsharpyuv.pc', 'libwebp.pc', 'libwebpdecoder.pc', 'libwebpdemux.pc', 'libwebpmux.pc'], PKGCONF_PATCH_PREFIX | PKGCONF_PATCH_LIBDIR);
|
||||
$this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX | PKGCONF_PATCH_LIBDIR);
|
||||
$this->patchPkgconfPrefix(['libsharpyuv.pc'], PKGCONF_PATCH_CUSTOM, ['/^includedir=.*$/m', 'includedir=${prefix}/include/webp']);
|
||||
$this->patchPkgconfPrefix(['libwebp.pc'], PKGCONF_PATCH_CUSTOM, ['/-lwebp$/m', '-lwebp -lsharpyuv']);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
@ -20,11 +21,12 @@ trait libxslt
|
||||
protected function build(): void
|
||||
{
|
||||
$static_libs = $this instanceof LinuxLibraryBase ? $this->getStaticLibFiles(include_self: false) : '';
|
||||
$cpp = $this instanceof MacOSLibraryBase ? '-lc++' : '-lstdc++';
|
||||
$ac = UnixAutoconfExecutor::create($this)
|
||||
->appendEnv([
|
||||
'CFLAGS' => "-I{$this->getIncludeDir()}",
|
||||
'LDFLAGS' => "-L{$this->getLibDir()}",
|
||||
'LIBS' => "{$static_libs} -lstdc++",
|
||||
'LIBS' => "{$static_libs} {$cpp}",
|
||||
])
|
||||
->addConfigureArgs(
|
||||
'--without-python',
|
||||
@ -41,7 +43,7 @@ trait libxslt
|
||||
}
|
||||
$ac->configure()->make();
|
||||
|
||||
$this->patchPkgconfPrefix(['libexslt.pc']);
|
||||
$this->patchPkgconfPrefix(['libexslt.pc', 'libxslt.pc']);
|
||||
$this->patchLaDependencyPrefix();
|
||||
shell()->cd(BUILD_LIB_PATH)
|
||||
->exec("ar -t libxslt.a | grep '\\.a$' | xargs -n1 ar d libxslt.a")
|
||||
|
||||
@ -4,6 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
@ -19,7 +21,7 @@ trait ngtcp2
|
||||
protected function build(): void
|
||||
{
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->optionalLib('openssl', fn ($lib) => implode(' ', [
|
||||
->optionalLib('openssl', fn (LinuxLibraryBase|MacOSLibraryBase $lib) => implode(' ', [
|
||||
'--with-openssl=yes',
|
||||
"OPENSSL_LIBS=\"{$lib->getStaticLibFiles()}\"",
|
||||
"OPENSSL_CFLAGS=\"-I{$lib->getIncludeDir()}\"",
|
||||
@ -29,7 +31,7 @@ trait ngtcp2
|
||||
->optionalLib('jemalloc', ...ac_with_args('jemalloc', true))
|
||||
->optionalLib(
|
||||
'brotli',
|
||||
fn ($lib) => implode(' ', [
|
||||
fn (LinuxLibraryBase|MacOSLibraryBase $lib) => implode(' ', [
|
||||
'--with-brotlidec=yes',
|
||||
"LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"",
|
||||
"LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"",
|
||||
|
||||
@ -21,6 +21,7 @@ trait xz
|
||||
'--disable-scripts',
|
||||
'--disable-doc',
|
||||
'--with-libiconv',
|
||||
'--bindir=/tmp/xz', // xz binary will corrupt `tar` command, that's really strange.
|
||||
)
|
||||
->make();
|
||||
$this->patchPkgconfPrefix(['liblzma.pc']);
|
||||
|
||||
@ -61,11 +61,6 @@ class WindowsBuilder extends BuilderBase
|
||||
*/
|
||||
public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||
{
|
||||
// ---------- Update extra-libs ----------
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . implode(' ', $this->getAllStaticLibFiles());
|
||||
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;
|
||||
@ -162,8 +157,10 @@ class WindowsBuilder extends BuilderBase
|
||||
{
|
||||
SourcePatcher::patchWindowsCLITarget();
|
||||
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||
|
||||
// add nmake wrapper
|
||||
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cli_wrapper.bat', "nmake /nologo LIBS_CLI=\"{$this->getOption('extra-libs')} ws2_32.lib shell32.lib\" EXTRA_LD_FLAGS_PROGRAM= %*");
|
||||
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cli_wrapper.bat', "nmake /nologo LIBS_CLI=\"ws2_32.lib shell32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*");
|
||||
|
||||
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cli_wrapper.bat --task-args php.exe");
|
||||
|
||||
@ -197,9 +194,11 @@ class WindowsBuilder extends BuilderBase
|
||||
}
|
||||
FileSystem::writeFile(SOURCE_PATH . '\php-src\Makefile', $makefile);
|
||||
|
||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||
|
||||
// add nmake wrapper
|
||||
$fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' /DPHP_MICRO_FAKE_CLI" ' : '';
|
||||
$wrapper = "nmake /nologo LIBS_MICRO=\"{$this->getOption('extra-libs')} ws2_32.lib shell32.lib\" CFLAGS_MICRO=\"/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1{$fake_cli}\" %*";
|
||||
$wrapper = "nmake /nologo LIBS_MICRO=\"ws2_32.lib shell32.lib {$extra_libs}\" CFLAGS_MICRO=\"/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1{$fake_cli}\" %*";
|
||||
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_micro_wrapper.bat', $wrapper);
|
||||
|
||||
// phar patch for micro
|
||||
|
||||
@ -37,6 +37,7 @@ class curl extends WindowsLibraryBase
|
||||
'-DBUILD_EXAMPLES=OFF ' . // disable examples
|
||||
'-DUSE_LIBIDN2=OFF ' . // disable libidn2
|
||||
'-DCURL_USE_LIBPSL=OFF ' . // disable libpsl
|
||||
'-DUSE_WINDOWS_SSPI=ON ' . // use Schannel instead of OpenSSL
|
||||
'-DCURL_USE_SCHANNEL=ON ' . // use Schannel instead of OpenSSL
|
||||
'-DCURL_USE_OPENSSL=OFF ' . // disable openssl due to certificate issue
|
||||
'-DCURL_ENABLE_SSL=ON ' .
|
||||
|
||||
@ -18,7 +18,6 @@ abstract class BuildCommand extends BaseCommand
|
||||
}
|
||||
|
||||
$this->addOption('with-clean', null, null, 'fresh build, remove `source` and `buildroot` dir before build');
|
||||
$this->addOption('bloat', null, null, 'add all libraries into binary');
|
||||
$this->addOption('rebuild', 'r', null, 'Delete old build and rebuild');
|
||||
$this->addOption('enable-zts', null, null, 'enable ZTS support');
|
||||
}
|
||||
|
||||
@ -245,11 +245,14 @@ class DownloadCommand extends BaseCommand
|
||||
}
|
||||
// if download failed, we will try to download alternative sources
|
||||
logger()->warning("Download failed: {$e->getMessage()}");
|
||||
logger()->notice("Trying to download alternative sources for {$source}");
|
||||
$alt_sources = Config::getSource($source)['alt'] ?? null;
|
||||
if ($alt_sources === null) {
|
||||
$alt_config = array_merge($config, $this->getDefaultAlternativeSource($source));
|
||||
logger()->warning("No alternative sources found for {$source}, using default alternative source");
|
||||
$alt_config = array_merge($config, Downloader::getDefaultAlternativeSource($source));
|
||||
} elseif ($alt_sources === false) {
|
||||
throw new DownloaderException("No alternative sources found for {$source}, skipping alternative download");
|
||||
} else {
|
||||
logger()->notice("Trying to download alternative sources for {$source}");
|
||||
$alt_config = array_merge($config, $alt_sources);
|
||||
}
|
||||
Downloader::downloadSource($source, $alt_config, $force_all || in_array($source, $force_list));
|
||||
@ -395,27 +398,4 @@ class DownloadCommand extends BaseCommand
|
||||
}
|
||||
return static::FAILURE;
|
||||
}
|
||||
|
||||
private function getDefaultAlternativeSource(string $source_name): array
|
||||
{
|
||||
return [
|
||||
'type' => 'custom',
|
||||
'func' => function (bool $force, array $source, int $download_as) use ($source_name) {
|
||||
logger()->debug("Fetching alternative source for {$source_name}");
|
||||
// get from dl.static-php.dev
|
||||
$url = "https://dl.static-php.dev/static-php-cli/deps/spc-download-mirror/{$source_name}/?format=json";
|
||||
$json = json_decode(Downloader::curlExec(url: $url, retries: intval(getenv('SPC_DOWNLOAD_RETRIES') ?: 0)), true);
|
||||
if (!is_array($json)) {
|
||||
throw new RuntimeException('failed http fetch');
|
||||
}
|
||||
$item = $json[0] ?? null;
|
||||
if ($item === null) {
|
||||
throw new RuntimeException('failed to parse json');
|
||||
}
|
||||
$full_url = 'https://dl.static-php.dev' . $item['full_path'];
|
||||
$filename = basename($item['full_path']);
|
||||
Downloader::downloadFile($source_name, $full_url, $filename, $source['path'] ?? null, $download_as);
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,8 @@ class InstallPkgCommand extends BaseCommand
|
||||
$this->addArgument('packages', InputArgument::REQUIRED, 'The packages will be installed, comma separated');
|
||||
$this->addOption('shallow-clone', null, null, 'Clone shallow');
|
||||
$this->addOption('custom-url', 'U', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Specify custom source download url, e.g "php-src:https://downloads.php.net/~eric/php-8.3.0beta1.tar.gz"');
|
||||
$this->addOption('no-alt', null, null, 'Do not download alternative packages');
|
||||
$this->addOption('skip-extract', null, null, 'Skip package extraction, just download the package archive');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,10 +68,20 @@ class InstallPkgCommand extends BaseCommand
|
||||
$new_config['filename'] = $config['filename'];
|
||||
}
|
||||
logger()->info("Installing source {$pkg} from custom url [{$ni}/{$cnt}]");
|
||||
PackageManager::installPackage($pkg, $new_config);
|
||||
PackageManager::installPackage(
|
||||
$pkg,
|
||||
$new_config,
|
||||
allow_alt: false,
|
||||
extract: !$this->getOption('skip-extract')
|
||||
);
|
||||
} else {
|
||||
logger()->info("Fetching package {$pkg} [{$ni}/{$cnt}]");
|
||||
PackageManager::installPackage($pkg, Config::getPkg($pkg));
|
||||
PackageManager::installPackage(
|
||||
$pkg,
|
||||
Config::getPkg($pkg),
|
||||
allow_alt: !$this->getOption('no-alt'),
|
||||
extract: !$this->getOption('skip-extract')
|
||||
);
|
||||
}
|
||||
}
|
||||
$time = round(microtime(true) - START_TIME, 3);
|
||||
|
||||
@ -23,6 +23,9 @@ class SPCConfigCommand extends BaseCommand
|
||||
$this->addOption('with-suggested-exts', 'E', null, 'Build with suggested extensions for selected exts');
|
||||
$this->addOption('includes', null, null, 'Add additional include path');
|
||||
$this->addOption('libs', null, null, 'Add additional libs path');
|
||||
$this->addOption('libs-only-deps', null, null, 'Output dependent libraries with -l prefix');
|
||||
$this->addOption('absolute-libs', null, null, 'Output absolute paths for libraries');
|
||||
$this->addOption('no-php', null, null, 'Do not link to PHP library');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,16 +40,19 @@ class SPCConfigCommand extends BaseCommand
|
||||
$include_suggest_ext = $this->getOption('with-suggested-exts');
|
||||
$include_suggest_lib = $this->getOption('with-suggested-libs');
|
||||
|
||||
$util = new SPCConfigUtil();
|
||||
$util = new SPCConfigUtil(options: [
|
||||
'no_php' => $this->getOption('no-php'),
|
||||
'libs_only_deps' => $this->getOption('libs-only-deps'),
|
||||
'absolute_libs' => $this->getOption('absolute-libs'),
|
||||
]);
|
||||
$config = $util->config($extensions, $libraries, $include_suggest_ext, $include_suggest_lib);
|
||||
|
||||
if ($this->getOption('includes')) {
|
||||
$this->output->writeln($config['cflags']);
|
||||
} elseif ($this->getOption('libs')) {
|
||||
$this->output->writeln("{$config['ldflags']} {$config['libs']}");
|
||||
} else {
|
||||
$this->output->writeln("{$config['cflags']} {$config['ldflags']} {$config['libs']}");
|
||||
}
|
||||
$this->output->writeln(match (true) {
|
||||
$this->getOption('includes') => $config['cflags'],
|
||||
$this->getOption('libs-only-deps') => $config['libs'],
|
||||
$this->getOption('libs') => "{$config['ldflags']} {$config['libs']}",
|
||||
default => "{$config['cflags']} {$config['ldflags']} {$config['libs']}",
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -42,6 +42,19 @@ class PackLibCommand extends BuildCommand
|
||||
|
||||
$builder->proveLibs($libraries);
|
||||
$builder->validateLibsAndExts();
|
||||
|
||||
// before pack, check if the dependency tree contains lib-suggests
|
||||
foreach ($libraries as $lib) {
|
||||
if (Config::getLib($lib, 'lib-suggests', []) !== []) {
|
||||
logger()->critical("The library {$lib} has lib-suggests, packing [{$lib_name}] is not safe, abort !");
|
||||
return static::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
$origin_files = [];
|
||||
// get pack placehoder defines
|
||||
$placehoder = get_pack_replace();
|
||||
|
||||
foreach ($builder->getLibs() as $lib) {
|
||||
if ($lib->getName() !== $lib_name) {
|
||||
// other dependencies: install or build, both ok
|
||||
@ -64,6 +77,27 @@ class PackLibCommand extends BuildCommand
|
||||
// After build: load buildroot/ directory, and calculate increase files
|
||||
$after_buildroot = FileSystem::scanDirFiles(BUILD_ROOT_PATH, relative: true);
|
||||
$increase_files = array_diff($after_buildroot, $before_buildroot);
|
||||
|
||||
// patch pkg-config and la files with absolute path
|
||||
foreach ($increase_files as $file) {
|
||||
if (str_ends_with($file, '.pc') || str_ends_with($file, '.la')) {
|
||||
$content = FileSystem::readFile(BUILD_ROOT_PATH . '/' . $file);
|
||||
$origin_files[$file] = $content;
|
||||
// replace relative paths with absolute paths
|
||||
$content = str_replace(
|
||||
array_keys($placehoder),
|
||||
array_values($placehoder),
|
||||
$content
|
||||
);
|
||||
FileSystem::writeFile(BUILD_ROOT_PATH . '/' . $file, $content);
|
||||
}
|
||||
}
|
||||
|
||||
// add .spc-extract-placeholder.json in BUILD_ROOT_PATH
|
||||
$placeholder_file = BUILD_ROOT_PATH . '/.spc-extract-placeholder.json';
|
||||
file_put_contents($placeholder_file, json_encode(array_keys($origin_files), JSON_PRETTY_PRINT));
|
||||
$increase_files[] = '.spc-extract-placeholder.json';
|
||||
|
||||
// every file mapped with BUILD_ROOT_PATH
|
||||
// get BUILD_ROOT_PATH last dir part
|
||||
$buildroot_part = basename(BUILD_ROOT_PATH);
|
||||
@ -85,6 +119,16 @@ class PackLibCommand extends BuildCommand
|
||||
$filename = WORKING_DIR . '/dist/' . $filename;
|
||||
f_passthru("tar {$tar_option} {$filename} -T " . WORKING_DIR . '/packlib_files.txt');
|
||||
logger()->info('Pack library ' . $lib->getName() . ' to ' . $filename . ' complete.');
|
||||
|
||||
// remove temp files
|
||||
unlink($placeholder_file);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($origin_files as $file => $content) {
|
||||
// restore original files
|
||||
if (file_exists(BUILD_ROOT_PATH . '/' . $file)) {
|
||||
FileSystem::writeFile(BUILD_ROOT_PATH . '/' . $file, $content);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -219,34 +219,41 @@ class Downloader
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function downloadGit(string $name, string $url, string $branch, ?string $move_path = null, int $retries = 0, int $lock_as = SPC_DOWNLOAD_SOURCE): void
|
||||
public static function downloadGit(string $name, string $url, string $branch, ?array $submodules = null, ?string $move_path = null, int $retries = 0, int $lock_as = SPC_DOWNLOAD_SOURCE): void
|
||||
{
|
||||
$download_path = FileSystem::convertPath(DOWNLOAD_PATH . "/{$name}");
|
||||
if (file_exists($download_path)) {
|
||||
FileSystem::removeDir($download_path);
|
||||
}
|
||||
logger()->debug("cloning {$name} source");
|
||||
$check = !defined('DEBUG_MODE') ? ' -q' : '';
|
||||
$cancel_func = function () use ($download_path) {
|
||||
|
||||
$quiet = !defined('DEBUG_MODE') ? '-q --quiet' : '';
|
||||
$git = SPC_GIT_EXEC;
|
||||
$shallow = defined('GIT_SHALLOW_CLONE') ? '--depth 1 --single-branch' : '';
|
||||
$recursive = ($submodules === null) ? '--recursive' : '';
|
||||
|
||||
try {
|
||||
self::registerCancelEvent(function () use ($download_path) {
|
||||
if (is_dir($download_path)) {
|
||||
logger()->warning('Removing path ' . $download_path);
|
||||
FileSystem::removeDir($download_path);
|
||||
}
|
||||
};
|
||||
try {
|
||||
self::registerCancelEvent($cancel_func);
|
||||
f_passthru(
|
||||
SPC_GIT_EXEC . ' clone' . $check .
|
||||
(defined('DEBUG_MODE') ? '' : ' --quiet') .
|
||||
' --config core.autocrlf=false ' .
|
||||
"--branch \"{$branch}\" " . (defined('GIT_SHALLOW_CLONE') ? '--depth 1 --single-branch' : '') . " --recursive \"{$url}\" \"{$download_path}\""
|
||||
);
|
||||
});
|
||||
f_passthru("{$git} clone {$quiet} --config core.autocrlf=false --branch \"{$branch}\" {$shallow} {$recursive} \"{$url}\" \"{$download_path}\"");
|
||||
if ($submodules !== null) {
|
||||
foreach ($submodules as $submodule) {
|
||||
f_passthru("cd \"{$download_path}\" && {$git} submodule update --init " . escapeshellarg($submodule));
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException $e) {
|
||||
if (is_dir($download_path)) {
|
||||
FileSystem::removeDir($download_path);
|
||||
}
|
||||
if ($e->getCode() === 2 || $e->getCode() === -1073741510) {
|
||||
throw new WrongUsageException('Keyboard interrupted, download failed !');
|
||||
}
|
||||
if ($retries > 0) {
|
||||
self::downloadGit($name, $url, $branch, $move_path, $retries - 1);
|
||||
self::downloadGit($name, $url, $branch, $submodules, $move_path, $retries - 1, $lock_as);
|
||||
return;
|
||||
}
|
||||
throw $e;
|
||||
@ -343,6 +350,7 @@ class Downloader
|
||||
$name,
|
||||
$pkg['url'],
|
||||
$pkg['rev'],
|
||||
$pkg['submodules'] ?? null,
|
||||
$pkg['extract'] ?? null,
|
||||
self::getRetryAttempts(),
|
||||
SPC_DOWNLOAD_PRE_BUILT
|
||||
@ -360,6 +368,11 @@ class Downloader
|
||||
break;
|
||||
case 'custom': // Custom download method, like API-based download or other
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/pkg', 'SPC\store\pkg');
|
||||
if (isset($pkg['func']) && is_callable($pkg['func'])) {
|
||||
$pkg['name'] = $name;
|
||||
$pkg['func']($force, $pkg, SPC_DOWNLOAD_PACKAGE);
|
||||
break;
|
||||
}
|
||||
foreach ($classes as $class) {
|
||||
if (is_a($class, CustomPackage::class, true) && $class !== CustomPackage::class) {
|
||||
$cls = new $class();
|
||||
@ -462,6 +475,7 @@ class Downloader
|
||||
$name,
|
||||
$source['url'],
|
||||
$source['rev'],
|
||||
$source['submodules'] ?? null,
|
||||
$source['path'] ?? null,
|
||||
self::getRetryAttempts(),
|
||||
$download_as
|
||||
@ -599,6 +613,29 @@ class Downloader
|
||||
return "{$source}-{$os_family}-{$gnu_arch}-{$libc}-{$libc_version}";
|
||||
}
|
||||
|
||||
public static function getDefaultAlternativeSource(string $source_name): array
|
||||
{
|
||||
return [
|
||||
'type' => 'custom',
|
||||
'func' => function (bool $force, array $source, int $download_as) use ($source_name) {
|
||||
logger()->debug("Fetching alternative source for {$source_name}");
|
||||
// get from dl.static-php.dev
|
||||
$url = "https://dl.static-php.dev/static-php-cli/deps/spc-download-mirror/{$source_name}/?format=json";
|
||||
$json = json_decode(Downloader::curlExec(url: $url, retries: intval(getenv('SPC_DOWNLOAD_RETRIES') ?: 0)), true);
|
||||
if (!is_array($json)) {
|
||||
throw new RuntimeException('failed http fetch');
|
||||
}
|
||||
$item = $json[0] ?? null;
|
||||
if ($item === null) {
|
||||
throw new RuntimeException('failed to parse json');
|
||||
}
|
||||
$full_url = 'https://dl.static-php.dev' . $item['full_path'];
|
||||
$filename = basename($item['full_path']);
|
||||
Downloader::downloadFile($source_name, $full_url, $filename, $source['path'] ?? null, $download_as);
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register CTRL+C event for different OS.
|
||||
*
|
||||
|
||||
@ -4,13 +4,14 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\store;
|
||||
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\pkg\CustomPackage;
|
||||
|
||||
class PackageManager
|
||||
{
|
||||
public static function installPackage(string $pkg_name, ?array $config = null, bool $force = false): void
|
||||
public static function installPackage(string $pkg_name, ?array $config = null, bool $force = false, bool $allow_alt = true, bool $extract = true): void
|
||||
{
|
||||
if ($config === null) {
|
||||
$config = Config::getPkg($pkg_name);
|
||||
@ -32,7 +33,31 @@ class PackageManager
|
||||
}
|
||||
|
||||
// Download package
|
||||
try {
|
||||
Downloader::downloadPackage($pkg_name, $config, $force);
|
||||
} catch (\Throwable $e) {
|
||||
if (!$allow_alt) {
|
||||
throw new DownloaderException("Download package {$pkg_name} failed: " . $e->getMessage());
|
||||
}
|
||||
// if download failed, we will try to download alternative packages
|
||||
logger()->warning("Download package {$pkg_name} failed: " . $e->getMessage());
|
||||
$alt = $config['alt'] ?? null;
|
||||
if ($alt === null) {
|
||||
logger()->warning("No alternative package found for {$pkg_name}, using default mirror.");
|
||||
$alt_config = array_merge($config, Downloader::getDefaultAlternativeSource($pkg_name));
|
||||
} elseif ($alt === false) {
|
||||
logger()->error("No alternative package found for {$pkg_name}.");
|
||||
throw $e;
|
||||
} else {
|
||||
logger()->notice("Trying alternative package for {$pkg_name}.");
|
||||
$alt_config = array_merge($config, $alt);
|
||||
}
|
||||
Downloader::downloadPackage($pkg_name, $alt_config, $force);
|
||||
}
|
||||
if (!$extract) {
|
||||
logger()->info("Package [{$pkg_name}] downloaded, but extraction is skipped.");
|
||||
return;
|
||||
}
|
||||
if (Config::getPkg($pkg_name)['type'] === 'custom') {
|
||||
// Custom extract function
|
||||
$classes = FileSystem::getClassesPsr4(ROOT_DIR . '/src/SPC/store/pkg', 'SPC\store\pkg');
|
||||
|
||||
@ -90,6 +90,9 @@ class ConfigValidator
|
||||
if (isset($lib['static-libs' . $suffix]) && !is_list_array($lib['static-libs' . $suffix])) {
|
||||
throw new ValidationException("lib {$name} static-libs must be a list");
|
||||
}
|
||||
if (isset($lib['pkg-configs' . $suffix]) && !is_list_array($lib['pkg-configs' . $suffix])) {
|
||||
throw new ValidationException("lib {$name} pkg-configs must be a list");
|
||||
}
|
||||
}
|
||||
// check if frameworks is a list array
|
||||
if (isset($lib['frameworks']) && !is_list_array($lib['frameworks'])) {
|
||||
|
||||
75
src/SPC/util/PkgConfigUtil.php
Normal file
75
src/SPC/util/PkgConfigUtil.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\exception\RuntimeException;
|
||||
|
||||
class PkgConfigUtil
|
||||
{
|
||||
/**
|
||||
* Returns --cflags-only-other output.
|
||||
* The reason we return the string is we cannot use array_unique() on cflags,
|
||||
* some cflags may contains spaces.
|
||||
*
|
||||
* @param string $pkg_config_str .pc file str, accepts multiple files
|
||||
* @return string cflags string, e.g. "-Wno-implicit-int-float-conversion ..."
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function getCflags(string $pkg_config_str): string
|
||||
{
|
||||
// get other things
|
||||
$result = self::execWithResult("pkg-config --static --cflags-only-other {$pkg_config_str}");
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns --libs-only-l and --libs-only-other output.
|
||||
* The reason we return the array is to avoid duplicate lib defines.
|
||||
*
|
||||
* @param string $pkg_config_str .pc file str, accepts multiple files
|
||||
* @return array Unique libs array, e.g. [-lz, -lxml, ...]
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function getLibsArray(string $pkg_config_str): array
|
||||
{
|
||||
// Use this instead of shell() to avoid unnecessary outputs
|
||||
$result = self::execWithResult("pkg-config --static --libs-only-l {$pkg_config_str}");
|
||||
$libs = explode(' ', trim($result));
|
||||
|
||||
// get other things
|
||||
$result = self::execWithResult("pkg-config --static --libs-only-other {$pkg_config_str}");
|
||||
// convert libxxx.a to -L{path} -lxxx
|
||||
$exp = explode(' ', trim($result));
|
||||
foreach ($exp as $item) {
|
||||
if (str_starts_with($item, '-L')) {
|
||||
$libs[] = $item;
|
||||
continue;
|
||||
}
|
||||
// if item ends with .a, convert it to -lxxx
|
||||
if (str_ends_with($item, '.a') && (str_starts_with($item, 'lib') || str_starts_with($item, BUILD_LIB_PATH))) {
|
||||
$name = pathinfo($item, PATHINFO_BASENAME);
|
||||
$name = substr($name, 3, -2); // remove 'lib' prefix and '.a' suffix
|
||||
$shortlib = "-l{$name}";
|
||||
if (!in_array($shortlib, $libs)) {
|
||||
$libs[] = $shortlib;
|
||||
}
|
||||
} elseif (!in_array($item, $libs)) {
|
||||
$libs[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
// enhancement for linker
|
||||
return array_reverse(array_unique(array_reverse($libs)));
|
||||
}
|
||||
|
||||
private static function execWithResult(string $cmd): string
|
||||
{
|
||||
f_exec($cmd, $output, $result_code);
|
||||
if ($result_code !== 0) {
|
||||
throw new RuntimeException("pkg-config command failed with code {$result_code}: {$cmd}");
|
||||
}
|
||||
return implode("\n", $output);
|
||||
}
|
||||
}
|
||||
@ -6,7 +6,6 @@ namespace SPC\util;
|
||||
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\builder\macos\MacOSBuilder;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
@ -17,11 +16,27 @@ class SPCConfigUtil
|
||||
{
|
||||
private ?BuilderBase $builder = null;
|
||||
|
||||
public function __construct(?BuilderBase $builder = null)
|
||||
private bool $no_php;
|
||||
|
||||
private bool $libs_only_deps;
|
||||
|
||||
private bool $absolute_libs;
|
||||
|
||||
/**
|
||||
* @param array{
|
||||
* no_php?: bool,
|
||||
* libs_only_deps?: bool,
|
||||
* absolute_libs?: bool
|
||||
* } $options Options pass to spc-config
|
||||
*/
|
||||
public function __construct(?BuilderBase $builder = null, array $options = [])
|
||||
{
|
||||
if ($builder !== null) {
|
||||
$this->builder = $builder; // BuilderProvider::makeBuilderByInput($input ?? new ArgvInput());
|
||||
}
|
||||
$this->no_php = $options['no_php'] ?? false;
|
||||
$this->libs_only_deps = $options['libs_only_deps'] ?? false;
|
||||
$this->absolute_libs = $options['absolute_libs'] ?? false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,26 +69,27 @@ class SPCConfigUtil
|
||||
}
|
||||
ob_get_clean();
|
||||
$ldflags = $this->getLdflagsString();
|
||||
$libs = $this->getLibsString($libraries, $with_dependencies);
|
||||
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||
$libs .= " {$this->getFrameworksString($extensions)}";
|
||||
}
|
||||
$cflags = $this->getIncludesString();
|
||||
$cflags = $this->getIncludesString($libraries);
|
||||
$libs = $this->getLibsString($libraries, !$this->absolute_libs);
|
||||
|
||||
// embed
|
||||
$libs = trim("-lphp -lc {$libs}");
|
||||
// additional OS-specific libraries (e.g. macOS -lresolv)
|
||||
$extra_env = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS');
|
||||
if (is_string($extra_env)) {
|
||||
$libs .= ' ' . trim($extra_env, '"');
|
||||
}
|
||||
// c++
|
||||
$extra_env = getenv('SPC_EXTRA_LIBS');
|
||||
if (is_string($extra_env) && !empty($extra_env)) {
|
||||
$libs .= " {$extra_env}";
|
||||
}
|
||||
// extension frameworks
|
||||
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||
$libs .= " {$this->getFrameworksString($extensions)}";
|
||||
}
|
||||
if ($this->builder->hasCpp()) {
|
||||
$libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++';
|
||||
}
|
||||
// mimalloc must come first
|
||||
if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) {
|
||||
$libs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $libs);
|
||||
$libs .= SPCTarget::getTargetOS() === 'Darwin' ? ' -lc++' : ' -lstdc++';
|
||||
}
|
||||
|
||||
if ($this->libs_only_deps) {
|
||||
return [
|
||||
'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags),
|
||||
'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags),
|
||||
@ -81,18 +97,61 @@ class SPCConfigUtil
|
||||
];
|
||||
}
|
||||
|
||||
private function getIncludesString(): string
|
||||
// embed
|
||||
if (!$this->no_php) {
|
||||
$libs = "-lphp {$libs} -lc";
|
||||
}
|
||||
|
||||
$allLibs = getenv('LIBS') . ' ' . $libs;
|
||||
|
||||
// mimalloc must come first
|
||||
if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) {
|
||||
$allLibs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $allLibs);
|
||||
}
|
||||
|
||||
return [
|
||||
'cflags' => trim(getenv('CFLAGS') . ' ' . $cflags),
|
||||
'ldflags' => trim(getenv('LDFLAGS') . ' ' . $ldflags),
|
||||
'libs' => trim($allLibs),
|
||||
];
|
||||
}
|
||||
|
||||
private function getIncludesString(array $libraries): string
|
||||
{
|
||||
$base = BUILD_INCLUDE_PATH;
|
||||
$php_embed_includes = [
|
||||
"-I{$base}",
|
||||
$includes = ["-I{$base}"];
|
||||
|
||||
// link with libphp
|
||||
if (!$this->no_php) {
|
||||
$includes = [
|
||||
...$includes,
|
||||
"-I{$base}/php",
|
||||
"-I{$base}/php/main",
|
||||
"-I{$base}/php/TSRM",
|
||||
"-I{$base}/php/Zend",
|
||||
"-I{$base}/php/ext",
|
||||
];
|
||||
return implode(' ', $php_embed_includes);
|
||||
}
|
||||
|
||||
// parse pkg-configs
|
||||
foreach ($libraries as $library) {
|
||||
$pc = Config::getLib($library, 'pkg-configs', []);
|
||||
foreach ($pc as $file) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$file}.pc")) {
|
||||
throw new WrongUsageException("pkg-config file '{$file}.pc' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first.");
|
||||
}
|
||||
}
|
||||
$pc_cflags = implode(' ', $pc);
|
||||
if ($pc_cflags !== '' && ($pc_cflags = PkgConfigUtil::getCflags($pc_cflags)) !== '') {
|
||||
$arr = explode(' ', $pc_cflags);
|
||||
$arr = array_unique($arr);
|
||||
$arr = array_filter($arr, fn ($x) => !str_starts_with($x, 'SHELL:-Xarch_'));
|
||||
$pc_cflags = implode(' ', $arr);
|
||||
$includes[] = $pc_cflags;
|
||||
}
|
||||
}
|
||||
$includes = array_unique($includes);
|
||||
return implode(' ', $includes);
|
||||
}
|
||||
|
||||
private function getLdflagsString(): string
|
||||
@ -100,55 +159,62 @@ class SPCConfigUtil
|
||||
return '-L' . BUILD_LIB_PATH;
|
||||
}
|
||||
|
||||
private function getLibsString(array $libraries, bool $withDependencies = false): string
|
||||
private function getLibsString(array $libraries, bool $use_short_libs = true): string
|
||||
{
|
||||
$short_name = [];
|
||||
foreach (array_reverse($libraries) as $library) {
|
||||
$lib_names = [];
|
||||
$frameworks = [];
|
||||
|
||||
foreach ($libraries as $library) {
|
||||
// add pkg-configs libs
|
||||
$pkg_configs = Config::getLib($library, 'pkg-configs', []);
|
||||
foreach ($pkg_configs as $pkg_config) {
|
||||
if (!file_exists(BUILD_LIB_PATH . "/pkgconfig/{$pkg_config}.pc")) {
|
||||
throw new WrongUsageException("pkg-config file '{$pkg_config}.pc' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "/pkgconfig'. Please build it first.");
|
||||
}
|
||||
}
|
||||
$pkg_configs = implode(' ', $pkg_configs);
|
||||
if ($pkg_configs !== '') {
|
||||
// static libs with dependencies come in reverse order, so reverse this too
|
||||
$pc_libs = array_reverse(PkgConfigUtil::getLibsArray($pkg_configs));
|
||||
$lib_names = [...$lib_names, ...$pc_libs];
|
||||
}
|
||||
// convert all static-libs to short names
|
||||
$libs = Config::getLib($library, 'static-libs', []);
|
||||
foreach ($libs as $lib) {
|
||||
if ($withDependencies) {
|
||||
$noExt = str_replace('.a', '', $lib);
|
||||
$requiredLibs = [];
|
||||
$pkgconfFile = BUILD_LIB_PATH . "/pkgconfig/{$noExt}.pc";
|
||||
if (file_exists($pkgconfFile)) {
|
||||
$lines = file($pkgconfFile);
|
||||
foreach ($lines as $value) {
|
||||
if (str_starts_with($value, 'Libs')) {
|
||||
$items = explode(' ', $value);
|
||||
foreach ($items as $item) {
|
||||
$item = trim($item);
|
||||
if (str_starts_with($item, '-l')) {
|
||||
$requiredLibs[] = $item;
|
||||
// check file existence
|
||||
if (!file_exists(BUILD_LIB_PATH . "/{$lib}")) {
|
||||
throw new WrongUsageException("Library file '{$lib}' for lib [{$library}] does not exist in '" . BUILD_LIB_PATH . "'. Please build it first.");
|
||||
}
|
||||
$lib_names[] = $this->getShortLibName($lib);
|
||||
}
|
||||
// add frameworks for macOS
|
||||
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||
$frameworks = array_merge($frameworks, Config::getLib($library, 'frameworks', []));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$requiredLibs[] = $this->getShortLibName($lib);
|
||||
}
|
||||
foreach ($requiredLibs as $requiredLib) {
|
||||
if (!in_array($requiredLib, $short_name)) {
|
||||
$short_name[] = $requiredLib;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$short_name[] = $this->getShortLibName($lib);
|
||||
}
|
||||
}
|
||||
if (PHP_OS_FAMILY !== 'Darwin') {
|
||||
continue;
|
||||
}
|
||||
foreach (Config::getLib($library, 'frameworks', []) as $fw) {
|
||||
|
||||
// post-process
|
||||
$lib_names = array_filter($lib_names, fn ($x) => $x !== '');
|
||||
$lib_names = array_reverse(array_unique($lib_names));
|
||||
$frameworks = array_unique($frameworks);
|
||||
|
||||
// process frameworks to short_name
|
||||
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||
foreach ($frameworks as $fw) {
|
||||
$ks = '-framework ' . $fw;
|
||||
if (!in_array($ks, $short_name)) {
|
||||
$short_name[] = $ks;
|
||||
if (!in_array($ks, $lib_names)) {
|
||||
$lib_names[] = $ks;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in_array('imap', $libraries) && SPCTarget::getLibc() === 'glibc') {
|
||||
$short_name[] = '-lcrypt';
|
||||
$lib_names[] = '-lcrypt';
|
||||
}
|
||||
return implode(' ', $short_name);
|
||||
if (!$use_short_libs) {
|
||||
$lib_names = array_map(fn ($l) => $this->getFullLibName($l), $lib_names);
|
||||
}
|
||||
return implode(' ', $lib_names);
|
||||
}
|
||||
|
||||
private function getShortLibName(string $lib): string
|
||||
@ -160,6 +226,19 @@ class SPCConfigUtil
|
||||
return '-l' . substr($lib, 3, -2);
|
||||
}
|
||||
|
||||
private function getFullLibName(string $lib)
|
||||
{
|
||||
if (!str_starts_with($lib, '-l')) {
|
||||
return $lib;
|
||||
}
|
||||
$libname = substr($lib, 2);
|
||||
$staticLib = BUILD_LIB_PATH . '/' . "lib{$libname}.a";
|
||||
if (file_exists($staticLib)) {
|
||||
return $staticLib;
|
||||
}
|
||||
return $lib;
|
||||
}
|
||||
|
||||
private function getFrameworksString(array $extensions): string
|
||||
{
|
||||
$list = [];
|
||||
|
||||
@ -73,7 +73,7 @@ class SPCTarget
|
||||
public static function getTargetOS(): string
|
||||
{
|
||||
$target = getenv('SPC_TARGET');
|
||||
if ($target === false) {
|
||||
if ($target === false || $target === '') {
|
||||
return PHP_OS_FAMILY;
|
||||
}
|
||||
// TODO: zig target parser like below?
|
||||
|
||||
@ -12,7 +12,7 @@ use SPC\util\UnixShell;
|
||||
|
||||
class UnixAutoconfExecutor extends Executor
|
||||
{
|
||||
protected ?UnixShell $shell = null;
|
||||
protected UnixShell $shell;
|
||||
|
||||
protected array $configure_args = [];
|
||||
|
||||
|
||||
@ -5,25 +5,37 @@ declare(strict_types=1);
|
||||
namespace SPC\util\executor;
|
||||
|
||||
use Closure;
|
||||
use SPC\builder\freebsd\library\BSDLibraryBase;
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\UnixShell;
|
||||
|
||||
/**
|
||||
* Unix-like OS cmake command executor.
|
||||
*/
|
||||
class UnixCMakeExecutor extends Executor
|
||||
{
|
||||
protected ?string $build_dir = null;
|
||||
protected UnixShell $shell;
|
||||
|
||||
protected array $configure_args = [];
|
||||
|
||||
protected ?string $build_dir = null;
|
||||
|
||||
protected ?array $custom_default_args = null;
|
||||
|
||||
protected int $steps = 3;
|
||||
|
||||
protected bool $reset = true;
|
||||
|
||||
public function __construct(protected BSDLibraryBase|LinuxLibraryBase|MacOSLibraryBase $library)
|
||||
{
|
||||
parent::__construct($library);
|
||||
$this->initShell();
|
||||
}
|
||||
|
||||
public function build(string $build_pos = '..'): void
|
||||
{
|
||||
// set cmake dir
|
||||
@ -33,17 +45,16 @@ class UnixCMakeExecutor extends Executor
|
||||
FileSystem::resetDir($this->build_dir);
|
||||
}
|
||||
|
||||
// prepare shell
|
||||
$shell = shell()->cd($this->build_dir)->initializeEnv($this->library);
|
||||
$this->shell = $this->shell->cd($this->build_dir);
|
||||
|
||||
// config
|
||||
$this->steps >= 1 && $shell->exec("cmake {$this->getConfigureArgs()} {$this->getDefaultCMakeArgs()} {$build_pos}");
|
||||
$this->steps >= 1 && $this->shell->exec("cmake {$this->getConfigureArgs()} {$this->getDefaultCMakeArgs()} {$build_pos}");
|
||||
|
||||
// make
|
||||
$this->steps >= 2 && $shell->exec("cmake --build . -j {$this->library->getBuilder()->concurrency}");
|
||||
$this->steps >= 2 && $this->shell->exec("cmake --build . -j {$this->library->getBuilder()->concurrency}");
|
||||
|
||||
// install
|
||||
$this->steps >= 3 && $shell->exec('make install');
|
||||
$this->steps >= 3 && $this->shell->exec('make install');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,6 +88,12 @@ class UnixCMakeExecutor extends Executor
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function appendEnv(array $env): static
|
||||
{
|
||||
$this->shell->appendEnv($env);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* To build steps.
|
||||
*
|
||||
@ -209,4 +226,9 @@ CMAKE;
|
||||
FileSystem::writeFile(SOURCE_PATH . '/toolchain.cmake', $toolchain);
|
||||
return $created = realpath(SOURCE_PATH . '/toolchain.cmake');
|
||||
}
|
||||
|
||||
private function initShell(): void
|
||||
{
|
||||
$this->shell = shell()->initializeEnv($this->library);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ assert(function_exists('curl_close'));
|
||||
$curl_version = curl_version();
|
||||
if (stripos($curl_version['ssl_version'], 'schannel') !== false) {
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, 'https://example.com/');
|
||||
curl_setopt($curl, CURLOPT_URL, 'https://captive.apple.com/');
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_HEADER, 0);
|
||||
$data = curl_exec($curl);
|
||||
|
||||
@ -10,3 +10,4 @@ assert(Imagick::queryFormats('WEBP') !== []);
|
||||
assert(Imagick::queryFormats('JPEG') !== []);
|
||||
assert(Imagick::queryFormats('PNG') !== []);
|
||||
assert(Imagick::queryFormats('TIFF') !== []);
|
||||
assert(Imagick::queryFormats('JXL') !== []);
|
||||
|
||||
@ -5,5 +5,5 @@ declare(strict_types=1);
|
||||
assert(function_exists('openssl_digest'));
|
||||
assert(openssl_digest('123456', 'md5') === 'e10adc3949ba59abbe56e057f20f883e');
|
||||
if (file_exists('/etc/ssl/openssl.cnf')) {
|
||||
assert(file_get_contents('https://example.com/') !== false);
|
||||
assert(file_get_contents('https://captive.apple.com/') !== false);
|
||||
}
|
||||
|
||||
@ -232,3 +232,13 @@ function ac_with_args(string $arg_name, bool $use_value = false): array
|
||||
{
|
||||
return $use_value ? ["--with-{$arg_name}=yes", "--with-{$arg_name}=no"] : ["--with-{$arg_name}", "--without-{$arg_name}"];
|
||||
}
|
||||
|
||||
function get_pack_replace(): array
|
||||
{
|
||||
return [
|
||||
BUILD_LIB_PATH => '@build_lib_path@',
|
||||
BUILD_BIN_PATH => '@build_bin_path@',
|
||||
BUILD_INCLUDE_PATH => '@build_include_path@',
|
||||
BUILD_ROOT_PATH => '@build_root_path@',
|
||||
];
|
||||
}
|
||||
|
||||
@ -17,12 +17,11 @@ $test_php_version = [
|
||||
// '8.2',
|
||||
// '8.3',
|
||||
'8.4',
|
||||
'8.5',
|
||||
];
|
||||
|
||||
// test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available)
|
||||
$test_os = [
|
||||
'macos-13', // bin/spc for x86_64
|
||||
// 'macos-13', // bin/spc for x86_64
|
||||
// 'macos-14', // bin/spc for arm64
|
||||
'macos-15', // bin/spc for arm64
|
||||
'ubuntu-latest', // bin/spc-alpine-docker for x86_64
|
||||
@ -30,7 +29,7 @@ $test_os = [
|
||||
// 'ubuntu-24.04', // bin/spc for x86_64
|
||||
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
|
||||
'ubuntu-24.04-arm', // bin/spc for arm64
|
||||
'windows-latest', // .\bin\spc.ps1
|
||||
// 'windows-latest', // .\bin\spc.ps1
|
||||
];
|
||||
|
||||
// whether enable thread safe
|
||||
@ -49,8 +48,8 @@ $prefer_pre_built = false;
|
||||
|
||||
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
|
||||
$extensions = match (PHP_OS_FAMILY) {
|
||||
'Linux', 'Darwin' => 'apcu,bcmath,bz2,calendar,ctype,curl,dba,dom,event,exif,fileinfo,filter,ftp,gd,gmp,iconv,imagick,imap,intl,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,opentelemetry,pcntl,pdo,pdo_mysql,pgsql,phar,posix,protobuf,readline,redis,session,shmop,simplexml,soap,sockets,sodium,sqlite3,sysvmsg,sysvsem,sysvshm,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib',
|
||||
'Windows' => 'apcu,bcmath,bz2,calendar,ctype,curl,dba,dom,ds,exif,ffi,fileinfo,filter,ftp,gd,iconv,igbinary,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,rar,redis,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yac,yaml,zip,zlib',
|
||||
'Linux', 'Darwin' => 'grpc',
|
||||
'Windows' => 'curl',
|
||||
};
|
||||
|
||||
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
|
||||
|
||||
@ -78,11 +78,6 @@ class ExtensionTest extends TestCase
|
||||
}
|
||||
}
|
||||
|
||||
public function testGetLibFilesString()
|
||||
{
|
||||
$this->assertStringEndsWith('libonig.a', $this->extension->getLibFilesString());
|
||||
}
|
||||
|
||||
public function testGetName()
|
||||
{
|
||||
$this->assertEquals('mbregex', $this->extension->getName());
|
||||
|
||||
@ -54,7 +54,7 @@ class SPCConfigUtilTest extends TestCase
|
||||
$this->assertStringContainsString('-lphp', $result['libs']);
|
||||
|
||||
// has cpp
|
||||
$result = (new SPCConfigUtil())->config(['swoole']);
|
||||
$result = (new SPCConfigUtil())->config(['rar']);
|
||||
$this->assertStringContainsString(PHP_OS_FAMILY === 'Darwin' ? '-lc++' : '-lstdc++', $result['libs']);
|
||||
|
||||
// has mimalloc.o in lib dir
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user