mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-03-17 20:34:51 +08:00
Chore
This commit is contained in:
parent
08fa49b791
commit
29dc5e4ea7
@ -7,10 +7,6 @@ namespace SPC\builder\windows\library;
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\LibraryBase;
|
||||
use SPC\builder\windows\WindowsBuilder;
|
||||
use SPC\exception\FileSystemException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
abstract class WindowsLibraryBase extends LibraryBase
|
||||
{
|
||||
@ -23,50 +19,4 @@ abstract class WindowsLibraryBase extends LibraryBase
|
||||
{
|
||||
return $this->builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws RuntimeException
|
||||
* @throws FileSystemException
|
||||
* @throws WrongUsageException
|
||||
*/
|
||||
public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string
|
||||
{
|
||||
$libs = $include_self ? [$this] : [];
|
||||
if ($recursive) {
|
||||
array_unshift($libs, ...array_values($this->getDependencies(recursive: true)));
|
||||
}
|
||||
|
||||
$sep = match ($style) {
|
||||
'autoconf' => ' ',
|
||||
'cmake' => ';',
|
||||
default => throw new RuntimeException('style only support autoconf and cmake'),
|
||||
};
|
||||
$ret = [];
|
||||
foreach ($libs as $lib) {
|
||||
$libFiles = [];
|
||||
foreach ($lib->getStaticLibs() as $name) {
|
||||
$name = str_replace(' ', '\ ', FileSystem::convertPath(BUILD_LIB_PATH . "/{$name}"));
|
||||
$name = str_replace('"', '\"', $name);
|
||||
$libFiles[] = $name;
|
||||
}
|
||||
array_unshift($ret, implode($sep, $libFiles));
|
||||
}
|
||||
return implode($sep, $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a nmake wrapper file.
|
||||
*
|
||||
* @param string $content nmake wrapper content
|
||||
* @param string $default_filename default nmake wrapper filename
|
||||
* @throws FileSystemException
|
||||
*/
|
||||
public function makeNmakeWrapper(string $content, string $default_filename = ''): string
|
||||
{
|
||||
if ($default_filename === '') {
|
||||
$default_filename = $this->source_dir . '\nmake_wrapper.bat';
|
||||
}
|
||||
FileSystem::writeFile($default_filename, $content);
|
||||
return 'nmake_wrapper.bat';
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,36 +5,42 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\builder\windows\SystemUtil;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\EnvironmentException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libffi_win extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libffi-win';
|
||||
|
||||
protected function build()
|
||||
{
|
||||
$vs_ver_dir = match (SystemUtil::findVisualStudio()['version']) {
|
||||
'vs17' => '/win32/vs17_x64',
|
||||
'vs16' => '/win32/vs16_x64',
|
||||
default => throw new RuntimeException('Current VS version is not supported yet!'),
|
||||
};
|
||||
private string $vs_ver_dir;
|
||||
|
||||
public function validate(): void
|
||||
{
|
||||
$this->vs_ver_dir = match ($ver = SystemUtil::findVisualStudio()['version']) {
|
||||
'vs17' => '\win32\vs17_x64',
|
||||
'vs16' => '\win32\vs16_x64',
|
||||
default => throw new EnvironmentException("Current VS version {$ver} is not supported !"),
|
||||
};
|
||||
}
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
// start build
|
||||
cmd()->cd($this->source_dir . $vs_ver_dir)
|
||||
cmd()->cd($this->source_dir . $this->vs_ver_dir)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper('msbuild'),
|
||||
'libffi-msvc.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'
|
||||
);
|
||||
FileSystem::createDir(BUILD_LIB_PATH);
|
||||
FileSystem::createDir(BUILD_INCLUDE_PATH);
|
||||
copy($this->source_dir . $vs_ver_dir . '\x64\Release\libffi.lib', BUILD_LIB_PATH . '\libffi.lib');
|
||||
copy($this->source_dir . $vs_ver_dir . '\x64\Release\libffi.pdb', BUILD_LIB_PATH . '\libffi.pdb');
|
||||
copy($this->source_dir . '\include\ffi.h', BUILD_INCLUDE_PATH . '\ffi.h');
|
||||
|
||||
FileSystem::copy("{$this->source_dir}{$this->vs_ver_dir}\\x64\\Release\\libffi.lib", BUILD_LIB_PATH . '\libffi.lib');
|
||||
FileSystem::copy("{$this->source_dir}{$this->vs_ver_dir}\\x64\\Release\\libffi.pdb", BUILD_LIB_PATH . '\libffi.pdb');
|
||||
FileSystem::copy($this->source_dir . '\include\ffi.h', BUILD_INCLUDE_PATH . '\ffi.h');
|
||||
|
||||
FileSystem::replaceFileStr(BUILD_INCLUDE_PATH . '\ffi.h', '#define LIBFFI_H', "#define LIBFFI_H\n#define FFI_BUILDING");
|
||||
copy($this->source_dir . '\src\x86\ffitarget.h', BUILD_INCLUDE_PATH . '\ffitarget.h');
|
||||
copy($this->source_dir . '\fficonfig.h', BUILD_INCLUDE_PATH . '\fficonfig.h');
|
||||
FileSystem::copy($this->source_dir . '\src\x86\ffitarget.h', BUILD_INCLUDE_PATH . '\ffitarget.h');
|
||||
FileSystem::copy($this->source_dir . '\fficonfig.h', BUILD_INCLUDE_PATH . '\fficonfig.h');
|
||||
|
||||
// copy($this->source_dir . '\msvc_build\out\static-Release\X64\libffi.lib', BUILD_LIB_PATH . '\libffi.lib');
|
||||
// copy($this->source_dir . '\msvc_build\include\ffi.h', BUILD_INCLUDE_PATH . '\ffi.h');
|
||||
|
||||
@ -5,31 +5,36 @@ declare(strict_types=1);
|
||||
namespace SPC\builder\windows\library;
|
||||
|
||||
use SPC\builder\windows\SystemUtil;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\EnvironmentException;
|
||||
use SPC\store\FileSystem;
|
||||
|
||||
class libiconv_win extends WindowsLibraryBase
|
||||
{
|
||||
public const NAME = 'libiconv-win';
|
||||
|
||||
protected function build()
|
||||
{
|
||||
$vs_ver_dir = match (SystemUtil::findVisualStudio()['version']) {
|
||||
'vs17' => '/MSVC17',
|
||||
'vs16' => '/MSVC16',
|
||||
default => throw new RuntimeException('Current VS version is not supported yet!'),
|
||||
};
|
||||
private string $vs_ver_dir = '';
|
||||
|
||||
public function validate(): void
|
||||
{
|
||||
$this->vs_ver_dir = match ($ver = SystemUtil::findVisualStudio()['version']) {
|
||||
'vs17' => '\MSVC17',
|
||||
'vs16' => '\MSVC16',
|
||||
default => throw new EnvironmentException("Current VS version {$ver} is not supported yet!"),
|
||||
};
|
||||
}
|
||||
|
||||
protected function build(): void
|
||||
{
|
||||
// start build
|
||||
cmd()->cd($this->source_dir . $vs_ver_dir)
|
||||
cmd()->cd($this->source_dir . $this->vs_ver_dir)
|
||||
->execWithWrapper(
|
||||
$this->builder->makeSimpleWrapper('msbuild'),
|
||||
'libiconv.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64'
|
||||
);
|
||||
FileSystem::createDir(BUILD_LIB_PATH);
|
||||
FileSystem::createDir(BUILD_INCLUDE_PATH);
|
||||
copy($this->source_dir . $vs_ver_dir . '\x64\lib\libiconv.lib', BUILD_LIB_PATH . '\libiconv.lib');
|
||||
copy($this->source_dir . $vs_ver_dir . '\x64\lib\libiconv_a.lib', BUILD_LIB_PATH . '\libiconv_a.lib');
|
||||
copy("{$this->source_dir}{$this->vs_ver_dir}\\x64\\lib\\libiconv.lib", BUILD_LIB_PATH . '\libiconv.lib');
|
||||
copy("{$this->source_dir}{$this->vs_ver_dir}\\x64\\lib\\libiconv_a.lib", BUILD_LIB_PATH . '\libiconv_a.lib');
|
||||
copy($this->source_dir . '\source\include\iconv.h', BUILD_INCLUDE_PATH . '\iconv.h');
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ use SPC\builder\traits\UnixSystemUtilTrait;
|
||||
use SPC\doctor\AsCheckItem;
|
||||
use SPC\doctor\AsFixItem;
|
||||
use SPC\doctor\CheckResult;
|
||||
use SPC\exception\RuntimeException;
|
||||
|
||||
class BSDToolCheckList
|
||||
{
|
||||
@ -56,11 +55,8 @@ class BSDToolCheckList
|
||||
} else {
|
||||
$prefix = '';
|
||||
}
|
||||
try {
|
||||
shell(true)->exec("ASSUME_ALWAYS_YES=yes {$prefix}pkg install -y " . implode(' ', $missing));
|
||||
} catch (RuntimeException) {
|
||||
return false;
|
||||
}
|
||||
shell(true)->exec("ASSUME_ALWAYS_YES=yes {$prefix}pkg install -y " . implode(' ', $missing));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SPC\util\executor;
|
||||
use SPC\builder\freebsd\library\BSDLibraryBase;
|
||||
use SPC\builder\linux\library\LinuxLibraryBase;
|
||||
use SPC\builder\macos\library\MacOSLibraryBase;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\SPCException;
|
||||
use SPC\util\shell\UnixShell;
|
||||
|
||||
class UnixAutoconfExecutor extends Executor
|
||||
@ -34,8 +34,7 @@ class UnixAutoconfExecutor extends Executor
|
||||
$args = array_diff($args, $this->ignore_args);
|
||||
$configure_args = implode(' ', $args);
|
||||
|
||||
$this->shell->exec("./configure {$configure_args}");
|
||||
return $this;
|
||||
return $this->seekLogFileOnException(fn () => $this->shell->exec("./configure {$configure_args}"));
|
||||
}
|
||||
|
||||
public function getConfigureArgsString(): string
|
||||
@ -53,15 +52,17 @@ class UnixAutoconfExecutor extends Executor
|
||||
*/
|
||||
public function make(string $target = '', false|string $with_install = 'install', bool $with_clean = true, array $after_env_vars = []): static
|
||||
{
|
||||
if ($with_clean) {
|
||||
$this->shell->exec('make clean');
|
||||
}
|
||||
$after_env_vars_str = $after_env_vars !== [] ? shell()->setEnv($after_env_vars)->getEnvString() : '';
|
||||
$this->shell->exec("make -j{$this->library->getBuilder()->concurrency} {$target} {$after_env_vars_str}");
|
||||
if ($with_install !== false) {
|
||||
$this->shell->exec("make {$with_install}");
|
||||
}
|
||||
return $this;
|
||||
return $this->seekLogFileOnException(function () use ($target, $with_install, $with_clean, $after_env_vars) {
|
||||
if ($with_clean) {
|
||||
$this->shell->exec('make clean');
|
||||
}
|
||||
$after_env_vars_str = $after_env_vars !== [] ? shell()->setEnv($after_env_vars)->getEnvString() : '';
|
||||
$this->shell->exec("make -j{$this->library->getBuilder()->concurrency} {$target} {$after_env_vars_str}");
|
||||
if ($with_install !== false) {
|
||||
$this->shell->exec("make {$with_install}");
|
||||
}
|
||||
return $this->shell;
|
||||
});
|
||||
}
|
||||
|
||||
public function exec(string $cmd): static
|
||||
@ -141,4 +142,24 @@ class UnixAutoconfExecutor extends Executor
|
||||
'LDFLAGS' => "-L{$this->library->getLibDir()}",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* When an exception occurs, this method will check if the config log file exists.
|
||||
*/
|
||||
private function seekLogFileOnException(mixed $callable): static
|
||||
{
|
||||
try {
|
||||
$callable();
|
||||
return $this;
|
||||
} catch (SPCException $e) {
|
||||
if (file_exists("{$this->library->getSourceDir()}/config.log")) {
|
||||
logger()->debug("Config log file found: {$this->library->getSourceDir()}/config.log");
|
||||
$log_file = "lib.{$this->library->getName()}.console.log";
|
||||
logger()->debug('Saved config log file to: ' . SPC_LOGS_DIR . "/{$log_file}");
|
||||
$e->addExtraLogFile("{$this->library->getName()} library config.log", $log_file);
|
||||
copy("{$this->library->getSourceDir()}/config.log", SPC_LOGS_DIR . "/{$log_file}");
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,5 +90,11 @@ const SPC_SOURCE_ARCHIVE = 'archive'; // download as archive
|
||||
const SPC_SOURCE_GIT = 'git'; // download as git repository
|
||||
const SPC_SOURCE_LOCAL = 'local'; // download as local directory
|
||||
|
||||
// spc logs dir
|
||||
const SPC_LOGS_DIR = WORKING_DIR . DIRECTORY_SEPARATOR . 'log';
|
||||
const SPC_OUTPUT_LOG = SPC_LOGS_DIR . DIRECTORY_SEPARATOR . 'spc.output.log';
|
||||
const SPC_SHELL_LOG = SPC_LOGS_DIR . DIRECTORY_SEPARATOR . 'spc.shell.log';
|
||||
const SPC_ENV_LOG = SPC_LOGS_DIR . DIRECTORY_SEPARATOR . 'spc.env.log';
|
||||
|
||||
ConsoleLogger::$date_format = 'H:i:s';
|
||||
ConsoleLogger::$format = '[%date%] [%level_short%] %body%';
|
||||
|
||||
@ -5,8 +5,8 @@ declare(strict_types=1);
|
||||
use Psr\Log\LoggerInterface;
|
||||
use SPC\builder\BuilderBase;
|
||||
use SPC\builder\BuilderProvider;
|
||||
use SPC\exception\ExecutionException;
|
||||
use SPC\exception\InterruptException;
|
||||
use SPC\exception\RuntimeException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\util\shell\UnixShell;
|
||||
use SPC\util\shell\WindowsCmd;
|
||||
@ -165,7 +165,7 @@ function f_passthru(string $cmd): ?bool
|
||||
}
|
||||
$ret = passthru($cmd, $code);
|
||||
if ($code !== 0) {
|
||||
throw new RuntimeException('Command run failed with code[' . $code . ']: ' . $cmd, $code);
|
||||
throw new ExecutionException($cmd, "Direct command run failed with code: {$code}", $code);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
@ -203,7 +203,7 @@ function f_putenv(string $env): bool
|
||||
function get_cmake_version(): ?string
|
||||
{
|
||||
try {
|
||||
[,$output] = shell()->execWithResult('cmake --version', false);
|
||||
[,$output] = shell(false)->execWithResult('cmake --version', false);
|
||||
if (preg_match('/cmake version ([\d.]+)/i', $output[0], $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
@ -244,3 +244,42 @@ function clean_spaces(string $string): string
|
||||
{
|
||||
return trim(preg_replace('/\s+/', ' ', $string));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback function to handle keyboard interrupts (Ctrl+C).
|
||||
*
|
||||
* @param callable $callback callback function to handle keyboard interrupts
|
||||
*/
|
||||
function keyboard_interrupt_register(callable $callback): void
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
sapi_windows_set_ctrl_handler($callback);
|
||||
} elseif (extension_loaded('pcntl')) {
|
||||
pcntl_signal(SIGINT, $callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister the keyboard interrupt handler.
|
||||
*
|
||||
* This function is used to remove the previously registered keyboard interrupt handler.
|
||||
* It should be called when you no longer need to handle keyboard interrupts.
|
||||
*/
|
||||
function keyboard_interrupt_unregister(): void
|
||||
{
|
||||
if (PHP_OS_FAMILY === 'Windows') {
|
||||
sapi_windows_set_ctrl_handler(null);
|
||||
} elseif (extension_loaded('pcntl')) {
|
||||
pcntl_signal(SIGINT, SIG_IGN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip ANSI color codes from a string.
|
||||
*/
|
||||
function strip_ansi_colors(string $text): string
|
||||
{
|
||||
// Regular expression to match ANSI escape sequences
|
||||
// Including color codes, cursor control, clear screen and other control sequences
|
||||
return preg_replace('/\e\[[0-9;]*[a-zA-Z]/', '', $text);
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ use SPC\builder\macos\SystemUtil as MacOSSystemUtil;
|
||||
use SPC\builder\windows\SystemUtil as WindowsSystemUtil;
|
||||
use SPC\ConsoleApplication;
|
||||
use SPC\store\FileSystem;
|
||||
use SPC\util\GlobalEnvManager;
|
||||
|
||||
// static-php-cli version string
|
||||
const SPC_VERSION = ConsoleApplication::VERSION;
|
||||
@ -47,15 +46,15 @@ define('SEPARATED_PATH', [
|
||||
]);
|
||||
|
||||
// add these to env vars with same name
|
||||
GlobalEnvManager::putenv('SPC_VERSION=' . SPC_VERSION);
|
||||
GlobalEnvManager::putenv('BUILD_ROOT_PATH=' . BUILD_ROOT_PATH);
|
||||
GlobalEnvManager::putenv('BUILD_INCLUDE_PATH=' . BUILD_INCLUDE_PATH);
|
||||
GlobalEnvManager::putenv('BUILD_LIB_PATH=' . BUILD_LIB_PATH);
|
||||
GlobalEnvManager::putenv('BUILD_BIN_PATH=' . BUILD_BIN_PATH);
|
||||
GlobalEnvManager::putenv('PKG_ROOT_PATH=' . PKG_ROOT_PATH);
|
||||
GlobalEnvManager::putenv('SOURCE_PATH=' . SOURCE_PATH);
|
||||
GlobalEnvManager::putenv('DOWNLOAD_PATH=' . DOWNLOAD_PATH);
|
||||
GlobalEnvManager::putenv('CPU_COUNT=' . CPU_COUNT);
|
||||
GlobalEnvManager::putenv('SPC_ARCH=' . php_uname('m'));
|
||||
GlobalEnvManager::putenv('GNU_ARCH=' . GNU_ARCH);
|
||||
GlobalEnvManager::putenv('MAC_ARCH=' . MAC_ARCH);
|
||||
putenv('SPC_VERSION=' . SPC_VERSION);
|
||||
putenv('BUILD_ROOT_PATH=' . BUILD_ROOT_PATH);
|
||||
putenv('BUILD_INCLUDE_PATH=' . BUILD_INCLUDE_PATH);
|
||||
putenv('BUILD_LIB_PATH=' . BUILD_LIB_PATH);
|
||||
putenv('BUILD_BIN_PATH=' . BUILD_BIN_PATH);
|
||||
putenv('PKG_ROOT_PATH=' . PKG_ROOT_PATH);
|
||||
putenv('SOURCE_PATH=' . SOURCE_PATH);
|
||||
putenv('DOWNLOAD_PATH=' . DOWNLOAD_PATH);
|
||||
putenv('CPU_COUNT=' . CPU_COUNT);
|
||||
putenv('SPC_ARCH=' . php_uname('m'));
|
||||
putenv('GNU_ARCH=' . GNU_ARCH);
|
||||
putenv('MAC_ARCH=' . MAC_ARCH);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user