This commit is contained in:
crazywhalecc
2025-08-06 20:47:48 +08:00
committed by Jerry Ma
parent 08fa49b791
commit 29dc5e4ea7
8 changed files with 131 additions and 109 deletions

View File

@@ -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';
}
}

View File

@@ -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');

View File

@@ -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');
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}