Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions config/artifact/ncurses.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ ncurses:
license-files:
- COPYING
source:
type: filelist
url: 'https://ftp.gnu.org/gnu/ncurses/'
regex: '/href="(?<file>ncurses-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/ncurses/'
regex: '/href="(?<file>ncurses-(?<version>[^"]+)\.tar\.gz)"/'
4 changes: 2 additions & 2 deletions config/env.ini
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ SPC_PRESERVE_LOGS="no"
[windows]
; build target: win7-static
SPC_TARGET=native-windows
; php-sdk-binary-tools path
PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools"
; MSYS2 root directory (msys64 subfolder), used by the Windows toolchain
SPC_MSYS2_PATH="${PKG_ROOT_PATH}\msys2-build-essentials\msys64"
; upx executable path
UPX_EXEC="${PKG_ROOT_PATH}\bin\upx.exe"
; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches
Expand Down
4 changes: 4 additions & 0 deletions config/pkg/lib/gettext.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ gettext:
type: library
artifact:
source:
type: filelist
url: 'https://ftp.gnu.org/gnu/gettext/'
regex: '/href="(?<file>gettext-(?<version>[^"]+)\.tar\.xz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/gettext/'
regex: '/href="(?<file>gettext-(?<version>[^"]+)\.tar\.xz)"/'
Expand Down
7 changes: 4 additions & 3 deletions config/pkg/lib/gmp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ gmp:
artifact:
source:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/gmp/'
url: 'https://ftp.gnu.org/gnu/gmp/'
regex: '/href="(?<file>gmp-(?<version>[^"]+)\.tar\.xz)"/'
source-mirror:
type: url
url: 'https://dl.static-php.dev/static-php-cli/deps/gmp/gmp-6.3.0.tar.xz'
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/gmp/'
regex: '/href="(?<file>gmp-(?<version>[^"]+)\.tar\.xz)"/'
metadata:
license-files: ['@/gmp.txt']
license: Custom
Expand Down
4 changes: 4 additions & 0 deletions config/pkg/lib/idn2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ idn2:
type: library
artifact:
source:
type: filelist
url: 'https://ftp.gnu.org/gnu/libidn/'
regex: '/href="(?<file>libidn2-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/libidn/'
regex: '/href="(?<file>libidn2-(?<version>[^"]+)\.tar\.gz)"/'
Expand Down
4 changes: 4 additions & 0 deletions config/pkg/lib/libiconv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ libiconv:
type: library
artifact:
source:
type: filelist
url: 'https://ftp.gnu.org/gnu/libiconv/'
regex: '/href="(?<file>libiconv-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/libiconv/'
regex: '/href="(?<file>libiconv-(?<version>[^"]+)\.tar\.gz)"/'
Expand Down
4 changes: 3 additions & 1 deletion config/pkg/lib/libssh2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ libssh2:
metadata:
license-files: [COPYING]
license: BSD-3-Clause
depends:
depends@unix:
- openssl
depends@windows:
- zlib
headers:
- libssh2.h
- libssh2_publickey.h
Expand Down
4 changes: 4 additions & 0 deletions config/pkg/lib/libunistring.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ libunistring:
type: library
artifact:
source:
type: filelist
url: 'https://ftp.gnu.org/gnu/libunistring/'
regex: '/href="(?<file>libunistring-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/libunistring/'
regex: '/href="(?<file>libunistring-(?<version>[^"]+)\.tar\.gz)"/'
Expand Down
4 changes: 4 additions & 0 deletions config/pkg/lib/readline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ readline:
type: library
artifact:
source:
type: filelist
url: 'https://ftp.gnu.org/gnu/readline/'
regex: '/href="(?<file>readline-(?<version>[^"]+)\.tar\.gz)"/'
source-mirror:
type: filelist
url: 'https://ftpmirror.gnu.org/gnu/readline/'
regex: '/href="(?<file>readline-(?<version>[^"]+)\.tar\.gz)"/'
Expand Down
5 changes: 5 additions & 0 deletions config/pkg/target/7za-win.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
7za-win:
type: target
artifact:
binary:
windows-x86_64: { type: url, url: 'https://dl.static-php.dev/v3/tools/7zip/7za.exe', extract: '{pkg_root_path}/bin/7za.exe' }
8 changes: 8 additions & 0 deletions config/pkg/target/msys2-build-essentials.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
msys2-build-essentials:
type: target
artifact:
binary: custom
env:
SPC_MSYS2_PATH: '{pkg_root_path}/msys2-build-essentials/msys64'
path@windows:
- '{pkg_root_path}/msys2-build-essentials/msys64/usr/bin'
2 changes: 1 addition & 1 deletion config/pkg/target/nasm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ nasm:
type: target
artifact:
binary:
windows-x86_64: { type: url, url: 'https://dl.static-php.dev/static-php-cli/deps/nasm/nasm-2.16.01-win64.zip', extract: { nasm.exe: '{php_sdk_path}/bin/nasm.exe', ndisasm.exe: '{php_sdk_path}/bin/ndisasm.exe' } }
windows-x86_64: { type: url, url: 'https://dl.static-php.dev/static-php-cli/deps/nasm/nasm-2.16.01-win64.zip', extract: { nasm.exe: '{pkg_root_path}/bin/nasm.exe', ndisasm.exe: '{pkg_root_path}/bin/ndisasm.exe' } }
5 changes: 0 additions & 5 deletions config/pkg/target/php-sdk-binary-tools.yml

