diff --git a/.gitignore b/.gitignore index 0560542f..9d9289f6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ docker/source/ # default source extract directory /source/ +# built by shared embed tests +/locale/ + # default source download directory /downloads/ diff --git a/config/env.ini b/config/env.ini index 4fd1a28a..49952645 100644 --- a/config/env.ini +++ b/config/env.ini @@ -68,7 +68,7 @@ CXX=${SPC_LINUX_DEFAULT_CXX} AR=${SPC_LINUX_DEFAULT_AR} LD=ld.gold ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build -SPC_DEFAULT_C_FLAGS="-fPIC -std=c11" +SPC_DEFAULT_C_FLAGS="-fPIC" SPC_DEFAULT_CXX_FLAGS= ; extra libs for building php executable, used in `make` command for building php (this value may changed by extension build process, space separated) SPC_EXTRA_LIBS= @@ -81,7 +81,7 @@ SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime ; buildconf command SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force" ; configure command -SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg --with-pic" +SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-shared=yes --enable-static=no --disable-all --disable-cgi --disable-phpdbg --with-pic" ; make command SPC_CMD_PREFIX_PHP_MAKE="make -j${CPU_COUNT}" ; embed type for php, static (libphp.a) or shared (libphp.so) @@ -97,7 +97,7 @@ SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS="-L${BUILD_LIB_PATH}" ; LIBS for configuring php SPC_CMD_VAR_PHP_CONFIGURE_LIBS="-ldl -lpthread -lm" ; EXTRA_CFLAGS for `make` php -SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -fPIE -fPIC -Os -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fno-ident" +SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -Os -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fno-ident -fPIE -fPIC" ; EXTRA_LIBS for `make` php SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm" ; EXTRA_LDFLAGS_PROGRAM for `make` php diff --git a/config/ext.json b/config/ext.json index 1df91d3b..eaa27d1b 100644 --- a/config/ext.json +++ b/config/ext.json @@ -124,10 +124,6 @@ "Linux": "partial", "BSD": "wip" }, - "target": [ - "static", - "shared" - ], "notes": true, "arg-type": "custom", "type": "builtin", @@ -329,13 +325,16 @@ }, "type": "builtin", "arg-type": "none", - "ext-depends": [ - "xml" + "target": [ + "static" ] }, "mbregex": { "type": "builtin", "arg-type": "custom", + "target": [ + "static" + ], "ext-depends": [ "mbstring" ], @@ -417,6 +416,9 @@ "arg-type": "with", "ext-depends": [ "mysqlnd" + ], + "target": [ + "static" ] }, "mysqlnd": { @@ -424,6 +426,9 @@ "arg-type-windows": "with", "lib-depends": [ "zlib" + ], + "target": [ + "static" ] }, "oci8": { @@ -638,6 +643,9 @@ "arg-type": "with-prefix", "lib-depends": [ "readline" + ], + "target": [ + "static" ] }, "redis": { @@ -781,9 +789,6 @@ "Windows": "no", "BSD": "wip" }, - "target": [ - "static" - ], "notes": true, "type": "external", "source": "swoole", @@ -1055,9 +1060,6 @@ "support": { "BSD": "wip" }, - "target": [ - "static" - ], "type": "builtin", "arg-type": "with-prefix", "arg-type-windows": "enable", @@ -1081,6 +1083,9 @@ "arg-type-windows": "enable", "lib-depends": [ "zlib" + ], + "target": [ + "static" ] }, "zstd": { diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index 59f371ef..0e4c0603 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace SPC\builder; +use PharIo\FileSystem\File; use SPC\exception\ExceptionHandler; use SPC\exception\FileSystemException; use SPC\exception\InterruptException; @@ -233,15 +234,40 @@ abstract class BuilderBase */ abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE); + /** + * @throws WrongUsageException + * @throws RuntimeException + * @throws FileSystemException + */ public function buildSharedExts(): void { + $lines = file(BUILD_BIN_PATH . '/php-config'); + $extension_dir_line = null; + foreach ($lines as $key => $value) { + if (str_starts_with($value, 'extension_dir=')) { + $lines[$key] = 'extension_dir="' . BUILD_MODULES_PATH . '"' . PHP_EOL; + $extension_dir_line = $value; + break; + } + } + 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)'); + 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(); } + FileSystem::replaceFileLineContainsString(BUILD_BIN_PATH . '/php-config', 'extension_dir=', $extension_dir_line); } /** @@ -254,9 +280,17 @@ abstract class BuilderBase public function makeStaticExtensionArgs(): string { $ret = []; - foreach ($this->getExts(false) as $ext) { - logger()->info($ext->getName() . ' is using ' . $ext->getConfigureArg()); - $ret[] = trim($ext->getConfigureArg()); + foreach ($this->getExts() as $ext) { + $arg = $ext->getConfigureArg(); + if ($ext->isBuildShared()) { + if (Config::getExt($ext->getName(), 'type') === 'builtin') { + $arg = $ext->getConfigureArg(true); + } else { + continue; + } + } + logger()->info($ext->getName() . ' is using ' . $arg); + $ret[] = trim($arg); } logger()->debug('Using configure: ' . implode(' ', $ret)); return implode(' ', $ret); diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index a3d08f09..0cda99b6 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -59,20 +59,15 @@ class Extension * @throws FileSystemException * @throws WrongUsageException */ - public function getConfigureArg(): string + public function getConfigureArg(bool $shared = false): string { - $arg = $this->getEnableArg(); - switch (PHP_OS_FAMILY) { - case 'Windows': - $arg .= $this->getWindowsConfigureArg(); - break; - case 'Darwin': - case 'Linux': - case 'BSD': - $arg .= $this->getUnixConfigureArg(); - break; - } - return $arg; + return match (PHP_OS_FAMILY) { + 'Windows' => $this->getWindowsConfigureArg($shared), + 'Darwin', + 'Linux', + 'BSD' => $this->getUnixConfigureArg($shared), + default => throw new WrongUsageException(PHP_OS_FAMILY . ' build is not supported yet'), + }; } /** @@ -81,13 +76,13 @@ class Extension * @throws FileSystemException * @throws WrongUsageException */ - public function getEnableArg(): string + public function getEnableArg(bool $shared = false): string { $_name = str_replace('_', '-', $this->name); return match ($arg_type = Config::getExt($this->name, 'arg-type', 'enable')) { - 'enable' => '--enable-' . $_name . ' ', - 'with' => '--with-' . $_name . ' ', - 'with-prefix' => '--with-' . $_name . '="' . BUILD_ROOT_PATH . '" ', + 'enable' => '--enable-' . $_name . ($shared ? '=shared' : '') . ' ', + 'with' => '--with-' . $_name . ($shared ? '=shared' : '') . ' ', + 'with-prefix' => '--with-' . $_name . '=' . ($shared ? 'shared,' : '') . '"' . BUILD_ROOT_PATH . '" ', 'none', 'custom' => '', default => throw new WrongUsageException("argType does not accept {$arg_type}, use [enable/with/with-prefix] ."), }; @@ -126,6 +121,9 @@ class Extension foreach (Config::getExt($this->name, 'ext-suggests', []) as $name) { $this->addExtensionDependency($name, true); } + foreach (Config::getExt($this->name, 'shared-ext-depends', []) as $name) { + $this->addExtensionDependency($name); + } return $this; } @@ -147,15 +145,15 @@ class Extension return $this->name; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { - return ''; + return $this->getEnableArg(); // Windows is not supported yet } public function getUnixConfigureArg(bool $shared = false): string { - return ''; + return $this->getEnableArg($shared); } /** @@ -188,13 +186,33 @@ class Extension return false; } + /** + * Patch code before shared extension phpize + * If you need to patch some code, overwrite this + * return true if you patched something, false if not + */ + public function patchBeforeSharedBuild(): bool + { + return false; + } + + /** + * Patch code before shared extension ./configure + * If you need to patch some code, overwrite this + * return true if you patched something, false if not + */ + public function patchBeforeSharedConfigure(): bool + { + return false; + } + /** * Run shared extension check when cli is enabled * @throws RuntimeException */ public function runSharedExtensionCheckUnix(): void { - [$ret] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n -d "extension=' . BUILD_LIB_PATH . '/' . $this->getName() . '.so" --ri ' . $this->getName()); + [$ret] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n -d "extension=' . BUILD_MODULES_PATH . '/' . $this->getName() . '.so" --ri ' . $this->getName()); if ($ret !== 0) { throw new RuntimeException($this->getName() . '.so failed to load'); } @@ -275,6 +293,17 @@ class Extension */ public function buildShared(): void { + if (file_exists(BUILD_MODULES_PATH . '/' . $this->getName() . '.so')) { + logger()->info('extension ' . $this->getName() . ' already built, skipping'); + return; + } + foreach (Config::getExt($this->name, 'shared-ext-depends', []) as $name) { + $dependencyExt = $this->builder->getExt($name); + if ($dependencyExt === null) { + throw new RuntimeException("extension {$this->name} requires shared extension {$name}"); + } + $dependencyExt->buildShared(); + } match (PHP_OS_FAMILY) { 'Darwin', 'Linux' => $this->buildUnixShared(), default => throw new WrongUsageException(PHP_OS_FAMILY . ' build shared extensions is not supported yet'), @@ -297,17 +326,24 @@ class Extension 'CFLAGS' => $config['cflags'], 'LDFLAGS' => $config['ldflags'], 'LIBS' => $config['libs'], + 'LD_LIBRARY_PATH' => BUILD_LIB_PATH, ]; // prepare configure args shell()->cd($this->source_dir) ->setEnv($env) - ->execWithEnv(BUILD_BIN_PATH . '/phpize') - ->execWithEnv('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --enable-shared --disable-static') - ->execWithEnv('make clean') - ->execWithEnv('make -j' . $this->builder->concurrency); + ->execWithEnv(BUILD_BIN_PATH . '/phpize'); + + if ($this->patchBeforeSharedConfigure()) { + logger()->info('ext [ . ' . $this->getName() . '] patching before shared configure'); + } + + shell()->cd($this->source_dir) + ->setEnv($env) + ->execWithEnv('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --with-pic') + ->execWithEnv('make clean') + ->execWithEnv('make -j' . $this->builder->concurrency) + ->execWithEnv('make install'); - // copy shared library - copy($this->source_dir . '/modules/' . $this->getDistName() . '.so', BUILD_LIB_PATH . '/' . $this->getDistName() . '.so'); // check shared extension with php-cli if (file_exists(BUILD_BIN_PATH . '/php')) { $this->runSharedExtensionCheckUnix(); diff --git a/src/SPC/builder/extension/amqp.php b/src/SPC/builder/extension/amqp.php index 8fbfea24..40a6131c 100644 --- a/src/SPC/builder/extension/amqp.php +++ b/src/SPC/builder/extension/amqp.php @@ -28,7 +28,7 @@ class amqp extends Extension return '--with-amqp --with-librabbitmq-dir=' . BUILD_ROOT_PATH; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg($shared = false): string { return '--with-amqp'; } diff --git a/src/SPC/builder/extension/curl.php b/src/SPC/builder/extension/curl.php index d4f8b078..4779e67c 100644 --- a/src/SPC/builder/extension/curl.php +++ b/src/SPC/builder/extension/curl.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace SPC\builder\extension; use SPC\builder\Extension; +use SPC\builder\linux\LinuxBuilder; use SPC\builder\macos\MacOSBuilder; use SPC\exception\FileSystemException; use SPC\exception\WrongUsageException; @@ -52,6 +53,72 @@ class curl extends Extension { $frameworks = $this->builder instanceof MacOSBuilder ? ' ' . $this->builder->getFrameworks(true) . ' ' : ''; FileSystem::replaceFileRegex(SOURCE_PATH . '/php-src/configure', '/-lcurl/', $this->getLibFilesString() . $frameworks); + $this->patchBeforeSharedConfigure(); return true; } + + public function patchBeforeSharedConfigure(): bool + { + $file = SOURCE_PATH . '/php-src/ext/curl/config.m4'; + $content = FileSystem::readFile($file); + + // Inject patch before it + $patch = ' save_LIBS="$LIBS" + LIBS="$LIBS $CURL_LIBS" +'; + // Check if already patched + if (str_contains($content, $patch)) { + return false; // Already patched + } + + // Match the line containing PHP_CHECK_LIBRARY for curl + $pattern = '/(PHP_CHECK_LIBRARY\(\[curl],\s*\[curl_easy_perform],)/'; + + // Restore LIBS after the check — append this just after the macro block + $restore = ' + LIBS="$save_LIBS"'; + + // Apply patch + $patched = preg_replace_callback($pattern, function ($matches) use ($patch) { + return $patch . $matches[1]; + }, $content, 1); + + // Inject restore after the matching PHP_CHECK_LIBRARY block + $patched = preg_replace( + '/(PHP_CHECK_LIBRARY\(\[curl],\s*\[curl_easy_perform],.*?\)\n)/s', + "$1{$restore}\n", + $patched, + 1 + ); + + if ($patched === null) { + throw new \RuntimeException('Failed to patch config.m4 due to a regex error'); + } + + FileSystem::writeFile($file, $patched); + return true; + } + + public function buildUnixShared(): void + { + if (!$this->builder instanceof LinuxBuilder) { + parent::buildUnixShared(); + return; + } + + FileSystem::replaceFileStr( + $this->source_dir . '/config.m4', + ['$ext_dir/phar.1', '$ext_dir/phar.phar.1'], + ['${ext_dir}phar.1', '${ext_dir}phar.phar.1'] + ); + try { + parent::buildUnixShared(); + } finally { + FileSystem::replaceFileStr( + $this->source_dir . '/config.m4', + ['${ext_dir}phar.1', '${ext_dir}phar.phar.1'], + ['$ext_dir/phar.1', '$ext_dir/phar.phar.1'] + ); + } + } } diff --git a/src/SPC/builder/extension/dba.php b/src/SPC/builder/extension/dba.php index bd7388f3..abda5651 100644 --- a/src/SPC/builder/extension/dba.php +++ b/src/SPC/builder/extension/dba.php @@ -12,11 +12,11 @@ class dba extends Extension { public function getUnixConfigureArg(bool $shared = false): string { - $qdbm = $this->builder->getLib('qdbm') ? (' --with-qdbm=' . BUILD_ROOT_PATH) : ''; - return '--enable-dba' . $qdbm; + $qdbm = $this->builder->getLib('qdbm') ? (' --with-qdbm=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH) : ''; + return '--enable-dba' . ($shared ? '=shared' : '') . $qdbm; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { $qdbm = $this->builder->getLib('qdbm') ? ' --with-qdbm' : ''; return '--with-dba' . $qdbm; diff --git a/src/SPC/builder/extension/dom.php b/src/SPC/builder/extension/dom.php new file mode 100644 index 00000000..fb1a4e15 --- /dev/null +++ b/src/SPC/builder/extension/dom.php @@ -0,0 +1,35 @@ +builder->getLib('freetype') ? ' --with-freetype' : ''; $arg .= $this->builder->getLib('libjpeg') ? ' --with-jpeg' : ''; $arg .= $this->builder->getLib('libwebp') ? ' --with-webp' : ''; diff --git a/src/SPC/builder/extension/glfw.php b/src/SPC/builder/extension/glfw.php index 444b5d93..3ebb5228 100644 --- a/src/SPC/builder/extension/glfw.php +++ b/src/SPC/builder/extension/glfw.php @@ -35,7 +35,7 @@ class glfw extends Extension return '--enable-glfw --with-glfw-dir=' . BUILD_ROOT_PATH; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { return '--enable-glfw=static'; } diff --git a/src/SPC/builder/extension/intl.php b/src/SPC/builder/extension/intl.php index 8130b5d3..819aee69 100644 --- a/src/SPC/builder/extension/intl.php +++ b/src/SPC/builder/extension/intl.php @@ -23,4 +23,9 @@ class intl extends Extension } return true; } + + public function patchBeforeSharedBuild(): bool + { + return $this->patchBeforeBuildconf(); + } } diff --git a/src/SPC/builder/extension/mbregex.php b/src/SPC/builder/extension/mbregex.php index 4bf28544..1f169e1a 100644 --- a/src/SPC/builder/extension/mbregex.php +++ b/src/SPC/builder/extension/mbregex.php @@ -16,7 +16,7 @@ class mbregex extends Extension return 'mbstring'; } - public function getConfigureArg(): string + public function getConfigureArg(bool $shared = false): string { return ''; } diff --git a/src/SPC/builder/extension/mbstring.php b/src/SPC/builder/extension/mbstring.php index 5fcb88bd..3576877f 100644 --- a/src/SPC/builder/extension/mbstring.php +++ b/src/SPC/builder/extension/mbstring.php @@ -10,9 +10,20 @@ use SPC\util\CustomExt; #[CustomExt('mbstring')] class mbstring extends Extension { - public function getConfigureArg(): string + public function getConfigureArg(bool $shared = false): string { - $arg = '--enable-mbstring'; + $arg = '--enable-mbstring' . ($shared ? '=shared' : ''); + if ($this->builder->getExt('mbregex') === null) { + $arg .= ' --disable-mbregex'; + } else { + $arg .= ' --enable-mbregex'; + } + return $arg; + } + + public function getUnixConfigureArg(bool $shared = false): string + { + $arg = '--enable-mbstring' . ($shared ? '=shared' : ''); if ($this->builder->getExt('mbregex') === null) { $arg .= ' --disable-mbregex'; } else { diff --git a/src/SPC/builder/extension/odbc.php b/src/SPC/builder/extension/odbc.php index ac5c3e8f..278b5865 100644 --- a/src/SPC/builder/extension/odbc.php +++ b/src/SPC/builder/extension/odbc.php @@ -12,6 +12,6 @@ class odbc extends Extension { public function getUnixConfigureArg(bool $shared = false): string { - return '--with-unixODBC=' . BUILD_ROOT_PATH; + return '--with-unixODBC=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH; } } diff --git a/src/SPC/builder/extension/opcache.php b/src/SPC/builder/extension/opcache.php index 5d9dda0a..ec468cb8 100644 --- a/src/SPC/builder/extension/opcache.php +++ b/src/SPC/builder/extension/opcache.php @@ -24,6 +24,17 @@ class opcache extends Extension } } + public function runSharedExtensionCheckUnix(): void + { + [$ret, $out] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n -d "zend_extension=' . BUILD_MODULES_PATH . '/opcache.so" -v'); + if ($ret !== 0) { + throw new RuntimeException('opcache.so failed to load.'); + } + if (!str_contains(join($out), 'with Zend OPcache')) { + throw new RuntimeException('opcache.so failed to load.'); + } + } + public function patchBeforeBuildconf(): bool { if (file_exists(SOURCE_PATH . '/php-src/.opcache_patched')) { diff --git a/src/SPC/builder/extension/openssl.php b/src/SPC/builder/extension/openssl.php index add1aede..fc4831f3 100644 --- a/src/SPC/builder/extension/openssl.php +++ b/src/SPC/builder/extension/openssl.php @@ -26,6 +26,6 @@ class openssl extends Extension public function getUnixConfigureArg(bool $shared = false): string { $openssl_dir = $this->builder->getPHPVersionID() >= 80400 ? '' : ' --with-openssl-dir=' . BUILD_ROOT_PATH; - return '--with-openssl=' . BUILD_ROOT_PATH . $openssl_dir; + return '--with-openssl=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . $openssl_dir; } } diff --git a/src/SPC/builder/extension/pdo_odbc.php b/src/SPC/builder/extension/pdo_odbc.php index e436f381..c47144fe 100644 --- a/src/SPC/builder/extension/pdo_odbc.php +++ b/src/SPC/builder/extension/pdo_odbc.php @@ -19,10 +19,10 @@ class pdo_odbc extends Extension public function getUnixConfigureArg(bool $shared = false): string { - return '--with-pdo-odbc=unixODBC,' . BUILD_ROOT_PATH; + return '--with-pdo-odbc=' . ($shared ? 'shared,' : '') . 'unixODBC,' . BUILD_ROOT_PATH; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { return '--with-pdo-odbc'; } diff --git a/src/SPC/builder/extension/pdo_pgsql.php b/src/SPC/builder/extension/pdo_pgsql.php index e29014cb..b1ca1a81 100644 --- a/src/SPC/builder/extension/pdo_pgsql.php +++ b/src/SPC/builder/extension/pdo_pgsql.php @@ -10,7 +10,7 @@ use SPC\util\CustomExt; #[CustomExt('pdo_pgsql')] class pdo_pgsql extends Extension { - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { return '--with-pdo-pgsql=yes'; } diff --git a/src/SPC/builder/extension/pdo_sqlsrv.php b/src/SPC/builder/extension/pdo_sqlsrv.php new file mode 100644 index 00000000..195eaffe --- /dev/null +++ b/src/SPC/builder/extension/pdo_sqlsrv.php @@ -0,0 +1,38 @@ +builder))->config([$this->getName()]); + $env = [ + 'CFLAGS' => $config['cflags'], + 'CXXFLAGS' => $config['cflags'], + 'LDFLAGS' => $config['ldflags'], + 'LIBS' => $config['libs'], + 'LD_LIBRARY_PATH' => BUILD_LIB_PATH, + ]; + // prepare configure args + shell()->cd($this->source_dir) + ->setEnv($env) + ->execWithEnv(BUILD_BIN_PATH . '/phpize') + ->execWithEnv('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --enable-shared --disable-static') + ->execWithEnv('make clean') + ->execWithEnv('make -j' . $this->builder->concurrency) + ->execWithEnv('make install'); + + // check shared extension with php-cli + if (file_exists(BUILD_BIN_PATH . '/php')) { + $this->runSharedExtensionCheckUnix(); + } + } +} diff --git a/src/SPC/builder/extension/pgsql.php b/src/SPC/builder/extension/pgsql.php index 1c63f163..b45ba667 100644 --- a/src/SPC/builder/extension/pgsql.php +++ b/src/SPC/builder/extension/pgsql.php @@ -36,16 +36,16 @@ class pgsql extends Extension public function getUnixConfigureArg(bool $shared = false): string { if ($this->builder->getPHPVersionID() >= 80400) { - return '--with-pgsql PGSQL_CFLAGS=-I' . BUILD_INCLUDE_PATH . ' PGSQL_LIBS="-L' . BUILD_LIB_PATH . ' -lpq -lpgport -lpgcommon"'; + return '--with-pgsql' . ($shared ? '=shared' : '') . ' PGSQL_CFLAGS=-I' . BUILD_INCLUDE_PATH . ' PGSQL_LIBS="-L' . BUILD_LIB_PATH . ' -lpq -lpgport -lpgcommon"'; } - return '--with-pgsql=' . BUILD_ROOT_PATH; + return '--with-pgsql=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH; } /** * @throws WrongUsageException * @throws RuntimeException */ - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { if ($this->builder->getPHPVersionID() >= 80400) { return '--with-pgsql'; diff --git a/src/SPC/builder/extension/phar.php b/src/SPC/builder/extension/phar.php new file mode 100644 index 00000000..7396ba83 --- /dev/null +++ b/src/SPC/builder/extension/phar.php @@ -0,0 +1,37 @@ +builder instanceof LinuxBuilder) { + parent::buildUnixShared(); + return; + } + + FileSystem::replaceFileStr( + $this->source_dir . '/config.m4', + ['$ext_dir/phar.1', '$ext_dir/phar.phar.1'], + ['${ext_dir}phar.1', '${ext_dir}phar.phar.1'] + ); + try { + parent::buildUnixShared(); + } finally { + FileSystem::replaceFileStr( + $this->source_dir . '/config.m4', + ['${ext_dir}phar.1', '${ext_dir}phar.phar.1'], + ['$ext_dir/phar.1', '$ext_dir/phar.phar.1'] + ); + } + } +} diff --git a/src/SPC/builder/extension/rdkafka.php b/src/SPC/builder/extension/rdkafka.php index 50610325..9f28c627 100644 --- a/src/SPC/builder/extension/rdkafka.php +++ b/src/SPC/builder/extension/rdkafka.php @@ -27,10 +27,18 @@ class rdkafka extends Extension return true; } - public function getConfigureArg(): string + public function getConfigureArg(bool $shared = false): string { $pkgconf_libs = shell()->execWithResult('pkg-config --libs --static rdkafka')[1]; $pkgconf_libs = trim(implode('', $pkgconf_libs)); return '--with-rdkafka=' . BUILD_ROOT_PATH . ' LIBS="' . $pkgconf_libs . '"'; } + + public function getUnixConfigureArg(bool $shared = false): string + { + if ($shared) { + return '--with-rdkafka=' . BUILD_ROOT_PATH; + } + return parent::getUnixConfigureArg($shared); + } } diff --git a/src/SPC/builder/extension/readline.php b/src/SPC/builder/extension/readline.php index c66e7afa..dc4d15f7 100644 --- a/src/SPC/builder/extension/readline.php +++ b/src/SPC/builder/extension/readline.php @@ -24,4 +24,18 @@ class readline extends Extension ); return true; } + + public function getUnixConfigureArg(bool $shared = false): string + { + return '--without-libedit --with-readline=' . BUILD_ROOT_PATH; + } + + public function buildUnixShared(): void + { + if (!file_exists(BUILD_BIN_PATH . '/php') || !file_exists(BUILD_INCLUDE_PATH . '/php/sapi/cli/cli.h')) { + logger()->warning('CLI mode is not enabled, skipping readline build'); + return; + } + parent::buildUnixShared(); + } } diff --git a/src/SPC/builder/extension/redis.php b/src/SPC/builder/extension/redis.php index 0b60075c..75158ad7 100644 --- a/src/SPC/builder/extension/redis.php +++ b/src/SPC/builder/extension/redis.php @@ -24,7 +24,7 @@ class redis extends Extension return $arg; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { $arg = '--enable-redis'; $arg .= $this->builder->getExt('session') ? ' --enable-redis-session' : ' --disable-redis-session'; diff --git a/src/SPC/builder/extension/sockets.php b/src/SPC/builder/extension/sockets.php new file mode 100644 index 00000000..a0901415 --- /dev/null +++ b/src/SPC/builder/extension/sockets.php @@ -0,0 +1,21 @@ +builder))->config([$this->getName()]); + $env = [ + 'CFLAGS' => $config['cflags'], + 'CXXFLAGS' => $config['cflags'], + 'LDFLAGS' => $config['ldflags'], + 'LIBS' => $config['libs'], + 'LD_LIBRARY_PATH' => BUILD_LIB_PATH, + ]; + // prepare configure args + shell()->cd($this->source_dir) + ->setEnv($env) + ->execWithEnv(BUILD_BIN_PATH . '/phpize'); + + if ($this->patchBeforeSharedConfigure()) { + logger()->info('ext [ . ' . $this->getName() . '] patching before shared configure'); + } + + shell()->cd($this->source_dir) + ->setEnv($env) + ->execWithEnv('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --with-pic') + ->execWithEnv('make clean') + ->execWithEnv('make -j' . $this->builder->concurrency) + ->execWithEnv('make install'); + + // check shared extension with php-cli + if (file_exists(BUILD_BIN_PATH . '/php')) { + $this->runSharedExtensionCheckUnix(); + } + } } diff --git a/src/SPC/builder/extension/swow.php b/src/SPC/builder/extension/swow.php index 27576635..390ec27f 100644 --- a/src/SPC/builder/extension/swow.php +++ b/src/SPC/builder/extension/swow.php @@ -18,7 +18,7 @@ class swow extends Extension } } - public function getConfigureArg(): string + public function getConfigureArg(bool $shared = false): string { $arg = '--enable-swow'; $arg .= $this->builder->getLib('openssl') ? ' --enable-swow-ssl' : ' --disable-swow-ssl'; diff --git a/src/SPC/builder/extension/xdebug.php b/src/SPC/builder/extension/xdebug.php index ed592056..367eb420 100644 --- a/src/SPC/builder/extension/xdebug.php +++ b/src/SPC/builder/extension/xdebug.php @@ -13,9 +13,12 @@ class xdebug extends Extension { public function runSharedExtensionCheckUnix(): void { - [$ret] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n -d "zend_extension=' . BUILD_LIB_PATH . '/xdebug.so" --ri xdebug'); + [$ret, $out] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n -d "zend_extension=' . BUILD_MODULES_PATH . '/xdebug.so" -v'); if ($ret !== 0) { throw new RuntimeException('xdebug.so failed to load.'); } + if (!str_contains(join($out), 'with Xdebug')) { + throw new RuntimeException('xdebug.so failed to load.'); + } } } diff --git a/src/SPC/builder/extension/xhprof.php b/src/SPC/builder/extension/xhprof.php index c3d98aac..118a34cd 100644 --- a/src/SPC/builder/extension/xhprof.php +++ b/src/SPC/builder/extension/xhprof.php @@ -7,6 +7,7 @@ namespace SPC\builder\extension; use SPC\builder\Extension; use SPC\store\FileSystem; use SPC\util\CustomExt; +use SPC\util\SPCConfigUtil; #[CustomExt('xhprof')] class xhprof extends Extension @@ -30,4 +31,35 @@ class xhprof extends Extension } return false; } + + public function buildUnixShared(): void + { + $config = (new SPCConfigUtil($this->builder))->config([$this->getName()]); + $env = [ + 'CFLAGS' => $config['cflags'], + 'LDFLAGS' => $config['ldflags'], + 'LIBS' => $config['libs'], + 'LD_LIBRARY_PATH' => BUILD_LIB_PATH, + ]; + // prepare configure args + shell()->cd($this->source_dir . '/extension') + ->setEnv($env) + ->execWithEnv(BUILD_BIN_PATH . '/phpize'); + + if ($this->patchBeforeSharedConfigure()) { + logger()->info('ext [ . ' . $this->getName() . '] patching before shared configure'); + } + + shell()->cd($this->source_dir . '/extension') + ->setEnv($env) + ->execWithEnv('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --with-pic') + ->execWithEnv('make clean') + ->execWithEnv('make -j' . $this->builder->concurrency) + ->execWithEnv('make install'); + + // check shared extension with php-cli + if (file_exists(BUILD_BIN_PATH . '/php')) { + $this->runSharedExtensionCheckUnix(); + } + } } diff --git a/src/SPC/builder/extension/xlswriter.php b/src/SPC/builder/extension/xlswriter.php index 2ceb8e5c..878168ad 100644 --- a/src/SPC/builder/extension/xlswriter.php +++ b/src/SPC/builder/extension/xlswriter.php @@ -20,7 +20,7 @@ class xlswriter extends Extension return $arg; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { return '--with-xlswriter'; } diff --git a/src/SPC/builder/extension/xml.php b/src/SPC/builder/extension/xml.php index fc8bfc4d..bd64d346 100644 --- a/src/SPC/builder/extension/xml.php +++ b/src/SPC/builder/extension/xml.php @@ -13,7 +13,6 @@ use SPC\util\CustomExt; #[CustomExt('soap')] #[CustomExt('xmlreader')] #[CustomExt('xmlwriter')] -#[CustomExt('dom')] #[CustomExt('simplexml')] class xml extends Extension { @@ -27,11 +26,10 @@ class xml extends Extension 'soap' => '--enable-soap', 'xmlreader' => '--enable-xmlreader', 'xmlwriter' => '--enable-xmlwriter', - 'dom' => '--enable-dom', 'simplexml' => '--enable-simplexml', default => throw new RuntimeException('Not accept non-xml extension'), }; - $arg .= ' --with-libxml="' . BUILD_ROOT_PATH . '"'; + $arg .= ($shared ? '=shared' : '') . ' --with-libxml="' . BUILD_ROOT_PATH . '"'; return $arg; } @@ -41,14 +39,13 @@ class xml extends Extension return true; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { $arg = match ($this->name) { 'xml' => '--with-xml', 'soap' => '--enable-soap', 'xmlreader' => '--enable-xmlreader', 'xmlwriter' => '--enable-xmlwriter', - 'dom' => '--with-dom', 'simplexml' => '--with-simplexml', default => throw new RuntimeException('Not accept non-xml extension'), }; diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index e38714f1..0a827c85 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -106,6 +106,18 @@ class LinuxBuilder extends UnixBuilderBase */ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void { + if ($build_target === BUILD_TARGET_EMBED && + file_exists(BUILD_BIN_PATH . '/php-config') && + file_exists(BUILD_BIN_PATH . '/phpize') + ) { + $embed_type = getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') ?: 'static'; + if ($embed_type === 'shared' && file_exists(BUILD_LIB_PATH . '/libphp.so')) { + return; + } + if (file_exists(BUILD_LIB_PATH . '/libphp.a')) { + return; + } + } // ---------- Update extra-libs ---------- $extra_libs = getenv('SPC_EXTRA_LIBS') ?: ''; // bloat means force-load all static libraries, even if they are not used @@ -310,6 +322,7 @@ class LinuxBuilder extends UnixBuilderBase shell()->cd(SOURCE_PATH . '/php-src') ->exec('sed -i "s|//lib|/lib|g" Makefile') + ->exec('sed -i "s|^EXTENSION_DIR = .*|EXTENSION_DIR = /' . basename(BUILD_MODULES_PATH) . '|" Makefile') ->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install"); $this->patchPhpScripts(); } diff --git a/src/SPC/builder/linux/library/icu.php b/src/SPC/builder/linux/library/icu.php index 519c0734..ddcfe1b2 100644 --- a/src/SPC/builder/linux/library/icu.php +++ b/src/SPC/builder/linux/library/icu.php @@ -14,11 +14,16 @@ class icu extends LinuxLibraryBase protected function build(): void { - $cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1 -fPIC -fPIE -fno-ident"'; - $cxxflags = 'CXXFLAGS="-std=c++17"'; + $cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1 -DPIC -fPIC"'; + $cxxflags = 'CXXFLAGS="-std=c++17 -fPIC -fno-ident"'; $ldflags = getenv('SPC_LIBC') !== 'glibc' ? 'LDFLAGS="-static"' : ''; shell()->cd($this->source_dir . '/source') - ->exec( + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) + ->execWithEnv( "{$cppflags} {$cxxflags} {$ldflags} " . './runConfigureICU Linux ' . '--enable-static ' . @@ -33,9 +38,9 @@ class icu extends LinuxLibraryBase '--enable-samples=no ' . '--prefix=' . BUILD_ROOT_PATH ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install'); + ->execWithEnv('make clean') + ->execWithEnv("make -j{$this->builder->concurrency}") + ->execWithEnv('make install'); $this->patchPkgconfPrefix(['icu-i18n.pc', 'icu-io.pc', 'icu-uc.pc'], PKGCONF_PATCH_PREFIX); FileSystem::removeDir(BUILD_LIB_PATH . '/icu'); diff --git a/src/SPC/builder/linux/library/libffi.php b/src/SPC/builder/linux/library/libffi.php index 9d1c2d79..d7421425 100644 --- a/src/SPC/builder/linux/library/libffi.php +++ b/src/SPC/builder/linux/library/libffi.php @@ -21,7 +21,11 @@ class libffi extends LinuxLibraryBase $arch = getenv('SPC_ARCH'); shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . '--enable-static ' . diff --git a/src/SPC/builder/linux/library/libpng.php b/src/SPC/builder/linux/library/libpng.php index 56daee55..16fdca60 100644 --- a/src/SPC/builder/linux/library/libpng.php +++ b/src/SPC/builder/linux/library/libpng.php @@ -45,12 +45,11 @@ class libpng extends LinuxLibraryBase ->exec('chmod +x ./configure') ->exec('chmod +x ./install-sh') ->setEnv([ - 'CFLAGS' => trim($this->getLibExtraCFlags() . ' ' . $this->builder->arch_c_flags), - 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags() . ' -L' . BUILD_LIB_PATH, 'LIBS' => $this->getLibExtraLibs(), ]) ->execWithEnv( - 'LDFLAGS="-L' . BUILD_LIB_PATH . '" ' . './configure ' . '--disable-shared ' . '--enable-static ' . diff --git a/src/SPC/builder/linux/library/libxml2.php b/src/SPC/builder/linux/library/libxml2.php index 6f42d672..6d9470ae 100644 --- a/src/SPC/builder/linux/library/libxml2.php +++ b/src/SPC/builder/linux/library/libxml2.php @@ -24,13 +24,19 @@ class libxml2 extends LinuxLibraryBase FileSystem::resetDir($this->source_dir . '/build'); shell()->cd($this->source_dir . '/build') - ->exec( + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) + ->execWithEnv( 'cmake ' . '-DCMAKE_BUILD_TYPE=Release ' . '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . '-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' . "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . '-DBUILD_SHARED_LIBS=OFF ' . + '-DPOSITION_INDEPENDENT_CODE=ON ' . '-DIconv_IS_BUILT_IN=OFF ' . '-DLIBXML2_WITH_ICONV=ON ' . "-DLIBXML2_WITH_ZLIB={$enable_zlib} " . @@ -41,8 +47,8 @@ class libxml2 extends LinuxLibraryBase '-DLIBXML2_WITH_TESTS=OFF ' . '..' ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") + ->execWithEnv('make install'); FileSystem::replaceFileStr( BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc', diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index 5c07ec7e..55a238f9 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -65,7 +65,11 @@ class openssl extends LinuxLibraryBase $clang_postfix = SystemUtil::getCCType(getenv('CC')) === 'clang' ? '-clang' : ''; shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags() ?: $this->builder->arch_c_flags, 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( "{$env} ./Configure no-shared {$extra} " . '--prefix=/ ' . diff --git a/src/SPC/builder/macos/library/libpng.php b/src/SPC/builder/macos/library/libpng.php index b61cc898..f273bff6 100644 --- a/src/SPC/builder/macos/library/libpng.php +++ b/src/SPC/builder/macos/library/libpng.php @@ -59,6 +59,7 @@ class libpng extends MacOSLibraryBase ->cd(BUILD_LIB_PATH) ->exec('ln -sf libpng16.a libpng.a'); $this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX); + $this->patchLaDependencyPrefix(['libpng16.la']); $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/macos/library/openssl.php b/src/SPC/builder/macos/library/openssl.php index e0e3919f..28796d7c 100644 --- a/src/SPC/builder/macos/library/openssl.php +++ b/src/SPC/builder/macos/library/openssl.php @@ -50,7 +50,11 @@ class openssl extends MacOSLibraryBase $arch = getenv('SPC_ARCH'); shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->exec( "./Configure no-shared {$extra} " . '--prefix=/ ' . // use prefix=/ diff --git a/src/SPC/builder/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index 8e69f6d3..869bf531 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -84,6 +84,23 @@ trait UnixLibraryTrait } } + public function patchLaDependencyPrefix(array $files): void + { + logger()->info('Patching library [' . static::NAME . '] la files'); + foreach ($files as $name) { + $realpath = realpath(BUILD_LIB_PATH . '/' . $name); + if ($realpath === false) { + throw new RuntimeException('Cannot find library [' . static::NAME . '] la file [' . $name . '] !'); + } + logger()->debug('Patching ' . $realpath); + // replace prefix + $file = FileSystem::readFile($realpath); + $file = str_replace(' /lib/', ' ' . BUILD_LIB_PATH . '/', $file); + $file = preg_replace('/^libdir=.*$/m', "libdir='" . BUILD_LIB_PATH . "'", $file); + FileSystem::writeFile($realpath, $file); + } + } + /** * remove libtool archive files * diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index 4c8df333..48c82601 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -223,8 +223,8 @@ abstract class UnixBuilderBase extends BuilderBase default => throw new RuntimeException('Deployment does not accept type ' . $type), }; logger()->info('Deploying ' . $this->getBuildTypeName($type) . ' file'); - FileSystem::createDir(BUILD_ROOT_PATH . '/bin'); - shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_ROOT_PATH . '/bin/')); + FileSystem::createDir(BUILD_BIN_PATH); + shell()->exec('cp ' . escapeshellarg($src) . ' ' . escapeshellarg(BUILD_BIN_PATH)); return true; } @@ -250,6 +250,7 @@ abstract class UnixBuilderBase extends BuilderBase logger()->debug('Patching phpize prefix'); FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', "prefix=''", "prefix='" . BUILD_ROOT_PATH . "'"); FileSystem::replaceFileStr(BUILD_BIN_PATH . '/phpize', 's##', 's#/usr/local#'); + FileSystem::replaceFileStr(BUILD_LIB_PATH . '/php/build/phpize.m4', 'test "[$]$1" = "no" && $1=yes', '# test "[$]$1" = "no" && $1=yes'); } // patch php-config if (file_exists(BUILD_BIN_PATH . '/php-config')) { diff --git a/src/SPC/builder/unix/library/brotli.php b/src/SPC/builder/unix/library/brotli.php index 9e764fcb..44be934d 100644 --- a/src/SPC/builder/unix/library/brotli.php +++ b/src/SPC/builder/unix/library/brotli.php @@ -18,7 +18,11 @@ trait brotli { FileSystem::resetDir($this->source_dir . '/build-dir'); shell()->cd($this->source_dir . '/build-dir') - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( 'cmake ' . '-DCMAKE_BUILD_TYPE=Release ' . diff --git a/src/SPC/builder/unix/library/bzip2.php b/src/SPC/builder/unix/library/bzip2.php index 0241fb1b..284783c9 100644 --- a/src/SPC/builder/unix/library/bzip2.php +++ b/src/SPC/builder/unix/library/bzip2.php @@ -17,7 +17,11 @@ trait bzip2 protected function build(): void { shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv("make PREFIX='" . BUILD_ROOT_PATH . "' clean") ->execWithEnv("make -j{$this->builder->concurrency} {$this->builder->getEnvString()} PREFIX='" . BUILD_ROOT_PATH . "' libbz2.a") ->exec('cp libbz2.a ' . BUILD_LIB_PATH) diff --git a/src/SPC/builder/unix/library/freetype.php b/src/SPC/builder/unix/library/freetype.php index 42e8f91c..6fb24212 100644 --- a/src/SPC/builder/unix/library/freetype.php +++ b/src/SPC/builder/unix/library/freetype.php @@ -23,7 +23,11 @@ trait freetype $extra_libs .= $this->builder->getLib('brotli') ? '-DFT_DISABLE_BROTLI=OFF ' : '-DFT_DISABLE_BROTLI=ON '; FileSystem::resetDir($this->source_dir . '/build'); shell()->cd($this->source_dir . '/build') - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( "cmake {$this->builder->makeCmakeArgs()} -DFT_DISABLE_HARFBUZZ=ON " . '-DBUILD_SHARED_LIBS=OFF ' . diff --git a/src/SPC/builder/unix/library/gettext.php b/src/SPC/builder/unix/library/gettext.php index 69736c36..16622560 100644 --- a/src/SPC/builder/unix/library/gettext.php +++ b/src/SPC/builder/unix/library/gettext.php @@ -37,5 +37,6 @@ trait gettext ->execWithEnv('make clean') ->execWithEnv("make -j{$this->builder->concurrency}") ->execWithEnv('make install'); + $this->patchLaDependencyPrefix(['libintl.la']); } } diff --git a/src/SPC/builder/unix/library/gmp.php b/src/SPC/builder/unix/library/gmp.php index 49b207fb..e458401c 100644 --- a/src/SPC/builder/unix/library/gmp.php +++ b/src/SPC/builder/unix/library/gmp.php @@ -16,10 +16,14 @@ trait gmp protected function build(): void { shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags() ?: $this->builder->arch_c_flags, 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . - '--enable-static --disable-shared ' . + '--enable-static --disable-shared --with-pic ' . '--prefix=' ) ->execWithEnv('make clean') diff --git a/src/SPC/builder/unix/library/gmssl.php b/src/SPC/builder/unix/library/gmssl.php index 1d946621..792a1c93 100644 --- a/src/SPC/builder/unix/library/gmssl.php +++ b/src/SPC/builder/unix/library/gmssl.php @@ -20,7 +20,11 @@ trait gmssl FileSystem::resetDir($this->source_dir . '/build'); // Start build shell()->cd($this->source_dir . '/build') - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF ..") ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") ->execWithEnv('make install'); diff --git a/src/SPC/builder/unix/library/imagemagick.php b/src/SPC/builder/unix/library/imagemagick.php index 56da92e5..deb1e402 100644 --- a/src/SPC/builder/unix/library/imagemagick.php +++ b/src/SPC/builder/unix/library/imagemagick.php @@ -80,5 +80,10 @@ trait imagemagick 'includearchdir=${prefix}/include/ImageMagick-7' ); } + $this->patchLaDependencyPrefix([ + 'libMagick++-7.Q16HDRI.la', + 'libMagickCore-7.Q16HDRI.la', + 'libMagickWand-7.Q16HDRI.la', + ]); } } diff --git a/src/SPC/builder/unix/library/ldap.php b/src/SPC/builder/unix/library/ldap.php index 2831f094..93f889f0 100644 --- a/src/SPC/builder/unix/library/ldap.php +++ b/src/SPC/builder/unix/library/ldap.php @@ -50,5 +50,6 @@ trait ldap ->exec("make -j{$this->builder->concurrency}") ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['ldap.pc', 'lber.pc']); + $this->patchLaDependencyPrefix(['libldap.la', 'liblber.la']); } } diff --git a/src/SPC/builder/unix/library/libargon2.php b/src/SPC/builder/unix/library/libargon2.php index e91b71f0..e2dba687 100644 --- a/src/SPC/builder/unix/library/libargon2.php +++ b/src/SPC/builder/unix/library/libargon2.php @@ -11,7 +11,11 @@ trait libargon2 protected function build() { shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->exec("make PREFIX='' clean") ->execWithEnv("make -j{$this->builder->concurrency} PREFIX=''") ->execWithEnv("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH); diff --git a/src/SPC/builder/unix/library/libavif.php b/src/SPC/builder/unix/library/libavif.php index c2aaafcd..ddcf1d57 100644 --- a/src/SPC/builder/unix/library/libavif.php +++ b/src/SPC/builder/unix/library/libavif.php @@ -22,7 +22,11 @@ trait libavif FileSystem::resetDir($this->source_dir . '/build'); // Start build shell()->cd($this->source_dir . '/build') - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv("cmake {$this->builder->makeCmakeArgs()} -DBUILD_SHARED_LIBS=OFF -DAVIF_LIBYUV=OFF ..") ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") ->execWithEnv('make install'); diff --git a/src/SPC/builder/unix/library/libcares.php b/src/SPC/builder/unix/library/libcares.php index d99cc685..94871927 100644 --- a/src/SPC/builder/unix/library/libcares.php +++ b/src/SPC/builder/unix/library/libcares.php @@ -25,7 +25,11 @@ trait libcares protected function build(): void { shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv('./configure --prefix= --enable-static --disable-shared --disable-tests --with-pic') ->execWithEnv("make -j {$this->builder->concurrency}") ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); diff --git a/src/SPC/builder/unix/library/libevent.php b/src/SPC/builder/unix/library/libevent.php index 2e80f32e..bd070fd5 100644 --- a/src/SPC/builder/unix/library/libevent.php +++ b/src/SPC/builder/unix/library/libevent.php @@ -44,7 +44,11 @@ trait libevent FileSystem::resetDir($this->source_dir . '/build'); // Start build shell()->cd($this->source_dir . '/build') - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( 'cmake ' . '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . diff --git a/src/SPC/builder/unix/library/libiconv.php b/src/SPC/builder/unix/library/libiconv.php index a587c472..72297646 100644 --- a/src/SPC/builder/unix/library/libiconv.php +++ b/src/SPC/builder/unix/library/libiconv.php @@ -11,7 +11,11 @@ trait libiconv [,,$destdir] = SEPARATED_PATH; shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . '--enable-static ' . @@ -26,5 +30,6 @@ trait libiconv if (file_exists(BUILD_BIN_PATH . '/iconv')) { unlink(BUILD_BIN_PATH . '/iconv'); } + $this->patchLaDependencyPrefix(['libiconv.la']); } } diff --git a/src/SPC/builder/unix/library/liblz4.php b/src/SPC/builder/unix/library/liblz4.php index 45e803bf..39c24512 100644 --- a/src/SPC/builder/unix/library/liblz4.php +++ b/src/SPC/builder/unix/library/liblz4.php @@ -18,7 +18,11 @@ trait liblz4 protected function build(): void { shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv("make PREFIX='' clean") ->execWithEnv("make -j{$this->builder->concurrency} PREFIX=''") ->execWithEnv("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH); diff --git a/src/SPC/builder/unix/library/libsodium.php b/src/SPC/builder/unix/library/libsodium.php index b24d52b7..c6bc6168 100644 --- a/src/SPC/builder/unix/library/libsodium.php +++ b/src/SPC/builder/unix/library/libsodium.php @@ -9,10 +9,15 @@ trait libsodium protected function build(): void { shell()->cd($this->source_dir) - ->exec('./configure --enable-static --disable-shared --prefix=') - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) + ->execWithEnv('./configure --with-pic --enable-static --disable-shared --prefix=') + ->execWithEnv('make clean') + ->execWithEnv("make -j{$this->builder->concurrency}") + ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libsodium.pc'], PKGCONF_PATCH_PREFIX); } diff --git a/src/SPC/builder/unix/library/libtiff.php b/src/SPC/builder/unix/library/libtiff.php index 5d2cb4c1..b4ed21ad 100644 --- a/src/SPC/builder/unix/library/libtiff.php +++ b/src/SPC/builder/unix/library/libtiff.php @@ -23,7 +23,11 @@ trait libtiff $extra_libs .= ' --disable-lzma --disable-zstd --disable-webp --disable-libdeflate'; $shell = shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . '--enable-static --disable-shared ' . diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index 17fb2f1e..6de23e3e 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -25,12 +25,14 @@ trait libxslt } } shell()->cd($this->source_dir) - ->exec( - 'CFLAGS="-I' . BUILD_INCLUDE_PATH . '" ' . + ->setEnv([ + 'CFLAGS' => trim($this->getLibExtraCFlags() . ' -I' . BUILD_INCLUDE_PATH), + 'LDFLAGS' => trim($this->getLibExtraLdFlags() . ' -L' . BUILD_LIB_PATH), + 'LIBS' => trim($this->getLibExtraLibs() . "{$required_libs} -lstdc++"), + ]) + ->execWithEnv( "{$this->builder->getOption('library_path')} " . "{$this->builder->getOption('ld_library_path')} " . - 'LDFLAGS="-L' . BUILD_LIB_PATH . '" ' . - "LIBS='{$required_libs} -lstdc++' " . './configure ' . '--enable-static --disable-shared ' . '--without-python ' . @@ -41,9 +43,10 @@ trait libxslt '--with-libxml-prefix=' . escapeshellarg(BUILD_ROOT_PATH) . ' ' . '--prefix=' ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . escapeshellarg(BUILD_ROOT_PATH)); + ->execWithEnv('make clean') + ->execWithEnv("make -j{$this->builder->concurrency}") + ->execWithEnv('make install DESTDIR=' . escapeshellarg(BUILD_ROOT_PATH)); $this->patchPkgconfPrefix(['libexslt.pc']); + $this->patchLaDependencyPrefix(['libxslt.la', 'libexslt.la']); } } diff --git a/src/SPC/builder/unix/library/ncurses.php b/src/SPC/builder/unix/library/ncurses.php index a44ac175..0297afe2 100644 --- a/src/SPC/builder/unix/library/ncurses.php +++ b/src/SPC/builder/unix/library/ncurses.php @@ -12,7 +12,11 @@ trait ncurses { $filelist = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true); shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . '--enable-static ' . diff --git a/src/SPC/builder/unix/library/nghttp2.php b/src/SPC/builder/unix/library/nghttp2.php index 8f764c2a..cd0c488f 100644 --- a/src/SPC/builder/unix/library/nghttp2.php +++ b/src/SPC/builder/unix/library/nghttp2.php @@ -36,7 +36,11 @@ trait nghttp2 [,,$destdir] = SEPARATED_PATH; shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . '--enable-static ' . diff --git a/src/SPC/builder/unix/library/onig.php b/src/SPC/builder/unix/library/onig.php index 60ea84fa..56f72413 100644 --- a/src/SPC/builder/unix/library/onig.php +++ b/src/SPC/builder/unix/library/onig.php @@ -18,7 +18,11 @@ trait onig [,,$destdir] = SEPARATED_PATH; shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags() ?: $this->builder->arch_c_flags, 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv('./configure --enable-static --disable-shared --prefix=') ->execWithEnv('make clean') ->execWithEnv("make -j{$this->builder->concurrency}") diff --git a/src/SPC/builder/unix/library/pkgconfig.php b/src/SPC/builder/unix/library/pkgconfig.php index b489bbba..9478d9ea 100644 --- a/src/SPC/builder/unix/library/pkgconfig.php +++ b/src/SPC/builder/unix/library/pkgconfig.php @@ -14,7 +14,11 @@ trait pkgconfig $ldflags = !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? '' : '--static'; shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => "{$this->getLibExtraCFlags()} {$cflags}", 'LDFLAGS' => "{$this->getLibExtraLdFlags()} {$ldflags}", 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => "{$this->getLibExtraCFlags()} {$cflags}", + 'LDFLAGS' => "{$this->getLibExtraLdFlags()} {$ldflags}", + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . '--disable-shared ' . diff --git a/src/SPC/builder/unix/library/postgresql.php b/src/SPC/builder/unix/library/postgresql.php index 7885eca3..5a0da5de 100644 --- a/src/SPC/builder/unix/library/postgresql.php +++ b/src/SPC/builder/unix/library/postgresql.php @@ -39,10 +39,12 @@ trait postgresql $output = shell()->execWithResult("pkg-config --cflags-only-I --static {$packages}"); $error_exec_cnt += $output[0] === 0 ? 0 : 1; + $macos_15_bug_cflags = PHP_OS_FAMILY === 'Darwin' ? ' -Wno-unguarded-availability-new' : ''; + $cflags = ''; if (!empty($output[1][0])) { - $cppflags = $output[1][0]; - $macos_15_bug_cflags = PHP_OS_FAMILY === 'Darwin' ? ' -Wno-unguarded-availability-new' : ''; - $envs .= " CPPFLAGS=\"{$cppflags} -fPIC -fPIE -fno-ident{$macos_15_bug_cflags}\""; + $cflags = $output[1][0]; + $envs .= ' CPPFLAGS="-DPIC"'; + $cflags = "{$cflags} -fno-ident{$macos_15_bug_cflags}"; } $output = shell()->execWithResult("pkg-config --libs-only-L --static {$packages}"); $error_exec_cnt += $output[0] === 0 ? 0 : 1; @@ -78,9 +80,15 @@ trait postgresql throw new RuntimeException('Unsupported version for postgresql: ' . $version . ' !'); } + $env = [ + 'CFLAGS' => $this->getLibExtraCFlags() . ' ' . $cflags, + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]; // configure shell()->cd($this->source_dir . '/build') - ->exec( + ->setEnv($env) + ->execWithEnv( "{$envs} ../configure " . "--prefix={$builddir} " . '--disable-thread-safety ' . @@ -89,6 +97,7 @@ trait postgresql '--with-readline ' . '--with-libxml ' . ($this->builder->getLib('icu') ? '--with-icu ' : '--without-icu ') . + // ($this->builder->getLib('ldap') ? '--with-ldap ' : '--without-ldap ') . '--without-ldap ' . ($this->builder->getLib('libxslt') ? '--with-libxslt ' : '--without-libxslt ') . ($this->builder->getLib('zstd') ? '--with-zstd ' : '--without-zstd ') . @@ -98,16 +107,12 @@ trait postgresql '--without-pam ' . '--without-bonjour ' . '--without-tcl ' - ); - // ($this->builder->getLib('ldap') ? '--with-ldap ' : '--without-ldap ') . - - // build - shell()->cd($this->source_dir . '/build') - ->exec($envs . ' make -C src/bin/pg_config install') - ->exec($envs . ' make -C src/include install') - ->exec($envs . ' make -C src/common install') - ->exec($envs . ' make -C src/port install') - ->exec($envs . ' make -C src/interfaces/libpq install'); + ) + ->execWithEnv($envs . ' make -C src/bin/pg_config install') + ->execWithEnv($envs . ' make -C src/include install') + ->execWithEnv($envs . ' make -C src/common install') + ->execWithEnv($envs . ' make -C src/port install') + ->execWithEnv($envs . ' make -C src/interfaces/libpq install'); // remove dynamic libs shell()->cd($this->source_dir . '/build') diff --git a/src/SPC/builder/unix/library/readline.php b/src/SPC/builder/unix/library/readline.php index d0369c1a..0e881e7c 100644 --- a/src/SPC/builder/unix/library/readline.php +++ b/src/SPC/builder/unix/library/readline.php @@ -16,7 +16,11 @@ trait readline protected function build(): void { shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv( './configure ' . '--enable-static=yes ' . diff --git a/src/SPC/builder/unix/library/sqlite.php b/src/SPC/builder/unix/library/sqlite.php index ee814702..7f9f31bd 100644 --- a/src/SPC/builder/unix/library/sqlite.php +++ b/src/SPC/builder/unix/library/sqlite.php @@ -9,7 +9,11 @@ trait sqlite protected function build(): void { shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv('./configure --enable-static --disable-shared --prefix=') ->execWithEnv('make clean') ->execWithEnv("make -j{$this->builder->concurrency}") diff --git a/src/SPC/builder/unix/library/unixodbc.php b/src/SPC/builder/unix/library/unixodbc.php index f89eb0a4..be7e9297 100644 --- a/src/SPC/builder/unix/library/unixodbc.php +++ b/src/SPC/builder/unix/library/unixodbc.php @@ -16,19 +16,25 @@ trait unixodbc protected function build(): void { shell()->cd($this->source_dir) - ->exec( + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) + ->execWithEnv( './configure ' . '--enable-static --disable-shared ' . '--disable-debug ' . + '--with-pic ' . '--disable-dependency-tracking ' . '--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' . '--with-included-ltdl ' . '--enable-gui=no ' . '--prefix=' ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + ->execWithEnv('make clean') + ->execWithEnv("make -j{$this->builder->concurrency}") + ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['odbc.pc', 'odbccr.pc', 'odbcinst.pc']); $this->cleanLaFiles(); } diff --git a/src/SPC/builder/unix/library/zlib.php b/src/SPC/builder/unix/library/zlib.php index f764de91..42c46259 100644 --- a/src/SPC/builder/unix/library/zlib.php +++ b/src/SPC/builder/unix/library/zlib.php @@ -18,7 +18,11 @@ trait zlib [,,$destdir] = SEPARATED_PATH; shell()->cd($this->source_dir) - ->setEnv(['CFLAGS' => $this->getLibExtraCFlags(), 'LDFLAGS' => $this->getLibExtraLdFlags(), 'LIBS' => $this->getLibExtraLibs()]) + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->execWithEnv('./configure --static --prefix=') ->execWithEnv('make clean') ->execWithEnv("make -j{$this->builder->concurrency}") diff --git a/src/SPC/builder/unix/library/zstd.php b/src/SPC/builder/unix/library/zstd.php index 1990f658..939567f2 100644 --- a/src/SPC/builder/unix/library/zstd.php +++ b/src/SPC/builder/unix/library/zstd.php @@ -18,11 +18,17 @@ trait zstd { FileSystem::resetDir($this->source_dir . '/build/cmake/build'); shell()->cd($this->source_dir . '/build/cmake/build') + ->setEnv([ + 'CFLAGS' => $this->getLibExtraCFlags(), + 'LDFLAGS' => $this->getLibExtraLdFlags(), + 'LIBS' => $this->getLibExtraLibs(), + ]) ->exec( 'cmake ' . "{$this->builder->makeCmakeArgs()} " . '-DZSTD_BUILD_STATIC=ON ' . '-DZSTD_BUILD_SHARED=OFF ' . + '-DPOSITION_INDEPENDENT_CODE=ON ' . '..' ) ->exec("cmake --build . -j {$this->builder->concurrency}") diff --git a/src/SPC/command/BuildPHPCommand.php b/src/SPC/command/BuildPHPCommand.php index 0cf64f67..550fad3f 100644 --- a/src/SPC/command/BuildPHPCommand.php +++ b/src/SPC/command/BuildPHPCommand.php @@ -210,6 +210,8 @@ class BuildPHPCommand extends BuildCommand // start to build $builder->buildPHP($rule); + SourcePatcher::patchBeforeSharedBuild($builder); + // build dynamic extensions if needed if (!empty($shared_extensions)) { logger()->info('Building shared extensions ...'); @@ -246,8 +248,12 @@ class BuildPHPCommand extends BuildCommand } if (!empty($shared_extensions)) { foreach ($shared_extensions as $ext) { - $path = FileSystem::convertPath("{$build_root_path}/lib/{$ext}.so"); - logger()->info("Shared extension [{$ext}] path{$fixed}: {$path}"); + $path = FileSystem::convertPath("{$build_root_path}/modules/{$ext}.so"); + if (file_exists("{$build_root_path}/modules/{$ext}.so")) { + logger()->info("Shared extension [{$ext}] path{$fixed}: {$path}"); + } else { + logger()->warning("Shared extension [{$ext}] not found, please check!"); + } } } diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index b5de166f..0c02e155 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -78,6 +78,15 @@ class SourcePatcher } } + public static function patchBeforeSharedBuild(BuilderBase $builder): void + { + foreach ($builder->getExts() as $ext) { + if ($ext->patchBeforeSharedBuild() === true) { + logger()->info('Extension [' . $ext->getName() . '] patched before shared build'); + } + } + } + /** * Source patcher runner before configure * @@ -86,7 +95,7 @@ class SourcePatcher */ public static function patchBeforeConfigure(BuilderBase $builder): void { - foreach ($builder->getExts(false) as $ext) { + foreach ($builder->getExts() as $ext) { if ($ext->patchBeforeConfigure() === true) { logger()->info('Extension [' . $ext->getName() . '] patched before configure'); } diff --git a/src/globals/internal-env.php b/src/globals/internal-env.php index 34b1ed99..1046848e 100644 --- a/src/globals/internal-env.php +++ b/src/globals/internal-env.php @@ -9,10 +9,17 @@ use SPC\builder\windows\SystemUtil as WindowsSystemUtil; use SPC\store\FileSystem; use SPC\util\GlobalEnvManager; +// output path for everything, other paths are defined relative to this by default define('BUILD_ROOT_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_ROOT_PATH')) ? $a : (WORKING_DIR . '/buildroot'))); +// output path for header files for development define('BUILD_INCLUDE_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_INCLUDE_PATH')) ? $a : (BUILD_ROOT_PATH . '/include'))); +// output path for libraries and for libphp.so, if building shared embed define('BUILD_LIB_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_LIB_PATH')) ? $a : (BUILD_ROOT_PATH . '/lib'))); +// output path for binaries define('BUILD_BIN_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_BIN_PATH')) ? $a : (BUILD_ROOT_PATH . '/bin'))); +// output path for shared extensions +define('BUILD_MODULES_PATH', FileSystem::convertPath(is_string($a = getenv('BUILD_MODULES_PATH')) ? $a : (BUILD_ROOT_PATH . '/modules'))); + define('PKG_ROOT_PATH', FileSystem::convertPath(is_string($a = getenv('PKG_ROOT_PATH')) ? $a : (WORKING_DIR . '/pkgroot'))); define('SOURCE_PATH', FileSystem::convertPath(is_string($a = getenv('SOURCE_PATH')) ? $a : (WORKING_DIR . '/source'))); define('DOWNLOAD_PATH', FileSystem::convertPath(is_string($a = getenv('DOWNLOAD_PATH')) ? $a : (WORKING_DIR . '/downloads'))); diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index ef2b6fa6..e2f0ca12 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -21,15 +21,15 @@ $test_php_version = [ // test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available) $test_os = [ - // 'macos-13', + 'macos-13', // 'macos-14', - // 'macos-15', - // 'ubuntu-latest', - // 'ubuntu-22.04', + 'macos-15', + 'ubuntu-latest', + 'ubuntu-22.04', // 'ubuntu-24.04', - // 'ubuntu-22.04-arm', - // 'ubuntu-24.04-arm', - 'windows-latest', + 'ubuntu-22.04-arm', + 'ubuntu-24.04-arm', + // 'windows-latest', ]; // whether enable thread safe @@ -45,13 +45,13 @@ $prefer_pre_built = false; // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'pgsql', + 'Linux', 'Darwin' => 'xsl,simplexml,xlswriter', 'Windows' => 'xlswriter,openssl', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). $shared_extensions = match (PHP_OS_FAMILY) { - 'Linux' => 'xdebug', + 'Linux' => 'xdebug,intl,pgsql', 'Windows', 'Darwin' => '', };