Skip to content

Commit 106b55d

Browse files
authored
[v3] Add musl-wrapper and musl-toolchain installation support (#984)
1 parent 93a697e commit 106b55d

File tree

5 files changed

+71
-25
lines changed

5 files changed

+71
-25
lines changed

config/artifact.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
}
99
}
1010
},
11+
"musl-wrapper": {
12+
"source": "https://musl.libc.org/releases/musl-1.2.5.tar.gz"
13+
},
1114
"php-src": {
1215
"source": {
1316
"type": "php-release"
@@ -28,8 +31,16 @@
2831
},
2932
"musl-toolchain": {
3033
"binary": {
31-
"linux-x86_64": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/x86_64-musl-toolchain.tgz",
32-
"linux-aarch64": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/aarch64-musl-toolchain.tgz"
34+
"linux-x86_64": {
35+
"type": "url",
36+
"url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/x86_64-musl-toolchain.tgz",
37+
"extract": "{pkg_root_path}/musl-toolchain"
38+
},
39+
"linux-aarch64": {
40+
"type": "url",
41+
"url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/aarch64-musl-toolchain.tgz",
42+
"extract": "{pkg_root_path}/musl-toolchain"
43+
}
3344
}
3445
},
3546
"pkg-config": {

src/StaticPHP/Artifact/ArtifactDownloader.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ public function download(bool $interactive = true): void
320320
$skipped = [];
321321
foreach ($this->artifacts as $artifact) {
322322
++$current;
323-
if ($this->downloadWithType($artifact, $current, $count) === SPC_DOWNLOAD_STATUS_SKIPPED) {
323+
if ($this->downloadWithType($artifact, $current, $count, interactive: $interactive) === SPC_DOWNLOAD_STATUS_SKIPPED) {
324324
$skipped[] = $artifact->getName();
325325
continue;
326326
}
@@ -358,7 +358,7 @@ public function getOption(string $name, mixed $default = null): mixed
358358
return $this->options[$name] ?? $default;
359359
}
360360

361-
private function downloadWithType(Artifact $artifact, int $current, int $total, bool $parallel = false): int
361+
private function downloadWithType(Artifact $artifact, int $current, int $total, bool $parallel = false, bool $interactive = true): int
362362
{
363363
$queue = $this->generateQueue($artifact);
364364
// already downloaded
@@ -379,7 +379,7 @@ private function downloadWithType(Artifact $artifact, int $current, int $total,
379379
};
380380
$try_h = $try ? 'Try downloading' : 'Downloading';
381381
logger()->info("{$try_h} artifact '{$artifact->getName()}' {$item['display']} ...");
382-
if ($parallel === false) {
382+
if ($parallel === false && $interactive) {
383383
InteractiveTerm::indicateProgress("[{$current}/{$total}] Downloading artifact " . ConsoleColor::green($artifact->getName()) . " {$item['display']} from {$type_display_name} ...");
384384
}
385385
// is valid download type
@@ -413,13 +413,13 @@ private function downloadWithType(Artifact $artifact, int $current, int $total,
413413
}
414414
// process lock
415415
ApplicationContext::get(ArtifactCache::class)->lock($artifact, $item['lock'], $lock, SystemTarget::getCurrentPlatformString());
416-
if ($parallel === false) {
416+
if ($parallel === false && $interactive) {
417417
$ver = $lock->hasVersion() ? (' (' . ConsoleColor::yellow($lock->version) . ')') : '';
418418
InteractiveTerm::finish('Downloaded ' . ($verified ? 'and verified ' : '') . 'artifact ' . ConsoleColor::green($artifact->getName()) . $ver . " {$item['display']} .");
419419
}
420420
return SPC_DOWNLOAD_STATUS_SUCCESS;
421421
} catch (DownloaderException|ExecutionException $e) {
422-
if ($parallel === false) {
422+
if ($parallel === false && $interactive) {
423423
InteractiveTerm::finish("Download artifact {$artifact->getName()} {$item['display']} failed !", false);
424424
InteractiveTerm::error("Failed message: {$e->getMessage()}", true);
425425
}

src/StaticPHP/Artifact/ArtifactExtractor.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,12 +78,17 @@ public function extractForPackages(array $packages, bool $force_source = false):
7878
/**
7979
* Extract a single artifact.
8080
*
81-
* @param Artifact $artifact The artifact to extract
82-
* @param bool $force_source If true, always extract source (ignore binary)
81+
* @param Artifact|string $artifact The artifact to extract
82+
* @param bool $force_source If true, always extract source (ignore binary)
8383
*/
84-
public function extract(Artifact $artifact, bool $force_source = false): int
84+
public function extract(Artifact|string $artifact, bool $force_source = false): int
8585
{
86-
$name = $artifact->getName();
86+
if (is_string($artifact)) {
87+
$name = $artifact;
88+
$artifact = ArtifactLoader::getArtifactInstance($name);
89+
} else {
90+
$name = $artifact->getName();
91+
}
8792

8893
// Already extracted in this session
8994
if (isset($this->extracted[$name])) {

src/StaticPHP/Doctor/Item/LinuxMuslCheck.php

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44

55
namespace StaticPHP\Doctor\Item;
66

7+
use StaticPHP\Artifact\ArtifactCache;
8+
use StaticPHP\Artifact\ArtifactDownloader;
9+
use StaticPHP\Artifact\ArtifactExtractor;
710
use StaticPHP\Attribute\Doctor\CheckItem;
811
use StaticPHP\Attribute\Doctor\FixItem;
912
use StaticPHP\Attribute\Doctor\OptionalCheck;
13+
use StaticPHP\DI\ApplicationContext;
1014
use StaticPHP\Doctor\CheckResult;
15+
use StaticPHP\Runtime\Shell\Shell;
1116
use StaticPHP\Toolchain\MuslToolchain;
1217
use StaticPHP\Toolchain\ZigToolchain;
1318
use StaticPHP\Util\FileSystem;
19+
use StaticPHP\Util\InteractiveTerm;
20+
use StaticPHP\Util\SourcePatcher;
1421
use StaticPHP\Util\System\LinuxUtil;
1522

1623
#[OptionalCheck([self::class, 'optionalCheck'])]
@@ -51,23 +58,46 @@ public function checkMuslCrossMake(): CheckResult
5158
#[FixItem('fix-musl-wrapper')]
5259
public function fixMusl(): bool
5360
{
54-
// TODO: implement musl-wrapper installation
55-
// This should:
56-
// 1. Download musl source using Downloader::downloadSource()
57-
// 2. Extract the source using FileSystem::extractSource()
58-
// 3. Apply CVE patches using SourcePatcher::patchFile()
59-
// 4. Build and install musl wrapper
60-
// 5. Add path using putenv instead of editing /etc/profile
61-
return false;
61+
$downloader = new ArtifactDownloader();
62+
$downloader->add('musl-wrapper')->download(false);
63+
$extractor = new ArtifactExtractor(ApplicationContext::get(ArtifactCache::class));
64+
$extractor->extract('musl-wrapper');
65+
66+
// Apply CVE-2025-26519 patch and install musl wrapper
67+
SourcePatcher::patchFile('musl-1.2.5_CVE-2025-26519_0001.patch', SOURCE_PATH . '/musl-wrapper');
68+
SourcePatcher::patchFile('musl-1.2.5_CVE-2025-26519_0002.patch', SOURCE_PATH . '/musl-wrapper');
69+
70+
$prefix = '';
71+
if (get_current_user() !== 'root') {
72+
$prefix = 'sudo ';
73+
logger()->warning('Current user is not root, using sudo for running command');
74+
}
75+
shell()->cd(SOURCE_PATH . '/musl-wrapper')
76+
->exec('CC=gcc CXX=g++ AR=ar LD=ld ./configure --disable-gcc-wrapper')
77+
->exec('CC=gcc CXX=g++ AR=ar LD=ld make -j')
78+
->exec("CC=gcc CXX=g++ AR=ar LD=ld {$prefix}make install");
79+
return true;
6280
}
6381

6482
#[FixItem('fix-musl-cross-make')]
6583
public function fixMuslCrossMake(): bool
6684
{
67-
// TODO: implement musl-cross-make installation
68-
// This should:
69-
// 1. Install musl-toolchain package using PackageManager::installPackage()
70-
// 2. Copy toolchain files to /usr/local/musl
71-
return false;
85+
// sudo
86+
$prefix = '';
87+
if (get_current_user() !== 'root') {
88+
$prefix = 'sudo ';
89+
logger()->warning('Current user is not root, using sudo for running command');
90+
}
91+
Shell::passthruCallback(function () {
92+
InteractiveTerm::advance();
93+
});
94+
$downloader = new ArtifactDownloader();
95+
$extractor = new ArtifactExtractor(ApplicationContext::get(ArtifactCache::class));
96+
$downloader->add('musl-toolchain')->download(false);
97+
$extractor->extract('musl-toolchain');
98+
$pkg_root = PKG_ROOT_PATH . '/musl-toolchain';
99+
shell()->exec("{$prefix}cp -rf {$pkg_root}/* /usr/local/musl");
100+
FileSystem::removeDir($pkg_root);
101+
return true;
72102
}
73103
}

src/StaticPHP/Util/System/LinuxUtil.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public static function getSupportedDistros(): array
9191
{
9292
return [
9393
// debian-like
94-
'debian', 'ubuntu', 'Deepin',
94+
'debian', 'ubuntu', 'Deepin', 'neon',
9595
// rhel-like
9696
'redhat',
9797
// centos

0 commit comments

Comments
 (0)