This file was deleted.

2 changes: 1 addition & 1 deletion docs/en/develop/package-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ The following path placeholders are supported in string values of the `path`, `e
| `{working_dir}` | Working directory (project root) |
| `{download_path}` | Download cache directory (`downloads/`) |
| `{source_path}` | Extracted source directory (`source/`) |
| `{php_sdk_path}` | Windows PHP SDK directory |
| `{spc_msys2_path}` | MSYS2 root directory (`msys64/`) — Windows only |

## target Package Type

Expand Down
8 changes: 7 additions & 1 deletion docs/en/guide/migrate-from-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ A single-file hook API for lightweight patches may be provided in a future relea

### Windows-only: `--with-sdk-binary-dir` and `--vs-ver`

These options are no longer accepted on the command line. Instead, set the `PHP_SDK_PATH` environment variable to point to your PHP SDK binary tools directory. The Visual Studio version is now managed by the toolchain configuration.
These options are no longer accepted on the command line. In v3, the `php-sdk-binary-tools` dependency has been completely removed. v3 now manages its own **MSYS2** environment to support autotools-based library builds on Windows. Run `spc doctor --install` to download and configure MSYS2 automatically.

If you need to point to a custom MSYS2 installation, set the `SPC_MSYS2_PATH` environment variable to the `msys64` directory (e.g. `C:\msys64`). Visual Studio is now auto-detected by the toolchain — no manual version flag needed.

::: warning Migrating from v2
v2 relied on `php-sdk-binary-tools` and required `--with-sdk-binary-dir` and `--vs-ver` on every build invocation. In v3 these options are gone. Remove them from all CI scripts and run `spc doctor --install` once to set up the Windows build environment.
:::

## Renamed / Deprecated Options

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/develop/package-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ openssl:
| `{working_dir}` | 工作目录(项目根目录) |
| `{download_path}` | 下载缓存目录(`downloads/`) |
| `{source_path}` | 解压源码目录(`source/`) |
| `{php_sdk_path}` | Windows PHP SDK 目录 |
| `{spc_msys2_path}` | MSYS2 根目录(`msys64/`)——仅 Windows |

## target 包类型

Expand Down
8 changes: 7 additions & 1 deletion docs/zh/guide/migrate-from-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ curl -o spc https://dl.static-php.dev/v3/spc-bin/nightly/spc-linux-x86_64

### Windows 专有:`--with-sdk-binary-dir` 和 `--vs-ver`

这两个选项已不再被命令行接受。请改为设置 `PHP_SDK_PATH` 环境变量,指向你的 PHP SDK binary tools 目录。Visual Studio 版本现在由工具链配置统一管理。
这两个选项已不再被命令行接受。在 v3 中,`php-sdk-binary-tools` 依赖已被完全移除。v3 现在通过管理自己的 **MSYS2** 环境来支持 Windows 上基于 autotools 的库构建。运行 `spc doctor --install` 即可自动下载并配置 MSYS2。

如需指向自定义 MSYS2 安装目录,请设置 `SPC_MSYS2_PATH` 环境变量,值为 `msys64` 目录路径(例如 `C:\msys64`)。Visual Studio 版本现在由工具链自动检测,无需手动指定版本号。

::: warning 从 v2 迁移
v2 依赖 `php-sdk-binary-tools`,并在每次构建时需要传入 `--with-sdk-binary-dir` 和 `--vs-ver` 参数。在 v3 中这些选项已被移除。请从所有 CI 脚本中删除这些参数,并使用 `spc doctor --install` 一次性完成 Windows 构建环境的配置。
:::

## 已重命名 / 已弃用的选项

Expand Down
93 changes: 93 additions & 0 deletions src/Package/Artifact/msys2_build_essentials.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

declare(strict_types=1);

namespace Package\Artifact;

use StaticPHP\Artifact\ArtifactDownloader;
use StaticPHP\Artifact\Downloader\DownloadResult;
use StaticPHP\Attribute\Artifact\AfterBinaryExtract;
use StaticPHP\Attribute\Artifact\BinaryExtract;
use StaticPHP\Attribute\Artifact\CustomBinary;
use StaticPHP\Exception\DownloaderException;
use StaticPHP\Util\FileSystem;
use StaticPHP\Util\GlobalEnvManager;

class msys2_build_essentials
{
// MSYS subsystem packages required for autotools-based builds.
private const REQUIRED_PACKAGES = ['make', 'autoconf', 'automake', 'libtool', 'pkgconf', 'perl', 'bison', 're2c'];

#[CustomBinary('msys2-build-essentials', ['windows-x86_64'])]
public function downBinary(ArtifactDownloader $downloader): DownloadResult
{
// MSYS2 nightly self-extracting archive; running it with `-y -oTARGET` extracts to TARGET\msys64\.
$url = 'https://github.com/msys2/msys2-installer/releases/download/nightly-x86_64/msys2-base-x86_64-latest.sfx.exe';
$filename = 'msys2-base-x86_64-latest.sfx.exe';
$path = DOWNLOAD_PATH . DIRECTORY_SEPARATOR . $filename;

default_shell()->executeCurlDownload($url, $path, retries: $downloader->getRetry());

return DownloadResult::file(
$filename,
['url' => $url, 'version' => 'nightly'],
version: 'nightly',
extract: '{pkg_root_path}/msys2-build-essentials',
);
}

#[BinaryExtract('msys2-build-essentials', ['windows-x86_64'])]
public function extractBinary(string $source_file, string $target_path): void
{
$target_path = FileSystem::convertPath($target_path);
$source_file = FileSystem::convertPath($source_file);

// Guard: skip re-extraction if already initialized (marker written at end of this method).
$marker = "{$target_path}\\.spc-msys2-initialized";
if (file_exists($marker)) {
return;
}

if (!is_dir($target_path)) {
FileSystem::createDir($target_path);
}

cmd()->exec("\"{$source_file}\" -y -o\"{$target_path}\"");

$msys2_bin = "{$target_path}\\msys64\\usr\\bin";
if (!file_exists("{$msys2_bin}\\bash.exe")) {
throw new DownloaderException("MSYS2 extraction failed: bash.exe not found at {$msys2_bin}\\bash.exe");
}

// Add MSYS2 usr\bin to PATH so pacman.exe can load msys-2.0.dll.
GlobalEnvManager::addPathIfNotExists($msys2_bin);
GlobalEnvManager::putenv('CHERE_INVOKING=yes');
GlobalEnvManager::putenv('MSYSTEM=MSYS');

// Disable PGP signature checking: pacman-key --init requires a pseudo-TTY which is unavailable
// from PHP. Patching pacman.conf is the standard approach for CI pipelines.
$pacman_conf = "{$target_path}\\msys64\\etc\\pacman.conf";
FileSystem::replaceFileRegex($pacman_conf, '/^SigLevel\s*=.*$/m', 'SigLevel = Never');

$pacman = "{$target_path}\\msys64\\usr\\bin\\pacman.exe";

// Two-pass update as recommended by MSYS2 CI docs.
cmd()->exec("\"{$pacman}\" --noconfirm -Syuu");
cmd()->exec("\"{$pacman}\" --noconfirm -Syuu");

$pkgs = implode(' ', self::REQUIRED_PACKAGES);
cmd()->exec("\"{$pacman}\" --noconfirm -S --needed {$pkgs}");

FileSystem::writeFile($marker, date('Y-m-d H:i:s'));
}

#[AfterBinaryExtract('msys2-build-essentials', ['windows-x86_64'])]
public function afterExtract(string $target_path): void
{
$target_path = FileSystem::convertPath($target_path);
$msys2_root = "{$target_path}\\msys64";

GlobalEnvManager::putenv("SPC_MSYS2_PATH={$msys2_root}");
GlobalEnvManager::addPathIfNotExists("{$msys2_root}\\usr\\bin");
}
}
12 changes: 12 additions & 0 deletions src/Package/Extension/gmssl.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ public function patchSm2VerifyCtx(): void
);
}

#[BeforeStage('php', [php::class, 'buildconfForUnix'], 'ext-gmssl')]
#[BeforeStage('php', [php::class, 'buildconfForWindows'], 'ext-gmssl')]
#[PatchDescription('Fix ext-gmssl v1.1.1: pbkdf2_hmac_sm3_genkey was renamed to sm3_pbkdf2 in GmSSL >= 3.2.0')]
public function patchPbkdf2Rename(): void
{
FileSystem::replaceFileStr(
"{$this->getSourceDir()}/gmssl.c",
'pbkdf2_hmac_sm3_genkey',
'sm3_pbkdf2'
);
}

#[BeforeStage('php', [php::class, 'buildconfForWindows'], 'ext-gmssl')]
#[PatchDescription('Add CHECK_LIB to config.w32 for static Windows builds')]
public function patchBeforeBuildconfWin(): bool
Expand Down
16 changes: 8 additions & 8 deletions src/Package/Library/gmssl.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ public function buildWin(LibraryPackage $lib): void
->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');
cmd()->cd($buildDir)->exec('nmake gmssl XCFLAGS=/MT');

$libPath = "{$lib->getBuildRootPath()}/lib";
$incPath = "{$lib->getBuildRootPath()}/include/gmssl";
FileSystem::createDir($libPath);
FileSystem::createDir($incPath);
FileSystem::copy("{$buildDir}\\bin\\gmssl.lib", "{$libPath}/gmssl.lib");
FileSystem::copyDir("{$lib->getSourceDir()}\\include\\gmssl", $incPath);
}
}
1 change: 1 addition & 0 deletions src/Package/Library/libssh2.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function buildWin(LibraryPackage $lib): void
{
WindowsCMakeExecutor::create($lib)
->addConfigureArgs(
'-DCRYPTO_BACKEND=WinCNG',
'-DENABLE_ZLIB_COMPRESSION=ON',
'-DBUILD_TESTING=OFF'
)
Expand Down
2 changes: 1 addition & 1 deletion src/Package/Library/openssl.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ 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_path_native = PKG_ROOT_PATH . '\strawberry-perl\perl\bin\perl.exe';
$perl = file_exists($perl_path_native) ? ($perl_path_native) : WindowsUtil::findCommand('perl.exe');
if ($perl === null) {
throw new EnvironmentException(
Expand Down
2 changes: 1 addition & 1 deletion src/Package/Target/curl.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function buildWin(LibraryPackage $lib): void
->optionalPackage('brotli', ...cmake_boolean_args('CURL_BROTLI'))
->addConfigureArgs(
'-DBUILD_CURL_EXE=ON',
'-DZSTD_LIBRARY=zstd_static.lib',
'-DZSTD_LIBRARY=' . BUILD_LIB_PATH . '/zstd_static.lib',
'-DBUILD_TESTING=OFF',
'-DBUILD_EXAMPLES=OFF',
'-DUSE_LIBIDN2=OFF',
Expand Down
5 changes: 5 additions & 0 deletions src/Package/Target/php.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,11 @@ public function resolveBuild(TargetPackage $package, PackageInstaller $installer
$installer->addBuildPackage('php-embed');
}

// UPX compression: ensure the upx binary package is installed when requested
if ($package->getBuildOption('with-upx-pack')) {
$additional_packages[] = 'upx';
}

return [...$extensions_pkg, ...$additional_packages];
}

Expand Down
18 changes: 18 additions & 0 deletions src/Package/Target/php/windows.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ public function buildconfForWindows(TargetPackage $package, PackageInstaller $in
InteractiveTerm::setMessage('Building php: ' . ConsoleColor::yellow('./buildconf.bat'));
cmd()->cd($package->getSourceDir())->exec('.\buildconf.bat');

// Bypass the phpsdk_version check in configure.js: we use MSVC + msys2 instead of PHP SDK, so phpsdk_version is not available and the check would always fail.
FileSystem::replaceFileStr(
"{$package->getSourceDir()}\\configure.js",
'check_binary_tools_sdk();',
'/* check_binary_tools_sdk(); skipped: using MSVC + msys2 without PHP SDK */'
);

if ($package->getBuildOption('enable-micro-win32') && $installer->isPackageResolved('php-micro')) {
SourcePatcher::patchMicroWin32();
} else {
Expand Down Expand Up @@ -88,6 +95,17 @@ public function configureForWindows(TargetPackage $package, PackageInstaller $in
cmd()->cd($package->getSourceDir())->exec(".\\configure.bat {$args} {$static_extension_str}");
}

#[BeforeStage('php', [self::class, 'makeCliForWindows'])]
#[PatchDescription('Patch Makefile to ensure buildroot/include comes before extension CFLAGS (fixes zip.h conflict with minizip)')]
public function patchMakefileIncludeOrder(TargetPackage $package): void
{
FileSystem::replaceFileStr(
"{$package->getSourceDir()}\\Makefile",
'$(CFLAGS_PHP_OBJ) $(CFLAGS)',
'$(CFLAGS) $(CFLAGS_PHP_OBJ)'
);
}

#[BeforeStage('php', [self::class, 'makeCliForWindows'])]
#[PatchDescription('Patch Windows Makefile for CLI target')]
public function patchCLITarget(TargetPackage $package): void
Expand Down
2 changes: 1 addition & 1 deletion src/StaticPHP/Artifact/Artifact.php
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ private function replaceExtractPathVariables(string $extract): string
'{artifact_name}' => $this->name,
'{pkg_root_path}' => PKG_ROOT_PATH,
'{build_root_path}' => BUILD_ROOT_PATH,
'{php_sdk_path}' => getenv('PHP_SDK_PATH') ?: WORKING_DIR . '/php-sdk-binary-tools',
'{spc_msys2_path}' => getenv('SPC_MSYS2_PATH'),
'{working_dir}' => WORKING_DIR,
'{download_path}' => DOWNLOAD_PATH,
'{source_path}' => SOURCE_PATH,
Expand Down
Loading
Loading