use arch-linux-musl toolchains

This commit is contained in:
DubbleClick
2023-10-16 14:09:49 +02:00
parent 46b0ecf3fa
commit 658e8e74bd
3 changed files with 115 additions and 47 deletions

View File

@@ -8,57 +8,122 @@ use SPC\builder\linux\SystemUtil;
use SPC\doctor\AsCheckItem;
use SPC\doctor\AsFixItem;
use SPC\doctor\CheckResult;
use SPC\exception\DownloaderException;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\store\Downloader;
use SPC\store\FileSystem;
class LinuxMuslCheck
{
/** @noinspection PhpUnused */
/**
* @throws WrongUsageException
*/
#[AsCheckItem('if musl-libc is installed', limit_os: 'Linux')]
public function checkMusl(): ?CheckResult
public function checkMusl(): CheckResult
{
$file = sprintf('/lib/ld-musl-%s.so.1', php_uname('m'));
if (file_exists($file)) {
if (SystemUtil::isMuslDist()) {
return CheckResult::ok();
}
// non-exist, need to recognize distro
$distro = SystemUtil::getOSRelease();
return match ($distro['dist']) {
'ubuntu', 'alpine', 'debian', 'rhel', 'almalinux' => CheckResult::fail('musl-libc is not installed on your system', 'fix-musl', [$distro]),
default => CheckResult::fail('musl-libc is not installed on your system'),
};
$arch = arch2gnu(php_uname('m'));
$cross_compile_lib = "/usr/local/musl/{$arch}-linux-musl/lib/libc.a";
$cross_compile_gcc = "/usr/local/musl/bin/{$arch}-linux-musl-gcc";
$musl_wrapper_lib = sprintf('/lib/ld-musl-%s.so.1', php_uname('m'));
if (file_exists($musl_wrapper_lib) && file_exists($cross_compile_lib) && file_exists($cross_compile_gcc)) {
return CheckResult::ok();
}
return CheckResult::fail('musl-libc is not installed on your system', 'fix-musl');
}
/** @noinspection PhpUnused */
/**
* @throws RuntimeException
* @noinspection PhpUnused
* @throws DownloaderException
* @throws FileSystemException
* @throws WrongUsageException
*/
#[AsFixItem('fix-musl')]
public function fixMusl(array $distro): bool
public function fixMusl(): bool
{
$rhel_install = 'wget https://musl.libc.org/releases/musl-1.2.4.tar.gz && tar -zxvf musl-1.2.4.tar.gz && \
rm -f musl-1.2.4.tar.gz && cd musl-1.2.4 &&
if [[ ! "$PATH" =~ (^|:)"/usr/local/musl/bin"(:|$) ]]; then echo "export PATH=/usr/local/musl/bin:$PATH" >> ~/.bash_profile
fi && \
./configure --enable-wrapper=gcc && \
make -j && make install && cd .. && rm -rf musl-1.2.4';
$install_cmd = match ($distro['dist']) {
'ubuntu', 'debian' => 'apt-get install musl musl-tools -y',
'alpine' => 'apk add musl musl-utils musl-dev',
'rhel' => $rhel_install,
'almalinux' => $rhel_install,
default => throw new RuntimeException('Current linux distro does not have an auto-install script for musl packages yet.'),
};
$prefix = '';
if (get_current_user() !== 'root') {
$prefix = 'sudo ';
logger()->warning('Current user is not root, using sudo for running command');
}
$arch = arch2gnu(php_uname('m'));
$musl_wrapper_lib = sprintf('/lib/ld-musl-%s.so.1', php_uname('m'));
$cross_compile_lib = "/usr/local/musl/{$arch}-linux-musl/lib/libc.a";
$cross_compile_gcc = "/usr/local/musl/bin/{$arch}-linux-musl-gcc";
try {
shell(true)->exec($prefix . $install_cmd);
if (!file_exists(DOWNLOAD_PATH)) {
FileSystem::createDir(DOWNLOAD_PATH);
}
if (!file_exists($musl_wrapper_lib)) {
$this->installMuslWrapper();
}
if (!file_exists($cross_compile_lib) || !file_exists($cross_compile_gcc)) {
$this->installMuslCrossMake();
}
$prefix = '';
if (get_current_user() !== 'root') {
$prefix = 'sudo ';
logger()->warning('Current user is not root, using sudo for running command');
}
$profile = '/etc/profile';
if (file_exists('~/.bash_profile')) {
$profile = '~/.bash_profile';
} elseif (file_exists('~/.profile')) {
$profile = '~/.profile';
}
if (!file_exists($profile)) {
shell(true)->exec($prefix . 'touch ' . $profile);
}
if (!getenv('PATH') || !str_contains(getenv('PATH'), '/usr/local/musl/bin')) {
$fix_path = 'echo "export PATH=/usr/local/musl/bin:$PATH" >> ' . $profile . ' && export PATH=/usr/local/musl/bin:$PATH';
shell(true)->exec($prefix . $fix_path);
}
return true;
} catch (RuntimeException) {
return false;
}
}
/**
* @throws DownloaderException
* @throws RuntimeException
* @throws FileSystemException
*/
public function installMuslWrapper(): void
{
$prefix = '';
if (get_current_user() !== 'root') {
$prefix = 'sudo ';
logger()->warning('Current user is not root, using sudo for running command');
}
$musl_source = [
'type' => 'url',
'url' => 'https://musl.libc.org/releases/musl-1.2.4.tar.gz',
];
Downloader::downloadSource('musl-1.2.4', $musl_source);
FileSystem::extractSource('musl-1.2.4', DOWNLOAD_PATH . '/musl-1.2.4.tar.gz');
$musl_gcc_install_cmd = 'cd ' . SOURCE_PATH . '/musl-1.2.4 && \
./configure --enable-wrapper=gcc && \
make -j && make install';
shell(true)->exec($prefix . $musl_gcc_install_cmd);
}
/**
* @throws DownloaderException
* @throws RuntimeException
* @throws FileSystemException
*/
public function installMuslCrossMake(): void
{
$arch = arch2gnu(php_uname('m'));
$musl_compile_source = [
'type' => 'url',
'url' => "https://musl.cc/{$arch}-linux-musl-cross.tgz",
];
Downloader::downloadSource('musl-compile', $musl_compile_source);
FileSystem::extractSource('musl-compile', DOWNLOAD_PATH . "/{$arch}-linux-musl-cross.tgz");
shell(true)->exec('cp -rf ' . SOURCE_PATH . '/musl-compile/* /usr/local/musl');
}
}