mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-02 22:35:43 +08:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90981e3877 | ||
|
|
d69826eb4a | ||
|
|
dc83282019 | ||
|
|
23c0d6f4aa | ||
|
|
8e4d4b7be5 | ||
|
|
ee906aaff9 | ||
|
|
e2b80e7f03 | ||
|
|
09073c5517 | ||
|
|
00050f4d0e | ||
|
|
cff6ec17ea | ||
|
|
64079d9331 | ||
|
|
541889d17b | ||
|
|
c91128995d | ||
|
|
fd2b7af1dc | ||
|
|
081e2d2846 | ||
|
|
9edb9417a1 | ||
|
|
4ae4165ba2 | ||
|
|
e441a575ea | ||
|
|
1575016885 | ||
|
|
987ad4b846 | ||
|
|
f4b03ae835 | ||
|
|
d6de01d05c | ||
|
|
09b7159119 | ||
|
|
4198ddd5d1 | ||
|
|
8332ed87e0 | ||
|
|
f6b091498f | ||
|
|
a45f314447 | ||
|
|
8c8cb70174 | ||
|
|
f09c18e78f | ||
|
|
f5d93d2f54 | ||
|
|
7402fbf7c1 | ||
|
|
2c590e5895 | ||
|
|
463a98b1bf | ||
|
|
6d1c6d7f61 | ||
|
|
08362fb6e5 | ||
|
|
4d5641f6ec | ||
|
|
f34ecf9468 | ||
|
|
aa5c829fae | ||
|
|
fc118d709e | ||
|
|
589a4a9803 | ||
|
|
944e314bab | ||
|
|
0b17ce9e61 | ||
|
|
ed4978bb89 | ||
|
|
7a4f28e939 | ||
|
|
5cb6a75e7d | ||
|
|
757af25d8f | ||
|
|
5e3e7eccbf | ||
|
|
9738fcd6cd | ||
|
|
5a6a33303c | ||
|
|
9a2d94cc33 | ||
|
|
8649068159 | ||
|
|
4d3501118e |
@@ -162,6 +162,47 @@ if [ ! -z "$GITHUB_TOKEN" ]; then
|
|||||||
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
|
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
|
||||||
|
FRANKENPHP_APP_PATH=""
|
||||||
|
NEW_ARGS=()
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--with-frankenphp-app=*)
|
||||||
|
FRANKENPHP_APP_PATH="${1#*=}"
|
||||||
|
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--with-frankenphp-app)
|
||||||
|
if [ -n "${2:-}" ]; then
|
||||||
|
FRANKENPHP_APP_PATH="$2"
|
||||||
|
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
NEW_ARGS+=("$1")
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
NEW_ARGS+=("$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Normalize the path and add mount if provided
|
||||||
|
if [ -n "$FRANKENPHP_APP_PATH" ]; then
|
||||||
|
# expand ~ to $HOME
|
||||||
|
if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
|
||||||
|
FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
|
||||||
|
fi
|
||||||
|
# make absolute if relative
|
||||||
|
case "$FRANKENPHP_APP_PATH" in
|
||||||
|
/*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
|
||||||
|
*) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
|
||||||
|
esac
|
||||||
|
MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
|
||||||
|
fi
|
||||||
|
|
||||||
# Run docker
|
# Run docker
|
||||||
# shellcheck disable=SC2068
|
# shellcheck disable=SC2068
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
@@ -183,5 +224,5 @@ if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
|
|||||||
set -ex
|
set -ex
|
||||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
||||||
else
|
else
|
||||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc $@
|
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -174,6 +174,47 @@ if [ ! -z "$GITHUB_TOKEN" ]; then
|
|||||||
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
|
ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
|
||||||
|
FRANKENPHP_APP_PATH=""
|
||||||
|
NEW_ARGS=()
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--with-frankenphp-app=*)
|
||||||
|
FRANKENPHP_APP_PATH="${1#*=}"
|
||||||
|
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
--with-frankenphp-app)
|
||||||
|
if [ -n "${2:-}" ]; then
|
||||||
|
FRANKENPHP_APP_PATH="$2"
|
||||||
|
NEW_ARGS+=("--with-frankenphp-app=/app/app")
|
||||||
|
shift 2
|
||||||
|
else
|
||||||
|
NEW_ARGS+=("$1")
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
NEW_ARGS+=("$1")
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Normalize the path and add mount if provided
|
||||||
|
if [ -n "$FRANKENPHP_APP_PATH" ]; then
|
||||||
|
# expand ~ to $HOME
|
||||||
|
if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
|
||||||
|
FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
|
||||||
|
fi
|
||||||
|
# make absolute if relative
|
||||||
|
case "$FRANKENPHP_APP_PATH" in
|
||||||
|
/*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
|
||||||
|
*) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
|
||||||
|
esac
|
||||||
|
MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
|
||||||
|
fi
|
||||||
|
|
||||||
# Run docker
|
# Run docker
|
||||||
# shellcheck disable=SC2068
|
# shellcheck disable=SC2068
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
@@ -196,5 +237,5 @@ if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
|
|||||||
set -ex
|
set -ex
|
||||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --privileged --rm -it $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
$DOCKER_EXECUTABLE run $PLATFORM_ARG --privileged --rm -it $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
||||||
else
|
else
|
||||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc $@
|
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,40 +1,41 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
; static-php-cli (spc) env configuration
|
; static-php-cli (spc) env configuration
|
||||||
;
|
;
|
||||||
; This file is used to set default env vars for static-php-cli build.
|
; This file is used to set default env vars for static-php-cli build.
|
||||||
; As dynamic build process, some of these vars can be overwritten by CLI options.
|
; As dynamic build process, some of these vars can be overwritten by CLI options.
|
||||||
; And you can also overwrite these vars by setting them in your shell environment.
|
; And you can also overwrite these vars by setting them in your shell environment.
|
||||||
|
; The value should be changed only if you know what you are doing. Otherwise, please leave them as default.
|
||||||
;
|
;
|
||||||
; We need to use some pre-defined internal env vars, like `BUILD_ROOT_PATH`, `DOWNLOAD_PATH`, etc.
|
; We need to use some pre-defined internal env vars, like `BUILD_ROOT_PATH`, `DOWNLOAD_PATH`, etc.
|
||||||
; Please note that these vars cannot be defined in this file, they are only be defined before static-php-cli running.
|
; Please note that these vars cannot be defined in this file, they should only be defined before static-php-cli running.
|
||||||
;
|
;
|
||||||
; Here's a list of env vars, these value cannot be changed anywhere:
|
; Here's a list of env vars, these variables will be defined if not defined:
|
||||||
;
|
;
|
||||||
; SPC_VERSION: the version of static-php-cli.
|
|
||||||
; WORKING_DIR: the working directory of the build process. (default: `$(pwd)`)
|
|
||||||
; ROOT_DIR: the root directory of static-php-cli. (default: `/path/to/static-php-cli`, when running in phar or micro mode: `phar://path/to/spc.phar`)
|
|
||||||
; BUILD_ROOT_PATH: the root path of the build process. (default: `$(pwd)/buildroot`)
|
; BUILD_ROOT_PATH: the root path of the build process. (default: `$(pwd)/buildroot`)
|
||||||
; BUILD_INCLUDE_PATH: the path of the include files. (default: `$BUILD_ROOT_PATH/include`)
|
; BUILD_INCLUDE_PATH: the path of the include files. (default: `$BUILD_ROOT_PATH/include`)
|
||||||
; BUILD_LIB_PATH: the path of the lib files. (default: `$BUILD_ROOT_PATH/lib`)
|
; BUILD_LIB_PATH: the path of the lib files. (default: `$BUILD_ROOT_PATH/lib`)
|
||||||
; BUILD_BIN_PATH: the path of the bin files. (default: `$BUILD_ROOT_PATH/bin`)
|
; BUILD_BIN_PATH: the path of the bin files. (default: `$BUILD_ROOT_PATH/bin`)
|
||||||
; PKG_ROOT_PATH: the root path of the package files. (default: `$(pwd)/pkgroot`)
|
; BUILD_MODULES_PATH: the path of the php modules (shared extensions) files. (default: `$BUILD_ROOT_PATH/modules`)
|
||||||
|
; PKG_ROOT_PATH: the root path of the package files. (default: `$(pwd)/pkgroot/$GNU_ARCH-{darwin|linux|windows}`)
|
||||||
; SOURCE_PATH: the path of the source files. (default: `$(pwd)/source`)
|
; SOURCE_PATH: the path of the source files. (default: `$(pwd)/source`)
|
||||||
; DOWNLOAD_PATH: the path of the download files. (default: `$(pwd)/downloads`)
|
; DOWNLOAD_PATH: the path of the download files. (default: `$(pwd)/downloads`)
|
||||||
; CPU_COUNT: the count of the CPU cores. (default: `$(nproc)`)
|
; PATH: (*nix only) static-php-cli will add `$BUILD_BIN_PATH` to PATH.
|
||||||
; SPC_ARCH: the arch of the current system, for some libraries needed `--host=XXX` args. (default: `$(uname -m)`, e.g. `x86_64`, `aarch64`, `arm64`)
|
; PKG_CONFIG_PATH: (*nix only) static-php-cli will set `$BUILD_LIB_PATH/pkgconfig` to PKG_CONFIG_PATH.
|
||||||
; GNU_ARCH: the GNU arch of the current system. (default: `$(uname -m)`, e.g. `x86_64`, `aarch64`)
|
|
||||||
; MAC_ARCH: the MAC arch of the current system. (default: `$(uname -m)`, e.g. `x86_64`, `arm64`)
|
|
||||||
;
|
;
|
||||||
; * These vars are only be defined in Unix (macOS, Linux, FreeBSD)Builder and cannot be changed anywhere:
|
; Here's a list of env vars, these variables is defined in SPC and cannot be changed anywhere:
|
||||||
; PATH: static-php-cli will add `$BUILD_BIN_PATH` to PATH.
|
|
||||||
; PKG_CONFIG: static-php-cli will set `$BUILD_BIN_PATH/pkg-config` to PKG_CONFIG.
|
|
||||||
; PKG_CONFIG_PATH: static-php-cli will set `$BUILD_LIB_PATH/pkgconfig` to PKG_CONFIG_PATH.
|
|
||||||
;
|
;
|
||||||
; * These vars are only be defined in LinuxBuilder and cannot be changed anywhere:
|
; SPC_VERSION: the version of static-php-cli.
|
||||||
; SPC_LINUX_DEFAULT_CC: the default compiler for linux. (For alpine linux: `gcc`, default: `$GNU_ARCH-linux-musl-gcc`)
|
; WORKING_DIR: the working directory of the build process. (default: `$(pwd)`)
|
||||||
; SPC_LINUX_DEFAULT_CXX: the default c++ compiler for linux. (For alpine linux: `g++`, default: `$GNU_ARCH-linux-musl-g++`)
|
; ROOT_DIR: the root directory of static-php-cli. (default: `/path/to/static-php-cli`, when running in phar or micro mode: `phar://path/to/spc.phar`)
|
||||||
; SPC_LINUX_DEFAULT_AR: the default archiver for linux. (For alpine linux: `ar`, default: `$GNU_ARCH-linux-musl-ar`)
|
; CPU_COUNT: the count of the CPU cores. (default: `$(nproc)`)
|
||||||
; SPC_EXTRA_PHP_VARS: the extra vars for building php, used in `configure` and `make` command.
|
; SPC_ARCH: the arch of the current system, for some libraries needed `--host=XXX` args. (default: `$(uname -m)`, e.g. `x86_64`, `aarch64`, `arm64`)
|
||||||
|
; GNU_ARCH: the GNU arch of the current system. (default: `$(uname -m)`, e.g. `x86_64`, `aarch64`)
|
||||||
|
; MAC_ARCH: the MAC arch of the current system. (default: `$(uname -m)`, e.g. `x86_64`, `arm64`)
|
||||||
|
; PKG_CONFIG: (*nix only) static-php-cli will set `$BUILD_BIN_PATH/pkg-config` to PKG_CONFIG.
|
||||||
|
; SPC_LINUX_DEFAULT_CC: (linux only) the default compiler for linux. (For alpine linux: `gcc`, default: `$GNU_ARCH-linux-musl-gcc`)
|
||||||
|
; SPC_LINUX_DEFAULT_CXX: (linux only) the default c++ compiler for linux. (For alpine linux: `g++`, default: `$GNU_ARCH-linux-musl-g++`)
|
||||||
|
; SPC_LINUX_DEFAULT_AR: (linux only) the default archiver for linux. (For alpine linux: `ar`, default: `$GNU_ARCH-linux-musl-ar`)
|
||||||
|
; SPC_EXTRA_PHP_VARS: (linux only) the extra vars for building php, used in `configure` and `make` command.
|
||||||
|
|
||||||
[global]
|
[global]
|
||||||
; Build concurrency for make -jN, default is CPU_COUNT, this value are used in every libs.
|
; Build concurrency for make -jN, default is CPU_COUNT, this value are used in every libs.
|
||||||
@@ -44,7 +45,7 @@ SPC_SKIP_PHP_VERSION_CHECK="no"
|
|||||||
; Ignore some check item for bin/spc doctor command, comma separated (e.g. SPC_SKIP_DOCTOR_CHECK_ITEMS="if homebrew has installed")
|
; Ignore some check item for bin/spc doctor command, comma separated (e.g. SPC_SKIP_DOCTOR_CHECK_ITEMS="if homebrew has installed")
|
||||||
SPC_SKIP_DOCTOR_CHECK_ITEMS=""
|
SPC_SKIP_DOCTOR_CHECK_ITEMS=""
|
||||||
; extra modules that xcaddy will include in the FrankenPHP build
|
; extra modules that xcaddy will include in the FrankenPHP build
|
||||||
SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/frankenphp/caddy --with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
|
SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/mercure/caddy --with github.com/dunglas/vulcain/caddy --with github.com/dunglas/caddy-cbrotli"
|
||||||
; The display message for php version output (PHP >= 8.4 available)
|
; The display message for php version output (PHP >= 8.4 available)
|
||||||
PHP_BUILD_PROVIDER="static-php-cli ${SPC_VERSION}"
|
PHP_BUILD_PROVIDER="static-php-cli ${SPC_VERSION}"
|
||||||
|
|
||||||
@@ -109,9 +110,7 @@ SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --disable
|
|||||||
; *** default build vars for building php ***
|
; *** default build vars for building php ***
|
||||||
; embed type for php, static (libphp.a) or shared (libphp.so)
|
; embed type for php, static (libphp.a) or shared (libphp.so)
|
||||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||||
; CFLAGS for configuring php
|
; EXTRA_CFLAGS for `configure` and `make` php
|
||||||
SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS} -fPIE"
|
|
||||||
; 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="-g -fstack-protector-strong -fno-ident -fPIE ${SPC_DEFAULT_C_FLAGS}"
|
||||||
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
|
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
|
||||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
|
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
|
||||||
@@ -141,10 +140,8 @@ SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-
|
|||||||
; *** default build vars for building php ***
|
; *** default build vars for building php ***
|
||||||
; embed type for php, static (libphp.a) or shared (libphp.dylib)
|
; embed type for php, static (libphp.a) or shared (libphp.dylib)
|
||||||
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
|
||||||
; CFLAGS for configuring php
|
; EXTRA_CFLAGS for `configure` and `make` php
|
||||||
SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS} -Werror=unknown-warning-option"
|
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -Werror=unknown-warning-option ${SPC_DEFAULT_C_FLAGS}"
|
||||||
; EXTRA_CFLAGS for `make` php
|
|
||||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie ${SPC_DEFAULT_C_FLAGS}"
|
|
||||||
|
|
||||||
[freebsd]
|
[freebsd]
|
||||||
; compiler environments
|
; compiler environments
|
||||||
|
|||||||
@@ -7,12 +7,14 @@
|
|||||||
"source": "php-src",
|
"source": "php-src",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
"lib-base",
|
"lib-base",
|
||||||
"micro"
|
"micro",
|
||||||
|
"frankenphp"
|
||||||
],
|
],
|
||||||
"lib-depends-macos": [
|
"lib-depends-macos": [
|
||||||
"lib-base",
|
"lib-base",
|
||||||
"micro",
|
"micro",
|
||||||
"libxml2"
|
"libxml2",
|
||||||
|
"frankenphp"
|
||||||
],
|
],
|
||||||
"lib-suggests-linux": [
|
"lib-suggests-linux": [
|
||||||
"libacl",
|
"libacl",
|
||||||
@@ -24,6 +26,10 @@
|
|||||||
"watcher"
|
"watcher"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"frankenphp": {
|
||||||
|
"source": "frankenphp",
|
||||||
|
"type": "target"
|
||||||
|
},
|
||||||
"micro": {
|
"micro": {
|
||||||
"type": "target",
|
"type": "target",
|
||||||
"source": "micro"
|
"source": "micro"
|
||||||
@@ -506,13 +512,16 @@
|
|||||||
},
|
},
|
||||||
"librdkafka": {
|
"librdkafka": {
|
||||||
"source": "librdkafka",
|
"source": "librdkafka",
|
||||||
"static-libs-unix": [
|
"pkg-configs": [
|
||||||
"librdkafka.a",
|
"rdkafka++-static",
|
||||||
"librdkafka++.a",
|
"rdkafka-static"
|
||||||
"librdkafka-static.a"
|
|
||||||
],
|
],
|
||||||
"cpp-library": true,
|
"cpp-library": true,
|
||||||
"lib-suggests": [
|
"lib-suggests": [
|
||||||
|
"curl",
|
||||||
|
"liblz4",
|
||||||
|
"openssl",
|
||||||
|
"zlib",
|
||||||
"zstd"
|
"zstd"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -965,5 +974,24 @@
|
|||||||
"zstd.h",
|
"zstd.h",
|
||||||
"zstd_errors.h"
|
"zstd_errors.h"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"liburing": {
|
||||||
|
"source": "liburing",
|
||||||
|
"pkg-configs": [
|
||||||
|
"liburing",
|
||||||
|
"liburing-ffi"
|
||||||
|
],
|
||||||
|
"static-libs-linux": [
|
||||||
|
"liburing.a",
|
||||||
|
"liburing-ffi.a"
|
||||||
|
],
|
||||||
|
"headers-linux": [
|
||||||
|
"liburing/",
|
||||||
|
"liburing.h"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"frankenphp": {
|
||||||
|
"source": "frankenphp",
|
||||||
|
"type": "target"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -301,10 +301,20 @@
|
|||||||
"path": "LICENSE.MIT"
|
"path": "LICENSE.MIT"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"frankenphp": {
|
||||||
|
"type": "ghtar",
|
||||||
|
"repo": "php/frankenphp",
|
||||||
|
"prefer-stable": true,
|
||||||
|
"provide-pre-built": false,
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"freetype": {
|
"freetype": {
|
||||||
"type": "git",
|
"type": "ghtagtar",
|
||||||
"rev": "VER-2-13-2",
|
"repo": "freetype/freetype",
|
||||||
"url": "https://github.com/freetype/freetype",
|
"match": "VER-2-\\d+-\\d+",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "LICENSE.TXT"
|
"path": "LICENSE.TXT"
|
||||||
@@ -363,6 +373,16 @@
|
|||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"frankenphp": {
|
||||||
|
"type": "ghtar",
|
||||||
|
"repo": "php/frankenphp",
|
||||||
|
"prefer-stable": true,
|
||||||
|
"provide-pre-build": false,
|
||||||
|
"license": {
|
||||||
|
"type": "file",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
"icu-static-win": {
|
"icu-static-win": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://dl.static-php.dev/static-php-cli/deps/icu-static-windows-x64/icu-static-windows-x64.zip",
|
"url": "https://dl.static-php.dev/static-php-cli/deps/icu-static-windows-x64/icu-static-windows-x64.zip",
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ use Symfony\Component\Console\Application;
|
|||||||
*/
|
*/
|
||||||
final class ConsoleApplication extends Application
|
final class ConsoleApplication extends Application
|
||||||
{
|
{
|
||||||
public const string VERSION = '2.7.6';
|
public const string VERSION = '2.7.7';
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder;
|
namespace SPC\builder;
|
||||||
|
|
||||||
|
use SPC\builder\unix\UnixBuilderBase;
|
||||||
use SPC\exception\EnvironmentException;
|
use SPC\exception\EnvironmentException;
|
||||||
use SPC\exception\SPCException;
|
use SPC\exception\SPCException;
|
||||||
use SPC\exception\ValidationException;
|
use SPC\exception\ValidationException;
|
||||||
@@ -220,7 +221,7 @@ class Extension
|
|||||||
*/
|
*/
|
||||||
public function patchBeforeSharedMake(): bool
|
public function patchBeforeSharedMake(): bool
|
||||||
{
|
{
|
||||||
$config = (new SPCConfigUtil($this->builder))->config([$this->getName()], array_map(fn ($l) => $l->getName(), $this->builder->getLibs()));
|
$config = (new SPCConfigUtil($this->builder))->getExtensionConfig($this);
|
||||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||||
$lstdcpp = str_contains($sharedLibs, '-l:libstdc++.a') ? '-l:libstdc++.a' : null;
|
$lstdcpp = str_contains($sharedLibs, '-l:libstdc++.a') ? '-l:libstdc++.a' : null;
|
||||||
$lstdcpp ??= str_contains($sharedLibs, '-lstdc++') ? '-lstdc++' : '';
|
$lstdcpp ??= str_contains($sharedLibs, '-lstdc++') ? '-lstdc++' : '';
|
||||||
@@ -448,6 +449,15 @@ class Extension
|
|||||||
->exec('make clean')
|
->exec('make clean')
|
||||||
->exec('make -j' . $this->builder->concurrency)
|
->exec('make -j' . $this->builder->concurrency)
|
||||||
->exec('make install');
|
->exec('make install');
|
||||||
|
|
||||||
|
// process *.so file
|
||||||
|
$soFile = BUILD_MODULES_PATH . '/' . $this->getName() . '.so';
|
||||||
|
if (!file_exists($soFile)) {
|
||||||
|
throw new ValidationException("extension {$this->getName()} build failed: {$soFile} not found", validation_module: "Extension {$this->getName()} build");
|
||||||
|
}
|
||||||
|
/** @var UnixBuilderBase $builder */
|
||||||
|
$builder = $this->builder;
|
||||||
|
$builder->deployBinary($soFile, $soFile, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -486,18 +496,46 @@ class Extension
|
|||||||
return $this->build_static;
|
return $this->build_static;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the library dependencies that current extension depends on.
|
||||||
|
*
|
||||||
|
* @param bool $recursive Whether it includes dependencies recursively
|
||||||
|
*/
|
||||||
|
public function getLibraryDependencies(bool $recursive = false): array
|
||||||
|
{
|
||||||
|
$ret = array_filter($this->dependencies, fn ($x) => $x instanceof LibraryBase);
|
||||||
|
if (!$recursive) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$deps = [];
|
||||||
|
|
||||||
|
$added = 1;
|
||||||
|
while ($added !== 0) {
|
||||||
|
$added = 0;
|
||||||
|
foreach ($ret as $depName => $dep) {
|
||||||
|
foreach ($dep->getDependencies(true) as $depdepName => $depdep) {
|
||||||
|
if (!array_key_exists($depdepName, $deps)) {
|
||||||
|
$deps[$depdepName] = $depdep;
|
||||||
|
++$added;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!array_key_exists($depName, $deps)) {
|
||||||
|
$deps[$depName] = $dep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $deps;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the environment variables a shared extension needs to be built.
|
* Returns the environment variables a shared extension needs to be built.
|
||||||
* CFLAGS, CXXFLAGS, LDFLAGS and so on.
|
* CFLAGS, CXXFLAGS, LDFLAGS and so on.
|
||||||
*/
|
*/
|
||||||
protected function getSharedExtensionEnv(): array
|
protected function getSharedExtensionEnv(): array
|
||||||
{
|
{
|
||||||
$config = (new SPCConfigUtil($this->builder))->config(
|
$config = (new SPCConfigUtil($this->builder))->getExtensionConfig($this);
|
||||||
[$this->getName()],
|
|
||||||
array_map(fn ($l) => $l->getName(), $this->getLibraryDependencies(recursive: true)),
|
|
||||||
$this->builder->getOption('with-suggested-exts'),
|
|
||||||
$this->builder->getOption('with-suggested-libs'),
|
|
||||||
);
|
|
||||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||||
$preStatic = PHP_OS_FAMILY === 'Darwin' ? '' : '-Wl,--start-group ';
|
$preStatic = PHP_OS_FAMILY === 'Darwin' ? '' : '-Wl,--start-group ';
|
||||||
$postStatic = PHP_OS_FAMILY === 'Darwin' ? '' : ' -Wl,--end-group ';
|
$postStatic = PHP_OS_FAMILY === 'Darwin' ? '' : ' -Wl,--end-group ';
|
||||||
@@ -519,7 +557,7 @@ class Extension
|
|||||||
}
|
}
|
||||||
logger()->info("enabling {$this->name} without library {$name}");
|
logger()->info("enabling {$this->name} without library {$name}");
|
||||||
} else {
|
} else {
|
||||||
$this->dependencies[] = $depLib;
|
$this->dependencies[$name] = $depLib;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,7 +570,7 @@ class Extension
|
|||||||
}
|
}
|
||||||
logger()->info("enabling {$this->name} without extension {$name}");
|
logger()->info("enabling {$this->name} without extension {$name}");
|
||||||
} else {
|
} else {
|
||||||
$this->dependencies[] = $depExt;
|
$this->dependencies[$name] = $depExt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,37 +605,4 @@ class Extension
|
|||||||
}
|
}
|
||||||
return [trim($staticLibString), trim($sharedLibString)];
|
return [trim($staticLibString), trim($sharedLibString)];
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getLibraryDependencies(bool $recursive = false): array
|
|
||||||
{
|
|
||||||
$ret = array_filter($this->dependencies, fn ($x) => $x instanceof LibraryBase);
|
|
||||||
if (!$recursive) {
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
$deps = [];
|
|
||||||
|
|
||||||
$added = 1;
|
|
||||||
while ($added !== 0) {
|
|
||||||
$added = 0;
|
|
||||||
foreach ($ret as $depName => $dep) {
|
|
||||||
foreach ($dep->getDependencies(true) as $depdepName => $depdep) {
|
|
||||||
if (!array_key_exists($depdepName, $deps)) {
|
|
||||||
$deps[$depdepName] = $depdep;
|
|
||||||
++$added;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!array_key_exists($depName, $deps)) {
|
|
||||||
$deps[$depName] = $dep;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_key_exists(0, $deps)) {
|
|
||||||
$zero = [0 => $deps[0]];
|
|
||||||
unset($deps[0]);
|
|
||||||
return $zero + $deps;
|
|
||||||
}
|
|
||||||
return $deps;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class grpc extends Extension
|
|||||||
public function patchBeforeConfigure(): bool
|
public function patchBeforeConfigure(): bool
|
||||||
{
|
{
|
||||||
$util = new SPCConfigUtil($this->builder, ['libs_only_deps' => true]);
|
$util = new SPCConfigUtil($this->builder, ['libs_only_deps' => true]);
|
||||||
$config = $util->config(['grpc']);
|
$config = $util->getExtensionConfig($this);
|
||||||
$libs = $config['libs'];
|
$libs = $config['libs'];
|
||||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lgrpc', $libs);
|
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/configure', '-lgrpc', $libs);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace SPC\builder\extension;
|
|||||||
use SPC\builder\Extension;
|
use SPC\builder\Extension;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
|
use SPC\util\SPCConfigUtil;
|
||||||
|
|
||||||
#[CustomExt('rdkafka')]
|
#[CustomExt('rdkafka')]
|
||||||
class rdkafka extends Extension
|
class rdkafka extends Extension
|
||||||
@@ -15,6 +16,7 @@ class rdkafka extends Extension
|
|||||||
{
|
{
|
||||||
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\n", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm \$RDKAFKA_LIBS\n");
|
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\n", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm \$RDKAFKA_LIBS\n");
|
||||||
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\"\n", '-L$RDKAFKA_DIR/$PHP_LIBDIR -lm $RDKAFKA_LIBS"');
|
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\"\n", '-L$RDKAFKA_DIR/$PHP_LIBDIR -lm $RDKAFKA_LIBS"');
|
||||||
|
FileSystem::replaceFileStr("{$this->source_dir}/config.m4", 'PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,', 'AC_CHECK_LIB([$LIBNAME], [$LIBSYMBOL],');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,8 +39,7 @@ class rdkafka extends Extension
|
|||||||
|
|
||||||
public function getUnixConfigureArg(bool $shared = false): string
|
public function getUnixConfigureArg(bool $shared = false): string
|
||||||
{
|
{
|
||||||
$pkgconf_libs = shell()->execWithResult('pkg-config --libs --static rdkafka')[1];
|
$pkgconf_libs = (new SPCConfigUtil($this->builder, ['no_php' => true, 'libs_only_deps' => true]))->getExtensionConfig($this);
|
||||||
$pkgconf_libs = trim(implode('', $pkgconf_libs));
|
return '--with-rdkafka=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . " RDKAFKA_LIBS=\"{$pkgconf_libs['libs']}\"";
|
||||||
return '--with-rdkafka=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . ' RDKAFKA_LIBS="' . $pkgconf_libs . '"';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ class swoole extends Extension
|
|||||||
$arg .= $this->builder->getExt('swoole-hook-mysql') ? ' --enable-mysqlnd' : ' --disable-mysqlnd';
|
$arg .= $this->builder->getExt('swoole-hook-mysql') ? ' --enable-mysqlnd' : ' --disable-mysqlnd';
|
||||||
$arg .= $this->builder->getExt('swoole-hook-sqlite') ? ' --enable-swoole-sqlite' : ' --disable-swoole-sqlite';
|
$arg .= $this->builder->getExt('swoole-hook-sqlite') ? ' --enable-swoole-sqlite' : ' --disable-swoole-sqlite';
|
||||||
if ($this->builder->getExt('swoole-hook-odbc')) {
|
if ($this->builder->getExt('swoole-hook-odbc')) {
|
||||||
$config = (new SPCConfigUtil($this->builder, ['libs_only_deps' => true]))->config([], ['unixodbc']);
|
$config = (new SPCConfigUtil($this->builder))->getLibraryConfig($this->builder->getLib('unixodbc'));
|
||||||
$arg .= ' --with-swoole-odbc=unixODBC,' . BUILD_ROOT_PATH . ' SWOOLE_ODBC_LIBS="' . $config['libs'] . '"';
|
$arg .= ' --with-swoole-odbc=unixODBC,' . BUILD_ROOT_PATH . ' SWOOLE_ODBC_LIBS="' . $config['libs'] . '"';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ class BSDBuilder extends UnixBuilderBase
|
|||||||
if (!$this->getOption('no-strip', false)) {
|
if (!$this->getOption('no-strip', false)) {
|
||||||
$shell->exec('strip sapi/cli/php');
|
$shell->exec('strip sapi/cli/php');
|
||||||
}
|
}
|
||||||
$this->deployBinary(BUILD_TARGET_CLI);
|
$this->deploySAPIBinary(BUILD_TARGET_CLI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -184,7 +184,7 @@ class BSDBuilder extends UnixBuilderBase
|
|||||||
if (!$this->getOption('no-strip', false)) {
|
if (!$this->getOption('no-strip', false)) {
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec('strip --strip-unneeded micro.sfx');
|
shell()->cd(SOURCE_PATH . '/php-src/sapi/micro')->exec('strip --strip-unneeded micro.sfx');
|
||||||
}
|
}
|
||||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
$this->deploySAPIBinary(BUILD_TARGET_MICRO);
|
||||||
|
|
||||||
if ($this->phar_patched) {
|
if ($this->phar_patched) {
|
||||||
SourcePatcher::unpatchMicroPhar();
|
SourcePatcher::unpatchMicroPhar();
|
||||||
@@ -206,7 +206,7 @@ class BSDBuilder extends UnixBuilderBase
|
|||||||
if (!$this->getOption('no-strip', false)) {
|
if (!$this->getOption('no-strip', false)) {
|
||||||
$shell->exec('strip sapi/fpm/php-fpm');
|
$shell->exec('strip sapi/fpm/php-fpm');
|
||||||
}
|
}
|
||||||
$this->deployBinary(BUILD_TARGET_FPM);
|
$this->deploySAPIBinary(BUILD_TARGET_FPM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use SPC\builder\unix\UnixBuilderBase;
|
|||||||
use SPC\exception\PatchException;
|
use SPC\exception\PatchException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
|
use SPC\store\DirDiff;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
use SPC\util\GlobalEnvManager;
|
use SPC\util\GlobalEnvManager;
|
||||||
@@ -90,7 +91,7 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
// prepare build php envs
|
// prepare build php envs
|
||||||
// $musl_flag = SPCTarget::getLibc() === 'musl' ? ' -D__MUSL__' : ' -U__MUSL__';
|
// $musl_flag = SPCTarget::getLibc() === 'musl' ? ' -D__MUSL__' : ' -U__MUSL__';
|
||||||
$php_configure_env = SystemUtil::makeEnvVarString([
|
$php_configure_env = SystemUtil::makeEnvVarString([
|
||||||
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
|
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
|
||||||
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH, // . ' -Dsomethinghere', // . $musl_flag,
|
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH, // . ' -Dsomethinghere', // . $musl_flag,
|
||||||
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
||||||
// 'LIBS' => SPCTarget::getRuntimeLibs(), // do not pass static libraries here yet, they may contain polyfills for libc functions!
|
// 'LIBS' => SPCTarget::getRuntimeLibs(), // do not pass static libraries here yet, they may contain polyfills for libc functions!
|
||||||
@@ -194,15 +195,7 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
SourcePatcher::patchFile('musl_static_readline.patch', SOURCE_PATH . '/php-src', true);
|
SourcePatcher::patchFile('musl_static_readline.patch', SOURCE_PATH . '/php-src', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->getOption('no-strip', false)) {
|
$this->deploySAPIBinary(BUILD_TARGET_CLI);
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')->exec('strip --strip-unneeded php');
|
|
||||||
}
|
|
||||||
if ($this->getOption('with-upx-pack')) {
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/cli')
|
|
||||||
->exec(getenv('UPX_EXEC') . ' --best php');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_CLI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildCgi(): void
|
protected function buildCgi(): void
|
||||||
@@ -213,15 +206,7 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec("make {$concurrency} {$vars} cgi");
|
->exec("make {$concurrency} {$vars} cgi");
|
||||||
|
|
||||||
if (!$this->getOption('no-strip', false)) {
|
$this->deploySAPIBinary(BUILD_TARGET_CGI);
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/cgi')->exec('strip --strip-unneeded php-cgi');
|
|
||||||
}
|
|
||||||
if ($this->getOption('with-upx-pack')) {
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/cgi')
|
|
||||||
->exec(getenv('UPX_EXEC') . ' --best php-cgi');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_CGI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -232,29 +217,33 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
if ($this->getPHPVersionID() < 80000) {
|
if ($this->getPHPVersionID() < 80000) {
|
||||||
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
||||||
}
|
}
|
||||||
if ($this->getExt('phar')) {
|
try {
|
||||||
$this->phar_patched = true;
|
if ($this->getExt('phar')) {
|
||||||
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
$this->phar_patched = true;
|
||||||
}
|
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
||||||
|
}
|
||||||
|
|
||||||
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||||
$vars = $this->getMakeExtraVars();
|
$vars = $this->getMakeExtraVars();
|
||||||
|
|
||||||
// patch fake cli for micro
|
// patch fake cli for micro
|
||||||
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
|
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
|
||||||
$vars = SystemUtil::makeEnvVarString($vars);
|
$vars = SystemUtil::makeEnvVarString($vars);
|
||||||
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec("make {$concurrency} {$vars} micro");
|
->exec("make {$concurrency} {$vars} micro");
|
||||||
|
|
||||||
$this->processMicroUPX();
|
// deploy micro.sfx
|
||||||
|
$dst = $this->deploySAPIBinary(BUILD_TARGET_MICRO);
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
// patch after UPX-ed micro.sfx
|
||||||
|
$this->processUpxedMicroSfx($dst);
|
||||||
if ($this->phar_patched) {
|
} finally {
|
||||||
SourcePatcher::unpatchMicroPhar();
|
if ($this->phar_patched) {
|
||||||
|
SourcePatcher::unpatchMicroPhar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,14 +258,7 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
->exec('sed -i "s|//lib|/lib|g" Makefile')
|
||||||
->exec("make {$concurrency} {$vars} fpm");
|
->exec("make {$concurrency} {$vars} fpm");
|
||||||
|
|
||||||
if (!$this->getOption('no-strip', false)) {
|
$this->deploySAPIBinary(BUILD_TARGET_FPM);
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')->exec('strip --strip-unneeded php-fpm');
|
|
||||||
}
|
|
||||||
if ($this->getOption('with-upx-pack')) {
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm')
|
|
||||||
->exec(getenv('UPX_EXEC') . ' --best php-fpm');
|
|
||||||
}
|
|
||||||
$this->deployBinary(BUILD_TARGET_FPM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,6 +271,9 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
return Config::getExt($ext->getName(), 'build-with-php') === true;
|
return Config::getExt($ext->getName(), 'build-with-php') === true;
|
||||||
});
|
});
|
||||||
$install_modules = $sharedExts ? 'install-modules' : '';
|
$install_modules = $sharedExts ? 'install-modules' : '';
|
||||||
|
|
||||||
|
// detect changes in module path
|
||||||
|
$diff = new DirDiff(BUILD_MODULES_PATH, true);
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars());
|
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars());
|
||||||
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
@@ -296,10 +281,54 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
->exec('sed -i "s|^EXTENSION_DIR = .*|EXTENSION_DIR = /' . basename(BUILD_MODULES_PATH) . '|" Makefile')
|
->exec('sed -i "s|^EXTENSION_DIR = .*|EXTENSION_DIR = /' . basename(BUILD_MODULES_PATH) . '|" Makefile')
|
||||||
->exec("make {$concurrency} INSTALL_ROOT=" . BUILD_ROOT_PATH . " {$vars} install-sapi {$install_modules} install-build install-headers install-programs");
|
->exec("make {$concurrency} INSTALL_ROOT=" . BUILD_ROOT_PATH . " {$vars} install-sapi {$install_modules} install-build install-headers install-programs");
|
||||||
|
|
||||||
|
// process libphp.so for shared embed
|
||||||
|
$libphpSo = BUILD_LIB_PATH . '/libphp.so';
|
||||||
|
if (file_exists($libphpSo)) {
|
||||||
|
// post actions: rename libphp.so to libphp-<release>.so if -release is set in LDFLAGS
|
||||||
|
$this->processLibphpSoFile($libphpSo);
|
||||||
|
// deploy libphp.so
|
||||||
|
$this->deployBinary($libphpSo, $libphpSo, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process shared extensions build-with-php
|
||||||
|
$increment_files = $diff->getChangedFiles();
|
||||||
|
foreach ($increment_files as $increment_file) {
|
||||||
|
$this->deployBinary($increment_file, $increment_file, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// process libphp.a for static embed
|
||||||
|
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'static') {
|
||||||
|
$AR = getenv('AR') ?: 'ar';
|
||||||
|
f_passthru("{$AR} -t " . BUILD_LIB_PATH . "/libphp.a | grep '\\.a$' | xargs -n1 {$AR} d " . BUILD_LIB_PATH . '/libphp.a');
|
||||||
|
// export dynamic symbols
|
||||||
|
SystemUtil::exportDynamicSymbols(BUILD_LIB_PATH . '/libphp.a');
|
||||||
|
}
|
||||||
|
|
||||||
|
// patch embed php scripts
|
||||||
|
$this->patchPhpScripts();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return extra variables for php make command.
|
||||||
|
*/
|
||||||
|
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 array_filter([
|
||||||
|
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
|
||||||
|
'EXTRA_LIBS' => $config['libs'],
|
||||||
|
'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'),
|
||||||
|
'EXTRA_LDFLAGS_PROGRAM' => "-L{$lib} {$static} -pie",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function processLibphpSoFile(string $libphpSo): void
|
||||||
|
{
|
||||||
$ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS') ?: '';
|
$ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS') ?: '';
|
||||||
$libDir = BUILD_LIB_PATH;
|
$libDir = BUILD_LIB_PATH;
|
||||||
$modulesDir = BUILD_MODULES_PATH;
|
$modulesDir = BUILD_MODULES_PATH;
|
||||||
$libphpSo = "{$libDir}/libphp.so";
|
|
||||||
$realLibName = 'libphp.so';
|
$realLibName = 'libphp.so';
|
||||||
$cwd = getcwd();
|
$cwd = getcwd();
|
||||||
|
|
||||||
@@ -361,60 +390,29 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'static') {
|
|
||||||
$AR = getenv('AR') ?: 'ar';
|
|
||||||
f_passthru("{$AR} -t " . BUILD_LIB_PATH . "/libphp.a | grep '\\.a$' | xargs -n1 {$AR} d " . BUILD_LIB_PATH . '/libphp.a');
|
|
||||||
// export dynamic symbols
|
|
||||||
SystemUtil::exportDynamicSymbols(BUILD_LIB_PATH . '/libphp.a');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->getOption('no-strip', false) && file_exists(BUILD_LIB_PATH . '/' . $realLibName)) {
|
|
||||||
shell()->cd(BUILD_LIB_PATH)->exec("strip --strip-unneeded {$realLibName}");
|
|
||||||
}
|
|
||||||
$this->patchPhpScripts();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return extra variables for php make command.
|
* Patch micro.sfx after UPX compression.
|
||||||
|
* micro needs special section handling in LinuxBuilder.
|
||||||
|
* The micro.sfx does not support UPX directly, but we can remove UPX
|
||||||
|
* info segment to adapt.
|
||||||
|
* This will also make micro.sfx with upx-packed more like a malware fore antivirus
|
||||||
*/
|
*/
|
||||||
private function getMakeExtraVars(): array
|
private function processUpxedMicroSfx(string $dst): void
|
||||||
{
|
{
|
||||||
$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'));
|
if ($this->getOption('with-upx-pack') && version_compare($this->getMicroVersion(), '0.2.0') >= 0) {
|
||||||
$static = SPCTarget::isStatic() ? '-all-static' : '';
|
// strip first
|
||||||
$lib = BUILD_LIB_PATH;
|
// cut binary with readelf
|
||||||
return array_filter([
|
[$ret, $out] = shell()->execWithResult("readelf -l {$dst} | awk '/LOAD|GNU_STACK/ {getline; print \$1, \$2, \$3, \$4, \$6, \$7}'");
|
||||||
'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
|
$out[1] = explode(' ', $out[1]);
|
||||||
'EXTRA_LIBS' => $config['libs'],
|
$offset = $out[1][0];
|
||||||
'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'),
|
if ($ret !== 0 || !str_starts_with($offset, '0x')) {
|
||||||
'EXTRA_LDFLAGS_PROGRAM' => "-L{$lib} {$static} -pie",
|
throw new PatchException('phpmicro UPX patcher', 'Cannot find offset in readelf output');
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strip micro.sfx for Linux.
|
|
||||||
* The micro.sfx does not support UPX directly, but we can remove UPX-info segment to adapt.
|
|
||||||
* This will also make micro.sfx with upx-packed more like a malware fore antivirus :(
|
|
||||||
*/
|
|
||||||
private function processMicroUPX(): void
|
|
||||||
{
|
|
||||||
if (version_compare($this->getMicroVersion(), '0.2.0') >= 0 && !$this->getOption('no-strip', false)) {
|
|
||||||
shell()->exec('strip --strip-unneeded ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx');
|
|
||||||
|
|
||||||
if ($this->getOption('with-upx-pack')) {
|
|
||||||
// strip first
|
|
||||||
shell()->exec(getenv('UPX_EXEC') . ' --best ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx');
|
|
||||||
// cut binary with readelf
|
|
||||||
[$ret, $out] = shell()->execWithResult('readelf -l ' . SOURCE_PATH . '/php-src/sapi/micro/micro.sfx | awk \'/LOAD|GNU_STACK/ {getline; print $1, $2, $3, $4, $6, $7}\'');
|
|
||||||
$out[1] = explode(' ', $out[1]);
|
|
||||||
$offset = $out[1][0];
|
|
||||||
if ($ret !== 0 || !str_starts_with($offset, '0x')) {
|
|
||||||
throw new PatchException('phpmicro UPX patcher', 'Cannot find offset in readelf output');
|
|
||||||
}
|
|
||||||
$offset = hexdec($offset);
|
|
||||||
// remove upx extra wastes
|
|
||||||
file_put_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx', substr(file_get_contents(SOURCE_PATH . '/php-src/sapi/micro/micro.sfx'), 0, $offset));
|
|
||||||
}
|
}
|
||||||
|
$offset = hexdec($offset);
|
||||||
|
// remove upx extra wastes
|
||||||
|
file_put_contents($dst, substr(file_get_contents($dst), 0, $offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use SPC\builder\macos\library\MacOSLibraryBase;
|
|||||||
use SPC\builder\unix\UnixBuilderBase;
|
use SPC\builder\unix\UnixBuilderBase;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
|
use SPC\store\DirDiff;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
use SPC\util\GlobalEnvManager;
|
use SPC\util\GlobalEnvManager;
|
||||||
@@ -105,7 +106,7 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
|
|
||||||
// prepare build php envs
|
// prepare build php envs
|
||||||
$envs_build_php = SystemUtil::makeEnvVarString([
|
$envs_build_php = SystemUtil::makeEnvVarString([
|
||||||
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS'),
|
'CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'),
|
||||||
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
|
'CPPFLAGS' => '-I' . BUILD_INCLUDE_PATH,
|
||||||
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
'LDFLAGS' => '-L' . BUILD_LIB_PATH,
|
||||||
]);
|
]);
|
||||||
@@ -189,10 +190,7 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||||
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
||||||
$shell->exec("make {$concurrency} {$vars} cli");
|
$shell->exec("make {$concurrency} {$vars} cli");
|
||||||
if (!$this->getOption('no-strip', false)) {
|
$this->deploySAPIBinary(BUILD_TARGET_CLI);
|
||||||
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip -S sapi/cli/php');
|
|
||||||
}
|
|
||||||
$this->deployBinary(BUILD_TARGET_CLI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function buildCgi(): void
|
protected function buildCgi(): void
|
||||||
@@ -202,10 +200,7 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||||
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
||||||
$shell->exec("make {$concurrency} {$vars} cgi");
|
$shell->exec("make {$concurrency} {$vars} cgi");
|
||||||
if (!$this->getOption('no-strip', false)) {
|
$this->deploySAPIBinary(BUILD_TARGET_CGI);
|
||||||
$shell->exec('dsymutil -f sapi/cgi/php-cgi')->exec('strip -S sapi/cgi/php-cgi');
|
|
||||||
}
|
|
||||||
$this->deployBinary(BUILD_TARGET_CGI);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -216,31 +211,30 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
if ($this->getPHPVersionID() < 80000) {
|
if ($this->getPHPVersionID() < 80000) {
|
||||||
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
throw new WrongUsageException('phpmicro only support PHP >= 8.0!');
|
||||||
}
|
}
|
||||||
if ($this->getExt('phar')) {
|
|
||||||
$this->phar_patched = true;
|
|
||||||
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
|
||||||
}
|
|
||||||
|
|
||||||
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
try {
|
||||||
$vars = $this->getMakeExtraVars();
|
if ($this->getExt('phar')) {
|
||||||
|
$this->phar_patched = true;
|
||||||
|
SourcePatcher::patchMicroPhar($this->getPHPVersionID());
|
||||||
|
}
|
||||||
|
|
||||||
// patch fake cli for micro
|
$enable_fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' -DPHP_MICRO_FAKE_CLI' : '';
|
||||||
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
|
$vars = $this->getMakeExtraVars();
|
||||||
$vars = SystemUtil::makeEnvVarString($vars);
|
|
||||||
|
|
||||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
// patch fake cli for micro
|
||||||
// build
|
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
|
||||||
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
$vars = SystemUtil::makeEnvVarString($vars);
|
||||||
$shell->exec("make {$concurrency} {$vars} micro");
|
|
||||||
// strip
|
|
||||||
if (!$this->getOption('no-strip', false)) {
|
|
||||||
$shell->exec('dsymutil -f sapi/micro/micro.sfx')->exec('strip -S sapi/micro/micro.sfx');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||||
|
// build
|
||||||
|
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
||||||
|
$shell->exec("make {$concurrency} {$vars} micro");
|
||||||
|
|
||||||
if ($this->phar_patched) {
|
$this->deploySAPIBinary(BUILD_TARGET_MICRO);
|
||||||
SourcePatcher::unpatchMicroPhar();
|
} finally {
|
||||||
|
if ($this->phar_patched) {
|
||||||
|
SourcePatcher::unpatchMicroPhar();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,10 +248,7 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||||
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
||||||
$shell->exec("make {$concurrency} {$vars} fpm");
|
$shell->exec("make {$concurrency} {$vars} fpm");
|
||||||
if (!$this->getOption('no-strip', false)) {
|
$this->deploySAPIBinary(BUILD_TARGET_FPM);
|
||||||
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip -S sapi/fpm/php-fpm');
|
|
||||||
}
|
|
||||||
$this->deployBinary(BUILD_TARGET_FPM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,9 +263,25 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
$install_modules = $sharedExts ? 'install-modules' : '';
|
$install_modules = $sharedExts ? 'install-modules' : '';
|
||||||
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars());
|
$vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars());
|
||||||
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
$concurrency = getenv('SPC_CONCURRENCY') ? '-j' . getenv('SPC_CONCURRENCY') : '';
|
||||||
|
|
||||||
|
$diff = new DirDiff(BUILD_MODULES_PATH, true);
|
||||||
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
|
->exec('sed -i "" "s|^EXTENSION_DIR = .*|EXTENSION_DIR = /' . basename(BUILD_MODULES_PATH) . '|" Makefile')
|
||||||
->exec("make {$concurrency} INSTALL_ROOT=" . BUILD_ROOT_PATH . " {$vars} install-sapi {$install_modules} install-build install-headers install-programs");
|
->exec("make {$concurrency} INSTALL_ROOT=" . BUILD_ROOT_PATH . " {$vars} install-sapi {$install_modules} install-build install-headers install-programs");
|
||||||
|
|
||||||
|
$libphp = BUILD_LIB_PATH . '/libphp.dylib';
|
||||||
|
if (file_exists($libphp)) {
|
||||||
|
$this->deployBinary($libphp, $libphp, false);
|
||||||
|
// macOS currently have no -release option for dylib, so we just rename it here
|
||||||
|
}
|
||||||
|
|
||||||
|
// process shared extensions build-with-php
|
||||||
|
$increment_files = $diff->getChangedFiles();
|
||||||
|
foreach ($increment_files as $increment_file) {
|
||||||
|
$this->deployBinary($increment_file, $increment_file, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'static') {
|
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'static') {
|
||||||
$AR = getenv('AR') ?: 'ar';
|
$AR = getenv('AR') ?: 'ar';
|
||||||
f_passthru("{$AR} -t " . BUILD_LIB_PATH . "/libphp.a | grep '\\.a$' | xargs -n1 {$AR} d " . BUILD_LIB_PATH . '/libphp.a');
|
f_passthru("{$AR} -t " . BUILD_LIB_PATH . "/libphp.a | grep '\\.a$' | xargs -n1 {$AR} d " . BUILD_LIB_PATH . '/libphp.a');
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace SPC\builder\unix;
|
namespace SPC\builder\unix;
|
||||||
|
|
||||||
use SPC\builder\BuilderBase;
|
use SPC\builder\BuilderBase;
|
||||||
|
use SPC\builder\linux\SystemUtil;
|
||||||
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||||
use SPC\exception\SPCException;
|
use SPC\exception\SPCException;
|
||||||
use SPC\exception\SPCInternalException;
|
use SPC\exception\SPCInternalException;
|
||||||
@@ -13,6 +14,7 @@ use SPC\exception\WrongUsageException;
|
|||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\pkg\GoXcaddy;
|
use SPC\store\pkg\GoXcaddy;
|
||||||
|
use SPC\store\SourceManager;
|
||||||
use SPC\toolchain\GccNativeToolchain;
|
use SPC\toolchain\GccNativeToolchain;
|
||||||
use SPC\toolchain\ToolchainManager;
|
use SPC\toolchain\ToolchainManager;
|
||||||
use SPC\util\DependencyUtil;
|
use SPC\util\DependencyUtil;
|
||||||
@@ -78,6 +80,92 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
$this->lib_list = $sorted_libraries;
|
$this->lib_list = $sorted_libraries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip unneeded symbols from binary file.
|
||||||
|
*/
|
||||||
|
public function stripBinary(string $binary_path): void
|
||||||
|
{
|
||||||
|
shell()->exec(match (PHP_OS_FAMILY) {
|
||||||
|
'Darwin' => "strip -S {$binary_path}",
|
||||||
|
'Linux' => "strip --strip-unneeded {$binary_path}",
|
||||||
|
default => throw new SPCInternalException('stripBinary is only supported on Linux and macOS'),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract debug information from binary file.
|
||||||
|
*
|
||||||
|
* @param string $binary_path the path to the binary file, including executables, shared libraries, etc
|
||||||
|
*/
|
||||||
|
public function extractDebugInfo(string $binary_path): string
|
||||||
|
{
|
||||||
|
$target_dir = BUILD_ROOT_PATH . '/debug';
|
||||||
|
FileSystem::createDir($target_dir);
|
||||||
|
$basename = basename($binary_path);
|
||||||
|
$debug_file = "{$target_dir}/{$basename}" . (PHP_OS_FAMILY === 'Darwin' ? '.dwarf' : '.debug');
|
||||||
|
if (PHP_OS_FAMILY === 'Darwin') {
|
||||||
|
shell()->exec("dsymutil -f {$binary_path} -o {$debug_file}");
|
||||||
|
} elseif (PHP_OS_FAMILY === 'Linux') {
|
||||||
|
if ($eu_strip = SystemUtil::findCommand('eu-strip')) {
|
||||||
|
shell()
|
||||||
|
->exec("{$eu_strip} -f {$debug_file} {$binary_path}")
|
||||||
|
->exec("objcopy --add-gnu-debuglink={$debug_file} {$binary_path}");
|
||||||
|
} else {
|
||||||
|
shell()
|
||||||
|
->exec("objcopy --only-keep-debug {$binary_path} {$debug_file}")
|
||||||
|
->exec("objcopy --add-gnu-debuglink={$debug_file} {$binary_path}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new SPCInternalException('extractDebugInfo is only supported on Linux and macOS');
|
||||||
|
}
|
||||||
|
return $debug_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deploy the binary file from src to dst.
|
||||||
|
*/
|
||||||
|
public function deployBinary(string $src, string $dst, bool $executable = true): string
|
||||||
|
{
|
||||||
|
logger()->debug('Deploying binary from ' . $src . ' to ' . $dst);
|
||||||
|
|
||||||
|
// file must exists
|
||||||
|
if (!file_exists($src)) {
|
||||||
|
throw new SPCInternalException("Deploy failed. Cannot find file: {$src}");
|
||||||
|
}
|
||||||
|
// dst dir must exists
|
||||||
|
FileSystem::createDir(dirname($dst));
|
||||||
|
|
||||||
|
// ignore copy to self
|
||||||
|
if (realpath($src) !== realpath($dst)) {
|
||||||
|
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg($dst));
|
||||||
|
}
|
||||||
|
|
||||||
|
// file exist
|
||||||
|
if (!file_exists($dst)) {
|
||||||
|
throw new SPCInternalException("Deploy failed. Cannot find file after copy: {$dst}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract debug info
|
||||||
|
$this->extractDebugInfo($dst);
|
||||||
|
|
||||||
|
// strip
|
||||||
|
if (!$this->getOption('no-strip')) {
|
||||||
|
$this->stripBinary($dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPX for linux
|
||||||
|
$upx_option = $this->getOption('with-upx-pack');
|
||||||
|
if ($upx_option && PHP_OS_FAMILY === 'Linux' && $executable) {
|
||||||
|
if ($this->getOption('no-strip')) {
|
||||||
|
logger()->warning('UPX compression is not recommended when --no-strip is enabled.');
|
||||||
|
}
|
||||||
|
logger()->info("Compressing {$dst} with UPX");
|
||||||
|
shell()->exec(getenv('UPX_EXEC') . " --best {$dst}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dst;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanity check after build complete.
|
* Sanity check after build complete.
|
||||||
*/
|
*/
|
||||||
@@ -208,23 +296,20 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deploy the binary file to the build bin path.
|
* Deploy binaries that produces executable SAPI
|
||||||
*
|
|
||||||
* @param int $type Type integer, one of BUILD_TARGET_CLI, BUILD_TARGET_MICRO, BUILD_TARGET_FPM
|
|
||||||
*/
|
*/
|
||||||
protected function deployBinary(int $type): bool
|
protected function deploySAPIBinary(int $type): string
|
||||||
{
|
{
|
||||||
$src = match ($type) {
|
$src = match ($type) {
|
||||||
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
|
BUILD_TARGET_CLI => SOURCE_PATH . '/php-src/sapi/cli/php',
|
||||||
BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
|
BUILD_TARGET_MICRO => SOURCE_PATH . '/php-src/sapi/micro/micro.sfx',
|
||||||
BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm',
|
BUILD_TARGET_FPM => SOURCE_PATH . '/php-src/sapi/fpm/php-fpm',
|
||||||
BUILD_TARGET_CGI => SOURCE_PATH . '/php-src/sapi/cgi/php-cgi',
|
BUILD_TARGET_CGI => SOURCE_PATH . '/php-src/sapi/cgi/php-cgi',
|
||||||
|
BUILD_TARGET_FRANKENPHP => BUILD_BIN_PATH . '/frankenphp',
|
||||||
default => throw new SPCInternalException("Deployment does not accept type {$type}"),
|
default => throw new SPCInternalException("Deployment does not accept type {$type}"),
|
||||||
};
|
};
|
||||||
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
$dst = BUILD_BIN_PATH . '/' . basename($src);
|
||||||
FileSystem::createDir(BUILD_BIN_PATH);
|
return $this->deployBinary($src, $dst);
|
||||||
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_BIN_PATH));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -265,22 +350,75 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the --with-frankenphp-app option
|
||||||
|
* Creates app.tar and app.checksum in source/frankenphp directory
|
||||||
|
*/
|
||||||
|
protected function processFrankenphpApp(): void
|
||||||
|
{
|
||||||
|
$frankenphpSourceDir = getenv('FRANKENPHP_SOURCE_PATH') ?: SOURCE_PATH . '/frankenphp';
|
||||||
|
if (!is_dir($frankenphpSourceDir)) {
|
||||||
|
SourceManager::initSource(['frankenphp'], ['frankenphp']);
|
||||||
|
}
|
||||||
|
$frankenphpAppPath = $this->getOption('with-frankenphp-app');
|
||||||
|
|
||||||
|
if ($frankenphpAppPath) {
|
||||||
|
if (!is_dir($frankenphpAppPath)) {
|
||||||
|
throw new WrongUsageException("The path provided to --with-frankenphp-app is not a valid directory: {$frankenphpAppPath}");
|
||||||
|
}
|
||||||
|
$appTarPath = $frankenphpSourceDir . '/app.tar';
|
||||||
|
logger()->info("Creating app.tar from {$frankenphpAppPath}");
|
||||||
|
|
||||||
|
shell()->exec('tar -cf ' . escapeshellarg($appTarPath) . ' -C ' . escapeshellarg($frankenphpAppPath) . ' .');
|
||||||
|
|
||||||
|
$checksum = hash_file('md5', $appTarPath);
|
||||||
|
file_put_contents($frankenphpSourceDir . '/app_checksum.txt', $checksum);
|
||||||
|
} else {
|
||||||
|
FileSystem::removeFileIfExists($frankenphpSourceDir . '/app.tar');
|
||||||
|
FileSystem::removeFileIfExists($frankenphpSourceDir . '/app_checksum.txt');
|
||||||
|
file_put_contents($frankenphpSourceDir . '/app.tar', '');
|
||||||
|
file_put_contents($frankenphpSourceDir . '/app_checksum.txt', '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getFrankenPHPVersion(): string
|
||||||
|
{
|
||||||
|
if ($version = getenv('FRANKENPHP_VERSION')) {
|
||||||
|
return $version;
|
||||||
|
}
|
||||||
|
$frankenphpSourceDir = getenv('FRANKENPHP_SOURCE_PATH') ?: SOURCE_PATH . '/frankenphp';
|
||||||
|
$goModPath = $frankenphpSourceDir . '/caddy/go.mod';
|
||||||
|
|
||||||
|
if (!file_exists($goModPath)) {
|
||||||
|
throw new SPCInternalException("FrankenPHP caddy/go.mod file not found at {$goModPath}, why did we not download FrankenPHP?");
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = file_get_contents($goModPath);
|
||||||
|
if (preg_match('/github\.com\/dunglas\/frankenphp\s+v?(\d+\.\d+\.\d+)/', $content, $matches)) {
|
||||||
|
return $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SPCInternalException('Could not find FrankenPHP version in caddy/go.mod');
|
||||||
|
}
|
||||||
|
|
||||||
protected function buildFrankenphp(): void
|
protected function buildFrankenphp(): void
|
||||||
{
|
{
|
||||||
GlobalEnvManager::addPathIfNotExists(GoXcaddy::getPath());
|
GlobalEnvManager::addPathIfNotExists(GoXcaddy::getPath());
|
||||||
|
$this->processFrankenphpApp();
|
||||||
$nobrotli = $this->getLib('brotli') === null ? ',nobrotli' : '';
|
$nobrotli = $this->getLib('brotli') === null ? ',nobrotli' : '';
|
||||||
$nowatcher = $this->getLib('watcher') === null ? ',nowatcher' : '';
|
$nowatcher = $this->getLib('watcher') === null ? ',nowatcher' : '';
|
||||||
$xcaddyModules = getenv('SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES');
|
$xcaddyModules = getenv('SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES');
|
||||||
// make it possible to build from a different frankenphp directory!
|
$frankenphpSourceDir = getenv('FRANKENPHP_SOURCE_PATH') ?: SOURCE_PATH . '/frankenphp';
|
||||||
if (!str_contains($xcaddyModules, '--with github.com/dunglas/frankenphp')) {
|
|
||||||
$xcaddyModules = '--with github.com/dunglas/frankenphp ' . $xcaddyModules;
|
$xcaddyModules = preg_replace('#--with github.com/dunglas/frankenphp\S*#', '', $xcaddyModules);
|
||||||
}
|
$xcaddyModules = "--with github.com/dunglas/frankenphp={$frankenphpSourceDir} " .
|
||||||
|
"--with github.com/dunglas/frankenphp/caddy={$frankenphpSourceDir}/caddy {$xcaddyModules}";
|
||||||
if ($this->getLib('brotli') === null && str_contains($xcaddyModules, '--with github.com/dunglas/caddy-cbrotli')) {
|
if ($this->getLib('brotli') === null && str_contains($xcaddyModules, '--with github.com/dunglas/caddy-cbrotli')) {
|
||||||
logger()->warning('caddy-cbrotli module is enabled, but brotli library is not built. Disabling caddy-cbrotli.');
|
logger()->warning('caddy-cbrotli module is enabled, but brotli library is not built. Disabling caddy-cbrotli.');
|
||||||
$xcaddyModules = str_replace('--with github.com/dunglas/caddy-cbrotli', '', $xcaddyModules);
|
$xcaddyModules = str_replace('--with github.com/dunglas/caddy-cbrotli', '', $xcaddyModules);
|
||||||
}
|
}
|
||||||
[, $out] = shell()->execWithResult('go list -m github.com/dunglas/frankenphp@latest');
|
|
||||||
$frankenPhpVersion = str_replace('github.com/dunglas/frankenphp v', '', $out[0]);
|
$frankenPhpVersion = $this->getFrankenPHPVersion();
|
||||||
$libphpVersion = $this->getPHPVersion();
|
$libphpVersion = $this->getPHPVersion();
|
||||||
$dynamic_exports = '';
|
$dynamic_exports = '';
|
||||||
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
|
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
|
||||||
@@ -290,7 +428,6 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
$dynamic_exports = ' ' . $dynamicSymbolsArgument;
|
$dynamic_exports = ' ' . $dynamicSymbolsArgument;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$debugFlags = $this->getOption('no-strip') ? '-w -s ' : '';
|
|
||||||
$extLdFlags = "-extldflags '-pie{$dynamic_exports} {$this->arch_ld_flags}'";
|
$extLdFlags = "-extldflags '-pie{$dynamic_exports} {$this->arch_ld_flags}'";
|
||||||
$muslTags = '';
|
$muslTags = '';
|
||||||
$staticFlags = '';
|
$staticFlags = '';
|
||||||
@@ -301,7 +438,7 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
$config = (new SPCConfigUtil($this))->config($this->ext_list, $this->lib_list);
|
$config = (new SPCConfigUtil($this))->config($this->ext_list, $this->lib_list);
|
||||||
$cflags = "{$this->arch_c_flags} {$config['cflags']} " . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS');
|
$cflags = "{$this->arch_c_flags} {$config['cflags']} " . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') . ' -DFRANKENPHP_VERSION=' . $frankenPhpVersion;
|
||||||
$libs = $config['libs'];
|
$libs = $config['libs'];
|
||||||
// Go's gcc driver doesn't automatically link against -lgcov or -lrt. Ugly, but necessary fix.
|
// Go's gcc driver doesn't automatically link against -lgcov or -lrt. Ugly, but necessary fix.
|
||||||
if ((str_contains((string) getenv('SPC_DEFAULT_C_FLAGS'), '-fprofile') ||
|
if ((str_contains((string) getenv('SPC_DEFAULT_C_FLAGS'), '-fprofile') ||
|
||||||
@@ -315,7 +452,7 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
'CGO_CFLAGS' => clean_spaces($cflags),
|
'CGO_CFLAGS' => clean_spaces($cflags),
|
||||||
'CGO_LDFLAGS' => "{$this->arch_ld_flags} {$staticFlags} {$config['ldflags']} {$libs}",
|
'CGO_LDFLAGS' => "{$this->arch_ld_flags} {$staticFlags} {$config['ldflags']} {$libs}",
|
||||||
'XCADDY_GO_BUILD_FLAGS' => '-buildmode=pie ' .
|
'XCADDY_GO_BUILD_FLAGS' => '-buildmode=pie ' .
|
||||||
'-ldflags \"-linkmode=external ' . $extLdFlags . ' ' . $debugFlags .
|
'-ldflags \"-linkmode=external ' . $extLdFlags . ' ' .
|
||||||
'-X \'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ' .
|
'-X \'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ' .
|
||||||
"v{$frankenPhpVersion} PHP {$libphpVersion} Caddy'\\\" " .
|
"v{$frankenPhpVersion} PHP {$libphpVersion} Caddy'\\\" " .
|
||||||
"-tags={$muslTags}nobadger,nomysql,nopgx{$nobrotli}{$nowatcher}",
|
"-tags={$muslTags}nobadger,nomysql,nopgx{$nobrotli}{$nowatcher}",
|
||||||
@@ -325,13 +462,7 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
->setEnv($env)
|
->setEnv($env)
|
||||||
->exec("xcaddy build --output frankenphp {$xcaddyModules}");
|
->exec("xcaddy build --output frankenphp {$xcaddyModules}");
|
||||||
|
|
||||||
if (!$this->getOption('no-strip', false) && file_exists(BUILD_BIN_PATH . '/frankenphp')) {
|
$this->deploySAPIBinary(BUILD_TARGET_FRANKENPHP);
|
||||||
if (PHP_OS_FAMILY === 'Linux') {
|
|
||||||
shell()->cd(BUILD_BIN_PATH)->exec('strip --strip-unneeded frankenphp');
|
|
||||||
} else { // macOS doesn't understand strip-unneeded
|
|
||||||
shell()->cd(BUILD_BIN_PATH)->exec('strip -S frankenphp');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\executor\UnixAutoconfExecutor;
|
use SPC\util\executor\UnixCMakeExecutor;
|
||||||
|
|
||||||
trait librdkafka
|
trait librdkafka
|
||||||
{
|
{
|
||||||
@@ -26,34 +26,18 @@ trait librdkafka
|
|||||||
|
|
||||||
protected function build(): void
|
protected function build(): void
|
||||||
{
|
{
|
||||||
UnixAutoconfExecutor::create($this)
|
UnixCMakeExecutor::create($this)
|
||||||
->appendEnv(['CFLAGS' => '-Wno-int-conversion -Wno-unused-but-set-variable -Wno-unused-variable'])
|
->optionalLib('zstd', ...cmake_boolean_args('WITH_ZSTD'))
|
||||||
->optionalLib(
|
->optionalLib('curl', ...cmake_boolean_args('WITH_CURL'))
|
||||||
'zstd',
|
->optionalLib('openssl', ...cmake_boolean_args('WITH_SSL'))
|
||||||
function ($lib) {
|
->optionalLib('zlib', ...cmake_boolean_args('WITH_ZLIB'))
|
||||||
putenv("STATIC_LIB_libzstd={$lib->getLibDir()}/libzstd.a");
|
->optionalLib('liblz4', ...cmake_boolean_args('ENABLE_LZ4_EXT'))
|
||||||
return '';
|
->addConfigureArgs(
|
||||||
},
|
'-DWITH_SASL=OFF',
|
||||||
'--disable-zstd'
|
'-DRDKAFKA_BUILD_STATIC=ON',
|
||||||
|
'-DRDKAFKA_BUILD_EXAMPLES=OFF',
|
||||||
|
'-DRDKAFKA_BUILD_TESTS=OFF',
|
||||||
)
|
)
|
||||||
->removeConfigureArgs(
|
->build();
|
||||||
'--with-pic',
|
|
||||||
'--enable-pic',
|
|
||||||
)
|
|
||||||
->configure(
|
|
||||||
'--disable-curl',
|
|
||||||
'--disable-sasl',
|
|
||||||
'--disable-valgrind',
|
|
||||||
'--disable-zlib',
|
|
||||||
'--disable-ssl',
|
|
||||||
)
|
|
||||||
->make();
|
|
||||||
|
|
||||||
$this->patchPkgconfPrefix(['rdkafka.pc', 'rdkafka-static.pc', 'rdkafka++.pc', 'rdkafka++-static.pc']);
|
|
||||||
// remove dynamic libs
|
|
||||||
shell()
|
|
||||||
->exec("rm -rf {$this->getLibDir()}/*.so.*")
|
|
||||||
->exec("rm -rf {$this->getLibDir()}/*.so")
|
|
||||||
->exec("rm -rf {$this->getLibDir()}/*.dylib");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ trait postgresql
|
|||||||
{
|
{
|
||||||
$libs = array_map(fn ($x) => $x->getName(), $this->getDependencies(true));
|
$libs = array_map(fn ($x) => $x->getName(), $this->getDependencies(true));
|
||||||
$spc = new SPCConfigUtil($this->builder, ['no_php' => true, 'libs_only_deps' => true]);
|
$spc = new SPCConfigUtil($this->builder, ['no_php' => true, 'libs_only_deps' => true]);
|
||||||
$config = $spc->config(libraries: $libs, include_suggest_lib: $this->builder->getOption('with-suggested-libs'));
|
$config = $spc->config(libraries: $libs, include_suggest_lib: $this->builder->getOption('with-suggested-libs', false));
|
||||||
|
|
||||||
$env_vars = [
|
$env_vars = [
|
||||||
'CFLAGS' => $config['cflags'],
|
'CFLAGS' => $config['cflags'],
|
||||||
|
|||||||
@@ -67,21 +67,6 @@ class WindowsBuilder extends BuilderBase
|
|||||||
|
|
||||||
$zts = $this->zts ? '--enable-zts=yes ' : '--enable-zts=no ';
|
$zts = $this->zts ? '--enable-zts=yes ' : '--enable-zts=no ';
|
||||||
|
|
||||||
// with-upx-pack for phpmicro
|
|
||||||
if ($enableMicro && version_compare($this->getMicroVersion(), '0.2.0') < 0) {
|
|
||||||
$makefile = FileSystem::convertPath(SOURCE_PATH . '/php-src/sapi/micro/Makefile.frag.w32');
|
|
||||||
if ($this->getOption('with-upx-pack', false)) {
|
|
||||||
if (!file_exists($makefile . '.originfile')) {
|
|
||||||
copy($makefile, $makefile . '.originfile');
|
|
||||||
FileSystem::replaceFileStr($makefile, '$(MICRO_SFX):', '_MICRO_UPX = ' . getenv('UPX_EXEC') . " --best $(MICRO_SFX)\n$(MICRO_SFX):");
|
|
||||||
FileSystem::replaceFileStr($makefile, '@$(_MICRO_MT)', "@$(_MICRO_MT)\n\t@$(_MICRO_UPX)");
|
|
||||||
}
|
|
||||||
} elseif (file_exists($makefile . '.originfile')) {
|
|
||||||
copy($makefile . '.originfile', $makefile);
|
|
||||||
unlink($makefile . '.originfile');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$opcache_jit = !$this->getOption('disable-opcache-jit', false);
|
$opcache_jit = !$this->getOption('disable-opcache-jit', false);
|
||||||
$opcache_jit_arg = $opcache_jit ? '--enable-opcache-jit=yes ' : '--enable-opcache-jit=no ';
|
$opcache_jit_arg = $opcache_jit ? '--enable-opcache-jit=yes ' : '--enable-opcache-jit=no ';
|
||||||
|
|
||||||
@@ -145,7 +130,7 @@ class WindowsBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPHP(int $build_target = BUILD_TARGET_NONE)
|
public function testPHP(int $build_target = BUILD_TARGET_NONE): void
|
||||||
{
|
{
|
||||||
$this->sanityCheck($build_target);
|
$this->sanityCheck($build_target);
|
||||||
}
|
}
|
||||||
@@ -156,12 +141,27 @@ class WindowsBuilder extends BuilderBase
|
|||||||
|
|
||||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||||
|
|
||||||
|
// Add debug symbols for release build if --no-strip is specified
|
||||||
|
// We need to modify CFLAGS to replace /Ox with /Zi and add /DEBUG to LDFLAGS
|
||||||
|
$debug_overrides = '';
|
||||||
|
if ($this->getOption('no-strip', false)) {
|
||||||
|
// Read current CFLAGS from Makefile and replace optimization flags
|
||||||
|
$makefile_content = file_get_contents(SOURCE_PATH . '\php-src\Makefile');
|
||||||
|
if (preg_match('/^CFLAGS=(.+?)$/m', $makefile_content, $matches)) {
|
||||||
|
$cflags = $matches[1];
|
||||||
|
// Replace /Ox (full optimization) with /Zi (debug info) and /Od (disable optimization)
|
||||||
|
// Keep optimization for speed: /O2 /Zi instead of /Od /Zi
|
||||||
|
$cflags = str_replace('/Ox ', '/O2 /Zi ', $cflags);
|
||||||
|
$debug_overrides = '"CFLAGS=' . $cflags . '" "LDFLAGS=/DEBUG /LTCG /INCREMENTAL:NO" "LDFLAGS_CLI=/DEBUG" ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add nmake wrapper
|
// add nmake wrapper
|
||||||
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= %*");
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cli_wrapper.bat', "nmake /nologo {$debug_overrides}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");
|
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cli_wrapper.bat --task-args php.exe");
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_CLI);
|
$this->deploySAPIBinary(BUILD_TARGET_CLI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildCgi(): void
|
public function buildCgi(): void
|
||||||
@@ -170,12 +170,23 @@ class WindowsBuilder extends BuilderBase
|
|||||||
|
|
||||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||||
|
|
||||||
|
// Add debug symbols for release build if --no-strip is specified
|
||||||
|
$debug_overrides = '';
|
||||||
|
if ($this->getOption('no-strip', false)) {
|
||||||
|
$makefile_content = file_get_contents(SOURCE_PATH . '\php-src\Makefile');
|
||||||
|
if (preg_match('/^CFLAGS=(.+?)$/m', $makefile_content, $matches)) {
|
||||||
|
$cflags = $matches[1];
|
||||||
|
$cflags = str_replace('/Ox ', '/O2 /Zi ', $cflags);
|
||||||
|
$debug_overrides = '"CFLAGS=' . $cflags . '" "LDFLAGS=/DEBUG /LTCG /INCREMENTAL:NO" "LDFLAGS_CGI=/DEBUG" ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add nmake wrapper
|
// add nmake wrapper
|
||||||
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo LIBS_CGI=\"ws2_32.lib kernel32.lib advapi32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*");
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_cgi_wrapper.bat', "nmake /nologo {$debug_overrides}LIBS_CGI=\"ws2_32.lib kernel32.lib advapi32.lib {$extra_libs}\" EXTRA_LD_FLAGS_PROGRAM= %*");
|
||||||
|
|
||||||
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe");
|
cmd()->cd(SOURCE_PATH . '\php-src')->exec("{$this->sdk_prefix} nmake_cgi_wrapper.bat --task-args php-cgi.exe");
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_CGI);
|
$this->deploySAPIBinary(BUILD_TARGET_CGI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildEmbed(): void
|
public function buildEmbed(): void
|
||||||
@@ -202,9 +213,20 @@ class WindowsBuilder extends BuilderBase
|
|||||||
|
|
||||||
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
$extra_libs = getenv('SPC_EXTRA_LIBS') ?: '';
|
||||||
|
|
||||||
|
// Add debug symbols for release build if --no-strip is specified
|
||||||
|
$debug_overrides = '';
|
||||||
|
if ($this->getOption('no-strip', false) && !$this->getOption('debug', false)) {
|
||||||
|
$makefile_content = file_get_contents(SOURCE_PATH . '\php-src\Makefile');
|
||||||
|
if (preg_match('/^CFLAGS=(.+?)$/m', $makefile_content, $matches)) {
|
||||||
|
$cflags = $matches[1];
|
||||||
|
$cflags = str_replace('/Ox ', '/O2 /Zi ', $cflags);
|
||||||
|
$debug_overrides = '"CFLAGS=' . $cflags . '" "LDFLAGS=/DEBUG /LTCG /INCREMENTAL:NO" "LDFLAGS_MICRO=/DEBUG" ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add nmake wrapper
|
// add nmake wrapper
|
||||||
$fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' /DPHP_MICRO_FAKE_CLI" ' : '';
|
$fake_cli = $this->getOption('with-micro-fake-cli', false) ? ' /DPHP_MICRO_FAKE_CLI" ' : '';
|
||||||
$wrapper = "nmake /nologo LIBS_MICRO=\"ws2_32.lib shell32.lib {$extra_libs}\" CFLAGS_MICRO=\"/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1{$fake_cli}\" %*";
|
$wrapper = "nmake /nologo {$debug_overrides}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);
|
FileSystem::writeFile(SOURCE_PATH . '\php-src\nmake_micro_wrapper.bat', $wrapper);
|
||||||
|
|
||||||
// phar patch for micro
|
// phar patch for micro
|
||||||
@@ -221,7 +243,7 @@ class WindowsBuilder extends BuilderBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->deployBinary(BUILD_TARGET_MICRO);
|
$this->deploySAPIBinary(BUILD_TARGET_MICRO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function proveLibs(array $sorted_libraries): void
|
public function proveLibs(array $sorted_libraries): void
|
||||||
@@ -335,28 +357,53 @@ class WindowsBuilder extends BuilderBase
|
|||||||
*
|
*
|
||||||
* @param int $type Deploy type
|
* @param int $type Deploy type
|
||||||
*/
|
*/
|
||||||
public function deployBinary(int $type): bool
|
public function deploySAPIBinary(int $type): void
|
||||||
{
|
{
|
||||||
|
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
||||||
|
|
||||||
|
$debug_dir = BUILD_ROOT_PATH . '\debug';
|
||||||
|
$bin_path = BUILD_BIN_PATH;
|
||||||
|
|
||||||
|
// create dirs
|
||||||
|
FileSystem::createDir($debug_dir);
|
||||||
|
FileSystem::createDir($bin_path);
|
||||||
|
|
||||||
|
// determine source path for different SAPI
|
||||||
|
$rel_type = 'Release'; // TODO: Debug build support
|
||||||
$ts = $this->zts ? '_TS' : '';
|
$ts = $this->zts ? '_TS' : '';
|
||||||
$src = match ($type) {
|
$src = match ($type) {
|
||||||
BUILD_TARGET_CLI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php.exe",
|
BUILD_TARGET_CLI => [SOURCE_PATH . "\\php-src\\x64\\{$rel_type}{$ts}", 'php.exe', 'php.pdb'],
|
||||||
BUILD_TARGET_MICRO => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\micro.sfx",
|
BUILD_TARGET_MICRO => [SOURCE_PATH . "\\php-src\\x64\\{$rel_type}{$ts}", 'micro.sfx', 'micro.pdb'],
|
||||||
BUILD_TARGET_CGI => SOURCE_PATH . "\\php-src\\x64\\Release{$ts}\\php-cgi.exe",
|
BUILD_TARGET_CGI => [SOURCE_PATH . "\\php-src\\x64\\{$rel_type}{$ts}", 'php-cgi.exe', 'php-cgi.pdb'],
|
||||||
default => throw new SPCInternalException("Deployment does not accept type {$type}"),
|
default => throw new SPCInternalException("Deployment does not accept type {$type}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$src = "{$src[0]}\\{$src[1]}";
|
||||||
|
$dst = BUILD_BIN_PATH . '\\' . basename($src);
|
||||||
|
|
||||||
|
// file must exists
|
||||||
|
if (!file_exists($src)) {
|
||||||
|
throw new SPCInternalException("Deploy failed. Cannot find file: {$src}");
|
||||||
|
}
|
||||||
|
// dst dir must exists
|
||||||
|
FileSystem::createDir(dirname($dst));
|
||||||
|
|
||||||
|
// copy file
|
||||||
|
if (realpath($src) !== realpath($dst)) {
|
||||||
|
cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg($dst));
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract debug info in buildroot/debug
|
||||||
|
if ($this->getOption('no-strip', false) && file_exists("{$src[0]}\\{$src[2]}")) {
|
||||||
|
cmd()->exec('copy ' . escapeshellarg("{$src[0]}\\{$src[2]}") . ' ' . escapeshellarg($debug_dir));
|
||||||
|
}
|
||||||
|
|
||||||
// with-upx-pack for cli and micro
|
// with-upx-pack for cli and micro
|
||||||
if ($this->getOption('with-upx-pack', false)) {
|
if ($this->getOption('with-upx-pack', false)) {
|
||||||
if ($type === BUILD_TARGET_CLI || $type === BUILD_TARGET_CGI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) {
|
if ($type === BUILD_TARGET_CLI || $type === BUILD_TARGET_CGI || ($type === BUILD_TARGET_MICRO && version_compare($this->getMicroVersion(), '0.2.0') >= 0)) {
|
||||||
cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($src));
|
cmd()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($dst));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file');
|
|
||||||
FileSystem::createDir(BUILD_BIN_PATH);
|
|
||||||
|
|
||||||
cmd()->exec('copy ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_BIN_PATH . '\\'));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class BuildPHPCommand extends BuildCommand
|
|||||||
$this->addOption('with-upx-pack', null, null, 'Compress / pack binary using UPX tool (linux/windows only)');
|
$this->addOption('with-upx-pack', null, null, 'Compress / pack binary using UPX tool (linux/windows only)');
|
||||||
$this->addOption('with-micro-logo', null, InputOption::VALUE_REQUIRED, 'Use custom .ico for micro.sfx (windows only)');
|
$this->addOption('with-micro-logo', null, InputOption::VALUE_REQUIRED, 'Use custom .ico for micro.sfx (windows only)');
|
||||||
$this->addOption('enable-micro-win32', null, null, 'Enable win32 mode for phpmicro (Windows only)');
|
$this->addOption('enable-micro-win32', null, null, 'Enable win32 mode for phpmicro (Windows only)');
|
||||||
|
$this->addOption('with-frankenphp-app', null, InputOption::VALUE_REQUIRED, 'Path to a folder to be embedded in FrankenPHP');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
|
|||||||
@@ -159,7 +159,9 @@ class ExceptionHandler
|
|||||||
public static function handleDefaultException(\Throwable $e): void
|
public static function handleDefaultException(\Throwable $e): void
|
||||||
{
|
{
|
||||||
$class = get_class($e);
|
$class = get_class($e);
|
||||||
self::logError("✗ Unhandled exception {$class}:\n\t{$e->getMessage()}\n");
|
$file = $e->getFile();
|
||||||
|
$line = $e->getLine();
|
||||||
|
self::logError("✗ Unhandled exception {$class} on {$file} line {$line}:\n\t{$e->getMessage()}\n");
|
||||||
self::logError('Stack trace:');
|
self::logError('Stack trace:');
|
||||||
self::logError(ConsoleColor::gray($e->getTraceAsString()) . PHP_EOL, 4);
|
self::logError(ConsoleColor::gray($e->getTraceAsString()) . PHP_EOL, 4);
|
||||||
self::logError('⚠ Please report this exception to: https://github.com/crazywhalecc/static-php-cli/issues');
|
self::logError('⚠ Please report this exception to: https://github.com/crazywhalecc/static-php-cli/issues');
|
||||||
|
|||||||
95
src/SPC/store/DirDiff.php
Normal file
95
src/SPC/store/DirDiff.php
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\store;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A util class to diff directory file increments.
|
||||||
|
*/
|
||||||
|
class DirDiff
|
||||||
|
{
|
||||||
|
protected array $before = [];
|
||||||
|
|
||||||
|
protected array $before_file_hashes = [];
|
||||||
|
|
||||||
|
public function __construct(protected string $dir, protected bool $track_content_changes = false)
|
||||||
|
{
|
||||||
|
$this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the baseline to current state.
|
||||||
|
*/
|
||||||
|
public function reset(): void
|
||||||
|
{
|
||||||
|
$this->before = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
|
||||||
|
|
||||||
|
if ($this->track_content_changes) {
|
||||||
|
$this->before_file_hashes = [];
|
||||||
|
foreach ($this->before as $file) {
|
||||||
|
$this->before_file_hashes[$file] = md5_file($this->dir . DIRECTORY_SEPARATOR . $file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of incremented files.
|
||||||
|
*
|
||||||
|
* @param bool $relative Return relative paths or absolute paths
|
||||||
|
* @return array<string> List of incremented files
|
||||||
|
*/
|
||||||
|
public function getIncrementFiles(bool $relative = false): array
|
||||||
|
{
|
||||||
|
$after = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
|
||||||
|
$diff = array_diff($after, $this->before);
|
||||||
|
if ($relative) {
|
||||||
|
return $diff;
|
||||||
|
}
|
||||||
|
return array_map(fn ($f) => $this->dir . DIRECTORY_SEPARATOR . $f, $diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of changed files (including new files).
|
||||||
|
*
|
||||||
|
* @param bool $relative Return relative paths or absolute paths
|
||||||
|
* @param bool $include_new_files Include new files as changed files
|
||||||
|
* @return array<string> List of changed files
|
||||||
|
*/
|
||||||
|
public function getChangedFiles(bool $relative = false, bool $include_new_files = true): array
|
||||||
|
{
|
||||||
|
$after = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
|
||||||
|
$changed = [];
|
||||||
|
foreach ($after as $file) {
|
||||||
|
if (isset($this->before_file_hashes[$file])) {
|
||||||
|
$after_hash = md5_file($this->dir . DIRECTORY_SEPARATOR . $file);
|
||||||
|
if ($after_hash !== $this->before_file_hashes[$file]) {
|
||||||
|
$changed[] = $file;
|
||||||
|
}
|
||||||
|
} elseif ($include_new_files) {
|
||||||
|
// New file, consider as changed
|
||||||
|
$changed[] = $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($relative) {
|
||||||
|
return $changed;
|
||||||
|
}
|
||||||
|
return array_map(fn ($f) => $this->dir . DIRECTORY_SEPARATOR . $f, $changed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of removed files.
|
||||||
|
*
|
||||||
|
* @param bool $relative Return relative paths or absolute paths
|
||||||
|
* @return array<string> List of removed files
|
||||||
|
*/
|
||||||
|
public function getRemovedFiles(bool $relative = false): array
|
||||||
|
{
|
||||||
|
$after = FileSystem::scanDirFiles($this->dir, relative: true) ?: [];
|
||||||
|
$removed = array_diff($this->before, $after);
|
||||||
|
if ($relative) {
|
||||||
|
return $removed;
|
||||||
|
}
|
||||||
|
return array_map(fn ($f) => $this->dir . DIRECTORY_SEPARATOR . $f, $removed);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -174,6 +174,9 @@ class FileSystem
|
|||||||
logger()->debug("Copying file from {$from} to {$to}");
|
logger()->debug("Copying file from {$from} to {$to}");
|
||||||
$dst_path = FileSystem::convertPath($to);
|
$dst_path = FileSystem::convertPath($to);
|
||||||
$src_path = FileSystem::convertPath($from);
|
$src_path = FileSystem::convertPath($from);
|
||||||
|
if ($src_path === $dst_path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!copy($src_path, $dst_path)) {
|
if (!copy($src_path, $dst_path)) {
|
||||||
throw new FileSystemException('Cannot copy file from ' . $src_path . ' to ' . $dst_path);
|
throw new FileSystemException('Cannot copy file from ' . $src_path . ' to ' . $dst_path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class PhpSource extends CustomSourceBase
|
|||||||
{
|
{
|
||||||
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.4';
|
$major = defined('SPC_BUILD_PHP_VERSION') ? SPC_BUILD_PHP_VERSION : '8.4';
|
||||||
if ($major === '8.5') {
|
if ($major === '8.5') {
|
||||||
Downloader::downloadSource('php-src', ['type' => 'url', 'url' => 'https://downloads.php.net/~daniels/php-8.5.0RC3.tar.xz'], $force);
|
Downloader::downloadSource('php-src', ['type' => 'url', 'url' => 'https://downloads.php.net/~daniels/php-8.5.0RC5.tar.xz'], $force);
|
||||||
} elseif ($major === 'git') {
|
} elseif ($major === 'git') {
|
||||||
Downloader::downloadSource('php-src', ['type' => 'git', 'url' => 'https://github.com/php/php-src.git', 'rev' => 'master'], $force);
|
Downloader::downloadSource('php-src', ['type' => 'git', 'url' => 'https://github.com/php/php-src.git', 'rev' => 'master'], $force);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace SPC\util;
|
|||||||
use SPC\builder\BuilderBase;
|
use SPC\builder\BuilderBase;
|
||||||
use SPC\builder\BuilderProvider;
|
use SPC\builder\BuilderProvider;
|
||||||
use SPC\builder\Extension;
|
use SPC\builder\Extension;
|
||||||
|
use SPC\builder\LibraryBase;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
use Symfony\Component\Console\Input\ArgvInput;
|
use Symfony\Component\Console\Input\ArgvInput;
|
||||||
@@ -53,6 +54,9 @@ class SPCConfigUtil
|
|||||||
*/
|
*/
|
||||||
public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false): array
|
public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false): array
|
||||||
{
|
{
|
||||||
|
logger()->debug('config extensions: ' . implode(',', $extensions));
|
||||||
|
logger()->debug('config libs: ' . implode(',', $libraries));
|
||||||
|
logger()->debug('config suggest for [ext, lib]: ' . ($include_suggest_ext ? 'true' : 'false') . ',' . ($include_suggest_lib ? 'true' : 'false'));
|
||||||
$extra_exts = [];
|
$extra_exts = [];
|
||||||
foreach ($extensions as $ext) {
|
foreach ($extensions as $ext) {
|
||||||
$extra_exts = array_merge($extra_exts, Config::getExt($ext, 'ext-suggests', []));
|
$extra_exts = array_merge($extra_exts, Config::getExt($ext, 'ext-suggests', []));
|
||||||
@@ -124,6 +128,63 @@ class SPCConfigUtil
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Helper function]
|
||||||
|
* Get configuration for a specific extension(s) dependencies.
|
||||||
|
*
|
||||||
|
* @param Extension|Extension[] $extension Extension instance or list
|
||||||
|
* @param bool $include_suggest_ext Whether to include suggested extensions
|
||||||
|
* @param bool $include_suggest_lib Whether to include suggested libraries
|
||||||
|
* @return array{
|
||||||
|
* cflags: string,
|
||||||
|
* ldflags: string,
|
||||||
|
* libs: string
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
public function getExtensionConfig(array|Extension $extension, bool $include_suggest_ext = false, bool $include_suggest_lib = false): array
|
||||||
|
{
|
||||||
|
if (!is_array($extension)) {
|
||||||
|
$extension = [$extension];
|
||||||
|
}
|
||||||
|
$libs = array_map(fn ($y) => $y->getName(), array_merge(...array_map(fn ($x) => $x->getLibraryDependencies(true), $extension)));
|
||||||
|
return $this->config(
|
||||||
|
extensions: array_map(fn ($x) => $x->getName(), $extension),
|
||||||
|
libraries: $libs,
|
||||||
|
include_suggest_ext: $include_suggest_ext ?: $this->builder?->getOption('with-suggested-exts') ?? false,
|
||||||
|
include_suggest_lib: $include_suggest_lib ?: $this->builder?->getOption('with-suggested-libs') ?? false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Helper function]
|
||||||
|
* Get configuration for a specific library(s) dependencies.
|
||||||
|
*
|
||||||
|
* @param LibraryBase|LibraryBase[] $lib Library instance or list
|
||||||
|
* @param bool $include_suggest_lib Whether to include suggested libraries
|
||||||
|
* @return array{
|
||||||
|
* cflags: string,
|
||||||
|
* ldflags: string,
|
||||||
|
* libs: string
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
public function getLibraryConfig(array|LibraryBase $lib, bool $include_suggest_lib = false): array
|
||||||
|
{
|
||||||
|
if (!is_array($lib)) {
|
||||||
|
$lib = [$lib];
|
||||||
|
}
|
||||||
|
$save_no_php = $this->no_php;
|
||||||
|
$this->no_php = true;
|
||||||
|
$save_libs_only_deps = $this->libs_only_deps;
|
||||||
|
$this->libs_only_deps = true;
|
||||||
|
$ret = $this->config(
|
||||||
|
libraries: array_map(fn ($x) => $x->getName(), $lib),
|
||||||
|
include_suggest_lib: $include_suggest_lib ?: $this->builder?->getOption('with-suggested-libs') ?? false,
|
||||||
|
);
|
||||||
|
$this->no_php = $save_no_php;
|
||||||
|
$this->libs_only_deps = $save_libs_only_deps;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
private function hasCpp(array $extensions, array $libraries): bool
|
private function hasCpp(array $extensions, array $libraries): bool
|
||||||
{
|
{
|
||||||
// judge cpp-extension
|
// judge cpp-extension
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
// test php version (8.1 ~ 8.4 available, multiple for matrix)
|
// test php version (8.1 ~ 8.4 available, multiple for matrix)
|
||||||
$test_php_version = [
|
$test_php_version = [
|
||||||
'8.1',
|
// '8.1',
|
||||||
'8.2',
|
// '8.2',
|
||||||
'8.3',
|
// '8.3',
|
||||||
'8.4',
|
'8.4',
|
||||||
'8.5',
|
// '8.5',
|
||||||
// 'git',
|
// 'git',
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ $test_os = [
|
|||||||
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
|
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
|
||||||
'ubuntu-24.04-arm', // bin/spc for arm64
|
'ubuntu-24.04-arm', // bin/spc for arm64
|
||||||
// 'windows-2022', // .\bin\spc.ps1
|
// 'windows-2022', // .\bin\spc.ps1
|
||||||
// 'windows-2025',
|
'windows-2025',
|
||||||
];
|
];
|
||||||
|
|
||||||
// whether enable thread safe
|
// whether enable thread safe
|
||||||
@@ -50,19 +50,19 @@ $prefer_pre_built = false;
|
|||||||
|
|
||||||
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
|
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
|
||||||
$extensions = match (PHP_OS_FAMILY) {
|
$extensions = match (PHP_OS_FAMILY) {
|
||||||
'Linux', 'Darwin' => 'trader',
|
'Linux', 'Darwin' => 'rdkafka',
|
||||||
'Windows' => 'bcmath,bz2,calendar,ctype,curl,dba,dom,exif,ffi,fileinfo,filter,ftp,iconv,libxml,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pdo,pdo_mysql,pdo_sqlite,pdo_sqlsrv,phar,session,shmop,simdjson,simplexml,soap,sockets,sqlite3,sqlsrv,ssh2,sysvshm,tokenizer,xml,xmlreader,xmlwriter,yaml,zip,zlib',
|
'Windows' => 'bcmath',
|
||||||
};
|
};
|
||||||
|
|
||||||
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
|
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
|
||||||
$shared_extensions = match (PHP_OS_FAMILY) {
|
$shared_extensions = match (PHP_OS_FAMILY) {
|
||||||
'Linux' => '',
|
'Linux' => 'snmp',
|
||||||
'Darwin' => '',
|
'Darwin' => 'snmp',
|
||||||
'Windows' => '',
|
'Windows' => '',
|
||||||
};
|
};
|
||||||
|
|
||||||
// If you want to test lib-suggests for all extensions and libraries, set it to true.
|
// If you want to test lib-suggests for all extensions and libraries, set it to true.
|
||||||
$with_suggested_libs = false;
|
$with_suggested_libs = true;
|
||||||
|
|
||||||
// If you want to test extra libs for extensions, add them below (comma separated, example `libwebp,libavif`). Unnecessary, when $with_suggested_libs is true.
|
// If you want to test extra libs for extensions, add them below (comma separated, example `libwebp,libavif`). Unnecessary, when $with_suggested_libs is true.
|
||||||
$with_libs = match (PHP_OS_FAMILY) {
|
$with_libs = match (PHP_OS_FAMILY) {
|
||||||
|
|||||||
Reference in New Issue
Block a user