From 631a1b586497558e6fd89d56fa01ddaa60f391dd Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 30 Mar 2025 20:16:41 +0800 Subject: [PATCH] Add libc version for pre-built content name --- config/pre-built.json | 2 +- src/SPC/builder/LibraryBase.php | 2 +- src/SPC/builder/linux/SystemUtil.php | 31 +++++++++++++++++++++++ src/SPC/command/DeleteDownloadCommand.php | 2 +- src/SPC/command/DownloadCommand.php | 2 ++ src/SPC/command/dev/PackLibCommand.php | 3 +++ src/SPC/store/Downloader.php | 6 ++--- src/SPC/store/SourceManager.php | 2 +- 8 files changed, 43 insertions(+), 7 deletions(-) diff --git a/config/pre-built.json b/config/pre-built.json index 1f1803f8..829023c7 100644 --- a/config/pre-built.json +++ b/config/pre-built.json @@ -1,7 +1,7 @@ { "repo": "static-php/static-php-cli-hosted", "prefer-stable": true, - "match-pattern-linux": "{name}-{arch}-{os}-{libc}.txz", + "match-pattern-linux": "{name}-{arch}-{os}-{libc}-{libcver}.txz", "match-pattern": "{name}-{arch}-{os}.txz", "suffix": "txz" } \ No newline at end of file diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 165e4f13..5ac43508 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -46,7 +46,7 @@ abstract class LibraryBase $lock = json_decode(FileSystem::readFile(DOWNLOAD_PATH . '/.lock.json'), true) ?? []; $source = Config::getLib(static::NAME, 'source'); // if source is locked as pre-built, we just tryInstall it - $pre_built_name = Downloader::getPreBuiltName($source); + $pre_built_name = Downloader::getPreBuiltLockName($source); if (isset($lock[$pre_built_name]) && ($lock[$pre_built_name]['lock_as'] ?? SPC_DOWN_SOURCE) === SPC_DOWN_PRE_BUILT) { return $this->tryInstall($lock[$pre_built_name]['filename'], $force); } diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index c0ae6766..a2efe9bb 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -182,4 +182,35 @@ class SystemUtil 'arch', 'manjaro', ]; } + + /** + * Get libc version string from ldd + */ + public static function getLibcVersionIfExists(): ?string + { + if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'glibc') { + $result = shell()->execWithResult('ldd --version'); + if ($result[0] !== 0) { + return null; + } + // get first line + $first_line = $result[1][0]; + // match ldd version: "ldd (some useless text) 2.17" match 2.17 + $pattern = '/ldd\s+\(.*?\)\s+(\d+\.\d+)/'; + if (preg_match($pattern, $first_line, $matches)) { + return $matches[1]; + } + return null; + } + if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') { + $result = shell()->execWithResult('ldd 2>&1'); + // Match Version * line + // match ldd version: "Version 1.2.3" match 1.2.3 + $pattern = '/Version\s+(\d+\.\d+\.\d+)/'; + if (preg_match($pattern, $result[1][1], $matches)) { + return $matches[1]; + } + } + return null; + } } diff --git a/src/SPC/command/DeleteDownloadCommand.php b/src/SPC/command/DeleteDownloadCommand.php index 1471451c..b68b8618 100644 --- a/src/SPC/command/DeleteDownloadCommand.php +++ b/src/SPC/command/DeleteDownloadCommand.php @@ -51,7 +51,7 @@ class DeleteDownloadCommand extends BaseCommand $deleted_sources = []; foreach ($chosen_sources as $source) { $source = trim($source); - foreach ([$source, Downloader::getPreBuiltName($source)] as $name) { + foreach ([$source, Downloader::getPreBuiltLockName($source)] as $name) { if (isset($lock[$name])) { $deleted_sources[] = $name; } diff --git a/src/SPC/command/DownloadCommand.php b/src/SPC/command/DownloadCommand.php index 85a01b56..9a7f6310 100644 --- a/src/SPC/command/DownloadCommand.php +++ b/src/SPC/command/DownloadCommand.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace SPC\command; +use SPC\builder\linux\SystemUtil; use SPC\builder\traits\UnixSystemUtilTrait; use SPC\exception\DownloaderException; use SPC\exception\FileSystemException; @@ -236,6 +237,7 @@ class DownloadCommand extends BaseCommand '{arch}' => arch2gnu(php_uname('m')), '{os}' => strtolower(PHP_OS_FAMILY), '{libc}' => getenv('SPC_LIBC') ?: 'default', + '{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default', ]; $find = str_replace(array_keys($replace), array_values($replace), Config::getPreBuilt('match-pattern')); // find filename in asset list diff --git a/src/SPC/command/dev/PackLibCommand.php b/src/SPC/command/dev/PackLibCommand.php index 340736d5..c10c62f3 100644 --- a/src/SPC/command/dev/PackLibCommand.php +++ b/src/SPC/command/dev/PackLibCommand.php @@ -6,6 +6,7 @@ namespace SPC\command\dev; use SPC\builder\BuilderProvider; use SPC\builder\LibraryBase; +use SPC\builder\linux\SystemUtil; use SPC\command\BuildCommand; use SPC\exception\ExceptionHandler; use SPC\exception\FileSystemException; @@ -23,6 +24,7 @@ class PackLibCommand extends BuildCommand public function configure(): void { $this->addArgument('library', InputArgument::REQUIRED, 'The library will be compiled'); + $this->addOption('show-libc-ver', null, null); } public function handle(): int @@ -75,6 +77,7 @@ class PackLibCommand extends BuildCommand '{arch}' => arch2gnu(php_uname('m')), '{os}' => strtolower(PHP_OS_FAMILY), '{libc}' => getenv('SPC_LIBC') ?: 'default', + '{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default', ]; $filename = str_replace(array_keys($replace), array_values($replace), $filename); $filename = WORKING_DIR . '/dist/' . $filename . '.' . Config::getPreBuilt('suffix'); diff --git a/src/SPC/store/Downloader.php b/src/SPC/store/Downloader.php index 66a47b45..f133f404 100644 --- a/src/SPC/store/Downloader.php +++ b/src/SPC/store/Downloader.php @@ -204,7 +204,7 @@ class Downloader self::unregisterCancelEvent(); logger()->debug("Locking {$filename}"); if ($download_as === SPC_DOWN_PRE_BUILT) { - $name = self::getPreBuiltName($name); + $name = self::getPreBuiltLockName($name); } self::lockSource($name, ['source_type' => 'archive', 'filename' => $filename, 'move_path' => $move_path, 'lock_as' => $download_as]); } @@ -594,7 +594,7 @@ class Downloader } } - public static function getPreBuiltName(string $source): string + public static function getPreBuiltLockName(string $source): string { return "{$source}-" . PHP_OS_FAMILY . '-' . getenv('GNU_ARCH') . '-' . (getenv('SPC_LIBC') ?: 'default'); } @@ -653,7 +653,7 @@ class Downloader } } // If lock file exists for current arch and glibc target, skip downloading - $lock_name = self::getPreBuiltName($name); + $lock_name = self::getPreBuiltLockName($name); if (!$force && $download_as === SPC_DOWN_PRE_BUILT && isset($lock[$lock_name])) { // lock name with env if ( diff --git a/src/SPC/store/SourceManager.php b/src/SPC/store/SourceManager.php index b18a47be..c36bfc58 100644 --- a/src/SPC/store/SourceManager.php +++ b/src/SPC/store/SourceManager.php @@ -55,7 +55,7 @@ class SourceManager throw new WrongUsageException("Source [{$source}] does not exist, please check the name and correct it !"); } // check source downloaded - $pre_built_name = Downloader::getPreBuiltName($source); + $pre_built_name = Downloader::getPreBuiltLockName($source); if (!isset($lock[$pre_built_name])) { if (!isset($lock[$source])) { throw new WrongUsageException("Source [{$source}] not downloaded or not locked, you should download it first !");