Add windows php cli builds, support micro patches

This commit is contained in:
crazywhalecc
2025-12-11 13:49:32 +08:00
parent 48fbeab7e4
commit 7c8b40a49a
4 changed files with 80 additions and 443 deletions

View File

@@ -99,7 +99,7 @@ class PackageBuilder
// ignore copy to self
if (realpath($src) !== realpath($dst)) {
shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg($dst));
FileSystem::copy($src, $dst);
}
// file exist
@@ -111,7 +111,7 @@ class PackageBuilder
$this->extractDebugInfo($dst);
// strip
if (!$this->getOption('no-strip')) {
if (!$this->getOption('no-strip') && SystemTarget::isUnix()) {
$this->stripBinary($dst);
}
@@ -123,6 +123,9 @@ class PackageBuilder
}
logger()->info("Compressing {$dst} with UPX");
shell()->exec(getenv('UPX_EXEC') . " --best {$dst}");
} elseif ($upx_option && SystemTarget::getTargetOS() === 'Windows' && $executable) {
logger()->info("Compressing {$dst} with UPX");
shell()->exec(getenv('UPX_EXEC') . ' --best ' . escapeshellarg($dst));
}
return $dst;
@@ -136,12 +139,13 @@ class PackageBuilder
public function extractDebugInfo(string $binary_path): string
{
$target_dir = BUILD_ROOT_PATH . '/debug';
FileSystem::createDir($target_dir);
$basename = basename($binary_path);
$debug_file = "{$target_dir}/{$basename}" . (SystemTarget::getTargetOS() === 'Darwin' ? '.dwarf' : '.debug');
if (SystemTarget::getTargetOS() === 'Darwin') {
FileSystem::createDir($target_dir);
shell()->exec("dsymutil -f {$binary_path} -o {$debug_file}");
} elseif (SystemTarget::getTargetOS() === 'Linux') {
FileSystem::createDir($target_dir);
if ($eu_strip = LinuxUtil::findCommand('eu-strip')) {
shell()
->exec("{$eu_strip} -f {$debug_file} {$binary_path}")
@@ -152,7 +156,8 @@ class PackageBuilder
->exec("objcopy --add-gnu-debuglink={$debug_file} {$binary_path}");
}
} else {
throw new SPCInternalException('extractDebugInfo is only supported on Linux and macOS');
logger()->debug('extractDebugInfo is only supported on Linux and macOS');
return '';
}
return $debug_file;
}

View File

@@ -151,9 +151,6 @@ abstract class Shell
bool $throw_on_error = true,
?string $cwd = null
): array {
if ($cwd !== null) {
$cwd = $cwd;
}
$file_res = null;
if ($this->enable_log_file) {
// write executed command to the log file using fwrite

View File

@@ -6,6 +6,7 @@ namespace StaticPHP\Util;
use StaticPHP\Attribute\PatchDescription;
use StaticPHP\Exception\PatchException;
use StaticPHP\Registry\PackageLoader;
/**
* SourcePatcher provides static utility methods for patching source files.
@@ -194,4 +195,69 @@ class SourcePatcher
{
FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/ext/phar/phar.c');
}
public static function patchPhpSrc(?array $items = null): bool
{
$patch_dir = ROOT_DIR . '/src/globals/patch/php-src-patches';
// in phar mode, we need to extract all the patch files
if (str_starts_with($patch_dir, 'phar://')) {
$tmp_dir = sys_get_temp_dir() . '/php-src-patches';
FileSystem::createDir($tmp_dir);
foreach (FileSystem::scanDirFiles($patch_dir) as $file) {
FileSystem::writeFile("{$tmp_dir}/" . basename($file), file_get_contents($file));
}
$patch_dir = $tmp_dir;
}
$php_package = PackageLoader::getTargetPackage('php');
if (!file_exists("{$php_package->getSourceDir()}/sapi/micro/php_micro.c")) {
return false;
}
$ver_file = "{$php_package->getSourceDir()}/main/php_version.h";
if (!file_exists($ver_file)) {
throw new PatchException('php-src patcher (original micro patches)', 'Patch failed, cannot find php source files');
}
$version_h = FileSystem::readFile("{$php_package->getSourceDir()}/main/php_version.h");
preg_match('/#\s*define\s+PHP_MAJOR_VERSION\s+(\d+)\s+#\s*define\s+PHP_MINOR_VERSION\s+(\d+)\s+/m', $version_h, $match);
// $ver = "{$match[1]}.{$match[2]}";
$major_ver = $match[1] . $match[2];
if ($major_ver === '74') {
return false;
}
// $check = !defined('DEBUG_MODE') ? ' -q' : '';
// f_passthru('cd ' . SOURCE_PATH . '/php-src && git checkout' . $check . ' HEAD');
if ($items !== null) {
$spc_micro_patches = $items;
} else {
$spc_micro_patches = getenv('SPC_MICRO_PATCHES');
$spc_micro_patches = $spc_micro_patches === false ? [] : explode(',', $spc_micro_patches);
}
$spc_micro_patches = array_filter($spc_micro_patches, fn ($item) => trim((string) $item) !== '');
$patch_list = $spc_micro_patches;
$patches = [];
$serial = ['80', '81', '82', '83', '84', '85'];
foreach ($patch_list as $patchName) {
if (file_exists("{$patch_dir}/{$patchName}.patch")) {
$patches[] = "{$patch_dir}/{$patchName}.patch";
continue;
}
for ($i = array_search($major_ver, $serial, true); $i >= 0; --$i) {
$tryMajMin = $serial[$i];
if (!file_exists("{$patch_dir}/{$patchName}_{$tryMajMin}.patch")) {
continue;
}
$patches[] = "{$patch_dir}/{$patchName}_{$tryMajMin}.patch";
continue 2;
}
throw new PatchException('phpmicro patches', "Failed finding patch file or versioned file {$patchName} !");
}
foreach ($patches as $patch) {
logger()->info("Patching micro with {$patch}");
self::patchFile($patch, $php_package->getSourceDir());
}
return true;
}
}