mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-03 23:05:41 +08:00
Use separated functions for exporting symbols
This commit is contained in:
@@ -4,15 +4,88 @@ declare(strict_types=1);
|
||||
|
||||
namespace SPC\builder\traits;
|
||||
|
||||
/**
|
||||
* Unix 系统的工具函数 Trait,适用于 Linux、macOS
|
||||
*/
|
||||
use SPC\exception\ExecutionException;
|
||||
use SPC\exception\WrongUsageException;
|
||||
use SPC\toolchain\ToolchainManager;
|
||||
use SPC\toolchain\ZigToolchain;
|
||||
use SPC\util\SPCTarget;
|
||||
|
||||
trait UnixSystemUtilTrait
|
||||
{
|
||||
/**
|
||||
* @param string $name 命令名称
|
||||
* @param array $paths 寻找的目标路径(如果不传入,则使用环境变量 PATH)
|
||||
* @return null|string 找到了返回命令路径,找不到返回 null
|
||||
* Export static library dynamic symbols to a .dynsym file.
|
||||
* It will export to "/path/to/libxxx.a.dynsym".
|
||||
*
|
||||
* @param string $lib_file Static library file path (e.g. /path/to/libxxx.a)
|
||||
*/
|
||||
public static function exportDynamicSymbols(string $lib_file): void
|
||||
{
|
||||
// check
|
||||
if (!is_file($lib_file)) {
|
||||
throw new WrongUsageException("The lib archive file {$lib_file} does not exist, please build it first.");
|
||||
}
|
||||
// shell out
|
||||
$cmd = 'nm -g --defined-only -P ' . escapeshellarg($lib_file);
|
||||
$result = shell()->execWithResult($cmd);
|
||||
if ($result[0] !== 0) {
|
||||
throw new ExecutionException($cmd, 'Failed to get defined symbols from ' . $lib_file);
|
||||
}
|
||||
// parse shell output and filter
|
||||
$defined = [];
|
||||
foreach ($result[1] as $line) {
|
||||
$line = trim($line);
|
||||
if ($line === '' || str_ends_with($line, '.o:') || str_ends_with($line, '.o]:')) {
|
||||
continue;
|
||||
}
|
||||
$name = strtok($line, " \t");
|
||||
if (!$name) {
|
||||
continue;
|
||||
}
|
||||
$name = preg_replace('/@.*$/', '', $name);
|
||||
if ($name !== '' && $name !== false) {
|
||||
$defined[] = $name;
|
||||
}
|
||||
}
|
||||
$defined = array_unique($defined);
|
||||
sort($defined);
|
||||
// export
|
||||
if (SPCTarget::getTargetOS() === 'Linux') {
|
||||
file_put_contents("{$lib_file}.dynsym", "{\n" . implode("\n", array_map(fn ($x) => " {$x};", $defined)) . "};\n");
|
||||
} else {
|
||||
file_put_contents("{$lib_file}.dynsym", implode("\n", $defined) . "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get linker flag to export dynamic symbols from a static library.
|
||||
*
|
||||
* @param string $lib_file Static library file path (e.g. /path/to/libxxx.a)
|
||||
* @return null|string Linker flag to export dynamic symbols, null if no .dynsym file found
|
||||
*/
|
||||
public static function getDynamicExportedSymbols(string $lib_file): ?string
|
||||
{
|
||||
$symbol_file = "{$lib_file}.dynsym";
|
||||
if (!is_file($symbol_file)) {
|
||||
return null;
|
||||
}
|
||||
// https://github.com/ziglang/zig/issues/24662
|
||||
if (ToolchainManager::getToolchainClass() === ZigToolchain::class) {
|
||||
return '-Wl,--export-dynamic';
|
||||
}
|
||||
// macOS
|
||||
if (SPCTarget::getTargetOS() !== 'Linux') {
|
||||
return "-Wl,-exported_symbols_list,{$symbol_file}";
|
||||
}
|
||||
return "-Wl,--dynamic-list={$symbol_file}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a command in given paths or system PATH.
|
||||
* If $name is an absolute path, check if it exists.
|
||||
*
|
||||
* @param string $name Command name or absolute path
|
||||
* @param array $paths Paths to search, if empty, use system PATH
|
||||
* @return null|string Absolute path of the command if found, null otherwise
|
||||
*/
|
||||
public static function findCommand(string $name, array $paths = []): ?string
|
||||
{
|
||||
@@ -31,6 +104,8 @@ trait UnixSystemUtilTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* Make environment variable string for shell command.
|
||||
*
|
||||
* @param array $vars Variables, like: ["CFLAGS" => "-Ixxx"]
|
||||
* @return string like: CFLAGS="-Ixxx"
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user