2025-11-30 15:35:04 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace StaticPHP\Toolchain;
|
|
|
|
|
|
2025-12-11 11:35:12 +08:00
|
|
|
use StaticPHP\Exception\EnvironmentException;
|
2025-11-30 15:35:04 +08:00
|
|
|
use StaticPHP\Toolchain\Interface\ToolchainInterface;
|
2025-12-11 11:35:12 +08:00
|
|
|
use StaticPHP\Util\GlobalEnvManager;
|
|
|
|
|
use StaticPHP\Util\System\WindowsUtil;
|
2025-11-30 15:35:04 +08:00
|
|
|
|
|
|
|
|
class MSVCToolchain implements ToolchainInterface
|
|
|
|
|
{
|
2025-12-11 11:35:12 +08:00
|
|
|
public function initEnv(): void
|
|
|
|
|
{
|
|
|
|
|
GlobalEnvManager::addPathIfNotExists(PKG_ROOT_PATH . '\bin');
|
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.
2026-06-21 16:56:40 +08:00
|
|
|
// 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");
|
2025-12-11 11:35:12 +08:00
|
|
|
}
|
|
|
|
|
// strawberry-perl
|
|
|
|
|
if (is_dir(PKG_ROOT_PATH . '\strawberry-perl')) {
|
|
|
|
|
GlobalEnvManager::addPathIfNotExists(PKG_ROOT_PATH . '\strawberry-perl\perl\bin');
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-30 15:35:04 +08:00
|
|
|
|
2025-12-11 11:35:12 +08:00
|
|
|
public function afterInit(): void
|
|
|
|
|
{
|
|
|
|
|
$count = count(getenv());
|
|
|
|
|
$vs = WindowsUtil::findVisualStudio();
|
|
|
|
|
if ($vs === false || !file_exists($vcvarsall = "{$vs['dir']}\\VC\\Auxiliary\\Build\\vcvarsall.bat")) {
|
|
|
|
|
throw new EnvironmentException(
|
|
|
|
|
'Visual Studio with C++ tools not found',
|
|
|
|
|
'Please install Visual Studio with C++ tools'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (getenv('VCINSTALLDIR') === false) {
|
|
|
|
|
if (file_exists(DOWNLOAD_PATH . '/.vcenv-cache') && (time() - filemtime(DOWNLOAD_PATH . '/.vcenv-cache')) < 3600) {
|
|
|
|
|
$output = file(DOWNLOAD_PATH . '/.vcenv-cache', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
|
|
|
} else {
|
|
|
|
|
exec('call "' . $vcvarsall . '" x64 > NUL && set', $output);
|
|
|
|
|
file_put_contents(DOWNLOAD_PATH . '/.vcenv-cache', implode("\n", $output));
|
|
|
|
|
}
|
|
|
|
|
array_map(fn ($x) => putenv($x), $output);
|
|
|
|
|
}
|
|
|
|
|
$after = count(getenv());
|
|
|
|
|
if ($after > $count) {
|
|
|
|
|
logger()->debug('Applied ' . ($after - $count) . ' environment variables from Visual Studio setup');
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-11-30 15:35:04 +08:00
|
|
|
|
|
|
|
|
public function getCompilerInfo(): ?string
|
|
|
|
|
{
|
2025-12-11 11:35:12 +08:00
|
|
|
if ($vcver = getenv('VisualStudioVersion')) {
|
|
|
|
|
return "Visual Studio {$vcver}";
|
|
|
|
|
}
|
2025-11-30 15:35:04 +08:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function isStatic(): bool
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|