diff --git a/config/ext.json b/config/ext.json index eaa27d1b..629b753f 100644 --- a/config/ext.json +++ b/config/ext.json @@ -95,7 +95,10 @@ "ev": { "type": "external", "source": "ev", - "arg-type-windows": "with" + "arg-type-windows": "with", + "shared-ext-depends": [ + "sockets" + ] }, "event": { "support": { diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index 0e4c0603..2e0fe3ec 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -252,20 +252,26 @@ abstract class BuilderBase } file_put_contents(BUILD_BIN_PATH . '/php-config', implode('', $lines)); FileSystem::createDir(BUILD_MODULES_PATH); - foreach ($this->getExts() as $ext) { - if (!$ext->isBuildShared()) { - continue; - } - if (Config::getExt($ext->getName(), 'type') === 'builtin') { - if (file_exists(BUILD_MODULES_PATH . '/' . $ext->getName() . '.so')) { - logger()->info('Shared extension [' . $ext->getName() . '] was already built by php-src/configure (' . $ext->getName() . '.so)'); + try { + foreach ($this->getExts() as $ext) { + if (!$ext->isBuildShared()) { continue; } - logger()->warning('Shared extension [' . $ext->getName() . '] was built statically by php-src/configure'); - continue; + if (Config::getExt($ext->getName(), 'type') === 'builtin') { + if (file_exists(BUILD_MODULES_PATH . '/' . $ext->getName() . '.so')) { + logger()->info('Shared extension [' . $ext->getName() . '] was already built by php-src/configure (' . $ext->getName() . '.so)'); + continue; + } + logger()->warning('Shared extension [' . $ext->getName() . '] was built statically by php-src/configure'); + continue; + } + logger()->info('Building extension [' . $ext->getName() . '] as shared extension (' . $ext->getName() . '.so)'); + $ext->buildShared(); } - logger()->info('Building extension [' . $ext->getName() . '] as shared extension (' . $ext->getName() . '.so)'); - $ext->buildShared(); + } + catch (RuntimeException $e) { + FileSystem::replaceFileLineContainsString(BUILD_BIN_PATH . '/php-config', 'extension_dir=', $extension_dir_line); + throw $e; } FileSystem::replaceFileLineContainsString(BUILD_BIN_PATH . '/php-config', 'extension_dir=', $extension_dir_line); } diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index 0cda99b6..e79c3db9 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -221,6 +221,36 @@ class Extension } } + public function getRequiredSharedExtensions(): string + { + $loaded = []; + $order = []; + + $resolve = function ($extension) use (&$resolve, &$loaded, &$order) { + if (isset($loaded[$extension->getName()])) { + return; + } + $loaded[$extension->getName()] = true; + + foreach ($this->dependencies as $dependency) { + $resolve($dependency); + } + + $order[] = $extension; + }; + + $resolve($this); + + $ret = ''; + foreach ($order as $ext) { + if ($ext instanceof Extension && $ext->isBuildShared()) { + $ret .= ' -d "extension=' . BUILD_MODULES_PATH . '/' . $ext->getName() . '.so"'; + } + } + + return $ret; + } + /** * @throws RuntimeException */ @@ -229,7 +259,8 @@ class Extension // Run compile check if build target is cli // If you need to run some check, overwrite this or add your assert in src/globals/ext-tests/{extension_name}.php // If check failed, throw RuntimeException - [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n --ri "' . $this->getDistName() . '"', false); + $sharedExtensions = $this->getRequiredSharedExtensions(); + [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n' . $sharedExtensions . ' --ri "' . $this->getDistName() . '"', false); if ($ret !== 0) { throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); } @@ -242,7 +273,7 @@ class Extension file_get_contents(ROOT_DIR . '/src/globals/ext-tests/' . $this->getName() . '.php') ); - [$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n -r "' . trim($test) . '"'); + [$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n' . $sharedExtensions . ' -r "' . trim($test) . '"'); if ($ret !== 0) { if ($this->builder->getOption('debug')) { var_dump($out); diff --git a/src/SPC/builder/extension/mbregex.php b/src/SPC/builder/extension/mbregex.php index 1f169e1a..a26e7024 100644 --- a/src/SPC/builder/extension/mbregex.php +++ b/src/SPC/builder/extension/mbregex.php @@ -26,7 +26,8 @@ class mbregex extends Extension */ public function runCliCheckUnix(): void { - [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n --ri "mbstring" | grep regex', false); + $sharedext = $this->builder->getExt('mbstring')->isBuildShared() ? ' -d "extension=' . BUILD_MODULES_PATH . '/mbstring.so"' : ''; + [$ret] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n' . $sharedext . ' --ri "mbstring" | grep regex', false); if ($ret !== 0) { throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: compiled php-cli mbstring extension does not contain regex !'); } diff --git a/src/SPC/builder/extension/spx.php b/src/SPC/builder/extension/spx.php index a797a126..dccf131c 100644 --- a/src/SPC/builder/extension/spx.php +++ b/src/SPC/builder/extension/spx.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace SPC\builder\extension; use SPC\builder\Extension; +use SPC\store\FileSystem; use SPC\util\CustomExt; #[CustomExt('spx')] @@ -18,4 +19,11 @@ class spx extends Extension } 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/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index 869bf531..2d71c8eb 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -95,7 +95,8 @@ trait UnixLibraryTrait logger()->debug('Patching ' . $realpath); // replace prefix $file = FileSystem::readFile($realpath); - $file = str_replace(' /lib/', ' ' . BUILD_LIB_PATH . '/', $file); + $file = str_replace( + ' /lib/', ' ' . BUILD_LIB_PATH . '/', $file); $file = preg_replace('/^libdir=.*$/m', "libdir='" . BUILD_LIB_PATH . "'", $file); FileSystem::writeFile($realpath, $file); } diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index 48c82601..b92c2b7e 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -146,7 +146,7 @@ abstract class UnixBuilderBase extends BuilderBase throw new RuntimeException("cli failed sanity check: ret[{$ret}]. out[{$raw_output}]"); } - foreach ($this->getExts(false) as $ext) { + foreach ($this->getExts() as $ext) { logger()->debug('testing ext: ' . $ext->getName()); $ext->runCliCheckUnix(); }