mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-19 06:45:35 +08:00
Compare commits
38 Commits
a2f0640b1b
...
2.6.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b04ffadf13 | ||
|
|
5681722c09 | ||
|
|
3ac4a71085 | ||
|
|
2963ced1d5 | ||
|
|
175aafee50 | ||
|
|
b75a3d6e81 | ||
|
|
f6d25153c6 | ||
|
|
853294e168 | ||
|
|
1a4296386a | ||
|
|
c464f78340 | ||
|
|
8992c96014 | ||
|
|
62a13f2da6 | ||
|
|
f9005757bd | ||
|
|
cd6aca832d | ||
|
|
1b4eb039ae | ||
|
|
6c47065686 | ||
|
|
9bfcea6feb | ||
|
|
58d979712e | ||
|
|
a0f99858e3 | ||
|
|
2abbb75f98 | ||
|
|
3f92df0865 | ||
|
|
be0b98c467 | ||
|
|
7d45415990 | ||
|
|
f3f581fe2d | ||
|
|
f6837079d3 | ||
|
|
5cd987ba3a | ||
|
|
8293160a01 | ||
|
|
625ee2703d | ||
|
|
c3b520c3d4 | ||
|
|
80687dfea3 | ||
|
|
7f9da6478f | ||
|
|
056971fcbc | ||
|
|
ba26359dde | ||
|
|
6b330fa869 | ||
|
|
5cc753dec4 | ||
|
|
f7a0f50f87 | ||
|
|
8466970a1f | ||
|
|
48cb87ada2 |
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@@ -190,7 +190,7 @@ jobs:
|
||||
echo "UPX_CMD=$(php src/globals/test-extensions.php upx)" >> $GITHUB_ENV
|
||||
|
||||
- name: "Run Build Tests (download)"
|
||||
run: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} php src/globals/test-extensions.php download_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
run: php src/globals/test-extensions.php download_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
|
||||
- name: "Run Build Tests (build)"
|
||||
run: php src/globals/test-extensions.php build_cmd ${{ matrix.os }} ${{ matrix.php }}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#!/usr/bin/env sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# This file is using docker to run commands
|
||||
SPC_DOCKER_VERSION=v3
|
||||
SPC_DOCKER_VERSION=v4
|
||||
|
||||
# Detect docker can run
|
||||
if ! which docker >/dev/null; then
|
||||
echo "Docker is not installed, please install docker first !"
|
||||
exit 1
|
||||
echo "Docker is not installed, please install docker first !"
|
||||
exit 1
|
||||
fi
|
||||
DOCKER_EXECUTABLE="docker"
|
||||
# shellcheck disable=SC2046
|
||||
@@ -22,27 +24,48 @@ if [ $(id -u) -ne 0 ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# to check if qemu-docker run
|
||||
if [ "$SPC_USE_ARCH" = "" ]; then
|
||||
SPC_USE_ARCH=x86_64
|
||||
# Convert uname to gnu arch
|
||||
CURRENT_ARCH=$(uname -m)
|
||||
if [ "$CURRENT_ARCH" = "arm64" ]; then
|
||||
CURRENT_ARCH=aarch64
|
||||
fi
|
||||
if [ -z "$SPC_USE_ARCH" ]; then
|
||||
SPC_USE_ARCH=$CURRENT_ARCH
|
||||
fi
|
||||
# parse SPC_USE_ARCH
|
||||
case $SPC_USE_ARCH in
|
||||
x86_64)
|
||||
ALPINE_FROM=alpine:edge
|
||||
x86_64|amd64)
|
||||
SPC_USE_ARCH=x86_64
|
||||
if [ "$CURRENT_ARCH" != "x86_64" ]; then
|
||||
PLATFORM_ARG="--platform linux/amd64"
|
||||
ALPINE_FROM=multiarch/alpine:x86_64-edge
|
||||
fi
|
||||
;;
|
||||
aarch64)
|
||||
ALPINE_FROM=multiarch/alpine:aarch64-edge
|
||||
# shellcheck disable=SC2039
|
||||
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
|
||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
|
||||
aarch64|arm64)
|
||||
SPC_USE_ARCH=aarch64
|
||||
if [ "$CURRENT_ARCH" != "aarch64" ]; then
|
||||
PLATFORM_ARG="--platform linux/arm64"
|
||||
ALPINE_FROM=multiarch/alpine:aarch64-edge
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
# if ALPINE_FROM is not set, use alpine:edge
|
||||
if [ -z "$ALPINE_FROM" ]; then
|
||||
ALPINE_FROM=alpine:edge
|
||||
fi
|
||||
if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then
|
||||
echo "* Using different arch needs to setup qemu-static for docker !"
|
||||
ALPINE_FROM=multiarch/alpine:$SPC_USE_ARCH-edge
|
||||
if [ "$(uname -s)" = "Linux" ]; then
|
||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
|
||||
fi
|
||||
else
|
||||
ALPINE_FROM=alpine:edge
|
||||
fi
|
||||
|
||||
if [ "$SPC_USE_MIRROR" = "yes" ]; then
|
||||
SPC_USE_MIRROR="RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories"
|
||||
@@ -53,7 +76,7 @@ fi
|
||||
# Detect docker env is setup
|
||||
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION; then
|
||||
echo "Docker container does not exist. Building docker image ..."
|
||||
$DOCKER_EXECUTABLE build -t cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
|
||||
$DOCKER_EXECUTABLE build $PLATFORM_ARG -t cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
|
||||
FROM $ALPINE_FROM
|
||||
$SPC_USE_MIRROR
|
||||
RUN apk update; \
|
||||
@@ -148,7 +171,7 @@ if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
|
||||
echo "* ./pkgroot: $(pwd)/pkgroot"
|
||||
echo "*"
|
||||
set -ex
|
||||
$DOCKER_EXECUTABLE run --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION
|
||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
||||
else
|
||||
$DOCKER_EXECUTABLE run --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 $@
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
# This file is using docker to run commands
|
||||
SPC_DOCKER_VERSION=v4
|
||||
|
||||
# Detect docker can run
|
||||
if ! which docker >/dev/null; then
|
||||
echo "Docker is not installed, please install docker first !"
|
||||
@@ -19,35 +24,47 @@ if [ $(id -u) -ne 0 ]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# to check if qemu-docker run
|
||||
if [ "$SPC_USE_ARCH" = "" ]; then
|
||||
SPC_USE_ARCH=current
|
||||
# Convert uname to gnu arch
|
||||
CURRENT_ARCH=$(uname -m)
|
||||
if [ "$CURRENT_ARCH" = "arm64" ]; then
|
||||
CURRENT_ARCH=aarch64
|
||||
fi
|
||||
if [ -z "$SPC_USE_ARCH" ]; then
|
||||
SPC_USE_ARCH=$CURRENT_ARCH
|
||||
fi
|
||||
# parse SPC_USE_ARCH
|
||||
case $SPC_USE_ARCH in
|
||||
current)
|
||||
BASE_ARCH=$(uname -m)
|
||||
if [ "$BASE_ARCH" = "arm64" ]; then
|
||||
BASE_ARCH=aarch64
|
||||
x86_64|amd64)
|
||||
SPC_USE_ARCH=x86_64
|
||||
SPC_USE_ARCH_DOCKER=amd64
|
||||
if [ "$CURRENT_ARCH" != "x86_64" ]; then
|
||||
PLATFORM_ARG="--platform linux/amd64"
|
||||
fi
|
||||
;;
|
||||
aarch64)
|
||||
BASE_ARCH=aarch64
|
||||
# shellcheck disable=SC2039
|
||||
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
|
||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
|
||||
aarch64|arm64)
|
||||
SPC_USE_ARCH=aarch64
|
||||
SPC_USE_ARCH_DOCKER=arm64
|
||||
if [ "$CURRENT_ARCH" != "aarch64" ]; then
|
||||
PLATFORM_ARG="--platform linux/arm64"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
# detect if we need to use qemu-static
|
||||
if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then
|
||||
if [ "$(uname -s)" = "Linux" ]; then
|
||||
echo "* Using different arch needs to setup qemu-static for docker !"
|
||||
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static --reset -p yes > /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect docker env is setup
|
||||
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-gnu-$SPC_USE_ARCH; then
|
||||
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION; then
|
||||
echo "Docker container does not exist. Building docker image ..."
|
||||
$DOCKER_EXECUTABLE build -t cwcc-spc-gnu-$SPC_USE_ARCH -f- . <<EOF
|
||||
$DOCKER_EXECUTABLE buildx build $PLATFORM_ARG --no-cache -t cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
|
||||
FROM centos:7
|
||||
RUN sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo && \
|
||||
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
|
||||
@@ -59,7 +76,7 @@ RUN yum clean all && \
|
||||
|
||||
RUN yum install -y centos-release-scl
|
||||
|
||||
RUN if [ "$BASE_ARCH" = "aarch64" ]; then \
|
||||
RUN if [ "$SPC_USE_ARCH" = "aarch64" ]; then \
|
||||
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo ; \
|
||||
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl.repo ; \
|
||||
else \
|
||||
@@ -74,12 +91,12 @@ RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc
|
||||
RUN source /etc/bashrc
|
||||
RUN yum install -y which
|
||||
|
||||
RUN curl -fsSL -o patchelf.tgz https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-$BASE_ARCH.tar.gz && \
|
||||
RUN curl -fsSL -o patchelf.tgz https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-$SPC_USE_ARCH.tar.gz && \
|
||||
mkdir -p /patchelf && \
|
||||
tar -xzf patchelf.tgz -C /patchelf --strip-components=1 && \
|
||||
cp /patchelf/bin/patchelf /usr/bin/
|
||||
|
||||
RUN curl -o cmake.tgz -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$BASE_ARCH.tar.gz && \
|
||||
RUN curl -o cmake.tgz -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$SPC_USE_ARCH.tar.gz && \
|
||||
mkdir /cmake && \
|
||||
tar -xzf cmake.tgz -C /cmake --strip-components 1
|
||||
|
||||
@@ -173,7 +190,7 @@ if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
|
||||
echo "* ./pkgroot: $(pwd)/pkgroot"
|
||||
echo "*"
|
||||
set -ex
|
||||
$DOCKER_EXECUTABLE run --rm -it --privileged $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH
|
||||
$DOCKER_EXECUTABLE run $PLATFORM_ARG --privileged --rm -it $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
|
||||
else
|
||||
$DOCKER_EXECUTABLE run --rm $INTERACT $ENV_LIST --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH 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 $@
|
||||
fi
|
||||
|
||||
@@ -304,12 +304,14 @@
|
||||
},
|
||||
"intl": {
|
||||
"support": {
|
||||
"Windows": "no",
|
||||
"BSD": "wip"
|
||||
},
|
||||
"type": "builtin",
|
||||
"lib-depends": [
|
||||
"lib-depends-unix": [
|
||||
"icu"
|
||||
],
|
||||
"lib-depends-windows": [
|
||||
"icu-static-win"
|
||||
]
|
||||
},
|
||||
"ldap": {
|
||||
@@ -336,6 +338,9 @@
|
||||
},
|
||||
"type": "builtin",
|
||||
"arg-type": "none",
|
||||
"ext-depends": [
|
||||
"xml"
|
||||
],
|
||||
"target": [
|
||||
"static"
|
||||
]
|
||||
|
||||
@@ -207,6 +207,18 @@
|
||||
"libicudata.a"
|
||||
]
|
||||
},
|
||||
"icu-static-win": {
|
||||
"source": "icu-static-win",
|
||||
"static-libs-windows": [
|
||||
"icudt.lib",
|
||||
"icuin.lib",
|
||||
"icuio.lib",
|
||||
"icuuc.lib"
|
||||
],
|
||||
"headers-windows": [
|
||||
"unicode"
|
||||
]
|
||||
},
|
||||
"imagemagick": {
|
||||
"source": "imagemagick",
|
||||
"static-libs-unix": [
|
||||
|
||||
@@ -342,6 +342,14 @@
|
||||
"path": "LICENSE"
|
||||
}
|
||||
},
|
||||
"icu-static-win": {
|
||||
"type": "url",
|
||||
"url": "https://dl.static-php.dev/static-php-cli/deps/icu-static-windows-x64/icu-static-windows-x64.zip",
|
||||
"license": {
|
||||
"type": "text",
|
||||
"text": "none"
|
||||
}
|
||||
},
|
||||
"igbinary": {
|
||||
"type": "url",
|
||||
"url": "https://pecl.php.net/get/igbinary",
|
||||
|
||||
@@ -38,17 +38,11 @@ buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" -
|
||||
```
|
||||
|
||||
For macOS platform, almost all binaries under macOS cannot be truly purely statically linked, and almost all binaries will link macOS system libraries: `/usr/lib/libresolv.9.dylib` and `/usr/lib/libSystem.B.dylib`.
|
||||
So on macOS, you can use statically compiled PHP binaries under certain compilation conditions, and dynamically linked extensions:
|
||||
So on macOS, you can **directly** use SPC to build statically compiled PHP binaries with dynamically linked extensions:
|
||||
|
||||
1. Using the `--no-strip` parameter will not strip information such as debugging symbols from the binary file for use with external Zend extensions such as `Xdebug`.
|
||||
2. If you want to compile some Zend extensions, use Homebrew, MacPorts, source code compilation, and install a normal version of PHP on your operating system.
|
||||
3. Use the `phpize && ./configure && make` command to compile the extensions you want to use.
|
||||
4. Copy the extension file `xxxx.so` to the outside, use the statically compiled PHP binary, for example to use the Xdebug extension: `cd buildroot/bin/ && ./php -d "zend_extension=/path/to/xdebug.so"`.
|
||||
|
||||
```bash
|
||||
# build statically linked php-cli but not stripped
|
||||
bin/spc build ffi --build-cli --no-strip
|
||||
```
|
||||
1. Build shared extension `xxx.so` using: `--build-shared=XXX` option. e.g. `bin/spc build bcmath,zlib --build-shared=xdebug --build-cli`
|
||||
2. You will get `buildroot/modules/xdebug.so` and `buildroot/bin/php`.
|
||||
3. The `xdebug.so` file could be used for php that version and thread-safe are the same.
|
||||
|
||||
## Can it support Oracle database extension?
|
||||
|
||||
|
||||
@@ -339,7 +339,7 @@ You can try to use the following commands:
|
||||
- `--cxx=XXX`: Specifies the execution command of the C++ language compiler (Linux defaults to `g++`, macOS defaults to `clang++`)
|
||||
- `--with-clean`: clean up old make files before compiling PHP
|
||||
- `--enable-zts`: Make compiled PHP thread-safe version (default is NTS version)
|
||||
- `--no-strip`: Do not run `strip` after compiling the PHP library to trim the binary file to reduce its size (the macOS binary file without trim can use dynamically linked third-party extensions)
|
||||
- `--no-strip`: Do not run `strip` after compiling the PHP library to trim the binary file to reduce its size
|
||||
- `--with-libs=XXX,YYY`: Compile the specified dependent library before compiling PHP, and activate some extended optional functions (such as libavif of the gd library, etc.)
|
||||
- `--with-config-file-path=XXX`: Set the path in which to look for `php.ini` (Check [here](../faq/index.html#what-is-the-path-of-php-ini) for default paths)
|
||||
- `--with-config-file-scan-dir=XXX`: Set the directory to scan for `.ini` files after reading `php.ini` (Check [here](../faq/index.html#what-is-the-path-of-php-ini) for default paths)
|
||||
|
||||
@@ -35,17 +35,11 @@ buildroot/bin/php -d "zend_extension=/path/to/php{PHP_VER}-{ts/nts}/xdebug.so" -
|
||||
```
|
||||
|
||||
对于 macOS 平台来说,macOS 下的几乎所有二进制文件都无法真正纯静态链接,几乎所有二进制文件都会链接 macOS 的系统库:`/usr/lib/libresolv.9.dylib` 和 `/usr/lib/libSystem.B.dylib`。
|
||||
所以在 macOS 系统下,在特定的编译条件下可以使用静态编译的 php 二进制文件,可使用动态链接的扩展:
|
||||
因此,在 macOS 上,您可以直接构建出使用静态编译的 PHP 二进制文件和动态链接的扩展:
|
||||
|
||||
1. 使用 `--no-strip` 参数,将不会对二进制文件去除调试符号等信息,以供使用 `Xdebug` 等外部 Zend 扩展。
|
||||
2. 如果要编译某些 Zend 扩展,使用 Homebrew、MacPorts、源码编译的形式,在所在的操作系统安装一个普通版本的 PHP。
|
||||
3. 使用 `phpize && ./configure && make` 命令编译想要使用的扩展。
|
||||
4. 将扩展文件 `xxxx.so` 拷贝到外部,使用静态编译的 PHP 二进制,例如使用 Xdebug 扩展:`cd buildroot/bin/ && ./php -d "zend_extension=/path/to/xdebug.so"`。
|
||||
|
||||
```bash
|
||||
# 构建静态 php-cli
|
||||
bin/spc build ffi --build-cli --no-strip
|
||||
```
|
||||
1. 使用 `--build-shared=XXX` 选项构建共享扩展 `xxx.so`。例如:`bin/spc build bcmath,zlib --build-shared=xdebug --build-cli`
|
||||
2. 您将获得 `buildroot/modules/xdebug.so` 和 `buildroot/bin/php`。
|
||||
3. `xdebug.so` 文件可用于版本和线程安全相同的 php。
|
||||
|
||||
## 可以支持 Oracle 数据库扩展吗
|
||||
|
||||
|
||||
@@ -296,7 +296,7 @@ bin/spc build bcmath,curl,openssl,ftp,posix,pcntl --build-cli
|
||||
- `--cxx=XXX`: 指定 C++ 语言编译器的执行命令(Linux 默认 `g++`,macOS 默认 `clang++`)
|
||||
- `--with-clean`: 编译 PHP 前先清理旧的 make 产生的文件
|
||||
- `--enable-zts`: 让编译的 PHP 为线程安全版本(默认为 NTS 版本)
|
||||
- `--no-strip`: 编译 PHP 库后不运行 `strip` 裁剪二进制文件缩小体积(不裁剪的 macOS 二进制文件可使用动态链接的第三方扩展)
|
||||
- `--no-strip`: 编译 PHP 库后不运行 `strip` 裁剪二进制文件缩小体积
|
||||
- `--with-libs=XXX,YYY`: 编译 PHP 前先编译指定的依赖库,激活部分扩展的可选功能(例如 gd 库的 libavif 等)
|
||||
- `--with-config-file-path=XXX`: 查找 `php.ini` 的路径(在 [这里](../faq/index.html#php-ini-的路径是什么) 查看默认路径)
|
||||
- `--with-config-file-scan-dir=XXX`: 读取 `php.ini` 后扫描 `.ini` 文件的目录(在 [这里](../faq/index.html#php-ini-的路径是什么) 查看默认路径)
|
||||
|
||||
@@ -193,7 +193,7 @@ class Extension
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeSharedBuild(): bool
|
||||
public function patchBeforeSharedPhpize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -208,6 +208,16 @@ class Extension
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch code before shared extension make
|
||||
* If you need to patch some code, overwrite this
|
||||
* return true if you patched something, false if not
|
||||
*/
|
||||
public function patchBeforeSharedMake(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* returns a command line string with all required shared extensions to load
|
||||
@@ -342,6 +352,9 @@ class Extension
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (file_exists(BUILD_MODULES_PATH . '/' . $this->getName() . '.so')) {
|
||||
logger()->info('Shared extension [' . $this->getName() . '] was already built, skipping (' . $this->getName() . '.so)');
|
||||
}
|
||||
logger()->info('Building extension [' . $this->getName() . '] as shared extension (' . $this->getName() . '.so)');
|
||||
foreach ($this->dependencies as $dependency) {
|
||||
if (!$dependency instanceof Extension) {
|
||||
@@ -384,13 +397,17 @@ class Extension
|
||||
'LD_LIBRARY_PATH' => BUILD_LIB_PATH,
|
||||
];
|
||||
|
||||
if ($this->patchBeforeSharedPhpize()) {
|
||||
logger()->info("Extension [{$this->getName()}] patched before shared phpize");
|
||||
}
|
||||
|
||||
// prepare configure args
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->exec(BUILD_BIN_PATH . '/phpize');
|
||||
|
||||
if ($this->patchBeforeSharedConfigure()) {
|
||||
logger()->info('ext [ . ' . $this->getName() . '] patching before shared configure');
|
||||
logger()->info("Extension [{$this->getName()}] patched before shared configure");
|
||||
}
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
@@ -408,6 +425,10 @@ class Extension
|
||||
'$1 ' . $staticLibString
|
||||
);
|
||||
|
||||
if ($this->patchBeforeSharedMake()) {
|
||||
logger()->info("Extension [{$this->getName()}] patched before shared make");
|
||||
}
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->exec('make clean')
|
||||
|
||||
@@ -215,19 +215,6 @@ abstract class LibraryBase
|
||||
*/
|
||||
public function tryBuild(bool $force_build = false): int
|
||||
{
|
||||
if (str_contains((string) getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), '-release')) {
|
||||
FileSystem::replaceFileLineContainsString(
|
||||
SOURCE_PATH . '/php-src/ext/standard/info.c',
|
||||
'#ifdef CONFIGURE_COMMAND',
|
||||
'#ifdef NO_CONFIGURE_COMMAND',
|
||||
);
|
||||
} else {
|
||||
FileSystem::replaceFileLineContainsString(
|
||||
SOURCE_PATH . '/php-src/ext/standard/info.c',
|
||||
'#ifdef NO_CONFIGURE_COMMAND',
|
||||
'#ifdef CONFIGURE_COMMAND',
|
||||
);
|
||||
}
|
||||
if (file_exists($this->source_dir . '/.spc.patched')) {
|
||||
$this->patched = true;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\windows\WindowsBuilder;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
@@ -13,16 +14,18 @@ class intl extends Extension
|
||||
{
|
||||
public function patchBeforeBuildconf(): bool
|
||||
{
|
||||
// TODO: remove the following line when https://github.com/php/php-src/pull/14002 will be released
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/intl/config.m4', 'PHP_CXX_COMPILE_STDCXX(11', 'PHP_CXX_COMPILE_STDCXX(17');
|
||||
// Also need to use clang++ -std=c++17 to force override the default C++ standard
|
||||
if (is_string($env = getenv('CXX')) && !str_contains($env, 'std=c++17')) {
|
||||
f_putenv('CXX=' . $env . ' -std=c++17');
|
||||
if ($this->builder instanceof WindowsBuilder) {
|
||||
FileSystem::replaceFileStr(
|
||||
SOURCE_PATH . '/php-src/ext/intl/config.w32',
|
||||
'EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", true,',
|
||||
'EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", PHP_INTL_SHARED,'
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function patchBeforeSharedBuild(): bool
|
||||
public function patchBeforeSharedPhpize(): bool
|
||||
{
|
||||
return $this->patchBeforeBuildconf();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ class protobuf extends Extension
|
||||
if ($this->builder->getPHPVersionID() < 80000 && getenv('SPC_SKIP_PHP_VERSION_CHECK') !== 'yes') {
|
||||
throw new \RuntimeException('The latest protobuf extension requires PHP 8.0 or later');
|
||||
}
|
||||
$grpc = $this->builder->getExt('grpc');
|
||||
// protobuf conflicts with grpc
|
||||
if ($this->builder->getExt('grpc') !== null) {
|
||||
if ($grpc?->isBuildStatic()) {
|
||||
throw new \RuntimeException('protobuf conflicts with grpc, please remove grpc or protobuf extension');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('uv')]
|
||||
@@ -16,4 +17,13 @@ class uv extends Extension
|
||||
throw new \RuntimeException('The latest uv extension requires PHP 8.0 or later');
|
||||
}
|
||||
}
|
||||
|
||||
public function patchBeforeSharedMake(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY !== 'Linux' || arch2gnu(php_uname('m')) !== 'aarch64') {
|
||||
return false;
|
||||
}
|
||||
FileSystem::replaceFileRegex($this->source_dir . '/Makefile', '/^(LDFLAGS =.*)$/m', '$1 -luv -ldl -lrt -pthread');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
// check musl-cross make installed if we use musl-cross-make
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
|
||||
GlobalEnvManager::init($this);
|
||||
GlobalEnvManager::init();
|
||||
|
||||
if (getenv('SPC_LIBC') === 'musl' && !SystemUtil::isMuslDist()) {
|
||||
$this->setOptionIfNotExist('library_path', "LIBRARY_PATH=\"/usr/local/musl/{$arch}-linux-musl/lib\"");
|
||||
|
||||
@@ -28,7 +28,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
$this->options = $options;
|
||||
|
||||
// apply global environment variables
|
||||
GlobalEnvManager::init($this);
|
||||
GlobalEnvManager::init();
|
||||
|
||||
// ---------- set necessary compile vars ----------
|
||||
// concurrency
|
||||
@@ -207,7 +207,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
$SPC_CMD_PREFIX_PHP_MAKE = getenv('SPC_CMD_PREFIX_PHP_MAKE') ?: 'make';
|
||||
$shell->exec("{$SPC_CMD_PREFIX_PHP_MAKE} {$vars} cli");
|
||||
if (!$this->getOption('no-strip', false)) {
|
||||
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php');
|
||||
$shell->exec('dsymutil -f sapi/cli/php')->exec('strip -S sapi/cli/php');
|
||||
}
|
||||
$this->deployBinary(BUILD_TARGET_CLI);
|
||||
}
|
||||
@@ -234,12 +234,15 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
|
||||
// patch fake cli for micro
|
||||
$vars['EXTRA_CFLAGS'] .= $enable_fake_cli;
|
||||
if ($this->getOption('no-strip', false)) {
|
||||
$vars['STRIP'] = 'dsymutil -f ';
|
||||
}
|
||||
$vars = SystemUtil::makeEnvVarString($vars);
|
||||
|
||||
shell()->cd(SOURCE_PATH . '/php-src')->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . " {$vars} micro");
|
||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||
// build
|
||||
$shell->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . " {$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);
|
||||
|
||||
@@ -261,7 +264,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
$shell = shell()->cd(SOURCE_PATH . '/php-src');
|
||||
$shell->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . " {$vars} fpm");
|
||||
if (!$this->getOption('no-strip', false)) {
|
||||
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip sapi/fpm/php-fpm');
|
||||
$shell->exec('dsymutil -f sapi/fpm/php-fpm')->exec('strip -S sapi/fpm/php-fpm');
|
||||
}
|
||||
$this->deployBinary(BUILD_TARGET_FPM);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ trait curl
|
||||
->optionalLib('libssh2', fn ($lib) => "-DLIBSSH2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DLIBSSH2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DCURL_USE_LIBSSH2=OFF')
|
||||
->optionalLib('nghttp2', fn ($lib) => "-DUSE_NGHTTP2=ON -DNGHTTP2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP2=OFF')
|
||||
->optionalLib('nghttp3', fn ($lib) => "-DUSE_NGHTTP3=ON -DNGHTTP3_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP3_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP3=OFF')
|
||||
->optionalLib('ngtcp2', fn ($lib) => "-DUSE_NGTCP2=ON -DNGNGTCP2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGNGTCP2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGTCP2=OFF')
|
||||
->optionalLib('ldap', ...cmake_boolean_args('CURL_DISABLE_LDAP', true))
|
||||
->optionalLib('zstd', ...cmake_boolean_args('CURL_ZSTD'))
|
||||
->optionalLib('idn2', ...cmake_boolean_args('USE_LIBIDN2'))
|
||||
|
||||
@@ -33,7 +33,7 @@ class WindowsBuilder extends BuilderBase
|
||||
{
|
||||
$this->options = $options;
|
||||
|
||||
GlobalEnvManager::init($this);
|
||||
GlobalEnvManager::init();
|
||||
|
||||
// ---------- set necessary options ----------
|
||||
// set sdk (require visual studio 16 or 17)
|
||||
|
||||
27
src/SPC/builder/windows/library/icu_static_win.php
Normal file
27
src/SPC/builder/windows/library/icu_static_win.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class icu_static_win extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'icu-static-win';
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
copy("{$this->source_dir}\\x64-windows-static\\lib\\icudt.lib", "{$this->getLibDir()}\\icudt.lib");
|
||||
copy("{$this->source_dir}\\x64-windows-static\\lib\\icuin.lib", "{$this->getLibDir()}\\icuin.lib");
|
||||
copy("{$this->source_dir}\\x64-windows-static\\lib\\icuio.lib", "{$this->getLibDir()}\\icuio.lib");
|
||||
copy("{$this->source_dir}\\x64-windows-static\\lib\\icuuc.lib", "{$this->getLibDir()}\\icuuc.lib");
|
||||
|
||||
// create libpq folder in buildroot/includes/libpq
|
||||
if (!file_exists("{$this->getIncludeDir()}\\unicode")) {
|
||||
mkdir("{$this->getIncludeDir()}\\unicode");
|
||||
}
|
||||
|
||||
FileSystem::copyDir("{$this->source_dir}\\x64-windows-static\\include\\unicode", "{$this->getIncludeDir()}\\unicode");
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,10 @@ class BuildPHPCommand extends BuildCommand
|
||||
$this->addOption('build-micro', null, null, 'Build micro SAPI');
|
||||
$this->addOption('build-cli', null, null, 'Build cli SAPI');
|
||||
$this->addOption('build-fpm', null, null, 'Build fpm SAPI (not available on Windows)');
|
||||
$this->addOption('build-embed', null, InputOption::VALUE_OPTIONAL, 'Build embed SAPI (not available on Windows)');
|
||||
$this->addOption('build-embed', null, null, 'Build embed SAPI (not available on Windows)');
|
||||
$this->addOption('build-frankenphp', null, null, 'Build FrankenPHP SAPI (not available on Windows)');
|
||||
$this->addOption('build-all', null, null, 'Build all SAPI');
|
||||
$this->addOption('no-strip', null, null, 'build without strip, in order to debug and load external extensions');
|
||||
$this->addOption('no-strip', null, null, 'build without strip, keep symbols to debug');
|
||||
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');
|
||||
$this->addOption('with-config-file-path', null, InputOption::VALUE_REQUIRED, 'Set the path in which to look for php.ini', $isWindows ? null : '/usr/local/etc/php');
|
||||
$this->addOption('with-config-file-scan-dir', null, InputOption::VALUE_REQUIRED, 'Set the directory to scan for .ini files after reading php.ini', $isWindows ? null : '/usr/local/etc/php/conf.d');
|
||||
@@ -62,11 +62,6 @@ class BuildPHPCommand extends BuildCommand
|
||||
$rule = $this->parseRules($shared_extensions);
|
||||
|
||||
// check dynamic extension build env
|
||||
// macOS must use --no-strip option
|
||||
if (!empty($shared_extensions) && PHP_OS_FAMILY === 'Darwin' && !$this->getOption('no-strip')) {
|
||||
$this->output->writeln('MacOS does not support dynamic extension loading with stripped binary, please use --no-strip option!');
|
||||
return static::FAILURE;
|
||||
}
|
||||
// linux must build with glibc
|
||||
if (!empty($shared_extensions) && PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') !== 'glibc') {
|
||||
$this->output->writeln('Linux does not support dynamic extension loading with musl-libc full-static build, please build with glibc!');
|
||||
@@ -79,12 +74,12 @@ class BuildPHPCommand extends BuildCommand
|
||||
|
||||
if ($rule === BUILD_TARGET_NONE) {
|
||||
$this->output->writeln('<error>Please add at least one build SAPI!</error>');
|
||||
$this->output->writeln("<comment>\t--build-cli\tBuild php-cli SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-micro\tBuild phpmicro SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-fpm\tBuild php-fpm SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-embed\tBuild embed SAPI/libphp</comment>");
|
||||
$this->output->writeln("<comment>\t--build-cli\t\tBuild php-cli SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-micro\t\tBuild phpmicro SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-fpm\t\tBuild php-fpm SAPI</comment>");
|
||||
$this->output->writeln("<comment>\t--build-embed\t\tBuild embed SAPI/libphp</comment>");
|
||||
$this->output->writeln("<comment>\t--build-frankenphp\tBuild FrankenPHP SAPI/libphp</comment>");
|
||||
$this->output->writeln("<comment>\t--build-all\tBuild all SAPI: cli, micro, fpm, embed, frankenphp</comment>");
|
||||
$this->output->writeln("<comment>\t--build-all\t\tBuild all SAPI: cli, micro, fpm, embed, frankenphp</comment>");
|
||||
return static::FAILURE;
|
||||
}
|
||||
if ($rule === BUILD_TARGET_ALL) {
|
||||
@@ -207,11 +202,11 @@ class BuildPHPCommand extends BuildCommand
|
||||
// add static-php-cli.version to main.c, in order to debug php failure more easily
|
||||
SourcePatcher::patchSPCVersionToPHP($this->getApplication()->getVersion());
|
||||
|
||||
// clean old modules that may conflict with the new php build
|
||||
FileSystem::removeDir(BUILD_MODULES_PATH);
|
||||
// start to build
|
||||
$builder->buildPHP($rule);
|
||||
|
||||
SourcePatcher::patchBeforeSharedBuild($builder);
|
||||
|
||||
// build dynamic extensions if needed
|
||||
if (!empty($shared_extensions)) {
|
||||
logger()->info('Building shared extensions ...');
|
||||
@@ -292,17 +287,7 @@ class BuildPHPCommand extends BuildCommand
|
||||
$rule |= ($this->getOption('build-cli') ? BUILD_TARGET_CLI : BUILD_TARGET_NONE);
|
||||
$rule |= ($this->getOption('build-micro') ? BUILD_TARGET_MICRO : BUILD_TARGET_NONE);
|
||||
$rule |= ($this->getOption('build-fpm') ? BUILD_TARGET_FPM : BUILD_TARGET_NONE);
|
||||
$embed = $this->getOption('build-embed');
|
||||
if (!$embed && !empty($shared_extensions)) {
|
||||
$embed = true;
|
||||
}
|
||||
if ($embed) {
|
||||
if ($embed === true) {
|
||||
$embed = getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') ?: 'static';
|
||||
}
|
||||
$rule |= BUILD_TARGET_EMBED;
|
||||
f_putenv('SPC_CMD_VAR_PHP_EMBED_TYPE=' . ($embed === 'static' ? 'static' : 'shared'));
|
||||
}
|
||||
$rule |= $this->getOption('build-embed') || !empty($shared_extensions) ? BUILD_TARGET_EMBED : BUILD_TARGET_NONE;
|
||||
$rule |= ($this->getOption('build-frankenphp') ? (BUILD_TARGET_FRANKENPHP | BUILD_TARGET_EMBED) : BUILD_TARGET_NONE);
|
||||
$rule |= ($this->getOption('build-all') ? BUILD_TARGET_ALL : BUILD_TARGET_NONE);
|
||||
return $rule;
|
||||
|
||||
@@ -22,6 +22,8 @@ class DeleteDownloadCommand extends BaseCommand
|
||||
{
|
||||
$this->addArgument('sources', InputArgument::REQUIRED, 'The sources/packages will be deleted, comma separated');
|
||||
$this->addOption('all', 'A', null, 'Delete all downloaded and locked sources/packages');
|
||||
$this->addOption('pre-built-only', 'W', null, 'Delete only pre-built sources/packages, not the original ones');
|
||||
$this->addOption('source-only', 'S', null, 'Delete only sources, not the pre-built packages');
|
||||
}
|
||||
|
||||
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||
@@ -51,10 +53,11 @@ class DeleteDownloadCommand extends BaseCommand
|
||||
$deleted_sources = [];
|
||||
foreach ($chosen_sources as $source) {
|
||||
$source = trim($source);
|
||||
foreach ([$source, Downloader::getPreBuiltLockName($source)] as $name) {
|
||||
if (LockFile::get($name)) {
|
||||
$deleted_sources[] = $name;
|
||||
}
|
||||
if (LockFile::get($source) && !$this->getOption('pre-built-only')) {
|
||||
$deleted_sources[] = $source;
|
||||
}
|
||||
if (LockFile::get(Downloader::getPreBuiltLockName($source)) && !$this->getOption('source-only')) {
|
||||
$deleted_sources[] = Downloader::getPreBuiltLockName($source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,12 @@ class SourcePatcher
|
||||
{
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeBuildconf() === true) {
|
||||
logger()->info('Extension [' . $ext->getName() . '] patched before buildconf');
|
||||
logger()->info("Extension [{$ext->getName()}] patched before buildconf");
|
||||
}
|
||||
}
|
||||
foreach ($builder->getLibs() as $lib) {
|
||||
if ($lib->patchBeforeBuildconf() === true) {
|
||||
logger()->info('Library [' . $lib->getName() . '] patched before buildconf');
|
||||
logger()->info("Library [{$lib->getName()}]patched before buildconf");
|
||||
}
|
||||
}
|
||||
// patch windows php 8.1 bug
|
||||
@@ -79,15 +79,6 @@ class SourcePatcher
|
||||
}
|
||||
}
|
||||
|
||||
public static function patchBeforeSharedBuild(BuilderBase $builder): void
|
||||
{
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeSharedBuild() === true) {
|
||||
logger()->info('Extension [' . $ext->getName() . '] patched before shared build');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Source patcher runner before configure
|
||||
*
|
||||
@@ -98,19 +89,16 @@ class SourcePatcher
|
||||
{
|
||||
foreach ($builder->getExts() as $ext) {
|
||||
if ($ext->patchBeforeConfigure() === true) {
|
||||
logger()->info('Extension [' . $ext->getName() . '] patched before configure');
|
||||
logger()->info("Extension [{$ext->getName()}] patched before configure");
|
||||
}
|
||||
}
|
||||
foreach ($builder->getLibs() as $lib) {
|
||||
if ($lib->patchBeforeConfigure() === true) {
|
||||
logger()->info('Library [' . $lib->getName() . '] patched before configure');
|
||||
logger()->info("Library [{$lib->getName()}] patched before configure");
|
||||
}
|
||||
}
|
||||
// patch capstone
|
||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/have_capstone="yes"/', 'have_capstone="no"');
|
||||
if ($builder instanceof LinuxBuilder && getenv('SPC_LIBC') === 'glibc') {
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/Zend/zend_operators.h', '# define ZEND_USE_ASM_ARITHMETIC 1', '# define ZEND_USE_ASM_ARITHMETIC 0');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,14 +267,28 @@ class SourcePatcher
|
||||
// call extension patch before make
|
||||
foreach ($builder->getExts(false) as $ext) {
|
||||
if ($ext->patchBeforeMake() === true) {
|
||||
logger()->info('Extension [' . $ext->getName() . '] patched before make');
|
||||
logger()->info("Extension [{$ext->getName()}] patched before make");
|
||||
}
|
||||
}
|
||||
foreach ($builder->getLibs() as $lib) {
|
||||
if ($lib->patchBeforeMake() === true) {
|
||||
logger()->info('Library [' . $lib->getName() . '] patched before make');
|
||||
logger()->info("Library [{$lib->getName()}] patched before make");
|
||||
}
|
||||
}
|
||||
|
||||
if (str_contains((string) getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), '-release')) {
|
||||
FileSystem::replaceFileLineContainsString(
|
||||
SOURCE_PATH . '/php-src/ext/standard/info.c',
|
||||
'#ifdef CONFIGURE_COMMAND',
|
||||
'#ifdef NO_CONFIGURE_COMMAND',
|
||||
);
|
||||
} else {
|
||||
FileSystem::replaceFileLineContainsString(
|
||||
SOURCE_PATH . '/php-src/ext/standard/info.c',
|
||||
'#ifdef NO_CONFIGURE_COMMAND',
|
||||
'#ifdef CONFIGURE_COMMAND',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
@@ -24,11 +23,10 @@ class GlobalEnvManager
|
||||
/**
|
||||
* Initialize the environment variables
|
||||
*
|
||||
* @param null|BuilderBase $builder Builder
|
||||
* @throws RuntimeException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function init(?BuilderBase $builder = null): void
|
||||
public static function init(): void
|
||||
{
|
||||
// Check pre-defined env vars exists
|
||||
if (getenv('BUILD_ROOT_PATH') === false) {
|
||||
@@ -37,7 +35,7 @@ class GlobalEnvManager
|
||||
|
||||
// Define env vars for unix
|
||||
if (is_unix()) {
|
||||
self::putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH'));
|
||||
self::addPathIfNotExists(BUILD_BIN_PATH);
|
||||
self::putenv('PKG_CONFIG=' . BUILD_BIN_PATH . '/pkg-config');
|
||||
self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig');
|
||||
}
|
||||
@@ -55,10 +53,73 @@ class GlobalEnvManager
|
||||
self::putenv("SPC_LINUX_DEFAULT_CXX={$arch}-linux-musl-g++");
|
||||
self::putenv("SPC_LINUX_DEFAULT_AR={$arch}-linux-musl-ar");
|
||||
self::putenv("SPC_LINUX_DEFAULT_LD={$arch}-linux-musl-ld");
|
||||
GlobalEnvManager::putenv("PATH=/usr/local/musl/bin:/usr/local/musl/{$arch}-linux-musl/bin:" . getenv('PATH'));
|
||||
self::addPathIfNotExists('/usr/local/musl/bin');
|
||||
self::addPathIfNotExists("/usr/local/musl/{$arch}-linux-musl/bin");
|
||||
}
|
||||
}
|
||||
|
||||
$ini = self::readIniFile();
|
||||
|
||||
$default_put_list = [];
|
||||
foreach ($ini['global'] as $k => $v) {
|
||||
if (getenv($k) === false) {
|
||||
$default_put_list[$k] = $v;
|
||||
self::putenv("{$k}={$v}");
|
||||
}
|
||||
}
|
||||
$os_ini = match (PHP_OS_FAMILY) {
|
||||
'Windows' => $ini['windows'] ?? [],
|
||||
'Darwin' => $ini['macos'] ?? [],
|
||||
'Linux' => $ini['linux'] ?? [],
|
||||
'BSD' => $ini['freebsd'] ?? [],
|
||||
default => [],
|
||||
};
|
||||
foreach ($os_ini as $k => $v) {
|
||||
if (getenv($k) === false) {
|
||||
$default_put_list[$k] = $v;
|
||||
self::putenv("{$k}={$v}");
|
||||
}
|
||||
}
|
||||
// apply second time
|
||||
$ini2 = self::readIniFile();
|
||||
|
||||
foreach ($ini2['global'] as $k => $v) {
|
||||
if (isset($default_put_list[$k]) && $default_put_list[$k] !== $v) {
|
||||
self::putenv("{$k}={$v}");
|
||||
}
|
||||
}
|
||||
$os_ini2 = match (PHP_OS_FAMILY) {
|
||||
'Windows' => $ini2['windows'] ?? [],
|
||||
'Darwin' => $ini2['macos'] ?? [],
|
||||
'Linux' => $ini2['linux'] ?? [],
|
||||
'BSD' => $ini2['freebsd'] ?? [],
|
||||
default => [],
|
||||
};
|
||||
foreach ($os_ini2 as $k => $v) {
|
||||
if (isset($default_put_list[$k]) && $default_put_list[$k] !== $v) {
|
||||
self::putenv("{$k}={$v}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function putenv(string $val): void
|
||||
{
|
||||
f_putenv($val);
|
||||
self::$env_cache[] = $val;
|
||||
}
|
||||
|
||||
private static function addPathIfNotExists(string $path): void
|
||||
{
|
||||
if (is_unix() && !str_contains(getenv('PATH'), $path)) {
|
||||
self::putenv("PATH={$path}:" . getenv('PATH'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
private static function readIniFile(): array
|
||||
{
|
||||
// Init env.ini file, read order:
|
||||
// WORKING_DIR/config/env.ini
|
||||
// ROOT_DIR/config/env.ini
|
||||
@@ -100,28 +161,6 @@ class GlobalEnvManager
|
||||
break;
|
||||
}
|
||||
}
|
||||
self::applyConfig($ini['global']);
|
||||
match (PHP_OS_FAMILY) {
|
||||
'Windows' => self::applyConfig($ini['windows']),
|
||||
'Darwin' => self::applyConfig($ini['macos']),
|
||||
'Linux' => self::applyConfig($ini['linux']),
|
||||
'BSD' => self::applyConfig($ini['freebsd']),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
public static function putenv(string $val): void
|
||||
{
|
||||
f_putenv($val);
|
||||
self::$env_cache[] = $val;
|
||||
}
|
||||
|
||||
private static function applyConfig(array $ini): void
|
||||
{
|
||||
foreach ($ini as $k => $v) {
|
||||
if (getenv($k) === false) {
|
||||
self::putenv($k . '=' . $v);
|
||||
}
|
||||
}
|
||||
return $ini;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,23 +13,23 @@ declare(strict_types=1);
|
||||
|
||||
// test php version (8.1 ~ 8.4 available, multiple for matrix)
|
||||
$test_php_version = [
|
||||
// '8.1',
|
||||
// '8.2',
|
||||
// '8.3',
|
||||
'8.1',
|
||||
'8.2',
|
||||
'8.3',
|
||||
'8.4',
|
||||
];
|
||||
|
||||
// test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available)
|
||||
$test_os = [
|
||||
'macos-13',
|
||||
// 'macos-13',
|
||||
// 'macos-14',
|
||||
'macos-15',
|
||||
'ubuntu-latest',
|
||||
'ubuntu-22.04',
|
||||
'ubuntu-24.04',
|
||||
'ubuntu-22.04-arm',
|
||||
'ubuntu-24.04-arm',
|
||||
// 'windows-latest',
|
||||
// 'macos-15',
|
||||
// 'ubuntu-latest',
|
||||
// 'ubuntu-22.04',
|
||||
// 'ubuntu-24.04',
|
||||
// 'ubuntu-22.04-arm',
|
||||
// 'ubuntu-24.04-arm',
|
||||
'windows-latest',
|
||||
];
|
||||
|
||||
// whether enable thread safe
|
||||
@@ -41,26 +41,26 @@ $no_strip = false;
|
||||
$upx = false;
|
||||
|
||||
// whether to test frankenphp build, only available for macos and linux
|
||||
$frankenphp = true;
|
||||
$frankenphp = false;
|
||||
|
||||
// prefer downloading pre-built packages to speed up the build process
|
||||
$prefer_pre_built = false;
|
||||
$prefer_pre_built = true;
|
||||
|
||||
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
|
||||
$extensions = match (PHP_OS_FAMILY) {
|
||||
'Linux', 'Darwin' => 'apcu,ast,bcmath,calendar,ctype,curl,dba,dom,exif,fileinfo,filter,iconv,libxml,mbregex,mbstring,opcache,openssl,pcntl,phar,posix,readline,session,simplexml,sockets,sodium,tokenizer,xml,xmlreader,xmlwriter,zip,zlib',
|
||||
'Windows' => 'xlswriter,openssl',
|
||||
'Linux', 'Darwin' => 'curl',
|
||||
'Windows' => 'intl',
|
||||
};
|
||||
|
||||
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
|
||||
$shared_extensions = match (PHP_OS_FAMILY) {
|
||||
'Linux' => '',
|
||||
'Linux' => 'uv',
|
||||
'Darwin' => '',
|
||||
'Windows' => '',
|
||||
};
|
||||
|
||||
// If you want to test lib-suggests for all extensions and libraries, set it to true.
|
||||
$with_suggested_libs = true;
|
||||
$with_suggested_libs = false;
|
||||
|
||||
// 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) {
|
||||
|
||||
Reference in New Issue
Block a user