mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-12 03:15:35 +08:00
Compare commits
13 Commits
2b6d228bc3
...
feat/pgo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2adedc0943 | ||
|
|
fbb91e347e | ||
|
|
f3b7149287 | ||
|
|
3823631a58 | ||
|
|
435d2c07b0 | ||
|
|
ed0a45da31 | ||
|
|
6bc6e32dd0 | ||
|
|
dac2ea5677 | ||
|
|
9398a6677d | ||
|
|
967122cc7c | ||
|
|
53bd0fca4f | ||
|
|
daa694ab2c | ||
|
|
1ae4a00e10 |
@@ -287,6 +287,7 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"BSD": "wip"
|
"BSD": "wip"
|
||||||
},
|
},
|
||||||
|
"arg-type": "with-path",
|
||||||
"type": "external",
|
"type": "external",
|
||||||
"source": "ext-gmssl",
|
"source": "ext-gmssl",
|
||||||
"lib-depends": [
|
"lib-depends": [
|
||||||
|
|||||||
@@ -124,10 +124,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ext-brotli": {
|
"ext-brotli": {
|
||||||
"type": "git",
|
"type": "ghtagtar",
|
||||||
|
"repo": "kjdev/php-ext-brotli",
|
||||||
"path": "php-src/ext/brotli",
|
"path": "php-src/ext/brotli",
|
||||||
"rev": "master",
|
|
||||||
"url": "https://github.com/kjdev/php-ext-brotli",
|
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
@@ -361,10 +360,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ext-zstd": {
|
"ext-zstd": {
|
||||||
"type": "git",
|
"type": "ghtar",
|
||||||
|
"repo": "kjdev/php-ext-zstd",
|
||||||
"path": "php-src/ext/zstd",
|
"path": "php-src/ext/zstd",
|
||||||
"rev": "master",
|
|
||||||
"url": "https://github.com/kjdev/php-ext-zstd",
|
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
@@ -421,9 +419,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gmssl": {
|
"gmssl": {
|
||||||
"type": "ghtar",
|
"type": "git",
|
||||||
"repo": "guanzhi/GmSSL",
|
"url": "https://github.com/guanzhi/GmSSL.git",
|
||||||
"provide-pre-built": true,
|
"rev": "master",
|
||||||
"license": {
|
"license": {
|
||||||
"type": "file",
|
"type": "file",
|
||||||
"path": "LICENSE"
|
"path": "LICENSE"
|
||||||
@@ -1108,7 +1106,7 @@
|
|||||||
},
|
},
|
||||||
"protobuf": {
|
"protobuf": {
|
||||||
"type": "url",
|
"type": "url",
|
||||||
"url": "https://pecl.php.net/get/protobuf-5.34.1.tgz",
|
"url": "https://pecl.php.net/get/protobuf",
|
||||||
"path": "php-src/ext/protobuf",
|
"path": "php-src/ext/protobuf",
|
||||||
"filename": "protobuf.tgz",
|
"filename": "protobuf.tgz",
|
||||||
"license": {
|
"license": {
|
||||||
|
|||||||
17
src/SPC/builder/extension/brotli.php
Normal file
17
src/SPC/builder/extension/brotli.php
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace SPC\builder\extension;
|
||||||
|
|
||||||
|
use SPC\builder\Extension;
|
||||||
|
use SPC\util\CustomExt;
|
||||||
|
|
||||||
|
#[CustomExt('brotli')]
|
||||||
|
class brotli extends Extension
|
||||||
|
{
|
||||||
|
public function getUnixConfigureArg(bool $shared = false): string
|
||||||
|
{
|
||||||
|
return $this->getEnableArg($shared) . '--with-libbrotli';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,23 @@ class event extends Extension
|
|||||||
// Prevent event extension compile error on macOS
|
// Prevent event extension compile error on macOS
|
||||||
if ($this->builder instanceof MacOSBuilder) {
|
if ($this->builder instanceof MacOSBuilder) {
|
||||||
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_OPENPTY 1$/m', '');
|
FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/main/php_config.h', '/^#define HAVE_OPENPTY 1$/m', '');
|
||||||
return true;
|
$patched = true;
|
||||||
|
}
|
||||||
|
return $this->patchLibeventConstPeer() || $patched;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function patchBeforeSharedMake(): bool
|
||||||
|
{
|
||||||
|
$patched = parent::patchBeforeSharedMake();
|
||||||
|
return $this->patchLibeventConstPeer() || $patched;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function patchLibeventConstPeer(): bool
|
||||||
|
{
|
||||||
|
$patched = false;
|
||||||
|
$file = SOURCE_PATH . '/php-src/ext/event/php8/classes/http_connection.c';
|
||||||
|
if (is_file($file) && FileSystem::replaceFileRegex($file, '/^\tchar \*address;$/m', "\tconst char *address;")) {
|
||||||
|
$patched = true;
|
||||||
}
|
}
|
||||||
return $patched;
|
return $patched;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,8 @@ class BSDBuilder extends UnixBuilderBase
|
|||||||
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
||||||
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
||||||
('--with-config-file-scan-dir=' . $this->getOption('with-config-file-scan-dir') . ' ') : '';
|
('--with-config-file-scan-dir=' . $this->getOption('with-config-file-scan-dir') . ' ') : '';
|
||||||
|
$sysconfdir = $this->getOption('with-sysconfdir', false) ?
|
||||||
|
('--sysconfdir=' . $this->getOption('with-sysconfdir') . ' ') : '';
|
||||||
|
|
||||||
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
||||||
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||||
@@ -89,6 +91,7 @@ class BSDBuilder extends UnixBuilderBase
|
|||||||
($enableMicro ? '--enable-micro ' : '--disable-micro ') .
|
($enableMicro ? '--enable-micro ' : '--disable-micro ') .
|
||||||
$config_file_path .
|
$config_file_path .
|
||||||
$config_file_scan_dir .
|
$config_file_scan_dir .
|
||||||
|
$sysconfdir .
|
||||||
$json_74 .
|
$json_74 .
|
||||||
$zts .
|
$zts .
|
||||||
$this->makeStaticExtensionArgs()
|
$this->makeStaticExtensionArgs()
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
||||||
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
||||||
('--with-config-file-scan-dir=' . $this->getOption('with-config-file-scan-dir') . ' ') : '';
|
('--with-config-file-scan-dir=' . $this->getOption('with-config-file-scan-dir') . ' ') : '';
|
||||||
|
$sysconfdir = $this->getOption('with-sysconfdir', false) ?
|
||||||
|
('--sysconfdir=' . $this->getOption('with-sysconfdir') . ' ') : '';
|
||||||
|
|
||||||
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
||||||
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||||
@@ -125,6 +127,7 @@ class LinuxBuilder extends UnixBuilderBase
|
|||||||
($enableCgi ? '--enable-cgi ' : '--disable-cgi ') .
|
($enableCgi ? '--enable-cgi ' : '--disable-cgi ') .
|
||||||
$config_file_path .
|
$config_file_path .
|
||||||
$config_file_scan_dir .
|
$config_file_scan_dir .
|
||||||
|
$sysconfdir .
|
||||||
$json_74 .
|
$json_74 .
|
||||||
$zts .
|
$zts .
|
||||||
$maxExecutionTimers .
|
$maxExecutionTimers .
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
('--with-config-file-path=' . $this->getOption('with-config-file-path') . ' ') : '';
|
||||||
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
$config_file_scan_dir = $this->getOption('with-config-file-scan-dir', false) ?
|
||||||
('--with-config-file-scan-dir=' . $this->getOption('with-config-file-scan-dir') . ' ') : '';
|
('--with-config-file-scan-dir=' . $this->getOption('with-config-file-scan-dir') . ' ') : '';
|
||||||
|
$sysconfdir = $this->getOption('with-sysconfdir', false) ?
|
||||||
|
('--sysconfdir=' . $this->getOption('with-sysconfdir') . ' ') : '';
|
||||||
|
|
||||||
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
$enableCli = ($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI;
|
||||||
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
$enableFpm = ($build_target & BUILD_TARGET_FPM) === BUILD_TARGET_FPM;
|
||||||
@@ -129,6 +131,7 @@ class MacOSBuilder extends UnixBuilderBase
|
|||||||
($enableCgi ? '--enable-cgi ' : '--disable-cgi ') .
|
($enableCgi ? '--enable-cgi ' : '--disable-cgi ') .
|
||||||
$config_file_path .
|
$config_file_path .
|
||||||
$config_file_scan_dir .
|
$config_file_scan_dir .
|
||||||
|
$sysconfdir .
|
||||||
$json_74 .
|
$json_74 .
|
||||||
$zts .
|
$zts .
|
||||||
$this->makeStaticExtensionArgs() . ' ' .
|
$this->makeStaticExtensionArgs() . ' ' .
|
||||||
|
|||||||
@@ -30,7 +30,11 @@ trait libaom
|
|||||||
->setBuildDir("{$this->source_dir}/builddir")
|
->setBuildDir("{$this->source_dir}/builddir")
|
||||||
->addConfigureArgs(
|
->addConfigureArgs(
|
||||||
"-DAOM_TARGET_CPU={$targetCpu}",
|
"-DAOM_TARGET_CPU={$targetCpu}",
|
||||||
'-DCONFIG_RUNTIME_CPU_DETECT=1'
|
'-DCONFIG_RUNTIME_CPU_DETECT=1',
|
||||||
|
'-DENABLE_EXAMPLES=0',
|
||||||
|
'-DENABLE_TOOLS=0',
|
||||||
|
'-DENABLE_TESTS=0',
|
||||||
|
'-DENABLE_DOCS=0'
|
||||||
)
|
)
|
||||||
->build();
|
->build();
|
||||||
f_putenv("SPC_COMPILER_EXTRA={$extra}");
|
f_putenv("SPC_COMPILER_EXTRA={$extra}");
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class BuildPHPCommand extends BuildCommand
|
|||||||
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');
|
$this->addOption('disable-opcache-jit', null, null, 'disable opcache jit');
|
||||||
$this->addOption('with-config-file-path', null, InputOption::VALUE_REQUIRED, 'Set the path in which to look for php.ini', $isWindows ? null : '/usr/local/etc/php');
|
$this->addOption('with-config-file-path', null, InputOption::VALUE_REQUIRED, 'Set the path in which to look for php.ini', $isWindows ? null : '/usr/local/etc/php');
|
||||||
$this->addOption('with-config-file-scan-dir', null, InputOption::VALUE_REQUIRED, 'Set the directory to scan for .ini files after reading php.ini', $isWindows ? null : '/usr/local/etc/php/conf.d');
|
$this->addOption('with-config-file-scan-dir', null, InputOption::VALUE_REQUIRED, 'Set the directory to scan for .ini files after reading php.ini', $isWindows ? null : '/usr/local/etc/php/conf.d');
|
||||||
|
$this->addOption('with-sysconfdir', null, InputOption::VALUE_REQUIRED, 'Set the sysconfdir (e.g. /etc/php-zts) used by configure (not available on Windows)');
|
||||||
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
|
$this->addOption('with-hardcoded-ini', 'I', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Patch PHP source code, inject hardcoded INI');
|
||||||
$this->addOption('with-micro-fake-cli', null, null, 'Let phpmicro\'s PHP_SAPI use "cli" instead of "micro"');
|
$this->addOption('with-micro-fake-cli', null, null, 'Let phpmicro\'s PHP_SAPI use "cli" instead of "micro"');
|
||||||
$this->addOption('with-suggested-libs', 'L', null, 'Build with suggested libs for selected exts and libs');
|
$this->addOption('with-suggested-libs', 'L', null, 'Build with suggested libs for selected exts and libs');
|
||||||
|
|||||||
@@ -175,6 +175,16 @@ class Downloader
|
|||||||
hooks: [[CurlHook::class, 'setupGithubToken']],
|
hooks: [[CurlHook::class, 'setupGithubToken']],
|
||||||
retries: self::getRetryAttempts()
|
retries: self::getRetryAttempts()
|
||||||
), true);
|
), true);
|
||||||
|
if (($source['prefer-stable'] ?? false) === true) {
|
||||||
|
$latest = json_decode(self::curlExec(
|
||||||
|
url: "https://api.github.com/repos/{$source['repo']}/releases/latest",
|
||||||
|
hooks: [[CurlHook::class, 'setupGithubToken']],
|
||||||
|
retries: self::getRetryAttempts()
|
||||||
|
), true);
|
||||||
|
if (is_array($latest) && isset($latest['assets'])) {
|
||||||
|
array_unshift($data, $latest);
|
||||||
|
}
|
||||||
|
}
|
||||||
$url = null;
|
$url = null;
|
||||||
$filename = null;
|
$filename = null;
|
||||||
foreach ($data as $release) {
|
foreach ($data as $release) {
|
||||||
|
|||||||
@@ -138,6 +138,22 @@ class SourcePatcher
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// strip our build-time env vars from phpinfo's "Configure Command" ('|' delimiter: PHP_BUILD_PROVIDER may contain '#')
|
||||||
|
if (is_unix()) {
|
||||||
|
FileSystem::replaceFileStr(
|
||||||
|
SOURCE_PATH . '/php-src/configure',
|
||||||
|
'for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS EXTRA_LDFLAGS_PROGRAM LIBS CC CXX; do',
|
||||||
|
'for var in CFLAGS CXXFLAGS CPPFLAGS LDFLAGS EXTRA_LDFLAGS_PROGRAM LIBS CC CXX '
|
||||||
|
. 'PKG_CONFIG PKG_CONFIG_PATH EXTENSION_DIR OPENSSL_LIBS '
|
||||||
|
. 'PHP_BUILD_SYSTEM PHP_BUILD_PROVIDER PHP_BUILD_COMPILER PHP_BUILD_ARCH; do',
|
||||||
|
);
|
||||||
|
FileSystem::replaceFileStr(
|
||||||
|
SOURCE_PATH . '/php-src/configure',
|
||||||
|
'clean_configure_args=$(echo $clean_configure_args | $SED -e "s#\'$var=$val\'##")',
|
||||||
|
'clean_configure_args=$(echo $clean_configure_args | $SED -e "s|\'$var=$val\'||")',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (file_exists(SOURCE_PATH . '/php-src/configure.ac.bak')) {
|
if (file_exists(SOURCE_PATH . '/php-src/configure.ac.bak')) {
|
||||||
// restore configure.ac
|
// restore configure.ac
|
||||||
FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/configure.ac');
|
FileSystem::restoreBackupFile(SOURCE_PATH . '/php-src/configure.ac');
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use SPC\store\CurlHook;
|
|||||||
use SPC\store\Downloader;
|
use SPC\store\Downloader;
|
||||||
use SPC\store\FileSystem;
|
use SPC\store\FileSystem;
|
||||||
use SPC\store\LockFile;
|
use SPC\store\LockFile;
|
||||||
|
use SPC\util\SPCTarget;
|
||||||
|
|
||||||
class Zig extends CustomPackage
|
class Zig extends CustomPackage
|
||||||
{
|
{
|
||||||
@@ -157,32 +158,97 @@ class Zig extends CustomPackage
|
|||||||
$profileLib = "{$libDir}/libclang_rt.profile.a";
|
$profileLib = "{$libDir}/libclang_rt.profile.a";
|
||||||
$crtBegin = "{$libDir}/clang_rt.crtbegin.o";
|
$crtBegin = "{$libDir}/clang_rt.crtbegin.o";
|
||||||
$crtEnd = "{$libDir}/clang_rt.crtend.o";
|
$crtEnd = "{$libDir}/clang_rt.crtend.o";
|
||||||
if (file_exists($profileLib) && file_exists($crtBegin) && file_exists($crtEnd)) {
|
$cpuModelLib = "{$libDir}/libclang_rt.cpu_model.a";
|
||||||
|
if (file_exists($profileLib) && file_exists($crtBegin) && file_exists($crtEnd) && file_exists($cpuModelLib)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$zig = "{$zig_bin_dir}/zig";
|
$zig = "{$zig_bin_dir}/zig";
|
||||||
$verLine = trim((string) shell_exec(escapeshellarg($zig) . ' cc --version 2>/dev/null'));
|
$verLine = trim((string) shell_exec(escapeshellarg($zig) . ' cc --version 2>/dev/null'));
|
||||||
if (!preg_match('/clang version (\d+\.\d+\.\d+)/', $verLine, $m)) {
|
if (!preg_match('/clang version (\d+\.\d+\.\d+)/', $verLine, $m)) {
|
||||||
logger()->warning('[zig] could not detect bundled clang version; skipping runtime bit build (--pgo + shared libs without __dso_handle)');
|
throw new \RuntimeException('[zig] could not detect bundled clang version; cannot build clang runtime bits (--pgo, __dso_handle, __cpu_model)');
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
$llvmVersion = $m[1];
|
$llvmVersion = $m[1];
|
||||||
logger()->info("Building clang runtime bits for LLVM {$llvmVersion} (zig's bundled clang)");
|
logger()->info("Building clang runtime bits for LLVM {$llvmVersion} (zig's bundled clang)");
|
||||||
|
|
||||||
$srcRoot = $this->fetchCompilerRtSource($llvmVersion);
|
$srcRoot = $this->fetchCompilerRtSource($llvmVersion);
|
||||||
if ($srcRoot === null) {
|
if ($srcRoot === null) {
|
||||||
return;
|
throw new \RuntimeException("[zig] failed to fetch compiler-rt {$llvmVersion} sources; cannot build clang runtime bits (--pgo, __dso_handle, __cpu_model)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$targetFlag = $this->baselineZigTarget();
|
||||||
|
|
||||||
f_mkdir($libDir, recursive: true);
|
f_mkdir($libDir, recursive: true);
|
||||||
if (!file_exists($profileLib)) {
|
if (!file_exists($profileLib)) {
|
||||||
$this->buildProfileRuntime($zig, $srcRoot, $profileLib);
|
$this->buildProfileRuntime($zig, $srcRoot, $profileLib, $targetFlag);
|
||||||
}
|
}
|
||||||
if (!file_exists($crtBegin) || !file_exists($crtEnd)) {
|
if (!file_exists($crtBegin) || !file_exists($crtEnd)) {
|
||||||
$this->buildCrtObjects($zig, $srcRoot, $crtBegin, $crtEnd);
|
$this->buildCrtObjects($zig, $srcRoot, $crtBegin, $crtEnd, $targetFlag);
|
||||||
|
}
|
||||||
|
if (!file_exists($cpuModelLib)) {
|
||||||
|
$this->buildCpuModelBuiltins($zig, $srcRoot, $cpuModelLib, $targetFlag);
|
||||||
}
|
}
|
||||||
FileSystem::removeDir($srcRoot);
|
FileSystem::removeDir($srcRoot);
|
||||||
|
|
||||||
|
// A zig install missing any of these degrades silently at build time
|
||||||
|
// (no .profraw with --pgo, no __dso_handle in shared libs, unresolved
|
||||||
|
// __cpu_model for __builtin_cpu_supports — the last one even changes
|
||||||
|
// which code paths PHP's configure picks, making builds
|
||||||
|
// machine-dependent). Fail the install instead.
|
||||||
|
$missing = array_filter(
|
||||||
|
[$profileLib, $crtBegin, $crtEnd, $cpuModelLib],
|
||||||
|
fn ($f) => !file_exists($f)
|
||||||
|
);
|
||||||
|
if ($missing !== []) {
|
||||||
|
throw new \RuntimeException('[zig] failed to build clang runtime bits: missing ' . implode(', ', array_map('basename', $missing)) . ' (see warnings above)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A concrete `-target {arch}-linux-{abi}` for the clang runtime bits.
|
||||||
|
*/
|
||||||
|
private function baselineZigTarget(): string
|
||||||
|
{
|
||||||
|
$arch = SPCTarget::getTargetArch();
|
||||||
|
$abi = SPCTarget::getLibc() === 'musl' ? 'musl' : 'gnu';
|
||||||
|
return "-target {$arch}-linux-{$abi}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildCpuModelBuiltins(string $zig, string $srcRoot, string $libPath, string $targetFlag): void
|
||||||
|
{
|
||||||
|
$builtins = "{$srcRoot}/lib/builtins";
|
||||||
|
$arch = php_uname('m');
|
||||||
|
$cpuModelDir = "{$builtins}/cpu_model";
|
||||||
|
if (is_dir($cpuModelDir)) {
|
||||||
|
$src = match (true) {
|
||||||
|
in_array($arch, ['x86_64', 'amd64', 'i386', 'i686', 'x86'], true) => "{$cpuModelDir}/x86.c",
|
||||||
|
in_array($arch, ['aarch64', 'arm64'], true) => "{$cpuModelDir}/aarch64.c",
|
||||||
|
str_starts_with($arch, 'riscv') => "{$cpuModelDir}/riscv.c",
|
||||||
|
default => null,
|
||||||
|
};
|
||||||
|
$includes = '-I' . escapeshellarg($builtins) . ' -I' . escapeshellarg($cpuModelDir);
|
||||||
|
} else {
|
||||||
|
$src = "{$builtins}/cpu_model.c";
|
||||||
|
$includes = '-I' . escapeshellarg($builtins);
|
||||||
|
}
|
||||||
|
if ($src === null || !is_file($src)) {
|
||||||
|
logger()->warning("[zig] cpu_model source not found for arch {$arch} under {$builtins} — __builtin_cpu_supports/__cpu_model will be unresolved");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$objDir = "{$srcRoot}/obj-cpu-model";
|
||||||
|
f_mkdir($objDir, recursive: true);
|
||||||
|
$obj = "{$objDir}/cpu_model.o";
|
||||||
|
$cflags = $targetFlag . ' -c -O2 -fPIC ' . $includes;
|
||||||
|
$cmd = escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($obj) . ' ' . escapeshellarg($src) . ' 2>&1';
|
||||||
|
if (!$this->runZigCmd($cmd, $obj, "failed to compile {$src}")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$arCmd = escapeshellarg($zig) . ' ar rcs ' . escapeshellarg($libPath) . ' ' . escapeshellarg($obj) . ' 2>&1';
|
||||||
|
if (!$this->runZigCmd($arCmd, $libPath, 'zig ar failed for cpu_model')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger()->info('[zig] libclang_rt.cpu_model.a installed (' . filesize($libPath) . ' bytes)');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function fetchCompilerRtSource(string $llvmVersion): ?string
|
private function fetchCompilerRtSource(string $llvmVersion): ?string
|
||||||
@@ -206,7 +272,7 @@ class Zig extends CustomPackage
|
|||||||
return $srcRoot;
|
return $srcRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildProfileRuntime(string $zig, string $srcRoot, string $libPath): void
|
private function buildProfileRuntime(string $zig, string $srcRoot, string $libPath, string $targetFlag): void
|
||||||
{
|
{
|
||||||
$profileSrc = "{$srcRoot}/lib/profile";
|
$profileSrc = "{$srcRoot}/lib/profile";
|
||||||
$profileInc = "{$srcRoot}/include";
|
$profileInc = "{$srcRoot}/include";
|
||||||
@@ -230,7 +296,7 @@ class Zig extends CustomPackage
|
|||||||
|
|
||||||
$objDir = "{$srcRoot}/obj-profile";
|
$objDir = "{$srcRoot}/obj-profile";
|
||||||
f_mkdir($objDir, recursive: true);
|
f_mkdir($objDir, recursive: true);
|
||||||
$cflags = '-c -O2 -fPIC -fvisibility=hidden ' .
|
$cflags = $targetFlag . ' -c -O2 -fPIC -fvisibility=hidden ' .
|
||||||
'-I' . escapeshellarg($profileInc) . ' ' .
|
'-I' . escapeshellarg($profileInc) . ' ' .
|
||||||
'-DCOMPILER_RT_HAS_ATOMICS=1 -DCOMPILER_RT_HAS_FCNTL_LCK=1 -DCOMPILER_RT_HAS_UNAME=1';
|
'-DCOMPILER_RT_HAS_ATOMICS=1 -DCOMPILER_RT_HAS_FCNTL_LCK=1 -DCOMPILER_RT_HAS_UNAME=1';
|
||||||
$objs = [];
|
$objs = [];
|
||||||
@@ -249,7 +315,7 @@ class Zig extends CustomPackage
|
|||||||
logger()->info('[zig] libclang_rt.profile.a installed (' . filesize($libPath) . ' bytes)');
|
logger()->info('[zig] libclang_rt.profile.a installed (' . filesize($libPath) . ' bytes)');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function buildCrtObjects(string $zig, string $srcRoot, string $crtBegin, string $crtEnd): void
|
private function buildCrtObjects(string $zig, string $srcRoot, string $crtBegin, string $crtEnd, string $targetFlag): void
|
||||||
{
|
{
|
||||||
$beginSrc = "{$srcRoot}/lib/builtins/crtbegin.c";
|
$beginSrc = "{$srcRoot}/lib/builtins/crtbegin.c";
|
||||||
$endSrc = "{$srcRoot}/lib/builtins/crtend.c";
|
$endSrc = "{$srcRoot}/lib/builtins/crtend.c";
|
||||||
@@ -257,7 +323,7 @@ class Zig extends CustomPackage
|
|||||||
logger()->error("[zig] crtbegin/crtend source missing under {$srcRoot}/lib/builtins — shared libs will lack __dso_handle");
|
logger()->error("[zig] crtbegin/crtend source missing under {$srcRoot}/lib/builtins — shared libs will lack __dso_handle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$cflags = '-c -O2 -fPIC -fvisibility=hidden -DCRT_HAS_INITFINI_ARRAY';
|
$cflags = $targetFlag . ' -c -O2 -fPIC -fvisibility=hidden -DCRT_HAS_INITFINI_ARRAY';
|
||||||
foreach ([[$beginSrc, $crtBegin], [$endSrc, $crtEnd]] as [$src, $dst]) {
|
foreach ([[$beginSrc, $crtBegin], [$endSrc, $crtEnd]] as [$src, $dst]) {
|
||||||
$cmd = escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($dst) . ' ' . escapeshellarg($src) . ' 2>&1';
|
$cmd = escapeshellarg($zig) . ' cc ' . $cflags . ' -o ' . escapeshellarg($dst) . ' ' . escapeshellarg($src) . ' 2>&1';
|
||||||
if (!$this->runZigCmd($cmd, $dst, "failed to compile {$src}")) {
|
if (!$this->runZigCmd($cmd, $dst, "failed to compile {$src}")) {
|
||||||
|
|||||||
@@ -27,12 +27,14 @@ while [[ $# -gt 0 ]]; do
|
|||||||
-march=*|-mcpu=*)
|
-march=*|-mcpu=*)
|
||||||
OPT_NAME="${1%%=*}"
|
OPT_NAME="${1%%=*}"
|
||||||
OPT_VALUE="${1#*=}"
|
OPT_VALUE="${1#*=}"
|
||||||
# Skip armv8- flags entirely as Zig doesn't support them
|
# zig rejects -march=armv8-a but accepts -mcpu=generic+v8a; rewrite
|
||||||
if [[ "$OPT_VALUE" == armv8-* ]]; then
|
# armv<X>[.<Y>]-a[+feat] -> generic+v<X>[_<Y>]a[+feat] so it goes through.
|
||||||
shift
|
if [[ "$OPT_VALUE" =~ ^armv([89])(\.([0-9]+))?-a(\+.*)?$ ]]; then
|
||||||
continue
|
arch_feat="v${BASH_REMATCH[1]}"
|
||||||
|
[[ -n "${BASH_REMATCH[3]}" ]] && arch_feat="${arch_feat}_${BASH_REMATCH[3]}"
|
||||||
|
OPT_VALUE="generic+${arch_feat}a${BASH_REMATCH[4]}"
|
||||||
fi
|
fi
|
||||||
# replace -march=x86-64 with -march=x86_64
|
# zig uses snake_case in CPU/feature names (x86-64 -> x86_64).
|
||||||
OPT_VALUE="${OPT_VALUE//-/_}"
|
OPT_VALUE="${OPT_VALUE//-/_}"
|
||||||
PARSED_ARGS+=("${OPT_NAME}=${OPT_VALUE}")
|
PARSED_ARGS+=("${OPT_NAME}=${OPT_VALUE}")
|
||||||
shift
|
shift
|
||||||
@@ -60,10 +62,13 @@ for _a in "${PARSED_ARGS[@]}"; do
|
|||||||
done
|
done
|
||||||
[[ "$SPC_COMPILER_EXTRA" == *-fprofile-generate* || "$SPC_COMPILER_EXTRA" == *-fcs-profile-generate* ]] && NEED_PROFILE_RT=1
|
[[ "$SPC_COMPILER_EXTRA" == *-fprofile-generate* || "$SPC_COMPILER_EXTRA" == *-fcs-profile-generate* ]] && NEED_PROFILE_RT=1
|
||||||
if [[ $IS_LINK -eq 1 && $NEED_PROFILE_RT -eq 1 && -f "$SCRIPT_DIR/lib/libclang_rt.profile.a" ]]; then
|
if [[ $IS_LINK -eq 1 && $NEED_PROFILE_RT -eq 1 && -f "$SCRIPT_DIR/lib/libclang_rt.profile.a" ]]; then
|
||||||
PARSED_ARGS+=("$SCRIPT_DIR/lib/libclang_rt.profile.a" "-Wl,-u,__llvm_profile_runtime")
|
PARSED_ARGS+=("-x" "none" "$SCRIPT_DIR/lib/libclang_rt.profile.a" "-Wl,-u,__llvm_profile_runtime")
|
||||||
fi
|
fi
|
||||||
if [[ $IS_LINK -eq 1 && $NEED_CRT -eq 1 && -f "$SCRIPT_DIR/lib/clang_rt.crtbegin.o" && -f "$SCRIPT_DIR/lib/clang_rt.crtend.o" ]]; then
|
if [[ $IS_LINK -eq 1 && $NEED_CRT -eq 1 && -f "$SCRIPT_DIR/lib/clang_rt.crtbegin.o" && -f "$SCRIPT_DIR/lib/clang_rt.crtend.o" ]]; then
|
||||||
PARSED_ARGS+=("$SCRIPT_DIR/lib/clang_rt.crtbegin.o" "$SCRIPT_DIR/lib/clang_rt.crtend.o")
|
PARSED_ARGS+=("-x" "none" "$SCRIPT_DIR/lib/clang_rt.crtbegin.o" "$SCRIPT_DIR/lib/clang_rt.crtend.o")
|
||||||
|
fi
|
||||||
|
if [[ $IS_LINK -eq 1 && -f "$SCRIPT_DIR/lib/libclang_rt.cpu_model.a" ]]; then
|
||||||
|
PARSED_ARGS+=("-x" "none" "$SCRIPT_DIR/lib/libclang_rt.cpu_model.a")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ -n "$SPC_TARGET" ]] && TARGET="-target $SPC_TARGET" || TARGET=""
|
[[ -n "$SPC_TARGET" ]] && TARGET="-target $SPC_TARGET" || TARGET=""
|
||||||
|
|||||||
@@ -50,6 +50,15 @@ class ZigToolchain implements ToolchainInterface
|
|||||||
$extra_vars = getenv('SPC_EXTRA_PHP_VARS') ?: '';
|
$extra_vars = getenv('SPC_EXTRA_PHP_VARS') ?: '';
|
||||||
GlobalEnvManager::putenv("SPC_EXTRA_PHP_VARS=php_cv_have_avx512=no php_cv_have_avx512vbmi=no {$extra_vars}");
|
GlobalEnvManager::putenv("SPC_EXTRA_PHP_VARS=php_cv_have_avx512=no php_cv_have_avx512vbmi=no {$extra_vars}");
|
||||||
}
|
}
|
||||||
|
// An __attribute__((ifunc)) in LTO bitcode crashes zig 0.16's lld (LLVM 21)
|
||||||
|
// during thin-link symbol resolution
|
||||||
|
$all_flags = $cflags . ' ' . (getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS') ?: '') . ' ' . (getenv('SPC_DEFAULT_LD_FLAGS') ?: '');
|
||||||
|
if (str_contains($all_flags, '-flto')) {
|
||||||
|
$extra_vars = getenv('SPC_EXTRA_PHP_VARS') ?: '';
|
||||||
|
if (!str_contains($extra_vars, 'ax_cv_have_func_attribute_ifunc')) {
|
||||||
|
GlobalEnvManager::putenv("SPC_EXTRA_PHP_VARS={$extra_vars} ax_cv_have_func_attribute_ifunc=no");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getCompilerInfo(): ?string
|
public function getCompilerInfo(): ?string
|
||||||
|
|||||||
Reference in New Issue
Block a user