Compare commits

...

16 Commits

Author SHA1 Message Date
Jerry Ma
5a1fd1f388 Merge branch 'v3' into v3c/artifact-static-helpers 2026-05-29 17:32:02 +09:00
Jerry Ma
48d6e9ebc2 LinuxMuslCheck: pass tool env via setEnv instead of command prefixes (#1170) 2026-05-24 22:59:47 +08:00
Jerry Ma
6cab47db67 deduplicate_flags: keep paired flag+value tokens together (#1168) 2026-05-24 22:57:23 +08:00
Jerry Ma
ec3fd0f4b0 patch: strip trailing U+200E from spc_fix_avx512_cache_before_80400.p… (#1167) 2026-05-24 22:57:01 +08:00
henderkes
e72f9aa623 LinuxMuslCheck: pass tool env via setEnv instead of command prefixes
Build the CC/CXX/AR/LD/RANLIB map once and hand it to shell()->setEnv()
so the configure/make invocations don't have to repeat the same prefix
on every line. For the sudo make-install path the env still needs to
be on the command line (sudo strips the parent env), so the same map
is rendered into $envFlags and prepended there. Also adds RANLIB,
which the upstream Makefile honours.
2026-05-24 21:40:26 +07:00
henderkes
91cf4f83b5 artifact: add path/binary/isInstalled static helpers
Give zig, rust, go_win and go_xcaddy a small consistent surface for
locating the install directory and a binary inside it:

- path(): install/extract root for the artifact
- binary($name = '<default>'): full path to a binary under that root,
  picking the artifact's natural layout (top-level for zig, bin/ for
  rust and the go toolchains)
- isInstalled(): is the default binary present on disk

Callers that previously concatenated PKG_ROOT_PATH . '/zig/zig' (and
the equivalents for the other artifacts) by hand can call the helpers
instead, and any later code that needs to ask "is this toolchain
available" can use isInstalled() without rebuilding the path.
2026-05-24 21:39:56 +07:00
henderkes
c666cd6cd0 deduplicate_flags: keep paired flag+value tokens together
deduplicate_flags() split flags on whitespace then ran a per-token
unique. For paired flags like `-Xclang -mllvm` or `-framework Cocoa`,
where the value is a separate token, the value token could collide
with an unrelated flag or value and get dropped, corrupting the
command line.

Group known paired flags (-Xclang, -Xpreprocessor, -Xlinker,
-Xassembler, -framework, -arch, -target, -include, -imacros, -isystem,
-isysroot, -iquote, -idirafter, -MT, -MF, -MQ) with their following
token into a single atom before the unique pass.
2026-05-24 21:38:22 +07:00
henderkes
b8dd508148 patch: strip trailing U+200E from spc_fix_avx512_cache_before_80400.patch
The filename had a Left-To-Right Mark (U+200E) appended invisibly, so
the file is unreachable by code that constructs the path from a plain
ASCII string literal. Rename to the visible name.
2026-05-24 21:38:00 +07:00
Jerry Ma
582a88ef60 artifact: use {pkg_root_path} template in rust and go_win extract (#1164) 2026-05-24 22:04:39 +08:00
Jerry Ma
153003b75c imagemagick: --without-gcc-arch (#1162) 2026-05-24 22:04:02 +08:00
Jerry Ma
899555a964 watcher: drop ldflags from compile-only invocation (#1161) 2026-05-24 22:03:38 +08:00
Jerry Ma
891a222c39 revert useless patch (#1160) 2026-05-24 22:03:11 +08:00
henderkes
39beb68024 artifact: use {pkg_root_path} template in rust and go_win extract
Switch the rust and go_win downloaders from baking PKG_ROOT_PATH into
the extract path at download time to the {pkg_root_path} template,
which ArtifactExtractor resolves at extract time. This keeps the path
stable across runs where pkg_root_path differs between download and
extract (e.g. containerised vs host builds).
2026-05-24 20:56:08 +07:00
henderkes
0807e9e253 watcher: drop ldflags from compile-only invocation
The shell invocation runs `$CXX -c` to compile watcher-c.cpp to a .o,
which never links. Passing linker flags to a compile-only step is
either ignored or, with some flags, an error. Drop them.
2026-05-24 20:54:44 +07:00
henderkes
1a779be028 imagemagick: --without-gcc-arch
ax_gcc_archflag has no Zen cpuid pattern and falls back to
-mtune=amdfam10, which under LLVM+LTO emits SSE4a extrq and SIGILLs on
Intel hosts. Disable the implicit --with-gcc-arch so host CPU features
do not bleed into the built binaries.
2026-05-24 20:54:21 +07:00
henderkes
bdfd3eb269 also revert #1122 2026-05-24 20:41:18 +07:00
10 changed files with 109 additions and 28 deletions

View File

@@ -15,13 +15,28 @@ use StaticPHP\Util\GlobalEnvManager;
class go_win
{
/** GOROOT for the Windows Go toolchain. */
public static function path(): string
{
return PKG_ROOT_PATH . '/go-win';
}
/** Path to a binary inside go-win's bin/ (go.exe, gofmt.exe, …). */
public static function binary(string $name = 'go.exe'): string
{
return self::path() . '/bin/' . $name;
}
public static function isInstalled(): bool
{
return is_file(self::binary());
}
#[CustomBinary('go-win', [
'windows-x86_64',
])]
public function downBinary(ArtifactDownloader $downloader): DownloadResult
{
$pkgroot = PKG_ROOT_PATH;
// get version
[$version] = explode("\n", default_shell()->executeCurl('https://go.dev/VERSION?m=text', retries: $downloader->getRetry()) ?: '');
if ($version === '') {
@@ -52,7 +67,7 @@ class go_win
throw new DownloaderException("Hash mismatch for downloaded go-win binary. Expected {$hash}, got {$file_hash}");
}
return DownloadResult::archive(basename($path), ['url' => $url, 'version' => $version], extract: "{$pkgroot}/go-win", verified: true, version: $version);
return DownloadResult::archive(basename($path), ['url' => $url, 'version' => $version], extract: '{pkg_root_path}/go-win', verified: true, version: $version);
}
#[CustomBinaryCheckUpdate('go-win', ['windows-x86_64'])]

View File

@@ -17,6 +17,23 @@ use StaticPHP\Util\System\LinuxUtil;
class go_xcaddy
{
/** GOROOT for the bundled Go toolchain used to build xcaddy. */
public static function path(): string
{
return PKG_ROOT_PATH . '/go-xcaddy';
}
/** Path to a binary inside go-xcaddy's bin/ (xcaddy, go, …). */
public static function binary(string $name = 'xcaddy'): string
{
return self::path() . '/bin/' . $name;
}
public static function isInstalled(): bool
{
return is_file(self::binary());
}
#[CustomBinary('go-xcaddy', [
'linux-x86_64',
'linux-aarch64',

View File

@@ -16,6 +16,23 @@ use StaticPHP\Util\System\LinuxUtil;
class rust
{
/** Install prefix the rust tarball's install.sh writes into. */
public static function path(): string
{
return PKG_ROOT_PATH . '/rust';
}
/** Path to a binary inside the rust install dir (cargo, rustc, rustup, …). */
public static function binary(string $name = 'cargo'): string
{
return self::path() . '/bin/' . $name;
}
public static function isInstalled(): bool
{
return is_file(self::binary());
}
#[CustomBinary('rust', [
'linux-x86_64',
'linux-aarch64',
@@ -46,7 +63,7 @@ class rust
$download_url = "https://static.rust-lang.org/dist/rust-{$latest_version}-{$arch}-unknown-linux-{$distro}.tar.xz";
$path = DOWNLOAD_PATH . DIRECTORY_SEPARATOR . basename($download_url);
default_shell()->executeCurlDownload($download_url, $path, retries: $downloader->getRetry());
return DownloadResult::archive(basename($path), ['url' => $download_url, 'version' => $latest_version], extract: PKG_ROOT_PATH . '/rust-install', verified: false, version: $latest_version);
return DownloadResult::archive(basename($path), ['url' => $download_url, 'version' => $latest_version], extract: '{pkg_root_path}/rust-install', verified: false, version: $latest_version);
}
#[CustomBinaryCheckUpdate('rust', [

View File

@@ -15,6 +15,23 @@ use StaticPHP\Runtime\SystemTarget;
class zig
{
/** Directory zig extracts into. */
public static function path(): string
{
return PKG_ROOT_PATH . '/zig';
}
/** Path to a binary inside the zig install dir (zig, zig-cc, zig-c++, zig-ar, …). */
public static function binary(string $name = 'zig'): string
{
return self::path() . '/' . $name;
}
public static function isInstalled(): bool
{
return is_file(self::binary());
}
#[CustomBinary('zig', [
'linux-x86_64',
'linux-aarch64',

View File

@@ -11,7 +11,6 @@ use StaticPHP\Attribute\Package\Extension;
use StaticPHP\Attribute\PatchDescription;
use StaticPHP\Package\PackageInstaller;
use StaticPHP\Package\PhpExtensionPackage;
use StaticPHP\Util\GlobalEnvManager;
use StaticPHP\Util\SourcePatcher;
#[Extension('xlswriter')]
@@ -21,20 +20,14 @@ class xlswriter extends PhpExtensionPackage
#[CustomPhpConfigureArg('Linux')]
public function getUnixConfigureArg(bool $shared, PackageInstaller $installer): string
{
$arg = '--with-xlswriter --enable-reader';
$shared = $shared ? '=shared' : '';
$arg = "--with-xlswriter{$shared} --enable-reader";
if ($installer->getLibraryPackage('openssl')) {
$arg .= ' --with-openssl=' . $installer->getLibraryPackage('openssl')->getBuildRootPath();
}
return $arg;
}
#[BeforeStage('php', [php::class, 'makeForUnix'], 'ext-xlswriter')]
#[PatchDescription('Fix Unix build: add -std=gnu17 to CFLAGS to fix build errors on older GCC versions')]
public function patchBeforeUnixMake(): void
{
GlobalEnvManager::putenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS=' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') . ' -std=gnu17');
}
#[BeforeStage('php', [php::class, 'makeForWindows'], 'ext-xlswriter')]
#[PatchDescription('Fix Windows build: apply win32 patch and add UTF-8 BOM to theme.c')]
public function patchBeforeMakeForWindows(): void
@@ -47,11 +40,4 @@ class xlswriter extends PhpExtensionPackage
file_put_contents($this->getSourceDir() . '/library/libxlsxwriter/src/theme.c', $bom . $content);
}
}
public function getSharedExtensionEnv(): array
{
$parent = parent::getSharedExtensionEnv();
$parent['CFLAGS'] .= ' -std=gnu17';
return $parent;
}
}

View File

@@ -42,6 +42,9 @@ class imagemagick
->addConfigureArgs(
'--disable-openmp',
'--without-x',
// implicit --with-gcc-arch
// bleeds host cpu features into built binaries
'--without-gcc-arch',
);
// special: linux-static target needs `-static`

View File

@@ -20,9 +20,8 @@ class watcher extends LibraryPackage
if (stripos($cflags, '-fpic') === false) {
$cflags .= ' -fPIC';
}
$ldflags = $this->getLibExtraLdFlags() ? ' ' . $this->getLibExtraLdFlags() : '';
shell()->cd("{$this->getSourceDir()}/watcher-c")
->exec(getenv('CXX') . " -c -o libwatcher-c.o ./src/watcher-c.cpp -I ./include -I ../include -std=c++17 -Wall -Wextra {$cflags}{$ldflags}")
->exec(getenv('CXX') . " -c -o libwatcher-c.o ./src/watcher-c.cpp -I ./include -I ../include -std=c++17 -Wall -Wextra {$cflags}")
->exec(getenv('AR') . ' rcs libwatcher-c.a libwatcher-c.o');
copy("{$this->getSourceDir()}/watcher-c/libwatcher-c.a", "{$this->getLibDir()}/libwatcher-c.a");

View File

@@ -73,13 +73,20 @@ class LinuxMuslCheck
$prefix = 'sudo ';
logger()->warning('Current user is not root, using sudo for running command');
}
$sysEnv = ['CC' => 'gcc', 'CXX' => 'g++', 'AR' => 'ar', 'LD' => 'ld', 'RANLIB' => 'ranlib'];
$envFlags = '';
foreach ($sysEnv as $k => $v) {
$envFlags .= "{$k}={$v} ";
}
$envFlags = rtrim($envFlags);
$shell = shell()->cd(SOURCE_PATH . '/musl-wrapper')
->exec('CC=gcc CXX=g++ AR=ar LD=ld ./configure --disable-gcc-wrapper')
->exec('CC=gcc CXX=g++ AR=ar LD=ld make -j');
->setEnv($sysEnv)
->exec('./configure --disable-gcc-wrapper')
->exec('make -j');
if ($prefix !== '') {
f_passthru('cd ' . SOURCE_PATH . "/musl-wrapper && CC=gcc CXX=g++ AR=ar LD=ld {$prefix}make install");
f_passthru('cd ' . SOURCE_PATH . "/musl-wrapper && {$envFlags} {$prefix}make install");
} else {
$shell->exec("CC=gcc CXX=g++ AR=ar LD=ld {$prefix}make install");
$shell->exec("{$prefix}make install");
}
return true;
}

View File

@@ -256,10 +256,30 @@ function clean_spaces(string $string): string
*/
function deduplicate_flags(string $flags): string
{
$tokens = preg_split('/\s+/', trim($flags));
// Flags that take their value as a separate token.
static $paired = [
'-Xclang', '-Xpreprocessor', '-Xlinker', '-Xassembler',
'-framework', '-arch', '-target',
'-include', '-imacros', '-isystem', '-isysroot', '-iquote', '-idirafter',
'-MT', '-MF', '-MQ',
];
$tokens = preg_split('/\s+/', trim($flags)) ?: [];
// Group paired flag+value into a single atom before dedup.
$atoms = [];
$n = count($tokens);
for ($i = 0; $i < $n; ++$i) {
if (in_array($tokens[$i], $paired, true) && $i + 1 < $n) {
$atoms[] = $tokens[$i] . ' ' . $tokens[$i + 1];
++$i;
} else {
$atoms[] = $tokens[$i];
}
}
// Reverse, unique, reverse back - keeps last occurrence of duplicates
$deduplicated = array_reverse(array_unique(array_reverse($tokens)));
$deduplicated = array_reverse(array_unique(array_reverse($atoms)));
return implode(' ', $deduplicated);
}