From db83778663c7beff5ed9d92b794249ab441696bf Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:46:29 +0800 Subject: [PATCH 01/24] Apply ext-brotli,ext-zstd,gmssl changes in feat/pgo-v3 --- config/pkg/ext/ext-brotli.yml | 7 ++++--- config/pkg/ext/ext-zstd.yml | 5 ++--- config/pkg/lib/gmssl.yml | 5 +++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/config/pkg/ext/ext-brotli.yml b/config/pkg/ext/ext-brotli.yml index 147ecb636..b87fb9ef3 100644 --- a/config/pkg/ext/ext-brotli.yml +++ b/config/pkg/ext/ext-brotli.yml @@ -2,12 +2,13 @@ ext-brotli: type: php-extension artifact: source: - type: git + type: ghtagtar + repo: kjdev/php-ext-brotli extract: php-src/ext/brotli - rev: master - url: 'https://github.com/kjdev/php-ext-brotli' metadata: license-files: [LICENSE] license: MIT depends: - brotli + php-extension: + arg-type: '--enable-brotli@shared_suffix@ --with-libbrotli' diff --git a/config/pkg/ext/ext-zstd.yml b/config/pkg/ext/ext-zstd.yml index 9b01422be..b07db490c 100644 --- a/config/pkg/ext/ext-zstd.yml +++ b/config/pkg/ext/ext-zstd.yml @@ -2,9 +2,8 @@ ext-zstd: type: php-extension artifact: source: - type: git - url: 'https://github.com/kjdev/php-ext-zstd' - rev: master + type: ghtar + repo: kjdev/php-ext-zstd extract: php-src/ext/zstd metadata: license-files: [LICENSE] diff --git a/config/pkg/lib/gmssl.yml b/config/pkg/lib/gmssl.yml index 076234353..ff4250871 100644 --- a/config/pkg/lib/gmssl.yml +++ b/config/pkg/lib/gmssl.yml @@ -2,8 +2,9 @@ gmssl: type: library artifact: source: - type: ghtar - repo: guanzhi/GmSSL + type: git + url: 'https://github.com/guanzhi/GmSSL.git' + rev: master metadata: license-files: [LICENSE] license: Apache-2.0 From 6bf0ea18cae9f18db7adffeb1052a4b42ed437b2 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:46:46 +0800 Subject: [PATCH 02/24] Apply config/env.ini changes in feat/pgo-v3 --- config/env.ini | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/config/env.ini b/config/env.ini index 0be1abdfb..f9cde5a08 100644 --- a/config/env.ini +++ b/config/env.ini @@ -100,9 +100,10 @@ SPC_TARGET=${GNU_ARCH}-linux-musl CC=${SPC_DEFAULT_CC} CXX=${SPC_DEFAULT_CXX} AR=${SPC_DEFAULT_AR} +RANLIB=${SPC_DEFAULT_RANLIB} LD=${SPC_DEFAULT_LD} ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build -SPC_DEFAULT_CFLAGS="-fPIC -O3 -pipe -fno-plt -fno-semantic-interposition -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections" +SPC_DEFAULT_CFLAGS="-fPIC -O3 -pipe -fno-plt -fno-semantic-interposition -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections -Wno-unused-command-line-argument" SPC_DEFAULT_CXXFLAGS="${SPC_DEFAULT_CFLAGS}" SPC_DEFAULT_LDFLAGS="-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -Wl,-z,noexecstack -Wl,--gc-sections" ; upx executable path @@ -125,6 +126,8 @@ SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fPIE SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS="-g -fstack-protector-strong -fno-ident -fPIE -fvisibility=hidden -fvisibility-inlines-hidden ${SPC_DEFAULT_CXXFLAGS}" ; 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; appended only to SAPI executable links (cli/fpm/cgi/micro/embed). Used by PGO to inject -fprofile-use= without polluting libphp.{a,so}. +SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="" ; optional, path to openssl conf. This affects where openssl will look for the default CA. ; default on Debian/Alpine: /etc/ssl, default on RHEL: /etc/pki/tls @@ -140,6 +143,7 @@ SPC_USE_LLVM=system CC=${SPC_DEFAULT_CC} CXX=${SPC_DEFAULT_CXX} AR=${SPC_DEFAULT_AR} +RANLIB=${SPC_DEFAULT_RANLIB} LD=${SPC_DEFAULT_LD} ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build SPC_DEFAULT_CFLAGS="--target=${MAC_ARCH}-apple-darwin -O3 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections" @@ -163,5 +167,7 @@ SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -fvis SPC_CMD_VAR_PHP_MAKE_EXTRA_CXXFLAGS="-g -fstack-protector-strong -fno-ident -fpie -fvisibility=hidden -fvisibility-inlines-hidden -Werror=unknown-warning-option ${SPC_DEFAULT_CXXFLAGS}" ; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.dylib SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS="" +; EXTRA_LDFLAGS_PROGRAM for `make` php; appended only to SAPI executable links (cli/fpm/cgi/micro/embed). Used by PGO to inject -fprofile-use= without polluting libphp.{a,dylib}. +SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="" ; minimum compatible macOS version (LLVM vars, availability not guaranteed) MACOSX_DEPLOYMENT_TARGET=12.0 From 768e1a048caf4012e25c89162dd5702b689cfab7 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:47:53 +0800 Subject: [PATCH 03/24] Apply gmssl extension patch changes in feat/pgo-v3 --- src/Package/Artifact/gmssl.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Package/Artifact/gmssl.php b/src/Package/Artifact/gmssl.php index 4caa4d1e2..833c7b415 100644 --- a/src/Package/Artifact/gmssl.php +++ b/src/Package/Artifact/gmssl.php @@ -17,4 +17,11 @@ public function patch(string $target_path): void FileSystem::replaceFileStr($target_path . '/src/hex.c', 'unsigned char *OPENSSL_hexstr2buf(const char *str, size_t *len)', 'unsigned char *GMSSL_hexstr2buf(const char *str, size_t *len)'); FileSystem::replaceFileStr($target_path . '/src/hex.c', 'OPENSSL_hexchar2int', 'GMSSL_hexchar2int'); } + + #[AfterSourceExtract('ext-gmssl')] + #[PatchDescription('Rename pbkdf2_hmac_sm3_genkey() to sm3_pbkdf2() (renamed upstream in GmSSL 3.2+; identical signature)')] + public function patchExt(string $target_path): void + { + FileSystem::replaceFileStr($target_path . '/gmssl.c', 'pbkdf2_hmac_sm3_genkey(', 'sm3_pbkdf2('); + } } From 5d76b852cf7ac5a65344cd4b45ed88a038f6a33c Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:48:56 +0800 Subject: [PATCH 04/24] Apply bzip2 patch changes in feat/pgo-v3 --- src/Package/Library/bzip2.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Package/Library/bzip2.php b/src/Package/Library/bzip2.php index 90fcce7c6..7f99c22b4 100644 --- a/src/Package/Library/bzip2.php +++ b/src/Package/Library/bzip2.php @@ -17,7 +17,9 @@ class bzip2 #[PatchBeforeBuild] public function patchBeforeBuild(LibraryPackage $lib): void { - FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS=-Wall', 'CFLAGS=-fPIC -Wall'); + // Makefile pins -O2 -fPIC; inject SPC_DEFAULT_CFLAGS + $extra = deduplicate_flags(trim((string) getenv('SPC_DEFAULT_CFLAGS')) . ' -fPIC -Wall'); + FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS=-Wall', "CFLAGS={$extra}"); } #[BuildFor('Windows')] From 21c624eaa5f23bacdc0e10c04b19557a7748f8e3 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:49:52 +0800 Subject: [PATCH 05/24] Apply fastlz patch changes in feat/pgo-v3 --- src/Package/Library/fastlz.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Package/Library/fastlz.php b/src/Package/Library/fastlz.php index f9dd010dc..7c3792cd2 100644 --- a/src/Package/Library/fastlz.php +++ b/src/Package/Library/fastlz.php @@ -18,9 +18,11 @@ public function build(LibraryPackage $lib): void { $cc = getenv('CC') ?: 'cc'; $ar = getenv('AR') ?: 'ar'; + $extra = trim((string) getenv('SPC_DEFAULT_CFLAGS')); + $extra = $extra !== '' ? $extra . ' -fPIC' : '-O3 -fPIC'; shell()->cd($lib->getSourceDir())->initializeEnv($lib) - ->exec("{$cc} -c -O3 -fPIC fastlz.c -o fastlz.o") + ->exec("{$cc} -c {$extra} fastlz.c -o fastlz.o") ->exec("{$ar} rcs libfastlz.a fastlz.o"); // Copy header file From fb4d151c08d8f1c132a837453a1b3632819f1caf Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:50:21 +0800 Subject: [PATCH 06/24] Apply icu patch changes in feat/pgo-v3 --- src/Package/Library/icu.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Package/Library/icu.php b/src/Package/Library/icu.php index 7364e94ab..bab245081 100644 --- a/src/Package/Library/icu.php +++ b/src/Package/Library/icu.php @@ -24,9 +24,12 @@ public function beforePack(LibraryPackage $lib): void #[BuildFor('Linux')] public function buildLinux(LibraryPackage $lib, ToolchainInterface $toolchain, PackageBuilder $builder): void { + // runConfigureICU bakes CXXFLAGS/LDFLAGS, apply user flags too + $userCxxFlags = trim((string) getenv('SPC_DEFAULT_CXXFLAGS')); + $userLdFlags = trim((string) getenv('SPC_DEFAULT_LDFLAGS')); $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 = $toolchain->isStatic() ? 'LDFLAGS="-static"' : ''; + $cxxflags = "CXXFLAGS=\"-std=c++17 -DPIC -fPIC -fno-ident {$userCxxFlags}\""; + $ldflags = $toolchain->isStatic() ? "LDFLAGS=\"-static {$userLdFlags}\"" : "LDFLAGS=\"{$userLdFlags}\""; shell()->cd($lib->getSourceDir() . '/source')->initializeEnv($lib) ->exec( "{$cppflags} {$cxxflags} {$ldflags} " . From 3e48d8fea2c1f3b2652b192a9e8a7451fcc0c43f Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:51:43 +0800 Subject: [PATCH 07/24] Apply jbig patch changes in feat/pgo-v3 --- src/Package/Library/jbig.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Package/Library/jbig.php b/src/Package/Library/jbig.php index 1cfe60b74..94527f457 100644 --- a/src/Package/Library/jbig.php +++ b/src/Package/Library/jbig.php @@ -17,7 +17,9 @@ class jbig #[PatchBeforeBuild] public function patchBeforeBuild(LibraryPackage $lib): void { - FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS = -O2 -W -Wno-unused-result', 'CFLAGS = -O2 -W -Wno-unused-result -fPIC'); + $extra = trim((string) getenv('SPC_DEFAULT_CFLAGS')); + $cflags = ($extra !== '' ? $extra : '-O2') . ' -W -Wno-unused-result -fPIC'; + FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS = -O2 -W -Wno-unused-result', "CFLAGS = {$cflags}"); } #[BuildFor('Darwin')] From b872c425e74c336ac1309b9583e39d3e1b547618 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:52:04 +0800 Subject: [PATCH 08/24] Apply krb5 patch changes in feat/pgo-v3 --- src/Package/Library/krb5.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Package/Library/krb5.php b/src/Package/Library/krb5.php index 1370afccb..428c6d9b3 100644 --- a/src/Package/Library/krb5.php +++ b/src/Package/Library/krb5.php @@ -27,7 +27,7 @@ public function build(LibraryPackage $lib, PackageInstaller $installer, Toolchai $resolved = array_keys($installer->getResolvedPackages()); $spc = new SPCConfigUtil(['no_php' => true, 'libs_only_deps' => true]); - $config = $spc->getPackageDepsConfig($lib->getName(), $resolved, include_suggests: true); + $config = $spc->getPackageDepsConfig($lib->getName(), $resolved); $extraEnv = [ 'CFLAGS' => '-fcommon', 'LIBS' => $config['libs'], From fbbcc80126a252b0eeffd5a8be9553cf0041b098 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:57:15 +0800 Subject: [PATCH 09/24] Update libaom configuration to support target architecture detection --- src/Package/Library/libaom.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Package/Library/libaom.php b/src/Package/Library/libaom.php index 7e578242b..a896d9b57 100644 --- a/src/Package/Library/libaom.php +++ b/src/Package/Library/libaom.php @@ -9,8 +9,10 @@ use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Runtime\SystemTarget; use StaticPHP\Toolchain\Interface\ToolchainInterface; use StaticPHP\Toolchain\ZigToolchain; +use StaticPHP\Util\System\UnixUtil; #[Library('libaom')] class libaom extends LibraryPackage @@ -39,9 +41,27 @@ public function buildUnix(ToolchainInterface $toolchain): void $new = trim($extra . ' -D_GNU_SOURCE'); f_putenv("SPC_COMPILER_EXTRA={$new}"); } + $targetCpu = SystemTarget::getTargetArch(); + if (str_starts_with($targetCpu, 'aarch')) { + $targetCpu = str_replace('aarch', 'arm', $targetCpu); + } + if ( + in_array($targetCpu, ['x86', 'x86_64'], true) + && !UnixUtil::findCommand('nasm') + && !UnixUtil::findCommand('yasm') + ) { + $targetCpu = 'generic'; + } UnixCMakeExecutor::create($this) ->setBuildDir("{$this->getSourceDir()}/builddir") - ->addConfigureArgs('-DAOM_TARGET_CPU=generic') + ->addConfigureArgs( + "-DAOM_TARGET_CPU={$targetCpu}", + '-DCONFIG_RUNTIME_CPU_DETECT=1', + '-DENABLE_EXAMPLES=OFF', + '-DENABLE_TESTS=OFF', + '-DENABLE_TOOLS=OFF', + '-DENABLE_DOCS=OFF', + ) ->build(); f_putenv("SPC_COMPILER_EXTRA={$extra}"); $this->patchPkgconfPrefix(['aom.pc']); From d6b2b96aa813fb7e97c437c4c694260bde5773ff Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 12:59:20 +0800 Subject: [PATCH 10/24] Apply go_xcaddy patch changes in feat/pgo-v3 --- src/Package/Artifact/go_xcaddy.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Package/Artifact/go_xcaddy.php b/src/Package/Artifact/go_xcaddy.php index 51ccfb87b..08bf02d32 100644 --- a/src/Package/Artifact/go_xcaddy.php +++ b/src/Package/Artifact/go_xcaddy.php @@ -25,7 +25,6 @@ class go_xcaddy ])] public function downBinary(ArtifactDownloader $downloader): DownloadResult { - $pkgroot = PKG_ROOT_PATH; $name = SystemTarget::getCurrentPlatformString(); $arch = match (explode('-', $name)[1]) { 'x86_64' => 'amd64', @@ -64,7 +63,7 @@ public function downBinary(ArtifactDownloader $downloader): DownloadResult if ($file_hash !== $hash) { throw new DownloaderException("Hash mismatch for downloaded go-xcaddy binary. Expected {$hash}, got {$file_hash}"); } - return DownloadResult::archive(basename($path), ['url' => $url, 'version' => $version], extract: "{$pkgroot}/go-xcaddy", verified: true, version: $version); + return DownloadResult::archive(basename($path), ['url' => $url, 'version' => $version], extract: '{pkg_root_path}/go-xcaddy', verified: true, version: $version); } #[CustomBinaryCheckUpdate('go-xcaddy', [ @@ -109,7 +108,7 @@ public function afterExtract(string $target_path): void 'GOROOT' => "{$target_path}", 'GOBIN' => "{$target_path}/bin", 'GOPATH' => "{$target_path}/go", - ])->exec('CC=cc go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest'); + ])->exec('CGO_ENABLED=0 go install github.com/caddyserver/xcaddy/cmd/xcaddy@master'); GlobalEnvManager::addPathIfNotExists("{$target_path}/bin"); } } From 7ff2ccb81e29f56ae202b48f85dc89a40d1d8aad Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 13:00:04 +0800 Subject: [PATCH 11/24] Apply libffi patch changes in feat/pgo-v3 --- src/Package/Library/libffi.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Package/Library/libffi.php b/src/Package/Library/libffi.php index 351b9076c..e40127fb3 100644 --- a/src/Package/Library/libffi.php +++ b/src/Package/Library/libffi.php @@ -8,6 +8,7 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\SystemTarget; #[Library('libffi')] class libffi extends LibraryPackage @@ -28,7 +29,7 @@ public function buildLinux(): void #[BuildFor('Darwin')] public function buildDarwin(): void { - $arch = getenv('SPC_ARCH'); + $arch = SystemTarget::getTargetArch(); UnixAutoconfExecutor::create($this) ->configure( "--host={$arch}-apple-darwin", From 521b949d2cebfb181ebb1b15a09f5fdde9785915 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 13:00:36 +0800 Subject: [PATCH 12/24] Apply libheif patch changes in feat/pgo-v3 --- src/Package/Library/libheif.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Package/Library/libheif.php b/src/Package/Library/libheif.php index 65545f365..19ad4c619 100644 --- a/src/Package/Library/libheif.php +++ b/src/Package/Library/libheif.php @@ -24,6 +24,17 @@ public function patchBeforeBuild(LibraryPackage $lib): void 'list(APPEND REQUIRES_PRIVATE "libbrotlidec")' . "\n" . ' list(APPEND REQUIRES_PRIVATE "libbrotlienc")' ); } + // libheif 1.22+ ships a C-incompatible header: `struct heif_bad_pixel` + $heif_properties = $lib->getSourceDir() . '/libheif/api/libheif/heif_properties.h'; + if (file_exists($heif_properties) + && str_contains(file_get_contents($heif_properties), 'struct heif_bad_pixel { uint32_t row; uint32_t column; };') + ) { + FileSystem::replaceFileStr( + $heif_properties, + 'struct heif_bad_pixel { uint32_t row; uint32_t column; };', + 'typedef struct heif_bad_pixel { uint32_t row; uint32_t column; } heif_bad_pixel;' + ); + } } #[BuildFor('Darwin')] From b46bc39a3d34fc409d12c6adc1484202477b26c0 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 13:01:28 +0800 Subject: [PATCH 13/24] Apply ncurses patch changes in feat/pgo-v3 --- src/Package/Library/ncurses.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Package/Library/ncurses.php b/src/Package/Library/ncurses.php index dd591a6f9..74e3a30f6 100644 --- a/src/Package/Library/ncurses.php +++ b/src/Package/Library/ncurses.php @@ -6,6 +6,8 @@ use StaticPHP\Attribute\Package\BuildFor; use StaticPHP\Attribute\Package\Library; +use StaticPHP\Attribute\Package\PatchBeforeBuild; +use StaticPHP\Attribute\PatchDescription; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; use StaticPHP\Toolchain\Interface\ToolchainInterface; @@ -16,6 +18,24 @@ #[Library('ncursesw')] class ncurses { + #[PatchBeforeBuild] + #[PatchDescription('Filter clang/zig "N warning(s) generated." line out of MKlib_gen.sh preprocessor pipe')] + public function patchBeforeBuild(LibraryPackage $lib): void + { + // MKlib_gen.sh feeds the C preprocessor's stdout through a sed/awk + // pipeline into lib_gen.c. zig-cc/clang emits "N warning(s) generated." + // on stdout (not stderr), and that line ends up as invalid C in the + // generated source. Filter it out of the pipe before sed sees it. + $mklibGen = $lib->getSourceDir() . '/ncurses/base/MKlib_gen.sh'; + if (is_file($mklibGen) && !str_contains((string) file_get_contents($mklibGen), "| grep -v ' generated")) { + FileSystem::replaceFileStr( + $mklibGen, + '$preprocessor $TMP 2>/dev/null \\', + "\$preprocessor \$TMP 2>/dev/null \\\n| grep -v ' generated\\.\$' \\", + ); + } + } + #[BuildFor('Darwin')] #[BuildFor('Linux')] public function build(LibraryPackage $package, ToolchainInterface $toolchain): void @@ -45,6 +65,7 @@ public function build(LibraryPackage $package, ToolchainInterface $toolchain): v '--without-tests', '--without-dlsym', '--without-debug', + '--disable-stripping', '--enable-symlinks', "--with-terminfo-dirs={$terminfo_dirs}", "--bindir={$package->getBinDir()}", From 873222299b933846e637e9db9c7438d3df0fd2a6 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 13:02:52 +0800 Subject: [PATCH 14/24] Apply openssl patch changes in feat/pgo-v3 --- src/Package/Library/openssl.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Package/Library/openssl.php b/src/Package/Library/openssl.php index f673bb67f..8e3c53b75 100644 --- a/src/Package/Library/openssl.php +++ b/src/Package/Library/openssl.php @@ -11,6 +11,7 @@ use StaticPHP\Package\PackageBuilder; use StaticPHP\Package\ToolPackage; use StaticPHP\Registry\PackageLoader; +use StaticPHP\Runtime\SystemTarget; use StaticPHP\Util\FileSystem; use StaticPHP\Util\System\LinuxUtil; @@ -57,7 +58,7 @@ public function buildWin(LibraryPackage $lib, PackageBuilder $builder): void public function buildForDarwin(LibraryPackage $pkg): void { $zlib_libs = $pkg->getInstaller()->getLibraryPackage('zlib')->getStaticLibFiles(); - $arch = getenv('SPC_ARCH'); + $arch = SystemTarget::getTargetArch(); shell()->cd($pkg->getSourceDir())->initializeEnv($pkg) ->exec( @@ -76,12 +77,7 @@ public function buildForDarwin(LibraryPackage $pkg): void #[BuildFor('Linux')] public function build(LibraryPackage $lib): void { - $arch = getenv('SPC_ARCH'); - - $env = "CC='" . getenv('CC') . ' -idirafter ' . BUILD_INCLUDE_PATH . - ' -idirafter /usr/include/ ' . - ' -idirafter /usr/include/' . getenv('SPC_ARCH') . '-linux-gnu/ ' . - "' "; + $arch = SystemTarget::getTargetArch(); $ex_lib = trim($lib->getInstaller()->getLibraryPackage('zlib')->getStaticLibFiles()) . ' -ldl -pthread'; $zlib_extra = @@ -92,9 +88,15 @@ public function build(LibraryPackage $lib): void $openssl_dir ??= LinuxUtil::getOSRelease()['dist'] === 'redhat' ? '/etc/pki/tls' : '/etc/ssl'; $ex_lib = trim($ex_lib); + // anything we want included (PGO -fprofile-*, LTO, custom hardening) + // has to be appended on the command line *after* the target name. + $userCFlags = trim((string) getenv('SPC_DEFAULT_CFLAGS')); + $userLdFlags = trim((string) getenv('SPC_DEFAULT_LDFLAGS')); + $userExtra = trim($userCFlags . ' ' . $userLdFlags); + shell()->cd($lib->getSourceDir())->initializeEnv($lib) ->exec( - "{$env} ./Configure no-shared zlib " . + './Configure no-shared zlib ' . "--prefix={$lib->getBuildRootPath()} " . "--libdir={$lib->getLibDir()} " . "--openssldir={$openssl_dir} " . @@ -102,7 +104,8 @@ public function build(LibraryPackage $lib): void 'enable-pie ' . 'no-legacy ' . 'no-tests ' . - "linux-{$arch}" + "linux-{$arch} " . + $userExtra ) ->exec('make clean') ->exec("make -j{$lib->getBuilder()->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") From 0de02d743d8415fa44776819ea7501a0d214533c Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 13:20:36 +0800 Subject: [PATCH 15/24] Fix openssl patch changes in feat/pgo-v3 --- src/Package/Library/openssl.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Package/Library/openssl.php b/src/Package/Library/openssl.php index 8e3c53b75..fbde9cf24 100644 --- a/src/Package/Library/openssl.php +++ b/src/Package/Library/openssl.php @@ -58,7 +58,11 @@ public function buildWin(LibraryPackage $lib, PackageBuilder $builder): void public function buildForDarwin(LibraryPackage $pkg): void { $zlib_libs = $pkg->getInstaller()->getLibraryPackage('zlib')->getStaticLibFiles(); - $arch = SystemTarget::getTargetArch(); + $targetArch = SystemTarget::getTargetArch(); + $arch = match ($targetArch) { + 'aarch64' => 'arm64', + default => $targetArch, + }; shell()->cd($pkg->getSourceDir())->initializeEnv($pkg) ->exec( From 42c343d44d9ef1ea3474354f454f3dd7935c2e83 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 14:07:01 +0800 Subject: [PATCH 16/24] Revert krb5 patch changes in feat/pgo-v3 --- src/Package/Library/krb5.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Package/Library/krb5.php b/src/Package/Library/krb5.php index 428c6d9b3..1370afccb 100644 --- a/src/Package/Library/krb5.php +++ b/src/Package/Library/krb5.php @@ -27,7 +27,7 @@ public function build(LibraryPackage $lib, PackageInstaller $installer, Toolchai $resolved = array_keys($installer->getResolvedPackages()); $spc = new SPCConfigUtil(['no_php' => true, 'libs_only_deps' => true]); - $config = $spc->getPackageDepsConfig($lib->getName(), $resolved); + $config = $spc->getPackageDepsConfig($lib->getName(), $resolved, include_suggests: true); $extraEnv = [ 'CFLAGS' => '-fcommon', 'LIBS' => $config['libs'], From df0bc83aeb68cd8e67458284a8d2d88adf744c1a Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 15 Jul 2026 15:04:48 +0800 Subject: [PATCH 17/24] Disable musl-wrapper installation on default situation --- src/StaticPHP/Doctor/Item/LinuxMuslCheck.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/StaticPHP/Doctor/Item/LinuxMuslCheck.php b/src/StaticPHP/Doctor/Item/LinuxMuslCheck.php index 1fe7ed00d..2d871f0c7 100644 --- a/src/StaticPHP/Doctor/Item/LinuxMuslCheck.php +++ b/src/StaticPHP/Doctor/Item/LinuxMuslCheck.php @@ -13,6 +13,7 @@ use StaticPHP\DI\ApplicationContext; use StaticPHP\Doctor\CheckResult; use StaticPHP\Runtime\Shell\Shell; +use StaticPHP\Runtime\SystemTarget; use StaticPHP\Toolchain\Interface\ToolchainInterface; use StaticPHP\Toolchain\MuslToolchain; use StaticPHP\Toolchain\ZigToolchain; @@ -27,7 +28,14 @@ class LinuxMuslCheck public static function optionalCheck(): bool { $toolchain = ApplicationContext::get(ToolchainInterface::class); - return $toolchain instanceof MuslToolchain || $toolchain instanceof ZigToolchain && !LinuxUtil::isMuslDist() && !str_contains(getenv('SPC_TARGET') ?: '', 'gnu'); + return PHP_OS_FAMILY === 'Linux' && ( + $toolchain instanceof MuslToolchain || ( + $toolchain instanceof ZigToolchain + && !LinuxUtil::isMuslDist() + && SystemTarget::getLibc() === 'musl' + && !$toolchain->isStatic() + ) + ); } /** @noinspection PhpUnused */ From 977ea4a8f800dff5fa6c47bac05ded454d7e0b76 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Jul 2026 13:58:25 +0800 Subject: [PATCH 18/24] Apply event changes in feat/pgo-v3 --- src/Package/Extension/event.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Package/Extension/event.php b/src/Package/Extension/event.php index db1192745..2b9515cf7 100644 --- a/src/Package/Extension/event.php +++ b/src/Package/Extension/event.php @@ -35,12 +35,37 @@ public function getUnixConfigureArg(PackageInstaller $installer): string #[BeforeStage('php', [php::class, 'makeForUnix'], 'ext-event')] #[PatchDescription('Prevent event extension compile error on macOS')] + #[PatchDescription('Patch libevent http_connection.c to use a const peer address')] public function patchBeforeMake(PackageInstaller $installer): void { + $php_src = $installer->getTargetPackage('php')->getSourceDir(); // Prevent event extension compile error on macOS if (SystemTarget::getTargetOS() === 'Darwin') { - $php_src = $installer->getTargetPackage('php')->getSourceDir(); FileSystem::replaceFileRegex("{$php_src}/main/php_config.h", '/^#define HAVE_OPENPTY 1$/m', ''); } + $this->patchLibeventConstPeer("{$php_src}/ext/event"); + } + + #[BeforeStage('ext-event', [PhpExtensionPackage::class, 'makeForUnix'])] + #[PatchDescription('Patch libevent http_connection.c to use a const peer address')] + public function patchBeforeSharedMake(PhpExtensionPackage $pkg): void + { + $this->patchLibeventConstPeer($pkg->getSourceDir()); + } + + private function patchLibeventConstPeer(string $event_source_dir): bool + { + $file = "{$event_source_dir}/php8/classes/http_connection.c"; + if (!is_file($file)) { + return false; + } + // libevent >= 2.2 changed evhttp_connection_get_peer()'s + // address arg to `const char **` + $header = $this->getBuilder()->getBuildRootPath() . '/include/event2/http.h'; + $isConst = is_file($header) + && preg_match('/evhttp_connection_get_peer\s*\([^;]*\bconst\s+char\s*\*\*\s*address/s', file_get_contents($header)) === 1; + return (bool) ($isConst + ? FileSystem::replaceFileRegex($file, '/^\tchar \*address;$/m', "\tconst char *address;") + : FileSystem::replaceFileRegex($file, '/^\tconst char \*address;$/m', "\tchar *address;")); } } From 0f92692f4ec403d36acd11de6bdf6b653dfacfb9 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Jul 2026 14:00:14 +0800 Subject: [PATCH 19/24] Apply github token header injection changes in feat/pgo-v3 --- .../Downloader/Type/GitHubTokenSetupTrait.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/StaticPHP/Artifact/Downloader/Type/GitHubTokenSetupTrait.php b/src/StaticPHP/Artifact/Downloader/Type/GitHubTokenSetupTrait.php index 412a4c1c3..1850cd5ba 100644 --- a/src/StaticPHP/Artifact/Downloader/Type/GitHubTokenSetupTrait.php +++ b/src/StaticPHP/Artifact/Downloader/Type/GitHubTokenSetupTrait.php @@ -14,17 +14,18 @@ public function getGitHubTokenHeaders(): array public static function getGitHubTokenHeadersStatic(): array { // GITHUB_TOKEN support - if (($token = getenv('GITHUB_TOKEN')) !== false && ($user = getenv('GITHUB_USER')) !== false) { + $token = getenv('GITHUB_TOKEN'); + if ($token === false || $token === '') { + return []; + } + if (($user = getenv('GITHUB_USER')) !== false && $user !== '') { logger()->debug("Using 'GITHUB_TOKEN' with user {$user} for authentication"); $encoded = base64_encode("{$user}:{$token}"); spc_add_log_filter([$user, $token, $encoded]); return ["Authorization: Basic {$encoded}"]; } - if (($token = getenv('GITHUB_TOKEN')) !== false) { - logger()->debug("Using 'GITHUB_TOKEN' for authentication"); - spc_add_log_filter($token); - return ["Authorization: Bearer {$token}"]; - } - return []; + logger()->debug("Using 'GITHUB_TOKEN' for authentication"); + spc_add_log_filter($token); + return ["Authorization: Bearer {$token}"]; } } From 8a7cf24b70a85d5772cb36d49f19d9559cd2d9ec Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Jul 2026 14:07:50 +0800 Subject: [PATCH 20/24] Apply phpmicro phar patch changes in feat/pgo-v3 --- src/StaticPHP/Util/SourcePatcher.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/StaticPHP/Util/SourcePatcher.php b/src/StaticPHP/Util/SourcePatcher.php index 98fee7ec2..430a44edc 100644 --- a/src/StaticPHP/Util/SourcePatcher.php +++ b/src/StaticPHP/Util/SourcePatcher.php @@ -173,6 +173,9 @@ public static function unpatchHardcodedINI(string $php_source_dir): bool */ public static function patchMicroPhar(int $version_id): void { + if (file_exists(SOURCE_PATH . '/php-src/ext/phar/phar.c.bak')) { + return; + } FileSystem::backupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c'); FileSystem::replaceFileStr( SOURCE_PATH . '/php-src/ext/phar/phar.c', @@ -198,6 +201,12 @@ public static function patchMicroPhar(int $version_id): void public static function unpatchMicroPhar(): void { + // Tolerate a missing .bak: both drivers call this, and the first restore + // consumes the backup. Without this guard the second call throws + // "Cannot find bak file". No .bak means the source is already pristine. + if (!file_exists(SOURCE_PATH . '/php-src/ext/phar/phar.c.bak')) { + return; + } FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c'); } From 55697ce801d1b245410ee68d75731ae9a3eff025 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Jul 2026 14:59:36 +0800 Subject: [PATCH 21/24] Remove LinuxMuslCheck --- src/StaticPHP/Doctor/Item/LinuxMuslCheck.php | 123 ------------------- 1 file changed, 123 deletions(-) delete mode 100644 src/StaticPHP/Doctor/Item/LinuxMuslCheck.php diff --git a/src/StaticPHP/Doctor/Item/LinuxMuslCheck.php b/src/StaticPHP/Doctor/Item/LinuxMuslCheck.php deleted file mode 100644 index 2d871f0c7..000000000 --- a/src/StaticPHP/Doctor/Item/LinuxMuslCheck.php +++ /dev/null @@ -1,123 +0,0 @@ -isStatic() - ) - ); - } - - /** @noinspection PhpUnused */ - #[CheckItem('if musl-wrapper is installed', limit_os: 'Linux', level: 800)] - public function checkMusl(): ?CheckResult - { - $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') || getenv('SPC_TOOLCHAIN') === ZigToolchain::class)) { - return null; - } - return CheckResult::fail('musl-wrapper is not installed on your system', 'fix-musl-wrapper'); - } - - #[CheckItem('if musl-cross-make is installed', limit_os: 'Linux', level: 799)] - public function checkMuslCrossMake(): ?CheckResult - { - if (getenv('SPC_TOOLCHAIN') === ZigToolchain::class && !LinuxUtil::isMuslDist()) { - return null; - } - $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"; - if (file_exists($cross_compile_lib) && file_exists($cross_compile_gcc)) { - return CheckResult::ok(); - } - return CheckResult::fail('musl-cross-make is not installed on your system', 'fix-musl-cross-make'); - } - - #[FixItem('fix-musl-wrapper')] - public function fixMusl(): bool - { - $downloader = new ArtifactDownloader(interactive: false); - $downloader->add('musl-wrapper')->download(); - $extractor = new ArtifactExtractor(ApplicationContext::get(ArtifactCache::class)); - $extractor->extract('musl-wrapper'); - - // Apply CVE-2025-26519 patch and install musl wrapper - SourcePatcher::patchFile('musl-1.2.5_CVE-2025-26519_0001.patch', SOURCE_PATH . '/musl-wrapper'); - SourcePatcher::patchFile('musl-1.2.5_CVE-2025-26519_0002.patch', SOURCE_PATH . '/musl-wrapper'); - - $prefix = ''; - if (get_current_user() !== 'root') { - $prefix = 'sudo '; - logger()->warning('Current user is not root, using sudo for running command'); - } - $sysEnv = ['CC' => 'gcc', 'CXX' => 'g++', 'AR' => 'ar', 'LD' => 'ld', 'RANLIB' => 'ranlib']; - $envFlags = ''; - foreach ($sysEnv as $k => $v) { - $envFlags .= "{$k}={$v} "; - } - $envFlags = rtrim($envFlags); - $shell = shell()->cd(SOURCE_PATH . '/musl-wrapper') - ->setEnv($sysEnv) - ->exec('./configure --disable-gcc-wrapper') - ->exec('make -j'); - if ($prefix !== '') { - f_passthru('cd ' . SOURCE_PATH . "/musl-wrapper && {$envFlags} {$prefix}make install"); - } else { - $shell->exec("{$prefix}make install"); - } - return true; - } - - #[FixItem('fix-musl-cross-make')] - public function fixMuslCrossMake(): bool - { - // sudo - $prefix = ''; - if (get_current_user() !== 'root') { - $prefix = 'sudo '; - logger()->warning('Current user is not root, using sudo for running command'); - } - Shell::passthruCallback(function () { - InteractiveTerm::advance(); - }); - $downloader = new ArtifactDownloader(interactive: false); - $extractor = new ArtifactExtractor(ApplicationContext::get(ArtifactCache::class)); - $downloader->add('musl-toolchain')->download(); - $extractor->extract('musl-toolchain'); - $pkg_root = PKG_ROOT_PATH . '/musl-toolchain'; - f_passthru("{$prefix}cp -rf {$pkg_root}/* /usr/local/musl"); - FileSystem::removeDir($pkg_root); - return true; - } -} From 3a3602214dc8f6ba56f7ae62b3daa30660451d74 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Jul 2026 14:59:53 +0800 Subject: [PATCH 22/24] Revert RANLIB in env.ini --- config/env.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/env.ini b/config/env.ini index f9cde5a08..cec799156 100644 --- a/config/env.ini +++ b/config/env.ini @@ -100,7 +100,6 @@ SPC_TARGET=${GNU_ARCH}-linux-musl CC=${SPC_DEFAULT_CC} CXX=${SPC_DEFAULT_CXX} AR=${SPC_DEFAULT_AR} -RANLIB=${SPC_DEFAULT_RANLIB} LD=${SPC_DEFAULT_LD} ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build SPC_DEFAULT_CFLAGS="-fPIC -O3 -pipe -fno-plt -fno-semantic-interposition -fstack-clash-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections -Wno-unused-command-line-argument" @@ -143,7 +142,6 @@ SPC_USE_LLVM=system CC=${SPC_DEFAULT_CC} CXX=${SPC_DEFAULT_CXX} AR=${SPC_DEFAULT_AR} -RANLIB=${SPC_DEFAULT_RANLIB} LD=${SPC_DEFAULT_LD} ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build SPC_DEFAULT_CFLAGS="--target=${MAC_ARCH}-apple-darwin -O3 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffunction-sections -fdata-sections" From 77a13fb02b08dbd7a18adf39f0bef88048cd0c2e Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Jul 2026 15:00:18 +0800 Subject: [PATCH 23/24] Revert "Apply event changes in feat/pgo-v3" This reverts commit 977ea4a8f800dff5fa6c47bac05ded454d7e0b76. --- src/Package/Extension/event.php | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/Package/Extension/event.php b/src/Package/Extension/event.php index 2b9515cf7..db1192745 100644 --- a/src/Package/Extension/event.php +++ b/src/Package/Extension/event.php @@ -35,37 +35,12 @@ public function getUnixConfigureArg(PackageInstaller $installer): string #[BeforeStage('php', [php::class, 'makeForUnix'], 'ext-event')] #[PatchDescription('Prevent event extension compile error on macOS')] - #[PatchDescription('Patch libevent http_connection.c to use a const peer address')] public function patchBeforeMake(PackageInstaller $installer): void { - $php_src = $installer->getTargetPackage('php')->getSourceDir(); // Prevent event extension compile error on macOS if (SystemTarget::getTargetOS() === 'Darwin') { + $php_src = $installer->getTargetPackage('php')->getSourceDir(); FileSystem::replaceFileRegex("{$php_src}/main/php_config.h", '/^#define HAVE_OPENPTY 1$/m', ''); } - $this->patchLibeventConstPeer("{$php_src}/ext/event"); - } - - #[BeforeStage('ext-event', [PhpExtensionPackage::class, 'makeForUnix'])] - #[PatchDescription('Patch libevent http_connection.c to use a const peer address')] - public function patchBeforeSharedMake(PhpExtensionPackage $pkg): void - { - $this->patchLibeventConstPeer($pkg->getSourceDir()); - } - - private function patchLibeventConstPeer(string $event_source_dir): bool - { - $file = "{$event_source_dir}/php8/classes/http_connection.c"; - if (!is_file($file)) { - return false; - } - // libevent >= 2.2 changed evhttp_connection_get_peer()'s - // address arg to `const char **` - $header = $this->getBuilder()->getBuildRootPath() . '/include/event2/http.h'; - $isConst = is_file($header) - && preg_match('/evhttp_connection_get_peer\s*\([^;]*\bconst\s+char\s*\*\*\s*address/s', file_get_contents($header)) === 1; - return (bool) ($isConst - ? FileSystem::replaceFileRegex($file, '/^\tchar \*address;$/m', "\tconst char *address;") - : FileSystem::replaceFileRegex($file, '/^\tconst char \*address;$/m', "\tchar *address;")); } } From 6c52febf5f5cd4d5dc614034253ab792b33e77ae Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Thu, 16 Jul 2026 15:02:58 +0800 Subject: [PATCH 24/24] Apply suggestion --- src/Package/Library/bzip2.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Package/Library/bzip2.php b/src/Package/Library/bzip2.php index 7f99c22b4..09b418a2a 100644 --- a/src/Package/Library/bzip2.php +++ b/src/Package/Library/bzip2.php @@ -17,8 +17,8 @@ class bzip2 #[PatchBeforeBuild] public function patchBeforeBuild(LibraryPackage $lib): void { - // Makefile pins -O2 -fPIC; inject SPC_DEFAULT_CFLAGS - $extra = deduplicate_flags(trim((string) getenv('SPC_DEFAULT_CFLAGS')) . ' -fPIC -Wall'); + // Inject SPC_DEFAULT_CFLAGS into the Makefile + $extra = deduplicate_flags(trim((string) getenv('SPC_DEFAULT_CFLAGS')) . ' -Wall'); FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS=-Wall', "CFLAGS={$extra}"); }