mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-18 22:35:36 +08:00
Compare commits
142 Commits
2.6.1
...
a6d68b9ecf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6d68b9ecf | ||
|
|
d275d6cc69 | ||
|
|
fd89e83798 | ||
|
|
88f9172866 | ||
|
|
27f57cc23a | ||
|
|
f6c6011061 | ||
|
|
408b3b4060 | ||
|
|
55fd7ba8e6 | ||
|
|
e34eb502db | ||
|
|
292df38c10 | ||
|
|
a483c42893 | ||
|
|
bebcb978f6 | ||
|
|
ba7f994a71 | ||
|
|
9c7e2171f6 | ||
|
|
b7e8587608 | ||
|
|
0a33fba23e | ||
|
|
5370af4a84 | ||
|
|
df0d5fdbe8 | ||
|
|
7b33ee79dd | ||
|
|
ad8322b6a6 | ||
|
|
c43a10027b | ||
|
|
2ebdc4509c | ||
|
|
4cb4c9c6a5 | ||
|
|
9190335a70 | ||
|
|
4e244789a2 | ||
|
|
6de7b8e63b | ||
|
|
68e500eea0 | ||
|
|
840e09a684 | ||
|
|
d00a5223d3 | ||
|
|
3965a899c7 | ||
|
|
956667bf08 | ||
|
|
51e23d21cd | ||
|
|
44c6d6288e | ||
|
|
e5848086c3 | ||
|
|
138e5588e9 | ||
|
|
ab5828a560 | ||
|
|
1839f13149 | ||
|
|
320c21d272 | ||
|
|
e1e48922de | ||
|
|
3940f032af | ||
|
|
956688d9f4 | ||
|
|
7f45f4aeec | ||
|
|
78666ff7de | ||
|
|
dbdf10c75a | ||
|
|
2564da2615 | ||
|
|
bd25de15cc | ||
|
|
fcaa7c5f42 | ||
|
|
e36800b951 | ||
|
|
977fbaa8ef | ||
|
|
6ed62aa05c | ||
|
|
1d29ac228c | ||
|
|
a44d90671c | ||
|
|
d6b0912492 | ||
|
|
d588e6e4fd | ||
|
|
19ddddf618 | ||
|
|
a7bf1e9676 | ||
|
|
02f2837f86 | ||
|
|
0598eff9c5 | ||
|
|
a6364389ba | ||
|
|
9e9474a026 | ||
|
|
c23c5ae614 | ||
|
|
de3cb2f686 | ||
|
|
454b5a77ad | ||
|
|
4a493f3f6d | ||
|
|
61274cb865 | ||
|
|
8145a7536b | ||
|
|
e41d7899c7 | ||
|
|
88d99a7dea | ||
|
|
90823e3b17 | ||
|
|
3357f286ab | ||
|
|
ad080da026 | ||
|
|
25c2def710 | ||
|
|
604131b31d | ||
|
|
924da6ae69 | ||
|
|
12aadf18cc | ||
|
|
aa516522aa | ||
|
|
efb1ff5a93 | ||
|
|
aff9ff20e8 | ||
|
|
4c8a173213 | ||
|
|
b6240f16fb | ||
|
|
f5281535d9 | ||
|
|
96babd0939 | ||
|
|
464c2dca85 | ||
|
|
43dc04b4d0 | ||
|
|
e92f043cfa | ||
|
|
ff95b464ce | ||
|
|
69e1acd5ae | ||
|
|
e162a0ecd6 | ||
|
|
383045d1c0 | ||
|
|
e6bec8eb57 | ||
|
|
d2dea83c63 | ||
|
|
797aaf1ea8 | ||
|
|
5a7fd8c24e | ||
|
|
cc4ec4b598 | ||
|
|
55d78579c8 | ||
|
|
d94542049c | ||
|
|
6dec25b4f4 | ||
|
|
8c7049913b | ||
|
|
7edd8e6e19 | ||
|
|
2b4eb7127d | ||
|
|
9a3ce775a8 | ||
|
|
2ff78e531e | ||
|
|
03a33d87ff | ||
|
|
176e5627e5 | ||
|
|
5801d05047 | ||
|
|
815ba75c76 | ||
|
|
fff16b4019 | ||
|
|
e408a2cf1d | ||
|
|
b535600297 | ||
|
|
762c554468 | ||
|
|
a8c7057aba | ||
|
|
935f3fc37c | ||
|
|
fae2878c41 | ||
|
|
d30ccb810c | ||
|
|
8d75a85d6d | ||
|
|
625bfd1bec | ||
|
|
b142610800 | ||
|
|
9a3a536479 | ||
|
|
55f01149e4 | ||
|
|
6f5fc43490 | ||
|
|
cb62ffdfc2 | ||
|
|
40ac705c46 | ||
|
|
5334727528 | ||
|
|
253206de22 | ||
|
|
5a60f4c02b | ||
|
|
63fcdd9db4 | ||
|
|
832c0230e2 | ||
|
|
e1028b0348 | ||
|
|
2433752273 | ||
|
|
1b0b551fc6 | ||
|
|
74849a8d48 | ||
|
|
ee0de6933f | ||
|
|
bd863dba34 | ||
|
|
f9af24e246 | ||
|
|
864c55feaf | ||
|
|
7628847a46 | ||
|
|
955b586908 | ||
|
|
32a1fd45df | ||
|
|
15fbde29d4 | ||
|
|
2cce02bfa9 | ||
|
|
7e35de8a0e | ||
|
|
9a98fd9cff |
@@ -69,4 +69,5 @@ return (new PhpCsFixer\Config())
|
||||
])
|
||||
->setFinder(
|
||||
PhpCsFixer\Finder::create()->in([__DIR__ . '/src', __DIR__ . '/tests/SPC'])
|
||||
);
|
||||
)
|
||||
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect());
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
**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 运行时打包为一个文件并运行。
|
||||
|
||||
@@ -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** 服务器。
|
||||
|
||||
**特别赞助商**:
|
||||
|
||||
<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 许可开源,下面是类似的项目:
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
**static-php-cli** is a powerful tool designed for building static, standalone PHP runtime
|
||||
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
|
||||
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.
|
||||
|
||||
**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
|
||||
|
||||
This project itself is based on MIT License,
|
||||
|
||||
@@ -64,7 +64,7 @@ fi
|
||||
# Detect docker env is setup
|
||||
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 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
|
||||
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 && \
|
||||
@@ -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 && \
|
||||
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 && \
|
||||
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
|
||||
RUN /app/bin/setup-runtime
|
||||
RUN /app/bin/php /app/bin/composer install --no-dev
|
||||
ENV PATH="/app/bin:/cmake/bin:$PATH"
|
||||
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
|
||||
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 install && \
|
||||
ln -sf /usr/local/bin/automake /usr/bin/automake
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -154,11 +153,7 @@ if [ -f "$(pwd)/craft.yml" ]; then
|
||||
fi
|
||||
|
||||
# Apply env in temp env file
|
||||
echo 'CC=/opt/rh/devtoolset-10/root/usr/bin/gcc' > /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_DEFAULT_C_FLAGS=-fPIC' > /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_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=
|
||||
|
||||
[windows]
|
||||
; build target: win7-static
|
||||
SPC_TARGET=native-windows
|
||||
; php-sdk-binary-tools path
|
||||
PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools"
|
||||
; upx executable path
|
||||
@@ -63,22 +65,37 @@ 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
|
||||
|
||||
[linux]
|
||||
; include PATH for musl libc.
|
||||
; Linux can use different build toolchains.
|
||||
; - musl (default, when SPC_LIBC=musl): used for general linux distros, can build `musl` (statically linked) only.
|
||||
; - zig (will become default): usable on all Linux distros, can build `-musl`, `arch-linux-musl -dynamic` and `arch-linux-gnu` targets. Can specify version such as `x86_64-linux-gnu.2.17`.
|
||||
; - musl-native: used for alpine linux, can build `musl` and `musl -dynamic` target.
|
||||
; - gnu-native: used for general linux distros, can build gnu target for the installed glibc version only.
|
||||
|
||||
; LEGACY option to specify the target, switch to SPC_TARGET with zig toolchain instead
|
||||
SPC_LIBC=musl
|
||||
|
||||
; Recommended: specify your target here. Zig toolchain will be used.
|
||||
; examples:
|
||||
; `native-native-gnu` - links against glibc, current OS version
|
||||
; `native-native-gnu.2.17` - links against glibc, version 2.17
|
||||
; `native-native` - static linking against musl
|
||||
; `native-native-musl -dynamic` - links against musl libc
|
||||
; SPC_TARGET=
|
||||
|
||||
; compiler environments
|
||||
CC=${SPC_LINUX_DEFAULT_CC}
|
||||
CXX=${SPC_LINUX_DEFAULT_CXX}
|
||||
AR=${SPC_LINUX_DEFAULT_AR}
|
||||
LD=${SPC_LINUX_DEFAULT_LD}
|
||||
; default compiler flags, used in CMake toolchain file, openssl and pkg-config build
|
||||
SPC_DEFAULT_C_FLAGS="-fPIC -Os"
|
||||
SPC_DEFAULT_CXX_FLAGS="-fPIC -Os"
|
||||
SPC_DEFAULT_C_FLAGS="-fPIC -Os -Wno-error=date-time"
|
||||
SPC_DEFAULT_CXX_FLAGS="-fPIC -Os -Wno-error=date-time"
|
||||
; 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=
|
||||
; upx executable path
|
||||
UPX_EXEC=${PKG_ROOT_PATH}/bin/upx
|
||||
; 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 ***
|
||||
; buildconf command
|
||||
@@ -98,17 +115,20 @@ SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS="-I${BUILD_INCLUDE_PATH}"
|
||||
; LDFLAGS for configuring php
|
||||
SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS="-L${BUILD_LIB_PATH}"
|
||||
; LIBS for configuring php
|
||||
SPC_CMD_VAR_PHP_CONFIGURE_LIBS="-ldl -lpthread -lm"
|
||||
SPC_CMD_VAR_PHP_CONFIGURE_LIBS="-ldl -lrt -lpthread -lm -lresolv -lutil"
|
||||
; EXTRA_CFLAGS for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE ${SPC_DEFAULT_C_FLAGS}"
|
||||
; EXTRA_LIBS for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm"
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lrt -lpthread -lm -lresolv -lutil"
|
||||
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
|
||||
; EXTRA_LDFLAGS_PROGRAM for `make` php
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -Wl,-O1 -pie"
|
||||
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -pie"
|
||||
|
||||
[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
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
@@ -118,7 +138,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)
|
||||
SPC_EXTRA_LIBS=
|
||||
; 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 ***
|
||||
; buildconf command
|
||||
|
||||
@@ -54,5 +54,20 @@
|
||||
},
|
||||
"go-xcaddy-aarch64-macos": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-x86_64-linux": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-aarch64-linux": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-x86_64-macos": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-aarch64-macos": {
|
||||
"type": "custom"
|
||||
},
|
||||
"zig-x86_64-win": {
|
||||
"type": "custom"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@ export default {
|
||||
nav: [],
|
||||
socialLinks: [
|
||||
{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 {inBrowser, useData} from "vitepress";
|
||||
import {watchEffect} from "vue";
|
||||
import './style.css';
|
||||
|
||||
export default {
|
||||
...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;
|
||||
}
|
||||
|
||||
@@ -48,17 +48,17 @@ This extension contains an implementation of the coroutine environment for `pdo_
|
||||
|
||||
## swow
|
||||
|
||||
1. Only PHP 8.0 ~ 8.4 is supported.
|
||||
1. Only PHP 8.0+ is supported.
|
||||
|
||||
## imagick
|
||||
|
||||
1. The imagick extension currently only has openmp support on musl libc. This means that multithreading is disabled on glibc or other operating systems. The extension is still fully functional.
|
||||
1. OpenMP support is disabled, this is recommended by the maintainers and also the case system packages.
|
||||
|
||||
## imap
|
||||
|
||||
1. Kerberos is not supported
|
||||
2. ext-imap is not thread safe due to the underlying c-client. It's not possible to use it in --enable-zts builds.
|
||||
3. Because the extension may be dropped from php, we recommend you look for an alternative implementation, such as [Webklex/php-imap](https://github.com/Webklex/php-imap)
|
||||
2. ext-imap is not thread safe due to the underlying c-client. It's not possible to use it in `--enable-zts` builds.
|
||||
3. The extension was dropped from php 8.4, we recommend you look for an alternative implementation, such as [Webklex/php-imap](https://github.com/Webklex/php-imap)
|
||||
|
||||
## gd
|
||||
|
||||
@@ -82,7 +82,7 @@ and this extension cannot be compiled into php by static linking, so it cannot b
|
||||
|
||||
## 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. On Linux, you'll need to use a SPC_TARGET like `native-native -dynamic` or `native-native-gnu`.
|
||||
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`.
|
||||
|
||||
|
||||
@@ -21,3 +21,16 @@ features:
|
||||
- title: Dependency Management
|
||||
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 |
@@ -45,17 +45,17 @@ swoole-hook-sqlite 与 `pdo_sqlite` 扩展冲突。如需使用 Swoole 和 `pdo_
|
||||
|
||||
## swow
|
||||
|
||||
1. swow 仅支持 PHP 8.0 ~ 8.4 版本。
|
||||
1. swow 仅支持 PHP 8.0+ 版本。
|
||||
|
||||
## imagick
|
||||
|
||||
imagick 扩展目前仅在 musl libc 上支持 OpenMP(libgomp)。使用 glibc 方式构建的 imagick 扩展无法支持多线程特性。
|
||||
1. OpenMP 支持已被禁用,这是维护者推荐的做法,系统软件包也是如此配置。
|
||||
|
||||
## imap
|
||||
|
||||
1. 该扩展目前不支持 Kerberos。
|
||||
2. 由于底层的 c-client、ext-imap 不是线程安全的。 无法在 `--enable-zts` 构建中使用它。
|
||||
3. 由于该扩展可能会从未来的 PHP 中删除,因此我们建议您寻找替代实现,例如 [Webklex/php-imap](https://github.com/Webklex/php-imap)。
|
||||
3. 该扩展已在 PHP 8.4 中被移除,因此我们建议您寻找替代实现,例如 [Webklex/php-imap](https://github.com/Webklex/php-imap)。
|
||||
|
||||
## gd
|
||||
|
||||
@@ -76,7 +76,7 @@ bin/spc build gd --with-libs=freetype,libjpeg,libavif,libwebp --build-cli
|
||||
|
||||
## xdebug
|
||||
|
||||
1. Xdebug 只能作为共享扩展进行构建。在 Linux 上,您需要使用 static-php-cli 并设置 SPC_LIBC=glibc。
|
||||
1. Xdebug 只能作为共享扩展进行构建。您需要使用除了 `musl-static` 外的其他 `SPC_TARGET` 构建目标。
|
||||
2. 使用 Linux/glibc 或 macOS 时,您可以使用 `--build-shared=xdebug` 将 Xdebug 编译为共享扩展。
|
||||
编译后的 `./php` 二进制文件可以通过指定 INI 文件进行配置和运行,例如 `./php -d 'zend_extension=/path/to/xdebug.so' your-code.php`。
|
||||
|
||||
|
||||
@@ -4,5 +4,6 @@
|
||||
>
|
||||
<php>
|
||||
<env name="SPC_IGNORE_BAD_HASH" value="yes" force="true" />
|
||||
<env name="SPC_SKIP_TOOLCHAIN_CHECK" value="yes" force="true" />
|
||||
</php>
|
||||
</phpunit>
|
||||
|
||||
@@ -9,6 +9,7 @@ use SPC\command\BuildPHPCommand;
|
||||
use SPC\command\CraftCommand;
|
||||
use SPC\command\DeleteDownloadCommand;
|
||||
use SPC\command\dev\AllExtCommand;
|
||||
use SPC\command\dev\EnvCommand;
|
||||
use SPC\command\dev\ExtVerCommand;
|
||||
use SPC\command\dev\GenerateExtDepDocsCommand;
|
||||
use SPC\command\dev\GenerateExtDocCommand;
|
||||
@@ -70,6 +71,7 @@ final class ConsoleApplication extends Application
|
||||
new GenerateExtDepDocsCommand(),
|
||||
new GenerateLibDepDocsCommand(),
|
||||
new PackLibCommand(),
|
||||
new EnvCommand(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\LockFile;
|
||||
use SPC\store\SourceManager;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
abstract class BuilderBase
|
||||
@@ -203,6 +204,8 @@ abstract class BuilderBase
|
||||
$this->emitPatchPoint('before-exts-extract');
|
||||
SourceManager::initSource(exts: [...$static_extensions, ...$shared_extensions]);
|
||||
$this->emitPatchPoint('after-exts-extract');
|
||||
// patch micro
|
||||
SourcePatcher::patchMicro();
|
||||
}
|
||||
|
||||
foreach ([...$static_extensions, ...$shared_extensions] as $extension) {
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
@@ -215,7 +216,16 @@ class Extension
|
||||
*/
|
||||
public function patchBeforeSharedMake(): bool
|
||||
{
|
||||
return false;
|
||||
$extra = SystemUtil::getExtraRuntimeObjects();
|
||||
if (!$extra) {
|
||||
return false;
|
||||
}
|
||||
FileSystem::replaceFileRegex(
|
||||
$this->source_dir . '/Makefile',
|
||||
"/^(shared_objects_{$this->getName()}\\s*=.*)$/m",
|
||||
"$1 {$extra}",
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,8 +397,8 @@ class Extension
|
||||
|
||||
// macOS ld64 doesn't understand these, while Linux and BSD do
|
||||
// use them to make sure that all symbols are picked up, even if a library has already been visited before
|
||||
$preStatic = PHP_OS_FAMILY !== 'Darwin' ? '-Wl,-Bstatic -Wl,--start-group ' : '';
|
||||
$postStatic = PHP_OS_FAMILY !== 'Darwin' ? ' -Wl,--end-group -Wl,-Bdynamic ' : ' ';
|
||||
$preStatic = PHP_OS_FAMILY !== 'Darwin' ? '-Wl,--start-group ' : '';
|
||||
$postStatic = PHP_OS_FAMILY !== 'Darwin' ? ' -Wl,--end-group ' : ' ';
|
||||
$env = [
|
||||
'CFLAGS' => $config['cflags'],
|
||||
'CXXFLAGS' => $config['cflags'],
|
||||
@@ -404,6 +414,7 @@ class Extension
|
||||
// prepare configure args
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->appendEnv($this->getExtraEnv())
|
||||
->exec(BUILD_BIN_PATH . '/phpize');
|
||||
|
||||
if ($this->patchBeforeSharedConfigure()) {
|
||||
@@ -412,6 +423,7 @@ class Extension
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->appendEnv($this->getExtraEnv())
|
||||
->exec(
|
||||
'./configure ' . $this->getUnixConfigureArg(true) .
|
||||
' --with-php-config=' . BUILD_BIN_PATH . '/php-config ' .
|
||||
@@ -431,6 +443,7 @@ class Extension
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->setEnv($env)
|
||||
->appendEnv($this->getExtraEnv())
|
||||
->exec('make clean')
|
||||
->exec('make -j' . $this->builder->concurrency)
|
||||
->exec('make install');
|
||||
@@ -515,8 +528,7 @@ class Extension
|
||||
$sharedLibString = '';
|
||||
$staticLibString = '';
|
||||
$staticLibs = $this->getLibFilesString();
|
||||
$staticLibs = str_replace(BUILD_LIB_PATH . '/lib', '-l', $staticLibs);
|
||||
$staticLibs = str_replace('.a', '', $staticLibs);
|
||||
$staticLibs = str_replace([BUILD_LIB_PATH . '/lib', '.a'], ['-l', ''], $staticLibs);
|
||||
$staticLibs = explode('-l', $staticLibs . ' ' . $config['libs']);
|
||||
foreach ($staticLibs as $lib) {
|
||||
$lib = trim($lib);
|
||||
@@ -535,6 +547,11 @@ class Extension
|
||||
return [trim($staticLibString), trim($sharedLibString)];
|
||||
}
|
||||
|
||||
protected function getExtraEnv(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getLibraryDependencies(bool $recursive = false): array
|
||||
{
|
||||
$ret = array_filter($this->dependencies, fn ($x) => $x instanceof LibraryBase);
|
||||
|
||||
@@ -5,36 +5,22 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\util\CustomExt;
|
||||
|
||||
#[CustomExt('imagick')]
|
||||
class imagick extends Extension
|
||||
{
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY !== 'Linux') {
|
||||
return false;
|
||||
}
|
||||
if (getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10')) {
|
||||
return false;
|
||||
}
|
||||
// imagick with calls omp_pause_all, which requires openmp, on non-musl we build imagick without openmp
|
||||
$extra_libs = trim(getenv('SPC_EXTRA_LIBS') . ' -lgomp');
|
||||
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
{
|
||||
$disable_omp = !(getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10')) ? '' : ' 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 (getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10')) {
|
||||
if (SystemUtil::getLibcVersionIfExists('glibc') && SystemUtil::getLibcVersionIfExists('glibc') <= '2.17') {
|
||||
$static .= ' -lstdc++';
|
||||
$shared = str_replace('-lstdc++', '', $shared);
|
||||
}
|
||||
|
||||
@@ -57,4 +57,11 @@ class pgsql extends Extension
|
||||
}
|
||||
return '--with-pgsql=' . BUILD_ROOT_PATH;
|
||||
}
|
||||
|
||||
protected function getExtraEnv(): array
|
||||
{
|
||||
return [
|
||||
'CFLAGS' => '-Wno-int-conversion',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,13 @@ class redis extends Extension
|
||||
public function getUnixConfigureArg(bool $shared = false): string
|
||||
{
|
||||
$arg = '--enable-redis';
|
||||
$arg .= $this->builder->getExt('session') ? ' --enable-redis-session' : ' --disable-redis-session';
|
||||
$arg .= $this->builder->getExt('igbinary') ? ' --enable-redis-igbinary' : ' --disable-redis-igbinary';
|
||||
if ($this->isBuildStatic()) {
|
||||
$arg .= $this->builder->getExt('session')?->isBuildStatic() ? ' --enable-redis-session' : ' --disable-redis-session';
|
||||
$arg .= $this->builder->getExt('igbinary')?->isBuildStatic() ? ' --enable-redis-igbinary' : ' --disable-redis-igbinary';
|
||||
} else {
|
||||
$arg .= $this->builder->getExt('session') ? ' --enable-redis-session' : ' --disable-redis-session';
|
||||
$arg .= $this->builder->getExt('igbinary') ? ' --enable-redis-igbinary' : ' --disable-redis-igbinary';
|
||||
}
|
||||
if ($this->builder->getLib('zstd')) {
|
||||
$arg .= ' --enable-redis-zstd --with-libzstd="' . BUILD_ROOT_PATH . '"';
|
||||
}
|
||||
|
||||
@@ -14,13 +14,14 @@ class swoole extends Extension
|
||||
{
|
||||
public function patchBeforeMake(): bool
|
||||
{
|
||||
$patched = false;
|
||||
if ($this->builder instanceof MacOSBuilder) {
|
||||
// Fix swoole with event extension <util.h> conflict bug
|
||||
$util_path = shell()->execWithResult('xcrun --show-sdk-path', false)[1][0] . '/usr/include/util.h';
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/swoole/thirdparty/php/standard/proc_open.cc', 'include <util.h>', 'include "' . $util_path . '"');
|
||||
return true;
|
||||
$patched = true;
|
||||
}
|
||||
return false;
|
||||
return $patched;
|
||||
}
|
||||
|
||||
public function getExtVersion(): ?string
|
||||
|
||||
@@ -20,6 +20,7 @@ class uv extends Extension
|
||||
|
||||
public function patchBeforeSharedMake(): bool
|
||||
{
|
||||
parent::patchBeforeSharedMake();
|
||||
if (PHP_OS_FAMILY !== 'Linux' || arch2gnu(php_uname('m')) !== 'aarch64') {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class LinuxBuilder extends UnixBuilderBase
|
||||
{
|
||||
@@ -25,22 +28,8 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
{
|
||||
$this->options = $options;
|
||||
|
||||
// check musl-cross make installed if we use musl-cross-make
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
|
||||
GlobalEnvManager::init();
|
||||
|
||||
if (getenv('SPC_LIBC') === 'musl' && !SystemUtil::isMuslDist()) {
|
||||
$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)');
|
||||
}
|
||||
}
|
||||
GlobalEnvManager::afterInit();
|
||||
|
||||
// concurrency
|
||||
$this->concurrency = intval(getenv('SPC_CONCURRENCY'));
|
||||
@@ -80,6 +69,7 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
}
|
||||
// add libstdc++, some extensions or libraries need it
|
||||
$extra_libs .= (empty($extra_libs) ? '' : ' ') . ($this->hasCpp() ? '-lstdc++ ' : '');
|
||||
$extra_libs .= (ToolchainManager::getToolchainClass() === ZigToolchain::class ? ' -lunwind' : '');
|
||||
f_putenv('SPC_EXTRA_LIBS=' . $extra_libs);
|
||||
$cflags = $this->arch_c_flags;
|
||||
f_putenv('CFLAGS=' . $cflags);
|
||||
@@ -103,7 +93,9 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
$zts = '';
|
||||
}
|
||||
$disable_jit = $this->getOption('disable-opcache-jit', false) ? '--disable-opcache-jit ' : '';
|
||||
|
||||
if (!$disable_jit && $this->getExt('opcache')) {
|
||||
f_putenv('COMPILER_EXTRA=-fno-sanitize=undefined');
|
||||
}
|
||||
$config_file_path = $this->getOption('with-config-file-path', false) ?
|
||||
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
||||
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
||||
@@ -134,6 +126,12 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
}
|
||||
|
||||
$embed_type = getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') ?: 'static';
|
||||
if ($embed_type !== 'static' && SPCTarget::isStatic()) {
|
||||
throw new WrongUsageException(
|
||||
'Linux does not support loading shared libraries when linking libc statically. ' .
|
||||
'Change SPC_CMD_VAR_PHP_EMBED_TYPE to static.'
|
||||
);
|
||||
}
|
||||
shell()->cd(SOURCE_PATH . '/php-src')
|
||||
->exec(
|
||||
getenv('SPC_CMD_PREFIX_PHP_CONFIGURE') . ' ' .
|
||||
@@ -289,34 +287,48 @@ class LinuxBuilder extends UnixBuilderBase
|
||||
->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install");
|
||||
|
||||
$ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS');
|
||||
$realLibName = 'libphp.so';
|
||||
if (preg_match('/-release\s+(\S+)/', $ldflags, $matches)) {
|
||||
$release = $matches[1];
|
||||
$realLibName = 'libphp-' . $release . '.so';
|
||||
$realLib = BUILD_LIB_PATH . '/' . $realLibName;
|
||||
rename(BUILD_LIB_PATH . '/libphp.so', $realLib);
|
||||
$cwd = getcwd();
|
||||
chdir(BUILD_LIB_PATH);
|
||||
symlink($realLibName, 'libphp.so');
|
||||
chdir(BUILD_MODULES_PATH);
|
||||
foreach ($this->getExts() as $ext) {
|
||||
if (!$ext->isBuildShared()) {
|
||||
continue;
|
||||
$libphpPath = BUILD_LIB_PATH . '/libphp.so';
|
||||
$libphpRelease = BUILD_LIB_PATH . '/' . $realLibName;
|
||||
if (!file_exists($libphpRelease) && file_exists($libphpPath)) {
|
||||
rename($libphpPath, $libphpRelease);
|
||||
}
|
||||
if (file_exists($libphpRelease)) {
|
||||
chdir(BUILD_LIB_PATH);
|
||||
if (file_exists($libphpPath)) {
|
||||
unlink($libphpPath);
|
||||
}
|
||||
$name = $ext->getName();
|
||||
$versioned = "{$name}-{$release}.so";
|
||||
$unversioned = "{$name}.so";
|
||||
if (is_file(BUILD_MODULES_PATH . "/{$versioned}")) {
|
||||
rename(BUILD_MODULES_PATH . "/{$versioned}", BUILD_MODULES_PATH . "/{$unversioned}");
|
||||
shell()->cd(BUILD_MODULES_PATH)
|
||||
->exec(sprintf(
|
||||
'patchelf --set-soname %s %s',
|
||||
escapeshellarg($unversioned),
|
||||
escapeshellarg($unversioned)
|
||||
));
|
||||
symlink($realLibName, 'libphp.so');
|
||||
}
|
||||
if (is_dir(BUILD_MODULES_PATH)) {
|
||||
chdir(BUILD_MODULES_PATH);
|
||||
foreach ($this->getExts() as $ext) {
|
||||
if (!$ext->isBuildShared()) {
|
||||
continue;
|
||||
}
|
||||
$name = $ext->getName();
|
||||
$versioned = "{$name}-{$release}.so";
|
||||
$unversioned = "{$name}.so";
|
||||
if (is_file(BUILD_MODULES_PATH . "/{$versioned}")) {
|
||||
rename(BUILD_MODULES_PATH . "/{$versioned}", BUILD_MODULES_PATH . "/{$unversioned}");
|
||||
shell()->cd(BUILD_MODULES_PATH)
|
||||
->exec(sprintf(
|
||||
'patchelf --set-soname %s %s',
|
||||
escapeshellarg($unversioned),
|
||||
escapeshellarg($unversioned)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
chdir($cwd);
|
||||
}
|
||||
if (!$this->getOption('no-strip', false) && file_exists(BUILD_LIB_PATH . '/' . $realLibName)) {
|
||||
shell()->cd(BUILD_LIB_PATH)->exec("strip --strip-all {$realLibName}");
|
||||
}
|
||||
$this->patchPhpScripts();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace SPC\builder\linux;
|
||||
|
||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
|
||||
class SystemUtil
|
||||
{
|
||||
@@ -13,6 +15,8 @@ class SystemUtil
|
||||
|
||||
public static ?string $libc_version = null;
|
||||
|
||||
private static ?string $extra_runtime_objects = null;
|
||||
|
||||
/** @noinspection PhpMissingBreakStatementInspection */
|
||||
public static function getOSRelease(): array
|
||||
{
|
||||
@@ -78,9 +82,11 @@ class SystemUtil
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function getCCType(string $cc): string
|
||||
public static function getCCType(?string $cc = null): string
|
||||
{
|
||||
$cc ??= getenv('CC');
|
||||
return match (true) {
|
||||
str_contains($cc, 'zig') => 'clang',
|
||||
str_ends_with($cc, 'c++'), str_ends_with($cc, 'cc'), str_ends_with($cc, 'g++'), str_ends_with($cc, 'gcc') => 'gcc',
|
||||
$cc === 'clang++', $cc === 'clang', str_starts_with($cc, 'musl-clang') => 'clang',
|
||||
default => throw new RuntimeException("unknown cc type: {$cc}"),
|
||||
@@ -188,12 +194,12 @@ class SystemUtil
|
||||
/**
|
||||
* Get libc version string from ldd
|
||||
*/
|
||||
public static function getLibcVersionIfExists(): ?string
|
||||
public static function getLibcVersionIfExists(?string $libc = null): ?string
|
||||
{
|
||||
if (self::$libc_version !== null) {
|
||||
return self::$libc_version;
|
||||
}
|
||||
if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'glibc') {
|
||||
if ($libc === 'glibc') {
|
||||
$result = shell()->execWithResult('ldd --version', false);
|
||||
if ($result[0] !== 0) {
|
||||
return null;
|
||||
@@ -208,7 +214,7 @@ class SystemUtil
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') {
|
||||
if ($libc === 'musl') {
|
||||
if (self::isMuslDist()) {
|
||||
$result = shell()->execWithResult('ldd 2>&1', false);
|
||||
} else {
|
||||
@@ -224,4 +230,37 @@ class SystemUtil
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getExtraRuntimeObjects(): string
|
||||
{
|
||||
if (ToolchainManager::getToolchainClass() !== ZigToolchain::class) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (self::$extra_runtime_objects !== null) {
|
||||
return self::$extra_runtime_objects;
|
||||
}
|
||||
|
||||
$paths = ['/usr/lib/gcc', '/usr/local/lib/gcc'];
|
||||
$objects = ['crtbeginS.o', 'crtendS.o'];
|
||||
$found = [];
|
||||
|
||||
foreach ($objects as $obj) {
|
||||
$located = null;
|
||||
foreach ($paths as $base) {
|
||||
$output = shell_exec("find {$base} -name {$obj} -print -quit 2>/dev/null");
|
||||
$line = trim((string) $output);
|
||||
if ($line !== '') {
|
||||
$located = $line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($located) {
|
||||
$found[] = $located;
|
||||
}
|
||||
}
|
||||
|
||||
self::$extra_runtime_objects = implode(' ', $found);
|
||||
return implode(' ', $found);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\linux\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
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"';
|
||||
$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)
|
||||
->exec(
|
||||
"{$cppflags} {$cxxflags} {$ldflags} " .
|
||||
|
||||
@@ -12,6 +12,8 @@ class libmemcached extends LinuxLibraryBase
|
||||
|
||||
public function build(): void
|
||||
{
|
||||
UnixCMakeExecutor::create($this)->build();
|
||||
UnixCMakeExecutor::create($this)
|
||||
->addConfigureArgs('-DCMAKE_INSTALL_RPATH=""')
|
||||
->build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,8 @@ class openssl extends LinuxLibraryBase
|
||||
|
||||
$ex_lib = trim($ex_lib);
|
||||
|
||||
$clang_postfix = SystemUtil::getCCType(getenv('CC')) === 'clang' ? '-clang' : '';
|
||||
/* @phpstan-ignore-next-line */
|
||||
$clang_postfix = SystemUtil::getCCType() === 'clang' && (GNU_ARCH === 'x86_64' || PHP_OS_FAMILY === 'Darwin') ? '-clang' : '';
|
||||
|
||||
shell()->cd($this->source_dir)->initializeEnv($this)
|
||||
->exec(
|
||||
|
||||
@@ -29,6 +29,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
|
||||
// apply global environment variables
|
||||
GlobalEnvManager::init();
|
||||
GlobalEnvManager::afterInit();
|
||||
|
||||
// ---------- set necessary compile vars ----------
|
||||
// concurrency
|
||||
|
||||
@@ -119,9 +119,9 @@ trait UnixLibraryTrait
|
||||
{
|
||||
$env = getenv($this->getSnakeCaseName() . '_CFLAGS') ?: '';
|
||||
if (!str_contains($env, $this->builder->arch_c_flags)) {
|
||||
$env .= $this->builder->arch_c_flags;
|
||||
$env .= ' ' . $this->builder->arch_c_flags;
|
||||
}
|
||||
return $env;
|
||||
return trim($env);
|
||||
}
|
||||
|
||||
public function getLibExtraLdFlags(): string
|
||||
@@ -138,8 +138,8 @@ trait UnixLibraryTrait
|
||||
{
|
||||
$env = getenv($this->getSnakeCaseName() . '_CXXFLAGS') ?: '';
|
||||
if (!str_contains($env, $this->builder->arch_cxx_flags)) {
|
||||
$env .= $this->builder->arch_cxx_flags;
|
||||
$env .= ' ' . $this->builder->arch_cxx_flags;
|
||||
}
|
||||
return $env;
|
||||
return trim($env);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,11 @@ use SPC\store\Config;
|
||||
use SPC\store\CurlHook;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\pkg\GoXcaddy;
|
||||
use SPC\util\DependencyUtil;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
abstract class UnixBuilderBase extends BuilderBase
|
||||
{
|
||||
@@ -200,21 +203,23 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
$util = new SPCConfigUtil($this);
|
||||
$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']}";
|
||||
if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') {
|
||||
if (SPCTarget::isStatic()) {
|
||||
$lens .= ' -static';
|
||||
}
|
||||
// if someone changed to EMBED_TYPE=shared, we need to add LD_LIBRARY_PATH
|
||||
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);
|
||||
if ($ret !== 0) {
|
||||
throw new RuntimeException('embed failed sanity check: build failed. Error message: ' . implode("\n", $out));
|
||||
}
|
||||
// if someone changed to --enable-embed=shared, we need to add LD_LIBRARY_PATH
|
||||
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
|
||||
$ext_path = 'LD_LIBRARY_PATH=' . BUILD_ROOT_PATH . '/lib:$LD_LIBRARY_PATH ';
|
||||
FileSystem::removeFileIfExists(BUILD_ROOT_PATH . '/lib/libphp.a');
|
||||
} else {
|
||||
$ext_path = '';
|
||||
FileSystem::removeFileIfExists(BUILD_ROOT_PATH . '/lib/libphp.so');
|
||||
}
|
||||
[$ret, $output] = shell()->cd($sample_file_path)->execWithResult($ext_path . './embed');
|
||||
if ($ret !== 0 || trim(implode('', $output)) !== 'hello') {
|
||||
throw new RuntimeException('embed failed sanity check: run failed. Error message: ' . implode("\n", $output));
|
||||
@@ -301,18 +306,6 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
*/
|
||||
protected function buildFrankenphp(): void
|
||||
{
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Linux' => 'linux',
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => throw new RuntimeException('Unsupported OS: ' . PHP_OS_FAMILY),
|
||||
};
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
|
||||
// define executables for go and xcaddy
|
||||
$xcaddy_exec = PKG_ROOT_PATH . "/go-xcaddy-{$arch}-{$os}/bin/xcaddy";
|
||||
|
||||
$nobrotli = $this->getLib('brotli') === null ? ',nobrotli' : '';
|
||||
$nowatcher = $this->getLib('watcher') === null ? ',nowatcher' : '';
|
||||
$xcaddyModules = getenv('SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES');
|
||||
@@ -325,7 +318,10 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
$xcaddyModules = str_replace('--with github.com/dunglas/caddy-cbrotli', '', $xcaddyModules);
|
||||
}
|
||||
$lrt = PHP_OS_FAMILY === 'Linux' ? '-lrt' : '';
|
||||
$releaseInfo = json_decode(Downloader::curlExec('https://api.github.com/repos/php/frankenphp/releases/latest', retries: 3, hooks: [[CurlHook::class, 'setupGithubToken']]), true);
|
||||
$releaseInfo = json_decode(Downloader::curlExec(
|
||||
'https://api.github.com/repos/php/frankenphp/releases/latest',
|
||||
hooks: [[CurlHook::class, 'setupGithubToken']],
|
||||
), true);
|
||||
$frankenPhpVersion = $releaseInfo['tag_name'];
|
||||
$libphpVersion = $this->getPHPVersion();
|
||||
if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'shared') {
|
||||
@@ -334,21 +330,19 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
$debugFlags = $this->getOption('no-strip') ? "'-w -s' " : '';
|
||||
$extLdFlags = "-extldflags '-pie'";
|
||||
$muslTags = '';
|
||||
if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') {
|
||||
$staticFlags = '';
|
||||
if (SPCTarget::isStatic()) {
|
||||
$extLdFlags = "-extldflags '-static-pie -Wl,-z,stack-size=0x80000'";
|
||||
$muslTags = 'static_build,';
|
||||
$staticFlags = '-static -static-pie';
|
||||
}
|
||||
|
||||
$config = (new SPCConfigUtil($this))->config($this->ext_list, $this->lib_list, with_dependencies: true);
|
||||
|
||||
$env = [
|
||||
'PATH' => PKG_ROOT_PATH . "/go-xcaddy-{$arch}-{$os}/bin:" . getenv('PATH'),
|
||||
'GOROOT' => PKG_ROOT_PATH . "/go-xcaddy-{$arch}-{$os}",
|
||||
'GOBIN' => PKG_ROOT_PATH . "/go-xcaddy-{$arch}-{$os}/bin",
|
||||
'GOPATH' => PKG_ROOT_PATH . '/go',
|
||||
'CGO_ENABLED' => '1',
|
||||
'CGO_CFLAGS' => $config['cflags'],
|
||||
'CGO_LDFLAGS' => "{$config['ldflags']} {$config['libs']} {$lrt}",
|
||||
'CGO_LDFLAGS' => "{$staticFlags} {$config['ldflags']} {$config['libs']} {$lrt}",
|
||||
'XCADDY_GO_BUILD_FLAGS' => '-buildmode=pie ' .
|
||||
'-ldflags \"-linkmode=external ' . $extLdFlags . ' ' . $debugFlags .
|
||||
'-X \'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP ' .
|
||||
@@ -356,8 +350,19 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
"-tags={$muslTags}nobadger,nomysql,nopgx{$nobrotli}{$nowatcher}",
|
||||
'LD_LIBRARY_PATH' => BUILD_LIB_PATH,
|
||||
];
|
||||
foreach (GoXcaddy::getEnvironment() as $key => $value) {
|
||||
if ($key === 'PATH') {
|
||||
GlobalEnvManager::addPathIfNotExists($value);
|
||||
} else {
|
||||
$env[$key] = $value;
|
||||
}
|
||||
}
|
||||
shell()->cd(BUILD_BIN_PATH)
|
||||
->setEnv($env)
|
||||
->exec("{$xcaddy_exec} build --output frankenphp {$xcaddyModules}");
|
||||
->exec("xcaddy build --output frankenphp {$xcaddyModules}");
|
||||
|
||||
if (!$this->getOption('no-strip', false) && file_exists(BUILD_BIN_PATH . '/frankenphp')) {
|
||||
shell()->cd(BUILD_BIN_PATH)->exec('strip --strip-all frankenphp');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ trait attr
|
||||
protected function build(): void
|
||||
{
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->appendEnv([
|
||||
'CFLAGS' => '-Wno-int-conversion -Wno-implicit-function-declaration',
|
||||
])
|
||||
->exec('libtoolize --force --copy')
|
||||
->exec('./autogen.sh || autoreconf -if')
|
||||
->configure('--disable-nls')
|
||||
|
||||
@@ -31,7 +31,7 @@ trait gettext
|
||||
$autoconf->addConfigureArgs('--disable-threads');
|
||||
}
|
||||
|
||||
$autoconf->configure()->make(with_clean: true);
|
||||
$autoconf->configure()->make();
|
||||
$this->patchLaDependencyPrefix();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,19 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait imagemagick
|
||||
{
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
@@ -32,17 +33,16 @@ trait imagemagick
|
||||
->optionalLib('freetype', ...ac_with_args('freetype'))
|
||||
->optionalLib('bzip2', ...ac_with_args('bzlib'))
|
||||
->addConfigureArgs(
|
||||
// TODO: glibc rh 10 toolset's libgomp.a was built without -fPIC so we can't use openmp without depending on libgomp.so
|
||||
getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10') ? '--disable-openmp' : '--enable-openmp',
|
||||
'--disable-openmp',
|
||||
'--without-jxl',
|
||||
'--without-x',
|
||||
);
|
||||
|
||||
// special: linux musl needs `-static`
|
||||
$ldflags = ($this instanceof LinuxLibraryBase) && getenv('SPC_LIBC') !== 'glibc' ? ('-static -ldl') : '-ldl';
|
||||
// special: linux-static target needs `-static`
|
||||
$ldflags = SPCTarget::isStatic() ? ('-static -ldl') : '-ldl';
|
||||
|
||||
// special: macOS needs -iconv
|
||||
$libs = $this instanceof MacOSLibraryBase ? '-liconv' : '';
|
||||
$libs = SPCTarget::getTargetOS() === 'Darwin' ? '-liconv' : '';
|
||||
|
||||
$ac->appendEnv([
|
||||
'LDFLAGS' => $ldflags,
|
||||
|
||||
@@ -6,12 +6,13 @@ namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait ldap
|
||||
{
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
@@ -26,8 +27,10 @@ trait ldap
|
||||
'--disable-slapd',
|
||||
'--without-systemd',
|
||||
'--without-cyrus-sasl',
|
||||
'ac_cv_func_pthread_kill_other_threads_np=no'
|
||||
)
|
||||
->appendEnv([
|
||||
'CFLAGS' => '-Wno-date-time',
|
||||
'LDFLAGS' => "-L{$this->getLibDir()}",
|
||||
'CPPFLAGS' => "-I{$this->getIncludeDir()}",
|
||||
])
|
||||
|
||||
@@ -4,22 +4,24 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
use SPC\util\executor\UnixCMakeExecutor;
|
||||
|
||||
trait libaom
|
||||
{
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
$extra = getenv('COMPILER_EXTRA');
|
||||
if (ToolchainManager::getToolchainClass() === ZigToolchain::class) {
|
||||
$new = trim($extra . ' -D_GNU_SOURCE');
|
||||
f_putenv("COMPILER_EXTRA={$new}");
|
||||
}
|
||||
UnixCMakeExecutor::create($this)
|
||||
->setBuildDir("{$this->source_dir}/builddir")
|
||||
->addConfigureArgs('-DAOM_TARGET_CPU=generic')
|
||||
->build();
|
||||
f_putenv("COMPILER_EXTRA={$extra}");
|
||||
$this->patchPkgconfPrefix(['aom.pc']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,11 @@ trait liblz4
|
||||
{
|
||||
shell()->cd($this->source_dir)->initializeEnv($this)
|
||||
->exec("make PREFIX='' clean")
|
||||
->exec("make -j{$this->builder->concurrency} PREFIX=''")
|
||||
->exec("make lib -j{$this->builder->concurrency} PREFIX=''");
|
||||
|
||||
FileSystem::replaceFileStr($this->source_dir . '/Makefile', '$(MAKE) -C $(PRGDIR) $@', '');
|
||||
|
||||
shell()->cd($this->source_dir)
|
||||
->exec("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH);
|
||||
|
||||
$this->patchPkgconfPrefix(['liblz4.pc']);
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
|
||||
trait librdkafka
|
||||
@@ -16,7 +17,18 @@ trait librdkafka
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
FileSystem::replaceFileStr(
|
||||
$this->source_dir . '/lds-gen.py',
|
||||
"funcs.append('rd_ut_coverage_check')",
|
||||
''
|
||||
);
|
||||
FileSystem::replaceFileStr(
|
||||
$this->source_dir . '/src/rd.h',
|
||||
'#error "IOV_MAX not defined"',
|
||||
"#define IOV_MAX 1024\n#define __GNU__"
|
||||
);
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->appendEnv(['CFLAGS' => '-Wno-int-conversion -Wno-unused-but-set-variable -Wno-unused-variable'])
|
||||
->optionalLib(
|
||||
'zstd',
|
||||
function ($lib) {
|
||||
|
||||
@@ -33,7 +33,13 @@ trait libxslt
|
||||
'--without-debugger',
|
||||
"--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_LD_LIBRARY_PATH') && getenv('SPC_LIBRARY_PATH')) {
|
||||
$ac->appendEnv([
|
||||
'LD_LIBRARY_PATH' => getenv('SPC_LD_LIBRARY_PATH'),
|
||||
'LIBRARY_PATH' => getenv('SPC_LIBRARY_PATH'),
|
||||
]);
|
||||
}
|
||||
$ac->configure()->make();
|
||||
|
||||
$this->patchPkgconfPrefix(['libexslt.pc']);
|
||||
$this->patchLaDependencyPrefix();
|
||||
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\util\executor\UnixCMakeExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait mimalloc
|
||||
{
|
||||
@@ -13,9 +14,9 @@ trait mimalloc
|
||||
$cmake = UnixCMakeExecutor::create($this)
|
||||
->addConfigureArgs(
|
||||
'-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->build();
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait ncurses
|
||||
{
|
||||
@@ -14,6 +15,9 @@ trait ncurses
|
||||
$filelist = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true);
|
||||
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->appendEnv([
|
||||
'LDFLAGS' => SPCTarget::isStatic() ? '-static' : '',
|
||||
])
|
||||
->configure(
|
||||
'--enable-overwrite',
|
||||
'--with-curses-h',
|
||||
|
||||
@@ -4,8 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait pkgconfig
|
||||
{
|
||||
@@ -13,8 +13,8 @@ trait pkgconfig
|
||||
{
|
||||
UnixAutoconfExecutor::create($this)
|
||||
->appendEnv([
|
||||
'CFLAGS' => PHP_OS_FAMILY !== 'Linux' ? '-Wimplicit-function-declaration -Wno-int-conversion' : '',
|
||||
'LDFLAGS' => !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? '' : '--static',
|
||||
'CFLAGS' => '-Wimplicit-function-declaration -Wno-int-conversion',
|
||||
'LDFLAGS' => SPCTarget::isStatic() ? '--static' : '',
|
||||
])
|
||||
->configure(
|
||||
'--with-internal-glib',
|
||||
|
||||
@@ -8,6 +8,7 @@ use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait postgresql
|
||||
{
|
||||
@@ -50,7 +51,7 @@ trait postgresql
|
||||
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||
if (!empty($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}");
|
||||
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||
|
||||
@@ -18,7 +18,7 @@ trait watcher
|
||||
{
|
||||
shell()->cd($this->source_dir . '/watcher-c')
|
||||
->initializeEnv($this)
|
||||
->exec(getenv('CC') . ' -c -o libwatcher-c.o ./src/watcher-c.cpp -I ./include -I ../include -std=c++17 -Wall -Wextra -fPIC')
|
||||
->exec(getenv('CXX') . ' -c -o libwatcher-c.o ./src/watcher-c.cpp -I ./include -I ../include -std=c++17 -Wall -Wextra -fPIC')
|
||||
->exec(getenv('AR') . ' rcs libwatcher-c.a libwatcher-c.o');
|
||||
|
||||
copy($this->source_dir . '/watcher-c/libwatcher-c.a', BUILD_LIB_PATH . '/libwatcher-c.a');
|
||||
|
||||
@@ -34,6 +34,7 @@ class WindowsBuilder extends BuilderBase
|
||||
$this->options = $options;
|
||||
|
||||
GlobalEnvManager::init();
|
||||
GlobalEnvManager::afterInit();
|
||||
|
||||
// ---------- set necessary options ----------
|
||||
// set sdk (require visual studio 16 or 17)
|
||||
|
||||
@@ -99,6 +99,7 @@ abstract class BaseCommand extends Command
|
||||
// init GlobalEnv
|
||||
if (!$this instanceof BuildCommand) {
|
||||
GlobalEnvManager::init();
|
||||
f_putenv('SPC_SKIP_TOOLCHAIN_CHECK=yes');
|
||||
}
|
||||
if ($this->shouldExecute()) {
|
||||
try {
|
||||
|
||||
@@ -13,6 +13,7 @@ use SPC\store\SourcePatcher;
|
||||
use SPC\util\DependencyUtil;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\LicenseDumper;
|
||||
use SPC\util\SPCTarget;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
@@ -63,8 +64,8 @@ class BuildPHPCommand extends BuildCommand
|
||||
|
||||
// check dynamic extension build env
|
||||
// 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!');
|
||||
if (!empty($shared_extensions) && SPCTarget::isStatic()) {
|
||||
$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;
|
||||
}
|
||||
$static_and_shared = array_intersect($static_extensions, $shared_extensions);
|
||||
@@ -133,6 +134,8 @@ class BuildPHPCommand extends BuildCommand
|
||||
// print info
|
||||
$indent_texts = [
|
||||
'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')',
|
||||
'Build Target' => getenv('SPC_TARGET'),
|
||||
'Build Toolchain' => getenv('SPC_TOOLCHAIN'),
|
||||
'Build SAPI' => $builder->getBuildTypeName($rule),
|
||||
'Static Extensions (' . count($static_extensions) . ')' => implode(',', $static_extensions),
|
||||
'Shared Extensions (' . count($shared_extensions) . ')' => implode(',', $shared_extensions),
|
||||
|
||||
@@ -5,12 +5,14 @@ declare(strict_types=1);
|
||||
namespace SPC\command;
|
||||
|
||||
use SPC\exception\ValidationException;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
use SPC\util\ConfigValidator;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
#[AsCommand('craft', 'Build static-php from craft.yml')]
|
||||
class CraftCommand extends BaseCommand
|
||||
class CraftCommand extends BuildCommand
|
||||
{
|
||||
public function configure(): void
|
||||
{
|
||||
@@ -71,7 +73,16 @@ class CraftCommand extends BaseCommand
|
||||
$retcode = $this->runCommand('install-pkg', 'go-xcaddy');
|
||||
if ($retcode !== 0) {
|
||||
$this->output->writeln('<error>craft go-xcaddy failed</error>');
|
||||
$this->log("craft go-xcaddy failed with code: {$retcode}", true);
|
||||
$this->log("craft: spc install-pkg go-xcaddy failed with code: {$retcode}", true);
|
||||
return static::FAILURE;
|
||||
}
|
||||
}
|
||||
// install zig if requested
|
||||
if (ToolchainManager::getToolchainClass() === ZigToolchain::class) {
|
||||
$retcode = $this->runCommand('install-pkg', 'zig');
|
||||
if ($retcode !== 0) {
|
||||
$this->output->writeln('<error>craft zig failed</error>');
|
||||
$this->log("craft: spc install-pkg zig failed with code: {$retcode}", true);
|
||||
return static::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\command;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\exception\FileSystemException;
|
||||
@@ -14,6 +13,7 @@ use SPC\store\Config;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\LockFile;
|
||||
use SPC\util\DependencyUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@@ -223,8 +223,8 @@ class DownloadCommand extends BaseCommand
|
||||
'{name}' => $source,
|
||||
'{arch}' => arch2gnu(php_uname('m')),
|
||||
'{os}' => strtolower(PHP_OS_FAMILY),
|
||||
'{libc}' => getenv('SPC_LIBC') ?: 'default',
|
||||
'{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default',
|
||||
'{libc}' => SPCTarget::getLibc() ?? 'default',
|
||||
'{libcver}' => SPCTarget::getLibcVersion() ?? 'default',
|
||||
];
|
||||
$find = str_replace(array_keys($replace), array_values($replace), Config::getPreBuilt('match-pattern'));
|
||||
// find filename in asset list
|
||||
|
||||
@@ -11,7 +11,7 @@ use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
#[AsCommand('spc-config', 'Build dependencies')]
|
||||
class SPCConfigCommand extends BuildCommand
|
||||
class SPCConfigCommand extends BaseCommand
|
||||
{
|
||||
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\LibraryBase;
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\command\BuildCommand;
|
||||
use SPC\exception\ExceptionHandler;
|
||||
use SPC\exception\FileSystemException;
|
||||
@@ -16,6 +15,7 @@ use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\LockFile;
|
||||
use SPC\util\DependencyUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
@@ -76,8 +76,8 @@ class PackLibCommand extends BuildCommand
|
||||
'{name}' => $lib->getName(),
|
||||
'{arch}' => arch2gnu(php_uname('m')),
|
||||
'{os}' => strtolower(PHP_OS_FAMILY),
|
||||
'{libc}' => getenv('SPC_LIBC') ?: 'default',
|
||||
'{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default',
|
||||
'{libc}' => SPCTarget::getLibc() ?? 'default',
|
||||
'{libcver}' => SPCTarget::getLibcVersion() ?? 'default',
|
||||
];
|
||||
// detect suffix, for proper tar option
|
||||
$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) {
|
||||
$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 ($method->getAttributes() as $a) {
|
||||
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;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\doctor\AsCheckItem;
|
||||
use SPC\doctor\AsFixItem;
|
||||
use SPC\doctor\CheckResult;
|
||||
use SPC\doctor\OptionalCheck;
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
@@ -16,20 +16,20 @@ use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\PackageManager;
|
||||
use SPC\store\SourcePatcher;
|
||||
use SPC\toolchain\MuslToolchain;
|
||||
|
||||
#[OptionalCheck([self::class, 'optionalCheck'])]
|
||||
class LinuxMuslCheck
|
||||
{
|
||||
public static function optionalCheck(): bool
|
||||
{
|
||||
return getenv('SPC_TOOLCHAIN') === MuslToolchain::class;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
#[AsCheckItem('if musl-wrapper is installed', limit_os: 'Linux', level: 800)]
|
||||
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');
|
||||
}
|
||||
|
||||
$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')) {
|
||||
return CheckResult::ok();
|
||||
@@ -40,13 +40,6 @@ class LinuxMuslCheck
|
||||
#[AsCheckItem('if musl-cross-make is installed', limit_os: 'Linux', level: 799)]
|
||||
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');
|
||||
}
|
||||
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$cross_compile_lib = "/usr/local/musl/{$arch}-linux-musl/lib/libc.a";
|
||||
$cross_compile_gcc = "/usr/local/musl/bin/{$arch}-linux-musl-gcc";
|
||||
|
||||
@@ -51,6 +51,7 @@ class LinuxToolCheckList
|
||||
'binutils-gold' => 'ld.gold',
|
||||
'base-devel' => 'automake',
|
||||
'gettext-devel' => 'gettextize',
|
||||
'gettext-dev' => 'gettextize',
|
||||
];
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
|
||||
53
src/SPC/doctor/item/ZigCheck.php
Normal file
53
src/SPC/doctor/item/ZigCheck.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\doctor\item;
|
||||
|
||||
use SPC\doctor\AsCheckItem;
|
||||
use SPC\doctor\AsFixItem;
|
||||
use SPC\doctor\CheckResult;
|
||||
use SPC\doctor\OptionalCheck;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\PackageManager;
|
||||
use SPC\store\pkg\Zig;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
|
||||
#[OptionalCheck([self::class, 'optionalCheck'])]
|
||||
class ZigCheck
|
||||
{
|
||||
public static function optionalCheck(): bool
|
||||
{
|
||||
return getenv('SPC_TOOLCHAIN') === ZigToolchain::class;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
#[AsCheckItem('if zig is installed', level: 800)]
|
||||
public function checkZig(): CheckResult
|
||||
{
|
||||
if (Zig::isInstalled()) {
|
||||
return CheckResult::ok();
|
||||
}
|
||||
return CheckResult::fail('zig is not installed', 'install-zig');
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
/**
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
#[AsFixItem('install-zig')]
|
||||
public function fixMuslCrossMake(): bool
|
||||
{
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => 'linux',
|
||||
};
|
||||
PackageManager::installPackage("zig-{$arch}-{$os}");
|
||||
return Zig::isInstalled();
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,13 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\store;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\pkg\CustomPackage;
|
||||
use SPC\store\source\CustomSourceBase;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
/**
|
||||
* Source Downloader.
|
||||
@@ -365,8 +365,8 @@ class Downloader
|
||||
$cls = new $class();
|
||||
if (in_array($name, $cls->getSupportName())) {
|
||||
(new $class())->fetch($name, $force, $pkg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -591,7 +591,12 @@ class Downloader
|
||||
|
||||
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,27 +11,27 @@ use SPC\builder\unix\UnixBuilderBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class SourcePatcher
|
||||
{
|
||||
public static function init(): void
|
||||
{
|
||||
// FileSystem::addSourceExtractHook('swow', [SourcePatcher::class, 'patchSwow']);
|
||||
FileSystem::addSourceExtractHook('micro', [SourcePatcher::class, 'patchMicro']);
|
||||
FileSystem::addSourceExtractHook('openssl', [SourcePatcher::class, 'patchOpenssl11Darwin']);
|
||||
FileSystem::addSourceExtractHook('swoole', [SourcePatcher::class, 'patchSwoole']);
|
||||
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchPhpLibxml212']);
|
||||
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchGDWin32']);
|
||||
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchFfiCentos7FixO3strncmp']);
|
||||
FileSystem::addSourceExtractHook('sqlsrv', [SourcePatcher::class, 'patchSQLSRVWin32']);
|
||||
FileSystem::addSourceExtractHook('pdo_sqlsrv', [SourcePatcher::class, 'patchSQLSRVWin32']);
|
||||
FileSystem::addSourceExtractHook('yaml', [SourcePatcher::class, 'patchYamlWin32']);
|
||||
FileSystem::addSourceExtractHook('libyaml', [SourcePatcher::class, 'patchLibYaml']);
|
||||
FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchImapLicense']);
|
||||
FileSystem::addSourceExtractHook('ext-imagick', [SourcePatcher::class, 'patchImagickWith84']);
|
||||
FileSystem::addSourceExtractHook('libaom', [SourcePatcher::class, 'patchLibaomForAlpine']);
|
||||
FileSystem::addSourceExtractHook('attr', [SourcePatcher::class, 'patchAttrForAlpine']);
|
||||
FileSystem::addSourceExtractHook('gmssl', [SourcePatcher::class, 'patchGMSSL']);
|
||||
// FileSystem::addSourceExtractHook('swow', [__CLASS__, 'patchSwow']);
|
||||
FileSystem::addSourceExtractHook('openssl', [__CLASS__, 'patchOpenssl11Darwin']);
|
||||
FileSystem::addSourceExtractHook('swoole', [__CLASS__, 'patchSwoole']);
|
||||
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchPhpLibxml212']);
|
||||
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchGDWin32']);
|
||||
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchFfiCentos7FixO3strncmp']);
|
||||
FileSystem::addSourceExtractHook('sqlsrv', [__CLASS__, 'patchSQLSRVWin32']);
|
||||
FileSystem::addSourceExtractHook('pdo_sqlsrv', [__CLASS__, 'patchSQLSRVWin32']);
|
||||
FileSystem::addSourceExtractHook('yaml', [__CLASS__, 'patchYamlWin32']);
|
||||
FileSystem::addSourceExtractHook('libyaml', [__CLASS__, 'patchLibYaml']);
|
||||
FileSystem::addSourceExtractHook('php-src', [__CLASS__, 'patchImapLicense']);
|
||||
FileSystem::addSourceExtractHook('ext-imagick', [__CLASS__, 'patchImagickWith84']);
|
||||
FileSystem::addSourceExtractHook('libaom', [__CLASS__, 'patchLibaomForAlpine']);
|
||||
FileSystem::addSourceExtractHook('attr', [__CLASS__, 'patchAttrForAlpine']);
|
||||
FileSystem::addSourceExtractHook('gmssl', [__CLASS__, 'patchGMSSL']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,9 +73,9 @@ class SourcePatcher
|
||||
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/build/php.m4', 'PKG_CHECK_MODULES(', 'PKG_CHECK_MODULES_STATIC(');
|
||||
|
||||
if ($builder->getOption('enable-micro-win32')) {
|
||||
SourcePatcher::patchMicroWin32();
|
||||
self::patchMicroWin32();
|
||||
} else {
|
||||
SourcePatcher::unpatchMicroWin32();
|
||||
self::unpatchMicroWin32();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class SourcePatcher
|
||||
* @throws RuntimeException
|
||||
* @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')) {
|
||||
return false;
|
||||
@@ -152,11 +152,7 @@ class SourcePatcher
|
||||
|
||||
foreach ($patches as $patch) {
|
||||
logger()->info("Patching micro with {$patch}");
|
||||
$patchesStr = str_replace('/', DIRECTORY_SEPARATOR, $patch);
|
||||
f_passthru(
|
||||
'cd ' . SOURCE_PATH . '/php-src && ' .
|
||||
(PHP_OS_FAMILY === 'Windows' ? 'type' : 'cat') . ' ' . $patchesStr . ' | patch -p1 '
|
||||
);
|
||||
self::patchFile(SOURCE_PATH . "/php-src/{$patch}", SOURCE_PATH . '/php-src');
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -165,24 +161,32 @@ class SourcePatcher
|
||||
/**
|
||||
* 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 bool $reverse Reverse patches (default: False)
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
$patch_file = ROOT_DIR . "/src/globals/patch/{$patch_name}";
|
||||
$patch_str = str_replace('/', DIRECTORY_SEPARATOR, $patch_file);
|
||||
$patch_str = FileSystem::convertPath($patch_file);
|
||||
if (!file_exists($patch_str)) {
|
||||
throw new RuntimeException("Patch file [{$patch_str}] does not exist");
|
||||
}
|
||||
|
||||
// Copy patch from phar
|
||||
if (\Phar::running() !== '') {
|
||||
file_put_contents(SOURCE_PATH . '/' . $patch_name, file_get_contents($patch_file));
|
||||
$patch_str = str_replace('/', DIRECTORY_SEPARATOR, SOURCE_PATH . '/' . $patch_name);
|
||||
if (str_starts_with($patch_str, 'phar://')) {
|
||||
$filename = pathinfo($patch_file, PATHINFO_BASENAME);
|
||||
file_put_contents(SOURCE_PATH . "/{$filename}", file_get_contents($patch_file));
|
||||
$patch_str = FileSystem::convertPath(SOURCE_PATH . "/{$filename}");
|
||||
}
|
||||
|
||||
// detect
|
||||
@@ -229,6 +233,7 @@ class SourcePatcher
|
||||
'PHP_ADD_INCLUDE([$ext_srcdir])',
|
||||
"PHP_ADD_INCLUDE( [\$ext_srcdir] )\n PHP_ADD_INCLUDE([\$abs_srcdir/ext])"
|
||||
);
|
||||
|
||||
// swoole 5.1.3 build fix
|
||||
// get swoole version first
|
||||
$file = SOURCE_PATH . '/php-src/ext/swoole/include/swoole_version.h';
|
||||
@@ -242,6 +247,7 @@ class SourcePatcher
|
||||
if ($version === '5.1.3') {
|
||||
self::patchFile('spc_fix_swoole_50513.patch', SOURCE_PATH . '/php-src/ext/swoole');
|
||||
}
|
||||
self::patchFile('swoole_fix_date_time.patch', SOURCE_PATH . '/php-src/ext/swoole');
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -448,7 +454,7 @@ class SourcePatcher
|
||||
}
|
||||
$extnum = intval($match[1]);
|
||||
if ($extnum < 30800) {
|
||||
SourcePatcher::patchFile('imagick_php84_before_30800.patch', SOURCE_PATH . '/php-src/ext/imagick');
|
||||
self::patchFile('imagick_php84_before_30800.patch', SOURCE_PATH . '/php-src/ext/imagick');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -456,7 +462,7 @@ class SourcePatcher
|
||||
|
||||
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;
|
||||
}
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
|
||||
@@ -466,14 +472,14 @@ class SourcePatcher
|
||||
if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0 && intval($match[1]) < 80316) {
|
||||
return false;
|
||||
}
|
||||
SourcePatcher::patchFile('ffi_centos7_fix_O3_strncmp.patch', SOURCE_PATH . '/php-src');
|
||||
self::patchFile('ffi_centos7_fix_O3_strncmp.patch', SOURCE_PATH . '/php-src');
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function patchLibaomForAlpine(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist()) {
|
||||
SourcePatcher::patchFile('libaom_posix_implict.patch', SOURCE_PATH . '/libaom');
|
||||
self::patchFile('libaom_posix_implict.patch', SOURCE_PATH . '/libaom');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -482,7 +488,7 @@ class SourcePatcher
|
||||
public static function patchAttrForAlpine(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist() || PHP_OS_FAMILY === 'Darwin') {
|
||||
SourcePatcher::patchFile('attr_alpine_gethostname.patch', SOURCE_PATH . '/attr');
|
||||
self::patchFile('attr_alpine_gethostname.patch', SOURCE_PATH . '/attr');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -10,8 +10,9 @@ abstract class CustomPackage
|
||||
|
||||
abstract public function fetch(string $name, bool $force = false, ?array $config = null): void;
|
||||
|
||||
public function extract(string $name): void
|
||||
{
|
||||
throw new \RuntimeException("Extract method not implemented for package: {$name}");
|
||||
}
|
||||
abstract public function extract(string $name): void;
|
||||
|
||||
abstract public static function getEnvironment(): array;
|
||||
|
||||
abstract public static function isInstalled(): bool;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,26 @@ namespace SPC\store\pkg;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\LockFile;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class GoXcaddy extends CustomPackage
|
||||
{
|
||||
public static function isInstalled(): bool
|
||||
{
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => 'linux',
|
||||
};
|
||||
|
||||
$packageName = "go-xcaddy-{$arch}-{$os}";
|
||||
$pkgroot = PKG_ROOT_PATH;
|
||||
$folder = "{$pkgroot}/{$packageName}";
|
||||
|
||||
return is_dir($folder) && is_file("{$folder}/bin/go") && is_file("{$folder}/bin/xcaddy");
|
||||
}
|
||||
|
||||
public function getSupportName(): array
|
||||
{
|
||||
return [
|
||||
@@ -26,6 +42,9 @@ class GoXcaddy extends CustomPackage
|
||||
$pkgroot = PKG_ROOT_PATH;
|
||||
$go_exec = "{$pkgroot}/{$name}/bin/go";
|
||||
$xcaddy_exec = "{$pkgroot}/{$name}/bin/xcaddy";
|
||||
if ($force) {
|
||||
FileSystem::removeDir("{$pkgroot}/{$name}");
|
||||
}
|
||||
if (file_exists($go_exec) && file_exists($xcaddy_exec)) {
|
||||
return;
|
||||
}
|
||||
@@ -62,7 +81,6 @@ class GoXcaddy extends CustomPackage
|
||||
|
||||
FileSystem::extractPackage($name, $source_type, $filename, $extract);
|
||||
|
||||
GlobalEnvManager::init();
|
||||
// install xcaddy
|
||||
shell()
|
||||
->appendEnv([
|
||||
@@ -71,6 +89,27 @@ class GoXcaddy extends CustomPackage
|
||||
'GOBIN' => "{$pkgroot}/{$name}/bin",
|
||||
'GOPATH' => "{$pkgroot}/go",
|
||||
])
|
||||
->exec("{$go_exec} install github.com/caddyserver/xcaddy/cmd/xcaddy@latest");
|
||||
->exec("CC=cc {$go_exec} install github.com/caddyserver/xcaddy/cmd/xcaddy@latest");
|
||||
}
|
||||
|
||||
public static function getEnvironment(): array
|
||||
{
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => 'linux',
|
||||
};
|
||||
|
||||
$packageName = "go-xcaddy-{$arch}-{$os}";
|
||||
$pkgroot = PKG_ROOT_PATH;
|
||||
|
||||
return [
|
||||
'PATH' => "{$pkgroot}/{$packageName}/bin",
|
||||
'GOROOT' => "{$pkgroot}/{$packageName}",
|
||||
'GOBIN' => "{$pkgroot}/{$packageName}/bin",
|
||||
'GOPATH' => "{$pkgroot}/go",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
164
src/SPC/store/pkg/Zig.php
Normal file
164
src/SPC/store/pkg/Zig.php
Normal file
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\store\pkg;
|
||||
|
||||
use SPC\store\CurlHook;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\LockFile;
|
||||
|
||||
class Zig extends CustomPackage
|
||||
{
|
||||
public static function isInstalled(): bool
|
||||
{
|
||||
$path = self::getPath();
|
||||
return file_exists("{$path}/zig") && file_exists("{$path}/zig-cc") && file_exists("{$path}/zig-c++");
|
||||
}
|
||||
|
||||
public function getSupportName(): array
|
||||
{
|
||||
return [
|
||||
'zig-x86_64-linux',
|
||||
'zig-aarch64-linux',
|
||||
'zig-x86_64-macos',
|
||||
'zig-aarch64-macos',
|
||||
'zig-x86_64-win',
|
||||
];
|
||||
}
|
||||
|
||||
public function fetch(string $name, bool $force = false, ?array $config = null): void
|
||||
{
|
||||
$pkgroot = PKG_ROOT_PATH;
|
||||
$zig_exec = match (PHP_OS_FAMILY) {
|
||||
'Windows' => "{$pkgroot}/{$name}/zig.exe",
|
||||
default => "{$pkgroot}/{$name}/zig",
|
||||
};
|
||||
|
||||
if ($force) {
|
||||
FileSystem::removeDir("{$pkgroot}/{$name}");
|
||||
}
|
||||
|
||||
if (file_exists($zig_exec)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parts = explode('-', $name);
|
||||
$arch = $parts[1];
|
||||
$os = $parts[2];
|
||||
|
||||
$zig_arch = match ($arch) {
|
||||
'x86_64', 'aarch64' => $arch,
|
||||
default => throw new \InvalidArgumentException('Unsupported architecture: ' . $arch),
|
||||
};
|
||||
|
||||
$zig_os = match ($os) {
|
||||
'linux' => 'linux',
|
||||
'macos' => 'macos',
|
||||
'win' => 'windows',
|
||||
default => throw new \InvalidArgumentException('Unsupported OS: ' . $os),
|
||||
};
|
||||
|
||||
$index_json = json_decode(Downloader::curlExec('https://ziglang.org/download/index.json', hooks: [[CurlHook::class, 'setupGithubToken']]), true);
|
||||
|
||||
$latest_version = null;
|
||||
foreach ($index_json as $version => $data) {
|
||||
$latest_version = $version;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$latest_version) {
|
||||
throw new \RuntimeException('Could not determine latest Zig version');
|
||||
}
|
||||
|
||||
logger()->info("Installing Zig version {$latest_version}");
|
||||
|
||||
$platform_key = "{$zig_arch}-{$zig_os}";
|
||||
if (!isset($index_json[$latest_version][$platform_key])) {
|
||||
throw new \RuntimeException("No download available for {$platform_key} in Zig version {$latest_version}");
|
||||
}
|
||||
|
||||
$download_info = $index_json[$latest_version][$platform_key];
|
||||
$url = $download_info['tarball'];
|
||||
$filename = basename($url);
|
||||
|
||||
$pkg = [
|
||||
'type' => 'url',
|
||||
'url' => $url,
|
||||
'filename' => $filename,
|
||||
];
|
||||
|
||||
Downloader::downloadPackage($name, $pkg, $force);
|
||||
}
|
||||
|
||||
public function extract(string $name): void
|
||||
{
|
||||
$pkgroot = PKG_ROOT_PATH;
|
||||
$zig_bin_dir = "{$pkgroot}/{$name}";
|
||||
$zig_exec = match (PHP_OS_FAMILY) {
|
||||
'Windows' => "{$zig_bin_dir}/zig.exe",
|
||||
default => "{$zig_bin_dir}/zig",
|
||||
};
|
||||
|
||||
if (file_exists($zig_exec) && file_exists("{$zig_bin_dir}/zig-cc")) {
|
||||
return;
|
||||
}
|
||||
|
||||
$lock = json_decode(FileSystem::readFile(LockFile::LOCK_FILE), true);
|
||||
$source_type = $lock[$name]['source_type'];
|
||||
$filename = DOWNLOAD_PATH . '/' . ($lock[$name]['filename'] ?? $lock[$name]['dirname']);
|
||||
$extract = "{$pkgroot}/{$name}";
|
||||
|
||||
FileSystem::extractPackage($name, $source_type, $filename, $extract);
|
||||
|
||||
$this->createZigCcScript($zig_bin_dir);
|
||||
}
|
||||
|
||||
public static function getEnvironment(): array
|
||||
{
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Linux' => 'linux',
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => 'linux',
|
||||
};
|
||||
|
||||
$packageName = "zig-{$arch}-{$os}";
|
||||
$path = PKG_ROOT_PATH . "/{$packageName}";
|
||||
|
||||
return [
|
||||
'PATH' => $path,
|
||||
];
|
||||
}
|
||||
|
||||
private static function getPath(): string
|
||||
{
|
||||
$arch = arch2gnu(php_uname('m'));
|
||||
$os = match (PHP_OS_FAMILY) {
|
||||
'Linux' => 'linux',
|
||||
'Windows' => 'win',
|
||||
'Darwin' => 'macos',
|
||||
'BSD' => 'freebsd',
|
||||
default => 'linux',
|
||||
};
|
||||
|
||||
$packageName = "zig-{$arch}-{$os}";
|
||||
return PKG_ROOT_PATH . "/{$packageName}";
|
||||
}
|
||||
|
||||
private function createZigCcScript(string $bin_dir): void
|
||||
{
|
||||
$script_path = __DIR__ . '/../scripts/zig-cc.sh';
|
||||
$script_content = file_get_contents($script_path);
|
||||
|
||||
file_put_contents("{$bin_dir}/zig-cc", $script_content);
|
||||
chmod("{$bin_dir}/zig-cc", 0755);
|
||||
|
||||
$script_content = str_replace('zig cc', 'zig c++', $script_content);
|
||||
file_put_contents("{$bin_dir}/zig-c++", $script_content);
|
||||
chmod("{$bin_dir}/zig-c++", 0755);
|
||||
}
|
||||
}
|
||||
55
src/SPC/store/scripts/zig-cc.sh
Normal file
55
src/SPC/store/scripts/zig-cc.sh
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT_DIR="$(dirname "${BASH_SOURCE[0]}")"
|
||||
BUILDROOT_ABS="$(realpath "$SCRIPT_DIR/../../buildroot/include" 2>/dev/null || echo "")"
|
||||
PARSED_ARGS=()
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-isystem)
|
||||
shift
|
||||
ARG="$1"
|
||||
[[ -n "$ARG" ]] && shift || break
|
||||
ARG_ABS="$(realpath "$ARG" 2>/dev/null || echo "")"
|
||||
if [[ -n "$ARG_ABS" && "$ARG_ABS" == "$BUILDROOT_ABS" ]]; then
|
||||
PARSED_ARGS+=("-I$ARG")
|
||||
else
|
||||
PARSED_ARGS+=("-isystem" "$ARG")
|
||||
fi
|
||||
;;
|
||||
-isystem*)
|
||||
ARG="${1#-isystem}"
|
||||
shift
|
||||
ARG_ABS="$(realpath "$ARG" 2>/dev/null || echo "")"
|
||||
if [[ -n "$ARG_ABS" && "$ARG_ABS" == "$BUILDROOT_ABS" ]]; then
|
||||
PARSED_ARGS+=("-I$ARG")
|
||||
else
|
||||
PARSED_ARGS+=("-isystem$ARG")
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
PARSED_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
TARGET=""
|
||||
if [ -n "$SPC_TARGET" ]; then
|
||||
TARGET="-target $SPC_TARGET"
|
||||
fi
|
||||
|
||||
output=$(zig cc $TARGET -lstdc++ $COMPILER_EXTRA "${PARSED_ARGS[@]}" 2>&1)
|
||||
status=$?
|
||||
|
||||
if [ $status -eq 0 ]; then
|
||||
echo "$output"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if echo "$output" | grep -q "version '.*' in target triple"; then
|
||||
echo "$output" | grep -v "version '.*' in target triple"
|
||||
exit 0
|
||||
else
|
||||
exec zig cc $TARGET $COMPILER_EXTRA "${PARSED_ARGS[@]}"
|
||||
fi
|
||||
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_LD_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
GlobalEnvManager::putenv("SPC_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_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;
|
||||
}
|
||||
56
src/SPC/toolchain/ToolchainManager.php
Normal file
56
src/SPC/toolchain/ToolchainManager.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?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' => ZigToolchain::class,
|
||||
'Windows' => MSVCToolchain::class,
|
||||
'Darwin' => ClangNativeToolchain::class,
|
||||
'BSD' => ClangNativeToolchain::class,
|
||||
];
|
||||
|
||||
public static function getToolchainClass(): string
|
||||
{
|
||||
$libc = getenv('SPC_LIBC');
|
||||
if ($libc && !getenv('SPC_TARGET')) {
|
||||
// TODO: @crazywhalecc this breaks tests
|
||||
// logger()->warning('SPC_LIBC is deprecated, please use SPC_TARGET instead.');
|
||||
return match ($libc) {
|
||||
'musl' => SystemUtil::isMuslDist() ? GccNativeToolchain::class : MuslToolchain::class,
|
||||
'glibc' => !SystemUtil::isMuslDist() ? GccNativeToolchain::class : throw new WrongUsageException('SPC_LIBC must be musl for musl dist.'),
|
||||
default => throw new WrongUsageException('Unsupported SPC_LIBC value: ' . $libc),
|
||||
};
|
||||
}
|
||||
|
||||
return self::OS_DEFAULT_TOOLCHAIN[PHP_OS_FAMILY];
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function initToolchain(): void
|
||||
{
|
||||
$toolchainClass = self::getToolchainClass();
|
||||
/* @var ToolchainInterface $toolchainClass */
|
||||
(new $toolchainClass())->initEnv();
|
||||
GlobalEnvManager::putenv("SPC_TOOLCHAIN={$toolchainClass}");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
29
src/SPC/toolchain/ZigToolchain.php
Normal file
29
src/SPC/toolchain/ZigToolchain.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\toolchain;
|
||||
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\pkg\Zig;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class ZigToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(): void
|
||||
{
|
||||
// Set environment variables for zig toolchain
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CC=zig-cc');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=zig-c++');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld');
|
||||
}
|
||||
|
||||
public function afterInit(): void
|
||||
{
|
||||
if (!is_dir(Zig::getEnvironment()['PATH'])) {
|
||||
throw new WrongUsageException('You are building with zig, but zig is not installed, please install zig first. (You can use `doctor` command to install it)');
|
||||
}
|
||||
GlobalEnvManager::addPathIfNotExists(Zig::getEnvironment()['PATH']);
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
|
||||
/**
|
||||
* Environment variable manager
|
||||
@@ -40,24 +40,6 @@ class GlobalEnvManager
|
||||
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 (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();
|
||||
|
||||
$default_put_list = [];
|
||||
@@ -80,6 +62,9 @@ class GlobalEnvManager
|
||||
self::putenv("{$k}={$v}");
|
||||
}
|
||||
}
|
||||
|
||||
ToolchainManager::initToolchain();
|
||||
|
||||
// apply second time
|
||||
$ini2 = self::readIniFile();
|
||||
|
||||
@@ -108,13 +93,26 @@ class GlobalEnvManager
|
||||
self::$env_cache[] = $val;
|
||||
}
|
||||
|
||||
private static function addPathIfNotExists(string $path): void
|
||||
public static function addPathIfNotExists(string $path): void
|
||||
{
|
||||
if (is_unix() && !str_contains(getenv('PATH'), $path)) {
|
||||
self::putenv("PATH={$path}:" . getenv('PATH'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,8 @@ use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
|
||||
class SPCConfigUtil
|
||||
@@ -55,7 +57,7 @@ class SPCConfigUtil
|
||||
ob_get_clean();
|
||||
$ldflags = $this->getLdflagsString();
|
||||
$libs = $this->getLibsString($libraries, $with_dependencies);
|
||||
if (PHP_OS_FAMILY === 'Darwin') {
|
||||
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||
$libs .= " {$this->getFrameworksString($extensions)}";
|
||||
}
|
||||
$cflags = $this->getIncludesString();
|
||||
@@ -70,6 +72,9 @@ class SPCConfigUtil
|
||||
if ($this->builder->hasCpp()) {
|
||||
$libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++';
|
||||
}
|
||||
if (ToolchainManager::getToolchainClass() === ZigToolchain::class) {
|
||||
$libs .= ' -lunwind';
|
||||
}
|
||||
// mimalloc must come first
|
||||
if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) {
|
||||
$libs = BUILD_LIB_PATH . '/mimalloc.o ' . str_replace(BUILD_LIB_PATH . '/mimalloc.o', '', $libs);
|
||||
@@ -145,10 +150,6 @@ class SPCConfigUtil
|
||||
}
|
||||
}
|
||||
}
|
||||
// patch: imagick (imagemagick wrapper) for linux needs libgomp
|
||||
if (in_array('imagemagick', $libraries) && PHP_OS_FAMILY === 'Linux' && !(getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10'))) {
|
||||
$short_name[] = '-lgomp';
|
||||
}
|
||||
return implode(' ', $short_name);
|
||||
}
|
||||
|
||||
|
||||
101
src/SPC/util/SPCTarget.php
Normal file
101
src/SPC/util/SPCTarget.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?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 we link the C runtime in statically.
|
||||
*/
|
||||
public static function isStatic(): bool
|
||||
{
|
||||
// if SPC_LIBC is set, it means the target is static, remove it when 3.0 is released
|
||||
if ($target = getenv('SPC_TARGET')) {
|
||||
if (str_contains($target, '-macos') || str_contains($target, '-native') && PHP_OS_FAMILY === 'Darwin') {
|
||||
return false;
|
||||
}
|
||||
if (str_contains($target, '-gnu')) {
|
||||
return false;
|
||||
}
|
||||
if (str_contains($target, '-dynamic')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (getenv('SPC_LIBC') === 'musl') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the libc type if set, for other OS, it will always return null.
|
||||
*/
|
||||
public static function getLibc(): ?string
|
||||
{
|
||||
if ($target = getenv('SPC_TARGET')) {
|
||||
if (str_contains($target, '-gnu')) {
|
||||
return 'glibc';
|
||||
}
|
||||
if (str_contains($target, '-musl')) {
|
||||
return 'musl';
|
||||
}
|
||||
if (str_contains($target, '-linux')) {
|
||||
return 'musl';
|
||||
}
|
||||
if (PHP_OS_FAMILY === 'Linux' && str_contains($target, '-native')) {
|
||||
return 'musl';
|
||||
}
|
||||
}
|
||||
$libc = getenv('SPC_LIBC');
|
||||
if ($libc !== false) {
|
||||
return $libc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the libc version if set, for other OS, it will always return null.
|
||||
*/
|
||||
public static function getLibcVersion(): ?string
|
||||
{
|
||||
$libc = self::getLibc();
|
||||
return SystemUtil::getLibcVersionIfExists($libc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
return match (true) {
|
||||
str_contains($target, '-linux') => 'Linux',
|
||||
str_contains($target, '-macos') => 'Darwin',
|
||||
str_contains($target, '-windows') => 'Windows',
|
||||
str_contains($target, '-native') => PHP_OS_FAMILY,
|
||||
default => throw new WrongUsageException('Cannot parse target.'),
|
||||
};
|
||||
}
|
||||
}
|
||||
19
src/globals/patch/swoole_fix_date_time.patch
Normal file
19
src/globals/patch/swoole_fix_date_time.patch
Normal file
@@ -0,0 +1,19 @@
|
||||
--- a/config.m4
|
||||
+++ b/config.m4
|
||||
@@ -426,6 +426,7 @@
|
||||
AX_CHECK_COMPILE_FLAG(-Wlogical-op-parentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-op-parentheses")
|
||||
AX_CHECK_COMPILE_FLAG(-Wloop-analysis, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wloop-analysis")
|
||||
AX_CHECK_COMPILE_FLAG(-Wuninitialized, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wuninitialized")
|
||||
+ AX_CHECK_COMPILE_FLAG(-Wno-date-time, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-date-time")
|
||||
AX_CHECK_COMPILE_FLAG(-Wno-missing-field-initializers, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-missing-field-initializers")
|
||||
AX_CHECK_COMPILE_FLAG(-Wno-sign-compare, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-sign-compare")
|
||||
AX_CHECK_COMPILE_FLAG(-Wno-unused-const-variable, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-unused-const-variable")
|
||||
@@ -1307,7 +1308,7 @@
|
||||
|
||||
PHP_REQUIRE_CXX()
|
||||
|
||||
- CXXFLAGS="$CXXFLAGS -Wall -Wno-unused-function -Wno-deprecated -Wno-deprecated-declarations"
|
||||
+ CXXFLAGS="$CXXFLAGS -Wall -Wno-date-time -Wno-unused-function -Wno-deprecated -Wno-deprecated-declarations"
|
||||
|
||||
if test "$SW_OS" = "CYGWIN" || test "$SW_OS" = "MINGW"; then
|
||||
CXXFLAGS="$CXXFLAGS -std=gnu++14"
|
||||
@@ -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-14',
|
||||
// 'macos-15',
|
||||
// 'ubuntu-latest',
|
||||
// 'ubuntu-22.04',
|
||||
// 'ubuntu-24.04',
|
||||
// 'ubuntu-22.04-arm',
|
||||
// 'ubuntu-24.04-arm',
|
||||
'windows-latest',
|
||||
// 'macos-13', // bin/spc for x86_64
|
||||
// 'macos-14', // bin/spc for arm64
|
||||
'macos-15', // bin/spc for arm64
|
||||
// 'ubuntu-latest', // bin/spc-alpine-docker for x86_64
|
||||
'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
|
||||
'ubuntu-24.04', // bin/spc for x86_64
|
||||
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
|
||||
'ubuntu-24.04-arm', // bin/spc for arm64
|
||||
// 'windows-latest', // .\bin\spc.ps1
|
||||
];
|
||||
|
||||
// whether enable thread safe
|
||||
@@ -48,13 +48,13 @@ $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' => 'curl',
|
||||
'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' => 'intl',
|
||||
};
|
||||
|
||||
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
|
||||
$shared_extensions = match (PHP_OS_FAMILY) {
|
||||
'Linux' => 'uv',
|
||||
'Linux' => 'amqp,brotli,bz2,dio,ds,ev,event,ffi,ftp,gd,gettext,gmp,gmssl,igbinary,imagick,inotify,intl,ldap,lz4,memcache,memcached,mongodb,msgpack,mysqli,mysqlnd,odbc,opentelemetry,parallel,pdo,pdo_mysql,pdo_odbc,pdo_pgsql,pdo_sqlite,pdo_sqlsrv,pgsql,protobuf,rar,redis,rdkafka,shmop,spx,sqlite3,sqlsrv,ssh2,swoole,sysvmsg,sysvsem,sysvshm,tidy,uuid,uv,xdebug,xhprof,xlswriter,xsl,xz,yac,yaml,zstd',
|
||||
'Darwin' => '',
|
||||
'Windows' => '',
|
||||
};
|
||||
@@ -156,6 +156,13 @@ if ($shared_extensions) {
|
||||
case 'ubuntu-22.04-arm':
|
||||
$shared_cmd = ' --build-shared=' . quote2($shared_extensions) . ' ';
|
||||
break;
|
||||
case 'ubuntu-24.04':
|
||||
case 'ubuntu-24.04-arm':
|
||||
putenv('SPC_TARGET=native-linux-gnu');
|
||||
if (str_contains((string) getenv('SPC_TARGET'), '-gnu')) {
|
||||
$shared_cmd = ' --build-shared=' . quote2($shared_extensions) . ' ';
|
||||
}
|
||||
break;
|
||||
case 'macos-13':
|
||||
case 'macos-14':
|
||||
case 'macos-15':
|
||||
|
||||
Reference in New Issue
Block a user