- 将 Clang 和 GCC 后端重构为继承自新的 GccLikeBackend 基类 - 移除重复的编译和链接命令构建逻辑 - 添加平台特定的钩子方法用于扩展功能 - 在 FunctionContext 中添加 SSA 构建器属性 - 统一编译器和链接器命令的初始化方式 - 优化 Windows 平台兼容性处理逻辑pull/3/head
parent
d49743a0fe
commit
7c2192ff54
9 changed files with 615 additions and 1195 deletions
@ -0,0 +1,355 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace PhpAot\Php\Backend; |
||||||
|
|
||||||
|
use PhpAot\Php\Platform\PlatformBase; |
||||||
|
|
||||||
|
/** |
||||||
|
* GCC/Clang 共享后端基类 |
||||||
|
* 包含 Unix-like 编译器(GCC、Clang)的通用命令行构建逻辑。 |
||||||
|
* 子类只需覆盖平台差异的钩子方法。 |
||||||
|
*/ |
||||||
|
abstract class GccLikeBackend extends CompilerBackend |
||||||
|
{ |
||||||
|
protected string $compilerCommand; |
||||||
|
protected ?string $linkerCommand; |
||||||
|
|
||||||
|
public function __construct(PlatformBase $platform, string $compilerCommand, ?string $linkerCommand = null) |
||||||
|
{ |
||||||
|
parent::__construct($platform); |
||||||
|
$this->compilerCommand = $compilerCommand; |
||||||
|
$this->linkerCommand = $linkerCommand; |
||||||
|
} |
||||||
|
|
||||||
|
public function getCompilerCommand(): string |
||||||
|
{ |
||||||
|
return $this->compilerCommand; |
||||||
|
} |
||||||
|
|
||||||
|
// ──── 钩子方法(子类覆盖点) ──── |
||||||
|
|
||||||
|
/** 编译器特定的前缀标志(如 MSVC 兼容模式) */ |
||||||
|
protected function getCompilerPrefixFlags(): string |
||||||
|
{ |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
/** 链接器输出标志(-o vs /OUT:) */ |
||||||
|
protected function getLinkerOutputFlag(): string |
||||||
|
{ |
||||||
|
return '-o'; |
||||||
|
} |
||||||
|
|
||||||
|
/** 格式化 sanitizer 标志 */ |
||||||
|
protected function formatSanitizerFlag(string $sanitizer): string |
||||||
|
{ |
||||||
|
return match ($sanitizer) { |
||||||
|
'address', 'addr' => '-fsanitize=address', |
||||||
|
'undefined', 'undef' => '-fsanitize=undefined', |
||||||
|
default => '-fsanitize=' . $sanitizer, |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
/** 添加 PIC 标志 */ |
||||||
|
protected function addPICFlag(array $config, string &$cmd): void |
||||||
|
{ |
||||||
|
if ((!empty($config['build_mode']) && $config['build_mode'] === 'ext') || !empty($config['pic'])) { |
||||||
|
$cmd .= ' -fPIC'; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** 添加平台特定的链接选项 */ |
||||||
|
protected function addPlatformLinkFlags(array $config, string &$cmd): void |
||||||
|
{ |
||||||
|
if ((!empty($config['build_mode']) && $config['build_mode'] === 'ext') || !empty($config['shared'])) { |
||||||
|
$cmd .= ' ' . $this->platform->getSharedLinkFlag(); |
||||||
|
|
||||||
|
if ($this->platform instanceof \PhpAot\Php\Platform\Macos && !empty($config['install_name'])) { |
||||||
|
$cmd .= ' ' . $this->platform->getCurrentInstallNameOption($config['install_name']); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['rpath'])) { |
||||||
|
foreach ($config['rpath'] as $path) { |
||||||
|
$cmd .= ' -Wl,-rpath,' . escapeshellarg($path); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** 添加平台特定的完整链接选项 */ |
||||||
|
protected function addPlatformFullLinkFlags(array $options, string &$cmd): void |
||||||
|
{ |
||||||
|
if (!empty($options['shared'])) { |
||||||
|
$cmd .= ' ' . $this->platform->getSharedLinkFlag(); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($options['rpath'])) { |
||||||
|
$cmd .= ' ' . $this->platform->getRpathOptions($options['rpath']); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// ──── 抽象方法实现 ──── |
||||||
|
|
||||||
|
public function compileFile( |
||||||
|
string $sourceFile, |
||||||
|
string $outputFile, |
||||||
|
array $includePaths = [], |
||||||
|
array $defines = [], |
||||||
|
array $flags = [] |
||||||
|
): string { |
||||||
|
$cmd = $this->getCompilerCommand(); |
||||||
|
$cmd .= $this->getCompilerPrefixFlags(); |
||||||
|
$cmd .= ' -c ' . escapeshellarg($sourceFile); |
||||||
|
$cmd .= ' -o ' . escapeshellarg($outputFile); |
||||||
|
|
||||||
|
if (!empty($includePaths)) { |
||||||
|
$cmd .= ' ' . $this->formatIncludePaths($includePaths); |
||||||
|
} |
||||||
|
|
||||||
|
foreach ($defines as $define) { |
||||||
|
$cmd .= ' -D' . $define; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($flags)) { |
||||||
|
$cmd .= ' ' . implode(' ', $flags); |
||||||
|
} |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function linkObjects( |
||||||
|
array $objectFiles, |
||||||
|
string $outputFile, |
||||||
|
array $libraryPaths = [], |
||||||
|
array $libraries = [], |
||||||
|
array $flags = [] |
||||||
|
): string { |
||||||
|
$cmd = $this->getLinkerCommand(); |
||||||
|
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles)); |
||||||
|
$cmd .= ' ' . $this->getLinkerOutputFlag() . ' ' . escapeshellarg($outputFile); |
||||||
|
|
||||||
|
if (!empty($libraryPaths)) { |
||||||
|
$cmd .= ' ' . $this->formatLibraryPaths($libraryPaths); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($libraries)) { |
||||||
|
$cmd .= ' ' . $this->formatLibraries($libraries); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($flags)) { |
||||||
|
$cmd .= ' ' . implode(' ', $flags); |
||||||
|
} |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildCompileCommand(string $sourceFile, string $outputFile, array $options = []): string |
||||||
|
{ |
||||||
|
$cmd = $this->getCompilerCommand(); |
||||||
|
$cmd .= $this->getCompilerPrefixFlags(); |
||||||
|
$cmd .= ' -c'; |
||||||
|
$cmd .= ' ' . escapeshellarg($sourceFile); |
||||||
|
$cmd .= ' -o ' . escapeshellarg($outputFile); |
||||||
|
|
||||||
|
if (!empty($options['include_paths'])) { |
||||||
|
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']); |
||||||
|
} |
||||||
|
|
||||||
|
$cmd .= $this->buildCompileOptions($options); |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildCCompileCommand(string $sourceFile, string $outputFile, array $options = []): string |
||||||
|
{ |
||||||
|
$cmd = $this->getCompilerCommand(); |
||||||
|
$cmd .= $this->getCompilerPrefixFlags(); |
||||||
|
$cmd .= ' -c'; |
||||||
|
$cmd .= ' -x c'; |
||||||
|
$cmd .= ' ' . escapeshellarg($sourceFile); |
||||||
|
$cmd .= ' -o ' . escapeshellarg($outputFile); |
||||||
|
|
||||||
|
if (!empty($options['include_paths'])) { |
||||||
|
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']); |
||||||
|
} |
||||||
|
|
||||||
|
$optimizeLevel = $options['optimize'] ?? 0; |
||||||
|
if (!empty($options['debug'])) { |
||||||
|
$cmd .= ' -O0 -g'; |
||||||
|
} else { |
||||||
|
$cmd .= ' -O' . $optimizeLevel; |
||||||
|
} |
||||||
|
|
||||||
|
$cmd .= ' -Wall'; |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildNativeCompileCommand(string $sourceFile, string $outputFile, array $options = [], string $language = ''): string |
||||||
|
{ |
||||||
|
$cmd = $this->getCompilerCommand(); |
||||||
|
$cmd .= $this->getCompilerPrefixFlags(); |
||||||
|
$cmd .= ' -c'; |
||||||
|
if ($language !== '') { |
||||||
|
$cmd .= ' -x ' . $language; |
||||||
|
} |
||||||
|
$cmd .= ' ' . escapeshellarg($sourceFile); |
||||||
|
$cmd .= ' -o ' . escapeshellarg($outputFile); |
||||||
|
|
||||||
|
if (!empty($options['include_paths'])) { |
||||||
|
$cmd .= ' ' . $this->formatIncludePaths($options['include_paths']); |
||||||
|
} |
||||||
|
|
||||||
|
$cmd .= $this->buildCompileOptions($options); |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildLinkCommand(array $objectFiles, string $outputFile, array $options = []): string |
||||||
|
{ |
||||||
|
$cmd = $this->getLinkerCommand(); |
||||||
|
$cmd .= ' ' . implode(' ', array_map('escapeshellarg', $objectFiles)); |
||||||
|
$cmd .= ' ' . $this->getLinkerOutputFlag() . ' ' . escapeshellarg($outputFile); |
||||||
|
|
||||||
|
if (!empty($options['library_paths'])) { |
||||||
|
$cmd .= ' ' . $this->formatLibraryPaths($options['library_paths']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($options['ldflags'])) { |
||||||
|
$cmd .= ' ' . $options['ldflags']; |
||||||
|
} |
||||||
|
|
||||||
|
$cmd .= $this->buildLinkOptions($options); |
||||||
|
|
||||||
|
if (!empty($options['libraries'])) { |
||||||
|
$cmd .= ' ' . $this->formatLibraries($options['libraries']); |
||||||
|
} |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildCompileOptions(array $config = []): string |
||||||
|
{ |
||||||
|
$cmd = ''; |
||||||
|
|
||||||
|
$cmd .= $this->getCompilerPrefixFlags(); |
||||||
|
|
||||||
|
if (!empty($config['sanitize'])) { |
||||||
|
$cmd .= ' ' . $this->formatSanitizerFlag($config['sanitize']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['debug'])) { |
||||||
|
$cmd .= ' -O0 -g'; |
||||||
|
} else { |
||||||
|
$optimizeLevel = $config['optimize'] ?? 2; |
||||||
|
$cmd .= ' -O' . $optimizeLevel; |
||||||
|
} |
||||||
|
|
||||||
|
$cmd .= ' -Wall'; |
||||||
|
|
||||||
|
if (!empty($config['cpp_std'])) { |
||||||
|
$cmd .= ' -std=' . $config['cpp_std']; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['march'])) { |
||||||
|
$cmd .= ' -march=' . $config['march']; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['target_platform'])) { |
||||||
|
$cmd .= ' --target=' . $config['target_platform']; |
||||||
|
} |
||||||
|
|
||||||
|
$this->addPICFlag($config, $cmd); |
||||||
|
|
||||||
|
if (!empty($config['enable_profiler'])) { |
||||||
|
$cmd .= ' -DPPROF_ON=1'; |
||||||
|
if (!empty($config['prof_output'])) { |
||||||
|
$cmd .= ' -DPROF_OUTPUT_FILE=\'"' . $config['prof_output'] . '"\''; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['cxxflags'])) { |
||||||
|
$cmd .= ' ' . $config['cxxflags']; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['user_defines'])) { |
||||||
|
foreach ($config['user_defines'] as $define) { |
||||||
|
$cmd .= ' -D' . $define; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['lto'])) { |
||||||
|
$cmd .= ' -flto'; |
||||||
|
} |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildLinkOptions(array $config = []): string |
||||||
|
{ |
||||||
|
$cmd = ''; |
||||||
|
|
||||||
|
$this->addPlatformLinkFlags($config, $cmd); |
||||||
|
|
||||||
|
if (!empty($config['sanitize'])) { |
||||||
|
$cmd .= ' ' . $this->formatSanitizerFlag($config['sanitize']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['target_platform'])) { |
||||||
|
$cmd .= ' --target=' . $config['target_platform']; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($config['lto'])) { |
||||||
|
$cmd .= ' -flto'; |
||||||
|
} |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildFullCompileOptions(array $options = []): string |
||||||
|
{ |
||||||
|
$cmd = ''; |
||||||
|
|
||||||
|
$cmd .= $this->getCompilerPrefixFlags(); |
||||||
|
|
||||||
|
if (!empty($options['debug'])) { |
||||||
|
$cmd .= ' -O0 -g'; |
||||||
|
} else { |
||||||
|
$optimizeLevel = $options['optimize'] ?? 2; |
||||||
|
$cmd .= ' -O' . $optimizeLevel; |
||||||
|
} |
||||||
|
|
||||||
|
$cmd .= ' -Wall'; |
||||||
|
|
||||||
|
if (!empty($options['cpp_std'])) { |
||||||
|
$cmd .= ' -std=' . $options['cpp_std']; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($options['march'])) { |
||||||
|
$cmd .= ' -march=' . $options['march']; |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($options['sanitize'])) { |
||||||
|
$cmd .= ' ' . $this->formatSanitizerFlag($options['sanitize']); |
||||||
|
} |
||||||
|
|
||||||
|
if (!empty($options['pic'])) { |
||||||
|
$cmd .= ' -fPIC'; |
||||||
|
} |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
|
||||||
|
public function buildFullLinkOptions(array $options = []): string |
||||||
|
{ |
||||||
|
$cmd = ''; |
||||||
|
|
||||||
|
$this->addPlatformFullLinkFlags($options, $cmd); |
||||||
|
|
||||||
|
if (!empty($options['sanitize'])) { |
||||||
|
$cmd .= ' -fsanitize=' . $options['sanitize']; |
||||||
|
} |
||||||
|
|
||||||
|
return $cmd; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,211 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace PhpAot\Php\Platform; |
||||||
|
|
||||||
|
/** |
||||||
|
* Unix-like 平台基类(Linux, macOS) |
||||||
|
* 包含 GCC/Clang 通用标志语法的共享实现 |
||||||
|
*/ |
||||||
|
abstract class UnixPlatform extends PlatformBase |
||||||
|
{ |
||||||
|
public function getIncludeFlags(array $includePaths): string |
||||||
|
{ |
||||||
|
if (empty($includePaths)) { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
$flags = []; |
||||||
|
foreach ($includePaths as $path) { |
||||||
|
$flags[] = '-I' . escapeshellarg($path); |
||||||
|
} |
||||||
|
|
||||||
|
return implode(' ', $flags); |
||||||
|
} |
||||||
|
|
||||||
|
public function getLibraryPathFlags(array $libraryPaths): string |
||||||
|
{ |
||||||
|
if (empty($libraryPaths)) { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
$flags = []; |
||||||
|
foreach ($libraryPaths as $path) { |
||||||
|
$flags[] = '-L' . escapeshellarg($path); |
||||||
|
} |
||||||
|
|
||||||
|
return implode(' ', $flags); |
||||||
|
} |
||||||
|
|
||||||
|
public function getLibraryFlags(array $libraries): string |
||||||
|
{ |
||||||
|
if (empty($libraries)) { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
$ext = ltrim($this->getSharedLibraryExtension(), '.'); |
||||||
|
$flags = []; |
||||||
|
foreach ($libraries as $lib) { |
||||||
|
$libName = basename($lib); |
||||||
|
if (str_starts_with($libName, 'lib')) { |
||||||
|
$libName = substr($libName, 3); |
||||||
|
} |
||||||
|
$libName = preg_replace('/\.(a|' . $ext . ')$/', '', $libName); |
||||||
|
|
||||||
|
$flags[] = '-l' . $libName; |
||||||
|
} |
||||||
|
|
||||||
|
return implode(' ', $flags); |
||||||
|
} |
||||||
|
|
||||||
|
public function getObjectExtension(): string |
||||||
|
{ |
||||||
|
return '.o'; |
||||||
|
} |
||||||
|
|
||||||
|
public function getExecutableExtension(): string |
||||||
|
{ |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
public function getPathSeparator(): string |
||||||
|
{ |
||||||
|
return '/'; |
||||||
|
} |
||||||
|
|
||||||
|
public function getPhpDir(): string |
||||||
|
{ |
||||||
|
$phpDir = getenv('PHP_HOME'); |
||||||
|
if ($phpDir && is_dir($phpDir)) { |
||||||
|
return rtrim($phpDir, '\/'); |
||||||
|
} |
||||||
|
|
||||||
|
$phpDir = shell_exec('php-config --prefix 2>/dev/null'); |
||||||
|
if (!empty($phpDir)) { |
||||||
|
return trim($phpDir); |
||||||
|
} |
||||||
|
|
||||||
|
$phpExe = trim(shell_exec('which php 2>/dev/null')); |
||||||
|
if ($phpExe && file_exists($phpExe)) { |
||||||
|
$phpDir = dirname(dirname($phpExe)); |
||||||
|
if (is_dir($phpDir)) { |
||||||
|
return $phpDir; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
throw new \RuntimeException('The `php-config` is not found. Please install PHP development package or set PHP_HOME environment variable'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取 RPATH 选项 |
||||||
|
*/ |
||||||
|
public function getRpathOptions(array $paths): string |
||||||
|
{ |
||||||
|
if (empty($paths)) { |
||||||
|
return ''; |
||||||
|
} |
||||||
|
|
||||||
|
$rpaths = []; |
||||||
|
foreach ($paths as $path) { |
||||||
|
$rpaths[] = '-Wl,-rpath,' . escapeshellarg($path); |
||||||
|
} |
||||||
|
|
||||||
|
return implode(' ', $rpaths); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取 PIC 选项 |
||||||
|
*/ |
||||||
|
public function getPicFlag(): string |
||||||
|
{ |
||||||
|
return '-fPIC'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 构建 PHP 包含路径(使用 php-config 动态获取) |
||||||
|
*/ |
||||||
|
public function buildPhpIncludePaths(string $phpDir): array |
||||||
|
{ |
||||||
|
$phpConfigPath = $this->findPhpConfig($phpDir); |
||||||
|
if ($phpConfigPath) { |
||||||
|
$includes = shell_exec("{$phpConfigPath} --includes 2>/dev/null"); |
||||||
|
if ($includes) { |
||||||
|
preg_match_all('/-I([^\s]+)/', $includes, $matches); |
||||||
|
if (!empty($matches[1])) { |
||||||
|
return array_filter($matches[1], 'is_dir'); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$paths = [ |
||||||
|
$phpDir . '/include/php', |
||||||
|
$phpDir . '/include/php/main', |
||||||
|
$phpDir . '/include/php/TSRM', |
||||||
|
$phpDir . '/include/php/Zend', |
||||||
|
$phpDir . '/include/php/ext', |
||||||
|
]; |
||||||
|
|
||||||
|
return array_filter($paths, 'is_dir'); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 查找 php-config 可执行文件 |
||||||
|
*/ |
||||||
|
protected function findPhpConfig(string $phpDir): ?string |
||||||
|
{ |
||||||
|
$candidate = $phpDir . '/bin/php-config'; |
||||||
|
if (is_executable($candidate)) { |
||||||
|
return $candidate; |
||||||
|
} |
||||||
|
|
||||||
|
$whichResult = trim(shell_exec('which php-config 2>/dev/null')); |
||||||
|
if ($whichResult && is_executable($whichResult)) { |
||||||
|
return $whichResult; |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 构建 PHP 库路径 |
||||||
|
*/ |
||||||
|
public function buildPhpLibPaths(string $phpDir): array |
||||||
|
{ |
||||||
|
$paths = []; |
||||||
|
|
||||||
|
$libPath = $phpDir . '/lib'; |
||||||
|
if (is_dir($libPath)) { |
||||||
|
$paths[] = $libPath; |
||||||
|
} |
||||||
|
|
||||||
|
return $paths; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检测 PHP 库文件 |
||||||
|
*/ |
||||||
|
public function detectPhpLibs(string $phpDir): array |
||||||
|
{ |
||||||
|
$libPath = $phpDir . '/lib'; |
||||||
|
|
||||||
|
if (!is_dir($libPath)) { |
||||||
|
throw new \RuntimeException("PHP lib directory not found: {$libPath}"); |
||||||
|
} |
||||||
|
|
||||||
|
$ext = ltrim($this->getSharedLibraryExtension(), '.'); |
||||||
|
$embedLib = $libPath . '/libphp.' . $ext; |
||||||
|
$staticLib = $libPath . '/libphp.a'; |
||||||
|
|
||||||
|
$hasEmbed = file_exists($embedLib); |
||||||
|
$hasStatic = file_exists($staticLib); |
||||||
|
|
||||||
|
if (!$hasEmbed && !$hasStatic) { |
||||||
|
throw new \RuntimeException("Neither libphp.{$ext} nor libphp.a found"); |
||||||
|
} |
||||||
|
|
||||||
|
return [ |
||||||
|
'embed' => $hasEmbed ? $embedLib : null, |
||||||
|
'static' => $hasStatic ? $staticLib : null, |
||||||
|
'is_shared' => $hasEmbed, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue