2025-06-29 16:00:17 +08:00
< ? php
declare ( strict_types = 1 );
namespace SPC\toolchain ;
2025-08-06 20:43:23 +08:00
use SPC\exception\EnvironmentException ;
2025-07-01 14:01:48 +07:00
use SPC\store\pkg\Zig ;
use SPC\util\GlobalEnvManager ;
2025-06-29 16:00:17 +08:00
class ZigToolchain implements ToolchainInterface
{
2025-07-01 14:01:48 +07:00
public function initEnv () : void
{
2025-07-01 17:08:19 +07:00
// Set environment variables for zig toolchain
2025-07-01 14:02:10 +07:00
GlobalEnvManager :: putenv ( 'SPC_LINUX_DEFAULT_CC=zig-cc' );
GlobalEnvManager :: putenv ( 'SPC_LINUX_DEFAULT_CXX=zig-c++' );
2025-07-26 21:44:01 +07:00
GlobalEnvManager :: putenv ( 'SPC_LINUX_DEFAULT_AR=zig-ar' );
2025-07-27 01:07:54 +07:00
GlobalEnvManager :: putenv ( 'SPC_LINUX_DEFAULT_LD=zig-ld.lld' );
2025-07-05 10:48:56 +08:00
2025-07-26 21:44:01 +07:00
// Generate additional objects needed for zig toolchain
2025-07-05 10:48:56 +08:00
$paths = [ '/usr/lib/gcc' , '/usr/local/lib/gcc' ];
$objects = [ 'crtbeginS.o' , 'crtendS.o' ];
$found = [];
foreach ( $objects as $obj ) {
$located = null ;
foreach ( $paths as $base ) {
$output = shell_exec ( " find { $base } -name { $obj } 2>/dev/null | grep -v '/32/' | head -n 1 " );
$line = trim (( string ) $output );
if ( $line !== '' ) {
$located = $line ;
break ;
}
}
if ( $located ) {
$found [] = $located ;
}
}
2025-07-22 13:16:26 +08:00
GlobalEnvManager :: putenv ( 'SPC_EXTRA_RUNTIME_OBJECTS=' . implode ( ' ' , $found ));
}
2025-07-05 10:48:56 +08:00
2025-07-22 13:16:26 +08:00
public function afterInit () : void
{
2025-09-09 12:10:06 +07:00
if ( ! Zig :: isInstalled ()) {
2025-08-06 20:43:23 +08:00
throw new EnvironmentException ( 'You are building with zig, but zig is not installed, please install zig first. (You can use `doctor` command to install it)' );
2025-07-22 13:16:26 +08:00
}
2025-09-09 12:10:06 +07:00
GlobalEnvManager :: addPathIfNotExists ( Zig :: getPath ());
2025-07-25 16:26:07 +07:00
f_passthru ( 'ulimit -n 2048' ); // zig opens extra file descriptors, so when a lot of extensions are built statically, 1024 is not enough
2025-07-24 15:51:08 +07:00
$cflags = getenv ( 'SPC_DEFAULT_C_FLAGS' ) ? : '' ;
$cxxflags = getenv ( 'SPC_DEFAULT_CXX_FLAGS' ) ? : '' ;
$extraCflags = getenv ( 'SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS' ) ? : '' ;
$cflags = trim ( $cflags . ' -Wno-date-time' );
$cxxflags = trim ( $cxxflags . ' -Wno-date-time' );
$extraCflags = trim ( $extraCflags . ' -Wno-date-time' );
2025-07-24 18:43:10 +07:00
GlobalEnvManager :: putenv ( " SPC_DEFAULT_C_FLAGS= { $cflags } " );
GlobalEnvManager :: putenv ( " SPC_DEFAULT_CXX_FLAGS= { $cxxflags } " );
2025-07-24 15:51:08 +07:00
GlobalEnvManager :: putenv ( " SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS= { $extraCflags } " );
2025-07-26 23:46:36 +07:00
GlobalEnvManager :: putenv ( 'RANLIB=zig-ranlib' );
GlobalEnvManager :: putenv ( 'OBJCOPY=zig-objcopy' );
2025-07-24 15:51:08 +07:00
$extra_libs = getenv ( 'SPC_EXTRA_LIBS' ) ? : '' ;
if ( ! str_contains ( $extra_libs , '-lunwind' )) {
// Add unwind library if not already present
$extra_libs = trim ( $extra_libs . ' -lunwind' );
GlobalEnvManager :: putenv ( " SPC_EXTRA_LIBS= { $extra_libs } " );
}
2025-10-11 10:38:51 +02:00
$cflags = getenv ( 'SPC_DEFAULT_C_FLAGS' ) ? : getenv ( 'CFLAGS' ) ? : '' ;
$has_avx512 = str_contains ( $cflags , '-mavx512' ) || str_contains ( $cflags , '-march=x86-64-v4' );
if ( ! $has_avx512 ) {
2025-10-12 16:42:38 +08:00
GlobalEnvManager :: putenv ( 'SPC_EXTRA_PHP_VARS=php_cv_have_avx512=no php_cv_have_avx512vbmi=no' );
2025-10-11 10:38:51 +02:00
}
2025-07-05 10:48:56 +08:00
}
2025-08-01 12:48:48 +08:00
public function getCompilerInfo () : ? string
{
$version = shell ( false ) -> execWithResult ( 'zig version' , false )[ 1 ][ 0 ] ? ? '' ;
return trim ( " zig { $version } " );
}
2025-06-29 16:00:17 +08:00
}