From c5efcc0c93c2852dde5734471ed8e49362ac03d8 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 16:07:28 +0800 Subject: [PATCH 01/52] Fix wrongly using msys2 tar.exe --- src/StaticPHP/Artifact/ArtifactExtractor.php | 3 +++ src/StaticPHP/Runtime/Shell/DefaultShell.php | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/StaticPHP/Artifact/ArtifactExtractor.php b/src/StaticPHP/Artifact/ArtifactExtractor.php index 4d38a84bd..8b73243a4 100644 --- a/src/StaticPHP/Artifact/ArtifactExtractor.php +++ b/src/StaticPHP/Artifact/ArtifactExtractor.php @@ -468,6 +468,9 @@ protected function extractArchive(string $filename, string $target): void if ($extname !== 'exe' && !is_dir($target)) { FileSystem::createDir($target); + if (!is_dir($target)) { + throw new FileSystemException("Failed to create target directory: {$target}"); + } } match (SystemTarget::getTargetOS()) { 'Windows' => match ($extname) { diff --git a/src/StaticPHP/Runtime/Shell/DefaultShell.php b/src/StaticPHP/Runtime/Shell/DefaultShell.php index 66dfb7ab0..77dbf94a0 100644 --- a/src/StaticPHP/Runtime/Shell/DefaultShell.php +++ b/src/StaticPHP/Runtime/Shell/DefaultShell.php @@ -132,7 +132,7 @@ public function executeTarExtract(string $archive_path, string $target_path, str }; $mute = $this->console_putput ? '' : ' 2>/dev/null'; - $cmd = "tar {$compression_flag}xf {$archive_arg} --strip-components {$strip} -C {$target_arg}{$mute}"; + $cmd = "\"C:\\Windows\\system32\\tar.exe\" {$compression_flag}xf {$archive_arg} --strip-components {$strip} -C {$target_arg}{$mute}"; $this->logCommandInfo($cmd); logger()->debug("[TAR EXTRACT] {$cmd}"); @@ -187,7 +187,7 @@ public function execute7zExtract(string $archive_path, string $target_path): boo $extname = FileSystem::extname($archive_path); match ($extname) { 'tar' => $this->executeTarExtract($archive_path, $target_path, 'none'), - 'gz', 'tgz', 'xz', 'txz', 'bz2' => $run("{$_7z} x -so {$archive_arg} | tar -f - -x -C {$target_arg} --strip-components 1"), + 'gz', 'tgz', 'xz', 'txz', 'bz2' => $run("{$_7z} x -so {$archive_arg} | \"C:\\Windows\\system32\\tar.exe\" -f - -x -C {$target_arg} --strip-components 1"), default => $run("{$_7z} x {$archive_arg} -o{$target_arg} -y{$mute}"), }; From 3c9e868ce14d159339bcdf32408955dceea8fe9d Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 16:08:58 +0800 Subject: [PATCH 02/52] Add spc-debug script on Windows --- bin/spc-debug.ps1 | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 bin/spc-debug.ps1 diff --git a/bin/spc-debug.ps1 b/bin/spc-debug.ps1 new file mode 100644 index 000000000..015dae9c9 --- /dev/null +++ b/bin/spc-debug.ps1 @@ -0,0 +1,12 @@ +$PHP_Exec = ".\runtime\php.exe" + +if (-not(Test-Path $PHP_Exec)) { + $PHP_Exec = Get-Command php.exe -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Definition + if (-not $PHP_Exec) { + Write-Host "Error: PHP not found, you need to install PHP on your system or use 'bin/setup-runtime'." -ForegroundColor Red + exit 1 + } +} + +& "$PHP_Exec" -d xdebug.mode=debug -d xdebug.client_host=127.0.0.1 -d xdebug.client_port=9003 -d xdebug.start_with_request=yes ("bin/spc") @args +exit $LASTEXITCODE From 46132ee1c88e1b34dc611c4138176b6aaf6f49d6 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 16:16:09 +0800 Subject: [PATCH 03/52] Fix doctor lock path on Windows --- src/StaticPHP/Doctor/Doctor.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/StaticPHP/Doctor/Doctor.php b/src/StaticPHP/Doctor/Doctor.php index 1239a30c8..05f3c4a1d 100644 --- a/src/StaticPHP/Doctor/Doctor.php +++ b/src/StaticPHP/Doctor/Doctor.php @@ -147,13 +147,17 @@ private static function getLockPath(): string { if (SystemTarget::getTargetOS() === 'Windows') { $trial_ls = [ - getenv('LOCALAPPDATA') ?: ((getenv('USERPROFILE') ?: 'C:\Users\Default') . '\AppData\Local') . '\.spc-doctor.lock', + getenv('LOCALAPPDATA') ? + (getenv('LOCALAPPDATA') . '\.spc-doctor.lock') : + (((getenv('USERPROFILE') ?: 'C:\Users\Default') . '\AppData\Local') . '\.spc-doctor.lock'), sys_get_temp_dir() . '\.spc-doctor.lock', WORKING_DIR . '\.spc-doctor.lock', ]; } else { $trial_ls = [ - getenv('XDG_CACHE_HOME') ?: ((getenv('HOME') ?: '/tmp') . '/.cache') . '/.spc-doctor.lock', + getenv('XDG_CACHE_HOME') ? + (getenv('XDG_CACHE_HOME') . '/.spc-doctor.lock') + : (((getenv('HOME') ?: '/tmp') . '/.cache') . '/.spc-doctor.lock'), sys_get_temp_dir() . '/.spc-doctor.lock', WORKING_DIR . '/.spc-doctor.lock', ]; From 1d2916fa8f1636090e793c79537217520f8ea4cc Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 16:16:29 +0800 Subject: [PATCH 04/52] Add brotli --- src/Package/Library/brotli.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Package/Library/brotli.php b/src/Package/Library/brotli.php index f22b9ef29..cab05112b 100644 --- a/src/Package/Library/brotli.php +++ b/src/Package/Library/brotli.php @@ -8,11 +8,19 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; use StaticPHP\Util\FileSystem; #[Library('brotli')] class brotli { + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $package): void + { + WindowsCMakeExecutor::create($package)->build(); + // FileSystem::copy("{$package->getLibDir()}\\onig.lib", "{$package->getLibDir()}\\onig_a.lib"); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void From 0c389d906954d575a02aa414576c1cb1d0b2d687 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 18:03:46 +0800 Subject: [PATCH 05/52] Add zlib --- config/pkg/lib/zlib.yml | 3 +++ src/Package/Library/zlib.php | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/config/pkg/lib/zlib.yml b/config/pkg/lib/zlib.yml index cf7f11ba0..b4e71364e 100644 --- a/config/pkg/lib/zlib.yml +++ b/config/pkg/lib/zlib.yml @@ -14,3 +14,6 @@ zlib: - zconf.h static-libs@unix: - libz.a + static-libs@windows: + - zlibstatic.lib + - zlib_a.lib diff --git a/src/Package/Library/zlib.php b/src/Package/Library/zlib.php index 8706dfe9b..f45b942c9 100644 --- a/src/Package/Library/zlib.php +++ b/src/Package/Library/zlib.php @@ -8,6 +8,8 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Util\FileSystem; #[Library('zlib')] class zlib @@ -21,4 +23,28 @@ public function build(LibraryPackage $lib): void // Patch pkg-config file $lib->patchPkgconfPrefix(['zlib.pc'], PKGCONF_PATCH_PREFIX); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib)->build(); + $detect_list = [ + 'zlibstatic.lib', + 'zs.lib', + 'libzs.lib', + ]; + foreach ($detect_list as $item) { + if (file_exists("{$lib->getLibDir()}\\{$item}")) { + FileSystem::copy("{$lib->getLibDir()}\\{$item}", "{$lib->getLibDir()}\\zlib_a.lib"); + FileSystem::copy("{$lib->getLibDir()}\\{$item}", "{$lib->getLibDir()}\\zlibstatic.lib"); + break; + } + } + FileSystem::removeFileIfExists("{$lib->getBinDir()}\\zlib.dll"); + FileSystem::removeFileIfExists("{$lib->getLibDir()}\\zlib.lib"); + FileSystem::removeFileIfExists("{$lib->getLibDir()}\\libz.dll"); + FileSystem::removeFileIfExists("{$lib->getLibDir()}\\libz.lib"); + FileSystem::removeFileIfExists("{$lib->getLibDir()}\\z.lib"); + FileSystem::removeFileIfExists("{$lib->getLibDir()}\\z.dll"); + } } From 464ddeb29d36712b6307b99dad56723b170f833e Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 18:03:58 +0800 Subject: [PATCH 06/52] Fix file copy operation to handle identical source and destination paths --- src/StaticPHP/Util/FileSystem.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/StaticPHP/Util/FileSystem.php b/src/StaticPHP/Util/FileSystem.php index 3015b4891..144f81eb3 100644 --- a/src/StaticPHP/Util/FileSystem.php +++ b/src/StaticPHP/Util/FileSystem.php @@ -142,6 +142,9 @@ public static function copy(string $from, string $to): bool logger()->debug("Copying file from {$from} to {$to}"); $dst_path = FileSystem::convertPath($to); $src_path = FileSystem::convertPath($from); + if ($src_path === $dst_path) { + return true; + } if (!copy($src_path, $dst_path)) { throw new FileSystemException('Cannot copy file from ' . $src_path . ' to ' . $dst_path); } From b21d5716e106419c1c772d49db968bfefbc2e6b8 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 18:04:18 +0800 Subject: [PATCH 07/52] Add onig --- config/pkg/lib/onig.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/pkg/lib/onig.yml b/config/pkg/lib/onig.yml index fa06524dc..c2ef658af 100644 --- a/config/pkg/lib/onig.yml +++ b/config/pkg/lib/onig.yml @@ -13,3 +13,6 @@ onig: - oniguruma.h static-libs@unix: - libonig.a + static-libs@windows: + - onig.lib + - onig_a.lib From 9f3e353699b1868f59fc4e7dea98ceb65ee73017 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 18:04:30 +0800 Subject: [PATCH 08/52] Add bzip2 --- config/pkg/lib/bzip2.yml | 3 +++ src/Package/Library/bzip2.php | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/config/pkg/lib/bzip2.yml b/config/pkg/lib/bzip2.yml index 1cd36bd7e..f9e1870d8 100644 --- a/config/pkg/lib/bzip2.yml +++ b/config/pkg/lib/bzip2.yml @@ -16,3 +16,6 @@ bzip2: - bzlib.h static-libs@unix: - libbz2.a + static-libs@windows: + - libbz2.lib + - libbz2_a.lib diff --git a/src/Package/Library/bzip2.php b/src/Package/Library/bzip2.php index 403773dab..90fcce7c6 100644 --- a/src/Package/Library/bzip2.php +++ b/src/Package/Library/bzip2.php @@ -20,6 +20,17 @@ public function patchBeforeBuild(LibraryPackage $lib): void FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS=-Wall', 'CFLAGS=-fPIC -Wall'); } + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $package): void + { + cmd()->cd($package->getSourceDir()) + ->exec('nmake /nologo /f Makefile.msc CFLAGS="-DWIN32 -MT -Ox -D_FILE_OFFSET_BITS=64 -nologo" clean') + ->exec('nmake /nologo /f Makefile.msc CFLAGS="-DWIN32 -MT -Ox -D_FILE_OFFSET_BITS=64 -nologo" lib'); + FileSystem::copy("{$package->getSourceDir()}\\libbz2.lib", "{$package->getLibDir()}\\libbz2.lib"); + FileSystem::copy("{$package->getSourceDir()}\\libbz2.lib", "{$package->getLibDir()}\\libbz2_a.lib"); + FileSystem::copy("{$package->getSourceDir()}\\bzlib.h", "{$package->getIncludeDir()}\\bzlib.h"); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib, PackageBuilder $builder): void From 03cd7e141ceb6ee0674b3a8c8e52066c028b0472 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 18:09:29 +0800 Subject: [PATCH 09/52] Add brotli libs --- config/pkg/lib/brotli.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/pkg/lib/brotli.yml b/config/pkg/lib/brotli.yml index 524f9ddc8..c88b93b5a 100644 --- a/config/pkg/lib/brotli.yml +++ b/config/pkg/lib/brotli.yml @@ -15,3 +15,7 @@ brotli: - libbrotlicommon - libbrotlidec - libbrotlienc + static-libs@windows: + - brotlicommon.lib + - brotlidec.lib + - brotlienc.lib From d7d41f4d897312aba0382757fd6a64a7e2f9d41a Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 21:47:27 +0800 Subject: [PATCH 10/52] Add openssl --- config/pkg/lib/openssl.yml | 3 ++ src/Package/Library/openssl.php | 56 +++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/config/pkg/lib/openssl.yml b/config/pkg/lib/openssl.yml index 22d065088..161cdcebc 100644 --- a/config/pkg/lib/openssl.yml +++ b/config/pkg/lib/openssl.yml @@ -21,3 +21,6 @@ openssl: static-libs@unix: - libssl.a - libcrypto.a + static-libs@windows: + - libssl.lib + - libcrypto.lib diff --git a/src/Package/Library/openssl.php b/src/Package/Library/openssl.php index 541b6145f..a01d01b0b 100644 --- a/src/Package/Library/openssl.php +++ b/src/Package/Library/openssl.php @@ -6,13 +6,69 @@ use StaticPHP\Attribute\Package\BuildFor; use StaticPHP\Attribute\Package\Library; +use StaticPHP\Attribute\Package\Validate; +use StaticPHP\DI\ApplicationContext; +use StaticPHP\Exception\EnvironmentException; use StaticPHP\Package\LibraryPackage; +use StaticPHP\Runtime\SystemTarget; use StaticPHP\Util\FileSystem; use StaticPHP\Util\System\LinuxUtil; +use StaticPHP\Util\System\WindowsUtil; #[Library('openssl')] class openssl { + #[Validate] + public function validate(): void + { + if (SystemTarget::getTargetOS() === 'Windows') { + global $argv; + $perl_path_native = PKG_ROOT_PATH . '\strawberry-perl-' . arch2gnu(php_uname('m')) . '-win\perl\bin\perl.exe'; + $perl = file_exists($perl_path_native) ? ($perl_path_native) : WindowsUtil::findCommand('perl.exe'); + if ($perl === null) { + throw new EnvironmentException( + 'You need to install perl first!', + "Please run \"{$argv[0]} doctor\" to fix the environment.", + ); + } + ApplicationContext::set('perl', $perl); + } + } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + $perl = ApplicationContext::get('perl'); + $cmd = cmd()->cd($lib->getSourceDir()) + ->exec( + "{$perl} Configure zlib VC-WIN64A " . + 'no-shared ' . + '--prefix=' . quote($lib->getBuildRootPath()) . ' ' . + '--with-zlib-lib=' . quote($lib->getLibDir()) . ' ' . + '--with-zlib-include=' . quote($lib->getIncludeDir()) . ' ' . + '--release ' . + 'no-legacy ' + ); + + // patch zlib + FileSystem::replaceFileStr("{$lib->getSourceDir()}\\Makefile", 'ZLIB1', 'zlibstatic.lib'); + // patch debug: https://stackoverflow.com/questions/18486243/how-do-i-build-openssl-statically-linked-against-windows-runtime + FileSystem::replaceFileStr("{$lib->getSourceDir()}\\Makefile", '/debug', '/incremental:no /opt:icf /dynamicbase /nxcompat /ltcg /nodefaultlib:msvcrt'); + + // build + $cmd->exec("nmake install_dev CNF_LDFLAGS=\"/NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:msvcrt /NODEFAULTLIB:msvcrtd /DEFAULTLIB:libcmt /LIBPATH:{$lib->getLibDir()} zlibstatic.lib\""); + + // copy necessary c files + FileSystem::copy("{$lib->getSourceDir()}\\ms\\applink.c", "{$lib->getIncludeDir()}\\openssl\\applink.c"); + + // patch cmake outputs + FileSystem::replaceFileRegex( + "{$lib->getLibDir()}\\cmake\\OpenSSL\\OpenSSLConfig.cmake", + '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', + 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}" ws2_32.lib gdi32.lib advapi32.lib crypt32.lib user32.lib)' + ); + } + #[BuildFor('Darwin')] public function buildForDarwin(LibraryPackage $pkg): void { From 94c579a4535144f70c66cabb433f9c3f0ad8b9eb Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Fri, 20 Mar 2026 21:48:46 +0800 Subject: [PATCH 11/52] Add libssh2 --- config/pkg/lib/libssh2.yml | 2 ++ src/Package/Library/libssh2.php | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/config/pkg/lib/libssh2.yml b/config/pkg/lib/libssh2.yml index 8e1d82754..2916e3a9c 100644 --- a/config/pkg/lib/libssh2.yml +++ b/config/pkg/lib/libssh2.yml @@ -20,3 +20,5 @@ libssh2: - libssh2 static-libs@unix: - libssh2.a + static-libs@windows: + - libssh2.lib diff --git a/src/Package/Library/libssh2.php b/src/Package/Library/libssh2.php index f71d508ac..b41434e09 100644 --- a/src/Package/Library/libssh2.php +++ b/src/Package/Library/libssh2.php @@ -8,10 +8,22 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; #[Library('libssh2')] class libssh2 { + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DENABLE_ZLIB_COMPRESSION=ON', + '-DBUILD_TESTING=OFF' + ) + ->build(); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void From 19bfb6bc83ac19291b27f79eb7fc1ba658878879 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:29:35 +0800 Subject: [PATCH 12/52] Add zstd --- config/pkg/lib/zstd.yml | 2 ++ src/Package/Library/zstd.php | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/config/pkg/lib/zstd.yml b/config/pkg/lib/zstd.yml index 3d76e270c..875380d1f 100644 --- a/config/pkg/lib/zstd.yml +++ b/config/pkg/lib/zstd.yml @@ -17,3 +17,5 @@ zstd: - libzstd static-libs@unix: - libzstd.a + static-libs@windows: + - zstd_static.lib diff --git a/src/Package/Library/zstd.php b/src/Package/Library/zstd.php index ab538358e..8cbf7aa62 100644 --- a/src/Package/Library/zstd.php +++ b/src/Package/Library/zstd.php @@ -8,10 +8,24 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; #[Library('zstd')] class zstd { + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $package): void + { + WindowsCMakeExecutor::create($package) + ->setRootDir("{$package->getSourceDir()}/build/cmake") + ->setBuildDir("{$package->getSourceDir()}/build/cmake/build") + ->addConfigureArgs( + '-DZSTD_BUILD_STATIC=ON', + '-DZSTD_BUILD_SHARED=OFF', + ) + ->build(); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void From d1ec473f212a7fb11f8ffe7bf3d78f5ef7abe9e1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:30:15 +0800 Subject: [PATCH 13/52] Allow set current working dir --- src/Package/Library/zstd.php | 2 +- .../Runtime/Executor/WindowsCMakeExecutor.php | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Package/Library/zstd.php b/src/Package/Library/zstd.php index 8cbf7aa62..f12bf3e02 100644 --- a/src/Package/Library/zstd.php +++ b/src/Package/Library/zstd.php @@ -17,7 +17,7 @@ class zstd public function buildWin(LibraryPackage $package): void { WindowsCMakeExecutor::create($package) - ->setRootDir("{$package->getSourceDir()}/build/cmake") + ->setWorkingDir("{$package->getSourceDir()}/build/cmake") ->setBuildDir("{$package->getSourceDir()}/build/cmake/build") ->addConfigureArgs( '-DZSTD_BUILD_STATIC=ON', diff --git a/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php b/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php index 9e0978196..1f057f126 100644 --- a/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php +++ b/src/StaticPHP/Runtime/Executor/WindowsCMakeExecutor.php @@ -176,6 +176,12 @@ public function getConfigureArgsString(): string return implode(' ', array_merge($this->configure_args, $this->getDefaultCMakeArgs())); } + public function setWorkingDir(string $dir): static + { + $this->cmd = $this->cmd->cd($dir); + return $this; + } + /** * Returns the default CMake args. */ @@ -207,12 +213,12 @@ private function makeCmakeToolchainFile(): string private function initBuildDir(): void { if ($this->build_dir === null) { - $this->build_dir = "{$this->package->getSourceDir()}\\build"; + $this->build_dir = "{$this->package->getSourceRoot()}\\build"; } } private function initCmd(): void { - $this->cmd = cmd()->cd($this->package->getSourceDir()); + $this->cmd = cmd()->cd($this->package->getSourceRoot()); } } From 1213cb578e88c892fdb0c699a6593b4f3b8a8dbb Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:30:30 +0800 Subject: [PATCH 14/52] Refactor WindowsUtil to cache Visual Studio search results and add CMake find modules --- src/StaticPHP/Util/System/WindowsUtil.php | 54 +++++++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/StaticPHP/Util/System/WindowsUtil.php b/src/StaticPHP/Util/System/WindowsUtil.php index a6df41564..9ed7a7b5f 100644 --- a/src/StaticPHP/Util/System/WindowsUtil.php +++ b/src/StaticPHP/Util/System/WindowsUtil.php @@ -8,8 +8,10 @@ class WindowsUtil { + private static array|false|null $vsCache = null; + /** - * Find windows program using executable name. + * Find Windows program using executable name. * * @param string $name command name (xxx.exe) * @param array $paths search path (default use env path) @@ -39,6 +41,10 @@ public static function findCommand(string $name, array $paths = []): ?string */ public static function findVisualStudio(): array|false { + if (self::$vsCache !== null) { + return self::$vsCache; + } + // call vswhere (need VS and C++ tools installed), output is json $vswhere_exec = PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'vswhere.exe'; $args = [ @@ -49,13 +55,13 @@ public static function findVisualStudio(): array|false $cmd = escapeshellarg($vswhere_exec) . ' ' . implode(' ', $args); $result = f_exec($cmd, $out, $code); if ($code !== 0 || !$result) { - return false; + return self::$vsCache = false; } $json = json_decode(implode("\n", $out), true); if (!is_array($json) || count($json) === 0) { - return false; + return self::$vsCache = false; } - return [ + return self::$vsCache = [ 'version' => $json[0]['installationVersion'], 'major_version' => explode('.', $json[0]['installationVersion'])[0], 'dir' => $json[0]['installationPath'], @@ -89,6 +95,7 @@ public static function makeCmakeToolchainFile(?string $cflags = null, ?string $l $ldflags = '/nodefaultlib:msvcrt /nodefaultlib:msvcrtd /defaultlib:libcmt'; } $buildroot = str_replace('\\', '\\\\', BUILD_ROOT_PATH); + $source = str_replace('\\', '/', SOURCE_PATH); $toolchain = << Date: Sat, 21 Mar 2026 00:31:02 +0800 Subject: [PATCH 15/52] Add ngtcp2, remove suggested libs --- config/pkg/lib/ngtcp2.yml | 5 ++--- src/Package/Library/ngtcp2.php | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/config/pkg/lib/ngtcp2.yml b/config/pkg/lib/ngtcp2.yml index c864739a7..8984ca729 100644 --- a/config/pkg/lib/ngtcp2.yml +++ b/config/pkg/lib/ngtcp2.yml @@ -11,9 +11,6 @@ ngtcp2: license: MIT depends: - openssl - suggests: - - nghttp3 - - brotli headers: - ngtcp2 pkg-configs: @@ -22,3 +19,5 @@ ngtcp2: static-libs@unix: - libngtcp2.a - libngtcp2_crypto_ossl.a + static-libs@windows: + - ngtcp2.lib diff --git a/src/Package/Library/ngtcp2.php b/src/Package/Library/ngtcp2.php index 15821225b..c88b643bf 100644 --- a/src/Package/Library/ngtcp2.php +++ b/src/Package/Library/ngtcp2.php @@ -8,10 +8,27 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; #[Library('ngtcp2')] class ngtcp2 { + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DENABLE_SHARED_LIB=OFF', + '-DENABLE_STATIC_LIB=ON', + '-DBUILD_STATIC_LIBS=ON', + '-DBUILD_SHARED_LIBS=OFF', + '-DENABLE_STATIC_CRT=ON', + '-DENABLE_LIB_ONLY=ON', + '-DENABLE_OPENSSL=ON', + ) + ->build(); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void @@ -26,18 +43,6 @@ public function build(LibraryPackage $lib): void ]), '--with-openssl=no' ) - ->optionalPackage('nghttp3', ...ac_with_args('libnghttp3', true)) - ->optionalPackage( - 'brotli', - fn (LibraryPackage $brotli) => implode(' ', [ - '--with-brotlidec=yes', - "LIBBROTLIDEC_CFLAGS=\"-I{$brotli->getIncludeDir()}\"", - "LIBBROTLIDEC_LIBS=\"{$brotli->getStaticLibFiles()}\"", - '--with-libbrotlienc=yes', - "LIBBROTLIENC_CFLAGS=\"-I{$brotli->getIncludeDir()}\"", - "LIBBROTLIENC_LIBS=\"{$brotli->getStaticLibFiles()}\"", - ]) - ) ->appendEnv(['PKG_CONFIG' => '$PKG_CONFIG --static']) ->configure('--enable-lib-only') ->make(); From 893f6404691ea0dafd22a2eeaab86eae5106515e Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:31:16 +0800 Subject: [PATCH 16/52] Add nghttp3 --- config/pkg/lib/nghttp3.yml | 2 ++ src/Package/Library/nghttp3.php | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/config/pkg/lib/nghttp3.yml b/config/pkg/lib/nghttp3.yml index f9adc05b5..272172b99 100644 --- a/config/pkg/lib/nghttp3.yml +++ b/config/pkg/lib/nghttp3.yml @@ -17,3 +17,5 @@ nghttp3: - libnghttp3 static-libs@unix: - libnghttp3.a + static-libs@windows: + - nghttp3.lib diff --git a/src/Package/Library/nghttp3.php b/src/Package/Library/nghttp3.php index 1f686b7b5..4659c5711 100644 --- a/src/Package/Library/nghttp3.php +++ b/src/Package/Library/nghttp3.php @@ -8,10 +8,26 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; #[Library('nghttp3')] class nghttp3 { + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DENABLE_SHARED_LIB=OFF', + '-DENABLE_STATIC_LIB=ON', + '-DBUILD_STATIC_LIBS=ON', + '-DBUILD_SHARED_LIBS=OFF', + '-DENABLE_STATIC_CRT=ON', + '-DENABLE_LIB_ONLY=ON', + ) + ->build(); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void From 92861669c25add6d27d879c6b245810ff2829415 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:31:30 +0800 Subject: [PATCH 17/52] Add nghttp2 --- config/pkg/lib/nghttp2.yml | 2 ++ src/Package/Library/nghttp2.php | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/config/pkg/lib/nghttp2.yml b/config/pkg/lib/nghttp2.yml index 166c33ac5..11521d5a3 100644 --- a/config/pkg/lib/nghttp2.yml +++ b/config/pkg/lib/nghttp2.yml @@ -22,3 +22,5 @@ nghttp2: - libnghttp2 static-libs@unix: - libnghttp2.a + static-libs@windows: + - nghttp2.lib diff --git a/src/Package/Library/nghttp2.php b/src/Package/Library/nghttp2.php index 3a85ada4a..f09659470 100644 --- a/src/Package/Library/nghttp2.php +++ b/src/Package/Library/nghttp2.php @@ -8,10 +8,26 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; #[Library('nghttp2')] class nghttp2 { + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DENABLE_SHARED_LIB=OFF', + '-DENABLE_STATIC_LIB=ON', + '-DENABLE_STATIC_CRT=ON', + '-DENABLE_LIB_ONLY=ON', + '-DENABLE_DOC=OFF', + '-DBUILD_TESTING=OFF', + ) + ->build(); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void From 7df861696d28028fd9d2d4f00328e4e109e6d114 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:31:45 +0800 Subject: [PATCH 18/52] Add libxml2 --- config/pkg/lib/libxml2.yml | 6 ++++++ src/Package/Library/libxml2.php | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/config/pkg/lib/libxml2.yml b/config/pkg/lib/libxml2.yml index 7e86b5af5..5ffdc8b27 100644 --- a/config/pkg/lib/libxml2.yml +++ b/config/pkg/lib/libxml2.yml @@ -12,7 +12,13 @@ libxml2: - libiconv - zlib - xz + depends@windows: + - zlib + - libiconv-win headers: - libxml2 pkg-configs: - libxml-2.0 + static-libs@windows: + - libxml2s.lib + - libxml2_a.lib diff --git a/src/Package/Library/libxml2.php b/src/Package/Library/libxml2.php index 3f8b3e71f..108b9962f 100644 --- a/src/Package/Library/libxml2.php +++ b/src/Package/Library/libxml2.php @@ -7,12 +7,33 @@ use StaticPHP\Attribute\Package\BuildFor; use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; +use StaticPHP\Package\PackageInstaller; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; use StaticPHP\Util\FileSystem; #[Library('libxml2')] class libxml2 { + #[BuildFor('Windows')] + public function buildForWindows(LibraryPackage $lib, PackageInstaller $installer): void + { + $iconv_win = $installer->getLibraryPackage('libiconv-win'); + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DLIBXML2_WITH_ICONV=ON', + "-DIconv_LIBRARY={$iconv_win->getLibDir()}", + "-DIconv_INCLUDE_DIR={$iconv_win->getIncludeDir()}", + '-DLIBXML2_WITH_ZLIB=ON', + '-DLIBXML2_WITH_PYTHON=OFF', + '-DLIBXML2_WITH_LZMA=OFF', + '-DLIBXML2_WITH_PROGRAMS=OFF', + '-DLIBXML2_WITH_TESTS=OFF', + ) + ->build(); + FileSystem::copy("{$lib->getLibDir()}\\libxml2s.lib", "{$lib->getLibDir()}\\libxml2_a.lib"); + } + #[BuildFor('Linux')] public function buildForLinux(LibraryPackage $lib): void { From f6e00c67ccf3d7f1fbdab4431665c07efdbeaca7 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:32:02 +0800 Subject: [PATCH 19/52] Refactor LibraryPackage to skip pkg-config and static-bin checks on Windows --- src/StaticPHP/Package/LibraryPackage.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/StaticPHP/Package/LibraryPackage.php b/src/StaticPHP/Package/LibraryPackage.php index aa24f057c..769612b9f 100644 --- a/src/StaticPHP/Package/LibraryPackage.php +++ b/src/StaticPHP/Package/LibraryPackage.php @@ -44,18 +44,20 @@ public function isInstalled(): bool return false; } } - foreach (PackageConfig::get($this->getName(), 'pkg-configs', []) as $pc) { - if (!str_ends_with($pc, '.pc')) { - $pc .= '.pc'; - } - if (!file_exists("{$this->getLibDir()}/pkgconfig/{$pc}")) { - return false; + if (SystemTarget::getTargetOS() !== 'Windows') { + foreach (PackageConfig::get($this->getName(), 'pkg-configs', []) as $pc) { + if (!str_ends_with($pc, '.pc')) { + $pc .= '.pc'; + } + if (!file_exists("{$this->getLibDir()}/pkgconfig/{$pc}")) { + return false; + } } - } - foreach (PackageConfig::get($this->getName(), 'static-bins', []) as $bin) { - $path = FileSystem::isRelativePath($bin) ? "{$this->getBinDir()}/{$bin}" : $bin; - if (!file_exists($path)) { - return false; + foreach (PackageConfig::get($this->getName(), 'static-bins', []) as $bin) { + $path = FileSystem::isRelativePath($bin) ? "{$this->getBinDir()}/{$bin}" : $bin; + if (!file_exists($path)) { + return false; + } } } return true; From deb979416f362a49c989e8397c6c946eed8e52bf Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:33:04 +0800 Subject: [PATCH 20/52] Add libiconv-win --- config/pkg/lib/libiconv-win.yml | 13 +++++++++ src/Package/Library/libiconv_win.php | 43 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 config/pkg/lib/libiconv-win.yml create mode 100644 src/Package/Library/libiconv_win.php diff --git a/config/pkg/lib/libiconv-win.yml b/config/pkg/lib/libiconv-win.yml new file mode 100644 index 000000000..103acf2e9 --- /dev/null +++ b/config/pkg/lib/libiconv-win.yml @@ -0,0 +1,13 @@ +libiconv-win: + type: library + artifact: + source: + type: git + rev: master + url: 'https://github.com/static-php/libiconv-win.git' + metadata: + license-files: [source/COPYING] + license: GPL-3.0-or-later + static-libs@windows: + - libiconv.lib + - libiconv_a.lib diff --git a/src/Package/Library/libiconv_win.php b/src/Package/Library/libiconv_win.php new file mode 100644 index 000000000..6cd235e12 --- /dev/null +++ b/src/Package/Library/libiconv_win.php @@ -0,0 +1,43 @@ + '\MSVC17', + '16' => '\MSVC16', + default => throw new EnvironmentException("Current VS version {$ver} is not supported yet!"), + }; + ApplicationContext::set('vs_ver_dir', $vs_ver_dir); + } + + #[BuildFor('Windows')] + public function build(LibraryPackage $lib): void + { + $vs_ver_dir = ApplicationContext::get('vs_ver_dir'); + cmd()->cd("{$lib->getSourceDir()}{$vs_ver_dir}") + ->exec('msbuild libiconv.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'); + FileSystem::createDir($lib->getLibDir()); + FileSystem::createDir($lib->getIncludeDir()); + FileSystem::copy("{$lib->getSourceDir()}{$vs_ver_dir}\\x64\\lib\\libiconv.lib", "{$lib->getLibDir()}\\libiconv.lib"); + FileSystem::copy("{$lib->getSourceDir()}{$vs_ver_dir}\\x64\\lib\\libiconv_a.lib", "{$lib->getLibDir()}\\libiconv_a.lib"); + FileSystem::copy("{$lib->getSourceDir()}\\source\\include\\iconv.h", "{$lib->getIncludeDir()}\\iconv.h"); + } +} From 327bb8bc0f9c30a25c34dd4077349e9b48c08be6 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:33:27 +0800 Subject: [PATCH 21/52] Add curl --- config/pkg/target/curl.yml | 9 +++++++++ src/Package/Target/curl.php | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/config/pkg/target/curl.yml b/config/pkg/target/curl.yml index 4daba8c14..78064510c 100644 --- a/config/pkg/target/curl.yml +++ b/config/pkg/target/curl.yml @@ -12,6 +12,10 @@ curl: depends@unix: - openssl - zlib + depends@windows: + - zlib + - libssh2 + - nghttp2 suggests@unix: - libssh2 - brotli @@ -23,6 +27,9 @@ curl: - ldap - idn2 - krb5 + suggests@windows: + - brotli + - zstd frameworks: - CoreFoundation - CoreServices @@ -33,3 +40,5 @@ curl: - curl static-libs@unix: - libcurl.a + static-libs@windows: + - libcurl_a.lib diff --git a/src/Package/Target/curl.php b/src/Package/Target/curl.php index dbfa8f7a1..43a2904b7 100644 --- a/src/Package/Target/curl.php +++ b/src/Package/Target/curl.php @@ -10,6 +10,7 @@ use StaticPHP\Attribute\PatchDescription; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; use StaticPHP\Runtime\SystemTarget; use StaticPHP\Util\FileSystem; @@ -20,7 +21,9 @@ class curl #[PatchDescription('Remove CMAKE_C_IMPLICIT_LINK_LIBRARIES and fix macOS framework detection')] public function patchBeforeBuild(LibraryPackage $lib): bool { - shell()->cd($lib->getSourceDir())->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ./CMakeLists.txt'); + if (SystemTarget::getTargetOS() !== 'Windows') { + shell()->cd($lib->getSourceDir())->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ./CMakeLists.txt'); + } if (SystemTarget::getTargetOS() === 'Darwin') { FileSystem::replaceFileRegex("{$lib->getSourceDir()}/CMakeLists.txt", '/NOT COREFOUNDATION_FRAMEWORK/m', 'FALSE'); FileSystem::replaceFileRegex("{$lib->getSourceDir()}/CMakeLists.txt", '/NOT SYSTEMCONFIGURATION_FRAMEWORK/m', 'FALSE'); @@ -29,6 +32,34 @@ public function patchBeforeBuild(LibraryPackage $lib): bool return true; } + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->optionalPackage('zstd', ...cmake_boolean_args('CURL_ZSTD')) + ->optionalPackage('brotli', ...cmake_boolean_args('CURL_BROTLI')) + ->addConfigureArgs( + '-DBUILD_CURL_EXE=OFF', + '-DZSTD_LIBRARY=zstd_static.lib', + '-DBUILD_TESTING=OFF', + '-DBUILD_EXAMPLES=OFF', + '-DUSE_LIBIDN2=OFF', + '-DCURL_USE_LIBPSL=OFF', + '-DUSE_WINDOWS_SSPI=ON', + '-DCURL_USE_SCHANNEL=ON', + '-DCURL_USE_OPENSSL=OFF', + '-DCURL_ENABLE_SSL=ON', + '-DUSE_NGHTTP2=ON', + '-DSHARE_LIB_OBJECT=OFF', + '-DCURL_USE_LIBSSH2=ON', + '-DENABLE_IPV6=ON', + ) + ->build(); + // move libcurl.lib to libcurl_a.lib + rename("{$lib->getLibDir()}\\libcurl.lib", "{$lib->getLibDir()}\\libcurl_a.lib"); + FileSystem::replaceFileStr("{$lib->getIncludeDir()}\\curl\\curl.h", '#ifdef CURL_STATICLIB', '#if 1'); + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void From bd73b4a6dc6daee7cde1a8b23a00fca29d55adb0 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 00:34:31 +0800 Subject: [PATCH 22/52] phpstan --- src/Package/Library/libiconv_win.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Package/Library/libiconv_win.php b/src/Package/Library/libiconv_win.php index 6cd235e12..b6b0531df 100644 --- a/src/Package/Library/libiconv_win.php +++ b/src/Package/Library/libiconv_win.php @@ -23,7 +23,7 @@ public function validate(): void $vs_ver_dir = match ($ver['major_version']) { '17' => '\MSVC17', '16' => '\MSVC16', - default => throw new EnvironmentException("Current VS version {$ver} is not supported yet!"), + default => throw new EnvironmentException("Current VS version {$ver['major_version']} is not supported yet!"), }; ApplicationContext::set('vs_ver_dir', $vs_ver_dir); } From 230be2ebe818db2f70853bb668e9b7592b36a07f Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 11:12:13 +0800 Subject: [PATCH 23/52] Add libpng --- config/pkg/lib/libpng.yml | 3 +++ src/Package/Library/libpng.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/config/pkg/lib/libpng.yml b/config/pkg/lib/libpng.yml index e8831d60c..083cf430a 100644 --- a/config/pkg/lib/libpng.yml +++ b/config/pkg/lib/libpng.yml @@ -14,3 +14,6 @@ libpng: - zlib static-libs@unix: - libpng16.a + static-libs@windows: + - libpng16_static.lib + - libpng_a.lib diff --git a/src/Package/Library/libpng.php b/src/Package/Library/libpng.php index 1d02fdd69..6a1690105 100644 --- a/src/Package/Library/libpng.php +++ b/src/Package/Library/libpng.php @@ -8,6 +8,8 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Util\FileSystem; #[Library('libpng')] class libpng @@ -44,4 +46,21 @@ public function buildUnix(LibraryPackage $lib): void $lib->patchPkgconfPrefix(['libpng16.pc']); $lib->patchLaDependencyPrefix(); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DSKIP_INSTALL_PROGRAM=ON', + '-DSKIP_INSTALL_FILES=ON', + '-DPNG_STATIC=ON', + '-DPNG_SHARED=OFF', + '-DPNG_TESTS=OFF', + ) + ->build(); + + // libpng16_static.lib to libpng_a.lib + FileSystem::copy("{$lib->getLibDir()}\\libpng16_static.lib", "{$lib->getLibDir()}\\libpng_a.lib"); + } } From 5ff973e446920cdfb5f28244a841b23527a27724 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 11:12:24 +0800 Subject: [PATCH 24/52] Add freetype --- config/pkg/lib/freetype.yml | 1 + src/Package/Library/freetype.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/config/pkg/lib/freetype.yml b/config/pkg/lib/freetype.yml index c101a174b..df7dc22a8 100644 --- a/config/pkg/lib/freetype.yml +++ b/config/pkg/lib/freetype.yml @@ -11,6 +11,7 @@ freetype: depends: - zlib suggests: + - libpng - bzip2 - brotli headers@unix: diff --git a/src/Package/Library/freetype.php b/src/Package/Library/freetype.php index 6cb05a90a..8a83eb5e3 100644 --- a/src/Package/Library/freetype.php +++ b/src/Package/Library/freetype.php @@ -8,6 +8,7 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; use StaticPHP\Util\FileSystem; #[Library('freetype')] @@ -33,4 +34,18 @@ public function buildUnix(LibraryPackage $lib): void $lib->patchPkgconfPrefix(['freetype2.pc']); FileSystem::replaceFileStr("{$lib->getBuildRootPath()}/lib/pkgconfig/freetype2.pc", ' -L/lib ', " -L{$lib->getBuildRootPath()}/lib "); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->optionalPackage('libpng', ...cmake_boolean_args('FT_DISABLE_PNG', true)) + ->optionalPackage('bzip2', ...cmake_boolean_args('FT_DISABLE_BZIP2', true)) + ->optionalPackage('brotli', ...cmake_boolean_args('FT_DISABLE_BROTLI', true)) + ->addConfigureArgs('-DFT_DISABLE_HARFBUZZ=ON') + ->build(); + + // freetype.lib to libfreetype_a.lib + FileSystem::copy("{$lib->getLibDir()}\\freetype.lib", "{$lib->getLibDir()}\\libfreetype_a.lib"); + } } From 520767638f779dd7cfffb38666c6f6dfa9615b67 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 11:20:05 +0800 Subject: [PATCH 25/52] Add gmssl --- src/Package/Library/gmssl.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/Package/Library/gmssl.php b/src/Package/Library/gmssl.php index 21b4ea668..7785e55a4 100644 --- a/src/Package/Library/gmssl.php +++ b/src/Package/Library/gmssl.php @@ -8,6 +8,8 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Util\FileSystem; #[Library('gmssl')] class gmssl @@ -18,4 +20,35 @@ public function build(LibraryPackage $lib): void { UnixCMakeExecutor::create($lib)->build(); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + $buildDir = "{$lib->getSourceDir()}\\builddir"; + + // GmSSL requires NMake Makefiles generator on Windows + WindowsCMakeExecutor::create($lib) + ->setBuildDir($buildDir) + ->setCustomDefaultArgs( + '-G "NMake Makefiles"', + '-DWIN32=ON', + '-DBUILD_SHARED_LIBS=OFF', + '-DCMAKE_BUILD_TYPE=Release', + '-DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG"', + '-DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG"', + '-DCMAKE_INSTALL_PREFIX=' . escapeshellarg($lib->getBuildRootPath()), + '-B ' . escapeshellarg($buildDir), + ) + ->toStep(1) + ->build(); + + // fix cmake_install.cmake install prefix (GmSSL overrides it internally) + $installCmake = "{$buildDir}\\cmake_install.cmake"; + FileSystem::writeFile( + $installCmake, + 'set(CMAKE_INSTALL_PREFIX "' . str_replace('\\', '/', $lib->getBuildRootPath()) . '")' . PHP_EOL . FileSystem::readFile($installCmake) + ); + + cmd()->cd($buildDir)->exec('nmake install XCFLAGS=/MT'); + } } From bf4d227a5544fe5e9a6b6eecb0217d22d946c5b8 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 12:42:47 +0800 Subject: [PATCH 26/52] Add error handling for missing vswhere.exe in WindowsUtil --- src/StaticPHP/Util/System/WindowsUtil.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/StaticPHP/Util/System/WindowsUtil.php b/src/StaticPHP/Util/System/WindowsUtil.php index 9ed7a7b5f..b6d943be4 100644 --- a/src/StaticPHP/Util/System/WindowsUtil.php +++ b/src/StaticPHP/Util/System/WindowsUtil.php @@ -4,6 +4,7 @@ namespace StaticPHP\Util\System; +use StaticPHP\Exception\EnvironmentException; use StaticPHP\Util\FileSystem; class WindowsUtil @@ -47,6 +48,10 @@ public static function findVisualStudio(): array|false // call vswhere (need VS and C++ tools installed), output is json $vswhere_exec = PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'vswhere.exe'; + // detect vswhere exists, if not throw error + if (!file_exists($vswhere_exec)) { + throw new EnvironmentException('vswhere.exe not found, please run `doctor` command first'); + } $args = [ '-latest', '-format', 'json', From 75dd01aa918c894e8987d8c8e1fda6fc27c73807 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 12:43:39 +0800 Subject: [PATCH 27/52] Enhance package download logic to handle binary-only packages and improve error messaging for installation failures --- src/StaticPHP/Package/PackageInstaller.php | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/StaticPHP/Package/PackageInstaller.php b/src/StaticPHP/Package/PackageInstaller.php index 417c4e1b6..f5c03a7de 100644 --- a/src/StaticPHP/Package/PackageInstaller.php +++ b/src/StaticPHP/Package/PackageInstaller.php @@ -168,10 +168,23 @@ public function run(bool $disable_delay_msg = false): void // check download if ($this->download) { $downloaderOptions = DownloaderOptions::extractFromConsoleOptions($this->options, 'dl'); - $downloader = new ArtifactDownloader( - [...$downloaderOptions, 'source-only' => implode(',', array_map(fn ($x) => $x->getName(), $this->build_packages))], - $this->interactive + // Collect packages that have no build stage for current OS but do have a platform binary. + // These must always download binary (not source), regardless of global prefer-source setting. + $binary_only_packages = array_filter( + $this->packages, + fn ($p) => $p instanceof LibraryPackage + && !$this->isBuildPackage($p) + && !$p->hasStage('build') + && ($p->getArtifact()?->hasPlatformBinary() ?? false) ); + $dl_opts = [ + ...$downloaderOptions, + 'source-only' => implode(',', array_map(fn ($x) => $x->getName(), $this->build_packages)), + ]; + if ($binary_only_packages !== []) { + $dl_opts['binary-only'] = implode(',', array_map(fn ($x) => $x->getName(), $binary_only_packages)); + } + $downloader = new ArtifactDownloader($dl_opts, $this->interactive); $downloader->addArtifacts($this->getArtifacts())->download(); } else { logger()->notice('Skipping download (--no-download option enabled)'); @@ -716,10 +729,13 @@ private function validatePackagesBeforeBuild(): void } $is_to_build = $this->isBuildPackage($package); $has_build_stage = $package instanceof LibraryPackage && $package->hasStage('build'); - $should_use_binary = $package instanceof LibraryPackage && ($package->getArtifact()?->shouldUseBinary() ?? false); + // Use hasPlatformBinary() here (not shouldUseBinary()) because this runs before download, + // so the binary is not yet on disk. We only need to know if a binary is declared for + // the current platform in the artifact config. + $has_platform_binary = $package instanceof LibraryPackage && ($package->getArtifact()?->hasPlatformBinary() ?? false); // Check if package can neither be built nor installed - if (!$is_to_build && !$should_use_binary && !$has_build_stage) { + if (!$is_to_build && !$has_platform_binary && !$has_build_stage) { throw new WrongUsageException("Package '{$package->getName()}' cannot be installed: no build stage defined and no binary artifact available for current OS: " . SystemTarget::getCurrentPlatformString()); } } From 43d8c9d9d62eb22a290f7226a05fdd3ba4ef26a7 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 12:44:17 +0800 Subject: [PATCH 28/52] Add icu (replace old icu-static-win) --- config/pkg/lib/icu.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/config/pkg/lib/icu.yml b/config/pkg/lib/icu.yml index 43328228d..e42dcb6c3 100644 --- a/config/pkg/lib/icu.yml +++ b/config/pkg/lib/icu.yml @@ -6,11 +6,20 @@ icu: repo: unicode-org/icu match: icu4c.+-src\.tgz prefer-stable: true + binary: + windows-x86_64: { type: url, url: 'https://dl.static-php.dev/static-php-cli/deps/icu-static-windows-x64/icu-static-windows-x64.zip', extract: hosted } metadata: - license-files: [LICENSE] + license-files: ['@/icu.txt'] license: ICU + headers@windows: + - unicode lang: cpp pkg-configs: - icu-uc - icu-i18n - icu-io + static-libs@windows: + - icudt.lib + - icuin.lib + - icuio.lib + - icuuc.lib From 801d41efeb1d30d3207b0e429fd9f8e388f402ac Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 17:53:49 +0800 Subject: [PATCH 29/52] Add libwebp --- config/pkg/lib/libwebp.yml | 5 +++++ src/Package/Library/libwebp.php | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/config/pkg/lib/libwebp.yml b/config/pkg/lib/libwebp.yml index 62ddddc13..24873b127 100644 --- a/config/pkg/lib/libwebp.yml +++ b/config/pkg/lib/libwebp.yml @@ -14,3 +14,8 @@ libwebp: - libwebpdemux - libwebpmux - libsharpyuv + static-libs@windows: + - libwebp.lib + - libwebpdecoder.lib + - libwebpdemux.lib + - libsharpyuv.lib diff --git a/src/Package/Library/libwebp.php b/src/Package/Library/libwebp.php index 0ee4028d5..30b3826ac 100644 --- a/src/Package/Library/libwebp.php +++ b/src/Package/Library/libwebp.php @@ -8,6 +8,7 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; #[Library('libwebp')] class libwebp extends LibraryPackage @@ -41,4 +42,23 @@ public function buildUnix(): void $this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX | PKGCONF_PATCH_LIBDIR); $this->patchPkgconfPrefix(['libsharpyuv.pc'], PKGCONF_PATCH_CUSTOM, ['/^includedir=.*$/m', 'includedir=${prefix}/include/webp']); } + + #[BuildFor('Windows')] + public function buildWin(): void + { + WindowsCMakeExecutor::create($this) + ->addConfigureArgs( + '-DWEBP_BUILD_EXTRAS=OFF', + '-DWEBP_BUILD_ANIM_UTILS=OFF', + '-DWEBP_BUILD_CWEBP=OFF', + '-DWEBP_BUILD_DWEBP=OFF', + '-DWEBP_BUILD_GIF2WEBP=OFF', + '-DWEBP_BUILD_IMG2WEBP=OFF', + '-DWEBP_BUILD_VWEBP=OFF', + '-DWEBP_BUILD_WEBPINFO=OFF', + '-DWEBP_BUILD_WEBPMUX=OFF', + '-DWEBP_BUILD_FUZZTEST=OFF', + ) + ->build(); + } } From 36177e4948d441eb947b6cb607e09019f8a276c7 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 17:54:07 +0800 Subject: [PATCH 30/52] Add libjpeg --- config/pkg/lib/libjpeg.yml | 4 ++++ src/Package/Library/libjpeg.php | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/config/pkg/lib/libjpeg.yml b/config/pkg/lib/libjpeg.yml index 9171ad388..cca706861 100644 --- a/config/pkg/lib/libjpeg.yml +++ b/config/pkg/lib/libjpeg.yml @@ -7,6 +7,10 @@ libjpeg: metadata: license-files: [LICENSE.md] license: IJG + suggests@windows: + - zlib static-libs@unix: - libjpeg.a - libturbojpeg.a + static-libs@windows: + - libjpeg_a.lib diff --git a/src/Package/Library/libjpeg.php b/src/Package/Library/libjpeg.php index 04f4fd254..6e06bfb70 100644 --- a/src/Package/Library/libjpeg.php +++ b/src/Package/Library/libjpeg.php @@ -8,6 +8,8 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Util\FileSystem; #[Library('libjpeg')] class libjpeg @@ -25,4 +27,20 @@ public function buildUnix(LibraryPackage $lib): void // patch pkgconfig $lib->patchPkgconfPrefix(['libjpeg.pc', 'libturbojpeg.pc']); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DENABLE_SHARED=OFF', + '-DENABLE_STATIC=ON', + '-DBUILD_TESTING=OFF', + '-DWITH_JAVA=OFF', + '-DWITH_CRT_DLL=OFF', + ) + ->optionalPackage('zlib', '-DENABLE_ZLIB_COMPRESSION=ON', '-DENABLE_ZLIB_COMPRESSION=OFF') + ->build(); + FileSystem::copy("{$lib->getLibDir()}\\jpeg-static.lib", "{$lib->getLibDir()}\\libjpeg_a.lib"); + } } From 33f33439d19e44b21320fd930ccbdbb324c4a2b9 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 17:54:21 +0800 Subject: [PATCH 31/52] Add libavif --- config/pkg/lib/libavif.yml | 2 ++ src/Package/Library/libavif.php | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/config/pkg/lib/libavif.yml b/config/pkg/lib/libavif.yml index c75b05c45..eaea8542a 100644 --- a/config/pkg/lib/libavif.yml +++ b/config/pkg/lib/libavif.yml @@ -16,3 +16,5 @@ libavif: - libpng static-libs@unix: - libavif.a + static-libs@windows: + - avif.lib diff --git a/src/Package/Library/libavif.php b/src/Package/Library/libavif.php index 6db235e19..b8321375e 100644 --- a/src/Package/Library/libavif.php +++ b/src/Package/Library/libavif.php @@ -6,12 +6,25 @@ use StaticPHP\Attribute\Package\BuildFor; use StaticPHP\Attribute\Package\Library; +use StaticPHP\Attribute\Package\PatchBeforeBuild; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Runtime\SystemTarget; +use StaticPHP\Util\FileSystem; #[Library('libavif')] class libavif { + #[PatchBeforeBuild] + public function patchBeforeBuild(LibraryPackage $lib): void + { + // workaround for libavif 1.2.0 bug: MSVC does not support empty initializer list + if (SystemTarget::getTargetOS() === 'Windows') { + FileSystem::replaceFileStr($lib->getSourceDir() . '/src/read.c', 'avifFileType ftyp = {};', 'avifFileType ftyp = { 0 };'); + } + } + #[BuildFor('Darwin')] #[BuildFor('Linux')] public function buildUnix(LibraryPackage $lib): void @@ -27,4 +40,17 @@ public function buildUnix(LibraryPackage $lib): void // patch pkgconfig $lib->patchPkgconfPrefix(['libavif.pc']); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs( + '-DAVIF_BUILD_APPS=OFF', + '-DAVIF_BUILD_TESTS=OFF', + '-DAVIF_LIBYUV=OFF', + '-DAVIF_ENABLE_GTEST=OFF', + ) + ->build(); + } } From a950f3d716a8c7be04efbc95ca66687257934115 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 17:54:34 +0800 Subject: [PATCH 32/52] Add libaom --- config/pkg/lib/libaom.yml | 2 ++ src/Package/Library/libaom.php | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/config/pkg/lib/libaom.yml b/config/pkg/lib/libaom.yml index 6a2dbe3cb..51d14a9b5 100644 --- a/config/pkg/lib/libaom.yml +++ b/config/pkg/lib/libaom.yml @@ -10,3 +10,5 @@ libaom: lang: cpp static-libs@unix: - libaom.a + static-libs@windows: + - aom.lib diff --git a/src/Package/Library/libaom.php b/src/Package/Library/libaom.php index 167ef0766..7e578242b 100644 --- a/src/Package/Library/libaom.php +++ b/src/Package/Library/libaom.php @@ -8,12 +8,28 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; use StaticPHP\Toolchain\Interface\ToolchainInterface; use StaticPHP\Toolchain\ZigToolchain; #[Library('libaom')] class libaom extends LibraryPackage { + #[BuildFor('Windows')] + public function buildWin(): void + { + WindowsCMakeExecutor::create($this) + ->setBuildDir("{$this->getSourceDir()}/builddir") + ->addConfigureArgs( + '-DAOM_TARGET_CPU=generic', + '-DENABLE_TESTS=OFF', + '-DENABLE_EXAMPLES=OFF', + '-DENABLE_TOOLS=OFF', + '-DENABLE_DOCS=OFF', + ) + ->build(); + } + #[BuildFor('Darwin')] #[BuildFor('Linux')] public function buildUnix(ToolchainInterface $toolchain): void From 9af132d67e9ebb6c6ad89db3ff088577aadf9d53 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 18:03:14 +0800 Subject: [PATCH 33/52] Add missing icu license file --- src/globals/licenses/icu.txt | 568 +++++++++++++++++++++++++++++++++++ 1 file changed, 568 insertions(+) create mode 100644 src/globals/licenses/icu.txt diff --git a/src/globals/licenses/icu.txt b/src/globals/licenses/icu.txt new file mode 100644 index 000000000..5a2eda629 --- /dev/null +++ b/src/globals/licenses/icu.txt @@ -0,0 +1,568 @@ +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 2016-2025 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. + +SPDX-License-Identifier: Unicode-3.0 + +---------------------------------------------------------------------- + +Third-Party Software Licenses + +This section contains third-party software notices and/or additional +terms for licensed third-party software components included within ICU +libraries. + +---------------------------------------------------------------------- + +ICU License - ICU 1.8.1 to ICU 57.1 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright (c) 1995-2016 International Business Machines Corporation and others +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, provided that the above +copyright notice(s) and this permission notice appear in all copies of +the Software and that both the above copyright notice(s) and this +permission notice appear in supporting documentation. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY +SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Except as contained in this notice, the name of a copyright holder +shall not be used in advertising or otherwise to promote the sale, use +or other dealings in this Software without prior written authorization +of the copyright holder. + +All trademarks and registered trademarks mentioned herein are the +property of their respective owners. + +---------------------------------------------------------------------- + +Chinese/Japanese Word Break Dictionary Data (cjdict.txt) + + # The Google Chrome software developed by Google is licensed under + # the BSD license. Other software included in this distribution is + # provided under other licenses, as set forth below. + # + # The BSD License + # http://opensource.org/licenses/bsd-license.php + # Copyright (C) 2006-2008, Google Inc. + # + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, + # this list of conditions and the following disclaimer. + # Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following + # disclaimer in the documentation and/or other materials provided with + # the distribution. + # Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + # + # The word list in cjdict.txt are generated by combining three word lists + # listed below with further processing for compound word breaking. The + # frequency is generated with an iterative training against Google web + # corpora. + # + # * Libtabe (Chinese) + # - https://sourceforge.net/project/?group_id=1519 + # - Its license terms and conditions are shown below. + # + # * IPADIC (Japanese) + # - http://chasen.aist-nara.ac.jp/chasen/distribution.html + # - Its license terms and conditions are shown below. + # + # ---------COPYING.libtabe ---- BEGIN-------------------- + # + # /* + # * Copyright (c) 1999 TaBE Project. + # * Copyright (c) 1999 Pai-Hsiang Hsiao. + # * All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the TaBE Project nor the names of its + # * contributors may be used to endorse or promote products derived + # * from this software without specific prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + # */ + # + # /* + # * Copyright (c) 1999 Computer Systems and Communication Lab, + # * Institute of Information Science, Academia + # * Sinica. All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the Computer Systems and Communication Lab + # * nor the names of its contributors may be used to endorse or + # * promote products derived from this software without specific + # * prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + # */ + # + # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, + # University of Illinois + # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 + # + # ---------------COPYING.libtabe-----END-------------------------------- + # + # + # ---------------COPYING.ipadic-----BEGIN------------------------------- + # + # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science + # and Technology. All Rights Reserved. + # + # Use, reproduction, and distribution of this software is permitted. + # Any copy of this software, whether in its original form or modified, + # must include both the above copyright notice and the following + # paragraphs. + # + # Nara Institute of Science and Technology (NAIST), + # the copyright holders, disclaims all warranties with regard to this + # software, including all implied warranties of merchantability and + # fitness, in no event shall NAIST be liable for + # any special, indirect or consequential damages or any damages + # whatsoever resulting from loss of use, data or profits, whether in an + # action of contract, negligence or other tortuous action, arising out + # of or in connection with the use or performance of this software. + # + # A large portion of the dictionary entries + # originate from ICOT Free Software. The following conditions for ICOT + # Free Software applies to the current dictionary as well. + # + # Each User may also freely distribute the Program, whether in its + # original form or modified, to any third party or parties, PROVIDED + # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear + # on, or be attached to, the Program, which is distributed substantially + # in the same form as set out herein and that such intended + # distribution, if actually made, will neither violate or otherwise + # contravene any of the laws and regulations of the countries having + # jurisdiction over the User or the intended distribution itself. + # + # NO WARRANTY + # + # The program was produced on an experimental basis in the course of the + # research and development conducted during the project and is provided + # to users as so produced on an experimental basis. Accordingly, the + # program is provided without any warranty whatsoever, whether express, + # implied, statutory or otherwise. The term "warranty" used herein + # includes, but is not limited to, any warranty of the quality, + # performance, merchantability and fitness for a particular purpose of + # the program and the nonexistence of any infringement or violation of + # any right of any third party. + # + # Each user of the program will agree and understand, and be deemed to + # have agreed and understood, that there is no warranty whatsoever for + # the program and, accordingly, the entire risk arising from or + # otherwise connected with the program is assumed by the user. + # + # Therefore, neither ICOT, the copyright holder, or any other + # organization that participated in or was otherwise related to the + # development of the program and their respective officials, directors, + # officers and other employees shall be held liable for any and all + # damages, including, without limitation, general, special, incidental + # and consequential damages, arising out of or otherwise in connection + # with the use or inability to use the program or any product, material + # or result produced or otherwise obtained by using the program, + # regardless of whether they have been advised of, or otherwise had + # knowledge of, the possibility of such damages at any time during the + # project or thereafter. Each user will be deemed to have agreed to the + # foregoing by his or her commencement of use of the program. The term + # "use" as used herein includes, but is not limited to, the use, + # modification, copying and distribution of the program and the + # production of secondary products from the program. + # + # In the case where the program, whether in its original form or + # modified, was distributed or delivered to or received by a user from + # any person, organization or entity other than ICOT, unless it makes or + # grants independently of ICOT any specific warranty to the user in + # writing, such person, organization or entity, will also be exempted + # from and not be held liable to the user for any such damages as noted + # above as far as the program is concerned. + # + # ---------------COPYING.ipadic-----END---------------------------------- + +---------------------------------------------------------------------- + +Lao Word Break Dictionary Data (laodict.txt) + + # Copyright (C) 2016 and later: Unicode, Inc. and others. + # License & terms of use: http://www.unicode.org/copyright.html + # Copyright (c) 2015 International Business Machines Corporation + # and others. All Rights Reserved. + # + # Project: https://github.com/rober42539/lao-dictionary + # Dictionary: https://github.com/rober42539/lao-dictionary/laodict.txt + # License: https://github.com/rober42539/lao-dictionary/LICENSE.txt + # (copied below) + # + # This file is derived from the above dictionary version of Nov 22, 2020 + # ---------------------------------------------------------------------- + # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, this + # list of conditions and the following disclaimer. Redistributions in binary + # form must reproduce the above copyright notice, this list of conditions and + # the following disclaimer in the documentation and/or other materials + # provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # OF THE POSSIBILITY OF SUCH DAMAGE. + # -------------------------------------------------------------------------- + +---------------------------------------------------------------------- + +Burmese Word Break Dictionary Data (burmesedict.txt) + + # Copyright (c) 2014 International Business Machines Corporation + # and others. All Rights Reserved. + # + # This list is part of a project hosted at: + # github.com/kanyawtech/myanmar-karen-word-lists + # + # -------------------------------------------------------------------------- + # Copyright (c) 2013, LeRoy Benjamin Sharon + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions + # are met: Redistributions of source code must retain the above + # copyright notice, this list of conditions and the following + # disclaimer. Redistributions in binary form must reproduce the + # above copyright notice, this list of conditions and the following + # disclaimer in the documentation and/or other materials provided + # with the distribution. + # + # Neither the name Myanmar Karen Word Lists, nor the names of its + # contributors may be used to endorse or promote products derived + # from this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + # SUCH DAMAGE. + # -------------------------------------------------------------------------- + +---------------------------------------------------------------------- + +Time Zone Database + + ICU uses the public domain data and code derived from Time Zone +Database for its time zone support. The ownership of the TZ database +is explained in BCP 175: Procedure for Maintaining the Time Zone +Database section 7. + + # 7. Database Ownership + # + # The TZ database itself is not an IETF Contribution or an IETF + # document. Rather it is a pre-existing and regularly updated work + # that is in the public domain, and is intended to remain in the + # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do + # not apply to the TZ Database or contributions that individuals make + # to it. Should any claims be made and substantiated against the TZ + # Database, the organization that is providing the IANA + # Considerations defined in this RFC, under the memorandum of + # understanding with the IETF, currently ICANN, may act in accordance + # with all competent court orders. No ownership claims will be made + # by ICANN or the IETF Trust on the database or the code. Any person + # making a contribution to the database or code waives all rights to + # future claims in that contribution or in the TZ Database. + +---------------------------------------------------------------------- + +Google double-conversion + +Copyright 2006-2011, the V8 project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +---------------------------------------------------------------------- + +JSON parsing library (nlohmann/json) + +File: vendor/json/upstream/single_include/nlohmann/json.hpp (only for ICU4C) + +MIT License + +Copyright (c) 2013-2022 Niels Lohmann + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +---------------------------------------------------------------------- + +File: aclocal.m4 (only for ICU4C) +Section: pkg.m4 - Macros to locate and utilise pkg-config. + + +Copyright © 2004 Scott James Remnant . +Copyright © 2012-2015 Dan Nicholson + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. + +As a special exception to the GNU General Public License, if you +distribute this file as part of a program that contains a +configuration script generated by Autoconf, you may include it under +the same distribution terms that you use for the rest of that +program. + + +(The condition for the exception is fulfilled because +ICU4C includes a configuration script generated by Autoconf, +namely the `configure` script.) + +---------------------------------------------------------------------- + +File: config.guess (only for ICU4C) + + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, see . + +As a special exception to the GNU General Public License, if you +distribute this file as part of a program that contains a +configuration script generated by Autoconf, you may include it under +the same distribution terms that you use for the rest of that +program. This Exception is an additional permission under section 7 +of the GNU General Public License, version 3 ("GPLv3"). + + +(The condition for the exception is fulfilled because +ICU4C includes a configuration script generated by Autoconf, +namely the `configure` script.) + +---------------------------------------------------------------------- + +File: install-sh (only for ICU4C) + + +Copyright 1991 by the Massachusetts Institute of Technology + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of M.I.T. not be used in advertising or +publicity pertaining to distribution of the software without specific, +written prior permission. M.I.T. makes no representations about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +---------------------------------------------------------------------- + +File: sorttable.js (only for ICU4J) + +The MIT Licence, for code from kryogenix.org + +Code downloaded from the Browser Experiments section of kryogenix.org is +licenced under the so-called MIT licence. The licence is below. + +Copyright (c) 1997-date Stuart Langridge + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From adff728999205116f411bb422a6e4353900767ca Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 18:04:15 +0800 Subject: [PATCH 34/52] Add libffi-win --- config/pkg/lib/libffi-win.yml | 12 ++++++++ src/Package/Library/libffi_win.php | 47 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 config/pkg/lib/libffi-win.yml create mode 100644 src/Package/Library/libffi_win.php diff --git a/config/pkg/lib/libffi-win.yml b/config/pkg/lib/libffi-win.yml new file mode 100644 index 000000000..051dfcb22 --- /dev/null +++ b/config/pkg/lib/libffi-win.yml @@ -0,0 +1,12 @@ +libffi-win: + type: library + artifact: + source: + type: git + rev: master + url: 'https://github.com/static-php/libffi-win.git' + metadata: + license-files: [LICENSE] + license: MIT + static-libs@windows: + - libffi.lib diff --git a/src/Package/Library/libffi_win.php b/src/Package/Library/libffi_win.php new file mode 100644 index 000000000..12faaabef --- /dev/null +++ b/src/Package/Library/libffi_win.php @@ -0,0 +1,47 @@ + '\win32\vs17_x64', + '16' => '\win32\vs16_x64', + default => throw new EnvironmentException("Current VS version {$ver['major_version']} is not supported!"), + }; + ApplicationContext::set('libffi_win_vs_ver_dir', $vs_ver_dir); + } + + #[BuildFor('Windows')] + public function build(LibraryPackage $lib): void + { + $vs_ver_dir = ApplicationContext::get('libffi_win_vs_ver_dir'); + cmd()->cd("{$lib->getSourceDir()}{$vs_ver_dir}") + ->exec('msbuild libffi-msvc.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'); + FileSystem::createDir($lib->getLibDir()); + FileSystem::createDir($lib->getIncludeDir()); + + FileSystem::copy("{$lib->getSourceDir()}{$vs_ver_dir}\\x64\\Release\\libffi.lib", "{$lib->getLibDir()}\\libffi.lib"); + FileSystem::copy("{$lib->getSourceDir()}{$vs_ver_dir}\\x64\\Release\\libffi.pdb", "{$lib->getLibDir()}\\libffi.pdb"); + FileSystem::copy("{$lib->getSourceDir()}\\include\\ffi.h", "{$lib->getIncludeDir()}\\ffi.h"); + FileSystem::replaceFileStr("{$lib->getIncludeDir()}\\ffi.h", '#define LIBFFI_H', "#define LIBFFI_H\n#define FFI_BUILDING"); + FileSystem::copy("{$lib->getSourceDir()}\\src\\x86\\ffitarget.h", "{$lib->getIncludeDir()}\\ffitarget.h"); + FileSystem::copy("{$lib->getSourceDir()}\\fficonfig.h", "{$lib->getIncludeDir()}\\fficonfig.h"); + } +} From e4434643ff9d01cbd35ad38ff223983619747c05 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 18:41:57 +0800 Subject: [PATCH 35/52] Add jom to reduce openssl building time --- config/pkg/target/jom.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 config/pkg/target/jom.yml diff --git a/config/pkg/target/jom.yml b/config/pkg/target/jom.yml new file mode 100644 index 000000000..70916bfdd --- /dev/null +++ b/config/pkg/target/jom.yml @@ -0,0 +1,7 @@ +jom: + type: target + artifact: + binary: + windows-x86_64: { type: url, url: 'https://download.qt.io/official_releases/jom/jom.zip', extract: '{pkg_root_path}/jom' } + path@windows: + - '{pkg_root_path}\jom' From 08dca4253dbff19641a5dae5af1edf0362f8c81b Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 18:42:34 +0800 Subject: [PATCH 36/52] Add librabbitmq --- config/pkg/lib/librabbitmq.yml | 2 ++ src/Package/Library/librabbitmq.php | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/config/pkg/lib/librabbitmq.yml b/config/pkg/lib/librabbitmq.yml index da4e98562..9928d331d 100644 --- a/config/pkg/lib/librabbitmq.yml +++ b/config/pkg/lib/librabbitmq.yml @@ -12,3 +12,5 @@ librabbitmq: - openssl static-libs@unix: - librabbitmq.a + static-libs@windows: + - rabbitmq.4.lib diff --git a/src/Package/Library/librabbitmq.php b/src/Package/Library/librabbitmq.php index 2350ea5e8..03eda2a74 100644 --- a/src/Package/Library/librabbitmq.php +++ b/src/Package/Library/librabbitmq.php @@ -8,6 +8,7 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; #[Library('librabbitmq')] class librabbitmq extends LibraryPackage @@ -18,4 +19,11 @@ public function buildUnix(): void { UnixCMakeExecutor::create($this)->addConfigureArgs('-DBUILD_STATIC_LIBS=ON')->build(); } + + #[BuildFor('Windows')] + public function buildWin(): void + { + WindowsCMakeExecutor::create($this)->build(); + rename("{$this->getLibDir()}\\librabbitmq.4.lib", "{$this->getLibDir()}\\rabbitmq.4.lib"); + } } From 508cfa67e5e47af405f29e722154d0bf943053bc Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sat, 21 Mar 2026 18:43:05 +0800 Subject: [PATCH 37/52] Make openssl build faster --- config/pkg/lib/openssl.yml | 3 +++ src/Package/Library/openssl.php | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/config/pkg/lib/openssl.yml b/config/pkg/lib/openssl.yml index 161cdcebc..da02f202b 100644 --- a/config/pkg/lib/openssl.yml +++ b/config/pkg/lib/openssl.yml @@ -16,6 +16,9 @@ openssl: license: OpenSSL depends: - zlib + depends@windows: + - zlib + - jom headers: - openssl static-libs@unix: diff --git a/src/Package/Library/openssl.php b/src/Package/Library/openssl.php index a01d01b0b..69297198d 100644 --- a/src/Package/Library/openssl.php +++ b/src/Package/Library/openssl.php @@ -10,6 +10,7 @@ use StaticPHP\DI\ApplicationContext; use StaticPHP\Exception\EnvironmentException; use StaticPHP\Package\LibraryPackage; +use StaticPHP\Package\PackageBuilder; use StaticPHP\Runtime\SystemTarget; use StaticPHP\Util\FileSystem; use StaticPHP\Util\System\LinuxUtil; @@ -36,7 +37,7 @@ public function validate(): void } #[BuildFor('Windows')] - public function buildWin(LibraryPackage $lib): void + public function buildWin(LibraryPackage $lib, PackageBuilder $builder): void { $perl = ApplicationContext::get('perl'); $cmd = cmd()->cd($lib->getSourceDir()) @@ -47,7 +48,9 @@ public function buildWin(LibraryPackage $lib): void '--with-zlib-lib=' . quote($lib->getLibDir()) . ' ' . '--with-zlib-include=' . quote($lib->getIncludeDir()) . ' ' . '--release ' . - 'no-legacy ' + 'no-legacy ' . + 'no-tests ' . + '/FS' ); // patch zlib @@ -56,7 +59,7 @@ public function buildWin(LibraryPackage $lib): void FileSystem::replaceFileStr("{$lib->getSourceDir()}\\Makefile", '/debug', '/incremental:no /opt:icf /dynamicbase /nxcompat /ltcg /nodefaultlib:msvcrt'); // build - $cmd->exec("nmake install_dev CNF_LDFLAGS=\"/NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:msvcrt /NODEFAULTLIB:msvcrtd /DEFAULTLIB:libcmt /LIBPATH:{$lib->getLibDir()} zlibstatic.lib\""); + $cmd->exec("jom.exe /j{$builder->concurrency} install_dev CNF_LDFLAGS=\"/NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:msvcrt /NODEFAULTLIB:msvcrtd /DEFAULTLIB:libcmt /LIBPATH:{$lib->getLibDir()} zlibstatic.lib\""); // copy necessary c files FileSystem::copy("{$lib->getSourceDir()}\\ms\\applink.c", "{$lib->getIncludeDir()}\\openssl\\applink.c"); From af9726359676099876d3252e5db921fed295bb35 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 22 Mar 2026 20:19:31 +0800 Subject: [PATCH 38/52] Forward-port #1070 --- src/Package/Library/zlib.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Package/Library/zlib.php b/src/Package/Library/zlib.php index f45b942c9..9bc9ef663 100644 --- a/src/Package/Library/zlib.php +++ b/src/Package/Library/zlib.php @@ -32,6 +32,7 @@ public function buildWin(LibraryPackage $lib): void 'zlibstatic.lib', 'zs.lib', 'libzs.lib', + 'libz.lib', ]; foreach ($detect_list as $item) { if (file_exists("{$lib->getLibDir()}\\{$item}")) { From 141c73738042827b73188c902eb7b745472c55ff Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Mon, 23 Mar 2026 16:50:13 +0800 Subject: [PATCH 39/52] Add libsodium --- config/pkg/lib/libsodium.yml | 2 ++ src/Package/Library/libsodium.php | 49 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/config/pkg/lib/libsodium.yml b/config/pkg/lib/libsodium.yml index f5a551b93..4bd41363b 100644 --- a/config/pkg/lib/libsodium.yml +++ b/config/pkg/lib/libsodium.yml @@ -13,3 +13,5 @@ libsodium: - libsodium static-libs@unix: - libsodium.a + static-libs@windows: + - libsodium.lib diff --git a/src/Package/Library/libsodium.php b/src/Package/Library/libsodium.php index 50d706ba4..5280927cc 100644 --- a/src/Package/Library/libsodium.php +++ b/src/Package/Library/libsodium.php @@ -6,12 +6,26 @@ use StaticPHP\Attribute\Package\BuildFor; use StaticPHP\Attribute\Package\Library; +use StaticPHP\Attribute\Package\PatchBeforeBuild; +use StaticPHP\Exception\BuildFailureException; +use StaticPHP\Exception\EnvironmentException; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\SystemTarget; +use StaticPHP\Util\FileSystem; +use StaticPHP\Util\System\WindowsUtil; #[Library('libsodium')] class libsodium { + #[PatchBeforeBuild] + public function patchBeforeBuild(LibraryPackage $lib): void + { + if (SystemTarget::getTargetOS() === 'Windows') { + FileSystem::replaceFileStr("{$lib->getSourceDir()}\\src\\libsodium\\include\\sodium\\export.h", '#ifdef SODIUM_STATIC', '#if 1'); + } + } + #[BuildFor('Linux')] #[BuildFor('Darwin')] public function build(LibraryPackage $lib): void @@ -21,4 +35,39 @@ public function build(LibraryPackage $lib): void // Patch pkg-config file $lib->patchPkgconfPrefix(['libsodium.pc'], PKGCONF_PATCH_PREFIX); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + $ver = WindowsUtil::findVisualStudio(); + $vs_ver_dir = match ($ver['major_version']) { + '17' => '\vs2022', + '16' => '\vs2019', + default => throw new EnvironmentException("Current VS version {$ver['major_version']} is not supported yet!"), + }; + + cmd()->cd("{$lib->getSourceDir()}\\builds\\msvc{$vs_ver_dir}") + ->exec('msbuild libsodium.sln /t:Rebuild /p:Configuration=StaticRelease /p:Platform=x64 /p:PreprocessorDefinitions="SODIUM_STATIC=1"'); + FileSystem::createDir($lib->getLibDir()); + FileSystem::createDir($lib->getIncludeDir()); + + // copy include + FileSystem::copyDir("{$lib->getSourceDir()}\\src\\libsodium\\include\\sodium", "{$lib->getIncludeDir()}\\sodium"); + FileSystem::copy("{$lib->getSourceDir()}\\src\\libsodium\\include\\sodium.h", "{$lib->getIncludeDir()}\\sodium.h"); + // copy lib + $ls = FileSystem::scanDirFiles("{$lib->getSourceDir()}\\bin"); + $find = false; + foreach ($ls as $file) { + if (str_ends_with($file, 'libsodium.lib')) { + FileSystem::copy($file, "{$lib->getLibDir()}\\libsodium.lib"); + $find = true; + } + if (str_ends_with($file, 'libsodium.pdb')) { + FileSystem::copy($file, "{$lib->getLibDir()}\\libsodium.pdb"); + } + } + if (!$find) { + throw new BuildFailureException("Build libsodium success, but cannot find libsodium.lib in {$lib->getSourceDir()}\\bin ."); + } + } } From 6d91f8b2d38c01ecc8881f4c321c936cf72deae2 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Mon, 23 Mar 2026 17:11:37 +0800 Subject: [PATCH 40/52] Add patch description for Windows static linking in libsodium --- src/Package/Library/libsodium.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Package/Library/libsodium.php b/src/Package/Library/libsodium.php index 5280927cc..0d4c8afef 100644 --- a/src/Package/Library/libsodium.php +++ b/src/Package/Library/libsodium.php @@ -7,6 +7,7 @@ use StaticPHP\Attribute\Package\BuildFor; use StaticPHP\Attribute\Package\Library; use StaticPHP\Attribute\Package\PatchBeforeBuild; +use StaticPHP\Attribute\PatchDescription; use StaticPHP\Exception\BuildFailureException; use StaticPHP\Exception\EnvironmentException; use StaticPHP\Package\LibraryPackage; @@ -19,11 +20,11 @@ class libsodium { #[PatchBeforeBuild] + #[PatchDescription('Replace SODIUM_STATIC define guard with unconditional #if 1 for MSVC static linking')] public function patchBeforeBuild(LibraryPackage $lib): void { - if (SystemTarget::getTargetOS() === 'Windows') { - FileSystem::replaceFileStr("{$lib->getSourceDir()}\\src\\libsodium\\include\\sodium\\export.h", '#ifdef SODIUM_STATIC', '#if 1'); - } + spc_skip_if(SystemTarget::getTargetOS() !== 'Windows', 'This patch is only for Windows builds.'); + FileSystem::replaceFileStr($lib->getSourceDir() . '\src\libsodium\include\sodium\export.h', '#ifdef SODIUM_STATIC', '#if 1'); } #[BuildFor('Linux')] From 41f5948392e18df0c2d9eb053156b4f737bc1eb1 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Mon, 23 Mar 2026 17:11:47 +0800 Subject: [PATCH 41/52] Add libyaml --- config/pkg/lib/libyaml.yml | 2 ++ src/Package/Library/libyaml.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/config/pkg/lib/libyaml.yml b/config/pkg/lib/libyaml.yml index 0d39e0b1d..8cabd58fb 100644 --- a/config/pkg/lib/libyaml.yml +++ b/config/pkg/lib/libyaml.yml @@ -13,3 +13,5 @@ libyaml: - yaml.h static-libs@unix: - libyaml.a + static-libs@windows: + - yaml.lib diff --git a/src/Package/Library/libyaml.php b/src/Package/Library/libyaml.php index 602c875c8..5334079ba 100644 --- a/src/Package/Library/libyaml.php +++ b/src/Package/Library/libyaml.php @@ -6,16 +6,44 @@ 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\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Runtime\SystemTarget; +use StaticPHP\Util\FileSystem; #[Library('libyaml')] class libyaml { + #[PatchBeforeBuild] + #[PatchDescription('Copy missing cmake helper files required for MSVC build (not included in libyaml git source)')] + public function patchBeforeBuild(LibraryPackage $lib): void + { + spc_skip_if(SystemTarget::getTargetOS() !== 'Windows', 'This patch is only for Windows builds.'); + // check missing files: cmake\config.h.in and .\YamlConfig.cmake.in + if (!file_exists($lib->getSourceDir() . '\cmake\config.h.in')) { + FileSystem::createDir($lib->getSourceDir() . '\cmake'); + FileSystem::copy(ROOT_DIR . '/src/globals/extra/libyaml_config.h.in', $lib->getSourceDir() . '\cmake\config.h.in'); + } + if (!file_exists($lib->getSourceDir() . '\YamlConfig.cmake.in')) { + FileSystem::copy(ROOT_DIR . '/src/globals/extra/libyaml_yamlConfig.cmake.in', $lib->getSourceDir() . '\YamlConfig.cmake.in'); + } + } + #[BuildFor('Darwin')] #[BuildFor('Linux')] public function buildUnix(LibraryPackage $lib): void { UnixAutoconfExecutor::create($lib)->configure()->make(); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->addConfigureArgs('-DBUILD_TESTING=OFF') + ->build(); + } } From 1f42f1a479c10b07ffd6aa77840b04315bef31e0 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 10:52:13 +0800 Subject: [PATCH 42/52] Add libzip --- config/pkg/lib/libzip.yml | 7 +++++-- src/Package/Library/libzip.php | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/config/pkg/lib/libzip.yml b/config/pkg/lib/libzip.yml index 2de69d424..3d8a375a0 100644 --- a/config/pkg/lib/libzip.yml +++ b/config/pkg/lib/libzip.yml @@ -8,9 +8,10 @@ libzip: prefer-stable: true metadata: license-files: [LICENSE] - depends@unix: + license: BSD-3-Clause + depends: - zlib - suggests@unix: + suggests: - bzip2 - xz - zstd @@ -20,3 +21,5 @@ libzip: - zipconf.h static-libs@unix: - libzip.a + static-libs@windows: + - libzip_a.lib diff --git a/src/Package/Library/libzip.php b/src/Package/Library/libzip.php index f6ebdfea7..b1d386345 100644 --- a/src/Package/Library/libzip.php +++ b/src/Package/Library/libzip.php @@ -8,6 +8,8 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixCMakeExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Util\FileSystem; #[Library('libzip')] class libzip @@ -33,4 +35,28 @@ public function buildUnix(LibraryPackage $lib): void ->build(); $lib->patchPkgconfPrefix(['libzip.pc'], PKGCONF_PATCH_PREFIX); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib) + ->optionalPackage('bzip2', ...cmake_boolean_args('ENABLE_BZIP2')) + ->optionalPackage('xz', ...cmake_boolean_args('ENABLE_LZMA')) + ->optionalPackage('openssl', ...cmake_boolean_args('ENABLE_OPENSSL')) + ->optionalPackage('zstd', ...cmake_boolean_args('ENABLE_ZSTD')) + ->addConfigureArgs( + '-DENABLE_GNUTLS=OFF', + '-DENABLE_MBEDTLS=OFF', + '-DBUILD_DOC=OFF', + '-DBUILD_EXAMPLES=OFF', + '-DBUILD_REGRESS=OFF', + '-DBUILD_TOOLS=OFF', + '-DBUILD_OSSFUZZ=OFF', + ) + ->build(); + FileSystem::copy( + $lib->getBuildRootPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'zip.lib', + $lib->getBuildRootPath() . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'libzip_a.lib' + ); + } } From 2a50015c12e8d32d4b39ec157428d164ed8c9e60 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 12:07:02 +0800 Subject: [PATCH 43/52] Add download options for install-pkg command --- src/StaticPHP/Command/InstallPackageCommand.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/StaticPHP/Command/InstallPackageCommand.php b/src/StaticPHP/Command/InstallPackageCommand.php index 864fd3796..1185e9f93 100644 --- a/src/StaticPHP/Command/InstallPackageCommand.php +++ b/src/StaticPHP/Command/InstallPackageCommand.php @@ -4,6 +4,7 @@ namespace StaticPHP\Command; +use StaticPHP\Artifact\DownloaderOptions; use StaticPHP\DI\ApplicationContext; use StaticPHP\Package\PackageInstaller; use StaticPHP\Registry\PackageLoader; @@ -29,6 +30,7 @@ public function configure(): void return array_filter($packages, fn ($name) => str_starts_with($name, $val)); } ); + $this->getDefinition()->addOptions(DownloaderOptions::getConsoleOptions('dl')); } public function handle(): int From 7c3022b7e3bf947e837d3fc43ccd97277cf9260f Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 12:07:57 +0800 Subject: [PATCH 44/52] Add postgresql (replace postgresql-win) --- config/pkg/lib/postgresql.yml | 12 +++++++++--- src/StaticPHP/Package/PackageInstaller.php | 5 +++++ src/StaticPHP/Util/FileSystem.php | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/config/pkg/lib/postgresql.yml b/config/pkg/lib/postgresql.yml index 1237b1846..ee78072e4 100644 --- a/config/pkg/lib/postgresql.yml +++ b/config/pkg/lib/postgresql.yml @@ -5,19 +5,25 @@ postgresql: type: ghtagtar repo: postgres/postgres match: REL_18_\d+ + binary: + windows-x86_64: { type: url, url: 'https://get.enterprisedb.com/postgresql/postgresql-16.8-1-windows-x64-binaries.zip', extract: { lib/libpq.lib: '{build_root_path}/lib/libpq.lib', lib/libpgport.lib: '{build_root_path}/lib/libpgport.lib', lib/libpgcommon.lib: '{build_root_path}/lib/libpgcommon.lib', include/libpq-fe.h: '{build_root_path}/include/libpq-fe.h', include/postgres_ext.h: '{build_root_path}/include/postgres_ext.h', include/pg_config_ext.h: '{build_root_path}/include/pg_config_ext.h', include/libpq/libpq-fs.h: '{build_root_path}/include/libpq/libpq-fs.h' } } metadata: - license-files: [COPYRIGHT] + license-files: ['@/postgresql.txt'] license: PostgreSQL - depends: + depends@unix: - libiconv - libxml2 - openssl - zlib - libedit - suggests: + suggests@unix: - icu - libxslt - ldap - zstd pkg-configs: - libpq + static-libs@windows: + - libpq.lib + - libpgport.lib + - libpgcommon.lib diff --git a/src/StaticPHP/Package/PackageInstaller.php b/src/StaticPHP/Package/PackageInstaller.php index f5c03a7de..16e8f45a9 100644 --- a/src/StaticPHP/Package/PackageInstaller.php +++ b/src/StaticPHP/Package/PackageInstaller.php @@ -323,6 +323,11 @@ public function isPackageInstalled(Package|string $package_name): bool $artifact = $package->getArtifact(); return $artifact->isBinaryExtracted(); } + // Fallback: if the download cache is missing (e.g. download failed or cache was cleared), + // still check whether the files are physically present in buildroot. + if ($package instanceof LibraryPackage) { + return $package->isInstalled(); + } return false; } diff --git a/src/StaticPHP/Util/FileSystem.php b/src/StaticPHP/Util/FileSystem.php index 144f81eb3..38a614e01 100644 --- a/src/StaticPHP/Util/FileSystem.php +++ b/src/StaticPHP/Util/FileSystem.php @@ -405,6 +405,7 @@ public static function isRelativePath(string $path): bool public static function replacePathVariable(string $path): string { $replacement = [ + '{build_root_path}' => BUILD_ROOT_PATH, '{pkg_root_path}' => PKG_ROOT_PATH, '{php_sdk_path}' => getenv('PHP_SDK_PATH') ? getenv('PHP_SDK_PATH') : WORKING_DIR . '/php-sdk-binary-tools', '{working_dir}' => WORKING_DIR, From bf05af7e16ff686c98141c50613705354ba05a8c Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 12:13:22 +0800 Subject: [PATCH 45/52] Add pthreads4w --- config/pkg/lib/pthreads4w.yml | 12 +++++++++++ src/Package/Library/pthreads4w.php | 34 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 config/pkg/lib/pthreads4w.yml create mode 100644 src/Package/Library/pthreads4w.php diff --git a/config/pkg/lib/pthreads4w.yml b/config/pkg/lib/pthreads4w.yml new file mode 100644 index 000000000..06a6245f8 --- /dev/null +++ b/config/pkg/lib/pthreads4w.yml @@ -0,0 +1,12 @@ +pthreads4w: + type: library + artifact: + source: + type: git + rev: master + url: 'https://git.code.sf.net/p/pthreads4w/code' + metadata: + license-files: [LICENSE] + license: Apache-2.0 + static-libs@windows: + - libpthreadVC3.lib diff --git a/src/Package/Library/pthreads4w.php b/src/Package/Library/pthreads4w.php new file mode 100644 index 000000000..69f181f0b --- /dev/null +++ b/src/Package/Library/pthreads4w.php @@ -0,0 +1,34 @@ +cd($lib->getSourceDir()) + ->exec( + 'nmake /E /nologo /f Makefile ' . + 'DESTROOT=' . $lib->getBuildRootPath() . ' ' . + 'XCFLAGS="/MT" ' . // no dll + 'EHFLAGS="/I. /DHAVE_CONFIG_H /Os /Ob2 /D__PTW32_STATIC_LIB /D__PTW32_BUILD_INLINED" ' . + 'pthreadVC3.inlined_static_stamp' + ); + FileSystem::createDir($lib->getLibDir()); + FileSystem::createDir($lib->getIncludeDir()); + FileSystem::copy("{$lib->getSourceDir()}\\libpthreadVC3.lib", "{$lib->getLibDir()}\\libpthreadVC3.lib"); + FileSystem::copy("{$lib->getSourceDir()}\\_ptw32.h", "{$lib->getIncludeDir()}\\_ptw32.h"); + FileSystem::copy("{$lib->getSourceDir()}\\pthread.h", "{$lib->getIncludeDir()}\\pthread.h"); + FileSystem::copy("{$lib->getSourceDir()}\\sched.h", "{$lib->getIncludeDir()}\\sched.h"); + FileSystem::copy("{$lib->getSourceDir()}\\semaphore.h", "{$lib->getIncludeDir()}\\semaphore.h"); + } +} From 175567fd1170d3e917551b240a26869a7bc44831 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 12:13:42 +0800 Subject: [PATCH 46/52] Add missing postgresql license --- src/globals/licenses/postgresql.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/globals/licenses/postgresql.txt diff --git a/src/globals/licenses/postgresql.txt b/src/globals/licenses/postgresql.txt new file mode 100644 index 000000000..2f33cebbe --- /dev/null +++ b/src/globals/licenses/postgresql.txt @@ -0,0 +1,23 @@ +PostgreSQL Database Management System +(also known as Postgres, formerly known as Postgres95) + +Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this +paragraph and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS +DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO +PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. From 6c52451c6c085dc8e3cae240bfb2a066fb3ddfda Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 12:18:06 +0800 Subject: [PATCH 47/52] Add qdbm --- config/pkg/lib/qdbm.yml | 2 ++ src/Package/Library/qdbm.php | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/config/pkg/lib/qdbm.yml b/config/pkg/lib/qdbm.yml index 1b46e3049..86b881d7c 100644 --- a/config/pkg/lib/qdbm.yml +++ b/config/pkg/lib/qdbm.yml @@ -10,3 +10,5 @@ qdbm: license: 'GPL-2.0-only OR LGPL-2.1-only' static-libs@unix: - libqdbm.a + static-libs@windows: + - qdbm_a.lib diff --git a/src/Package/Library/qdbm.php b/src/Package/Library/qdbm.php index 3b5c276c8..358846fb6 100644 --- a/src/Package/Library/qdbm.php +++ b/src/Package/Library/qdbm.php @@ -23,4 +23,15 @@ public function buildUnix(LibraryPackage $lib): void $ac->make(SystemTarget::getTargetOS() === 'Darwin' ? 'mac' : ''); $lib->patchPkgconfPrefix(['qdbm.pc']); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + cmd()->cd($lib->getSourceDir()) + ->exec('nmake /f VCMakefile'); + FileSystem::createDir($lib->getLibDir()); + FileSystem::createDir($lib->getIncludeDir()); + FileSystem::copy("{$lib->getSourceDir()}\\qdbm_a.lib", "{$lib->getLibDir()}\\qdbm_a.lib"); + FileSystem::copy("{$lib->getSourceDir()}\\depot.h", "{$lib->getIncludeDir()}\\depot.h"); + } } From fcd0052d12ceac15c146a5659dee944eb297e4fc Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 12:31:31 +0800 Subject: [PATCH 48/52] Add sqlite --- config/pkg/lib/sqlite.yml | 2 ++ src/Package/Library/sqlite.php | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/config/pkg/lib/sqlite.yml b/config/pkg/lib/sqlite.yml index fb6eecf35..442629d0c 100644 --- a/config/pkg/lib/sqlite.yml +++ b/config/pkg/lib/sqlite.yml @@ -10,3 +10,5 @@ sqlite: - sqlite3ext.h static-libs@unix: - libsqlite3.a + static-libs@windows: + - libsqlite3_a.lib diff --git a/src/Package/Library/sqlite.php b/src/Package/Library/sqlite.php index ae802bfa9..a3d15f9b7 100644 --- a/src/Package/Library/sqlite.php +++ b/src/Package/Library/sqlite.php @@ -6,8 +6,11 @@ use StaticPHP\Attribute\Package\BuildFor; use StaticPHP\Attribute\Package\Library; +use StaticPHP\Attribute\Package\PatchBeforeBuild; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\SystemTarget; +use StaticPHP\Util\FileSystem; #[Library('sqlite')] class sqlite @@ -19,4 +22,18 @@ public function buildUnix(LibraryPackage $lib): void UnixAutoconfExecutor::create($lib)->configure()->make(); $lib->patchPkgconfPrefix(['sqlite3.pc']); } + + #[PatchBeforeBuild] + public function patchBeforeBuild(LibraryPackage $lib): void + { + spc_skip_if(SystemTarget::getTargetOS() !== 'Windows', 'This patch is only for Windows builds.'); + FileSystem::copy(ROOT_DIR . '/src/globals/extra/Makefile-sqlite', "{$lib->getSourceDir()}\\Makefile"); + } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + cmd()->cd($lib->getSourceDir()) + ->exec("nmake PREFIX={$lib->getBuildRootPath()} install-static"); + } } From 93c099dd3166aa5d88290bc0535e49062f42069f Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 12:31:45 +0800 Subject: [PATCH 49/52] Add xz --- config/pkg/lib/xz.yml | 6 ++++++ src/Package/Library/xz.php | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/config/pkg/lib/xz.yml b/config/pkg/lib/xz.yml index 7d0af682b..3be1815d8 100644 --- a/config/pkg/lib/xz.yml +++ b/config/pkg/lib/xz.yml @@ -14,7 +14,13 @@ xz: - libiconv headers@unix: - lzma + headers@windows: + - lzma + - lzma.h pkg-configs: - liblzma static-libs@unix: - liblzma.a + static-libs@windows: + - lzma.lib + - liblzma_a.lib diff --git a/src/Package/Library/xz.php b/src/Package/Library/xz.php index 3486d4c17..44a20090f 100644 --- a/src/Package/Library/xz.php +++ b/src/Package/Library/xz.php @@ -8,6 +8,8 @@ use StaticPHP\Attribute\Package\Library; use StaticPHP\Package\LibraryPackage; use StaticPHP\Runtime\Executor\UnixAutoconfExecutor; +use StaticPHP\Runtime\Executor\WindowsCMakeExecutor; +use StaticPHP\Util\FileSystem; #[Library('xz')] class xz @@ -27,4 +29,14 @@ public function build(LibraryPackage $lib): void $lib->patchPkgconfPrefix(['liblzma.pc']); $lib->patchLaDependencyPrefix(); } + + #[BuildFor('Windows')] + public function buildWin(LibraryPackage $lib): void + { + WindowsCMakeExecutor::create($lib)->build(); + // copy lzma.lib to liblzma_a.lib + FileSystem::copy("{$lib->getLibDir()}\\lzma.lib", "{$lib->getLibDir()}\\liblzma_a.lib"); + // patch lzma.h: make static API always available on Windows + FileSystem::replaceFileStr("{$lib->getIncludeDir()}\\lzma.h", 'defined(LZMA_API_STATIC)', 'defined(_WIN32)'); + } } From b625d80dc02de60ba2ebc3256d751464434c6898 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 13:30:17 +0800 Subject: [PATCH 50/52] Fix tar command for unix --- src/StaticPHP/Runtime/Shell/DefaultShell.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/StaticPHP/Runtime/Shell/DefaultShell.php b/src/StaticPHP/Runtime/Shell/DefaultShell.php index 77dbf94a0..272011e49 100644 --- a/src/StaticPHP/Runtime/Shell/DefaultShell.php +++ b/src/StaticPHP/Runtime/Shell/DefaultShell.php @@ -6,6 +6,7 @@ use StaticPHP\Exception\InterruptException; use StaticPHP\Exception\SPCInternalException; +use StaticPHP\Runtime\SystemTarget; use StaticPHP\Util\FileSystem; /** @@ -132,7 +133,8 @@ public function executeTarExtract(string $archive_path, string $target_path, str }; $mute = $this->console_putput ? '' : ' 2>/dev/null'; - $cmd = "\"C:\\Windows\\system32\\tar.exe\" {$compression_flag}xf {$archive_arg} --strip-components {$strip} -C {$target_arg}{$mute}"; + $tar = SystemTarget::isUnix() ? 'tar' : '"C:\\Windows\\system32\\tar.exe"'; + $cmd = "{$tar} {$compression_flag}xf {$archive_arg} --strip-components {$strip} -C {$target_arg}{$mute}"; $this->logCommandInfo($cmd); logger()->debug("[TAR EXTRACT] {$cmd}"); @@ -185,9 +187,11 @@ public function execute7zExtract(string $archive_path, string $target_path): boo }; $extname = FileSystem::extname($archive_path); + $tar = SystemTarget::isUnix() ? 'tar' : '"C:\\Windows\\system32\\tar.exe"'; + match ($extname) { 'tar' => $this->executeTarExtract($archive_path, $target_path, 'none'), - 'gz', 'tgz', 'xz', 'txz', 'bz2' => $run("{$_7z} x -so {$archive_arg} | \"C:\\Windows\\system32\\tar.exe\" -f - -x -C {$target_arg} --strip-components 1"), + 'gz', 'tgz', 'xz', 'txz', 'bz2' => $run("{$_7z} x -so {$archive_arg} | {$tar} -f - -x -C {$target_arg} --strip-components 1"), default => $run("{$_7z} x {$archive_arg} -o{$target_arg} -y{$mute}"), }; From 590a94a723f0b85d5fd31d7271dace42c22f6575 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 14:41:32 +0800 Subject: [PATCH 51/52] Fix cli checks caused php testing fail --- src/globals/patch/php-src-patches/cli_checks_81.patch | 10 +++++----- src/globals/patch/php-src-patches/cli_checks_83.patch | 10 +++++----- src/globals/patch/php-src-patches/cli_checks_84.patch | 10 +++++----- src/globals/patch/php-src-patches/cli_checks_85.patch | 10 +++++----- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/globals/patch/php-src-patches/cli_checks_81.patch b/src/globals/patch/php-src-patches/cli_checks_81.patch index 92d6cce5a..39ed5828b 100644 --- a/src/globals/patch/php-src-patches/cli_checks_81.patch +++ b/src/globals/patch/php-src-patches/cli_checks_81.patch @@ -20,7 +20,7 @@ index 8f05686367..c155028233 100644 REGISTER_INI_ENTRIES(); - FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0; -+ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 1; ++ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 0; zend_ffi_exception_ce = register_class_FFI_Exception(zend_ce_error); @@ -103,7 +103,7 @@ index 4287045511..eab0311d07 100644 return NULL; } - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_in = 0; fd = STDIN_FILENO; if (cli_in) { @@ -112,7 +112,7 @@ index 4287045511..eab0311d07 100644 #endif } else if (!strcasecmp(path, "stdout")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_out = 0; fd = STDOUT_FILENO; if (cli_out++) { @@ -121,7 +121,7 @@ index 4287045511..eab0311d07 100644 #endif } else if (!strcasecmp(path, "stderr")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_err = 0; fd = STDERR_FILENO; if (cli_err++) { @@ -130,7 +130,7 @@ index 4287045511..eab0311d07 100644 int dtablesize; - if (strcmp(sapi_module.name, "cli")) { -+ if (strcmp(sapi_module.name, "cli") || strcmp(sapi_module.name, "micro")) { ++ if (strcmp(sapi_module.name, "cli") && strcmp(sapi_module.name, "micro")) { if (options & REPORT_ERRORS) { php_error_docref(NULL, E_WARNING, "Direct access to file descriptors is only available from command-line PHP"); } diff --git a/src/globals/patch/php-src-patches/cli_checks_83.patch b/src/globals/patch/php-src-patches/cli_checks_83.patch index e94250958..db02843b4 100644 --- a/src/globals/patch/php-src-patches/cli_checks_83.patch +++ b/src/globals/patch/php-src-patches/cli_checks_83.patch @@ -20,7 +20,7 @@ index bbfe07576e..398373d577 100644 REGISTER_INI_ENTRIES(); - FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0; -+ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 1; ++ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 0; zend_ffi_exception_ce = register_class_FFI_Exception(zend_ce_error); @@ -112,7 +112,7 @@ index 8926485025..6740163bc5 100644 return NULL; } - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_in = 0; fd = STDIN_FILENO; if (cli_in) { @@ -121,7 +121,7 @@ index 8926485025..6740163bc5 100644 #endif } else if (!strcasecmp(path, "stdout")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_out = 0; fd = STDOUT_FILENO; if (cli_out++) { @@ -130,7 +130,7 @@ index 8926485025..6740163bc5 100644 #endif } else if (!strcasecmp(path, "stderr")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_err = 0; fd = STDERR_FILENO; if (cli_err++) { @@ -139,7 +139,7 @@ index 8926485025..6740163bc5 100644 int dtablesize; - if (strcmp(sapi_module.name, "cli")) { -+ if (strcmp(sapi_module.name, "cli") || strcmp(sapi_module.name, "micro")) { ++ if (strcmp(sapi_module.name, "cli") && strcmp(sapi_module.name, "micro")) { if (options & REPORT_ERRORS) { php_error_docref(NULL, E_WARNING, "Direct access to file descriptors is only available from command-line PHP"); } diff --git a/src/globals/patch/php-src-patches/cli_checks_84.patch b/src/globals/patch/php-src-patches/cli_checks_84.patch index 6b8ac74e1..b137c6ef4 100644 --- a/src/globals/patch/php-src-patches/cli_checks_84.patch +++ b/src/globals/patch/php-src-patches/cli_checks_84.patch @@ -20,7 +20,7 @@ index d797f5f93f..27cb05e3e4 100644 REGISTER_INI_ENTRIES(); - FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0; -+ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 1; ++ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 0; zend_ffi_exception_ce = register_class_FFI_Exception(zend_ce_error); @@ -111,7 +111,7 @@ index a5581d9ccc..98455f7b52 100644 return NULL; } - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_in = 0; fd = STDIN_FILENO; if (cli_in) { @@ -120,7 +120,7 @@ index a5581d9ccc..98455f7b52 100644 #endif } else if (!strcasecmp(path, "stdout")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_out = 0; fd = STDOUT_FILENO; if (cli_out++) { @@ -129,7 +129,7 @@ index a5581d9ccc..98455f7b52 100644 #endif } else if (!strcasecmp(path, "stderr")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_err = 0; fd = STDERR_FILENO; if (cli_err++) { @@ -138,7 +138,7 @@ index a5581d9ccc..98455f7b52 100644 int dtablesize; - if (strcmp(sapi_module.name, "cli")) { -+ if (strcmp(sapi_module.name, "cli") || strcmp(sapi_module.name, "micro")) { ++ if (strcmp(sapi_module.name, "cli") && strcmp(sapi_module.name, "micro")) { if (options & REPORT_ERRORS) { php_error_docref(NULL, E_WARNING, "Direct access to file descriptors is only available from command-line PHP"); } diff --git a/src/globals/patch/php-src-patches/cli_checks_85.patch b/src/globals/patch/php-src-patches/cli_checks_85.patch index cfd72550c..b8cf0fa51 100644 --- a/src/globals/patch/php-src-patches/cli_checks_85.patch +++ b/src/globals/patch/php-src-patches/cli_checks_85.patch @@ -20,7 +20,7 @@ index 10fc11f5..eb4d4175 100644 REGISTER_INI_ENTRIES(); - FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0; -+ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 1; ++ FFI_G(is_cli) = strcmp(sapi_module.name, "cli") == 0 || strcmp(sapi_module.name, "micro") == 0; zend_ffi_exception_ce = register_class_FFI_Exception(zend_ce_error); @@ -98,7 +98,7 @@ index ea33ba49..083184b8 100644 return NULL; } - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_in = 0; fd = STDIN_FILENO; if (cli_in) { @@ -107,7 +107,7 @@ index ea33ba49..083184b8 100644 #endif } else if (!strcasecmp(path, "stdout")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_out = 0; fd = STDOUT_FILENO; if (cli_out++) { @@ -116,7 +116,7 @@ index ea33ba49..083184b8 100644 #endif } else if (!strcasecmp(path, "stderr")) { - if (!strcmp(sapi_module.name, "cli")) { -+ if (!strcmp(sapi_module.name, "cli") && !strcmp(sapi_module.name, "micro")) { ++ if (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "micro")) { static int cli_err = 0; fd = STDERR_FILENO; if (cli_err++) { @@ -125,7 +125,7 @@ index ea33ba49..083184b8 100644 int dtablesize; - if (strcmp(sapi_module.name, "cli")) { -+ if (strcmp(sapi_module.name, "cli") || strcmp(sapi_module.name, "micro")) { ++ if (strcmp(sapi_module.name, "cli") && strcmp(sapi_module.name, "micro")) { if (options & REPORT_ERRORS) { php_error_docref(NULL, E_WARNING, "Direct access to file descriptors is only available from command-line PHP"); } From 9cd312554494f0b9b10afe1bec2ea5f9f6f122f0 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Tue, 24 Mar 2026 14:41:46 +0800 Subject: [PATCH 52/52] Patch configure script to include liblber for ldap dependency --- src/Package/Library/postgresql.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Package/Library/postgresql.php b/src/Package/Library/postgresql.php index 682b79e28..45c48577c 100644 --- a/src/Package/Library/postgresql.php +++ b/src/Package/Library/postgresql.php @@ -73,6 +73,11 @@ public function buildUnix(PackageInstaller $installer, PackageBuilder $builder): FileSystem::resetDir("{$this->getSourceDir()}/build"); + if ($installer->isPackageResolved('ldap')) { + $ldap_libs = clean_spaces(implode(' ', PkgConfigUtil::getLibsArray('ldap'))); + FileSystem::replaceFileStr("{$this->getSourceDir()}/configure", '-lldap', $ldap_libs); + } + // PHP source relies on the non-private encoding functions in libpgcommon.a FileSystem::replaceFileStr( "{$this->getSourceDir()}/src/common/Makefile",