diff --git a/config/pkg/ext/ext-brotli.yml b/config/pkg/ext/ext-brotli.yml index 147ecb63..b87fb9ef 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 9b01422b..b07db490 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/src/Package/Extension/event.php b/src/Package/Extension/event.php index db119274..9aca279f 100644 --- a/src/Package/Extension/event.php +++ b/src/Package/Extension/event.php @@ -35,12 +35,30 @@ class event extends PhpExtensionPackage #[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) && FileSystem::replaceFileRegex($file, '/^\tchar \*address;$/m', "\tconst char *address;")) { + return true; + } + return false; } } diff --git a/src/Package/Target/php.php b/src/Package/Target/php.php index 280a0646..1704aa4e 100644 --- a/src/Package/Target/php.php +++ b/src/Package/Target/php.php @@ -143,6 +143,7 @@ class php extends TargetPackage $package->addBuildOption('disable-opcache-jit', null, null, 'Disable opcache jit'); $package->addBuildOption('with-config-file-path', null, InputOption::VALUE_REQUIRED, 'Set the path in which to look for php.ini', PHP_OS_FAMILY === 'Windows' ? null : '/usr/local/etc/php'); $package->addBuildOption('with-config-file-scan-dir', null, InputOption::VALUE_REQUIRED, 'Set the directory to scan for .ini files after reading php.ini', PHP_OS_FAMILY === 'Windows' ? null : '/usr/local/etc/php/conf.d'); + $package->addBuildOption('with-sysconfdir', null, InputOption::VALUE_REQUIRED, 'Set the sysconfdir (e.g. /etc/php-zts) used by configure (not available on Windows)'); $package->addBuildOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI'); $package->addBuildOption('enable-zts', null, null, 'Enable thread safe support'); $package->addBuildOption('no-smoke-test', null, InputOption::VALUE_OPTIONAL, 'Disable smoke test for specific SAPIs, or all if no value provided', false); diff --git a/src/Package/Target/php/unix.php b/src/Package/Target/php/unix.php index ae4f9ed7..b141a12d 100644 --- a/src/Package/Target/php/unix.php +++ b/src/Package/Target/php/unix.php @@ -75,6 +75,7 @@ trait unix #[BeforeStage('php', [self::class, 'configureForUnix'], 'php')] #[PatchDescription('Patch configure to use -std=gnu17 instead of -std=gnu23 for PHP <= 8.2')] + #[PatchDescription('Strip build-time env vars from phpinfo\'s "Configure Command"')] public function patchBeforeConfigure(TargetPackage $package): void { if (SystemTarget::isUnix() && self::getPHPVersionID() < 80300) { @@ -84,6 +85,22 @@ trait unix "for ac_arg in '' -std=gnu17", ); } + + // strip our build-time env vars from phpinfo's "Configure Command" ('|' delimiter: PHP_BUILD_PROVIDER may contain '#') + if (SystemTarget::isUnix()) { + FileSystem::replaceFileStr( + "{$package->getSourceDir()}/configure", + 'for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS EXTRA_LDFLAGS_PROGRAM LIBS CC CXX; do', + 'for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS EXTRA_LDFLAGS_PROGRAM LIBS CC CXX ' + . 'PKG_CONFIG PKG_CONFIG_PATH EXTENSION_DIR OPENSSL_LIBS ' + . 'PHP_BUILD_SYSTEM PHP_BUILD_PROVIDER PHP_BUILD_COMPILER PHP_BUILD_ARCH; do', + ); + FileSystem::replaceFileStr( + "{$package->getSourceDir()}/configure", + 'clean_configure_args=$(echo $clean_configure_args | $SED -e "s#\'$var=$val\'##")', + 'clean_configure_args=$(echo $clean_configure_args | $SED -e "s|\'$var=$val\'||")', + ); + } } #[Stage] @@ -125,6 +142,9 @@ trait unix if ($option = $package->getBuildOption('with-config-file-scan-dir', false)) { $args[] = "--with-config-file-scan-dir={$option}"; } + if ($option = $package->getBuildOption('with-sysconfdir', false)) { + $args[] = "--sysconfdir={$option}"; + } // perform enable cli options $args[] = $installer->isPackageResolved('php-cli') ? '--enable-cli' : '--disable-cli'; $args[] = $installer->isPackageResolved('php-fpm') diff --git a/src/StaticPHP/Artifact/Downloader/Type/GitHubRelease.php b/src/StaticPHP/Artifact/Downloader/Type/GitHubRelease.php index 20db7127..fd9b1f95 100644 --- a/src/StaticPHP/Artifact/Downloader/Type/GitHubRelease.php +++ b/src/StaticPHP/Artifact/Downloader/Type/GitHubRelease.php @@ -57,6 +57,16 @@ class GitHubRelease implements DownloadTypeInterface, ValidatorInterface, CheckU if (!is_array($data)) { throw new DownloaderException("Failed to get GitHub release API info for {$repo} from {$url}"); } + // GitHub's /releases list is ordered by publish date, so a newer-tagged prerelease + // (e.g. 2.2.x-alpha) can precede the latest stable (2.1.x-stable). /releases/latest + // returns the semantically latest stable release regardless of order; check it first. + if ($prefer_stable) { + $latest_url = str_replace('{repo}', $repo, self::API_URL) . '/latest'; + $latest = json_decode(default_shell()->executeCurl($latest_url, headers: $headers, retries: $retries) ?: '', true); + if (is_array($latest) && isset($latest['assets'])) { + array_unshift($data, $latest); + } + } foreach ($data as $release) { if ($prefer_stable && $release['prerelease'] === true) { continue; diff --git a/src/StaticPHP/Toolchain/ZigToolchain.php b/src/StaticPHP/Toolchain/ZigToolchain.php index 05819b16..c8dbb72e 100644 --- a/src/StaticPHP/Toolchain/ZigToolchain.php +++ b/src/StaticPHP/Toolchain/ZigToolchain.php @@ -75,6 +75,16 @@ class ZigToolchain implements UnixToolchainInterface $extra_vars = getenv('SPC_EXTRA_PHP_VARS') ?: ''; GlobalEnvManager::putenv("SPC_EXTRA_PHP_VARS=ac_cv_func_strlcpy=no ac_cv_func_strlcat=no {$extra_vars}"); + // An __attribute__((ifunc)) in LTO bitcode crashes zig 0.16's lld (LLVM 21) + // during thin-link symbol resolution + $all_flags = $cflags . ' ' . (getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') ?: '') . ' ' . (getenv('SPC_DEFAULT_LD_FLAGS') ?: ''); + if (str_contains($all_flags, '-flto')) { + $extra_vars = getenv('SPC_EXTRA_PHP_VARS') ?: ''; + if (!str_contains($extra_vars, 'ax_cv_have_func_attribute_ifunc')) { + GlobalEnvManager::putenv("SPC_EXTRA_PHP_VARS={$extra_vars} ax_cv_have_func_attribute_ifunc=no"); + } + } + $this->ensureCompilerRt(); } diff --git a/src/globals/scripts/zig-cc.sh b/src/globals/scripts/zig-cc.sh index 12bdd7e1..9c4ab1dd 100755 --- a/src/globals/scripts/zig-cc.sh +++ b/src/globals/scripts/zig-cc.sh @@ -68,13 +68,13 @@ done RT_DIR="${SPC_COMPILER_RT_DIR:-}" if [[ $IS_LINK -eq 1 && $NEED_PROFILE_RT -eq 1 && -n "$RT_DIR" && -f "$RT_DIR/libclang_rt.profile.a" ]]; then - PARSED_ARGS+=("$RT_DIR/libclang_rt.profile.a" "-Wl,-u,__llvm_profile_runtime") + PARSED_ARGS+=("-x" "none" "$RT_DIR/libclang_rt.profile.a" "-Wl,-u,__llvm_profile_runtime") fi if [[ $IS_LINK -eq 1 && $NEED_CRT -eq 1 && -n "$RT_DIR" && -f "$RT_DIR/clang_rt.crtbegin.o" && -f "$RT_DIR/clang_rt.crtend.o" ]]; then - PARSED_ARGS+=("$RT_DIR/clang_rt.crtbegin.o" "$RT_DIR/clang_rt.crtend.o") + PARSED_ARGS+=("-x" "none" "$RT_DIR/clang_rt.crtbegin.o" "$RT_DIR/clang_rt.crtend.o") fi if [[ $IS_LINK -eq 1 && -n "$RT_DIR" && -f "$RT_DIR/libclang_rt.cpu_model.a" ]]; then - PARSED_ARGS+=("$RT_DIR/libclang_rt.cpu_model.a") + PARSED_ARGS+=("-x" "none" "$RT_DIR/libclang_rt.cpu_model.a") fi [[ -n "$SPC_TARGET" ]] && TARGET="-target $SPC_TARGET" || TARGET=""