diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index a0a1e6d2..8d975837 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -313,6 +313,7 @@ class Extension */ public function buildShared(): void { + logger()->info('Building extension [' . $this->getName() . '] as shared extension (' . $this->getName() . '.so)'); if (file_exists(BUILD_MODULES_PATH . '/' . $this->getName() . '.so')) { logger()->info('extension ' . $this->getName() . ' already built, skipping'); return; @@ -322,7 +323,10 @@ class Extension if ($dependencyExt === null) { throw new RuntimeException("extension {$this->name} requires shared extension {$name}"); } - $dependencyExt->buildShared(); + if ($dependencyExt->isBuildShared()) { + logger()->info('extension ' . $this->getName() . ' requires shared extension ' . $name); + $dependencyExt->buildShared(); + } } match (PHP_OS_FAMILY) { 'Darwin', 'Linux' => $this->buildUnixShared(), @@ -341,11 +345,25 @@ class Extension */ public function buildUnixShared(): void { - $config = (new SPCConfigUtil($this->builder))->config([$this->getName()]); + $config = (new SPCConfigUtil($this->builder))->config([$this->getName()], with_dependencies: true); + $sharedLibs = ''; + $staticLibs = ''; + foreach (explode('-l', $config['libs']) as $lib) { + $lib = trim($lib); + if ($lib === '') { + continue; + } + $static_lib = 'lib' . $lib . '.a'; + if (file_exists(BUILD_LIB_PATH . '/' . $static_lib)) { + $staticLibs .= ' -l' . $lib; + } else { + $sharedLibs .= ' -l' . $lib; + } + } $env = [ 'CFLAGS' => $config['cflags'], - 'LDFLAGS' => $config['ldflags'], - 'LIBS' => $config['libs'], + 'LDFLAGS' => $config['ldflags'] . ' -Wl,--allow-multiple-definition', + 'LIBS' => '-Wl,-Bstatic ' . $staticLibs . ' -Wl,-Bdynamic ' . $sharedLibs, 'LD_LIBRARY_PATH' => BUILD_LIB_PATH, ]; // prepare configure args diff --git a/src/SPC/builder/extension/spx.php b/src/SPC/builder/extension/spx.php index dccf131c..ef9e95bf 100644 --- a/src/SPC/builder/extension/spx.php +++ b/src/SPC/builder/extension/spx.php @@ -5,7 +5,6 @@ declare(strict_types=1); namespace SPC\builder\extension; use SPC\builder\Extension; -use SPC\store\FileSystem; use SPC\util\CustomExt; #[CustomExt('spx')] @@ -13,17 +12,10 @@ class spx extends Extension { public function getUnixConfigureArg(bool $shared = false): string { - $arg = '--enable-spx'; + $arg = '--enable-SPX'; if ($this->builder->getExt('zlib') === null) { $arg .= ' --with-zlib-dir=' . BUILD_ROOT_PATH; } return $arg; } - - public function patchBeforeSharedConfigure(): bool - { - FileSystem::replaceFileStr($this->source_dir . '/config.m4', 'PHP_ARG_ENABLE(SPX-DEV,', 'PHP_ARG_ENABLE(spx-dev,'); - FileSystem::replaceFileStr($this->source_dir . '/config.m4', 'PHP_ARG_ENABLE(SPX,', 'PHP_ARG_ENABLE(spx,'); - return true; - } } diff --git a/src/SPC/builder/extension/xdebug.php b/src/SPC/builder/extension/xdebug.php index 90f225ae..cdfeea8c 100644 --- a/src/SPC/builder/extension/xdebug.php +++ b/src/SPC/builder/extension/xdebug.php @@ -12,6 +12,6 @@ class xdebug extends Extension { protected function isZendExtension(): bool { - return str_contains($this->builder->getExt('zend')->getName(), 'xdebug'); + return true; } } diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index 0c02e155..f78928de 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -43,7 +43,7 @@ class SourcePatcher */ public static function patchBeforeBuildconf(BuilderBase $builder): void { - foreach ($builder->getExts(false) as $ext) { + foreach ($builder->getExts() as $ext) { if ($ext->patchBeforeBuildconf() === true) { logger()->info('Extension [' . $ext->getName() . '] patched before buildconf'); } diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index e0b92a2e..4b2fd19a 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -11,6 +11,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\Config; +use SPC\store\FileSystem; use Symfony\Component\Console\Input\ArgvInput; class SPCConfigUtil @@ -42,7 +43,7 @@ class SPCConfigUtil * @throws WrongUsageException * @throws \Throwable */ - public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false): array + public function config(array $extensions = [], array $libraries = [], bool $include_suggest_ext = false, bool $include_suggest_lib = false, $with_dependencies = false): array { [$extensions, $libraries] = DependencyUtil::getExtsAndLibs($extensions, $libraries, $include_suggest_ext, $include_suggest_lib); @@ -54,7 +55,7 @@ class SPCConfigUtil } ob_get_clean(); $ldflags = $this->getLdflagsString(); - $libs = $this->getLibsString($libraries); + $libs = $this->getLibsString($libraries, $with_dependencies); $cflags = $this->getIncludesString(); // embed @@ -97,13 +98,39 @@ class SPCConfigUtil return '-L' . BUILD_LIB_PATH; } - private function getLibsString(array $libraries): string + private function getLibsString(array $libraries, bool $withDependencies = false): string { $short_name = []; foreach (array_reverse($libraries) as $library) { $libs = Config::getLib($library, 'static-libs', []); foreach ($libs as $lib) { - $short_name[] = $this->getShortLibName($lib); + if ($withDependencies) { + $noExt = str_replace('.a', '', $lib); + $requiredLibs = []; + $pkgconfFile = BUILD_LIB_PATH . "/pkgconfig/{$noExt}.pc"; + if (file_exists($pkgconfFile)) { + $lines = file($pkgconfFile); + foreach ($lines as $value) { + if (str_starts_with($value, 'Libs')) { + $items = explode(' ', $value); + foreach ($items as $item) { + $item = trim($item); + if (str_starts_with($item, '-l')) { + $requiredLibs[] = $item; + } + } + } + } + } + foreach ($requiredLibs as $requiredLib) { + if (!in_array($requiredLib, $short_name)) { + $short_name[] = $requiredLib; + } + } + } + else { + $short_name[] = $this->getShortLibName($lib); + } } if (PHP_OS_FAMILY !== 'Darwin') { continue;