Skip to content

Commit 5404926

Browse files
authored
Merge branch 'main' into fix/lide265
2 parents 823fe96 + 295df19 commit 5404926

File tree

9 files changed

+218
-22
lines changed

9 files changed

+218
-22
lines changed

.github/workflows/build-unix.yml

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ on:
2929
description: Extensions to build (comma separated)
3030
required: true
3131
type: string
32+
shared-extensions:
33+
description: Shared extensions to build (optional, comma separated)
34+
type: string
3235
extra-libs:
3336
description: Extra libraries to build (optional, comma separated)
3437
type: string
@@ -42,6 +45,14 @@ on:
4245
build-fpm:
4346
description: Build fpm binary
4447
type: boolean
48+
build-frankenphp:
49+
description: Build frankenphp binary (requires ZTS)
50+
type: boolean
51+
default: false
52+
enable-zts:
53+
description: Enable ZTS
54+
type: boolean
55+
default: false
4556
prefer-pre-built:
4657
description: Prefer pre-built binaries (reduce build time)
4758
type: boolean
@@ -73,6 +84,9 @@ on:
7384
description: Extensions to build (comma separated)
7485
required: true
7586
type: string
87+
shared-extensions:
88+
description: Shared extensions to build (optional, comma separated)
89+
type: string
7690
extra-libs:
7791
description: Extra libraries to build (optional, comma separated)
7892
type: string
@@ -86,6 +100,14 @@ on:
86100
build-fpm:
87101
description: Build fpm binary
88102
type: boolean
103+
build-frankenphp:
104+
description: Build frankenphp binary (requires ZTS)
105+
type: boolean
106+
default: false
107+
enable-zts:
108+
description: Enable ZTS
109+
type: boolean
110+
default: false
89111
prefer-pre-built:
90112
description: Prefer pre-built binaries (reduce build time)
91113
type: boolean
@@ -152,8 +174,19 @@ jobs:
152174
RUNS_ON="macos-15"
153175
;;
154176
esac
155-
DOWN_CMD="$DOWN_CMD --with-php=${{ inputs.php-version }} --for-extensions=${{ inputs.extensions }} --ignore-cache-sources=php-src"
156-
BUILD_CMD="$BUILD_CMD ${{ inputs.extensions }}"
177+
STATIC_EXTS="${{ inputs.extensions }}"
178+
SHARED_EXTS="${{ inputs['shared-extensions'] }}"
179+
BUILD_FRANKENPHP="${{ inputs['build-frankenphp'] }}"
180+
ENABLE_ZTS="${{ inputs['enable-zts'] }}"
181+
ALL_EXTS="$STATIC_EXTS"
182+
if [ -n "$SHARED_EXTS" ]; then
183+
ALL_EXTS="$ALL_EXTS,$SHARED_EXTS"
184+
fi
185+
DOWN_CMD="$DOWN_CMD --with-php=${{ inputs.php-version }} --for-extensions=$ALL_EXTS --ignore-cache-sources=php-src"
186+
BUILD_CMD="$BUILD_CMD $STATIC_EXTS"
187+
if [ -n "$SHARED_EXTS" ]; then
188+
BUILD_CMD="$BUILD_CMD --build-shared=$SHARED_EXTS"
189+
fi
157190
if [ -n "${{ inputs.extra-libs }}" ]; then
158191
DOWN_CMD="$DOWN_CMD --for-libs=${{ inputs.extra-libs }}"
159192
BUILD_CMD="$BUILD_CMD --with-libs=${{ inputs.extra-libs }}"
@@ -177,6 +210,12 @@ jobs:
177210
if [ ${{ inputs.build-fpm }} == true ]; then
178211
BUILD_CMD="$BUILD_CMD --build-fpm"
179212
fi
213+
if [ "$BUILD_FRANKENPHP" = "true" ]; then
214+
BUILD_CMD="$BUILD_CMD --build-frankenphp"
215+
fi
216+
if [ "$ENABLE_ZTS" = "true" ]; then
217+
BUILD_CMD="$BUILD_CMD --enable-zts"
218+
fi
180219
echo 'download='"$DOWN_CMD" >> "$GITHUB_OUTPUT"
181220
echo 'build='"$BUILD_CMD" >> "$GITHUB_OUTPUT"
182221
echo 'run='"$RUNS_ON" >> "$GITHUB_OUTPUT"
@@ -199,6 +238,27 @@ jobs:
199238
env:
200239
phpts: nts
201240

