mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-02 14:25:41 +08:00
feat(windows): replace php-sdk-binary-tools with MSYS2 + 7za-win
- Add msys2-build-essentials target: downloads the MSYS2 nightly sfx,
extracts it, disables PGP keyring (CI-safe), runs two-pass pacman
update, and installs autotools build essentials (make, autoconf,
automake, libtool, pkgconf, perl).
- Add 7za-win target: downloads 7za.exe to PKG_ROOT_PATH\bin.
- Remove php-sdk-binary-tools target and all PHP_SDK_PATH references;
replace with SPC_MSYS2_PATH throughout Artifact, ArtifactExtractor,
FileSystem, DefaultShell and MSVCToolchain.
- Replace {php_sdk_path} path placeholder with {spc_msys2_path}.
- WindowsToolCheck: replace checkSDK/installSDK with checkMsys2,
installMsys2 and check7zaWin/install7zaWin fix items.
- nasm.yml: extract nasm.exe/ndisasm.exe to {pkg_root_path}/bin.
- env.ini: rename PHP_SDK_PATH to SPC_MSYS2_PATH.
- Docs: update Windows migration guide and package-model placeholder docs.
This commit is contained in:
@@ -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
|
||||
|
||||
5
config/pkg/target/7za-win.yml
Normal file
5
config/pkg/target/7za-win.yml
Normal file
@@ -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
config/pkg/target/msys2-build-essentials.yml
Normal file
8
config/pkg/target/msys2-build-essentials.yml
Normal file
@@ -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,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' } }
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
php-sdk-binary-tools:
|
||||
type: target
|
||||
artifact:
|
||||
binary:
|
||||
windows-x86_64: { type: git, rev: master, url: 'https://github.com/php/php-sdk-binary-tools.git', extract: '{php_sdk_path}' }
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 包类型
|
||||
|
||||
|
||||
@@ -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 构建环境的配置。
|
||||
:::
|
||||
|
||||
## 已重命名 / 已弃用的选项
|
||||
|
||||
|
||||
93
src/Package/Artifact/msys2_build_essentials.php
Normal file
93
src/Package/Artifact/msys2_build_essentials.php
Normal file
@@ -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'];
|
||||
|
||||
#[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");
|
||||
}
|
||||
}
|
||||
@@ -644,7 +644,7 @@ class Artifact
|
||||
'{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,
|
||||
|
||||
@@ -614,7 +614,7 @@ class ArtifactExtractor
|
||||
'{source_path}' => SOURCE_PATH,
|
||||
'{download_path}' => DOWNLOAD_PATH,
|
||||
'{working_dir}' => WORKING_DIR,
|
||||
'{php_sdk_path}' => getenv('PHP_SDK_PATH') ?: '',
|
||||
'{spc_msys2_path}' => getenv('SPC_MSYS2_PATH') ?: '',
|
||||
];
|
||||
return str_replace(array_keys($replacement), array_values($replacement), $path);
|
||||
}
|
||||
|
||||
@@ -76,9 +76,10 @@ class DownloadResult
|
||||
?string $version = null,
|
||||
array $metadata = [],
|
||||
?string $downloader = null,
|
||||
mixed $extract = null,
|
||||
): DownloadResult {
|
||||
$cache_type = self::isArchiveFile($filename) ? 'archive' : 'file';
|
||||
return new self($cache_type, config: $config, filename: $filename, verified: $verified, version: $version, metadata: $metadata, downloader: $downloader);
|
||||
return new self($cache_type, config: $config, filename: $filename, extract: $extract, verified: $verified, version: $version, metadata: $metadata, downloader: $downloader);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,13 +54,24 @@ class WindowsToolCheck
|
||||
return CheckResult::ok();
|
||||
}
|
||||
|
||||
#[CheckItem('if php-sdk-binary-tools are downloaded', limit_os: 'Windows', level: 996)]
|
||||
public function checkSDK(): ?CheckResult
|
||||
#[CheckItem('if msys2-build-essentials is installed', limit_os: 'Windows', level: 996)]
|
||||
public function checkMsys2(): ?CheckResult
|
||||
{
|
||||
if (!file_exists(getenv('PHP_SDK_PATH') . DIRECTORY_SEPARATOR . 'phpsdk-starter.bat')) {
|
||||
return CheckResult::fail('php-sdk-binary-tools not downloaded', 'install-php-sdk');
|
||||
$marker = PKG_ROOT_PATH . '\msys2-build-essentials\.spc-msys2-initialized';
|
||||
if (!file_exists($marker)) {
|
||||
return CheckResult::fail('msys2-build-essentials not installed', 'install-msys2-build-essentials');
|
||||
}
|
||||
return CheckResult::ok(getenv('PHP_SDK_PATH'));
|
||||
return CheckResult::ok(PKG_ROOT_PATH . '\msys2-build-essentials\msys64');
|
||||
}
|
||||
|
||||
#[CheckItem('if 7za.exe is installed', limit_os: 'Windows', level: 999)]
|
||||
public function check7zaWin(): ?CheckResult
|
||||
{
|
||||
$path = FileSystem::convertPath(PKG_ROOT_PATH . '\bin\7za.exe');
|
||||
if (!file_exists($path)) {
|
||||
return CheckResult::fail('7za.exe not found', 'install-7za-win');
|
||||
}
|
||||
return CheckResult::ok($path);
|
||||
}
|
||||
|
||||
#[CheckItem('if nasm installed', level: 995)]
|
||||
@@ -112,12 +123,20 @@ class WindowsToolCheck
|
||||
return true;
|
||||
}
|
||||
|
||||
#[FixItem('install-php-sdk')]
|
||||
public function installSDK(): bool
|
||||
#[FixItem('install-msys2-build-essentials')]
|
||||
public function installMsys2(): bool
|
||||
{
|
||||
FileSystem::removeDir(getenv('PHP_SDK_PATH'));
|
||||
$installer = new PackageInstaller(interactive: false);
|
||||
$installer->addInstallPackage('php-sdk-binary-tools');
|
||||
$installer->addInstallPackage('msys2-build-essentials');
|
||||
$installer->run(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
#[FixItem('install-7za-win')]
|
||||
public function install7zaWin(): bool
|
||||
{
|
||||
$installer = new PackageInstaller(interactive: false);
|
||||
$installer->addInstallPackage('7za-win');
|
||||
$installer->run(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -184,12 +184,14 @@ class DefaultShell extends Shell
|
||||
*/
|
||||
public function execute7zExtract(string $archive_path, string $target_path): bool
|
||||
{
|
||||
$sdk_path = getenv('PHP_SDK_PATH');
|
||||
if ($sdk_path === false) {
|
||||
throw new SPCInternalException('PHP_SDK_PATH environment variable is not set');
|
||||
// 7za.exe is installed by the 7za-win target package into PKG_ROOT_PATH\bin,
|
||||
// which is added to PATH by MSVCToolchain::initEnv().
|
||||
$_7z_path = FileSystem::convertPath(PKG_ROOT_PATH . '\bin\7za.exe');
|
||||
if (!file_exists($_7z_path)) {
|
||||
throw new SPCInternalException('7za.exe not found. Please install the 7za-win target package.');
|
||||
}
|
||||
|
||||
$_7z = escapeshellarg(FileSystem::convertPath($sdk_path . '/bin/7za.exe'));
|
||||
$_7z = escapeshellarg(FileSystem::convertPath($_7z_path));
|
||||
$archive_arg = escapeshellarg(FileSystem::convertPath($archive_path));
|
||||
$target_arg = escapeshellarg(FileSystem::convertPath($target_path));
|
||||
|
||||
|
||||
@@ -14,10 +14,14 @@ class MSVCToolchain implements ToolchainInterface
|
||||
public function initEnv(): void
|
||||
{
|
||||
GlobalEnvManager::addPathIfNotExists(PKG_ROOT_PATH . '\bin');
|
||||
$sdk = getenv('PHP_SDK_PATH');
|
||||
if ($sdk !== false) {
|
||||
GlobalEnvManager::addPathIfNotExists($sdk . '\bin');
|
||||
GlobalEnvManager::addPathIfNotExists($sdk . '\msys2\usr\bin');
|
||||
// msys2-build-essentials: add MSYS2 usr\bin to PATH so that 7za.exe, make, autoconf, etc. are available.
|
||||
// This must be done here because msys2-build-essentials is not a dependency of any library package,
|
||||
// so its path@windows entries are not automatically applied by the package installer at runtime.
|
||||
$msys2_path = getenv('SPC_MSYS2_PATH') ?: (PKG_ROOT_PATH . '\msys2-build-essentials\msys64');
|
||||
if (is_dir($msys2_path)) {
|
||||
GlobalEnvManager::putenv("SPC_MSYS2_PATH={$msys2_path}");
|
||||
GlobalEnvManager::addPathIfNotExists($msys2_path . '\usr\bin');
|
||||
GlobalEnvManager::addPathIfNotExists("{$msys2_path}\\usr\\lib\\p7zip");
|
||||
}
|
||||
// strawberry-perl
|
||||
if (is_dir(PKG_ROOT_PATH . '\strawberry-perl')) {
|
||||
|
||||
@@ -411,7 +411,7 @@ class FileSystem
|
||||
$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',
|
||||
'{spc_msys2_path}' => getenv('SPC_MSYS2_PATH') ?: (PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'msys2-build-essentials' . DIRECTORY_SEPARATOR . 'msys64'),
|
||||
'{working_dir}' => WORKING_DIR,
|
||||
'{download_path}' => DOWNLOAD_PATH,
|
||||
'{source_path}' => SOURCE_PATH,
|
||||
|
||||
Reference in New Issue
Block a user