mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-18 12:54:52 +08:00
<
This commit is contained in:
commit
2ebdc4509c
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。
|
**static-php-cli**是一个用于静态编译、构建 PHP 解释器的工具,支持众多流行扩展。
|
||||||
|
|
||||||
目前 static-php-cli 支持 `cli`、`fpm`、`embed` 和 `micro` SAPI。
|
目前 static-php-cli 支持 `cli`、`fpm`、`embed`、`micro` 和 `frankenphp` SAPI。
|
||||||
|
|
||||||
**static-php-cli**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。
|
**static-php-cli**也支持将 PHP 代码和 PHP 运行时打包为一个文件并运行。
|
||||||
|
|
||||||
@ -292,6 +292,12 @@ bin/spc micro:combine my-app.phar -I "memory_limit=4G" -I "disable_functions=sys
|
|||||||
|
|
||||||
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。你捐赠的一部分将会被用于维护 **static-php.dev** 服务器。
|
你可以在 [我的个人赞助页](https://github.com/crazywhalecc/crazywhalecc/blob/master/FUNDING.md) 支持我和我的项目。你捐赠的一部分将会被用于维护 **static-php.dev** 服务器。
|
||||||
|
|
||||||
|
**特别赞助商**:
|
||||||
|
|
||||||
|
<a href="https://beyondco.de/"><img src="/docs/public/images/beyondcode-seeklogo.png" width="300" alt="Beyond Code Logo" /></a>
|
||||||
|
|
||||||
|
<a href="https://nativephp.com/"><img src="/docs/public/images/nativephp-logo.svg" width="300" alt="NativePHP Logo" /></a>
|
||||||
|
|
||||||
## 开源协议
|
## 开源协议
|
||||||
|
|
||||||
本项目采用 MIT License 许可开源,下面是类似的项目:
|
本项目采用 MIT License 许可开源,下面是类似的项目:
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
|
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
|
||||||
with popular extensions.
|
with popular extensions.
|
||||||
|
|
||||||
Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed` and `micro` SAPI.
|
Static PHP built by **static-php-cli** supports `cli`, `fpm`, `embed`, `micro` and `frankenphp` SAPI.
|
||||||
|
|
||||||
**static-php-cli** also has the ability to package PHP projects
|
**static-php-cli** also has the ability to package PHP projects
|
||||||
along with the PHP interpreter into one single executable file.
|
along with the PHP interpreter into one single executable file.
|
||||||
@ -317,6 +317,12 @@ Now there is a [static-php](https://github.com/static-php) organization, which i
|
|||||||
|
|
||||||
You can sponsor me or my project from [GitHub Sponsor](https://github.com/crazywhalecc). A portion of your donation will be used to maintain the **static-php.dev** server.
|
You can sponsor me or my project from [GitHub Sponsor](https://github.com/crazywhalecc). A portion of your donation will be used to maintain the **static-php.dev** server.
|
||||||
|
|
||||||
|
**Special thanks to sponsors below**:
|
||||||
|
|
||||||
|
<a href="https://beyondco.de/"><img src="/docs/public/images/beyondcode-seeklogo.png" width="300" alt="Beyond Code Logo" /></a>
|
||||||
|
|
||||||
|
<a href="https://nativephp.com/"><img src="/docs/public/images/nativephp-logo.svg" width="300" alt="NativePHP Logo" /></a>
|
||||||
|
|
||||||
## Open-Source License
|
## Open-Source License
|
||||||
|
|
||||||
This project itself is based on MIT License,
|
This project itself is based on MIT License,
|
||||||
|
|||||||
@ -64,7 +64,7 @@ fi
|
|||||||
# Detect docker env is setup
|
# Detect docker env is setup
|
||||||
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION; 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 ..."
|
echo "Docker container does not exist. Building docker image ..."
|
||||||
$DOCKER_EXECUTABLE buildx build $PLATFORM_ARG --no-cache -t cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
|
$DOCKER_EXECUTABLE buildx build $PLATFORM_ARG -t cwcc-spc-gnu-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
|
||||||
FROM centos:7
|
FROM centos:7
|
||||||
RUN sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo && \
|
RUN sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo && \
|
||||||
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
|
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
|
||||||
@ -96,7 +96,7 @@ RUN curl -fsSL -o patchelf.tgz https://github.com/NixOS/patchelf/releases/downlo
|
|||||||
tar -xzf patchelf.tgz -C /patchelf --strip-components=1 && \
|
tar -xzf patchelf.tgz -C /patchelf --strip-components=1 && \
|
||||||
cp /patchelf/bin/patchelf /usr/bin/
|
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-$SPC_USE_ARCH.tar.gz && \
|
RUN curl -o cmake.tgz -#fSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$SPC_USE_ARCH.tar.gz && \
|
||||||
mkdir /cmake && \
|
mkdir /cmake && \
|
||||||
tar -xzf cmake.tgz -C /cmake --strip-components 1
|
tar -xzf cmake.tgz -C /cmake --strip-components 1
|
||||||
|
|
||||||
@ -107,8 +107,8 @@ ADD ./bin/setup-runtime /app/bin/setup-runtime
|
|||||||
ADD ./bin/spc /app/bin/spc
|
ADD ./bin/spc /app/bin/spc
|
||||||
RUN /app/bin/setup-runtime
|
RUN /app/bin/setup-runtime
|
||||||
RUN /app/bin/php /app/bin/composer install --no-dev
|
RUN /app/bin/php /app/bin/composer install --no-dev
|
||||||
ENV PATH="/app/bin:/cmake/bin:$PATH"
|
|
||||||
ENV SPC_LIBC=glibc
|
ENV SPC_LIBC=glibc
|
||||||
|
ENV PATH="/app/bin:/cmake/bin:/opt/rh/devtoolset-10/root/usr/bin:\$PATH"
|
||||||
|
|
||||||
ADD ./config/env.ini /app/config/env.ini
|
ADD ./config/env.ini /app/config/env.ini
|
||||||
RUN CC=gcc bin/spc doctor --auto-fix --debug
|
RUN CC=gcc bin/spc doctor --auto-fix --debug
|
||||||
@ -128,7 +128,6 @@ RUN curl -o automake.tgz -fsSL https://ftp.gnu.org/gnu/automake/automake-1.17.ta
|
|||||||
make && \
|
make && \
|
||||||
make install && \
|
make install && \
|
||||||
ln -sf /usr/local/bin/automake /usr/bin/automake
|
ln -sf /usr/local/bin/automake /usr/bin/automake
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -154,11 +153,7 @@ if [ -f "$(pwd)/craft.yml" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Apply env in temp env file
|
# Apply env in temp env file
|
||||||
echo 'CC=/opt/rh/devtoolset-10/root/usr/bin/gcc' > /tmp/spc-gnu-docker.env
|
echo 'SPC_DEFAULT_C_FLAGS=-fPIC' > /tmp/spc-gnu-docker.env
|
||||||
echo 'CXX=/opt/rh/devtoolset-10/root/usr/bin/g++' >> /tmp/spc-gnu-docker.env
|
|
||||||
echo 'AR=/opt/rh/devtoolset-10/root/usr/bin/ar' >> /tmp/spc-gnu-docker.env
|
|
||||||
echo 'LD=/opt/rh/devtoolset-10/root/usr/bin/ld' >> /tmp/spc-gnu-docker.env
|
|
||||||
echo 'SPC_DEFAULT_C_FLAGS=-fPIC' >> /tmp/spc-gnu-docker.env
|
|
||||||
echo 'SPC_LIBC=glibc' >> /tmp/spc-gnu-docker.env
|
echo 'SPC_LIBC=glibc' >> /tmp/spc-gnu-docker.env
|
||||||
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-Wl,-O1 -pie"' >> /tmp/spc-gnu-docker.env
|
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-Wl,-O1 -pie"' >> /tmp/spc-gnu-docker.env
|
||||||
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm -lresolv -lutil -lrt"' >> /tmp/spc-gnu-docker.env
|
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm -lresolv -lutil -lrt"' >> /tmp/spc-gnu-docker.env
|
||||||
|
|||||||
@ -55,6 +55,8 @@ SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/frankenphp/cadd
|
|||||||
; EXTENSION_DIR=
|
; EXTENSION_DIR=
|
||||||
|
|
||||||
[windows]
|
[windows]
|
||||||
|
; build target: win7-static
|
||||||
|
SPC_TARGET=native-windows
|
||||||
; php-sdk-binary-tools path
|
; php-sdk-binary-tools path
|
||||||
PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools"
|
PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools"
|
||||||
; upx executable path
|
; upx executable path
|
||||||
@ -63,6 +65,17 @@ UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe"
|
|||||||
SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static
|
SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,cli_static
|
||||||
|
|
||||||
[linux]
|
[linux]
|
||||||
|
; Linux can use different build toolchain, but the toolchain can not be changed in this file:
|
||||||
|
; - musl (default): used for general linux distros, can build `musl-static` target only.
|
||||||
|
; - zig (WIP): used for general linux distros, can build `musl` and `glibc` targets.
|
||||||
|
; - musl-native: used for alpine linux, can build `musl-static` and `musl`(WIP) target.
|
||||||
|
; - gnu-native (assume): used for general linux distros, can build `glibc` target only and have portability issues.
|
||||||
|
|
||||||
|
; build target:
|
||||||
|
; - musl-static (default): pure static linking, using musl-libc, can run on any linux distro.
|
||||||
|
; - musl: static linking with dynamic linking to musl-libc, can run on musl-based linux distro.
|
||||||
|
; - glibc: static linking with dynamic linking to glibc, can run on glibc-based linux distro.
|
||||||
|
|
||||||
; include PATH for musl libc.
|
; include PATH for musl libc.
|
||||||
SPC_LIBC=musl
|
SPC_LIBC=musl
|
||||||
SPC_LIBC_VERSION=
|
SPC_LIBC_VERSION=
|
||||||
@ -80,7 +93,7 @@ SPC_EXTRA_LIBS=
|
|||||||
; upx executable path
|
; upx executable path
|
||||||
UPX_EXEC=${PKG_ROOT_PATH}/bin/upx
|
UPX_EXEC=${PKG_ROOT_PATH}/bin/upx
|
||||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||||
SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream
|
SPC_MICRO_PATCHES=cli_checks,disable_huge_page
|
||||||
|
|
||||||
; *** default build command for building php ***
|
; *** default build command for building php ***
|
||||||
; buildconf command
|
; buildconf command
|
||||||
@ -111,6 +124,9 @@ SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
|
|||||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -pie"
|
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -pie"
|
||||||
|
|
||||||
[macos]
|
[macos]
|
||||||
|
; build target: macho or macho (possibly we could support macho-universal in the future)
|
||||||
|
; Currently we do not support universal and cross-compilation for macOS.
|
||||||
|
SPC_TARGET=native-macos
|
||||||
; compiler environments
|
; compiler environments
|
||||||
CC=clang
|
CC=clang
|
||||||
CXX=clang++
|
CXX=clang++
|
||||||
@ -120,7 +136,7 @@ SPC_DEFAULT_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os"
|
|||||||
; extra libs for building php executable, used in `make` command for building php (this value may changed by extension build process, space separated)
|
; extra libs for building php executable, used in `make` command for building php (this value may changed by extension build process, space separated)
|
||||||
SPC_EXTRA_LIBS=
|
SPC_EXTRA_LIBS=
|
||||||
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
|
||||||
SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime140,win32,zend_stream,macos_iconv
|
SPC_MICRO_PATCHES=cli_checks,macos_iconv
|
||||||
|
|
||||||
; *** default build command for building php ***
|
; *** default build command for building php ***
|
||||||
; buildconf command
|
; buildconf command
|
||||||
|
|||||||
@ -47,6 +47,10 @@ export default {
|
|||||||
nav: [],
|
nav: [],
|
||||||
socialLinks: [
|
socialLinks: [
|
||||||
{icon: 'github', link: 'https://github.com/crazywhalecc/static-php-cli'}
|
{icon: 'github', link: 'https://github.com/crazywhalecc/static-php-cli'}
|
||||||
]
|
],
|
||||||
|
footer: {
|
||||||
|
message: 'Released under the MIT License.',
|
||||||
|
copyright: 'Copyright © 2023-present crazywhalecc'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
import DefaultTheme from 'vitepress/theme'
|
import DefaultTheme from 'vitepress/theme'
|
||||||
import {inBrowser, useData} from "vitepress";
|
import {inBrowser, useData} from "vitepress";
|
||||||
import {watchEffect} from "vue";
|
import {watchEffect} from "vue";
|
||||||
|
import './style.css';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
...DefaultTheme,
|
...DefaultTheme,
|
||||||
@ -13,4 +14,4 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
docs/.vitepress/theme/style.css
Normal file
6
docs/.vitepress/theme/style.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/** override default styles */
|
||||||
|
.vp-sponsor-grid-image {
|
||||||
|
max-height:36px !important;
|
||||||
|
max-width: 1000px !important;
|
||||||
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ and this extension cannot be compiled into php by static linking, so it cannot b
|
|||||||
|
|
||||||
## xdebug
|
## xdebug
|
||||||
|
|
||||||
1. Xdebug is only buildable as a shared extension. On Linux, you need to use static-php-cli with SPC_LIBC=glibc.
|
1. Xdebug is only buildable as a shared extension. You need to use a build target other than `musl-static` for SPC_TARGET.
|
||||||
2. When using Linux/glibc or macOS, you can compile Xdebug as a shared extension using --build-shared="xdebug".
|
2. When using Linux/glibc or macOS, you can compile Xdebug as a shared extension using --build-shared="xdebug".
|
||||||
The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`.
|
The compiled `./php` binary can be configured and run by specifying the INI, eg `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`.
|
||||||
|
|
||||||
|
|||||||
@ -21,3 +21,16 @@ features:
|
|||||||
- title: Dependency Management
|
- title: Dependency Management
|
||||||
details: static-php-cli comes with dependency management and supports installation of different types of PHP extensions.
|
details: static-php-cli comes with dependency management and supports installation of different types of PHP extensions.
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {VPSponsors} from "vitepress/theme";
|
||||||
|
const sponsors = [
|
||||||
|
{ name: 'Beyond Code', img: '/images/beyondcode-seeklogo.png', url: 'https://beyondco.de/' },
|
||||||
|
{ name: 'NativePHP', img: '/images/nativephp-logo.svg', url: 'https://nativephp.com/' },
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
## Special Sponsors
|
||||||
|
|
||||||
|
<VPSponsors :data="sponsors"/>
|
||||||
|
|
||||||
|
|||||||
BIN
docs/public/images/beyondcode-seeklogo.png
Normal file
BIN
docs/public/images/beyondcode-seeklogo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
6
docs/public/images/nativephp-logo.svg
Normal file
6
docs/public/images/nativephp-logo.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764 100">
|
||||||
|
<path fill="#505b93" d="M29.5,98.4H0V1.2h29.5V98.4z"/>
|
||||||
|
<path fill="#00aaa6" d="M96.7,98.4H67.2V1.2h29.5V98.4z"/>
|
||||||
|
<path fill="#272d48" d="M96.7,98.4H29.5V1.2L96.7,98.4z"/>
|
||||||
|
<path fill="#272d48" d="M102.6,54.5c0-6.2,1.3-11.8,4.1-16.7c2.7-5,6.7-8.8,11.9-11.6c5.2-2.8,11.4-4.2,18.6-4.2c1.1,0,2.8,0.1,5.2,0.3 c4.9,0.4,9.1,1.3,12.5,2.8c3.4,1.5,6.4,3.4,9.1,5.9v-7.2h25.8v74.7h-25.8v-7.2c-2.5,2.6-5.6,4.6-9.4,6.1c-3.8,1.5-7.9,2.4-12.1,2.6 c-0.9,0.1-2.3,0.1-4.1,0.1c-7.2,0-13.4-1.4-18.8-4.1c-5.4-2.7-9.5-6.6-12.4-11.5c-2.9-4.9-4.3-10.5-4.3-16.6V54.5z M128.4,63.9 c0,9.2,5.9,13.8,17.7,13.8c11.8,0,17.7-4.6,17.7-13.8v-5.6c0-9.3-5.9-14-17.7-14c-11.8,0-17.7,4.7-17.7,14V63.9z M208.3,98.4V47h-12.8V23.7l12.8-0.2V1.2h25.9l0.1,22.4h18.3V47h-18.4v51.4 M287.3,98.4h-25.9V23.6h25.9V98.4z M351,98.4H325l-31-74.8H320L338,68l18-44.5h25.9L351,98.4z M454.9,87.6c-4.1,4.2-8.8,7.3-14.1,9.3c-5.3,2-11.8,2.9-19.5,2.9c-8,0-15.1-1.4-21.3-4.2 c-6.2-2.8-11.1-6.7-14.7-11.6c-3.5-5-5.3-10.6-5.3-17V54.6c0-6.5,1.7-12.2,5.2-17.1c3.4-4.9,8.2-8.7,14.2-11.3c6-2.7,12.7-4,20-4 c8,0,15,1.5,21.2,4.3c6.1,2.9,10.9,7,14.4,12.4c3.4,5.4,5.2,11.6,5.2,18.7c0,1.7-0.2,4.2-0.7,7.7l-54.2,0.1v2.1 c0,4.1,1.5,7.3,4.4,9.4c2.9,2.2,6.9,3.2,11.8,3.2c4.6,0,8.5-0.6,11.8-1.8c3.2-1.2,6.4-3.5,9.4-6.8L454.9,87.6z M434.4,51.4 c0-3.1-1.4-5.5-4.2-7.1c-2.8-1.6-6.4-2.4-10.8-2.4s-7.9,0.8-10.5,2.4c-2.6,1.6-3.8,4-3.8,7.1H434.4z M466,98.4V1.2h56c9.9,0,17.8,1.9,23.7,5.6c5.9,3.7,10,8.2,12.2,13.3c2.3,5.1,3.4,10.1,3.4,15 c0,4.8-1.2,9.7-3.5,14.7c-2.3,5-6.4,9.2-12.2,12.8c-5.8,3.6-13.7,5.4-23.7,5.4h-30.2v30.5H466z M522,44.6c9,0,13.6-3.3,13.6-9.9 c0-6.9-4.6-10.3-13.7-10.3h-30.1v20.2H522z M593,98.4h-25.8V1.2H593v38h43.9v-38h25.8v97.2h-25.8V59.9H593V98.4z M668.6,98.4V1.2h56c9.9,0,17.8,1.9,23.7,5.6c5.9,3.7,10,8.2,12.2,13.3c2.3,5.1,3.4,10.1,3.4,15 c0,4.8-1.2,9.7-3.5,14.7c-2.3,5-6.4,9.2-12.2,12.8c-5.8,3.6-13.7,5.4-23.7,5.4h-30.2v30.5H668.6z M724.6,44.6c9,0,13.6-3.3,13.6-9.9 c0-6.9-4.6-10.3-13.7-10.3h-30.1v20.2H724.6z M291.1,20.2h-33.5V0h33.5V20.2z"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
@ -76,7 +76,7 @@ bin/spc build gd --with-libs=freetype,libjpeg,libavif,libwebp --build-cli
|
|||||||
|
|
||||||
## xdebug
|
## xdebug
|
||||||
|
|
||||||
1. Xdebug 只能作为共享扩展进行构建。在 Linux 上,您需要使用 static-php-cli 并设置 SPC_LIBC=glibc。
|
1. Xdebug 只能作为共享扩展进行构建。您需要使用除了 `musl-static` 外的其他 `SPC_TARGET` 构建目标。
|
||||||
2. 使用 Linux/glibc 或 macOS 时,您可以使用 `--build-shared=xdebug` 将 Xdebug 编译为共享扩展。
|
2. 使用 Linux/glibc 或 macOS 时,您可以使用 `--build-shared=xdebug` 将 Xdebug 编译为共享扩展。
|
||||||
编译后的 `./php` 二进制文件可以通过指定 INI 文件进行配置和运行,例如 `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`。
|
编译后的 `./php` 二进制文件可以通过指定 INI 文件进行配置和运行,例如 `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`。
|
||||||
|
|
||||||
|
|||||||
@ -4,5 +4,6 @@
|
|||||||
>
|
>
|
||||||
<php>
|
<php>
|
||||||
<env name="SPC_IGNORE_BAD_HASH" value="yes" force="true" />
|
<env name="SPC_IGNORE_BAD_HASH" value="yes" force="true" />
|
||||||
|
<env name="SPC_SKIP_TOOLCHAIN_CHECK" value="yes" force="true" />
|
||||||
</php>
|
</php>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|||||||
@ -9,6 +9,7 @@ use SPC\command\BuildPHPCommand;
|
|||||||
use SPC\command\CraftCommand;
|
use SPC\command\CraftCommand;
|
||||||
use SPC\command\DeleteDownloadCommand;
|
use SPC\command\DeleteDownloadCommand;
|
||||||
use SPC\command\dev\AllExtCommand;
|
use SPC\command\dev\AllExtCommand;
|
||||||
|
use SPC\command\dev\EnvCommand;
|
||||||
use SPC\command\dev\ExtVerCommand;
|
use SPC\command\dev\ExtVerCommand;
|
||||||
use SPC\command\dev\GenerateExtDepDocsCommand;
|
use SPC\command\dev\GenerateExtDepDocsCommand;
|
||||||
use SPC\command\dev\GenerateExtDocCommand;
|
use SPC\command\dev\GenerateExtDocCommand;
|
||||||
@ -70,6 +71,7 @@ final class ConsoleApplication extends Application
|
|||||||
new GenerateExtDepDocsCommand(),
|
new GenerateExtDepDocsCommand(),
|
||||||
new GenerateLibDepDocsCommand(),
|
new GenerateLibDepDocsCommand(),
|
||||||
new PackLibCommand(),
|
new PackLibCommand(),
|
||||||
|
new EnvCommand(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ use SPC\store\Config;
|
|||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\LockFile;
|
use SPC\store\LockFile;
|
||||||
use SPC\store\SourceManager;
|
use SPC\store\SourceManager;
|
||||||
|
use SPC\store\SourcePatcher;
|
||||||
use SPC\util\CustomExt;
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
abstract class BuilderBase
|
abstract class BuilderBase
|
||||||
@ -203,6 +204,8 @@ abstract class BuilderBase
|
|||||||
$this->emitPatchPoint('before-exts-extract');
|
$this->emitPatchPoint('before-exts-extract');
|
||||||
SourceManager::initSource(exts: [...$static_extensions, ...$shared_extensions]);
|
SourceManager::initSource(exts: [...$static_extensions, ...$shared_extensions]);
|
||||||
$this->emitPatchPoint('after-exts-extract');
|
$this->emitPatchPoint('after-exts-extract');
|
||||||
|
// patch micro
|
||||||
|
SourcePatcher::patchMicro();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ([...$static_extensions, ...$shared_extensions] as $extension) {
|
foreach ([...$static_extensions, ...$shared_extensions] as $extension) {
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use SPC\exception\WrongUsageException;
|
|||||||
use SPC\store\Config;
|
use SPC\store\Config;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\SPCConfigUtil;
|
use SPC\util\SPCConfigUtil;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
class Extension
|
class Extension
|
||||||
{
|
{
|
||||||
@ -545,6 +546,11 @@ class Extension
|
|||||||
$sharedLibString .= '-l' . $lib . ' ';
|
$sharedLibString .= '-l' . $lib . ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// move static libstdc++ to shared if we are on non-full-static build target
|
||||||
|
if (!SPCTarget::isStatic() && in_array(SPCTarget::getLibc(), SPCTarget::LIBC_LIST)) {
|
||||||
|
$staticLibString .= ' -lstdc++';
|
||||||
|
$sharedLibString = str_replace('-lstdc++', '', $sharedLibString);
|
||||||
|
}
|
||||||
return [trim($staticLibString), trim($sharedLibString)];
|
return [trim($staticLibString), trim($sharedLibString)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,17 +12,7 @@ class imagick extends Extension
|
|||||||
{
|
{
|
||||||
public function getUnixConfigureArg(bool $shared = false): string
|
public function getUnixConfigureArg(bool $shared = false): string
|
||||||
{
|
{
|
||||||
return '--with-imagick=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . ' ac_cv_func_omp_pause_resource_all=no';
|
$disable_omp = ' ac_cv_func_omp_pause_resource_all=no';
|
||||||
}
|
return '--with-imagick=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . $disable_omp;
|
||||||
|
|
||||||
protected function getStaticAndSharedLibs(): array
|
|
||||||
{
|
|
||||||
// on centos 7, it will use the symbol _ZTINSt6thread6_StateE, which is not defined in system libstdc++.so.6
|
|
||||||
[$static, $shared] = parent::getStaticAndSharedLibs();
|
|
||||||
if (str_contains(getenv('CC'), 'devtoolset-10')) {
|
|
||||||
$static .= ' -lstdc++';
|
|
||||||
$shared = str_replace('-lstdc++', '', $shared);
|
|
||||||
}
|
|
||||||
return [$static, $shared];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,22 +25,8 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
{
|
{
|
||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
|
|
||||||
// check musl-cross make installed if we use musl-cross-make
|
|
||||||
$arch = arch2gnu(php_uname('m'));
|
|
||||||
|
|
||||||
GlobalEnvManager::init();
|
GlobalEnvManager::init();
|
||||||
|
GlobalEnvManager::afterInit();
|
||||||
if (getenv('SPC_LIBC') === 'musl' && !SystemUtil::isMuslDist() && !str_contains((string) getenv('CC'), 'zig')) {
|
|
||||||
$this->setOptionIfNotExist('library_path', "LIBRARY_PATH=\"/usr/local/musl/{$arch}-linux-musl/lib\"");
|
|
||||||
$this->setOptionIfNotExist('ld_library_path', "LD_LIBRARY_PATH=\"/usr/local/musl/{$arch}-linux-musl/lib\"");
|
|
||||||
$configure = getenv('SPC_CMD_PREFIX_PHP_CONFIGURE');
|
|
||||||
$configure = "LD_LIBRARY_PATH=\"/usr/local/musl/{$arch}-linux-musl/lib\" " . $configure;
|
|
||||||
GlobalEnvManager::putenv("SPC_CMD_PREFIX_PHP_CONFIGURE={$configure}");
|
|
||||||
|
|
||||||
if (!file_exists("/usr/local/musl/{$arch}-linux-musl/lib/libc.a")) {
|
|
||||||
throw new WrongUsageException('You are building with musl-libc target in glibc distro, but musl-toolchain is not installed, please install musl-toolchain first. (You can use `doctor` command to install it)');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// concurrency
|
// concurrency
|
||||||
$this->concurrency = intval(getenv('SPC_CONCURRENCY'));
|
$this->concurrency = intval(getenv('SPC_CONCURRENCY'));
|
||||||
@ -104,10 +90,6 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
$zts = '';
|
$zts = '';
|
||||||
}
|
}
|
||||||
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';
|
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';
|
||||||
$cc = trim(getenv('CC'));
|
|
||||||
if (!$disable_jit && $this->getExt('opcache') && str_contains($cc, 'zig')) {
|
|
||||||
f_putenv("CC={$cc} -fno-sanitize=undefined");
|
|
||||||
}
|
|
||||||
|
|
||||||
$config_file_path = $this->getOption('with-config-file-path', false) ?
|
$config_file_path = $this->getOption('with-config-file-path', false) ?
|
||||||
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
||||||
@ -139,9 +121,6 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
$embed_type = getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') ?: 'static';
|
$embed_type = getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') ?: 'static';
|
||||||
if ($embed_type !== 'static' && getenv('SPC_LIBC') === 'musl' && getenv('SPC_LIBC_LINKAGE') === '-static') {
|
|
||||||
throw new WrongUsageException('Musl libc does not support dynamic linking of PHP embed!');
|
|
||||||
}
|
|
||||||
shell()->cd(SOURCE_PATH . '/php-src')
|
shell()->cd(SOURCE_PATH . '/php-src')
|
||||||
->exec(
|
->exec(
|
||||||
getenv('SPC_CMD_PREFIX_PHP_CONFIGURE') . ' ' .
|
getenv('SPC_CMD_PREFIX_PHP_CONFIGURE') . ' ' .
|
||||||
@ -183,9 +162,6 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
}
|
}
|
||||||
$this->buildEmbed();
|
$this->buildEmbed();
|
||||||
}
|
}
|
||||||
if (!$disable_jit && $this->getExt('opcache') && str_contains($cc, 'zig')) {
|
|
||||||
f_putenv("CC={$cc}");
|
|
||||||
}
|
|
||||||
if ($enableFrankenphp) {
|
if ($enableFrankenphp) {
|
||||||
logger()->info('building frankenphp');
|
logger()->info('building frankenphp');
|
||||||
$this->buildFrankenphp();
|
$this->buildFrankenphp();
|
||||||
|
|||||||
@ -192,12 +192,12 @@ class SystemUtil
|
|||||||
/**
|
/**
|
||||||
* Get libc version string from ldd
|
* Get libc version string from ldd
|
||||||
*/
|
*/
|
||||||
public static function getLibcVersionIfExists(): ?string
|
public static function getLibcVersionIfExists(string $libc): ?string
|
||||||
{
|
{
|
||||||
if (self::$libc_version !== null) {
|
if (self::$libc_version !== null) {
|
||||||
return self::$libc_version;
|
return self::$libc_version;
|
||||||
}
|
}
|
||||||
if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'glibc') {
|
if ($libc === 'glibc') {
|
||||||
$result = shell()->execWithResult('ldd --version', false);
|
$result = shell()->execWithResult('ldd --version', false);
|
||||||
if ($result[0] !== 0) {
|
if ($result[0] !== 0) {
|
||||||
return null;
|
return null;
|
||||||
@ -212,7 +212,7 @@ class SystemUtil
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') {
|
if ($libc === 'musl') {
|
||||||
if (self::isMuslDist()) {
|
if (self::isMuslDist()) {
|
||||||
$result = shell()->execWithResult('ldd 2>&1', false);
|
$result = shell()->execWithResult('ldd 2>&1', false);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace SPC\builder\linux\library;
|
namespace SPC\builder\linux\library;
|
||||||
|
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
class icu extends LinuxLibraryBase
|
class icu extends LinuxLibraryBase
|
||||||
{
|
{
|
||||||
@ -16,7 +17,7 @@ class icu extends LinuxLibraryBase
|
|||||||
{
|
{
|
||||||
$cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1 -DPIC -fPIC"';
|
$cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1 -DPIC -fPIC"';
|
||||||
$cxxflags = 'CXXFLAGS="-std=c++17 -DPIC -fPIC -fno-ident"';
|
$cxxflags = 'CXXFLAGS="-std=c++17 -DPIC -fPIC -fno-ident"';
|
||||||
$ldflags = getenv('SPC_LIBC') !== 'glibc' ? 'LDFLAGS="-static"' : '';
|
$ldflags = SPCTarget::isStatic() ? 'LDFLAGS="-static"' : '';
|
||||||
shell()->cd($this->source_dir . '/source')->initializeEnv($this)
|
shell()->cd($this->source_dir . '/source')->initializeEnv($this)
|
||||||
->exec(
|
->exec(
|
||||||
"{$cppflags} {$cxxflags} {$ldflags} " .
|
"{$cppflags} {$cxxflags} {$ldflags} " .
|
||||||
|
|||||||
@ -29,6 +29,7 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
|
|
||||||
// apply global environment variables
|
// apply global environment variables
|
||||||
GlobalEnvManager::init();
|
GlobalEnvManager::init();
|
||||||
|
GlobalEnvManager::afterInit();
|
||||||
|
|
||||||
// ---------- set necessary compile vars ----------
|
// ---------- set necessary compile vars ----------
|
||||||
// concurrency
|
// concurrency
|
||||||
|
|||||||
@ -19,6 +19,7 @@ use SPC\store\pkg\GoXcaddy;
|
|||||||
use SPC\util\DependencyUtil;
|
use SPC\util\DependencyUtil;
|
||||||
use SPC\util\GlobalEnvManager;
|
use SPC\util\GlobalEnvManager;
|
||||||
use SPC\util\SPCConfigUtil;
|
use SPC\util\SPCConfigUtil;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
abstract class UnixBuilderBase extends BuilderBase
|
abstract class UnixBuilderBase extends BuilderBase
|
||||||
{
|
{
|
||||||
@ -202,16 +203,8 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
$util = new SPCConfigUtil($this);
|
$util = new SPCConfigUtil($this);
|
||||||
$config = $util->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
|
$config = $util->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
|
||||||
$lens = "{$config['cflags']} {$config['ldflags']} {$config['libs']}";
|
$lens = "{$config['cflags']} {$config['ldflags']} {$config['libs']}";
|
||||||
$lens .= ' ' . getenv('SPC_LIBC_LINKAGE');
|
if (SPCTarget::isStatic()) {
|
||||||
// if someone changed to EMBED_TYPE=shared, we need to add LD_LIBRARY_PATH
|
$lens .= ' -static';
|
||||||
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
|
|
||||||
$ext_path = 'LD_LIBRARY_PATH=' . BUILD_LIB_PATH . ':$LD_LIBRARY_PATH ';
|
|
||||||
FileSystem::removeFileIfExists(BUILD_LIB_PATH . '/libphp.a');
|
|
||||||
} else {
|
|
||||||
$ext_path = '';
|
|
||||||
foreach (glob(BUILD_LIB_PATH . '/libphp*.so') as $file) {
|
|
||||||
unlink($file);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
[$ret, $out] = shell()->cd($sample_file_path)->execWithResult(getenv('CC') . ' -o embed embed.c ' . $lens);
|
[$ret, $out] = shell()->cd($sample_file_path)->execWithResult(getenv('CC') . ' -o embed embed.c ' . $lens);
|
||||||
if ($ret !== 0) {
|
if ($ret !== 0) {
|
||||||
@ -327,8 +320,7 @@ abstract class UnixBuilderBase extends BuilderBase
|
|||||||
$debugFlags = $this->getOption('no-strip') ? "'-w -s' " : '';
|
$debugFlags = $this->getOption('no-strip') ? "'-w -s' " : '';
|
||||||
$extLdFlags = "-extldflags '-pie'";
|
$extLdFlags = "-extldflags '-pie'";
|
||||||
$muslTags = '';
|
$muslTags = '';
|
||||||
$staticFlags = '';
|
if (SPCTarget::isStatic()) {
|
||||||
if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl' && getenv('SPC_LIBC_LINKAGE') === 'static') {
|
|
||||||
$extLdFlags = "-extldflags '-static-pie -Wl,-z,stack-size=0x80000'";
|
$extLdFlags = "-extldflags '-static-pie -Wl,-z,stack-size=0x80000'";
|
||||||
$muslTags = 'static_build,';
|
$muslTags = 'static_build,';
|
||||||
$staticFlags = '-static -static-pie';
|
$staticFlags = '-static -static-pie';
|
||||||
|
|||||||
@ -4,18 +4,19 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
|
||||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\executor\UnixAutoconfExecutor;
|
use SPC\util\executor\UnixAutoconfExecutor;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
trait imagemagick
|
trait imagemagick
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
protected function build(): void
|
protected function build(): void
|
||||||
{
|
{
|
||||||
@ -37,11 +38,11 @@ trait imagemagick
|
|||||||
'--without-x',
|
'--without-x',
|
||||||
);
|
);
|
||||||
|
|
||||||
// special: linux musl needs `-static`
|
// special: linux-static target needs `-static`
|
||||||
$ldflags = ($this instanceof LinuxLibraryBase) && getenv('SPC_LIBC') !== 'glibc' ? ('-static -ldl') : '-ldl';
|
$ldflags = SPCTarget::isStatic() ? ('-static -ldl') : '-ldl';
|
||||||
|
|
||||||
// special: macOS needs -iconv
|
// special: macOS needs -iconv
|
||||||
$libs = $this instanceof MacOSLibraryBase ? '-liconv' : '';
|
$libs = SPCTarget::getTargetOS() === 'Darwin' ? '-liconv' : '';
|
||||||
|
|
||||||
$ac->appendEnv([
|
$ac->appendEnv([
|
||||||
'LDFLAGS' => $ldflags,
|
'LDFLAGS' => $ldflags,
|
||||||
|
|||||||
@ -6,12 +6,13 @@ namespace SPC\builder\unix\library;
|
|||||||
|
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\util\executor\UnixAutoconfExecutor;
|
use SPC\util\executor\UnixAutoconfExecutor;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
trait ldap
|
trait ldap
|
||||||
{
|
{
|
||||||
public function patchBeforeBuild(): bool
|
public function patchBeforeBuild(): bool
|
||||||
{
|
{
|
||||||
$extra = getenv('SPC_LIBC') === 'glibc' ? '-ldl -lpthread -lm -lresolv -lutil' : '';
|
$extra = SPCTarget::getLibc() === 'glibc' ? '-ldl -lpthread -lm -lresolv -lutil' : '';
|
||||||
FileSystem::replaceFileStr($this->source_dir . '/configure', '"-lssl -lcrypto', '"-lssl -lcrypto -lz ' . $extra);
|
FileSystem::replaceFileStr($this->source_dir . '/configure', '"-lssl -lcrypto', '"-lssl -lcrypto -lz ' . $extra);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,13 @@ trait libxslt
|
|||||||
'--without-debugger',
|
'--without-debugger',
|
||||||
"--with-libxml-prefix={$this->getBuildRootPath()}",
|
"--with-libxml-prefix={$this->getBuildRootPath()}",
|
||||||
);
|
);
|
||||||
$ac->exec("{$this->builder->getOption('library_path')} {$this->builder->getOption('ld_library_path')} ./configure {$ac->getConfigureArgsString()}")->make();
|
if (getenv('SPC_LINUX_DEFAULT_LD_LIBRARY_PATH') && getenv('SPC_LINUX_DEFAULT_LIBRARY_PATH')) {
|
||||||
|
$ac->appendEnv([
|
||||||
|
'LD_LIBRARY_PATH' => getenv('SPC_LINUX_DEFAULT_LD_LIBRARY_PATH'),
|
||||||
|
'LIBRARY_PATH' => getenv('SPC_LINUX_DEFAULT_LIBRARY_PATH'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$ac->configure()->make();
|
||||||
|
|
||||||
$this->patchPkgconfPrefix(['libexslt.pc']);
|
$this->patchPkgconfPrefix(['libexslt.pc']);
|
||||||
$this->patchLaDependencyPrefix();
|
$this->patchLaDependencyPrefix();
|
||||||
|
|||||||
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
use SPC\util\executor\UnixCMakeExecutor;
|
use SPC\util\executor\UnixCMakeExecutor;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
trait mimalloc
|
trait mimalloc
|
||||||
{
|
{
|
||||||
@ -13,9 +14,9 @@ trait mimalloc
|
|||||||
$cmake = UnixCMakeExecutor::create($this)
|
$cmake = UnixCMakeExecutor::create($this)
|
||||||
->addConfigureArgs(
|
->addConfigureArgs(
|
||||||
'-DMI_BUILD_SHARED=OFF',
|
'-DMI_BUILD_SHARED=OFF',
|
||||||
'-DMI_INSTALL_TOPLEVEL=ON'
|
'-DMI_INSTALL_TOPLEVEL=ON',
|
||||||
);
|
);
|
||||||
if (getenv('SPC_LIBC') === 'musl') {
|
if (SPCTarget::getLibc() === 'musl') {
|
||||||
$cmake->addConfigureArgs('-DMI_LIBC_MUSL=ON');
|
$cmake->addConfigureArgs('-DMI_LIBC_MUSL=ON');
|
||||||
}
|
}
|
||||||
$cmake->build();
|
$cmake->build();
|
||||||
|
|||||||
@ -4,17 +4,17 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\builder\unix\library;
|
namespace SPC\builder\unix\library;
|
||||||
|
|
||||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
|
||||||
use SPC\util\executor\UnixAutoconfExecutor;
|
use SPC\util\executor\UnixAutoconfExecutor;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
trait pkgconfig
|
trait pkgconfig
|
||||||
{
|
{
|
||||||
protected function build(): void
|
protected function build(): void
|
||||||
{
|
{
|
||||||
UnixAutoconfExecutor::create($this)
|
UnixAutoconfExecutor::create($this)
|
||||||
->appendEnv([
|
->appendEnv([[
|
||||||
'CFLAGS' => '-Wimplicit-function-declaration -Wno-int-conversion',
|
'CFLAGS' => '-Wimplicit-function-declaration -Wno-int-conversion',
|
||||||
'LDFLAGS' => !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? '' : '--static',
|
'LDFLAGS' => SPCTarget::isStatic() ? '--static' : '',
|
||||||
])
|
])
|
||||||
->configure(
|
->configure(
|
||||||
'--with-internal-glib',
|
'--with-internal-glib',
|
||||||
|
|||||||
@ -8,6 +8,7 @@ use SPC\builder\linux\library\LinuxLibraryBase;
|
|||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
trait postgresql
|
trait postgresql
|
||||||
{
|
{
|
||||||
@ -50,7 +51,7 @@ trait postgresql
|
|||||||
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||||
if (!empty($output[1][0])) {
|
if (!empty($output[1][0])) {
|
||||||
$ldflags = $output[1][0];
|
$ldflags = $output[1][0];
|
||||||
$envs .= !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? " LDFLAGS=\"{$ldflags}\" " : " LDFLAGS=\"{$ldflags} -static\" ";
|
$envs .= SPCTarget::isStatic() ? " LDFLAGS=\"{$ldflags} -static\" " : " LDFLAGS=\"{$ldflags}\" ";
|
||||||
}
|
}
|
||||||
$output = shell()->execWithResult("pkg-config --libs-only-l --static {$packages}");
|
$output = shell()->execWithResult("pkg-config --libs-only-l --static {$packages}");
|
||||||
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class WindowsBuilder extends BuilderBase
|
|||||||
$this->options = $options;
|
$this->options = $options;
|
||||||
|
|
||||||
GlobalEnvManager::init();
|
GlobalEnvManager::init();
|
||||||
|
GlobalEnvManager::afterInit();
|
||||||
|
|
||||||
// ---------- set necessary options ----------
|
// ---------- set necessary options ----------
|
||||||
// set sdk (require visual studio 16 or 17)
|
// set sdk (require visual studio 16 or 17)
|
||||||
|
|||||||
@ -99,6 +99,7 @@ abstract class BaseCommand extends Command
|
|||||||
// init GlobalEnv
|
// init GlobalEnv
|
||||||
if (!$this instanceof BuildCommand) {
|
if (!$this instanceof BuildCommand) {
|
||||||
GlobalEnvManager::init();
|
GlobalEnvManager::init();
|
||||||
|
f_putenv('SPC_SKIP_TOOLCHAIN_CHECK=yes');
|
||||||
}
|
}
|
||||||
if ($this->shouldExecute()) {
|
if ($this->shouldExecute()) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ use SPC\store\SourcePatcher;
|
|||||||
use SPC\util\DependencyUtil;
|
use SPC\util\DependencyUtil;
|
||||||
use SPC\util\GlobalEnvManager;
|
use SPC\util\GlobalEnvManager;
|
||||||
use SPC\util\LicenseDumper;
|
use SPC\util\LicenseDumper;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
@ -63,8 +64,8 @@ class BuildPHPCommand extends BuildCommand
|
|||||||
|
|
||||||
// check dynamic extension build env
|
// check dynamic extension build env
|
||||||
// linux must build with glibc
|
// linux must build with glibc
|
||||||
if (!empty($shared_extensions) && PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') !== 'glibc' && getenv('SPC_LIBC_LINKAGE') === '-static') {
|
if (!empty($shared_extensions) && SPCTarget::isStatic()) {
|
||||||
$this->output->writeln('Linux does not support dynamic extension loading with musl-libc full-static build, please build with glibc!');
|
$this->output->writeln('Linux does not support dynamic extension loading with fully static builds, please build with a shared C runtime target!');
|
||||||
return static::FAILURE;
|
return static::FAILURE;
|
||||||
}
|
}
|
||||||
$static_and_shared = array_intersect($static_extensions, $shared_extensions);
|
$static_and_shared = array_intersect($static_extensions, $shared_extensions);
|
||||||
@ -133,6 +134,8 @@ class BuildPHPCommand extends BuildCommand
|
|||||||
// print info
|
// print info
|
||||||
$indent_texts = [
|
$indent_texts = [
|
||||||
'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')',
|
'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')',
|
||||||
|
'Build Target' => getenv('SPC_TARGET'),
|
||||||
|
'Build Toolchain' => getenv('SPC_TOOLCHAIN'),
|
||||||
'Build SAPI' => $builder->getBuildTypeName($rule),
|
'Build SAPI' => $builder->getBuildTypeName($rule),
|
||||||
'Static Extensions (' . count($static_extensions) . ')' => implode(',', $static_extensions),
|
'Static Extensions (' . count($static_extensions) . ')' => implode(',', $static_extensions),
|
||||||
'Shared Extensions (' . count($shared_extensions) . ')' => implode(',', $shared_extensions),
|
'Shared Extensions (' . count($shared_extensions) . ')' => implode(',', $shared_extensions),
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use Symfony\Component\Console\Attribute\AsCommand;
|
|||||||
use Symfony\Component\Process\Process;
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
#[AsCommand('craft', 'Build static-php from craft.yml')]
|
#[AsCommand('craft', 'Build static-php from craft.yml')]
|
||||||
class CraftCommand extends BaseCommand
|
class CraftCommand extends BuildCommand
|
||||||
{
|
{
|
||||||
public function configure(): void
|
public function configure(): void
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\command;
|
namespace SPC\command;
|
||||||
|
|
||||||
use SPC\builder\linux\SystemUtil;
|
|
||||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||||
use SPC\exception\DownloaderException;
|
use SPC\exception\DownloaderException;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
@ -14,6 +13,7 @@ use SPC\store\Config;
|
|||||||
use SPC\store\Downloader;
|
use SPC\store\Downloader;
|
||||||
use SPC\store\LockFile;
|
use SPC\store\LockFile;
|
||||||
use SPC\util\DependencyUtil;
|
use SPC\util\DependencyUtil;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
@ -223,8 +223,8 @@ class DownloadCommand extends BaseCommand
|
|||||||
'{name}' => $source,
|
'{name}' => $source,
|
||||||
'{arch}' => arch2gnu(php_uname('m')),
|
'{arch}' => arch2gnu(php_uname('m')),
|
||||||
'{os}' => strtolower(PHP_OS_FAMILY),
|
'{os}' => strtolower(PHP_OS_FAMILY),
|
||||||
'{libc}' => getenv('SPC_LIBC') ?: 'default',
|
'{libc}' => SPCTarget::getLibc() ?? 'default',
|
||||||
'{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default',
|
'{libcver}' => SPCTarget::getLibcVersion() ?? 'default',
|
||||||
];
|
];
|
||||||
$find = str_replace(array_keys($replace), array_values($replace), Config::getPreBuilt('match-pattern'));
|
$find = str_replace(array_keys($replace), array_values($replace), Config::getPreBuilt('match-pattern'));
|
||||||
// find filename in asset list
|
// find filename in asset list
|
||||||
|
|||||||
@ -11,7 +11,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
|||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
|
||||||
#[AsCommand('spc-config', 'Build dependencies')]
|
#[AsCommand('spc-config', 'Build dependencies')]
|
||||||
class SPCConfigCommand extends BuildCommand
|
class SPCConfigCommand extends BaseCommand
|
||||||
{
|
{
|
||||||
protected bool $no_motd = true;
|
protected bool $no_motd = true;
|
||||||
|
|
||||||
|
|||||||
37
src/SPC/command/dev/EnvCommand.php
Normal file
37
src/SPC/command/dev/EnvCommand.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\command\dev;
|
||||||
|
|
||||||
|
use SPC\command\BaseCommand;
|
||||||
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
#[AsCommand('dev:env', 'Returns the internally defined environment variables')]
|
||||||
|
class EnvCommand extends BaseCommand
|
||||||
|
{
|
||||||
|
public function configure()
|
||||||
|
{
|
||||||
|
$this->addArgument('env', InputArgument::REQUIRED, 'The environment variable to show, if not set, all will be shown');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function initialize(InputInterface $input, OutputInterface $output): void
|
||||||
|
{
|
||||||
|
$this->no_motd = true;
|
||||||
|
parent::initialize($input, $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handle(): int
|
||||||
|
{
|
||||||
|
$env = $this->getArgument('env');
|
||||||
|
if (($val = getenv($env)) === false) {
|
||||||
|
$this->output->writeln("<error>Environment variable '{$env}' is not set.</error>");
|
||||||
|
return static::FAILURE;
|
||||||
|
}
|
||||||
|
$this->output->writeln("<info>{$val}</info>");
|
||||||
|
return static::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,6 @@ namespace SPC\command\dev;
|
|||||||
|
|
||||||
use SPC\builder\BuilderProvider;
|
use SPC\builder\BuilderProvider;
|
||||||
use SPC\builder\LibraryBase;
|
use SPC\builder\LibraryBase;
|
||||||
use SPC\builder\linux\SystemUtil;
|
|
||||||
use SPC\command\BuildCommand;
|
use SPC\command\BuildCommand;
|
||||||
use SPC\exception\ExceptionHandler;
|
use SPC\exception\ExceptionHandler;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
@ -16,6 +15,7 @@ use SPC\store\Config;
|
|||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\LockFile;
|
use SPC\store\LockFile;
|
||||||
use SPC\util\DependencyUtil;
|
use SPC\util\DependencyUtil;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
|
||||||
@ -76,8 +76,8 @@ class PackLibCommand extends BuildCommand
|
|||||||
'{name}' => $lib->getName(),
|
'{name}' => $lib->getName(),
|
||||||
'{arch}' => arch2gnu(php_uname('m')),
|
'{arch}' => arch2gnu(php_uname('m')),
|
||||||
'{os}' => strtolower(PHP_OS_FAMILY),
|
'{os}' => strtolower(PHP_OS_FAMILY),
|
||||||
'{libc}' => getenv('SPC_LIBC') ?: 'default',
|
'{libc}' => SPCTarget::getLibc() ?? 'default',
|
||||||
'{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default',
|
'{libcver}' => SPCTarget::getLibcVersion() ?? 'default',
|
||||||
];
|
];
|
||||||
// detect suffix, for proper tar option
|
// detect suffix, for proper tar option
|
||||||
$tar_option = $this->getTarOptionFromSuffix(Config::getPreBuilt('match-pattern'));
|
$tar_option = $this->getTarOptionFromSuffix(Config::getPreBuilt('match-pattern'));
|
||||||
|
|||||||
@ -72,6 +72,14 @@ final class CheckListHandler
|
|||||||
{
|
{
|
||||||
foreach (FileSystem::getClassesPsr4(__DIR__ . '/item', 'SPC\doctor\item') as $class) {
|
foreach (FileSystem::getClassesPsr4(__DIR__ . '/item', 'SPC\doctor\item') as $class) {
|
||||||
$ref = new \ReflectionClass($class);
|
$ref = new \ReflectionClass($class);
|
||||||
|
$optional = $ref->getAttributes(OptionalCheck::class)[0] ?? null;
|
||||||
|
if ($optional !== null) {
|
||||||
|
/** @var OptionalCheck $instance */
|
||||||
|
$instance = $optional->newInstance();
|
||||||
|
if (is_callable($instance->check) && !call_user_func($instance->check)) {
|
||||||
|
continue; // skip this class if optional check is false
|
||||||
|
}
|
||||||
|
}
|
||||||
foreach ($ref->getMethods() as $method) {
|
foreach ($ref->getMethods() as $method) {
|
||||||
foreach ($method->getAttributes() as $a) {
|
foreach ($method->getAttributes() as $a) {
|
||||||
if (is_a($a->getName(), AsCheckItem::class, true)) {
|
if (is_a($a->getName(), AsCheckItem::class, true)) {
|
||||||
|
|||||||
11
src/SPC/doctor/OptionalCheck.php
Normal file
11
src/SPC/doctor/OptionalCheck.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\doctor;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
|
||||||
|
class OptionalCheck
|
||||||
|
{
|
||||||
|
public function __construct(public array $check) {}
|
||||||
|
}
|
||||||
@ -4,10 +4,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\doctor\item;
|
namespace SPC\doctor\item;
|
||||||
|
|
||||||
use SPC\builder\linux\SystemUtil;
|
|
||||||
use SPC\doctor\AsCheckItem;
|
use SPC\doctor\AsCheckItem;
|
||||||
use SPC\doctor\AsFixItem;
|
use SPC\doctor\AsFixItem;
|
||||||
use SPC\doctor\CheckResult;
|
use SPC\doctor\CheckResult;
|
||||||
|
use SPC\doctor\OptionalCheck;
|
||||||
use SPC\exception\DownloaderException;
|
use SPC\exception\DownloaderException;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
@ -16,23 +16,20 @@ use SPC\store\Downloader;
|
|||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\PackageManager;
|
use SPC\store\PackageManager;
|
||||||
use SPC\store\SourcePatcher;
|
use SPC\store\SourcePatcher;
|
||||||
|
use SPC\toolchain\MuslToolchain;
|
||||||
|
|
||||||
|
#[OptionalCheck([self::class, 'optionalCheck'])]
|
||||||
class LinuxMuslCheck
|
class LinuxMuslCheck
|
||||||
{
|
{
|
||||||
|
public static function optionalCheck(): bool
|
||||||
|
{
|
||||||
|
return getenv('SPC_TOOLCHAIN') === MuslToolchain::class;
|
||||||
|
}
|
||||||
|
|
||||||
/** @noinspection PhpUnused */
|
/** @noinspection PhpUnused */
|
||||||
#[AsCheckItem('if musl-wrapper is installed', limit_os: 'Linux', level: 800)]
|
#[AsCheckItem('if musl-wrapper is installed', limit_os: 'Linux', level: 800)]
|
||||||
public function checkMusl(): CheckResult
|
public function checkMusl(): CheckResult
|
||||||
{
|
{
|
||||||
if (SystemUtil::isMuslDist()) {
|
|
||||||
return CheckResult::ok('musl-based distro, skipped');
|
|
||||||
}
|
|
||||||
if (getenv('SPC_LIBC') === 'glibc') {
|
|
||||||
return CheckResult::ok('Building with glibc, skipped');
|
|
||||||
}
|
|
||||||
if (str_contains(getenv('CC'), 'zig')) {
|
|
||||||
return CheckResult::ok('Building with zig, skipped');
|
|
||||||
}
|
|
||||||
|
|
||||||
$musl_wrapper_lib = sprintf('/lib/ld-musl-%s.so.1', php_uname('m'));
|
$musl_wrapper_lib = sprintf('/lib/ld-musl-%s.so.1', php_uname('m'));
|
||||||
if (file_exists($musl_wrapper_lib) && file_exists('/usr/local/musl/lib/libc.a')) {
|
if (file_exists($musl_wrapper_lib) && file_exists('/usr/local/musl/lib/libc.a')) {
|
||||||
return CheckResult::ok();
|
return CheckResult::ok();
|
||||||
@ -43,16 +40,6 @@ class LinuxMuslCheck
|
|||||||
#[AsCheckItem('if musl-cross-make is installed', limit_os: 'Linux', level: 799)]
|
#[AsCheckItem('if musl-cross-make is installed', limit_os: 'Linux', level: 799)]
|
||||||
public function checkMuslCrossMake(): CheckResult
|
public function checkMuslCrossMake(): CheckResult
|
||||||
{
|
{
|
||||||
if (SystemUtil::isMuslDist()) {
|
|
||||||
return CheckResult::ok('musl-based distro, skipped');
|
|
||||||
}
|
|
||||||
if (getenv('SPC_LIBC') === 'glibc') {
|
|
||||||
return CheckResult::ok('Building with glibc, skipped');
|
|
||||||
}
|
|
||||||
if (str_contains(getenv('CC'), 'zig')) {
|
|
||||||
return CheckResult::ok('Building with zig, skipped');
|
|
||||||
}
|
|
||||||
|
|
||||||
$arch = arch2gnu(php_uname('m'));
|
$arch = arch2gnu(php_uname('m'));
|
||||||
$cross_compile_lib = "/usr/local/musl/{$arch}-linux-musl/lib/libc.a";
|
$cross_compile_lib = "/usr/local/musl/{$arch}-linux-musl/lib/libc.a";
|
||||||
$cross_compile_gcc = "/usr/local/musl/bin/{$arch}-linux-musl-gcc";
|
$cross_compile_gcc = "/usr/local/musl/bin/{$arch}-linux-musl-gcc";
|
||||||
|
|||||||
@ -51,6 +51,7 @@ class LinuxToolCheckList
|
|||||||
'binutils-gold' => 'ld.gold',
|
'binutils-gold' => 'ld.gold',
|
||||||
'base-devel' => 'automake',
|
'base-devel' => 'automake',
|
||||||
'gettext-devel' => 'gettextize',
|
'gettext-devel' => 'gettextize',
|
||||||
|
'gettext-dev' => 'gettextize',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @noinspection PhpUnused */
|
/** @noinspection PhpUnused */
|
||||||
|
|||||||
@ -4,13 +4,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\store;
|
namespace SPC\store;
|
||||||
|
|
||||||
use SPC\builder\linux\SystemUtil;
|
|
||||||
use SPC\exception\DownloaderException;
|
use SPC\exception\DownloaderException;
|
||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\pkg\CustomPackage;
|
use SPC\store\pkg\CustomPackage;
|
||||||
use SPC\store\source\CustomSourceBase;
|
use SPC\store\source\CustomSourceBase;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Source Downloader.
|
* Source Downloader.
|
||||||
@ -591,7 +591,12 @@ class Downloader
|
|||||||
|
|
||||||
public static function getPreBuiltLockName(string $source): string
|
public static function getPreBuiltLockName(string $source): string
|
||||||
{
|
{
|
||||||
return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default') . '-' . (SystemUtil::getLibcVersionIfExists() ?? 'default');
|
$os_family = PHP_OS_FAMILY;
|
||||||
|
$gnu_arch = getenv('GNU_ARCH') ?: 'unknown';
|
||||||
|
$libc = SPCTarget::getLibc();
|
||||||
|
$libc_version = SPCTarget::getLibcVersion() ?? 'default';
|
||||||
|
|
||||||
|
return "{$source}-{$os_family}-{$gnu_arch}-{$libc}-{$libc_version}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -11,13 +11,13 @@ use SPC\builder\unix\UnixBuilderBase;
|
|||||||
use SPC\exception\FileSystemException;
|
use SPC\exception\FileSystemException;
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
class SourcePatcher
|
class SourcePatcher
|
||||||
{
|
{
|
||||||
public static function init(): void
|
public static function init(): void
|
||||||
{
|
{
|
||||||
// FileSystem::addSourceExtractHook('swow', [__CLASS__, 'patchSwow']);
|
// FileSystem::addSourceExtractHook('swow', [__CLASS__, 'patchSwow']);
|
||||||
FileSystem::addSourceExtractHook('micro', [__CLASS__, 'patchMicro']);
|
|
||||||
FileSystem::addSourceExtractHook('openssl', [__CLASS__, 'patchOpenssl11Darwin']);
|
FileSystem::addSourceExtractHook('openssl', [__CLASS__, 'patchOpenssl11Darwin']);
|
||||||
FileSystem::addSourceExtractHook('swoole', [__CLASS__, 'patchSwoole']);
|
FileSystem::addSourceExtractHook('swoole', [__CLASS__, 'patchSwoole']);
|
||||||
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchPhpLibxml212']);
|
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchPhpLibxml212']);
|
||||||
@ -105,7 +105,7 @@ class SourcePatcher
|
|||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
* @throws FileSystemException
|
* @throws FileSystemException
|
||||||
*/
|
*/
|
||||||
public static function patchMicro(string $name = '', string $target = '', ?array $items = null): bool
|
public static function patchMicro(?array $items = null): bool
|
||||||
{
|
{
|
||||||
if (!file_exists(SOURCE_PATH . '/php-src/sapi/micro/php_micro.c')) {
|
if (!file_exists(SOURCE_PATH . '/php-src/sapi/micro/php_micro.c')) {
|
||||||
return false;
|
return false;
|
||||||
@ -152,11 +152,7 @@ class SourcePatcher
|
|||||||
|
|
||||||
foreach ($patches as $patch) {
|
foreach ($patches as $patch) {
|
||||||
logger()->info("Patching micro with {$patch}");
|
logger()->info("Patching micro with {$patch}");
|
||||||
$patchesStr = str_replace('/', DIRECTORY_SEPARATOR, $patch);
|
self::patchFile(SOURCE_PATH . "/php-src/{$patch}", SOURCE_PATH . '/php-src');
|
||||||
f_passthru(
|
|
||||||
'cd ' . SOURCE_PATH . '/php-src && ' .
|
|
||||||
(PHP_OS_FAMILY === 'Windows' ? 'type' : 'cat') . ' ' . $patchesStr . ' | patch -p1 '
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -165,24 +161,32 @@ class SourcePatcher
|
|||||||
/**
|
/**
|
||||||
* Use existing patch file for patching
|
* Use existing patch file for patching
|
||||||
*
|
*
|
||||||
* @param string $patch_name Patch file name in src/globals/patch/
|
* @param string $patch_name Patch file name in src/globals/patch/ or absolute path
|
||||||
* @param string $cwd Working directory for patch command
|
* @param string $cwd Working directory for patch command
|
||||||
* @param bool $reverse Reverse patches (default: False)
|
* @param bool $reverse Reverse patches (default: False)
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public static function patchFile(string $patch_name, string $cwd, bool $reverse = false): bool
|
public static function patchFile(string $patch_name, string $cwd, bool $reverse = false): bool
|
||||||
{
|
{
|
||||||
if (!file_exists(ROOT_DIR . "/src/globals/patch/{$patch_name}")) {
|
if (FileSystem::isRelativePath($patch_name)) {
|
||||||
|
$patch_file = ROOT_DIR . "/src/globals/patch/{$patch_name}";
|
||||||
|
} else {
|
||||||
|
$patch_file = $patch_name;
|
||||||
|
}
|
||||||
|
if (!file_exists($patch_file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$patch_file = ROOT_DIR . "/src/globals/patch/{$patch_name}";
|
$patch_str = FileSystem::convertPath($patch_file);
|
||||||
$patch_str = str_replace('/', DIRECTORY_SEPARATOR, $patch_file);
|
if (!file_exists($patch_str)) {
|
||||||
|
throw new RuntimeException("Patch file [{$patch_str}] does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
// Copy patch from phar
|
// Copy patch from phar
|
||||||
if (\Phar::running() !== '') {
|
if (str_starts_with($patch_str, 'phar://')) {
|
||||||
file_put_contents(SOURCE_PATH . '/' . $patch_name, file_get_contents($patch_file));
|
$filename = pathinfo($patch_file, PATHINFO_BASENAME);
|
||||||
$patch_str = str_replace('/', DIRECTORY_SEPARATOR, SOURCE_PATH . '/' . $patch_name);
|
file_put_contents(SOURCE_PATH . "/{$filename}", file_get_contents($patch_file));
|
||||||
|
$patch_str = FileSystem::convertPath(SOURCE_PATH . "/{$filename}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect
|
// detect
|
||||||
@ -458,7 +462,7 @@ class SourcePatcher
|
|||||||
|
|
||||||
public static function patchFfiCentos7FixO3strncmp(): bool
|
public static function patchFfiCentos7FixO3strncmp(): bool
|
||||||
{
|
{
|
||||||
if (PHP_OS_FAMILY !== 'Linux' || SystemUtil::getLibcVersionIfExists() > '2.17') {
|
if (!($ver = SPCTarget::getLibcVersion()) || version_compare($ver, '2.17', '>')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
|
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ namespace SPC\store\pkg;
|
|||||||
use SPC\store\Downloader;
|
use SPC\store\Downloader;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\LockFile;
|
use SPC\store\LockFile;
|
||||||
use SPC\util\GlobalEnvManager;
|
|
||||||
|
|
||||||
class GoXcaddy extends CustomPackage
|
class GoXcaddy extends CustomPackage
|
||||||
{
|
{
|
||||||
@ -65,7 +64,6 @@ class GoXcaddy extends CustomPackage
|
|||||||
|
|
||||||
FileSystem::extractPackage($name, $source_type, $filename, $extract);
|
FileSystem::extractPackage($name, $source_type, $filename, $extract);
|
||||||
|
|
||||||
GlobalEnvManager::init();
|
|
||||||
// install xcaddy
|
// install xcaddy
|
||||||
shell()
|
shell()
|
||||||
->appendEnv([
|
->appendEnv([
|
||||||
|
|||||||
33
src/SPC/toolchain/ClangNativeToolchain.php
Normal file
33
src/SPC/toolchain/ClangNativeToolchain.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\toolchain;
|
||||||
|
|
||||||
|
use SPC\builder\freebsd\SystemUtil as FreeBSDSystemUtil;
|
||||||
|
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||||
|
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\util\GlobalEnvManager;
|
||||||
|
|
||||||
|
class ClangNativeToolchain implements ToolchainInterface
|
||||||
|
{
|
||||||
|
public function initEnv(): void
|
||||||
|
{
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CC=clang');
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=clang++');
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function afterInit(): void
|
||||||
|
{
|
||||||
|
// check clang exists
|
||||||
|
match (PHP_OS_FAMILY) {
|
||||||
|
'Linux' => LinuxSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or manually set CC/CXX to a valid path.'),
|
||||||
|
'Darwin' => MacOSSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or set CC/CXX to a valid path.'),
|
||||||
|
'BSD' => FreeBSDSystemUtil::findCommand('clang++') ?? throw new WrongUsageException('Clang++ not found, please install it or set CC/CXX to a valid path.'),
|
||||||
|
default => throw new WrongUsageException('Clang is not supported on ' . PHP_OS_FAMILY . '.'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/SPC/toolchain/GccNativeToolchain.php
Normal file
33
src/SPC/toolchain/GccNativeToolchain.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\toolchain;
|
||||||
|
|
||||||
|
use SPC\builder\freebsd\SystemUtil as FreeBSDSystemUtil;
|
||||||
|
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||||
|
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\util\GlobalEnvManager;
|
||||||
|
|
||||||
|
class GccNativeToolchain implements ToolchainInterface
|
||||||
|
{
|
||||||
|
public function initEnv(): void
|
||||||
|
{
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CC=gcc');
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=g++');
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||||
|
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld.gold');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function afterInit(): void
|
||||||
|
{
|
||||||
|
// check gcc exists
|
||||||
|
match (PHP_OS_FAMILY) {
|
||||||
|
'Linux' => LinuxSystemUtil::findCommand('g++') ?? throw new WrongUsageException('g++ not found, please install it or set CC/CXX to a valid path.'),
|
||||||
|
'Darwin' => MacOSSystemUtil::findCommand('g++') ?? throw new WrongUsageException('g++ not found, please install it or set CC/CXX to a valid path.'),
|
||||||
|
'BSD' => FreeBSDSystemUtil::findCommand('g++') ?? throw new WrongUsageException('g++ not found, please install it or set CC/CXX to a valid path.'),
|
||||||
|
default => throw new \RuntimeException('GCC is not supported on ' . PHP_OS_FAMILY . '.'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/SPC/toolchain/MSVCToolchain.php
Normal file
12
src/SPC/toolchain/MSVCToolchain.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\toolchain;
|
||||||
|
|
||||||
|
class MSVCToolchain implements ToolchainInterface
|
||||||
|
{
|
||||||
|
public function initEnv(): void {}
|
||||||
|
|
||||||
|
public function afterInit(): void {}
|
||||||
|
}
|
||||||
39
src/SPC/toolchain/MuslToolchain.php
Normal file
39
src/SPC/toolchain/MuslToolchain.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\toolchain;
|
||||||
|
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\util\GlobalEnvManager;
|
||||||
|
|
||||||
|
class MuslToolchain implements ToolchainInterface
|
||||||
|
{
|
||||||
|
public function initEnv(): void
|
||||||
|
{
|
||||||
|
$arch = getenv('GNU_ARCH');
|
||||||
|
// Set environment variables for musl toolchain
|
||||||
|
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_CC={$arch}-linux-musl-gcc");
|
||||||
|
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_CXX={$arch}-linux-musl-g++");
|
||||||
|
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_AR={$arch}-linux-musl-ar");
|
||||||
|
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LD={$arch}-linux-musl-ld");
|
||||||
|
GlobalEnvManager::addPathIfNotExists('/usr/local/musl/bin');
|
||||||
|
GlobalEnvManager::addPathIfNotExists("/usr/local/musl/{$arch}-linux-musl/bin");
|
||||||
|
|
||||||
|
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LD_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||||
|
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function afterInit(): void
|
||||||
|
{
|
||||||
|
$arch = getenv('GNU_ARCH');
|
||||||
|
// append LD_LIBRARY_PATH to $configure = getenv('SPC_CMD_PREFIX_PHP_CONFIGURE');
|
||||||
|
$configure = getenv('SPC_CMD_PREFIX_PHP_CONFIGURE');
|
||||||
|
$ld_library_path = getenv('SPC_LINUX_DEFAULT_LD_LIBRARY_PATH');
|
||||||
|
GlobalEnvManager::putenv("SPC_CMD_PREFIX_PHP_CONFIGURE=LD_LIBRARY_PATH=\"{$ld_library_path}\" {$configure}");
|
||||||
|
|
||||||
|
if (!file_exists("/usr/local/musl/{$arch}-linux-musl/lib/libc.a")) {
|
||||||
|
throw new WrongUsageException('You are building with musl-libc target in glibc distro, but musl-toolchain is not installed, please install musl-toolchain first. (You can use `doctor` command to install it)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/SPC/toolchain/ToolchainInterface.php
Normal file
18
src/SPC/toolchain/ToolchainInterface.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\toolchain;
|
||||||
|
|
||||||
|
interface ToolchainInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Initialize the environment for the given target.
|
||||||
|
*/
|
||||||
|
public function initEnv(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform actions after the environment has been initialized for the given target.
|
||||||
|
*/
|
||||||
|
public function afterInit(): void;
|
||||||
|
}
|
||||||
52
src/SPC/toolchain/ToolchainManager.php
Normal file
52
src/SPC/toolchain/ToolchainManager.php
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\toolchain;
|
||||||
|
|
||||||
|
use SPC\builder\linux\SystemUtil;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
use SPC\util\GlobalEnvManager;
|
||||||
|
|
||||||
|
class ToolchainManager
|
||||||
|
{
|
||||||
|
public const array OS_DEFAULT_TOOLCHAIN = [
|
||||||
|
'Linux' => MuslToolchain::class, // use musl toolchain by default, after zig pr merged, change this to ZigToolchain::class
|
||||||
|
'Windows' => MSVCToolchain::class,
|
||||||
|
'Darwin' => ClangNativeToolchain::class,
|
||||||
|
'BSD' => ClangNativeToolchain::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public static function initToolchain(): void
|
||||||
|
{
|
||||||
|
$libc = getenv('SPC_LIBC');
|
||||||
|
if ($libc !== false) {
|
||||||
|
// uncomment this when zig pr is merged
|
||||||
|
// logger()->warning('SPC_LIBC is deprecated, please use SPC_TARGET instead.');
|
||||||
|
$toolchain = match ($libc) {
|
||||||
|
'musl' => SystemUtil::isMuslDist() ? GccNativeToolchain::class : MuslToolchain::class,
|
||||||
|
'glibc' => !SystemUtil::isMuslDist() ? GccNativeToolchain::class : throw new WrongUsageException('SPC_TARGET must be musl-static or musl for musl dist.'),
|
||||||
|
default => throw new WrongUsageException('Unsupported SPC_LIBC value: ' . $libc),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$toolchain = self::OS_DEFAULT_TOOLCHAIN[PHP_OS_FAMILY];
|
||||||
|
}
|
||||||
|
$toolchainClass = $toolchain;
|
||||||
|
/* @var ToolchainInterface $toolchainClass */
|
||||||
|
(new $toolchainClass())->initEnv();
|
||||||
|
GlobalEnvManager::putenv("SPC_TOOLCHAIN={$toolchain}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function afterInitToolchain(): void
|
||||||
|
{
|
||||||
|
if (!getenv('SPC_TOOLCHAIN')) {
|
||||||
|
throw new WrongUsageException('SPC_TOOLCHAIN not set');
|
||||||
|
}
|
||||||
|
$toolchain = getenv('SPC_TOOLCHAIN');
|
||||||
|
/* @var ToolchainInterface $toolchain */
|
||||||
|
(new $toolchain())->afterInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/SPC/toolchain/ZigToolchain.php
Normal file
12
src/SPC/toolchain/ZigToolchain.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\toolchain;
|
||||||
|
|
||||||
|
class ZigToolchain implements ToolchainInterface
|
||||||
|
{
|
||||||
|
public function initEnv(): void {}
|
||||||
|
|
||||||
|
public function afterInit(): void {}
|
||||||
|
}
|
||||||
@ -4,10 +4,10 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace SPC\util;
|
namespace SPC\util;
|
||||||
|
|
||||||
use SPC\builder\linux\SystemUtil;
|
|
||||||
use SPC\exception\RuntimeException;
|
use SPC\exception\RuntimeException;
|
||||||
use SPC\exception\WrongUsageException;
|
use SPC\exception\WrongUsageException;
|
||||||
use SPC\store\pkg\Zig;
|
use SPC\store\pkg\Zig;
|
||||||
|
use SPC\toolchain\ToolchainManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Environment variable manager
|
* Environment variable manager
|
||||||
@ -41,30 +41,6 @@ class GlobalEnvManager
|
|||||||
self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig');
|
self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define env vars for linux
|
|
||||||
if (PHP_OS_FAMILY === 'Linux') {
|
|
||||||
$arch = getenv('GNU_ARCH');
|
|
||||||
|
|
||||||
if (str_contains((string) getenv('CC'), 'zig')) {
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_CC=zig-cc');
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_CXX=zig-c++');
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_LD=ld.lld');
|
|
||||||
} elseif (SystemUtil::isMuslDist() || getenv('SPC_LIBC') === 'glibc') {
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_CC=gcc');
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_CXX=g++');
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
|
||||||
self::putenv('SPC_LINUX_DEFAULT_LD=ld.gold');
|
|
||||||
} else {
|
|
||||||
self::putenv("SPC_LINUX_DEFAULT_CC={$arch}-linux-musl-gcc");
|
|
||||||
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");
|
|
||||||
self::addPathIfNotExists('/usr/local/musl/bin');
|
|
||||||
self::addPathIfNotExists("/usr/local/musl/{$arch}-linux-musl/bin");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$ini = self::readIniFile();
|
$ini = self::readIniFile();
|
||||||
|
|
||||||
$default_put_list = [];
|
$default_put_list = [];
|
||||||
@ -87,6 +63,9 @@ class GlobalEnvManager
|
|||||||
self::putenv("{$k}={$v}");
|
self::putenv("{$k}={$v}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ToolchainManager::initToolchain();
|
||||||
|
|
||||||
// apply second time
|
// apply second time
|
||||||
$ini2 = self::readIniFile();
|
$ini2 = self::readIniFile();
|
||||||
|
|
||||||
@ -107,17 +86,6 @@ class GlobalEnvManager
|
|||||||
self::putenv("{$k}={$v}");
|
self::putenv("{$k}={$v}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (getenv('SPC_LIBC_LINKAGE') === '-static' && getenv('SPC_LIBC') === 'glibc') {
|
|
||||||
self::putenv('SPC_LIBC_LINKAGE=');
|
|
||||||
}
|
|
||||||
if (str_contains((string) getenv('CC'), 'zig') || str_contains((string) getenv('CXX'), 'zig')) {
|
|
||||||
$zigEnv = Zig::getEnvironment();
|
|
||||||
foreach ($zigEnv as $key => $value) {
|
|
||||||
if ($key === 'PATH') {
|
|
||||||
self::addPathIfNotExists($value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function putenv(string $val): void
|
public static function putenv(string $val): void
|
||||||
@ -133,6 +101,19 @@ class GlobalEnvManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the toolchain after the environment variables are set.
|
||||||
|
* The toolchain or environment availability check is done here.
|
||||||
|
*
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public static function afterInit(): void
|
||||||
|
{
|
||||||
|
if (!filter_var(getenv('SPC_SKIP_TOOLCHAIN_CHECK'), FILTER_VALIDATE_BOOL)) {
|
||||||
|
ToolchainManager::afterInitToolchain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws WrongUsageException
|
* @throws WrongUsageException
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -56,7 +56,7 @@ class SPCConfigUtil
|
|||||||
ob_get_clean();
|
ob_get_clean();
|
||||||
$ldflags = $this->getLdflagsString();
|
$ldflags = $this->getLdflagsString();
|
||||||
$libs = $this->getLibsString($libraries, $with_dependencies);
|
$libs = $this->getLibsString($libraries, $with_dependencies);
|
||||||
if (PHP_OS_FAMILY === 'Darwin') {
|
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||||
$libs .= " {$this->getFrameworksString($extensions)}";
|
$libs .= " {$this->getFrameworksString($extensions)}";
|
||||||
}
|
}
|
||||||
$cflags = $this->getIncludesString();
|
$cflags = $this->getIncludesString();
|
||||||
|
|||||||
87
src/SPC/util/SPCTarget.php
Normal file
87
src/SPC/util/SPCTarget.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\util;
|
||||||
|
|
||||||
|
use SPC\builder\linux\SystemUtil;
|
||||||
|
use SPC\exception\WrongUsageException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPC build target constants and toolchain initialization.
|
||||||
|
* format: {target_name}[-{libc_subtype}]
|
||||||
|
*/
|
||||||
|
class SPCTarget
|
||||||
|
{
|
||||||
|
public const array LIBC_LIST = [
|
||||||
|
'musl',
|
||||||
|
'glibc',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the target is a full-static target.
|
||||||
|
*/
|
||||||
|
public static function isStatic(): bool
|
||||||
|
{
|
||||||
|
$env = getenv('SPC_TARGET');
|
||||||
|
$libc = getenv('SPC_LIBC');
|
||||||
|
// if SPC_LIBC is set, it means the target is static, remove it when 3.0 is released
|
||||||
|
if ($libc === 'musl') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// TODO: add zig target parser here
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the libc type if set, for other OS, it will always return null.
|
||||||
|
*/
|
||||||
|
public static function getLibc(): ?string
|
||||||
|
{
|
||||||
|
$env = getenv('SPC_TARGET');
|
||||||
|
$libc = getenv('SPC_LIBC');
|
||||||
|
if ($libc !== false) {
|
||||||
|
return $libc;
|
||||||
|
}
|
||||||
|
// TODO: zig target parser
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the libc version if set, for other OS, it will always return null.
|
||||||
|
*/
|
||||||
|
public static function getLibcVersion(): ?string
|
||||||
|
{
|
||||||
|
$env = getenv('SPC_TARGET');
|
||||||
|
$libc = getenv('SPC_LIBC');
|
||||||
|
if ($libc !== false) {
|
||||||
|
// legacy method: get a version from system
|
||||||
|
return SystemUtil::getLibcVersionIfExists($libc);
|
||||||
|
}
|
||||||
|
// TODO: zig target parser
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the target OS family, e.g. Linux, Darwin, Windows, BSD.
|
||||||
|
* Currently, we only support native building.
|
||||||
|
*
|
||||||
|
* @return 'BSD'|'Darwin'|'Linux'|'Windows'
|
||||||
|
* @throws WrongUsageException
|
||||||
|
*/
|
||||||
|
public static function getTargetOS(): string
|
||||||
|
{
|
||||||
|
$target = getenv('SPC_TARGET');
|
||||||
|
if ($target === false) {
|
||||||
|
return PHP_OS_FAMILY;
|
||||||
|
}
|
||||||
|
// TODO: zig target parser like below?
|
||||||
|
return match (true) {
|
||||||
|
str_contains($target, 'linux') => 'Linux',
|
||||||
|
str_contains($target, 'macos') => 'Darwin',
|
||||||
|
str_contains($target, 'windows') => 'Windows',
|
||||||
|
default => throw new WrongUsageException('Cannot parse target.'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,15 +21,15 @@ $test_php_version = [
|
|||||||
|
|
||||||
// test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available)
|
// test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available)
|
||||||
$test_os = [
|
$test_os = [
|
||||||
// 'macos-13',
|
// 'macos-13', // bin/spc for x86_64
|
||||||
// 'macos-14',
|
// 'macos-14', // bin/spc for arm64
|
||||||
// 'macos-15',
|
'macos-15', // bin/spc for arm64
|
||||||
// 'ubuntu-latest',
|
'ubuntu-latest', // bin/spc-alpine-docker for x86_64
|
||||||
// 'ubuntu-22.04',
|
'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
|
||||||
// 'ubuntu-22.04-arm',
|
'ubuntu-24.04', // bin/spc for x86_64
|
||||||
'ubuntu-24.04',
|
// 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
|
||||||
'ubuntu-24.04-arm',
|
// 'ubuntu-24.04-arm', // bin/spc for arm64
|
||||||
// 'windows-latest',
|
// 'windows-latest', // .\bin\spc.ps1
|
||||||
];
|
];
|
||||||
|
|
||||||
$zig = true;
|
$zig = true;
|
||||||
@ -84,7 +84,7 @@ $with_libs = match (PHP_OS_FAMILY) {
|
|||||||
// You can use `common`, `bulk`, `minimal` or `none`.
|
// You can use `common`, `bulk`, `minimal` or `none`.
|
||||||
// note: combination is only available for *nix platform. Windows must use `none` combination
|
// note: combination is only available for *nix platform. Windows must use `none` combination
|
||||||
$base_combination = match (PHP_OS_FAMILY) {
|
$base_combination = match (PHP_OS_FAMILY) {
|
||||||
'Linux', 'Darwin' => 'minimal',
|
'Linux', 'Darwin' => 'common',
|
||||||
'Windows' => 'none',
|
'Windows' => 'none',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user