2023-07-17 20:26:48 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace SPC\doctor\item;
|
|
|
|
|
|
|
|
|
|
use SPC\builder\linux\SystemUtil;
|
|
|
|
|
use SPC\builder\traits\UnixSystemUtilTrait;
|
|
|
|
|
use SPC\doctor\AsCheckItem;
|
|
|
|
|
use SPC\doctor\AsFixItem;
|
|
|
|
|
use SPC\doctor\CheckResult;
|
|
|
|
|
use SPC\exception\RuntimeException;
|
|
|
|
|
|
|
|
|
|
class LinuxToolCheckList
|
|
|
|
|
{
|
|
|
|
|
use UnixSystemUtilTrait;
|
|
|
|
|
|
2023-07-17 21:11:06 +08:00
|
|
|
public const TOOLS_ALPINE = [
|
2023-09-18 13:43:58 +02:00
|
|
|
'make', 'bison', 'flex',
|
2025-03-10 09:01:54 +01:00
|
|
|
'git', 'autoconf', 'automake', 'gettext-dev',
|
2023-07-17 21:11:06 +08:00
|
|
|
'tar', 'unzip', 'gzip',
|
|
|
|
|
'bzip2', 'cmake', 'gcc',
|
2023-10-19 18:28:36 +02:00
|
|
|
'g++', 'patch', 'binutils-gold',
|
2025-06-06 23:51:58 +07:00
|
|
|
'libtoolize', 'which',
|
2025-06-12 20:19:21 +07:00
|
|
|
'patchelf',
|
2023-07-17 21:11:06 +08:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
public const TOOLS_DEBIAN = [
|
2023-09-18 13:43:58 +02:00
|
|
|
'make', 'bison', 'flex',
|
2025-03-10 09:01:54 +01:00
|
|
|
'git', 'autoconf', 'automake', 'autopoint',
|
2023-07-17 21:11:06 +08:00
|
|
|
'tar', 'unzip', 'gzip',
|
|
|
|
|
'bzip2', 'cmake', 'patch',
|
2025-06-06 23:51:58 +07:00
|
|
|
'xz', 'libtoolize', 'which',
|
2025-06-12 20:19:21 +07:00
|
|
|
'patchelf',
|
2023-07-17 21:11:06 +08:00
|
|
|
];
|
|
|
|
|
|
2023-09-18 13:43:58 +02:00
|
|
|
public const TOOLS_RHEL = [
|
|
|
|
|
'perl', 'make', 'bison', 'flex',
|
|
|
|
|
'git', 'autoconf', 'automake',
|
|
|
|
|
'tar', 'unzip', 'gzip', 'gcc',
|
2025-06-06 23:51:58 +07:00
|
|
|
'bzip2', 'cmake', 'patch', 'which',
|
2025-03-14 15:25:51 +08:00
|
|
|
'xz', 'libtool', 'gettext-devel',
|
2025-06-12 20:19:21 +07:00
|
|
|
'perl', 'patchelf',
|
2023-09-18 13:43:58 +02:00
|
|
|
];
|
|
|
|
|
|
2024-04-13 16:12:05 +08:00
|
|
|
public const TOOLS_ARCH = [
|
|
|
|
|
'base-devel', 'cmake',
|
|
|
|
|
];
|
|
|
|
|
|
2024-03-15 20:14:04 +01:00
|
|
|
private const PROVIDED_COMMAND = [
|
|
|
|
|
'binutils-gold' => 'ld.gold',
|
2024-04-13 16:12:05 +08:00
|
|
|
'base-devel' => 'automake',
|
2025-05-25 17:26:48 +07:00
|
|
|
'gettext-devel' => 'gettextize',
|
2024-03-15 20:14:04 +01:00
|
|
|
];
|
|
|
|
|
|
2023-08-20 19:51:45 +08:00
|
|
|
/** @noinspection PhpUnused */
|
2023-09-30 23:18:53 +08:00
|
|
|
#[AsCheckItem('if necessary tools are installed', limit_os: 'Linux', level: 999)]
|
2023-07-17 20:26:48 +08:00
|
|
|
public function checkCliTools(): ?CheckResult
|
|
|
|
|
{
|
|
|
|
|
$distro = SystemUtil::getOSRelease();
|
|
|
|
|
|
|
|
|
|
$required = match ($distro['dist']) {
|
2023-07-17 21:11:06 +08:00
|
|
|
'alpine' => self::TOOLS_ALPINE,
|
2025-01-28 19:37:50 +08:00
|
|
|
'redhat' => self::TOOLS_RHEL,
|
|
|
|
|
'centos' => array_merge(self::TOOLS_RHEL, ['perl-IPC-Cmd']),
|
2024-04-13 16:12:05 +08:00
|
|
|
'arch' => self::TOOLS_ARCH,
|
2023-07-17 21:11:06 +08:00
|
|
|
default => self::TOOLS_DEBIAN,
|
2023-07-17 20:26:48 +08:00
|
|
|
};
|
|
|
|
|
$missing = [];
|
2024-03-15 20:14:04 +01:00
|
|
|
foreach ($required as $package) {
|
|
|
|
|
if ($this->findCommand(self::PROVIDED_COMMAND[$package] ?? $package) === null) {
|
|
|
|
|
$missing[] = $package;
|
2023-07-17 20:26:48 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!empty($missing)) {
|
|
|
|
|
return match ($distro['dist']) {
|
2023-09-18 12:52:12 +02:00
|
|
|
'ubuntu',
|
|
|
|
|
'alpine',
|
2023-10-31 14:56:43 +01:00
|
|
|
'redhat',
|
2025-01-13 20:42:09 +08:00
|
|
|
'centos',
|
2024-01-08 23:34:17 +08:00
|
|
|
'Deepin',
|
2024-04-13 16:12:05 +08:00
|
|
|
'arch',
|
2023-09-18 12:52:12 +02:00
|
|
|
'debian' => CheckResult::fail(implode(', ', $missing) . ' not installed on your system', 'install-linux-tools', [$distro, $missing]),
|
2023-07-17 20:26:48 +08:00
|
|
|
default => CheckResult::fail(implode(', ', $missing) . ' not installed on your system'),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
return CheckResult::ok();
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-02 15:05:49 +08:00
|
|
|
#[AsCheckItem('if cmake version >= 3.18', limit_os: 'Linux')]
|
|
|
|
|
public function checkCMakeVersion(): ?CheckResult
|
|
|
|
|
{
|
2025-06-04 21:18:44 +07:00
|
|
|
$ver = get_cmake_version();
|
|
|
|
|
if ($ver === null) {
|
|
|
|
|
return CheckResult::fail('Failed to get cmake version');
|
|
|
|
|
}
|
|
|
|
|
if (version_compare($ver, '3.18.0') < 0) {
|
|
|
|
|
return CheckResult::fail('cmake version is too low (' . $ver . '), please update it manually!');
|
2024-04-02 15:05:49 +08:00
|
|
|
}
|
2025-06-04 21:18:44 +07:00
|
|
|
return CheckResult::ok($ver);
|
2024-04-02 15:05:49 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-20 19:51:45 +08:00
|
|
|
/** @noinspection PhpUnused */
|
2024-01-08 23:34:17 +08:00
|
|
|
#[AsCheckItem('if necessary linux headers are installed', limit_os: 'Linux')]
|
2023-07-17 20:58:48 +08:00
|
|
|
public function checkSystemOSPackages(): ?CheckResult
|
|
|
|
|
{
|
2023-10-31 14:56:43 +01:00
|
|
|
if (SystemUtil::isMuslDist()) {
|
2023-07-17 20:58:48 +08:00
|
|
|
// check linux-headers installation
|
|
|
|
|
if (!file_exists('/usr/include/linux/mman.h')) {
|
2023-10-31 14:56:43 +01:00
|
|
|
return CheckResult::fail('linux-headers not installed on your system', 'install-linux-tools', [SystemUtil::getOSRelease(), ['linux-headers']]);
|
2023-07-17 20:58:48 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return CheckResult::ok();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-20 19:51:45 +08:00
|
|
|
/**
|
|
|
|
|
* @throws RuntimeException
|
|
|
|
|
* @noinspection PhpUnused
|
|
|
|
|
*/
|
2023-07-17 20:26:48 +08:00
|
|
|
#[AsFixItem('install-linux-tools')]
|
|
|
|
|
public function fixBuildTools(array $distro, array $missing): bool
|
|
|
|
|
{
|
|
|
|
|
$install_cmd = match ($distro['dist']) {
|
2024-01-08 23:34:17 +08:00
|
|
|
'ubuntu', 'debian', 'Deepin' => 'apt-get install -y',
|
2023-07-17 20:26:48 +08:00
|
|
|
'alpine' => 'apk add',
|
2023-10-31 14:56:43 +01:00
|
|
|
'redhat' => 'dnf install -y',
|
2025-01-13 20:42:09 +08:00
|
|
|
'centos' => 'yum install -y',
|
2024-04-13 16:12:05 +08:00
|
|
|
'arch' => 'pacman -S --noconfirm',
|
2023-09-18 12:52:12 +02:00
|
|
|
default => throw new RuntimeException('Current linux distro does not have an auto-install script for musl packages yet.'),
|
2023-07-17 20:26:48 +08:00
|
|
|
};
|
|
|
|
|
$prefix = '';
|
2025-01-13 20:42:09 +08:00
|
|
|
if (($user = exec('whoami')) !== 'root') {
|
2023-07-17 20:26:48 +08:00
|
|
|
$prefix = 'sudo ';
|
2025-01-13 20:42:09 +08:00
|
|
|
logger()->warning('Current user (' . $user . ') is not root, using sudo for running command');
|
2023-07-17 20:26:48 +08:00
|
|
|
}
|
|
|
|
|
try {
|
2024-01-08 23:34:17 +08:00
|
|
|
$is_debian = in_array($distro['dist'], ['debian', 'ubuntu', 'Deepin']);
|
2023-10-31 14:56:43 +01:00
|
|
|
$to_install = $is_debian ? str_replace('xz', 'xz-utils', $missing) : $missing;
|
2023-12-10 18:27:19 +08:00
|
|
|
// debian, alpine libtool -> libtoolize
|
|
|
|
|
$to_install = str_replace('libtoolize', 'libtool', $to_install);
|
2023-09-18 12:52:12 +02:00
|
|
|
shell(true)->exec($prefix . $install_cmd . ' ' . implode(' ', $to_install));
|
2023-07-17 20:26:48 +08:00
|
|
|
} catch (RuntimeException) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|