mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-18 04:44:53 +08:00
Suggestions
This commit is contained in:
parent
0598eff9c5
commit
977fbaa8ef
@ -56,7 +56,7 @@ SPC_CMD_VAR_FRANKENPHP_XCADDY_MODULES="--with github.com/dunglas/frankenphp/cadd
|
||||
|
||||
[windows]
|
||||
; build target: win7-static
|
||||
SPC_TARGET=msvc-static
|
||||
SPC_TARGET=native
|
||||
; php-sdk-binary-tools path
|
||||
PHP_SDK_PATH="${WORKING_DIR}\php-sdk-binary-tools"
|
||||
; upx executable path
|
||||
@ -75,7 +75,9 @@ SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime
|
||||
; - musl-static (default): pure static linking, using musl-libc, can run on any linux distro.
|
||||
; - musl: static linking with dynamic linking to musl-libc, can run on musl-based linux distro.
|
||||
; - glibc: static linking with dynamic linking to glibc, can run on glibc-based linux distro.
|
||||
SPC_TARGET=musl-static
|
||||
|
||||
; include PATH for musl libc.
|
||||
SPC_LIBC=musl
|
||||
; compiler environments
|
||||
CC=${SPC_LINUX_DEFAULT_CC}
|
||||
CXX=${SPC_LINUX_DEFAULT_CXX}
|
||||
@ -122,7 +124,7 @@ SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -Wl,-O1 -pie"
|
||||
[macos]
|
||||
; build target: macho or macho (possibly we could support macho-universal in the future)
|
||||
; Currently we do not support universal and cross-compilation for macOS.
|
||||
SPC_TARGET=macho
|
||||
SPC_TARGET=native
|
||||
; compiler environments
|
||||
CC=clang
|
||||
CXX=clang++
|
||||
|
||||
@ -10,6 +10,7 @@ use SPC\exception\WrongUsageException;
|
||||
use SPC\store\Config;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\SPCConfigUtil;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class Extension
|
||||
{
|
||||
@ -532,6 +533,11 @@ class Extension
|
||||
$sharedLibString .= '-l' . $lib . ' ';
|
||||
}
|
||||
}
|
||||
// move static libstdc++ to shared if we are on non-full-static build target
|
||||
if (!SPCTarget::isStaticTarget() && in_array(SPCTarget::getLibc(), SPCTarget::LIBC_LIST)) {
|
||||
$staticLibString .= ' -lstdc++';
|
||||
$sharedLibString = str_replace('-lstdc++', '', $sharedLibString);
|
||||
}
|
||||
return [trim($staticLibString), trim($sharedLibString)];
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,6 @@ namespace SPC\builder\extension;
|
||||
|
||||
use SPC\builder\Extension;
|
||||
use SPC\util\CustomExt;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
#[CustomExt('imagick')]
|
||||
class imagick extends Extension
|
||||
@ -16,15 +15,4 @@ class imagick extends Extension
|
||||
$disable_omp = ' ac_cv_func_omp_pause_resource_all=no';
|
||||
return '--with-imagick=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . $disable_omp;
|
||||
}
|
||||
|
||||
protected function getStaticAndSharedLibs(): array
|
||||
{
|
||||
// on centos 7, it will use the symbol _ZTINSt6thread6_StateE, which is not defined in system libstdc++.so.6
|
||||
[$static, $shared] = parent::getStaticAndSharedLibs();
|
||||
if (SPCTarget::isTarget(SPCTarget::GLIBC)) {
|
||||
$static .= ' -lstdc++';
|
||||
$shared = str_replace('-lstdc++', '', $shared);
|
||||
}
|
||||
return [$static, $shared];
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ namespace SPC\builder\linux;
|
||||
|
||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class SystemUtil
|
||||
{
|
||||
@ -189,12 +188,12 @@ class SystemUtil
|
||||
/**
|
||||
* Get libc version string from ldd
|
||||
*/
|
||||
public static function getLibcVersionIfExists(): ?string
|
||||
public static function getLibcVersionIfExists(string $libc): ?string
|
||||
{
|
||||
if (self::$libc_version !== null) {
|
||||
return self::$libc_version;
|
||||
}
|
||||
if (SPCTarget::isTarget(SPCTarget::GLIBC)) {
|
||||
if ($libc === 'glibc') {
|
||||
$result = shell()->execWithResult('ldd --version', false);
|
||||
if ($result[0] !== 0) {
|
||||
return null;
|
||||
@ -209,7 +208,7 @@ class SystemUtil
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (SPCTarget::isTarget(SPCTarget::MUSL_STATIC)) {
|
||||
if ($libc === 'musl') {
|
||||
if (self::isMuslDist()) {
|
||||
$result = shell()->execWithResult('ldd 2>&1', false);
|
||||
} else {
|
||||
|
||||
@ -17,7 +17,7 @@ class icu extends LinuxLibraryBase
|
||||
{
|
||||
$cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1 -DPIC -fPIC"';
|
||||
$cxxflags = 'CXXFLAGS="-std=c++17 -DPIC -fPIC -fno-ident"';
|
||||
$ldflags = SPCTarget::isTarget(SPCTarget::MUSL_STATIC) ? 'LDFLAGS="-static"' : '';
|
||||
$ldflags = SPCTarget::isStaticTarget() ? 'LDFLAGS="-static"' : '';
|
||||
shell()->cd($this->source_dir . '/source')->initializeEnv($this)
|
||||
->exec(
|
||||
"{$cppflags} {$cxxflags} {$ldflags} " .
|
||||
|
||||
@ -29,6 +29,7 @@ class MacOSBuilder extends UnixBuilderBase
|
||||
|
||||
// apply global environment variables
|
||||
GlobalEnvManager::init();
|
||||
GlobalEnvManager::afterInit();
|
||||
|
||||
// ---------- set necessary compile vars ----------
|
||||
// concurrency
|
||||
|
||||
@ -201,7 +201,7 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
$util = new SPCConfigUtil($this);
|
||||
$config = $util->config($this->ext_list, $this->lib_list, $this->getOption('with-suggested-exts'), $this->getOption('with-suggested-libs'));
|
||||
$lens = "{$config['cflags']} {$config['ldflags']} {$config['libs']}";
|
||||
if (SPCTarget::isTarget(SPCTarget::MUSL_STATIC)) {
|
||||
if (SPCTarget::isStaticTarget()) {
|
||||
$lens .= ' -static';
|
||||
}
|
||||
[$ret, $out] = shell()->cd($sample_file_path)->execWithResult(getenv('CC') . ' -o embed embed.c ' . $lens);
|
||||
@ -335,7 +335,7 @@ abstract class UnixBuilderBase extends BuilderBase
|
||||
$debugFlags = $this->getOption('no-strip') ? "'-w -s' " : '';
|
||||
$extLdFlags = "-extldflags '-pie'";
|
||||
$muslTags = '';
|
||||
if (SPCTarget::isTarget(SPCTarget::MUSL_STATIC)) {
|
||||
if (SPCTarget::isStaticTarget()) {
|
||||
$extLdFlags = "-extldflags '-static-pie -Wl,-z,stack-size=0x80000'";
|
||||
$muslTags = 'static_build,';
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
|
||||
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\executor\UnixAutoconfExecutor;
|
||||
use SPC\util\SPCTarget;
|
||||
@ -15,6 +16,7 @@ trait imagemagick
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
protected function build(): void
|
||||
{
|
||||
@ -36,11 +38,11 @@ trait imagemagick
|
||||
'--without-x',
|
||||
);
|
||||
|
||||
// special: linux musl-static needs `-static`
|
||||
$ldflags = !SPCTarget::isTarget(SPCTarget::MUSL_STATIC) ? ('-static -ldl') : '-ldl';
|
||||
// special: linux-static target needs `-static`
|
||||
$ldflags = SPCTarget::isStaticTarget() ? ('-static -ldl') : '-ldl';
|
||||
|
||||
// special: macOS needs -iconv
|
||||
$libs = SPCTarget::isTarget(SPCTarget::MACHO) ? '-liconv' : '';
|
||||
$libs = SPCTarget::getTargetOS() === 'Darwin' ? '-liconv' : '';
|
||||
|
||||
$ac->appendEnv([
|
||||
'LDFLAGS' => $ldflags,
|
||||
|
||||
@ -12,7 +12,7 @@ trait ldap
|
||||
{
|
||||
public function patchBeforeBuild(): bool
|
||||
{
|
||||
$extra = SPCTarget::isTarget(SPCTarget::GLIBC) ? '-ldl -lpthread -lm -lresolv -lutil' : '';
|
||||
$extra = SPCTarget::getLibc() === 'glibc' ? '-ldl -lpthread -lm -lresolv -lutil' : '';
|
||||
FileSystem::replaceFileStr($this->source_dir . '/configure', '"-lssl -lcrypto', '"-lssl -lcrypto -lz ' . $extra);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -14,9 +14,9 @@ trait mimalloc
|
||||
$cmake = UnixCMakeExecutor::create($this)
|
||||
->addConfigureArgs(
|
||||
'-DMI_BUILD_SHARED=OFF',
|
||||
'-DMI_INSTALL_TOPLEVEL=ON'
|
||||
'-DMI_INSTALL_TOPLEVEL=ON',
|
||||
);
|
||||
if (SPCTarget::isTarget(SPCTarget::MUSL) || SPCTarget::isTarget(SPCTarget::MUSL_STATIC)) {
|
||||
if (SPCTarget::getLibc() === 'musl') {
|
||||
$cmake->addConfigureArgs('-DMI_LIBC_MUSL=ON');
|
||||
}
|
||||
$cmake->build();
|
||||
|
||||
@ -51,7 +51,7 @@ trait postgresql
|
||||
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||
if (!empty($output[1][0])) {
|
||||
$ldflags = $output[1][0];
|
||||
$envs .= SPCTarget::isTarget(SPCTarget::MUSL_STATIC) ? " LDFLAGS=\"{$ldflags} -static\" " : " LDFLAGS=\"{$ldflags}\" ";
|
||||
$envs .= SPCTarget::isStaticTarget() ? " LDFLAGS=\"{$ldflags} -static\" " : " LDFLAGS=\"{$ldflags}\" ";
|
||||
}
|
||||
$output = shell()->execWithResult("pkg-config --libs-only-l --static {$packages}");
|
||||
$error_exec_cnt += $output[0] === 0 ? 0 : 1;
|
||||
|
||||
@ -34,6 +34,7 @@ class WindowsBuilder extends BuilderBase
|
||||
$this->options = $options;
|
||||
|
||||
GlobalEnvManager::init();
|
||||
GlobalEnvManager::afterInit();
|
||||
|
||||
// ---------- set necessary options ----------
|
||||
// set sdk (require visual studio 16 or 17)
|
||||
|
||||
@ -64,8 +64,8 @@ class BuildPHPCommand extends BuildCommand
|
||||
|
||||
// check dynamic extension build env
|
||||
// linux must build with glibc
|
||||
if (!empty($shared_extensions) && SPCTarget::isTarget(SPCTarget::MUSL_STATIC)) {
|
||||
$this->output->writeln('Linux does not support dynamic extension loading with musl-libc full-static build, please build with glibc!');
|
||||
if (!empty($shared_extensions) && SPCTarget::isStaticTarget()) {
|
||||
$this->output->writeln('Linux does not support dynamic extension loading with musl-libc full-static build, please build with shared target!');
|
||||
return static::FAILURE;
|
||||
}
|
||||
$static_and_shared = array_intersect($static_extensions, $shared_extensions);
|
||||
|
||||
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\command;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\builder\traits\UnixSystemUtilTrait;
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\exception\FileSystemException;
|
||||
@ -224,12 +223,8 @@ class DownloadCommand extends BaseCommand
|
||||
'{name}' => $source,
|
||||
'{arch}' => arch2gnu(php_uname('m')),
|
||||
'{os}' => strtolower(PHP_OS_FAMILY),
|
||||
'{libc}' => match (getenv('SPC_TARGET')) {
|
||||
SPCTarget::MUSL_STATIC, SPCTarget::MUSL => 'musl',
|
||||
SPCTarget::GLIBC => 'glibc',
|
||||
default => 'default',
|
||||
},
|
||||
'{libcver}' => PHP_OS_FAMILY === 'Linux' ? (SystemUtil::getLibcVersionIfExists() ?? 'default') : 'default',
|
||||
'{libc}' => SPCTarget::getLibc() ?? 'default',
|
||||
'{libcver}' => SPCTarget::getLibcVersion() ?? 'default',
|
||||
];
|
||||
$find = str_replace(array_keys($replace), array_values($replace), Config::getPreBuilt('match-pattern'));
|
||||
// find filename in asset list
|
||||
|
||||
@ -6,7 +6,6 @@ namespace SPC\command\dev;
|
||||
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\builder\LibraryBase;
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\command\BuildCommand;
|
||||
use SPC\exception\ExceptionHandler;
|
||||
use SPC\exception\FileSystemException;
|
||||
@ -77,12 +76,8 @@ class PackLibCommand extends BuildCommand
|
||||
'{name}' => $lib->getName(),
|
||||
'{arch}' => arch2gnu(php_uname('m')),
|
||||
'{os}' => strtolower(PHP_OS_FAMILY),
|
||||
'{libc}' => match (getenv('SPC_TARGET')) {
|
||||
SPCTarget::MUSL_STATIC, SPCTarget::MUSL => 'musl',
|
||||
SPCTarget::GLIBC => 'glibc',
|
||||
default => 'default',
|
||||
},
|
||||
'{libcver}' => SystemUtil::getLibcVersionIfExists() ?? 'default',
|
||||
'{libc}' => SPCTarget::getLibc() ?? 'default',
|
||||
'{libcver}' => SPCTarget::getLibcVersion() ?? 'default',
|
||||
];
|
||||
// detect suffix, for proper tar option
|
||||
$tar_option = $this->getTarOptionFromSuffix(Config::getPreBuilt('match-pattern'));
|
||||
|
||||
@ -4,7 +4,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\store;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\DownloaderException;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
@ -594,12 +593,8 @@ class Downloader
|
||||
{
|
||||
$os_family = PHP_OS_FAMILY;
|
||||
$gnu_arch = getenv('GNU_ARCH') ?: 'unknown';
|
||||
$libc = match (getenv('SPC_TARGET')) {
|
||||
SPCTarget::MUSL_STATIC, SPCTarget::MUSL => 'musl',
|
||||
SPCTarget::GLIBC => 'glibc',
|
||||
default => 'default',
|
||||
};
|
||||
$libc_version = SystemUtil::getLibcVersionIfExists() ?? 'default';
|
||||
$libc = SPCTarget::getLibc();
|
||||
$libc_version = SPCTarget::getLibcVersion() ?? 'default';
|
||||
|
||||
return "{$source}-{$os_family}-{$gnu_arch}-{$libc}-{$libc_version}";
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ use SPC\builder\unix\UnixBuilderBase;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class SourcePatcher
|
||||
{
|
||||
@ -456,7 +457,7 @@ class SourcePatcher
|
||||
|
||||
public static function patchFfiCentos7FixO3strncmp(): bool
|
||||
{
|
||||
if (PHP_OS_FAMILY !== 'Linux' || SystemUtil::getLibcVersionIfExists() > '2.17') {
|
||||
if (!($ver = SPCTarget::getLibcVersion()) || version_compare($ver, '2.17', '>')) {
|
||||
return false;
|
||||
}
|
||||
if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) {
|
||||
|
||||
@ -7,7 +7,6 @@ namespace SPC\store\pkg;
|
||||
use SPC\store\Downloader;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\store\LockFile;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class GoXcaddy extends CustomPackage
|
||||
{
|
||||
@ -62,7 +61,6 @@ class GoXcaddy extends CustomPackage
|
||||
|
||||
FileSystem::extractPackage($name, $source_type, $filename, $extract);
|
||||
|
||||
GlobalEnvManager::init();
|
||||
// install xcaddy
|
||||
shell()
|
||||
->appendEnv([
|
||||
|
||||
@ -2,30 +2,25 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
namespace SPC\toolchain;
|
||||
|
||||
use SPC\builder\freebsd\SystemUtil as FreeBSDSystemUtil;
|
||||
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class ClangNativeToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
public function initEnv(): void
|
||||
{
|
||||
// native toolchain does not support versioning
|
||||
if (SPCTarget::getTargetSuffix() !== null) {
|
||||
throw new WrongUsageException('Clang native toolchain does not support versioning.');
|
||||
}
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CC=clang');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=clang++');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld');
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
public function afterInit(): void
|
||||
{
|
||||
// check clang exists
|
||||
match (PHP_OS_FAMILY) {
|
||||
@ -2,30 +2,25 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
namespace SPC\toolchain;
|
||||
|
||||
use SPC\builder\freebsd\SystemUtil as FreeBSDSystemUtil;
|
||||
use SPC\builder\linux\SystemUtil as LinuxSystemUtil;
|
||||
use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class GccNativeToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
public function initEnv(): void
|
||||
{
|
||||
// native toolchain does not support versioning
|
||||
if (SPCTarget::getTargetSuffix() !== null) {
|
||||
throw new WrongUsageException('gcc native toolchain does not support versioning.');
|
||||
}
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CC=gcc');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_CXX=g++');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_AR=ar');
|
||||
GlobalEnvManager::putenv('SPC_LINUX_DEFAULT_LD=ld.gold');
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
public function afterInit(): void
|
||||
{
|
||||
// check gcc exists
|
||||
match (PHP_OS_FAMILY) {
|
||||
12
src/SPC/toolchain/MSVCToolchain.php
Normal file
12
src/SPC/toolchain/MSVCToolchain.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\toolchain;
|
||||
|
||||
class MSVCToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(): void {}
|
||||
|
||||
public function afterInit(): void {}
|
||||
}
|
||||
@ -2,20 +2,15 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
namespace SPC\toolchain;
|
||||
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
class MuslToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
public function initEnv(): void
|
||||
{
|
||||
// Check if the target is musl-static (the musl(-shared) target is not supported yet)
|
||||
if (!in_array($target, [SPCTarget::MUSL_STATIC/* , SPCTarget::MUSL */], true)) {
|
||||
throw new WrongUsageException('MuslToolchain can only be used with the "musl-static" target.');
|
||||
}
|
||||
$arch = getenv('GNU_ARCH');
|
||||
// Set environment variables for musl toolchain
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_CC={$arch}-linux-musl-gcc");
|
||||
@ -29,7 +24,7 @@ class MuslToolchain implements ToolchainInterface
|
||||
GlobalEnvManager::putenv("SPC_LINUX_DEFAULT_LIBRARY_PATH=/usr/local/musl/lib:/usr/local/musl/{$arch}-linux-musl/lib");
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
public function afterInit(): void
|
||||
{
|
||||
$arch = getenv('GNU_ARCH');
|
||||
// append LD_LIBRARY_PATH to $configure = getenv('SPC_CMD_PREFIX_PHP_CONFIGURE');
|
||||
@ -2,17 +2,17 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
namespace SPC\toolchain;
|
||||
|
||||
interface ToolchainInterface
|
||||
{
|
||||
/**
|
||||
* Initialize the environment for the given target.
|
||||
*/
|
||||
public function initEnv(string $target): void;
|
||||
public function initEnv(): void;
|
||||
|
||||
/**
|
||||
* Perform actions after the environment has been initialized for the given target.
|
||||
*/
|
||||
public function afterInit(string $target): void;
|
||||
public function afterInit(): void;
|
||||
}
|
||||
52
src/SPC/toolchain/ToolchainManager.php
Normal file
52
src/SPC/toolchain/ToolchainManager.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\toolchain;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
class ToolchainManager
|
||||
{
|
||||
public const array OS_DEFAULT_TOOLCHAIN = [
|
||||
'Linux' => MuslToolchain::class, // use musl toolchain by default, after zig pr merged, change this to ZigToolchain::class
|
||||
'Windows' => MSVCToolchain::class,
|
||||
'Darwin' => ClangNativeToolchain::class,
|
||||
'BSD' => ClangNativeToolchain::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function initToolchain(): void
|
||||
{
|
||||
$libc = getenv('SPC_LIBC');
|
||||
if ($libc !== false) {
|
||||
// uncomment this when zig pr is merged
|
||||
// logger()->warning('SPC_LIBC is deprecated, please use SPC_TARGET instead.');
|
||||
$toolchain = match ($libc) {
|
||||
'musl' => SystemUtil::isMuslDist() ? GccNativeToolchain::class : MuslToolchain::class,
|
||||
'glibc' => !SystemUtil::isMuslDist() ? GccNativeToolchain::class : throw new WrongUsageException('SPC_TARGET must be musl-static or musl for musl dist.'),
|
||||
default => throw new WrongUsageException('Unsupported SPC_LIBC value: ' . $libc),
|
||||
};
|
||||
} else {
|
||||
$toolchain = self::OS_DEFAULT_TOOLCHAIN[PHP_OS_FAMILY];
|
||||
}
|
||||
$toolchainClass = $toolchain;
|
||||
/* @var ToolchainInterface $toolchainClass */
|
||||
(new $toolchainClass())->initEnv();
|
||||
GlobalEnvManager::putenv("SPC_TOOLCHAIN={$toolchain}");
|
||||
}
|
||||
|
||||
public static function afterInitToolchain(): void
|
||||
{
|
||||
if (!getenv('SPC_TOOLCHAIN')) {
|
||||
throw new WrongUsageException('SPC_TOOLCHAIN not set');
|
||||
}
|
||||
$toolchain = getenv('SPC_TOOLCHAIN');
|
||||
/* @var ToolchainInterface $toolchain */
|
||||
(new $toolchain())->afterInit();
|
||||
}
|
||||
}
|
||||
12
src/SPC/toolchain/ZigToolchain.php
Normal file
12
src/SPC/toolchain/ZigToolchain.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\toolchain;
|
||||
|
||||
class ZigToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(): void {}
|
||||
|
||||
public function afterInit(): void {}
|
||||
}
|
||||
@ -4,9 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
|
||||
/**
|
||||
* Environment variable manager
|
||||
@ -63,30 +63,7 @@ class GlobalEnvManager
|
||||
}
|
||||
}
|
||||
|
||||
// deprecated: convert SPC_LIBC to SPC_TARGET
|
||||
if (getenv('SPC_LIBC') !== false) {
|
||||
logger()->warning('SPC_LIBC is deprecated, please use SPC_TARGET instead.');
|
||||
$target = match (getenv('SPC_LIBC')) {
|
||||
'musl' => SPCTarget::MUSL_STATIC,
|
||||
'musl-shared' => SPCTarget::MUSL,
|
||||
'glibc' => SPCTarget::GLIBC,
|
||||
default => throw new WrongUsageException('Unsupported SPC_LIBC value: ' . getenv('SPC_LIBC')),
|
||||
};
|
||||
self::putenv("SPC_TARGET={$target}");
|
||||
self::putenv('SPC_LIBC');
|
||||
}
|
||||
|
||||
// auto-select toolchain based on target and OS temporarily
|
||||
// TODO: use 'zig' instead of 'gcc-native' when ZigToolchain is implemented
|
||||
$toolchain = match (SPCTarget::getTargetName()) {
|
||||
SPCTarget::MUSL_STATIC, SPCTarget::MUSL => SystemUtil::isMuslDist() ? 'gcc-native' : 'musl',
|
||||
SPCTarget::MACHO => 'clang-native',
|
||||
SPCTarget::MSVC_STATIC => 'msvc',
|
||||
SPCTarget::GLIBC => !SystemUtil::isMuslDist() ? 'gcc-native' : throw new WrongUsageException('SPC_TARGET must be musl-static or musl for musl dist.'),
|
||||
default => throw new WrongUsageException('Unknown SPC_TARGET: ' . getenv('SPC_TARGET')),
|
||||
};
|
||||
|
||||
SPCTarget::initTargetForToolchain($toolchain);
|
||||
ToolchainManager::initToolchain();
|
||||
|
||||
// apply second time
|
||||
$ini2 = self::readIniFile();
|
||||
@ -123,9 +100,15 @@ class GlobalEnvManager
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the toolchain after the environment variables are set.
|
||||
* The toolchain or environment availability check is done here.
|
||||
*
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function afterInit(): void
|
||||
{
|
||||
SPCTarget::afterInitTargetForToolchain();
|
||||
ToolchainManager::afterInitToolchain();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -55,7 +55,7 @@ class SPCConfigUtil
|
||||
ob_get_clean();
|
||||
$ldflags = $this->getLdflagsString();
|
||||
$libs = $this->getLibsString($libraries, $with_dependencies);
|
||||
if (SPCTarget::isTarget(SPCTarget::MACHO)) {
|
||||
if (SPCTarget::getTargetOS() === 'Darwin') {
|
||||
$libs .= " {$this->getFrameworksString($extensions)}";
|
||||
}
|
||||
$cflags = $this->getIncludesString();
|
||||
|
||||
@ -4,13 +4,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\util;
|
||||
|
||||
use SPC\builder\linux\SystemUtil;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\toolchain\ClangNativeToolchain;
|
||||
use SPC\util\toolchain\GccNativeToolchain;
|
||||
use SPC\util\toolchain\MSVCToolchain;
|
||||
use SPC\util\toolchain\MuslToolchain;
|
||||
use SPC\util\toolchain\ToolchainInterface;
|
||||
use SPC\util\toolchain\ZigToolchain;
|
||||
|
||||
/**
|
||||
* SPC build target constants and toolchain initialization.
|
||||
@ -18,86 +13,75 @@ use SPC\util\toolchain\ZigToolchain;
|
||||
*/
|
||||
class SPCTarget
|
||||
{
|
||||
public const MUSL = 'musl';
|
||||
|
||||
public const MUSL_STATIC = 'musl-static';
|
||||
|
||||
public const GLIBC = 'glibc';
|
||||
|
||||
public const MACHO = 'macho';
|
||||
|
||||
public const MSVC_STATIC = 'msvc-static';
|
||||
|
||||
public const TOOLCHAIN_LIST = [
|
||||
'musl' => MuslToolchain::class,
|
||||
'gcc-native' => GccNativeToolchain::class,
|
||||
'clang-native' => ClangNativeToolchain::class,
|
||||
'msvc' => MSVCToolchain::class,
|
||||
'zig' => ZigToolchain::class,
|
||||
public const array LIBC_LIST = [
|
||||
'musl',
|
||||
'glibc',
|
||||
];
|
||||
|
||||
public static function isTarget(string $target): bool
|
||||
{
|
||||
$env = getenv('SPC_TARGET');
|
||||
if ($env === false) {
|
||||
return false;
|
||||
}
|
||||
$env = strtolower($env);
|
||||
// ver
|
||||
$env = explode('@', $env)[0];
|
||||
return $env === $target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the target is a full-static target.
|
||||
*/
|
||||
public static function isStaticTarget(): bool
|
||||
{
|
||||
$env = getenv('SPC_TARGET');
|
||||
if ($env === false) {
|
||||
return false;
|
||||
$libc = getenv('SPC_LIBC');
|
||||
// if SPC_LIBC is set, it means the target is static, remove it when 3.0 is released
|
||||
if ($libc === 'musl') {
|
||||
return true;
|
||||
}
|
||||
$env = strtolower($env);
|
||||
// ver
|
||||
$env = explode('@', $env)[0];
|
||||
return str_ends_with($env, '-static');
|
||||
// TODO: add zig target parser here
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function initTargetForToolchain(string $toolchain): void
|
||||
/**
|
||||
* Returns the libc type if set, for other OS, it will always return null.
|
||||
*/
|
||||
public static function getLibc(): ?string
|
||||
{
|
||||
$env = getenv('SPC_TARGET');
|
||||
$libc = getenv('SPC_LIBC');
|
||||
if ($libc !== false) {
|
||||
return $libc;
|
||||
}
|
||||
// TODO: zig target parser
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the libc version if set, for other OS, it will always return null.
|
||||
*/
|
||||
public static function getLibcVersion(): ?string
|
||||
{
|
||||
$env = getenv('SPC_TARGET');
|
||||
$libc = getenv('SPC_LIBC');
|
||||
if ($libc !== false) {
|
||||
// legacy method: get a version from system
|
||||
return SystemUtil::getLibcVersionIfExists($libc);
|
||||
}
|
||||
// TODO: zig target parser
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target OS family, e.g. Linux, Darwin, Windows, BSD.
|
||||
* Currently, we only support native building.
|
||||
*
|
||||
* @return 'BSD'|'Darwin'|'Linux'|'Windows'
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public static function getTargetOS(): string
|
||||
{
|
||||
$target = getenv('SPC_TARGET');
|
||||
$toolchain = strtolower($toolchain);
|
||||
if (isset(self::TOOLCHAIN_LIST[$toolchain])) {
|
||||
$toolchainClass = self::TOOLCHAIN_LIST[$toolchain];
|
||||
/* @var ToolchainInterface $toolchainClass */
|
||||
(new $toolchainClass())->initEnv($target);
|
||||
if ($target === false) {
|
||||
return PHP_OS_FAMILY;
|
||||
}
|
||||
GlobalEnvManager::putenv("SPC_TOOLCHAIN={$toolchain}");
|
||||
}
|
||||
|
||||
public static function afterInitTargetForToolchain()
|
||||
{
|
||||
if (!getenv('SPC_TOOLCHAIN')) {
|
||||
throw new WrongUsageException('SPC_TOOLCHAIN not set');
|
||||
}
|
||||
$toolchain = getenv('SPC_TOOLCHAIN');
|
||||
if (!isset(self::TOOLCHAIN_LIST[$toolchain])) {
|
||||
throw new WrongUsageException("Unknown toolchain: {$toolchain}");
|
||||
}
|
||||
$toolchainClass = self::TOOLCHAIN_LIST[$toolchain];
|
||||
(new $toolchainClass())->afterInit(getenv('SPC_TARGET'));
|
||||
}
|
||||
|
||||
public static function getTargetName(): ?string
|
||||
{
|
||||
$target = getenv('SPC_TARGET');
|
||||
$target = strtolower($target);
|
||||
// ver
|
||||
return explode('@', $target)[0];
|
||||
}
|
||||
|
||||
public static function getTargetSuffix(): ?string
|
||||
{
|
||||
$target = getenv('SPC_TARGET');
|
||||
$target = strtolower($target);
|
||||
// ver
|
||||
return explode('@', $target)[1] ?? null;
|
||||
// TODO: zig target parser like below?
|
||||
return match (true) {
|
||||
str_contains($target, 'linux') => 'Linux',
|
||||
str_contains($target, 'macos') => 'Darwin',
|
||||
str_contains($target, 'windows') => 'Windows',
|
||||
default => throw new WrongUsageException('Cannot parse target.'),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
class MSVCToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void {}
|
||||
|
||||
public function afterInit(string $target): void {}
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace SPC\util\toolchain;
|
||||
|
||||
class ZigToolchain implements ToolchainInterface
|
||||
{
|
||||
public function initEnv(string $target): void
|
||||
{
|
||||
// TODO: Implement zig
|
||||
}
|
||||
|
||||
public function afterInit(string $target): void
|
||||
{
|
||||
// TODO: Implement afterInit() method.
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user