mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-19 06:45:35 +08:00
Refactor WindowsUtil to cache Visual Studio search results and add CMake find modules
This commit is contained in:
@@ -8,8 +8,10 @@ use StaticPHP\Util\FileSystem;
|
|||||||
|
|
||||||
class WindowsUtil
|
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 string $name command name (xxx.exe)
|
||||||
* @param array $paths search path (default use env path)
|
* @param array $paths search path (default use env path)
|
||||||
@@ -39,6 +41,10 @@ class WindowsUtil
|
|||||||
*/
|
*/
|
||||||
public static function findVisualStudio(): array|false
|
public static function findVisualStudio(): array|false
|
||||||
{
|
{
|
||||||
|
if (self::$vsCache !== null) {
|
||||||
|
return self::$vsCache;
|
||||||
|
}
|
||||||
|
|
||||||
// call vswhere (need VS and C++ tools installed), output is json
|
// call vswhere (need VS and C++ tools installed), output is json
|
||||||
$vswhere_exec = PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'vswhere.exe';
|
$vswhere_exec = PKG_ROOT_PATH . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'vswhere.exe';
|
||||||
$args = [
|
$args = [
|
||||||
@@ -49,13 +55,13 @@ class WindowsUtil
|
|||||||
$cmd = escapeshellarg($vswhere_exec) . ' ' . implode(' ', $args);
|
$cmd = escapeshellarg($vswhere_exec) . ' ' . implode(' ', $args);
|
||||||
$result = f_exec($cmd, $out, $code);
|
$result = f_exec($cmd, $out, $code);
|
||||||
if ($code !== 0 || !$result) {
|
if ($code !== 0 || !$result) {
|
||||||
return false;
|
return self::$vsCache = false;
|
||||||
}
|
}
|
||||||
$json = json_decode(implode("\n", $out), true);
|
$json = json_decode(implode("\n", $out), true);
|
||||||
if (!is_array($json) || count($json) === 0) {
|
if (!is_array($json) || count($json) === 0) {
|
||||||
return false;
|
return self::$vsCache = false;
|
||||||
}
|
}
|
||||||
return [
|
return self::$vsCache = [
|
||||||
'version' => $json[0]['installationVersion'],
|
'version' => $json[0]['installationVersion'],
|
||||||
'major_version' => explode('.', $json[0]['installationVersion'])[0],
|
'major_version' => explode('.', $json[0]['installationVersion'])[0],
|
||||||
'dir' => $json[0]['installationPath'],
|
'dir' => $json[0]['installationPath'],
|
||||||
@@ -89,6 +95,7 @@ class WindowsUtil
|
|||||||
$ldflags = '/nodefaultlib:msvcrt /nodefaultlib:msvcrtd /defaultlib:libcmt';
|
$ldflags = '/nodefaultlib:msvcrt /nodefaultlib:msvcrtd /defaultlib:libcmt';
|
||||||
}
|
}
|
||||||
$buildroot = str_replace('\\', '\\\\', BUILD_ROOT_PATH);
|
$buildroot = str_replace('\\', '\\\\', BUILD_ROOT_PATH);
|
||||||
|
$source = str_replace('\\', '/', SOURCE_PATH);
|
||||||
$toolchain = <<<CMAKE
|
$toolchain = <<<CMAKE
|
||||||
set(CMAKE_SYSTEM_NAME Windows)
|
set(CMAKE_SYSTEM_NAME Windows)
|
||||||
SET(CMAKE_SYSTEM_PROCESSOR x64)
|
SET(CMAKE_SYSTEM_PROCESSOR x64)
|
||||||
@@ -99,11 +106,50 @@ SET(CMAKE_CXX_FLAGS_DEBUG "{$cflags}")
|
|||||||
SET(CMAKE_EXE_LINKER_FLAGS "{$ldflags}")
|
SET(CMAKE_EXE_LINKER_FLAGS "{$ldflags}")
|
||||||
SET(CMAKE_FIND_ROOT_PATH "{$buildroot}")
|
SET(CMAKE_FIND_ROOT_PATH "{$buildroot}")
|
||||||
SET(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
|
SET(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded)
|
||||||
|
list(PREPEND CMAKE_MODULE_PATH "{$source}/cmake-find")
|
||||||
CMAKE;
|
CMAKE;
|
||||||
if (!is_dir(SOURCE_PATH)) {
|
if (!is_dir(SOURCE_PATH)) {
|
||||||
FileSystem::createDir(SOURCE_PATH);
|
FileSystem::createDir(SOURCE_PATH);
|
||||||
}
|
}
|
||||||
FileSystem::writeFile(SOURCE_PATH . '\toolchain.cmake', $toolchain);
|
FileSystem::writeFile(SOURCE_PATH . '\toolchain.cmake', $toolchain);
|
||||||
|
self::writeCmakeFindModules();
|
||||||
return realpath(SOURCE_PATH . '\toolchain.cmake');
|
return realpath(SOURCE_PATH . '\toolchain.cmake');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write cmake-find wrapper modules to source/cmake-find/.
|
||||||
|
* These override cmake's built-in Find*.cmake modules to inject
|
||||||
|
* Windows-specific static library dependencies (e.g. zlib into OpenSSL).
|
||||||
|
* Called both from makeCmakeToolchainFile() and from WindowsCMakeExecutor
|
||||||
|
* so the modules are always present even when the static toolchain.cmake
|
||||||
|
* file is used directly without regeneration.
|
||||||
|
*/
|
||||||
|
public static function writeCmakeFindModules(): void
|
||||||
|
{
|
||||||
|
$cmake_find_dir = SOURCE_PATH . DIRECTORY_SEPARATOR . 'cmake-find';
|
||||||
|
if (!is_dir($cmake_find_dir)) {
|
||||||
|
FileSystem::createDir($cmake_find_dir);
|
||||||
|
}
|
||||||
|
FileSystem::writeFile($cmake_find_dir . DIRECTORY_SEPARATOR . 'FindOpenSSL.cmake', <<<'CMAKE'
|
||||||
|
# Custom FindOpenSSL.cmake wrapper for static-php-cli Windows builds.
|
||||||
|
|
||||||
|
if(WIN32 AND (OpenSSL_FOUND OR OPENSSL_FOUND))
|
||||||
|
list(GET CMAKE_FIND_ROOT_PATH 0 _spc_buildroot)
|
||||||
|
# Normalize to forward slashes — backslash paths cause 'Invalid character
|
||||||
|
# escape' errors when cmake parses them inside string arguments.
|
||||||
|
file(TO_CMAKE_PATH "${_spc_buildroot}" _spc_buildroot)
|
||||||
|
set(_spc_zlib "${_spc_buildroot}/lib/zlibstatic.lib")
|
||||||
|
if(EXISTS "${_spc_zlib}")
|
||||||
|
foreach(_spc_var OPENSSL_LIBRARIES OPENSSL_CRYPTO_LIBRARIES OPENSSL_SSL_LIBRARIES)
|
||||||
|
if(DEFINED ${_spc_var} AND NOT "${_spc_zlib}" IN_LIST ${_spc_var})
|
||||||
|
list(APPEND ${_spc_var} "${_spc_zlib}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
unset(_spc_buildroot)
|
||||||
|
unset(_spc_zlib)
|
||||||
|
unset(_spc_var)
|
||||||
|
endif()
|
||||||
|
CMAKE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user