241+
- if: ${{ inputs['build-frankenphp'] == true }}
242+
name: "Install go-xcaddy for FrankenPHP"
243+
run: |
244+
case "${{ inputs.os }}" in
245+
linux-x86_64|linux-aarch64)
246+
./bin/spc-alpine-docker install-pkg go-xcaddy
247+
;;
248+
linux-x86_64-glibc|linux-aarch64-glibc)
249+
./bin/spc-gnu-docker install-pkg go-xcaddy
250+
;;
251+
macos-x86_64|macos-aarch64)
252+
composer update --no-dev --classmap-authoritative
253+
./bin/spc doctor --auto-fix
254+
./bin/spc install-pkg go-xcaddy
255+
;;
256+
*)
257+
echo "Unsupported OS for go-xcaddy install: ${{ inputs.os }}"
258+
exit 1
259+
;;
260+
esac
261+
202262
# Cache downloaded source
203263
- id: cache-download
204264
uses: actions/cache@v4
@@ -245,7 +305,22 @@ jobs:
245305
name: php-fpm-${{ inputs.php-version }}-${{ inputs.os }}
246306
path: buildroot/bin/php-fpm
247307

308+
# Upload frankenphp executable
309+
- if: ${{ inputs['build-frankenphp'] == true }}
310+
name: "Upload FrankenPHP SAPI"
311+
uses: actions/upload-artifact@v4
312+
with:
313+
name: php-frankenphp-${{ inputs.php-version }}-${{ inputs.os }}
314+
path: buildroot/bin/frankenphp
315+
248316
# Upload extensions metadata
317+
- if: ${{ inputs['shared-extensions'] != '' }}
318+
name: "Upload shared extensions"
319+
uses: actions/upload-artifact@v4
320+
with:
321+
name: php-shared-ext-${{ inputs.php-version }}-${{ inputs.os }}
322+
path: |
323+
buildroot/modules/*.so
249324
- uses: actions/upload-artifact@v4
250325
name: "Upload License Files"
251326
with:

config/env.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-
148148
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
149149
; EXTRA_CFLAGS for `configure` and `make` php
150150
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -Werror=unknown-warning-option ${SPC_DEFAULT_C_FLAGS}"
151+
; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so
152+
SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS=""
151153
; minimum compatible macOS version (LLVM vars, availability not guaranteed)
152154
MACOSX_DEPLOYMENT_TARGET=12.0
153155

docs/en/guide/action-build.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ while also defining the extensions to compile.
1616

1717
1. Fork project.
1818
2. Go to the Actions of the project and select `CI`.
19-
3. Select `Run workflow`, fill in the PHP version you want to compile, the target type, and the list of extensions. (extensions comma separated, e.g. `bcmath,curl,mbstring`)
20-
4. After waiting for about a period of time, enter the corresponding task and get `Artifacts`.
19+
3. Select `Run workflow`, fill in the PHP version you want to compile, the target type, and the list of static extensions. (comma separated, e.g. `bcmath,curl,mbstring`)
20+
4. If you need shared extensions (for example `xdebug`), set `shared-extensions` (comma separated, e.g. `xdebug`).
21+
5. If you need FrankenPHP, enable `build-frankenphp` and also enable `enable-zts`.
22+
6. After waiting for about a period of time, enter the corresponding task and get `Artifacts`.
2123

2224
If you enable `debug`, all logs will be output at build time, including compiled logs, for troubleshooting.
2325

docs/zh/guide/action-build.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ Action 构建指的是直接使用 GitHub Action 进行编译。
1414
1. Fork 本项目。
1515
2. 进入项目的 Actions,选择 CI 开头的 Workflow(根据你需要的操作系统选择)。
1616
3. 选择 `Run workflow`,填入你要编译的 PHP 版本、目标类型、扩展列表。(扩展列表使用英文逗号分割,例如 `bcmath,curl,mbstring`
17-
4. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`
17+
4. 如果需要共享扩展(例如 `xdebug`),请设置 `shared-extensions`(使用英文逗号分割,例如 `xdebug`)。
18+
5. 如果需要 FrankenPHP,请启用 `build-frankenphp`,同时也需要启用 `enable-zts`
19+
6. 等待大约一段时间后,进入对应的任务中,获取 `Artifacts`
1820

1921
如果你选择了 `debug`,则会在构建时输出所有日志,包括编译的日志,以供排查错误。
2022

src/SPC/builder/linux/LinuxBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void
162162
throw new WrongUsageException(
163163
"You're building against musl libc statically (the default on Linux), but you're trying to build shared extensions.\n" .
164164
'Static musl libc does not implement `dlopen`, so your php binary is not able to load shared extensions.' . "\n" .
165-
'Either use SPC_LIBC=glibc to link against glibc on a glibc OS, or use SPC_TARGET="native-native-musl -dynamic" to link against musl libc dynamically using `zig cc`.'
165+
'Either use SPC_LIBC=glibc to link against glibc on a glibc OS, use SPC_TARGET="native-native-musl -dynamic" to link against musl libc dynamically using `zig cc` or use SPC_MUSL_DYNAMIC=true on alpine.'
166166
);
167167
}
168168
logger()->info('Building shared extensions...');

src/SPC/builder/windows/library/zlib.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,23 @@ protected function build(): void
3131
$this->builder->makeSimpleWrapper('cmake'),
3232
"--build build --config Release --target install -j{$this->builder->concurrency}"
3333
);
34-
copy(BUILD_LIB_PATH . '\zlibstatic.lib', BUILD_LIB_PATH . '\zlib_a.lib');
35-
unlink(BUILD_ROOT_PATH . '\bin\zlib.dll');
36-
unlink(BUILD_LIB_PATH . '\zlib.lib');
34+
$detect_list = [
35+
'zlibstatic.lib',
36+
'zs.lib',
37+
'libzs.lib',
38+
];
39+
foreach ($detect_list as $item) {
40+
if (file_exists(BUILD_LIB_PATH . '\\' . $item)) {
41+
FileSystem::copy(BUILD_LIB_PATH . '\\' . $item, BUILD_LIB_PATH . '\zlib_a.lib');
42+
FileSystem::copy(BUILD_LIB_PATH . '\\' . $item, BUILD_LIB_PATH . '\zlibstatic.lib');
43+
break;
44+
}
45+
}
46+
FileSystem::removeFileIfExists(BUILD_ROOT_PATH . '\bin\zlib.dll');
47+
FileSystem::removeFileIfExists(BUILD_LIB_PATH . '\zlib.lib');
48+
FileSystem::removeFileIfExists(BUILD_LIB_PATH . '\libz.dll');
49+
FileSystem::removeFileIfExists(BUILD_LIB_PATH . '\libz.lib');
50+
FileSystem::removeFileIfExists(BUILD_LIB_PATH . '\z.lib');
51+
FileSystem::removeFileIfExists(BUILD_LIB_PATH . '\z.dll');
3752
}
3853
}

src/SPC/store/SourcePatcher.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,13 @@ public static function patchGDWin32(): bool
634634
FileSystem::replaceFileStr(SOURCE_PATH . '/php-src/ext/gd/libgd/gdft.c', '#ifndef MSWIN32', '#ifndef _WIN32');
635635
}
636636
// custom config.w32, because official config.w32 is hard-coded many things
637-
$origin = $ver_id >= 80100 ? file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_81.w32') : file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_80.w32');
637+
if ($ver_id >= 80500) {
638+
$origin = file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_85.w32');
639+
} elseif ($ver_id >= 80100) {
640+
$origin = file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_81.w32');
641+
} else {
642+
$origin = file_get_contents(ROOT_DIR . '/src/globals/extra/gd_config_80.w32');
643+
}
638644
file_put_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32.bak', file_get_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32'));
639645
return file_put_contents(SOURCE_PATH . '/php-src/ext/gd/config.w32', $origin) !== false;
640646
}

src/globals/extra/gd_config_85.w32

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// vim:ft=javascript
2+
3+
ARG_WITH("gd", "Bundled GD support", "yes");
4+
5+
if (PHP_GD != "no") {
6+
// check for gd.h (required)
7+
if (!CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd")) {
8+
ERROR("gd not enabled; libraries and headers not found");
9+
}
10+
11+
// zlib ext support (required)
12+
if (!CHECK_LIB("zlib_a.lib;zlib.lib", "gd", PHP_GD)) {
13+
ERROR("gd not enabled; zlib not enabled");
14+
}
15+
16+
// libjpeg lib support
17+
if (CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) &&
18+
CHECK_HEADER_ADD_INCLUDE("jpeglib.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include")) {
19+
AC_DEFINE("HAVE_LIBJPEG", 1, "JPEG support");
20+
AC_DEFINE("HAVE_GD_JPG", 1, "JPEG support");
21+
}
22+
23+
// libpng16 lib support
24+
if (CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) &&
25+
CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng16")) {
26+
AC_DEFINE("HAVE_LIBPNG", 1, "PNG support");
27+
AC_DEFINE("HAVE_GD_PNG", 1, "PNG support");
28+
}
29+
30+
// freetype lib support
31+
if (CHECK_LIB("libfreetype_a.lib;libfreetype.lib", "gd", PHP_GD) &&
32+
CHECK_HEADER_ADD_INCLUDE("ft2build.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\freetype2;" + PHP_PHP_BUILD + "\\include\\freetype")) {
33+
AC_DEFINE("HAVE_LIBFREETYPE", 1, "FreeType support");
34+
AC_DEFINE("HAVE_GD_FREETYPE", 1, "FreeType support");
35+
}
36+
37+
// xpm lib support
38+
if (CHECK_LIB("libXpm_a.lib", "gd", PHP_GD) &&
39+
CHECK_HEADER_ADD_INCLUDE("xpm.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\X11")) {
40+
AC_DEFINE("HAVE_LIBXPM", 1, "XPM support");
41+
AC_DEFINE("HAVE_GD_XPM", 1, "XPM support");
42+
}
43+
44+
// iconv lib support
45+
if ((CHECK_LIB("libiconv_a.lib;libiconv.lib", "gd", PHP_GD) || CHECK_LIB("iconv_a.lib;iconv.lib", "gd", PHP_GD)) &&
46+
CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_GD", PHP_GD)) {
47+
AC_DEFINE("HAVE_LIBICONV", 1, "Iconv support");
48+
}
49+
50+
// libwebp lib support
51+
if ((CHECK_LIB("libwebp_a.lib", "gd", PHP_GD) || CHECK_LIB("libwebp.lib", "gd", PHP_GD)) &&
52+
CHECK_LIB("libsharpyuv.lib", "gd", PHP_GD) &&
53+
CHECK_HEADER_ADD_INCLUDE("decode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp") &&
54+
CHECK_HEADER_ADD_INCLUDE("encode.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\webp")) {
55+
AC_DEFINE("HAVE_LIBWEBP", 1, "WebP support");
56+
AC_DEFINE("HAVE_GD_WEBP", 1, "WebP support");
57+
}
58+
59+
// libavif lib support
60+
if (CHECK_LIB("avif_a.lib", "gd", PHP_GD) &&
61+
CHECK_LIB("aom_a.lib", "gd", PHP_GD) &&
62+
CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) {
63+
ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF");
64+
} else if (CHECK_LIB("avif.lib", "gd", PHP_GD) &&
65+
CHECK_HEADER_ADD_INCLUDE("avif.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\avif")) {
66+
ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBAVIF /D HAVE_GD_AVIF");
67+
}
68+
69+
CHECK_LIB("User32.lib", "gd", PHP_GD);
70+
CHECK_LIB("Gdi32.lib", "gd", PHP_GD);
71+
72+
EXTENSION("gd", "gd.c", null, "-Iext/gd/libgd");
73+
ADD_SOURCES("ext/gd/libgd", "gd.c \
74+
gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \
75+
gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \
76+
gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \
77+
gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c gd_xbm.c gd_security.c gd_transform.c \
78+
gd_filter.c gd_rotate.c gd_color_match.c gd_webp.c gd_avif.c \
79+
gd_crop.c gd_interpolation.c gd_matrix.c gd_bmp.c gd_tga.c", "gd");
80+
81+
AC_DEFINE('HAVE_LIBGD', 1, 'GD support');
82+
AC_DEFINE('HAVE_GD_BUNDLED', 1, "Bundled GD");
83+
AC_DEFINE('HAVE_GD_BMP', 1, "BMP support");
84+
AC_DEFINE('HAVE_GD_TGA', 1, "TGA support");
85+
ADD_FLAG("CFLAGS_GD", " \
86+
/D PHP_GD_EXPORTS=1 \
87+
/D HAVE_GD_GET_INTERPOLATION \
88+
");
89+
if (ICC_TOOLSET) {
90+
ADD_FLAG("LDFLAGS_GD", "/nodefaultlib:libcmt");
91+
}
92+
93+
PHP_INSTALL_HEADERS("", "ext/gd ext/gd/libgd");
94+
}

src/globals/test-extensions.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
// test php version (8.1 ~ 8.4 available, multiple for matrix)
1515
$test_php_version = [
16-
// '8.1',
16+
'8.1',
1717
// '8.2',
1818
// '8.3',
1919
'8.4',
@@ -23,19 +23,19 @@
2323

2424
// test os (macos-15-intel, macos-15, ubuntu-latest, windows-latest are available)
2525
$test_os = [
26-
'macos-15-intel', // bin/spc for x86_64
27-
'macos-15', // bin/spc for arm64
26+
// 'macos-15-intel', // bin/spc for x86_64
27+
// 'macos-15', // bin/spc for arm64
2828
// 'ubuntu-latest', // bin/spc-alpine-docker for x86_64
29-
'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
30-
'ubuntu-24.04', // bin/spc for x86_64
31-
'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
32-
'ubuntu-24.04-arm', // bin/spc for arm64
29+
// 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64
30+
// 'ubuntu-24.04', // bin/spc for x86_64
31+
// 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64
32+
// 'ubuntu-24.04-arm', // bin/spc for arm64
3333
// 'windows-2022', // .\bin\spc.ps1
34-
// 'windows-2025',
34+
'windows-2025',
3535
];
3636

3737
// whether enable thread safe
38-
$zts = false;
38+
$zts = true;
3939

4040
$no_strip = false;
4141

@@ -50,8 +50,8 @@
5050

5151
// If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`).
5252
$extensions = match (PHP_OS_FAMILY) {
53-
'Linux', 'Darwin' => 'imagick',
54-
'Windows' => 'com_dotnet',
53+
'Linux', 'Darwin' => 'pgsql',
54+
'Windows' => 'gd,zlib,mbstring,filter',
5555
};
5656

5757
// If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`).
@@ -89,7 +89,7 @@ function _getCombination(string $type = 'common'): string
8989
'common' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,gd,gmp,iconv,xml,mbstring,mbregex,' .
9090
'mysqlnd,openssl,pcntl,pdo,pdo_mysql,pdo_sqlite,phar,posix,redis,session,simplexml,soap,sockets,' .
9191
'sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip',
92-
'bulk' => 'apcu,bcmath,bz2,calendar,ctype,curl,dba,dom,event,exif,fileinfo,filter,ftp,gd,gmp,iconv,imagick,' .
92+
'bulk' => 'apcu,bcmath,bz2,calendar,ctype,curl,dba,dom,event,exif,fileinfo,filter,ftp,gd,gmp,iconv,imagick,imap,' .
9393
'intl,mbregex,mbstring,mysqli,mysqlnd,opcache,openssl,pcntl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,pgsql,phar,' .
9494
'posix,protobuf,readline,redis,session,shmop,simplexml,soap,sockets,sodium,sqlite3,swoole,sysvmsg,sysvsem,' .
9595
'sysvshm,tokenizer,xml,xmlreader,xmlwriter,xsl,zip,zlib',

0 commit comments

Comments
 (0)