diff --git a/.gitignore b/.gitignore index 7f5ea9b74..a95eeaacd 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/bin/spc-gnu-docker b/bin/spc-gnu-docker index 1ff87303c..36e0420e9 100755 --- a/bin/spc-gnu-docker +++ b/bin/spc-gnu-docker @@ -72,6 +72,7 @@ RUN yum update -y && \ yum install -y devtoolset-10-gcc-* RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc RUN source /etc/bashrc +RUN yum install -y which RUN curl -o cmake.tgz -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$BASE_ARCH.tar.gz && \ mkdir /cmake && \ diff --git a/config/env.ini b/config/env.ini index f70ad0a2e..ba8652d5f 100644 --- a/config/env.ini +++ b/config/env.ini @@ -68,8 +68,8 @@ 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" -SPC_DEFAULT_CXX_FLAGS= +SPC_DEFAULT_C_FLAGS="-fpic -Os" +SPC_DEFAULT_CXX_FLAGS="-fpic -Os" ; 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= ; upx executable path @@ -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 --disable-shared --enable-static --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) @@ -89,7 +89,7 @@ SPC_CMD_VAR_PHP_EMBED_TYPE="static" ; *** default build vars for building php *** ; CFLAGS for configuring php -SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS} -fPIE" +SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS} -fpie" ; CPPFLAGS for configuring php SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS="-I${BUILD_INCLUDE_PATH}" ; LDFLAGS for configuring php @@ -97,9 +97,11 @@ 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 -Os -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -fno-ident -fPIE -fPIC" +SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fno-ident -fpie ${SPC_DEFAULT_C_FLAGS}" ; EXTRA_LIBS for `make` php SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm" +; EXTRA_LDFLAGS for `make` php, can use -release to set a soname for libphp.so +SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS="" ; EXTRA_LDFLAGS_PROGRAM for `make` php SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -Wl,-O1 -pie" @@ -108,8 +110,8 @@ SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-all-static -Wl,-O1 -pie" CC=clang CXX=clang++ ; default compiler flags, used in CMake toolchain file, openssl and pkg-config build -SPC_DEFAULT_C_FLAGS="--target=${MAC_ARCH}-apple-darwin" -SPC_DEFAULT_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin" +SPC_DEFAULT_C_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os" +SPC_DEFAULT_CXX_FLAGS="--target=${MAC_ARCH}-apple-darwin -Os" ; 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= ; phpmicro patches, for more info, see: https://github.com/easysoft/phpmicro/tree/master/patches @@ -131,7 +133,7 @@ SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS="-I${BUILD_INCLUDE_PATH}" ; LDFLAGS for configuring php SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS="-L${BUILD_LIB_PATH}" ; EXTRA_CFLAGS for `make` php -SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie -Os -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" +SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="-g -fstack-protector-strong -fpic -fpie ${SPC_DEFAULT_C_FLAGS}" ; EXTRA_LIBS for `make` php SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-lresolv" ; embed type for php, static (libphp.a) or shared (libphp.dylib) diff --git a/config/ext.json b/config/ext.json index 63e511e4d..f86306970 100644 --- a/config/ext.json +++ b/config/ext.json @@ -24,6 +24,14 @@ "bcmath": { "type": "builtin" }, + "brotli": { + "type": "external", + "source": "ext-brotli", + "arg-type": "enable", + "lib-depends": [ + "brotli" + ] + }, "bz2": { "type": "builtin", "arg-type-unix": "with-prefix", @@ -95,7 +103,10 @@ "ev": { "type": "external", "source": "ev", - "arg-type-windows": "with" + "arg-type-windows": "with", + "ext-depends": [ + "sockets" + ] }, "event": { "support": { @@ -124,10 +135,6 @@ "Linux": "partial", "BSD": "wip" }, - "target": [ - "static", - "shared" - ], "notes": true, "arg-type": "custom", "type": "builtin", @@ -323,6 +330,16 @@ "openssl" ] }, + "libxml": { + "support": { + "BSD": "wip" + }, + "type": "builtin", + "arg-type": "none", + "target": [ + "static" + ] + }, "lz4": { "support": { "Windows": "wip", @@ -335,19 +352,12 @@ "liblz4" ] }, - "libxml": { - "support": { - "BSD": "wip" - }, - "type": "builtin", - "arg-type": "none", - "ext-depends": [ - "xml" - ] - }, "mbregex": { "type": "builtin", "arg-type": "custom", + "target": [ + "static" + ], "ext-depends": [ "mbstring" ], @@ -380,13 +390,13 @@ "ext-depends": [ "zlib", "session" - ] + ], + "build-with-php": true }, "memcached": { "support": { "Windows": "wip", - "BSD": "wip", - "Linux": "no" + "BSD": "wip" }, "type": "external", "source": "memcached", @@ -395,6 +405,10 @@ "lib-depends": [ "libmemcached" ], + "lib-depends-unix": [ + "libmemcached", + "fastlz" + ], "ext-depends": [ "session", "zlib" @@ -413,6 +427,10 @@ "openssl", "zstd", "zlib" + ], + "frameworks": [ + "CoreFoundation", + "Security" ] }, "msgpack": { @@ -422,7 +440,10 @@ "type": "external", "source": "msgpack", "arg-type-unix": "with", - "arg-type-win": "enable" + "arg-type-win": "enable", + "ext-depends": [ + "session" + ] }, "mysqli": { "type": "builtin", @@ -461,7 +482,8 @@ }, "opcache": { "type": "builtin", - "arg-type-unix": "custom" + "arg-type-unix": "custom", + "zend-extension": true }, "openssl": { "notes": true, @@ -650,6 +672,9 @@ "arg-type": "with-prefix", "lib-depends": [ "readline" + ], + "target": [ + "static" ] }, "redis": { @@ -669,10 +694,12 @@ ] }, "session": { - "type": "builtin" + "type": "builtin", + "build-with-php": true }, "shmop": { - "type": "builtin" + "type": "builtin", + "build-with-php": true }, "simdjson": { "type": "external", @@ -690,7 +717,8 @@ ], "ext-depends-windows": [ "xml" - ] + ], + "build-with-php": true }, "snappy": { "support": { @@ -783,7 +811,7 @@ "lib-depends": [ "libssh2" ], - "ext-depends-windows": [ + "ext-depends": [ "openssl", "zlib" ] @@ -793,9 +821,6 @@ "Windows": "no", "BSD": "wip" }, - "target": [ - "static" - ], "notes": true, "type": "external", "source": "swoole", @@ -913,7 +938,8 @@ ] }, "tokenizer": { - "type": "builtin" + "type": "builtin", + "build-with-php": true }, "uuid": { "support": { @@ -954,7 +980,8 @@ "Darwin": "partial", "Linux": "partial" }, - "notes": true + "notes": true, + "zend-extension": true }, "xhprof": { "support": { @@ -966,7 +993,8 @@ "source": "xhprof", "ext-depends": [ "ctype" - ] + ], + "build-with-php": true }, "xlswriter": { "support": { @@ -996,7 +1024,8 @@ ], "ext-depends-windows": [ "iconv" - ] + ], + "build-with-php": true }, "xmlreader": { "support": { @@ -1010,7 +1039,8 @@ "ext-depends-windows": [ "xml", "dom" - ] + ], + "build-with-php": true }, "xmlwriter": { "support": { @@ -1023,7 +1053,8 @@ ], "ext-depends-windows": [ "xml" - ] + ], + "build-with-php": true }, "xsl": { "support": { @@ -1040,6 +1071,14 @@ "dom" ] }, + "xz": { + "type": "external", + "source": "ext-xz", + "arg-type": "with", + "lib-depends": [ + "xz" + ] + }, "yac": { "support": { "BSD": "wip" @@ -1047,6 +1086,9 @@ "type": "external", "source": "yac", "arg-type-unix": "custom", + "lib-depends-unix": [ + "fastlz" + ], "ext-depends-unix": [ "igbinary" ] @@ -1067,9 +1109,6 @@ "support": { "BSD": "wip" }, - "target": [ - "static" - ], "type": "builtin", "arg-type": "with-prefix", "arg-type-windows": "enable", @@ -1093,6 +1132,9 @@ "arg-type-windows": "enable", "lib-depends": [ "zlib" + ], + "target": [ + "static" ] }, "zstd": { diff --git a/config/lib.json b/config/lib.json index 0d4941f07..160d43f2f 100644 --- a/config/lib.json +++ b/config/lib.json @@ -101,6 +101,15 @@ "SystemConfiguration" ] }, + "fastlz": { + "source": "fastlz", + "static-libs-unix": [ + "libfastlz.a" + ], + "headers": [ + "fastlz/fastlz.h" + ] + }, "freetype": { "source": "freetype", "static-libs-unix": [ @@ -234,8 +243,8 @@ "ldap": { "source": "ldap", "static-libs-unix": [ - "liblber.a", - "libldap.a" + "libldap.a", + "liblber.a" ], "lib-depends": [ "openssl", @@ -389,7 +398,9 @@ "source": "libmemcached", "static-libs-unix": [ "libmemcached.a", - "libmemcachedutil.a" + "libmemcachedprotocol.a", + "libmemcachedutil.a", + "libhashkit.a" ] }, "libpng": { diff --git a/config/source.json b/config/source.json index 81c21cfd8..2ad8ec873 100644 --- a/config/source.json +++ b/config/source.json @@ -50,8 +50,9 @@ } }, "brotli": { - "type": "ghtar", + "type": "ghtagtar", "repo": "google/brotli", + "match": "v1\\.\\d.*", "provide-pre-built": true, "license": { "type": "file", @@ -102,6 +103,16 @@ "path": "LICENSE" } }, + "ext-brotli": { + "type": "git", + "path": "php-src/ext/brotli", + "rev": "master", + "url": "https://github.com/kjdev/php-ext-brotli", + "license": { + "type": "file", + "path": "LICENSE" + } + }, "ext-ds": { "type": "url", "url": "https://pecl.php.net/get/ds", @@ -241,6 +252,16 @@ "path": "LICENSE" } }, + "ext-xz": { + "type": "git", + "path": "php-src/ext/xz", + "rev": "main", + "url": "https://github.com/codemasher/php-ext-xz", + "license": { + "type": "file", + "path": "LICENSE" + } + }, "ext-zstd": { "type": "git", "path": "php-src/ext/zstd", @@ -251,6 +272,15 @@ "path": "LICENSE" } }, + "fastlz": { + "type": "git", + "url": "https://github.com/ariya/FastLZ.git", + "rev": "master", + "license": { + "type": "file", + "path": "LICENSE.MIT" + } + }, "freetype": { "type": "git", "rev": "VER-2-13-2", @@ -507,12 +537,12 @@ } }, "libmemcached": { - "type": "git", - "url": "https://github.com/static-php/libmemcached-macos.git", - "rev": "master", + "type": "ghtagtar", + "repo": "awesomized/libmemcached", + "match": "1.\\d.\\d", "license": { "type": "file", - "path": "COPYING" + "path": "LICENSE" } }, "libpng": { @@ -801,8 +831,9 @@ } }, "postgresql": { - "type": "url", - "url": "https://ftp.postgresql.org/pub/source/v16.2/postgresql-16.2.tar.bz2", + "type": "ghtagtar", + "repo": "postgres/postgres", + "match": "REL_16_\\d+", "license": { "type": "file", "path": "COPYRIGHT" diff --git a/docs/.vitepress/components/CliGenerator.vue b/docs/.vitepress/components/CliGenerator.vue index 0d830b730..ad17783ac 100644 --- a/docs/.vitepress/components/CliGenerator.vue +++ b/docs/.vitepress/components/CliGenerator.vue @@ -30,6 +30,7 @@
{{ I18N[lang].selectCommon }}
+
{{ I18N[lang].selectAll }}
{{ I18N[lang].selectNone }}
@@ -44,6 +45,7 @@

TIP

{{ I18N[lang].depTips }}

+

{{ I18N[lang].depTips2 }}

{{ I18N[lang].buildTarget }}

@@ -252,6 +254,7 @@ const I18N = { no: '否', resultShow: '结果展示', selectCommon: '选择常用扩展', + selectAll: '选择全部', selectNone: '全部取消选择', useZTS: '是否编译线程安全版', hardcodedINI: '硬编码 INI 选项', @@ -267,6 +270,7 @@ const I18N = { selectedSystem: '选择操作系统', buildLibs: '要构建的库', depTips: '选择扩展后,不可选中的项目为必需的依赖,编译的依赖库列表中可选的为现有扩展和依赖库的可选依赖。选择可选依赖后,将生成 --with-libs 参数。', + depTips2: '无法同时构建所有扩展,因为有些扩展之间相互冲突。请根据需要选择扩展。', microUnavailable: 'micro 不支持 PHP 7.4 及更早版本!', windowsSAPIUnavailable: 'Windows 目前不支持 fpm、embed 构建!', useUPX: '是否开启 UPX 压缩(减小二进制体积)', @@ -286,6 +290,7 @@ const I18N = { no: 'No', resultShow: 'Result', selectCommon: 'Select common extensions', + selectAll: 'Select all', selectNone: 'Unselect all', useZTS: 'Enable ZTS', hardcodedINI: 'Hardcoded INI options', @@ -301,6 +306,7 @@ const I18N = { selectedSystem: 'Select Build OS', buildLibs: 'Select Dependencies', depTips: 'After selecting the extensions, the unselectable items are essential dependencies. In the compiled dependencies list, optional dependencies consist of existing extensions and optional dependencies of libraries. Optional dependencies will be added in --with-libs parameter.', + depTips2: 'It is not possible to build all extensions at the same time, as some extensions conflict with each other. Please select the extensions you need.', microUnavailable: 'Micro does not support PHP 7.4 and earlier versions!', windowsSAPIUnavailable: 'Windows does not support fpm and embed build!', useUPX: 'Enable UPX compression (reduce binary size)', @@ -337,6 +343,10 @@ const selectCommon = () => { ]; }; +const selectAll = () => { + checkedExts.value = extFilter.value; +}; + const extList = computed(() => { return checkedExts.value.join(','); }); @@ -364,7 +374,7 @@ const checkedTargets = ref(['cli']); const selectedEnv = ref('spc'); // chosen php version -const selectedPhpVersion = ref('8.2'); +const selectedPhpVersion = ref('8.4'); // chosen debug const debug = ref(0); diff --git a/docs/en/guide/extension-notes.md b/docs/en/guide/extension-notes.md index dc0f1d7a7..aa11c3772 100644 --- a/docs/en/guide/extension-notes.md +++ b/docs/en/guide/extension-notes.md @@ -151,8 +151,7 @@ Parallel is only supported on PHP 8.0 ZTS and above. ## spx -1. The [SPX extension](https://github.com/NoiseByNorthwest/php-spx) only supports NTS mode. -2. SPX does not support Windows, and the official repository does not support static compilation. static-php-cli uses a [modified version](https://github.com/static-php/php-spx). +1. SPX does not support Windows, and the official repository does not support static compilation. static-php-cli uses a [modified version](https://github.com/static-php/php-spx). ## mimalloc diff --git a/docs/zh/guide/extension-notes.md b/docs/zh/guide/extension-notes.md index c7b3a8d19..10e62eb06 100644 --- a/docs/zh/guide/extension-notes.md +++ b/docs/zh/guide/extension-notes.md @@ -141,8 +141,7 @@ parallel 扩展只支持 PHP 8.0 及以上版本,并只支持 ZTS 构建(`-- ## spx -1. [SPX 扩展](https://github.com/NoiseByNorthwest/php-spx) 只支持非线程模式。 -2. SPX 目前不支持 Windows,且官方仓库也不支持静态编译,static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。 +1. SPX 目前不支持 Windows,且官方仓库也不支持静态编译,static-php-cli 使用了 [修改版本](https://github.com/static-php/php-spx)。 ## mimalloc diff --git a/package.json b/package.json index 4b4487159..da1bbb880 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "docs:preview": "vitepress preview docs" }, "devDependencies": { - "vitepress": "^1.0.0-rc.35", + "vitepress": "^2.0.0-alpha.5", "vue": "^3.2.47" } } diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index 59f371efc..433d0b97f 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -4,6 +4,7 @@ namespace SPC\builder; +use PharIo\FileSystem\File; use SPC\exception\ExceptionHandler; use SPC\exception\FileSystemException; use SPC\exception\InterruptException; @@ -127,7 +128,7 @@ public function getExts(bool $including_shared = true): array if ($including_shared) { return $this->exts; } - return array_filter($this->exts, fn ($ext) => !$ext->isBuildShared()); + return array_filter($this->exts, fn ($ext) => $ext->isBuildStatic()); } /** @@ -233,15 +234,52 @@ public function proveExts(array $static_extensions, array $shared_extensions = [ */ abstract public function buildPHP(int $build_target = BUILD_TARGET_NONE); + /** + * Test PHP + */ + abstract public function testPHP(int $build_target = BUILD_TARGET_NONE); + + /** + * @throws WrongUsageException + * @throws RuntimeException + * @throws FileSystemException + */ public function buildSharedExts(): void { - foreach ($this->getExts() as $ext) { - if (!$ext->isBuildShared()) { - continue; + $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; } - logger()->info('Building extension [' . $ext->getName() . '] as shared extension (' . $ext->getName() . '.so)'); - $ext->buildShared(); } + file_put_contents(BUILD_BIN_PATH . '/php-config', implode('', $lines)); + FileSystem::createDir(BUILD_MODULES_PATH); + try { + foreach ($this->getExts() as $ext) { + if (!$ext->isBuildShared()) { + continue; + } + if (Config::getExt($ext->getName(), 'type') === 'builtin' || Config::getExt($ext->getName(), 'build-with-php') === true) { + 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; + } + if (Config::getExt($ext->getName(), 'build-with-php') === true) { + logger()->warning('Shared extension [' . $ext->getName() . '] did not build with php-src/configure (' . $ext->getName() . '.so)'); + logger()->warning('Try deleting your build and source folders and running `spc build`` again.'); + continue; + } + } + $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); } /** @@ -254,9 +292,21 @@ public function buildSharedExts(): void 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() && !$ext->isBuildStatic()) { + if ( + (Config::getExt($ext->getName(), 'type') === 'builtin' && + !file_exists(SOURCE_PATH . '/php-src/ext/' . $ext->getName() . '/config.m4')) || + Config::getExt($ext->getName(), 'build-with-php') === true + ) { + $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 79c0a9576..6ec68b6fd 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -53,26 +53,26 @@ public function __construct(protected string $name, protected BuilderBase $build } } + public function getFrameworks(): array + { + return Config::getExt($this->getName(), 'frameworks', []); + } + /** * 获取开启该扩展的 PHP 编译添加的参数 * * @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 +81,13 @@ public function getConfigureArg(): string * @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] ."), }; @@ -147,15 +147,15 @@ public function getDistName(): string 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); } /** @@ -189,18 +189,70 @@ public function patchBeforeMake(): bool } /** - * Run shared extension check when cli is enabled - * @throws RuntimeException + * 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 runSharedExtensionCheckUnix(): void + public function patchBeforeSharedBuild(): bool { - [$ret] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n -d "extension=' . BUILD_LIB_PATH . '/' . $this->getName() . '.so" --ri ' . $this->getName()); - if ($ret !== 0) { - throw new RuntimeException($this->getName() . '.so failed to load'); + 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; + } + + /** + * @return string + * returns a command line string with all required shared extensions to load + * i.e.; pdo_pgsql would return: + * + * `-d "extension=pgsql" -d "extension=pdo_pgsql"` + * @throws FileSystemException + * @throws WrongUsageException + */ + public function getSharedExtensionLoadString(): 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()) { + if (Config::getExt($ext->getName(), 'zend-extension', false) === true) { + $ret .= " -d \"zend_extension={$ext->getName()}\""; + } else { + $ret .= " -d \"extension={$ext->getName()}\""; + } + } } - if ($this->isBuildStatic()) { - logger()->warning($this->getName() . '.so test succeeded, but has little significance since it is also compiled in statically.'); + + if ($ret !== '') { + $ret = ' -d "extension_dir=' . BUILD_MODULES_PATH . '"' . $ret; } + + return $ret; } /** @@ -211,7 +263,8 @@ public function runCliCheckUnix(): void // 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->getSharedExtensionLoadString(); + [$ret] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n' . $sharedExtensions . ' --ri "' . $this->getDistName() . '"'); if ($ret !== 0) { throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); } @@ -224,7 +277,7 @@ public function runCliCheckUnix(): void 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_BIN_PATH . '/php -n' . $sharedExtensions . ' -r "' . trim($test) . '"'); if ($ret !== 0) { if ($this->builder->getOption('debug')) { var_dump($out); @@ -275,6 +328,20 @@ public function validate(): void */ 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; + } + foreach ($this->dependencies as $dependency) { + if (!$dependency instanceof Extension) { + continue; + } + if (!$dependency->isBuildStatic()) { + logger()->info('extension ' . $this->getName() . ' requires extension ' . $dependency->getName()); + $dependency->buildShared(); + } + } match (PHP_OS_FAMILY) { 'Darwin', 'Linux' => $this->buildUnixShared(), default => throw new WrongUsageException(PHP_OS_FAMILY . ' build shared extensions is not supported yet'), @@ -292,26 +359,44 @@ public function buildShared(): void */ public function buildUnixShared(): void { - $config = (new SPCConfigUtil($this->builder))->config([$this->getName()]); + $config = (new SPCConfigUtil($this->builder))->config([$this->getName()], with_dependencies: true); + [$staticLibString, $sharedLibString] = $this->getStaticAndSharedLibs(); $env = [ 'CFLAGS' => $config['cflags'], + 'CXXFLAGS' => $config['cflags'], 'LDFLAGS' => $config['ldflags'], - 'LIBS' => $config['libs'], + 'LIBS' => '-Wl,-Bstatic -Wl,--start-group ' . $staticLibString . ' -Wl,--end-group -Wl,-Bdynamic ' . $sharedLibString, + 'LD_LIBRARY_PATH' => BUILD_LIB_PATH, ]; + // prepare configure args shell()->cd($this->source_dir) ->setEnv($env) - ->exec(BUILD_BIN_PATH . '/phpize') - ->exec('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --enable-shared --disable-static') - ->exec('make clean') - ->exec('make -j' . $this->builder->concurrency); + ->exec(BUILD_BIN_PATH . '/phpize'); - // 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(); + if ($this->patchBeforeSharedConfigure()) { + logger()->info('ext [ . ' . $this->getName() . '] patching before shared configure'); } + + shell()->cd($this->source_dir) + ->setEnv($env) + ->exec( + './configure ' . $this->getUnixConfigureArg(true) . + ' --with-php-config=' . BUILD_BIN_PATH . '/php-config ' . + '--enable-shared --disable-static' + ); + + FileSystem::replaceFileRegex( + $this->source_dir . '/Makefile', + '/^(.*_SHARED_LIBADD\s*=.*)$/m', + '$1 ' . $staticLibString + ); + + shell()->cd($this->source_dir) + ->setEnv($env) + ->exec('make clean') + ->exec('make -j' . $this->builder->concurrency) + ->exec('make install'); } /** @@ -382,6 +467,37 @@ protected function addExtensionDependency(string $name, bool $optional = false): } } + /** + * Get required static and shared libraries as a pair of strings in format -l{libname} -l{libname2} + * + * @return array [staticLibString, sharedLibString] + */ + private function getStaticAndSharedLibs(): array + { + $config = (new SPCConfigUtil($this->builder))->config([$this->getName()], with_dependencies: true); + $sharedLibString = ''; + $staticLibString = ''; + $staticLibs = $this->getLibFilesString(); + $staticLibs = str_replace(BUILD_LIB_PATH . '/lib', '-l', $staticLibs); + $staticLibs = str_replace('.a', '', $staticLibs); + $staticLibs = explode('-l', $staticLibs . ' ' . $config['libs']); + foreach ($staticLibs as $lib) { + $lib = trim($lib); + if ($lib === '') { + continue; + } + $static_lib = 'lib' . $lib . '.a'; + if (file_exists(BUILD_LIB_PATH . '/' . $static_lib)) { + if (!str_contains($staticLibString, '-l' . $lib . ' ')) { + $staticLibString .= '-l' . $lib . ' '; + } + } elseif (!str_contains($sharedLibString, '-l' . $lib . ' ')) { + $sharedLibString .= '-l' . $lib . ' '; + } + } + return [trim($staticLibString), trim($sharedLibString)]; + } + private function getLibraryDependencies(bool $recursive = false): array { $ret = array_filter($this->dependencies, fn ($x) => $x instanceof LibraryBase); @@ -407,6 +523,11 @@ private function getLibraryDependencies(bool $recursive = false): array } } + if (array_key_exists(0, $deps)) { + $zero = [0 => $deps[0]]; + unset($deps[0]); + return $zero + $deps; + } return $deps; } } diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 0d8ab739d..6780a6950 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -11,9 +11,12 @@ use SPC\store\Downloader; use SPC\store\FileSystem; use SPC\store\SourceManager; +use SPC\util\GlobalValueTrait; abstract class LibraryBase { + use GlobalValueTrait; + /** @var string */ public const NAME = 'unknown'; @@ -31,7 +34,7 @@ public function __construct(?string $source_dir = null) if (static::NAME === 'unknown') { throw new RuntimeException('no unknown!!!!!'); } - $this->source_dir = $source_dir ?? (SOURCE_PATH . '/' . static::NAME); + $this->source_dir = $source_dir ?? (SOURCE_PATH . '/' . Config::getLib(static::NAME, 'source')); } /** @@ -328,21 +331,6 @@ public function patchBeforeMake(): bool return false; } - public function getIncludeDir(): string - { - return BUILD_INCLUDE_PATH; - } - - public function getBuildRootPath(): string - { - return BUILD_ROOT_PATH; - } - - public function getLibDir(): string - { - return BUILD_LIB_PATH; - } - /** * Build this library. * diff --git a/src/SPC/builder/extension/amqp.php b/src/SPC/builder/extension/amqp.php index 8fbfea248..7e0ea2dec 100644 --- a/src/SPC/builder/extension/amqp.php +++ b/src/SPC/builder/extension/amqp.php @@ -25,10 +25,10 @@ public function patchBeforeMake(): bool public function getUnixConfigureArg(bool $shared = false): string { - return '--with-amqp --with-librabbitmq-dir=' . BUILD_ROOT_PATH; + return '--with-amqp' . ($shared ? '=shared' : '') . ' --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 d4f8b078c..0c5de6a5e 100644 --- a/src/SPC/builder/extension/curl.php +++ b/src/SPC/builder/extension/curl.php @@ -5,6 +5,7 @@ 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; @@ -21,7 +22,7 @@ public function patchBeforeBuildconf(): bool { logger()->info('patching before-configure for curl checks'); $file1 = "AC_DEFUN([PHP_CHECK_LIBRARY], [\n $3\n])"; - $files = FileSystem::readFile(SOURCE_PATH . '/php-src/ext/curl/config.m4'); + $files = FileSystem::readFile($this->source_dir . '/config.m4'); $file2 = 'AC_DEFUN([PHP_CHECK_LIBRARY], [ save_old_LDFLAGS=$LDFLAGS ac_stuff="$5" @@ -40,7 +41,7 @@ public function patchBeforeBuildconf(): bool $4 ])dnl ])'; - file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2); + file_put_contents($this->source_dir . '/config.m4', $file1 . "\n" . $files . "\n" . $file2); return true; } @@ -52,6 +53,72 @@ public function patchBeforeConfigure(): bool { $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 = $this->source_dir . '/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 bd7388f36..abda5651e 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 000000000..85437f623 --- /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 444b5d93a..3ebb5228b 100644 --- a/src/SPC/builder/extension/glfw.php +++ b/src/SPC/builder/extension/glfw.php @@ -35,7 +35,7 @@ public function getUnixConfigureArg(bool $shared = false): string 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/imagick.php b/src/SPC/builder/extension/imagick.php index a4cb93868..d78627ef7 100644 --- a/src/SPC/builder/extension/imagick.php +++ b/src/SPC/builder/extension/imagick.php @@ -12,10 +12,13 @@ class imagick extends Extension { public function patchBeforeMake(): bool { - if (getenv('SPC_LIBC') !== 'musl') { + if (PHP_OS_FAMILY !== 'Linux') { return false; } - // imagick with calls omp_pause_all which requires -lgomp, on non-musl we build imagick without openmp + if (getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10')) { + return false; + } + // imagick with calls omp_pause_all, which requires openmp, on non-musl we build imagick without openmp $extra_libs = trim(getenv('SPC_EXTRA_LIBS') . ' -lgomp'); f_putenv('SPC_EXTRA_LIBS=' . $extra_libs); return true; @@ -23,7 +26,7 @@ public function patchBeforeMake(): bool public function getUnixConfigureArg(bool $shared = false): string { - $disable_omp = getenv('SPC_LIBC') === 'musl' ? '' : ' ac_cv_func_omp_pause_resource_all=no'; - return '--with-imagick=' . BUILD_ROOT_PATH . $disable_omp; + $disable_omp = !(getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10')) ? '' : ' ac_cv_func_omp_pause_resource_all=no'; + return '--with-imagick=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . $disable_omp; } } diff --git a/src/SPC/builder/extension/intl.php b/src/SPC/builder/extension/intl.php index 8130b5d34..5676a4897 100644 --- a/src/SPC/builder/extension/intl.php +++ b/src/SPC/builder/extension/intl.php @@ -18,9 +18,12 @@ public function patchBeforeBuildconf(): bool // Also need to use clang++ -std=c++17 to force override the default C++ standard if (is_string($env = getenv('CXX')) && !str_contains($env, 'std=c++17')) { f_putenv('CXX=' . $env . ' -std=c++17'); - } else { - f_putenv('CXX=clang++ -std=c++17'); } return true; } + + public function patchBeforeSharedBuild(): bool + { + return $this->patchBeforeBuildconf(); + } } diff --git a/src/SPC/builder/extension/lz4.php b/src/SPC/builder/extension/lz4.php index 541b1ecde..5727a97d5 100644 --- a/src/SPC/builder/extension/lz4.php +++ b/src/SPC/builder/extension/lz4.php @@ -15,7 +15,7 @@ public function getUnixConfigureArg(bool $shared = false): string return '--enable-lz4' . ($shared ? '=shared' : '') . ' --with-lz4-includedir=' . BUILD_ROOT_PATH; } - public function getWindowsConfigureArg(): string + public function getWindowsConfigureArg(bool $shared = false): string { return '--enable-lz4'; } diff --git a/src/SPC/builder/extension/mbregex.php b/src/SPC/builder/extension/mbregex.php index 4bf285445..0e1cad28f 100644 --- a/src/SPC/builder/extension/mbregex.php +++ b/src/SPC/builder/extension/mbregex.php @@ -16,7 +16,7 @@ public function getDistName(): string return 'mbstring'; } - public function getConfigureArg(): string + public function getConfigureArg(bool $shared = false): string { return ''; } @@ -26,7 +26,8 @@ public function getConfigureArg(): string */ 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_dir=' . BUILD_MODULES_PATH . '" -d "extension=mbstring"' : ''; + [$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/mbstring.php b/src/SPC/builder/extension/mbstring.php index 5fcb88bdd..3576877f7 100644 --- a/src/SPC/builder/extension/mbstring.php +++ b/src/SPC/builder/extension/mbstring.php @@ -10,9 +10,20 @@ #[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/memcache.php b/src/SPC/builder/extension/memcache.php index 4625cae25..479744fdd 100644 --- a/src/SPC/builder/extension/memcache.php +++ b/src/SPC/builder/extension/memcache.php @@ -14,7 +14,7 @@ class memcache extends Extension { public function getUnixConfigureArg(bool $shared = false): string { - return '--enable-memcache --with-zlib-dir=' . BUILD_ROOT_PATH; + return '--enable-memcache' . ($shared ? '=shared' : '') . ' --with-zlib-dir=' . BUILD_ROOT_PATH; } /** diff --git a/src/SPC/builder/extension/memcached.php b/src/SPC/builder/extension/memcached.php index 9c4339543..a1b88ac68 100644 --- a/src/SPC/builder/extension/memcached.php +++ b/src/SPC/builder/extension/memcached.php @@ -12,8 +12,11 @@ class memcached extends Extension { public function getUnixConfigureArg(bool $shared = false): string { - $rootdir = BUILD_ROOT_PATH; - $zlib_dir = $this->builder->getPHPVersionID() >= 80400 ? '' : "--with-zlib-dir={$rootdir}"; - return "--enable-memcached {$zlib_dir} --with-libmemcached-dir={$rootdir} --disable-memcached-sasl --enable-memcached-json"; + return '--enable-memcached' . ($shared ? '=shared' : '') . ' ' . + '--with-zlib-dir=' . BUILD_ROOT_PATH . ' ' . + '--with-libmemcached-dir=' . BUILD_ROOT_PATH . ' ' . + '--disable-memcached-sasl ' . + '--enable-memcached-json ' . + '--with-system-fastlz'; } } diff --git a/src/SPC/builder/extension/odbc.php b/src/SPC/builder/extension/odbc.php index ac5c3e8f0..278b5865a 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/openssl.php b/src/SPC/builder/extension/openssl.php index add1aedef..fc4831f30 100644 --- a/src/SPC/builder/extension/openssl.php +++ b/src/SPC/builder/extension/openssl.php @@ -26,6 +26,6 @@ public function patchBeforeMake(): bool 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 e436f3819..c47144fe5 100644 --- a/src/SPC/builder/extension/pdo_odbc.php +++ b/src/SPC/builder/extension/pdo_odbc.php @@ -19,10 +19,10 @@ public function patchBeforeBuildconf(): bool 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 e29014cb5..b1ca1a813 100644 --- a/src/SPC/builder/extension/pdo_pgsql.php +++ b/src/SPC/builder/extension/pdo_pgsql.php @@ -10,7 +10,7 @@ #[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/pgsql.php b/src/SPC/builder/extension/pgsql.php index 1c63f1635..a70c1fb72 100644 --- a/src/SPC/builder/extension/pgsql.php +++ b/src/SPC/builder/extension/pgsql.php @@ -36,16 +36,21 @@ public function patchBeforeConfigure(): bool 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"'; + $libfiles = $this->getLibFilesString(); + $libfiles = str_replace(BUILD_LIB_PATH . '/lib', '-l', $libfiles); + $libfiles = str_replace('.a', '', $libfiles); + return '--with-pgsql' . ($shared ? '=shared' : '') . + ' PGSQL_CFLAGS=-I' . BUILD_INCLUDE_PATH . + ' PGSQL_LIBS="-L' . BUILD_LIB_PATH . ' ' . $libfiles . '"'; } - 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 000000000..7396ba837 --- /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 50610325f..cb1792c5f 100644 --- a/src/SPC/builder/extension/rdkafka.php +++ b/src/SPC/builder/extension/rdkafka.php @@ -11,6 +11,13 @@ #[CustomExt('rdkafka')] class rdkafka extends Extension { + public function patchBeforeBuildconf(): bool + { + FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\n", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm \$RDKAFKA_LIBS\n"); + FileSystem::replaceFileStr("{$this->source_dir}/config.m4", "-L\$RDKAFKA_DIR/\$PHP_LIBDIR -lm\"\n", '-L$RDKAFKA_DIR/$PHP_LIBDIR -lm $RDKAFKA_LIBS"'); + return true; + } + public function patchBeforeMake(): bool { // when compiling rdkafka with inline builds, it shows some errors, I don't know why. @@ -27,10 +34,10 @@ public function patchBeforeMake(): bool return true; } - public function getConfigureArg(): string + public function getUnixConfigureArg(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 . '"'; + return '--with-rdkafka=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH . ' RDKAFKA_LIBS="' . $pkgconf_libs . '"'; } } diff --git a/src/SPC/builder/extension/readline.php b/src/SPC/builder/extension/readline.php index c66e7afa6..dc4d15f7c 100644 --- a/src/SPC/builder/extension/readline.php +++ b/src/SPC/builder/extension/readline.php @@ -24,4 +24,18 @@ public function patchBeforeConfigure(): bool ); 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 0b60075c9..75158ad70 100644 --- a/src/SPC/builder/extension/redis.php +++ b/src/SPC/builder/extension/redis.php @@ -24,7 +24,7 @@ public function getUnixConfigureArg(bool $shared = false): string 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/spx.php b/src/SPC/builder/extension/spx.php index dc341e396..f5e736d58 100644 --- a/src/SPC/builder/extension/spx.php +++ b/src/SPC/builder/extension/spx.php @@ -5,28 +5,28 @@ namespace SPC\builder\extension; use SPC\builder\Extension; -use SPC\exception\WrongUsageException; +use SPC\store\FileSystem; use SPC\util\CustomExt; #[CustomExt('spx')] class spx extends Extension { - /** - * @throws WrongUsageException - */ - public function validate(): void - { - if ($this->builder->getOption('enable-zts')) { - throw new WrongUsageException('ext-spx is not thread safe, do not build it with ZTS builds'); - } - } - public function getUnixConfigureArg(bool $shared = false): string { - $arg = '--enable-spx'; - if ($this->builder->getExt('zlib') === null) { + $arg = '--enable-spx' . ($shared ? '=shared' : ''); + if ($this->builder->getLib('zlib') !== null) { $arg .= ' --with-zlib-dir=' . BUILD_ROOT_PATH; } return $arg; } + + public function patchBeforeConfigure(): bool + { + FileSystem::replaceFileStr( + $this->source_dir . '/Makefile.frag', + '@cp -r assets/web-ui/*', + '@cp -r ' . $this->source_dir . '/assets/web-ui/*', + ); + return true; + } } diff --git a/src/SPC/builder/extension/swoole_hook_mysql.php b/src/SPC/builder/extension/swoole_hook_mysql.php index e9684872a..b45516ee8 100644 --- a/src/SPC/builder/extension/swoole_hook_mysql.php +++ b/src/SPC/builder/extension/swoole_hook_mysql.php @@ -29,7 +29,7 @@ public function runCliCheckUnix(): void if ($this->builder->getExt('swoole') === null) { return; } - [$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n --ri "swoole"', false); + [$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n' . $this->getSharedExtensionLoadString() . ' --ri "swoole"', false); $out = implode('', $out); if ($ret !== 0) { throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); diff --git a/src/SPC/builder/extension/swoole_hook_pgsql.php b/src/SPC/builder/extension/swoole_hook_pgsql.php index 113b8eb67..dfbf7dc83 100644 --- a/src/SPC/builder/extension/swoole_hook_pgsql.php +++ b/src/SPC/builder/extension/swoole_hook_pgsql.php @@ -37,7 +37,8 @@ public function runCliCheckUnix(): void if ($this->builder->getExt('swoole') === null) { return; } - [$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n --ri "swoole"', false); + $sharedExtensions = $this->getSharedExtensionLoadString(); + [$ret, $out] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n' . $sharedExtensions . ' --ri "' . $this->getDistName() . '"'); $out = implode('', $out); if ($ret !== 0) { throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); diff --git a/src/SPC/builder/extension/swoole_hook_sqlite.php b/src/SPC/builder/extension/swoole_hook_sqlite.php index 7948dd291..29e9ef84a 100644 --- a/src/SPC/builder/extension/swoole_hook_sqlite.php +++ b/src/SPC/builder/extension/swoole_hook_sqlite.php @@ -37,7 +37,8 @@ public function runCliCheckUnix(): void if ($this->builder->getExt('swoole') === null) { return; } - [$ret, $out] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n --ri "swoole"', false); + $sharedExtensions = $this->getSharedExtensionLoadString(); + [$ret, $out] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n' . $sharedExtensions . ' --ri "' . $this->getDistName() . '"'); $out = implode('', $out); if ($ret !== 0) { throw new RuntimeException('extension ' . $this->getName() . ' failed compile check: php-cli returned ' . $ret); diff --git a/src/SPC/builder/extension/swow.php b/src/SPC/builder/extension/swow.php index 27576635c..390ec27fe 100644 --- a/src/SPC/builder/extension/swow.php +++ b/src/SPC/builder/extension/swow.php @@ -18,7 +18,7 @@ public function validate(): void } } - 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 deleted file mode 100644 index ed5920563..000000000 --- a/src/SPC/builder/extension/xdebug.php +++ /dev/null @@ -1,21 +0,0 @@ -execWithResult(BUILD_BIN_PATH . '/php -n -d "zend_extension=' . BUILD_LIB_PATH . '/xdebug.so" --ri xdebug'); - if ($ret !== 0) { - throw new RuntimeException('xdebug.so failed to load.'); - } - } -} diff --git a/src/SPC/builder/extension/xlswriter.php b/src/SPC/builder/extension/xlswriter.php index 2ceb8e5cd..878168adf 100644 --- a/src/SPC/builder/extension/xlswriter.php +++ b/src/SPC/builder/extension/xlswriter.php @@ -20,7 +20,7 @@ public function getUnixConfigureArg(bool $shared = false): string 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 fc8bfc4d5..bd64d346d 100644 --- a/src/SPC/builder/extension/xml.php +++ b/src/SPC/builder/extension/xml.php @@ -13,7 +13,6 @@ #[CustomExt('soap')] #[CustomExt('xmlreader')] #[CustomExt('xmlwriter')] -#[CustomExt('dom')] #[CustomExt('simplexml')] class xml extends Extension { @@ -27,11 +26,10 @@ public function getUnixConfigureArg(bool $shared = false): string '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 @@ public function patchBeforeBuildconf(): bool 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/extension/yac.php b/src/SPC/builder/extension/yac.php index bb085133e..07589b2eb 100644 --- a/src/SPC/builder/extension/yac.php +++ b/src/SPC/builder/extension/yac.php @@ -21,6 +21,6 @@ public function patchBeforeBuildconf(): bool public function getUnixConfigureArg(bool $shared = false): string { - return '--enable-yac --enable-igbinary --enable-json'; + return '--enable-yac ' . ($shared ? '=shared' : '') . ' --enable-igbinary --enable-json --with-system-fastlz'; } } diff --git a/src/SPC/builder/freebsd/BSDBuilder.php b/src/SPC/builder/freebsd/BSDBuilder.php index 0727e103e..04fd43d30 100644 --- a/src/SPC/builder/freebsd/BSDBuilder.php +++ b/src/SPC/builder/freebsd/BSDBuilder.php @@ -143,7 +143,10 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void } $this->buildEmbed(); } + } + public function testPHP(int $build_target = BUILD_TARGET_NONE) + { if (php_uname('m') === $this->getOption('arch')) { $this->emitPatchPoint('before-sanity-check'); $this->sanityCheck($build_target); diff --git a/src/SPC/builder/freebsd/library/curl.php b/src/SPC/builder/freebsd/library/curl.php index bb5c92656..4eeab20d8 100644 --- a/src/SPC/builder/freebsd/library/curl.php +++ b/src/SPC/builder/freebsd/library/curl.php @@ -10,9 +10,9 @@ class curl extends BSDLibraryBase public const NAME = 'curl'; - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string + public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string { - $libs = parent::getStaticLibFiles($style, $recursive); + $libs = parent::getStaticLibFiles($style, $recursive, $include_self); if ($this->builder->getLib('openssl')) { $this->builder->setOption('extra-libs', $this->builder->getOption('extra-libs') . ' /usr/lib/libpthread.a /usr/lib/libdl.a'); } diff --git a/src/SPC/builder/freebsd/library/openssl.php b/src/SPC/builder/freebsd/library/openssl.php index fb029a77f..1bbabf525 100644 --- a/src/SPC/builder/freebsd/library/openssl.php +++ b/src/SPC/builder/freebsd/library/openssl.php @@ -48,7 +48,7 @@ protected function build(): void $ex_lib = trim($zlib->getStaticLibFiles() . ' ' . $ex_lib); } - shell()->cd($this->source_dir) + shell()->cd($this->source_dir)->initializeEnv($this) ->exec( "./Configure no-shared {$extra} " . '--prefix=/ ' . // use prefix=/ diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index d8ced3b04..007326199 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -175,7 +175,10 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void } $this->buildEmbed(); } + } + public function testPHP(int $build_target = BUILD_TARGET_NONE) + { $this->emitPatchPoint('before-sanity-check'); $this->sanityCheck($build_target); } @@ -189,9 +192,10 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void protected function buildCli(): void { $vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); + $SPC_CMD_PREFIX_PHP_MAKE = getenv('SPC_CMD_PREFIX_PHP_MAKE') ?: 'make'; shell()->cd(SOURCE_PATH . '/php-src') ->exec('sed -i "s|//lib|/lib|g" Makefile') - ->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} cli"); + ->exec("{$SPC_CMD_PREFIX_PHP_MAKE} {$vars} cli"); if ($this->getOption('with-upx-pack')) { shell()->cd(SOURCE_PATH . '/php-src/sapi/cli') @@ -227,10 +231,11 @@ protected function buildMicro(): void // patch fake cli for micro $vars['EXTRA_CFLAGS'] .= $enable_fake_cli; $vars = SystemUtil::makeEnvVarString($vars); + $SPC_CMD_PREFIX_PHP_MAKE = getenv('SPC_CMD_PREFIX_PHP_MAKE') ?: 'make'; shell()->cd(SOURCE_PATH . '/php-src') ->exec('sed -i "s|//lib|/lib|g" Makefile') - ->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} micro"); + ->exec("{$SPC_CMD_PREFIX_PHP_MAKE} {$vars} micro"); $this->processMicroUPX(); @@ -250,9 +255,10 @@ protected function buildMicro(): void protected function buildFpm(): void { $vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); + $SPC_CMD_PREFIX_PHP_MAKE = getenv('SPC_CMD_PREFIX_PHP_MAKE') ?: 'make'; shell()->cd(SOURCE_PATH . '/php-src') ->exec('sed -i "s|//lib|/lib|g" Makefile') - ->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} fpm"); + ->exec("{$SPC_CMD_PREFIX_PHP_MAKE} {$vars} fpm"); if ($this->getOption('with-upx-pack')) { shell()->cd(SOURCE_PATH . '/php-src/sapi/fpm') @@ -275,7 +281,20 @@ protected function buildEmbed(): void 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"); + + $ldflags = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'); + if (preg_match('/-release\s+(\S+)/', $ldflags, $matches)) { + $release = $matches[1]; + $realLibName = 'libphp-' . $release . '.so'; + $realLib = BUILD_LIB_PATH . '/' . $realLibName; + rename(BUILD_LIB_PATH . '/libphp.so', $realLib); + $cwd = getcwd(); + chdir(BUILD_LIB_PATH); + symlink($realLibName, 'libphp.so'); + chdir($cwd); + } $this->patchPhpScripts(); } @@ -284,6 +303,7 @@ private function getMakeExtraVars(): array return [ 'EXTRA_CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'), 'EXTRA_LIBS' => getenv('SPC_EXTRA_LIBS') . ' ' . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'), + 'EXTRA_LDFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), 'EXTRA_LDFLAGS_PROGRAM' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM'), ]; } diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index e49830d25..a85f3dec6 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -11,6 +11,8 @@ class SystemUtil { use UnixSystemUtilTrait; + public static ?string $libc_version = null; + /** @noinspection PhpMissingBreakStatementInspection */ public static function getOSRelease(): array { @@ -188,6 +190,9 @@ public static function getSupportedDistros(): array */ public static function getLibcVersionIfExists(): ?string { + if (self::$libc_version !== null) { + return self::$libc_version; + } if (PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'glibc') { $result = shell()->execWithResult('ldd --version', false); if ($result[0] !== 0) { @@ -198,7 +203,8 @@ public static function getLibcVersionIfExists(): ?string // match ldd version: "ldd (some useless text) 2.17" match 2.17 $pattern = '/ldd\s+\(.*?\)\s+(\d+\.\d+)/'; if (preg_match($pattern, $first_line, $matches)) { - return $matches[1]; + self::$libc_version = $matches[1]; + return self::$libc_version; } return null; } @@ -212,7 +218,8 @@ public static function getLibcVersionIfExists(): ?string // match ldd version: "Version 1.2.3" match 1.2.3 $pattern = '/Version\s+(\d+\.\d+\.\d+)/'; if (preg_match($pattern, $result[1][1] ?? '', $matches)) { - return $matches[1]; + self::$libc_version = $matches[1]; + return self::$libc_version; } } return null; diff --git a/src/SPC/builder/linux/library/curl.php b/src/SPC/builder/linux/library/curl.php index d45492c48..f382773ff 100644 --- a/src/SPC/builder/linux/library/curl.php +++ b/src/SPC/builder/linux/library/curl.php @@ -10,9 +10,9 @@ class curl extends LinuxLibraryBase public const NAME = 'curl'; - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string + public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string { - $libs = parent::getStaticLibFiles($style, $recursive); + $libs = parent::getStaticLibFiles($style, $recursive, $include_self); if ($this->builder->getLib('openssl')) { $libs .= ' -ldl -lpthread'; } diff --git a/src/SPC/builder/linux/library/fastlz.php b/src/SPC/builder/linux/library/fastlz.php new file mode 100644 index 000000000..07bee9bb2 --- /dev/null +++ b/src/SPC/builder/linux/library/fastlz.php @@ -0,0 +1,12 @@ +cd($this->source_dir . '/source') + shell()->cd($this->source_dir . '/source')->initializeEnv($this) ->exec( "{$cppflags} {$cxxflags} {$ldflags} " . './runConfigureICU Linux ' . diff --git a/src/SPC/builder/linux/library/libffi.php b/src/SPC/builder/linux/library/libffi.php index e64581bc1..ecb3e1422 100644 --- a/src/SPC/builder/linux/library/libffi.php +++ b/src/SPC/builder/linux/library/libffi.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; class libffi extends LinuxLibraryBase { @@ -17,23 +18,14 @@ class libffi extends LinuxLibraryBase */ public function build(): void { - [$lib, , $destdir] = SEPARATED_PATH; $arch = getenv('SPC_ARCH'); - - shell()->cd($this->source_dir) - ->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - "--host={$arch}-unknown-linux " . - "--target={$arch}-unknown-linux " . - '--prefix= ' . - "--libdir={$lib}" + UnixAutoconfExecutor::create($this) + ->configure( + "--host={$arch}-unknown-linux", + "--target={$arch}-unknown-linux", + "--libdir={$this->getLibDir()}" ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec("make install DESTDIR={$destdir}"); + ->make(); if (is_file(BUILD_ROOT_PATH . '/lib64/libffi.a')) { copy(BUILD_ROOT_PATH . '/lib64/libffi.a', BUILD_ROOT_PATH . '/lib/libffi.a'); diff --git a/src/SPC/builder/linux/library/libmemcached.php b/src/SPC/builder/linux/library/libmemcached.php index ab393d2e2..fb09b52ab 100644 --- a/src/SPC/builder/linux/library/libmemcached.php +++ b/src/SPC/builder/linux/library/libmemcached.php @@ -4,17 +4,14 @@ namespace SPC\builder\linux\library; -use SPC\exception\RuntimeException; +use SPC\util\executor\UnixCMakeExecutor; -/** - * gmp is a template library class for unix - */ class libmemcached extends LinuxLibraryBase { public const NAME = 'libmemcached'; - public function build() + public function build(): void { - throw new RuntimeException('libmemcached is currently not supported on Linux platform'); + UnixCMakeExecutor::create($this)->build(); } } diff --git a/src/SPC/builder/linux/library/libpng.php b/src/SPC/builder/linux/library/libpng.php index 8c33ef0fc..c25dd654d 100644 --- a/src/SPC/builder/linux/library/libpng.php +++ b/src/SPC/builder/linux/library/libpng.php @@ -24,6 +24,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\util\executor\UnixAutoconfExecutor; class libpng extends LinuxLibraryBase { @@ -36,28 +37,22 @@ class libpng extends LinuxLibraryBase */ public function build(): void { - $optimizations = match (getenv('SPC_ARCH')) { - 'x86_64' => '--enable-intel-sse ', - 'aarch64' => '--enable-arm-neon ', - default => '', - }; - shell()->cd($this->source_dir)->initializeEnv($this) + UnixAutoconfExecutor::create($this) ->exec('chmod +x ./configure') ->exec('chmod +x ./install-sh') - ->exec( - 'LDFLAGS="-L' . BUILD_LIB_PATH . '" ' . - './configure ' . - '--disable-shared ' . - '--enable-static ' . - '--enable-hardware-optimizations ' . - '--with-zlib-prefix="' . BUILD_ROOT_PATH . '" ' . - $optimizations . - '--prefix=' + ->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"]) + ->configure( + '--enable-hardware-optimizations', + "--with-zlib-prefix={$this->getBuildRootPath()}", + match (getenv('SPC_ARCH')) { + 'x86_64' => '--enable-intel-sse', + 'aarch64' => '--enable-arm-neon', + default => '', + } ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I{$this->source_dir} -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la") - ->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH); + ->make('libpng16.la', 'install-libLTLIBRARIES install-data-am', after_env_vars: ['DEFAULT_INCLUDES' => "-I{$this->source_dir} -I{$this->getIncludeDir()}"]); + $this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX); - $this->cleanLaFiles(); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index 11c60067e..252eb47fb 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -92,9 +92,9 @@ public function build(): void FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/cmake/OpenSSL/OpenSSLConfig.cmake', '/set\(OPENSSL_LIBCRYPTO_DEPENDENCIES .*\)/m', 'set(OPENSSL_LIBCRYPTO_DEPENDENCIES "${OPENSSL_LIBRARY_DIR}/libz.a")'); } - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string + public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string { - $libFiles = parent::getStaticLibFiles($style, $recursive); + $libFiles = parent::getStaticLibFiles($style, $recursive, $include_self); if (!str_contains('-ldl -lpthread', $libFiles)) { $libFiles .= ' -ldl -lpthread'; } diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index e218407c8..c71dabceb 100644 --- a/src/SPC/builder/macos/MacOSBuilder.php +++ b/src/SPC/builder/macos/MacOSBuilder.php @@ -67,6 +67,10 @@ public function getFrameworks(bool $asString = false): array|string array_push($frameworks, ...$lib->getFrameworks()); } + foreach ($this->exts as $ext) { + array_push($frameworks, ...$ext->getFrameworks()); + } + if ($asString) { return implode(' ', array_map(fn ($x) => "-framework {$x}", $frameworks)); } @@ -181,6 +185,12 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void $this->sanityCheck($build_target); } + public function testPHP(int $build_target = BUILD_TARGET_NONE) + { + $this->emitPatchPoint('before-sanity-check'); + $this->sanityCheck($build_target); + } + /** * Build cli sapi * @@ -192,7 +202,8 @@ protected function buildCli(): void $vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); $shell = shell()->cd(SOURCE_PATH . '/php-src'); - $shell->exec("\$SPC_CMD_PREFIX_PHP_MAKE {$vars} cli"); + $SPC_CMD_PREFIX_PHP_MAKE = getenv('SPC_CMD_PREFIX_PHP_MAKE') ?: 'make'; + $shell->exec("{$SPC_CMD_PREFIX_PHP_MAKE} {$vars} cli"); if (!$this->getOption('no-strip', false)) { $shell->exec('dsymutil -f sapi/cli/php')->exec('strip sapi/cli/php'); } @@ -263,15 +274,12 @@ protected function buildEmbed(): void $vars = SystemUtil::makeEnvVarString($this->getMakeExtraVars()); shell()->cd(SOURCE_PATH . '/php-src') - ->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install") - // Workaround for https://github.com/php/php-src/issues/12082 - ->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o') - ->exec('mkdir ' . BUILD_ROOT_PATH . '/lib/php-o') - ->cd(BUILD_ROOT_PATH . '/lib/php-o') - ->exec('ar x ' . BUILD_ROOT_PATH . '/lib/libphp.a') - ->exec('rm ' . BUILD_ROOT_PATH . '/lib/libphp.a') - ->exec('ar rcs ' . BUILD_ROOT_PATH . '/lib/libphp.a *.o') - ->exec('rm -Rf ' . BUILD_ROOT_PATH . '/lib/php-o'); + ->exec(getenv('SPC_CMD_PREFIX_PHP_MAKE') . ' INSTALL_ROOT=' . BUILD_ROOT_PATH . " {$vars} install"); + + if (getenv('SPC_CMD_VAR_PHP_EMBED_TYPE') === 'static') { + shell()->cd(SOURCE_PATH . '/php-src') + ->exec('ar -t ' . BUILD_LIB_PATH . "/libphp.a | grep '\\.a$' | xargs -n1 ar d " . BUILD_LIB_PATH . '/libphp.a'); + } $this->patchPhpScripts(); } diff --git a/src/SPC/builder/macos/library/fastlz.php b/src/SPC/builder/macos/library/fastlz.php new file mode 100644 index 000000000..db0f517a4 --- /dev/null +++ b/src/SPC/builder/macos/library/fastlz.php @@ -0,0 +1,12 @@ +cd($this->source_dir) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - "--host={$arch}-apple-darwin " . - "--target={$arch}-apple-darwin " . - '--prefix= ' // use prefix=/ + UnixAutoconfExecutor::create($this) + ->configure( + "--host={$arch}-apple-darwin", + "--target={$arch}-apple-darwin", ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec("make install DESTDIR={$destdir}"); + ->make(); $this->patchPkgconfPrefix(['libffi.pc']); } } diff --git a/src/SPC/builder/macos/library/libheif.php b/src/SPC/builder/macos/library/libheif.php index e785809d5..af99740b7 100644 --- a/src/SPC/builder/macos/library/libheif.php +++ b/src/SPC/builder/macos/library/libheif.php @@ -4,24 +4,9 @@ namespace SPC\builder\macos\library; -use SPC\store\FileSystem; - class libheif extends MacOSLibraryBase { use \SPC\builder\unix\library\libheif; public const NAME = 'libheif'; - - public function patchBeforeBuild(): bool - { - if (!str_contains(file_get_contents($this->source_dir . '/CMakeLists.txt'), 'libbrotlienc')) { - FileSystem::replaceFileStr( - $this->source_dir . '/CMakeLists.txt', - 'list(APPEND REQUIRES_PRIVATE "libbrotlidec")', - 'list(APPEND REQUIRES_PRIVATE "libbrotlidec")' . "\n" . ' list(APPEND REQUIRES_PRIVATE "libbrotlienc")' - ); - return true; - } - return false; - } } diff --git a/src/SPC/builder/macos/library/libmemcached.php b/src/SPC/builder/macos/library/libmemcached.php index 09a600a23..b212b4877 100644 --- a/src/SPC/builder/macos/library/libmemcached.php +++ b/src/SPC/builder/macos/library/libmemcached.php @@ -4,28 +4,14 @@ namespace SPC\builder\macos\library; -/** - * gmp is a template library class for unix - */ +use SPC\util\executor\UnixCMakeExecutor; + class libmemcached extends MacOSLibraryBase { public const NAME = 'libmemcached'; public function build(): void { - $rootdir = BUILD_ROOT_PATH; - - shell()->cd($this->source_dir) - ->exec('chmod +x configure') - ->exec( - './configure ' . - '--enable-static --disable-shared ' . - '--disable-sasl ' . - "--prefix={$rootdir}" - ) - ->exec('make clean') - ->exec('sed -ie "s/-Werror//g" ' . $this->source_dir . '/Makefile') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this)->build(); } } diff --git a/src/SPC/builder/macos/library/libpng.php b/src/SPC/builder/macos/library/libpng.php index b61cc8988..0fec806ee 100644 --- a/src/SPC/builder/macos/library/libpng.php +++ b/src/SPC/builder/macos/library/libpng.php @@ -24,6 +24,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\util\executor\UnixAutoconfExecutor; class libpng extends MacOSLibraryBase { @@ -36,29 +37,25 @@ class libpng extends MacOSLibraryBase */ protected function build(): void { - $optimizations = match (php_uname('m')) { - 'x86_64' => '--enable-intel-sse ', - 'arm64' => '--enable-arm-neon ', - default => '', - }; - shell()->cd($this->source_dir) + $arch = arch2gnu(php_uname('m')); + UnixAutoconfExecutor::create($this) ->exec('chmod +x ./configure') ->exec('chmod +x ./install-sh') - ->exec( - './configure ' . - '--host=' . arch2gnu(php_uname('m')) . '-apple-darwin ' . - '--disable-shared ' . - '--enable-static ' . - '--enable-hardware-optimizations ' . - $optimizations . - '--prefix=' + ->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"]) + ->configure( + "--host={$arch}-apple-darwin", + '--enable-hardware-optimizations', + "--with-zlib-prefix={$this->getBuildRootPath()}", + match (getenv('SPC_ARCH')) { + 'x86_64' => '--enable-intel-sse', + 'aarch64' => '--enable-arm-neon', + default => '', + } ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I. -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la") - ->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH) - ->cd(BUILD_LIB_PATH) - ->exec('ln -sf libpng16.a libpng.a'); + ->make('libpng16.la', 'install-libLTLIBRARIES install-data-am', after_env_vars: ['DEFAULT_INCLUDES' => "-I{$this->source_dir} -I{$this->getIncludeDir()}"]); + + shell()->cd(BUILD_LIB_PATH)->exec('ln -sf libpng16.a libpng.a'); $this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX); - $this->cleanLaFiles(); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index f302bbfad..e98a6f3a8 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -17,9 +17,9 @@ trait UnixLibraryTrait * @throws FileSystemException * @throws WrongUsageException */ - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string + public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string { - $libs = [$this]; + $libs = $include_self ? [$this] : []; if ($recursive) { array_unshift($libs, ...array_values($this->getDependencies(recursive: true))); } @@ -84,19 +84,34 @@ public function patchPkgconfPrefix(array $files, int $patch_option = PKGCONF_PAT } } - /** - * remove libtool archive files - * - * @throws FileSystemException - * @throws WrongUsageException - */ - public function cleanLaFiles(): void + public function patchLaDependencyPrefix(?array $files = null): void { - foreach ($this->getStaticLibs() as $lib) { - $filename = pathinfo($lib, PATHINFO_FILENAME) . '.la'; - if (file_exists(BUILD_LIB_PATH . '/' . $filename)) { - unlink(BUILD_LIB_PATH . '/' . $filename); + logger()->info('Patching library [' . static::NAME . '] la files'); + $throwOnMissing = true; + if ($files === null) { + $files = $this->getStaticLibs(); + $files = array_map(fn ($name) => str_replace('.a', '.la', $name), $files); + $throwOnMissing = false; + } + foreach ($files as $name) { + $realpath = realpath(BUILD_LIB_PATH . '/' . $name); + if ($realpath === false) { + if ($throwOnMissing) { + throw new RuntimeException('Cannot find library [' . static::NAME . '] la file [' . $name . '] !'); + } + logger()->warning('Cannot find library [' . static::NAME . '] la file [' . $name . '] !'); + continue; } + 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); } } diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index e44b44763..0d367de19 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -153,13 +153,13 @@ protected function sanityCheck(int $build_target): void // sanity check for php-cli if (($build_target & BUILD_TARGET_CLI) === BUILD_TARGET_CLI) { logger()->info('running cli sanity check'); - [$ret, $output] = shell()->execWithResult(BUILD_ROOT_PATH . '/bin/php -n -r "echo \"hello\";"'); + [$ret, $output] = shell()->execWithResult(BUILD_BIN_PATH . '/php -n -r "echo \"hello\";"'); $raw_output = implode('', $output); if ($ret !== 0 || trim($raw_output) !== 'hello') { 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(); } @@ -236,8 +236,8 @@ protected function deployBinary(int $type): bool 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; } @@ -263,6 +263,7 @@ protected function patchPhpScripts(): void 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/attr.php b/src/SPC/builder/unix/library/attr.php index b62547201..439acf38e 100644 --- a/src/SPC/builder/unix/library/attr.php +++ b/src/SPC/builder/unix/library/attr.php @@ -5,6 +5,7 @@ namespace SPC\builder\unix\library; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait attr { @@ -13,14 +14,11 @@ trait attr */ protected function build(): void { - shell()->cd($this->source_dir)->initializeEnv($this) - ->appendEnv(['CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}"]) + UnixAutoconfExecutor::create($this) ->exec('libtoolize --force --copy') ->exec('./autogen.sh || autoreconf -if') - ->exec('./configure --prefix= --enable-static --disable-shared --with-pic --disable-nls') - ->exec("make -j {$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); - + ->configure('--disable-nls') + ->make(); $this->patchPkgconfPrefix(['libattr.pc'], PKGCONF_PATCH_PREFIX); } } diff --git a/src/SPC/builder/unix/library/brotli.php b/src/SPC/builder/unix/library/brotli.php index 34a100860..6de9c15c0 100644 --- a/src/SPC/builder/unix/library/brotli.php +++ b/src/SPC/builder/unix/library/brotli.php @@ -23,6 +23,8 @@ protected function build(): void ->build(); $this->patchPkgconfPrefix(['libbrotlicommon.pc', 'libbrotlidec.pc', 'libbrotlienc.pc']); + FileSystem::replaceFileLineContainsString(BUILD_LIB_PATH . '/pkgconfig/libbrotlidec.pc', 'Libs: -L${libdir} -lbrotlidec', 'Libs: -L${libdir} -lbrotlidec -lbrotlicommon'); + FileSystem::replaceFileLineContainsString(BUILD_LIB_PATH . '/pkgconfig/libbrotlienc.pc', 'Libs: -L${libdir} -lbrotlienc', 'Libs: -L${libdir} -lbrotlienc -lbrotlicommon'); shell()->cd(BUILD_ROOT_PATH . '/lib')->exec('ln -sf libbrotlicommon.a libbrotli.a'); foreach (FileSystem::scanDirFiles(BUILD_ROOT_PATH . '/lib/', false, true) as $filename) { if (str_starts_with($filename, 'libbrotli') && (str_contains($filename, '.so') || str_ends_with($filename, '.dylib'))) { diff --git a/src/SPC/builder/unix/library/fastlz.php b/src/SPC/builder/unix/library/fastlz.php new file mode 100644 index 000000000..db0b7f793 --- /dev/null +++ b/src/SPC/builder/unix/library/fastlz.php @@ -0,0 +1,22 @@ +cd($this->source_dir)->initializeEnv($this) + ->exec((getenv('CC') ?: 'cc') . ' -c -O3 -fPIC fastlz.c -o fastlz.o') + ->exec((getenv('AR') ?: 'ar') . ' rcs libfastlz.a fastlz.o'); + + if (!copy($this->source_dir . '/fastlz.h', BUILD_INCLUDE_PATH . '/fastlz.h')) { + throw new \RuntimeException('Failed to copy fastlz.h'); + } + if (!copy($this->source_dir . '/libfastlz.a', BUILD_LIB_PATH . '/libfastlz.a')) { + throw new \RuntimeException('Failed to copy libfastlz.a'); + } + } +} diff --git a/src/SPC/builder/unix/library/freetype.php b/src/SPC/builder/unix/library/freetype.php index 35e626020..581a5e754 100644 --- a/src/SPC/builder/unix/library/freetype.php +++ b/src/SPC/builder/unix/library/freetype.php @@ -38,7 +38,5 @@ protected function build(): void ' -L/lib ', ' -L' . BUILD_ROOT_PATH . '/lib ' ); - - $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/unix/library/gettext.php b/src/SPC/builder/unix/library/gettext.php index 75f50d1bd..257fa3051 100644 --- a/src/SPC/builder/unix/library/gettext.php +++ b/src/SPC/builder/unix/library/gettext.php @@ -4,34 +4,34 @@ namespace SPC\builder\unix\library; +use SPC\util\executor\UnixAutoconfExecutor; + trait gettext { protected function build(): void { - $extra = $this->builder->getLib('ncurses') ? ('--with-libncurses-prefix=' . BUILD_ROOT_PATH . ' ') : ''; - $extra .= $this->builder->getLib('libxml2') ? ('--with-libxml2-prefix=' . BUILD_ROOT_PATH . ' ') : ''; - - $zts = $this->builder->getOption('enable-zts') ? '--enable-threads=isoc+posix ' : '--disable-threads '; + $autoconf = UnixAutoconfExecutor::create($this) + ->optionalLib('ncurses', "--with-libncurses-prefix={$this->getBuildRootPath()}") + ->optionalLib('libxml2', "--with-libxml2-prefix={$this->getBuildRootPath()}") + ->addConfigureArgs( + '--disable-java', + '--disable-c++', + '--with-included-gettext', + "--with-iconv-prefix={$this->getBuildRootPath()}", + ); - $cflags = $this->builder->getOption('enable-zts') ? '-lpthread -D_REENTRANT' : ''; - $ldflags = $this->builder->getOption('enable-zts') ? '-lpthread' : ''; + // zts + if ($this->builder->getOption('enable-zts')) { + $autoconf->addConfigureArgs('--enable-threads=isoc+posix') + ->appendEnv([ + 'CFLAGS' => '-lpthread -D_REENTRANT', + 'LDFLGAS' => '-lpthread', + ]); + } else { + $autoconf->addConfigureArgs('--disable-threads'); + } - shell()->cd($this->source_dir)->initializeEnv($this) - ->appendEnv(['CFLAGS' => $cflags, 'LDFLAGS' => $ldflags]) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - '--disable-java ' . - '--disable-c++ ' . - $zts . - $extra . - '--with-included-gettext ' . - '--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' . - '--prefix=' . BUILD_ROOT_PATH - ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install'); + $autoconf->configure()->make(with_clean: true); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/gmp.php b/src/SPC/builder/unix/library/gmp.php index 2f4ba1a47..a8e4d15c6 100644 --- a/src/SPC/builder/unix/library/gmp.php +++ b/src/SPC/builder/unix/library/gmp.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait gmp { @@ -15,15 +16,7 @@ trait gmp */ protected function build(): void { - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static --disable-shared ' . - '--prefix=' - ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + UnixAutoconfExecutor::create($this)->configure()->make(); $this->patchPkgconfPrefix(['gmp.pc']); } } diff --git a/src/SPC/builder/unix/library/imagemagick.php b/src/SPC/builder/unix/library/imagemagick.php index 5ace2296b..ead786a22 100644 --- a/src/SPC/builder/unix/library/imagemagick.php +++ b/src/SPC/builder/unix/library/imagemagick.php @@ -9,6 +9,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixAutoconfExecutor; trait imagemagick { @@ -18,45 +19,39 @@ trait imagemagick */ protected function build(): void { - // TODO: glibc rh 10 toolset's libgomp.a was built without -fPIC -fPIE so we can't use openmp without depending on libgomp.so - $openmp = getenv('SPC_LIBC') === 'musl' ? '--enable-openmp' : '--disable-openmp'; - $extra = "--without-jxl --without-x {$openmp} "; - $required_libs = ''; - $optional_libs = [ - 'libzip' => 'zip', - 'libjpeg' => 'jpeg', - 'libpng' => 'png', - 'libwebp' => 'webp', - 'libxml2' => 'xml', - 'libheif' => 'heic', - 'zlib' => 'zlib', - 'xz' => 'lzma', - 'zstd' => 'zstd', - 'freetype' => 'freetype', - 'bzip2' => 'bzlib', - ]; - foreach ($optional_libs as $lib => $option) { - $extra .= $this->builder->getLib($lib) ? "--with-{$option} " : "--without-{$option} "; - if ($this->builder->getLib($lib) instanceof LinuxLibraryBase) { - $required_libs .= ' ' . $this->builder->getLib($lib)->getStaticLibFiles(); - } - } + $ac = UnixAutoconfExecutor::create($this) + ->optionalLib('libzip', ...ac_with_args('zip')) + ->optionalLib('libjpeg', ...ac_with_args('jpeg')) + ->optionalLib('libpng', ...ac_with_args('png')) + ->optionalLib('libwebp', ...ac_with_args('webp')) + ->optionalLib('libxml2', ...ac_with_args('xml')) + ->optionalLib('libheif', ...ac_with_args('heic')) + ->optionalLib('zlib', ...ac_with_args('zlib')) + ->optionalLib('xz', ...ac_with_args('lzma')) + ->optionalLib('zstd', ...ac_with_args('zstd')) + ->optionalLib('freetype', ...ac_with_args('freetype')) + ->optionalLib('bzip2', ...ac_with_args('bzlib')) + ->addConfigureArgs( + // TODO: glibc rh 10 toolset's libgomp.a was built without -fPIC so we can't use openmp without depending on libgomp.so + getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10') ? '--disable-openmp' : '--enable-openmp', + '--without-jxl', + '--without-x', + ); + // special: linux musl needs `-static` $ldflags = ($this instanceof LinuxLibraryBase) && getenv('SPC_LIBC') !== 'glibc' ? ('-static -ldl') : '-ldl'; - // libxml iconv patch - $required_libs .= $this instanceof MacOSLibraryBase ? ('-liconv') : ''; - shell()->cd($this->source_dir)->initializeEnv($this) - ->appendEnv(['LDFLAGS' => $ldflags, 'LIBS' => $required_libs, 'PKG_CONFIG' => '$PKG_CONFIG --static']) - ->exec( - './configure ' . - '--enable-static --disable-shared ' . - $extra . - '--prefix=' - ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + // special: macOS needs -iconv + $libs = $this instanceof MacOSLibraryBase ? '-liconv' : ''; + + $ac->appendEnv([ + 'LDFLAGS' => $ldflags, + 'LIBS' => $libs, + 'PKG_CONFIG' => '$PKG_CONFIG --static', + ]); + + $ac->configure()->make(); + $filelist = [ 'ImageMagick.pc', 'ImageMagick-7.Q16HDRI.pc', @@ -75,5 +70,6 @@ protected function build(): void 'includearchdir=${prefix}/include/ImageMagick-7' ); } + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/ldap.php b/src/SPC/builder/unix/library/ldap.php index bad3a65ba..62f7bcd75 100644 --- a/src/SPC/builder/unix/library/ldap.php +++ b/src/SPC/builder/unix/library/ldap.php @@ -5,6 +5,7 @@ namespace SPC\builder\unix\library; use SPC\store\FileSystem; +use SPC\util\executor\UnixAutoconfExecutor; trait ldap { @@ -17,33 +18,25 @@ public function patchBeforeBuild(): bool protected function build(): void { - $alt = ''; - // openssl support - $alt .= $this->builder->getLib('openssl') ? '--with-tls=openssl ' : ''; - // gmp support - $alt .= $this->builder->getLib('gmp') ? '--with-mp=gmp ' : ''; - // libsodium support - $alt .= $this->builder->getLib('libsodium') ? '--with-argon2=libsodium ' : '--enable-argon2=no '; - f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config'); - f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig'); - shell()->cd($this->source_dir)->initializeEnv($this) - ->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"]) - ->exec( - $this->builder->makeAutoconfFlags(AUTOCONF_CPPFLAGS) . - ' ./configure ' . - '--enable-static ' . - '--disable-shared ' . - '--disable-slapd ' . - '--without-systemd ' . - '--without-cyrus-sasl ' . - $alt . - '--prefix=' + UnixAutoconfExecutor::create($this) + ->optionalLib('openssl', '--with-tls=openssl') + ->optionalLib('gmp', '--with-mp=gmp') + ->optionalLib('libsodium', '--with-argon2=libsodium', '--enable-argon2=no') + ->addConfigureArgs( + '--disable-slapd', + '--without-systemd', + '--without-cyrus-sasl', ) - ->exec('make clean') - // remove tests and doc to prevent compile failed with error: soelim not found + ->appendEnv([ + 'LDFLAGS' => "-L{$this->getLibDir()}", + 'CPPFLAGS' => "-I{$this->getIncludeDir()}", + ]) + ->configure() ->exec('sed -i -e "s/SUBDIRS= include libraries clients servers tests doc/SUBDIRS= include libraries clients servers/g" Makefile') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + ->make(); + + FileSystem::replaceFileLineContainsString(BUILD_LIB_PATH . '/pkgconfig/ldap.pc', 'Libs: -L${libdir} -lldap', 'Libs: -L${libdir} -lldap -llber'); $this->patchPkgconfPrefix(['ldap.pc', 'lber.pc']); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/libacl.php b/src/SPC/builder/unix/library/libacl.php index 8f61be1b1..c25e73363 100644 --- a/src/SPC/builder/unix/library/libacl.php +++ b/src/SPC/builder/unix/library/libacl.php @@ -7,6 +7,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixAutoconfExecutor; trait libacl { @@ -29,14 +30,11 @@ public function patchBeforeMake(): bool */ protected function build(): void { - shell()->cd($this->source_dir)->initializeEnv($this) - ->appendEnv(['CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}"]) + UnixAutoconfExecutor::create($this) ->exec('libtoolize --force --copy') ->exec('./autogen.sh || autoreconf -if') - ->exec('./configure --prefix= --enable-static --disable-shared --disable-tests --disable-nls') - ->exec("make -j {$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); - + ->configure('--disable-nls', '--disable-tests') + ->make(); $this->patchPkgconfPrefix(['libacl.pc'], PKGCONF_PATCH_PREFIX); } } diff --git a/src/SPC/builder/unix/library/libavif.php b/src/SPC/builder/unix/library/libavif.php index cbec640bb..dea45c6ea 100644 --- a/src/SPC/builder/unix/library/libavif.php +++ b/src/SPC/builder/unix/library/libavif.php @@ -23,6 +23,5 @@ protected function build(): void ->build(); // patch pkgconfig $this->patchPkgconfPrefix(['libavif.pc']); - $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/unix/library/libcares.php b/src/SPC/builder/unix/library/libcares.php index 61683bbfd..59d9852e3 100644 --- a/src/SPC/builder/unix/library/libcares.php +++ b/src/SPC/builder/unix/library/libcares.php @@ -6,6 +6,7 @@ use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixAutoconfExecutor; trait libcares { @@ -24,11 +25,7 @@ public function patchBeforeBuild(): bool */ protected function build(): void { - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec('./configure --prefix= --enable-static --disable-shared --disable-tests --with-pic') - ->exec("make -j {$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); - + UnixAutoconfExecutor::create($this)->configure('--disable-tests')->make(); $this->patchPkgconfPrefix(['libcares.pc'], PKGCONF_PATCH_PREFIX); } } diff --git a/src/SPC/builder/unix/library/libevent.php b/src/SPC/builder/unix/library/libevent.php index da7269358..55889d1dc 100644 --- a/src/SPC/builder/unix/library/libevent.php +++ b/src/SPC/builder/unix/library/libevent.php @@ -40,15 +40,19 @@ public function beforePack(): void */ protected function build(): void { - UnixCMakeExecutor::create($this) + $cmake = UnixCMakeExecutor::create($this) ->addConfigureArgs( '-DEVENT__LIBRARY_TYPE=STATIC', '-DEVENT__DISABLE_BENCHMARK=ON', '-DEVENT__DISABLE_THREAD_SUPPORT=ON', '-DEVENT__DISABLE_TESTS=ON', '-DEVENT__DISABLE_SAMPLES=ON', - ) - ->build(); + '-DEVENT__DISABLE_MBEDTLS=ON ', + ); + if (version_compare(get_cmake_version(), '4.0.0', '>=')) { + $cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.10'); + } + $cmake->build(); $this->patchPkgconfPrefix(['libevent.pc', 'libevent_core.pc', 'libevent_extra.pc', 'libevent_openssl.pc']); diff --git a/src/SPC/builder/unix/library/libheif.php b/src/SPC/builder/unix/library/libheif.php index 131a330d7..680f33213 100644 --- a/src/SPC/builder/unix/library/libheif.php +++ b/src/SPC/builder/unix/library/libheif.php @@ -6,10 +6,24 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\store\FileSystem; use SPC\util\executor\UnixCMakeExecutor; trait libheif { + public function patchBeforeBuild(): bool + { + if (!str_contains(file_get_contents($this->source_dir . '/CMakeLists.txt'), 'libbrotlienc')) { + FileSystem::replaceFileStr( + $this->source_dir . '/CMakeLists.txt', + 'list(APPEND REQUIRES_PRIVATE "libbrotlidec")', + 'list(APPEND REQUIRES_PRIVATE "libbrotlidec")' . "\n" . ' list(APPEND REQUIRES_PRIVATE "libbrotlienc")' + ); + return true; + } + return false; + } + /** * @throws RuntimeException * @throws FileSystemException diff --git a/src/SPC/builder/unix/library/libiconv.php b/src/SPC/builder/unix/library/libiconv.php index 89c8e5bfc..fd68e309d 100644 --- a/src/SPC/builder/unix/library/libiconv.php +++ b/src/SPC/builder/unix/library/libiconv.php @@ -4,26 +4,13 @@ namespace SPC\builder\unix\library; +use SPC\util\executor\UnixAutoconfExecutor; + trait libiconv { protected function build(): void { - [,,$destdir] = SEPARATED_PATH; - - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - '--enable-extra-encodings ' . - '--prefix=' - ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . $destdir); - - if (file_exists(BUILD_BIN_PATH . '/iconv')) { - unlink(BUILD_BIN_PATH . '/iconv'); - } + UnixAutoconfExecutor::create($this)->configure('--enable-extra-encodings')->make(); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/libjpeg.php b/src/SPC/builder/unix/library/libjpeg.php index 3f8aff9e1..6196f8afa 100644 --- a/src/SPC/builder/unix/library/libjpeg.php +++ b/src/SPC/builder/unix/library/libjpeg.php @@ -26,6 +26,5 @@ protected function build(): void ->build(); // patch pkgconfig $this->patchPkgconfPrefix(['libjpeg.pc', 'libturbojpeg.pc']); - $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/unix/library/librdkafka.php b/src/SPC/builder/unix/library/librdkafka.php index 5ee4c0c8e..32f389e15 100644 --- a/src/SPC/builder/unix/library/librdkafka.php +++ b/src/SPC/builder/unix/library/librdkafka.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait librdkafka { @@ -15,25 +16,33 @@ trait librdkafka */ protected function build(): void { - $builddir = BUILD_ROOT_PATH; - - $zstd_option = $this->builder->getLib('zstd') ? ("STATIC_LIB_libzstd={$builddir}/lib/libzstd.a ") : ''; - shell()->cd($this->source_dir) - ->exec( - $zstd_option . - './configure ' . - '--enable-static --disable-shared --disable-curl --disable-sasl --disable-valgrind --disable-zlib --disable-ssl ' . - ($zstd_option == '' ? '--disable-zstd ' : '') . - '--prefix=' + UnixAutoconfExecutor::create($this) + ->optionalLib( + 'zstd', + function ($lib) { + putenv("STATIC_LIB_libzstd={$lib->getLibDir()}/libzstd.a"); + return ''; + }, + '--disable-zstd' + ) + ->removeConfigureArgs( + '--with-pic', + '--enable-pic', ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec("make install DESTDIR={$builddir}"); + ->configure( + '--disable-curl', + '--disable-sasl', + '--disable-valgrind', + '--disable-zlib', + '--disable-ssl', + ) + ->make(); + $this->patchPkgconfPrefix(['rdkafka.pc', 'rdkafka-static.pc', 'rdkafka++.pc', 'rdkafka++-static.pc']); // remove dynamic libs shell() - ->exec("rm -rf {$builddir}/lib/*.so.*") - ->exec("rm -rf {$builddir}/lib/*.so") - ->exec("rm -rf {$builddir}/lib/*.dylib"); + ->exec("rm -rf {$this->getLibDir()}/*.so.*") + ->exec("rm -rf {$this->getLibDir()}/*.so") + ->exec("rm -rf {$this->getLibDir()}/*.dylib"); } } diff --git a/src/SPC/builder/unix/library/libsodium.php b/src/SPC/builder/unix/library/libsodium.php index b24d52b7a..441166c9f 100644 --- a/src/SPC/builder/unix/library/libsodium.php +++ b/src/SPC/builder/unix/library/libsodium.php @@ -4,16 +4,13 @@ namespace SPC\builder\unix\library; +use SPC\util\executor\UnixAutoconfExecutor; + 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); - + UnixAutoconfExecutor::create($this)->configure()->make(); $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 17862a792..f615019a2 100644 --- a/src/SPC/builder/unix/library/libtiff.php +++ b/src/SPC/builder/unix/library/libtiff.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait libtiff { @@ -15,30 +16,26 @@ trait libtiff */ protected function build(): void { - // zlib - $extra_libs = '--enable-zlib --with-zlib-include-dir=' . BUILD_ROOT_PATH . '/include --with-zlib-lib-dir=' . BUILD_ROOT_PATH . '/lib'; - // libjpeg - $extra_libs .= ' --enable-jpeg --disable-old-jpeg --disable-jpeg12 --with-jpeg-include-dir=' . BUILD_ROOT_PATH . '/include --with-jpeg-lib-dir=' . BUILD_ROOT_PATH . '/lib'; - // We disabled lzma, zstd, webp, libdeflate by default to reduce the size of the binary - $extra_libs .= ' --disable-lzma --disable-zstd --disable-webp --disable-libdeflate'; - - $shell = shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static --disable-shared ' . - "{$extra_libs} " . - '--disable-cxx ' . - '--prefix=' - ); - - // TODO: Remove this check when https://gitlab.com/libtiff/libtiff/-/merge_requests/635 will be merged and released - if (file_exists($this->source_dir . '/html')) { - $shell->exec('make clean'); - } - - $shell - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + UnixAutoconfExecutor::create($this) + ->configure( + // zlib deps + '--enable-zlib', + "--with-zlib-include-dir={$this->getIncludeDir()}", + "--with-zlib-lib-dir={$this->getLibDir()}", + // libjpeg deps + '--enable-jpeg', + '--disable-old-jpeg', + '--disable-jpeg12', + "--with-jpeg-include-dir={$this->getIncludeDir()}", + "--with-jpeg-lib-dir={$this->getLibDir()}", + // We disabled lzma, zstd, webp, libdeflate by default to reduce the size of the binary + '--disable-lzma', + '--disable-zstd', + '--disable-webp', + '--disable-libdeflate', + '--disable-cxx', + ) + ->make(); $this->patchPkgconfPrefix(['libtiff-4.pc']); } } diff --git a/src/SPC/builder/unix/library/libwebp.php b/src/SPC/builder/unix/library/libwebp.php index e4f45eb43..32331ea27 100644 --- a/src/SPC/builder/unix/library/libwebp.php +++ b/src/SPC/builder/unix/library/libwebp.php @@ -24,8 +24,6 @@ protected function build(): void // patch pkgconfig $this->patchPkgconfPrefix(['libsharpyuv.pc', 'libwebp.pc', 'libwebpdecoder.pc', 'libwebpdemux.pc', 'libwebpmux.pc'], PKGCONF_PATCH_PREFIX | PKGCONF_PATCH_LIBDIR); $this->patchPkgconfPrefix(['libsharpyuv.pc'], PKGCONF_PATCH_CUSTOM, ['/^includedir=.*$/m', 'includedir=${prefix}/include/webp']); - $this->cleanLaFiles(); - // fix imagemagick binary linking issue $this->patchPkgconfPrefix(['libwebp.pc'], PKGCONF_PATCH_CUSTOM, ['/-lwebp$/m', '-lwebp -lsharpyuv']); } } diff --git a/src/SPC/builder/unix/library/libxml2.php b/src/SPC/builder/unix/library/libxml2.php index 72a418ef7..85a6e8b6f 100644 --- a/src/SPC/builder/unix/library/libxml2.php +++ b/src/SPC/builder/unix/library/libxml2.php @@ -17,7 +17,13 @@ trait libxml2 public function build(): void { $cmake = UnixCMakeExecutor::create($this) - ->optionalLib('zlib', "-DLIBXML2_WITH_ZLIB=ON -DZLIB_LIBRARY={$this->getLibDir()}/libz.a -DZLIB_INCLUDE_DIR={$this->getIncludeDir()}", '-DLIBXML2_WITH_ZLIB=OFF') + ->optionalLib( + 'zlib', + '-DLIBXML2_WITH_ZLIB=ON ' . + "-DZLIB_LIBRARY={$this->getLibDir()}/libz.a " . + "-DZLIB_INCLUDE_DIR={$this->getIncludeDir()}", + '-DLIBXML2_WITH_ZLIB=OFF', + ) ->optionalLib('icu', ...cmake_boolean_args('LIBXML2_WITH_ICU')) ->optionalLib('xz', ...cmake_boolean_args('LIBXML2_WITH_LZMA')) ->addConfigureArgs( @@ -35,8 +41,13 @@ public function build(): void FileSystem::replaceFileStr( BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc', - '-licudata -licui18n -licuuc', - '-licui18n -licuuc -licudata' + '-lxml2 -liconv', + '-lxml2' + ); + FileSystem::replaceFileStr( + BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc', + '-lxml2', + '-lxml2 -liconv' ); } } diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index b241d7156..c820f8f69 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -8,6 +8,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\util\executor\UnixAutoconfExecutor; trait libxslt { @@ -18,34 +19,26 @@ trait libxslt */ protected function build(): void { - $required_libs = ''; - foreach ($this->getDependencies() as $dep) { - if ($dep instanceof LinuxLibraryBase) { - $required_libs .= ' ' . $dep->getStaticLibFiles(); - } - } - shell()->cd($this->source_dir)->initializeEnv($this) + $static_libs = $this instanceof LinuxLibraryBase ? $this->getStaticLibFiles(include_self: false) : ''; + $ac = UnixAutoconfExecutor::create($this) ->appendEnv([ 'CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}", - 'LIBS' => "{$required_libs} -lstdc++", + 'LIBS' => "{$static_libs} -lstdc++", ]) - ->exec( - "{$this->builder->getOption('library_path')} " . - "{$this->builder->getOption('ld_library_path')} " . - './configure ' . - '--enable-static --disable-shared ' . - '--without-python ' . - '--without-mem-debug ' . - '--without-crypto ' . - '--without-debug ' . - '--without-debugger ' . - '--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)); + ->addConfigureArgs( + '--without-python', + '--without-crypto', + '--without-debug', + '--without-debugger', + "--with-libxml-prefix={$this->getBuildRootPath()}", + ); + $ac->exec("{$this->builder->getOption('library_path')} {$this->builder->getOption('ld_library_path')} ./configure {$ac->getConfigureArgsString()}")->make(); + $this->patchPkgconfPrefix(['libexslt.pc']); + $this->patchLaDependencyPrefix(); + shell()->cd(BUILD_LIB_PATH) + ->exec("ar -t libxslt.a | grep '\\.a$' | xargs -n1 ar d libxslt.a") + ->exec("ar -t libexslt.a | grep '\\.a$' | xargs -n1 ar d libexslt.a"); } } diff --git a/src/SPC/builder/unix/library/libyaml.php b/src/SPC/builder/unix/library/libyaml.php index 47ce3fb30..12ab39154 100644 --- a/src/SPC/builder/unix/library/libyaml.php +++ b/src/SPC/builder/unix/library/libyaml.php @@ -26,6 +26,10 @@ public function getLibVersion(): ?string protected function build(): void { - UnixCMakeExecutor::create($this)->addConfigureArgs('-DBUILD_TESTING=OFF')->build(); + $cmake = UnixCMakeExecutor::create($this)->addConfigureArgs('-DBUILD_TESTING=OFF'); + if (version_compare(get_cmake_version(), '4.0.0', '>=')) { + $cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.5'); + } + $cmake->build(); } } diff --git a/src/SPC/builder/unix/library/libzip.php b/src/SPC/builder/unix/library/libzip.php index b8d2893fe..a442129fb 100644 --- a/src/SPC/builder/unix/library/libzip.php +++ b/src/SPC/builder/unix/library/libzip.php @@ -24,7 +24,6 @@ protected function build(): void ->addConfigureArgs( '-DENABLE_GNUTLS=OFF', '-DENABLE_MBEDTLS=OFF', - '-DBUILD_SHARED_LIBS=OFF', '-DBUILD_DOC=OFF', '-DBUILD_EXAMPLES=OFF', '-DBUILD_REGRESS=OFF', diff --git a/src/SPC/builder/unix/library/ncurses.php b/src/SPC/builder/unix/library/ncurses.php index 7d33c76a7..14d2a6dc7 100644 --- a/src/SPC/builder/unix/library/ncurses.php +++ b/src/SPC/builder/unix/library/ncurses.php @@ -5,37 +5,33 @@ namespace SPC\builder\unix\library; use SPC\store\FileSystem; +use SPC\util\executor\UnixAutoconfExecutor; trait ncurses { protected function build(): void { $filelist = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true); - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - '--enable-overwrite ' . - '--with-curses-h ' . - '--enable-pc-files ' . - '--enable-echo ' . - '--disable-widec ' . - '--with-normal ' . - '--with-ticlib ' . - '--without-tests ' . - '--without-dlsym ' . - '--without-debug ' . - '-enable-symlinks ' . - '--bindir=' . BUILD_ROOT_PATH . '/bin ' . - '--includedir=' . BUILD_ROOT_PATH . '/include ' . - '--libdir=' . BUILD_ROOT_PATH . '/lib ' . - '--prefix=' . BUILD_ROOT_PATH - ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install'); + UnixAutoconfExecutor::create($this) + ->configure( + '--enable-overwrite', + '--with-curses-h', + '--enable-pc-files', + '--enable-echo', + '--disable-widec', + '--with-normal', + '--with-ticlib', + '--without-tests', + '--without-dlsym', + '--without-debug', + '-enable-symlinks', + "--bindir={$this->getBinDir()}", + "--includedir={$this->getIncludeDir()}", + "--libdir={$this->getLibDir()}", + "--prefix={$this->getBuildRootPath()}", + ) + ->make(); $final = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true); // Remove the new files $new_files = array_diff($final, $filelist); diff --git a/src/SPC/builder/unix/library/nghttp2.php b/src/SPC/builder/unix/library/nghttp2.php index 03c883bfd..d54a47daa 100644 --- a/src/SPC/builder/unix/library/nghttp2.php +++ b/src/SPC/builder/unix/library/nghttp2.php @@ -7,6 +7,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\util\executor\UnixAutoconfExecutor; trait nghttp2 { @@ -17,42 +18,33 @@ trait nghttp2 */ protected function build(): void { - $args = $this->builder->makeAutoconfArgs(static::NAME, [ - 'zlib' => null, - 'openssl' => null, - 'libxml2' => null, - 'libev' => null, - 'libcares' => null, - 'libngtcp2' => null, - 'libnghttp3' => null, - 'libbpf' => null, - 'libevent-openssl' => null, - 'jansson' => null, - 'jemalloc' => null, - 'systemd' => null, - ]); - if ($brotli = $this->builder->getLib('brotli')) { - /* @phpstan-ignore-next-line */ - $args .= ' --with-libbrotlidec=yes LIBBROTLIDEC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIDEC_LIBS="' . $brotli->getStaticLibFiles() . '"'; - /* @phpstan-ignore-next-line */ - $args .= ' --with-libbrotlienc=yes LIBBROTLIENC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIENC_LIBS="' . $brotli->getStaticLibFiles() . '"'; - } - - [,,$destdir] = SEPARATED_PATH; - - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - '--with-pic ' . - '--enable-lib-only ' . - $args . ' ' . - '--prefix=' + UnixAutoconfExecutor::create($this) + ->optionalLib('zlib', ...ac_with_args('zlib', true)) + ->optionalLib('openssl', ...ac_with_args('openssl', true)) + ->optionalLib('libxml2', ...ac_with_args('libxml2', true)) + ->optionalLib('libev', ...ac_with_args('libev', true)) + ->optionalLib('libcares', ...ac_with_args('libcares', true)) + ->optionalLib('ngtcp2', ...ac_with_args('libngtcp2', true)) + ->optionalLib('nghttp3', ...ac_with_args('libnghttp3', true)) + // ->optionalLib('libbpf', ...ac_with_args('libbpf', true)) + // ->optionalLib('libevent-openssl', ...ac_with_args('libevent-openssl', true)) + // ->optionalLib('jansson', ...ac_with_args('jansson', true)) + // ->optionalLib('jemalloc', ...ac_with_args('jemalloc', true)) + // ->optionalLib('systemd', ...ac_with_args('systemd', true)) + ->optionalLib( + 'brotli', + fn ($lib) => implode(' ', [ + '--with-brotlidec=yes', + "LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", + "LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"", + '--with-libbrotlienc=yes', + "LIBBROTLIENC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", + "LIBBROTLIENC_LIBS=\"{$lib->getStaticLibFiles()}\"", + ]) ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec("make install DESTDIR={$destdir}"); + ->configure('--enable-lib-only') + ->make(); $this->patchPkgconfPrefix(['libnghttp2.pc']); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/nghttp3.php b/src/SPC/builder/unix/library/nghttp3.php index 95cc22bf8..6d9d577c0 100644 --- a/src/SPC/builder/unix/library/nghttp3.php +++ b/src/SPC/builder/unix/library/nghttp3.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait nghttp3 { @@ -15,18 +16,8 @@ trait nghttp3 */ protected function build(): void { - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - '--with-pic ' . - '--enable-lib-only ' . - '--prefix=' - ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + UnixAutoconfExecutor::create($this)->configure('--enable-lib-only')->make(); $this->patchPkgconfPrefix(['libnghttp3.pc']); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/ngtcp2.php b/src/SPC/builder/unix/library/ngtcp2.php index 97a0a8af6..df29fba32 100644 --- a/src/SPC/builder/unix/library/ngtcp2.php +++ b/src/SPC/builder/unix/library/ngtcp2.php @@ -7,6 +7,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\util\executor\UnixAutoconfExecutor; trait ngtcp2 { @@ -17,37 +18,34 @@ trait ngtcp2 */ protected function build(): void { - $args = $this->builder->makeAutoconfArgs(static::NAME, [ - 'openssl' => null, - 'libev' => null, - 'jemalloc' => null, - 'libnghttp3' => null, - ]); - if ($brotli = $this->builder->getLib('brotli')) { - /* @phpstan-ignore-next-line */ - $args .= ' --with-libbrotlidec=yes LIBBROTLIDEC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIDEC_LIBS="' . $brotli->getStaticLibFiles() . '"'; - /* @phpstan-ignore-next-line */ - $args .= ' --with-libbrotlienc=yes LIBBROTLIENC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIENC_LIBS="' . $brotli->getStaticLibFiles() . '"'; - } - - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - '--with-pic ' . - '--enable-lib-only ' . - $args . ' ' . - '--prefix=' + UnixAutoconfExecutor::create($this) + ->optionalLib('openssl', fn ($lib) => implode(' ', [ + '--with-openssl=yes', + "OPENSSL_LIBS=\"{$lib->getStaticLibFiles()}\"", + "OPENSSL_CFLAGS=\"-I{$lib->getIncludeDir()}\"", + ]), '--with-openssl=no') + ->optionalLib('libev', ...ac_with_args('libev', true)) + ->optionalLib('nghttp3', ...ac_with_args('libnghttp3', true)) + ->optionalLib('jemalloc', ...ac_with_args('jemalloc', true)) + ->optionalLib( + 'brotli', + fn ($lib) => implode(' ', [ + '--with-brotlidec=yes', + "LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", + "LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"", + '--with-libbrotlienc=yes', + "LIBBROTLIENC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", + "LIBBROTLIENC_LIBS=\"{$lib->getStaticLibFiles()}\"", + ]) ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + ->appendEnv(['PKG_CONFIG' => '$PKG_CONFIG --static']) + ->configure('--enable-lib-only') + ->make(); $this->patchPkgconfPrefix(['libngtcp2.pc', 'libngtcp2_crypto_ossl.pc']); + $this->patchLaDependencyPrefix(); // on macOS, the static library may contain other static libraries? // ld: archive member 'libssl.a' not a mach-o file in libngtcp2_crypto_ossl.a - shell()->cd(BUILD_LIB_PATH) - ->exec("ar -t libngtcp2_crypto_ossl.a | grep '\\.a$' | xargs -n1 ar d libngtcp2_crypto_ossl.a"); + shell()->cd(BUILD_LIB_PATH)->exec("ar -t libngtcp2_crypto_ossl.a | grep '\\.a$' | xargs -n1 ar d libngtcp2_crypto_ossl.a"); } } diff --git a/src/SPC/builder/unix/library/onig.php b/src/SPC/builder/unix/library/onig.php index 0ff844db0..368c852bf 100644 --- a/src/SPC/builder/unix/library/onig.php +++ b/src/SPC/builder/unix/library/onig.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait onig { @@ -15,13 +16,7 @@ trait onig */ protected function build(): void { - [,,$destdir] = SEPARATED_PATH; - - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec('./configure --enable-static --disable-shared --prefix=') - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec("make install DESTDIR={$destdir}"); + UnixAutoconfExecutor::create($this)->configure()->make(); $this->patchPkgconfPrefix(['oniguruma.pc']); } } diff --git a/src/SPC/builder/unix/library/pkgconfig.php b/src/SPC/builder/unix/library/pkgconfig.php index 51fa586be..05727f96a 100644 --- a/src/SPC/builder/unix/library/pkgconfig.php +++ b/src/SPC/builder/unix/library/pkgconfig.php @@ -5,32 +5,27 @@ namespace SPC\builder\unix\library; use SPC\builder\linux\library\LinuxLibraryBase; +use SPC\util\executor\UnixAutoconfExecutor; trait pkgconfig { protected function build(): void { - $cflags = PHP_OS_FAMILY !== 'Linux' ? "{$this->builder->arch_c_flags} -Wimplicit-function-declaration -Wno-int-conversion" : ''; - $ldflags = !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? '' : '--static'; - - shell()->cd($this->source_dir)->initializeEnv($this) - ->appendEnv(['CFLAGS' => $cflags, 'LDFLAGS' => $ldflags]) - ->exec( - './configure ' . - '--disable-shared ' . - '--enable-static ' . - '--with-internal-glib ' . - '--disable-host-tool ' . - '--with-pic ' . - '--prefix=' . BUILD_ROOT_PATH . ' ' . - '--without-sysroot ' . - '--without-system-include-path ' . - '--without-system-library-path ' . - '--without-pc-path' + UnixAutoconfExecutor::create($this) + ->appendEnv([ + 'CFLAGS' => PHP_OS_FAMILY !== 'Linux' ? '-Wimplicit-function-declaration -Wno-int-conversion' : '', + 'LDFLAGS' => !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? '' : '--static', + ]) + ->configure( + '--with-internal-glib', + '--disable-host-tool', + '--without-sysroot', + '--without-system-include-path', + '--without-system-library-path', + '--without-pc-path', ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install-exec'); + ->make(with_install: 'install-exec'); + shell()->exec('strip ' . BUILD_ROOT_PATH . '/bin/pkg-config'); } } diff --git a/src/SPC/builder/unix/library/postgresql.php b/src/SPC/builder/unix/library/postgresql.php index 7885eca3a..1de3e4c28 100644 --- a/src/SPC/builder/unix/library/postgresql.php +++ b/src/SPC/builder/unix/library/postgresql.php @@ -22,7 +22,7 @@ protected function build(): void $packages = 'zlib openssl readline libxml-2.0'; $optional_packages = [ 'zstd' => 'libzstd', - // 'ldap' => 'ldap', + 'ldap' => 'ldap', 'libxslt' => 'libxslt', 'icu' => 'icu-i18n', ]; @@ -39,10 +39,12 @@ protected function build(): void $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; @@ -79,17 +81,19 @@ protected function build(): void } // configure - shell()->cd($this->source_dir . '/build') + shell()->cd($this->source_dir . '/build')->initializeEnv($this) + ->appendEnv(['CFLAGS' => $cflags]) ->exec( "{$envs} ../configure " . "--prefix={$builddir} " . - '--disable-thread-safety ' . + ($this->builder->getOption('enable-zts') ? '--enable-thread-safety ' : '--disable-thread-safety ') . '--enable-coverage=no ' . '--with-ssl=openssl ' . '--with-readline ' . '--with-libxml ' . ($this->builder->getLib('icu') ? '--with-icu ' : '--without-icu ') . - '--without-ldap ' . + ($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 ') . '--without-lz4 ' . @@ -98,11 +102,7 @@ protected function build(): void '--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') @@ -114,6 +114,8 @@ protected function build(): void ->exec("rm -rf {$builddir}/lib/*.so.*") ->exec("rm -rf {$builddir}/lib/*.so") ->exec("rm -rf {$builddir}/lib/*.dylib"); + + FileSystem::replaceFileStr(BUILD_LIB_PATH . '/pkgconfig/libpq.pc', '-lldap', '-lldap -llber'); } private function getVersion(): string diff --git a/src/SPC/builder/unix/library/qdbm.php b/src/SPC/builder/unix/library/qdbm.php index 21eff478a..b7a43cdf2 100644 --- a/src/SPC/builder/unix/library/qdbm.php +++ b/src/SPC/builder/unix/library/qdbm.php @@ -8,6 +8,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixAutoconfExecutor; trait qdbm { @@ -17,17 +18,9 @@ trait qdbm */ protected function build(): void { - shell()->cd($this->source_dir) - ->exec( - './configure ' . - '--enable-static --disable-shared ' . - '--prefix=' - ) - ->exec('make clean'); + $ac = UnixAutoconfExecutor::create($this)->configure(); FileSystem::replaceFileRegex($this->source_dir . '/Makefile', '/MYLIBS = libqdbm.a.*/m', 'MYLIBS = libqdbm.a'); - shell()->cd($this->source_dir) - ->exec("make -j{$this->builder->concurrency}" . ($this instanceof MacOSLibraryBase ? ' mac' : '')) - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + $ac->make($this instanceof MacOSLibraryBase ? 'mac' : ''); $this->patchPkgconfPrefix(['qdbm.pc']); } } diff --git a/src/SPC/builder/unix/library/readline.php b/src/SPC/builder/unix/library/readline.php index c0fe90780..8cfca0ab1 100644 --- a/src/SPC/builder/unix/library/readline.php +++ b/src/SPC/builder/unix/library/readline.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait readline { @@ -15,18 +16,12 @@ trait readline */ protected function build(): void { - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec( - './configure ' . - '--enable-static=yes ' . - '--enable-shared=no ' . - '--prefix= ' . - '--with-curses ' . - '--enable-multibyte=yes' + UnixAutoconfExecutor::create($this) + ->configure( + '--with-curses', + '--enable-multibyte=yes', ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + ->make(); $this->patchPkgconfPrefix(['readline.pc']); } } diff --git a/src/SPC/builder/unix/library/sqlite.php b/src/SPC/builder/unix/library/sqlite.php index c6219171b..8f9add24b 100644 --- a/src/SPC/builder/unix/library/sqlite.php +++ b/src/SPC/builder/unix/library/sqlite.php @@ -4,15 +4,13 @@ namespace SPC\builder\unix\library; +use SPC\util\executor\UnixAutoconfExecutor; + trait sqlite { protected function build(): void { - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec('./configure --enable-static --disable-shared --prefix=') - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + UnixAutoconfExecutor::create($this)->configure()->make(); $this->patchPkgconfPrefix(['sqlite3.pc']); } } diff --git a/src/SPC/builder/unix/library/tidy.php b/src/SPC/builder/unix/library/tidy.php index d842dc6df..33405a477 100644 --- a/src/SPC/builder/unix/library/tidy.php +++ b/src/SPC/builder/unix/library/tidy.php @@ -16,13 +16,16 @@ trait tidy */ protected function build(): void { - UnixCMakeExecutor::create($this) + $cmake = UnixCMakeExecutor::create($this) ->setBuildDir("{$this->source_dir}/build-dir") ->addConfigureArgs( '-DSUPPORT_CONSOLE_APP=OFF', '-DBUILD_SHARED_LIB=OFF' - ) - ->build(); + ); + if (version_compare(get_cmake_version(), '4.0.0', '>=')) { + $cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.5'); + } + $cmake->build(); $this->patchPkgconfPrefix(['tidy.pc']); } } diff --git a/src/SPC/builder/unix/library/unixodbc.php b/src/SPC/builder/unix/library/unixodbc.php index f89eb0a44..a795d2447 100644 --- a/src/SPC/builder/unix/library/unixodbc.php +++ b/src/SPC/builder/unix/library/unixodbc.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait unixodbc { @@ -15,21 +16,16 @@ trait unixodbc */ protected function build(): void { - shell()->cd($this->source_dir) - ->exec( - './configure ' . - '--enable-static --disable-shared ' . - '--disable-debug ' . - '--disable-dependency-tracking ' . - '--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' . - '--with-included-ltdl ' . - '--enable-gui=no ' . - '--prefix=' + UnixAutoconfExecutor::create($this) + ->configure( + '--disable-debug', + '--disable-dependency-tracking', + "--with-libiconv-prefix={$this->getBuildRootPath()}", + '--with-included-ltdl', + '--enable-gui=no', ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + ->make(); $this->patchPkgconfPrefix(['odbc.pc', 'odbccr.pc', 'odbcinst.pc']); - $this->cleanLaFiles(); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/xz.php b/src/SPC/builder/unix/library/xz.php index 1869f589c..f127e59ab 100644 --- a/src/SPC/builder/unix/library/xz.php +++ b/src/SPC/builder/unix/library/xz.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait xz { @@ -15,19 +16,14 @@ trait xz */ public function build(): void { - shell()->cd($this->source_dir) - ->exec( - './configure ' . - '--enable-static ' . - '--disable-shared ' . - '--disable-scripts ' . - '--disable-doc ' . - '--with-libiconv ' . - '--prefix=' + UnixAutoconfExecutor::create($this) + ->configure( + '--disable-scripts', + '--disable-doc', + '--with-libiconv', ) - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + ->make(); $this->patchPkgconfPrefix(['liblzma.pc']); + $this->patchLaDependencyPrefix(); } } diff --git a/src/SPC/builder/unix/library/zlib.php b/src/SPC/builder/unix/library/zlib.php index 8accaf666..717ec3fb3 100644 --- a/src/SPC/builder/unix/library/zlib.php +++ b/src/SPC/builder/unix/library/zlib.php @@ -6,6 +6,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixAutoconfExecutor; trait zlib { @@ -15,13 +16,7 @@ trait zlib */ protected function build(): void { - [,,$destdir] = SEPARATED_PATH; - - shell()->cd($this->source_dir)->initializeEnv($this) - ->exec('./configure --static --prefix=') - ->exec('make clean') - ->exec("make -j{$this->builder->concurrency}") - ->exec("make install DESTDIR={$destdir}"); + UnixAutoconfExecutor::create($this)->exec("./configure --static --prefix={$this->getBuildRootPath()}")->make(); $this->patchPkgconfPrefix(['zlib.pc']); } } diff --git a/src/SPC/builder/windows/WindowsBuilder.php b/src/SPC/builder/windows/WindowsBuilder.php index 7a604ca86..c76431438 100644 --- a/src/SPC/builder/windows/WindowsBuilder.php +++ b/src/SPC/builder/windows/WindowsBuilder.php @@ -146,7 +146,10 @@ public function buildPHP(int $build_target = BUILD_TARGET_NONE): void // logger()->info('building embed'); $this->buildEmbed(); } + } + public function testPHP(int $build_target = BUILD_TARGET_NONE) + { $this->sanityCheck($build_target); } diff --git a/src/SPC/builder/windows/library/WindowsLibraryBase.php b/src/SPC/builder/windows/library/WindowsLibraryBase.php index e8de629ea..076afa039 100644 --- a/src/SPC/builder/windows/library/WindowsLibraryBase.php +++ b/src/SPC/builder/windows/library/WindowsLibraryBase.php @@ -29,9 +29,9 @@ public function getBuilder(): BuilderBase * @throws FileSystemException * @throws WrongUsageException */ - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true): string + public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string { - $libs = [$this]; + $libs = $include_self ? [$this] : []; if ($recursive) { array_unshift($libs, ...array_values($this->getDependencies(recursive: true))); } diff --git a/src/SPC/command/BuildPHPCommand.php b/src/SPC/command/BuildPHPCommand.php index 49067b0b8..61781d2c7 100644 --- a/src/SPC/command/BuildPHPCommand.php +++ b/src/SPC/command/BuildPHPCommand.php @@ -73,7 +73,7 @@ public function handle(): int } $static_and_shared = array_intersect($static_extensions, $shared_extensions); if (!empty($static_and_shared)) { - $this->output->writeln('Building extensions [' . implode(',', $static_and_shared) . '] as both static and shared\, tests may not be accurate or fail.'); + $this->output->writeln('Building extensions [' . implode(',', $static_and_shared) . '] as both static and shared, tests may not be accurate or fail.'); } if ($rule === BUILD_TARGET_NONE) { @@ -128,7 +128,6 @@ public function handle(): int $include_suggest_lib = $this->getOption('with-suggested-libs'); [$extensions, $libraries, $not_included] = DependencyUtil::getExtsAndLibs(array_merge($static_extensions, $shared_extensions), $libraries, $include_suggest_ext, $include_suggest_lib); $display_libs = array_filter($libraries, fn ($lib) => in_array(Config::getLib($lib, 'type', 'lib'), ['lib', 'package'])); - $display_extensions = array_map(fn ($ext) => in_array($ext, $shared_extensions) ? "*{$ext}" : $ext, $extensions); // separate static and shared extensions from $extensions // filter rule: including shared extensions if they are in $static_extensions or $shared_extensions @@ -138,7 +137,8 @@ public function handle(): int $indent_texts = [ 'Build OS' => PHP_OS_FAMILY . ' (' . php_uname('m') . ')', 'Build SAPI' => $builder->getBuildTypeName($rule), - 'Extensions (' . count($extensions) . ')' => implode(',', $display_extensions), + 'Static Extensions (' . count($static_extensions) . ')' => implode(',', $static_extensions), + 'Shared Extensions (' . count($shared_extensions) . ')' => implode(',', $shared_extensions), 'Libraries (' . count($libraries) . ')' => implode(',', $display_libs), 'Strip Binaries' => $builder->getOption('no-strip') ? 'no' : 'yes', 'Enable ZTS' => $builder->getOption('enable-zts') ? 'yes' : 'no', @@ -210,12 +210,16 @@ public function handle(): int // start to build $builder->buildPHP($rule); + SourcePatcher::patchBeforeSharedBuild($builder); + // build dynamic extensions if needed if (!empty($shared_extensions)) { logger()->info('Building shared extensions ...'); $builder->buildSharedExts(); } + $builder->testPHP($rule); + // compile stopwatch :P $time = round(microtime(true) - START_TIME, 3); logger()->info(''); @@ -246,8 +250,12 @@ public function handle(): int } 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_MODULES_PATH . "/{$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/command/CraftCommand.php b/src/SPC/command/CraftCommand.php index 9fa2f385f..8d3cc2bee 100644 --- a/src/SPC/command/CraftCommand.php +++ b/src/SPC/command/CraftCommand.php @@ -48,7 +48,8 @@ public function handle(): int } } - $extensions = implode(',', $craft['extensions']); + $static_extensions = implode(',', $craft['extensions']); + $shared_extensions = implode(',', $craft['shared-extensions']); $libs = implode(',', $craft['libs']); // init log @@ -67,16 +68,15 @@ public function handle(): int } // craft download if ($craft['craft-options']['download']) { - $args = ["--for-extensions={$extensions}"]; + $sharedAppend = $shared_extensions ? ',' . $shared_extensions : ''; + $args = ["--for-extensions={$static_extensions}{$sharedAppend}"]; if ($craft['libs'] !== []) { $args[] = "--for-libs={$libs}"; } if (isset($craft['php-version'])) { $args[] = '--with-php=' . $craft['php-version']; - if (!array_key_exists('ignore-cache-sources', $craft['download-options']) || $craft['download-options']['ignore-cache-sources'] === false) { + if (!array_key_exists('ignore-cache-sources', $craft['download-options'])) { $craft['download-options']['ignore-cache-sources'] = 'php-src'; - } elseif ($craft['download-options']['ignore-cache-sources'] !== null) { - $craft['download-options']['ignore-cache-sources'] .= ',php-src'; } } $this->optionsToArguments($craft['download-options'], $args); @@ -90,7 +90,7 @@ public function handle(): int // craft build if ($craft['craft-options']['build']) { - $args = [$extensions, "--with-libs={$libs}", ...array_map(fn ($x) => "--build-{$x}", $craft['sapi'])]; + $args = [$static_extensions, "--with-libs={$libs}", "--build-shared={$shared_extensions}", ...array_map(fn ($x) => "--build-{$x}", $craft['sapi'])]; $this->optionsToArguments($craft['build-options'], $args); $retcode = $this->runCommand('build', ...$args); if ($retcode !== 0) { @@ -131,7 +131,8 @@ private function runCommand(string $cmd, ...$args): int } $prefix = PHP_SAPI === 'cli' ? [PHP_BINARY, $argv[0]] : [$argv[0]]; - $process = new Process([...$prefix, $cmd, '--no-motd', ...$args], timeout: null); + $env = getenv(); + $process = new Process([...$prefix, $cmd, '--no-motd', ...$args], env: $env, timeout: null); $this->log("Running: {$process->getCommandLine()}", true); if (PHP_OS_FAMILY === 'Windows') { @@ -142,7 +143,6 @@ private function runCommand(string $cmd, ...$args): int }); } elseif (extension_loaded('pcntl')) { pcntl_signal(SIGINT, function () use ($process) { - /* @noinspection PhpComposerExtensionStubsInspection */ $process->signal(SIGINT); }); } else { diff --git a/src/SPC/doctor/item/LinuxToolCheckList.php b/src/SPC/doctor/item/LinuxToolCheckList.php index 976d5fd60..2522eb58e 100644 --- a/src/SPC/doctor/item/LinuxToolCheckList.php +++ b/src/SPC/doctor/item/LinuxToolCheckList.php @@ -21,7 +21,7 @@ class LinuxToolCheckList 'tar', 'unzip', 'gzip', 'bzip2', 'cmake', 'gcc', 'g++', 'patch', 'binutils-gold', - 'libtoolize', + 'libtoolize', 'which', ]; public const TOOLS_DEBIAN = [ @@ -29,14 +29,14 @@ class LinuxToolCheckList 'git', 'autoconf', 'automake', 'autopoint', 'tar', 'unzip', 'gzip', 'bzip2', 'cmake', 'patch', - 'xz', 'libtoolize', + 'xz', 'libtoolize', 'which', ]; public const TOOLS_RHEL = [ 'perl', 'make', 'bison', 'flex', 'git', 'autoconf', 'automake', 'tar', 'unzip', 'gzip', 'gcc', - 'bzip2', 'cmake', 'patch', + 'bzip2', 'cmake', 'patch', 'which', 'xz', 'libtool', 'gettext-devel', ]; @@ -47,7 +47,7 @@ class LinuxToolCheckList private const PROVIDED_COMMAND = [ 'binutils-gold' => 'ld.gold', 'base-devel' => 'automake', - 'gettext-devel' => 'gettext', + 'gettext-devel' => 'gettextize', ]; /** @noinspection PhpUnused */ diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index b5de166f5..d61020b81 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -22,6 +22,7 @@ public static function init(): void FileSystem::addSourceExtractHook('swoole', [SourcePatcher::class, 'patchSwoole']); FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchPhpLibxml212']); FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchGDWin32']); + FileSystem::addSourceExtractHook('php-src', [SourcePatcher::class, 'patchFfiCentos7FixO3strncmp']); FileSystem::addSourceExtractHook('sqlsrv', [SourcePatcher::class, 'patchSQLSRVWin32']); FileSystem::addSourceExtractHook('pdo_sqlsrv', [SourcePatcher::class, 'patchSQLSRVWin32']); FileSystem::addSourceExtractHook('yaml', [SourcePatcher::class, 'patchYamlWin32']); @@ -43,7 +44,7 @@ public static function init(): void */ 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'); } @@ -78,6 +79,15 @@ public static function patchBeforeBuildconf(BuilderBase $builder): void } } + 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 +96,7 @@ public static function patchBeforeBuildconf(BuilderBase $builder): void */ 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'); } @@ -442,6 +452,22 @@ public static function patchImagickWith84(): bool return false; } + public static function patchFfiCentos7FixO3strncmp(): bool + { + if (PHP_OS_FAMILY !== 'Linux' || SystemUtil::getLibcVersionIfExists() >= '2.17') { + return false; + } + if (!file_exists(SOURCE_PATH . '/php-src/main/php_version.h')) { + return false; + } + $file = file_get_contents(SOURCE_PATH . '/php-src/main/php_version.h'); + if (preg_match('/PHP_VERSION_ID (\d+)/', $file, $match) !== 0 && intval($match[1]) < 80316) { + return false; + } + SourcePatcher::patchFile('ffi_centos7_fix_O3_strncmp.patch', SOURCE_PATH . '/php-src'); + return true; + } + public static function patchLibaomForAlpine(): bool { if (PHP_OS_FAMILY === 'Linux' && SystemUtil::isMuslDist()) { diff --git a/src/SPC/util/ConfigValidator.php b/src/SPC/util/ConfigValidator.php index d455dda50..eae2ef2bd 100644 --- a/src/SPC/util/ConfigValidator.php +++ b/src/SPC/util/ConfigValidator.php @@ -120,6 +120,7 @@ public static function validatePkgs(mixed $data): void * @return array{ * php-version?: string, * extensions: array, + * shared-extensions?: array, * libs?: array, * sapi: array, * debug?: bool, diff --git a/src/SPC/util/GlobalValueTrait.php b/src/SPC/util/GlobalValueTrait.php new file mode 100644 index 000000000..d815b1f09 --- /dev/null +++ b/src/SPC/util/GlobalValueTrait.php @@ -0,0 +1,28 @@ +getLdflagsString(); - $libs = $this->getLibsString($libraries); + $libs = $this->getLibsString($libraries, $with_dependencies); + if (PHP_OS_FAMILY === 'Darwin') { + $libs .= " {$this->getFrameworksString($extensions)}"; + } $cflags = $this->getIncludesString(); // embed - $libs = '-lphp -lc ' . $libs; + $libs = trim("-lphp -lc {$libs}"); $extra_env = getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS'); if (is_string($extra_env)) { $libs .= ' ' . trim($extra_env, '"'); @@ -97,13 +100,40 @@ private function getLdflagsString(): string 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; + } + } + } + } + } else { + $requiredLibs[] = $this->getShortLibName($lib); + } + 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; @@ -116,7 +146,7 @@ private function getLibsString(array $libraries): string } } // patch: imagick (imagemagick wrapper) for linux needs libgomp - if (in_array('imagemagick', $libraries) && PHP_OS_FAMILY === 'Linux' && getenv('SPC_LIBC') === 'musl') { + if (in_array('imagemagick', $libraries) && PHP_OS_FAMILY === 'Linux' && !(getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10'))) { $short_name[] = '-lgomp'; } return implode(' ', $short_name); @@ -130,4 +160,18 @@ private function getShortLibName(string $lib): string // get short name return '-l' . substr($lib, 3, -2); } + + private function getFrameworksString(array $extensions): string + { + $list = []; + foreach ($extensions as $extension) { + foreach (Config::getExt($extension, 'frameworks', []) as $fw) { + $ks = '-framework ' . $fw; + if (!in_array($ks, $list)) { + $list[] = $ks; + } + } + } + return implode(' ', $list); + } } diff --git a/src/SPC/util/UnixShell.php b/src/SPC/util/UnixShell.php index a53f423d2..0f320d50c 100644 --- a/src/SPC/util/UnixShell.php +++ b/src/SPC/util/UnixShell.php @@ -110,15 +110,15 @@ public function execWithResult(string $cmd, bool $with_log = true): array public function setEnv(array $env): UnixShell { foreach ($env as $k => $v) { - if ($v === '') { + if (trim($v) === '') { continue; } - $this->env[$k] = $v; + $this->env[$k] = trim($v); } return $this; } - private function getEnvString(): string + public function getEnvString(): string { $str = ''; foreach ($this->env as $k => $v) { diff --git a/src/SPC/util/WindowsCmd.php b/src/SPC/util/WindowsCmd.php index ca06dc259..4398dc445 100644 --- a/src/SPC/util/WindowsCmd.php +++ b/src/SPC/util/WindowsCmd.php @@ -75,24 +75,4 @@ public function setEnv(array $env): WindowsCmd $this->env = array_merge($this->env, $env); return $this; } - - /** - * @throws RuntimeException - */ - public function execWithEnv(string $cmd): WindowsCmd - { - if ($this->getEnvString() !== '') { - return $this->exec($this->getEnvString() . "call {$cmd}"); - } - return $this->exec($cmd); - } - - private function getEnvString(): string - { - $str = ''; - foreach ($this->env as $k => $v) { - $str .= 'set ' . $k . '=' . $v . ' && '; - } - return $str; - } } diff --git a/src/SPC/util/executor/UnixAutoconfExecutor.php b/src/SPC/util/executor/UnixAutoconfExecutor.php new file mode 100644 index 000000000..1c9f496e2 --- /dev/null +++ b/src/SPC/util/executor/UnixAutoconfExecutor.php @@ -0,0 +1,141 @@ +initShell(); + } + + /** + * Run ./configure + */ + public function configure(...$args): static + { + // remove all the ignored args + $args = array_merge($args, $this->getDefaultConfigureArgs(), $this->configure_args); + $args = array_diff($args, $this->ignore_args); + $configure_args = implode(' ', $args); + + $this->shell->exec("./configure {$configure_args}"); + return $this; + } + + public function getConfigureArgsString(): string + { + return implode(' ', array_merge($this->getDefaultConfigureArgs(), $this->configure_args)); + } + + /** + * Run make + * + * @param string $target Build target + * @throws RuntimeException + */ + public function make(string $target = '', false|string $with_install = 'install', bool $with_clean = true, array $after_env_vars = []): static + { + if ($with_clean) { + $this->shell->exec('make clean'); + } + $after_env_vars_str = $after_env_vars !== [] ? shell()->setEnv($after_env_vars)->getEnvString() : ''; + $this->shell->exec("make -j{$this->library->getBuilder()->concurrency} {$target} {$after_env_vars_str}"); + if ($with_install !== false) { + $this->shell->exec("make {$with_install}"); + } + return $this; + } + + public function exec(string $cmd): static + { + $this->shell->exec($cmd); + return $this; + } + + /** + * Add optional library configuration. + * This method checks if a library is available and adds the corresponding arguments to the CMake configuration. + * + * @param string $name library name to check + * @param \Closure|string $true_args arguments to use if the library is available (allow closure, returns string) + * @param string $false_args arguments to use if the library is not available + * @return $this + */ + public function optionalLib(string $name, \Closure|string $true_args, string $false_args = ''): static + { + if ($get = $this->library->getBuilder()->getLib($name)) { + logger()->info("Building library [{$this->library->getName()}] with {$name} support"); + $args = $true_args instanceof \Closure ? $true_args($get) : $true_args; + } else { + logger()->info("Building library [{$this->library->getName()}] without {$name} support"); + $args = $false_args; + } + $this->addConfigureArgs($args); + return $this; + } + + /** + * Add configure args. + */ + public function addConfigureArgs(...$args): static + { + $this->configure_args = [...$this->configure_args, ...$args]; + return $this; + } + + /** + * Remove some configure args, to bypass the configure option checking for some libs. + */ + public function removeConfigureArgs(...$args): static + { + $this->ignore_args = [...$this->ignore_args, ...$args]; + return $this; + } + + public function appendEnv(array $env): static + { + $this->shell->appendEnv($env); + return $this; + } + + /** + * Returns the default autoconf ./configure arguments + */ + private function getDefaultConfigureArgs(): array + { + return [ + '--disable-shared', + '--enable-static', + "--prefix={$this->library->getBuildRootPath()}", + '--with-pic', + '--enable-pic', + ]; + } + + /** + * Initialize UnixShell class. + */ + private function initShell(): void + { + $this->shell = shell()->cd($this->library->getSourceDir())->initializeEnv($this->library)->appendEnv([ + 'CFLAGS' => "-I{$this->library->getIncludeDir()}", + 'LDFLAGS' => "-L{$this->library->getLibDir()}", + ]); + } +} diff --git a/src/SPC/util/executor/UnixCMakeExecutor.php b/src/SPC/util/executor/UnixCMakeExecutor.php index 4b8ec2e21..b9c7ef589 100644 --- a/src/SPC/util/executor/UnixCMakeExecutor.php +++ b/src/SPC/util/executor/UnixCMakeExecutor.php @@ -58,8 +58,10 @@ public function build(string $build_pos = '..'): void public function optionalLib(string $name, \Closure|string $true_args, string $false_args = ''): static { if ($get = $this->library->getBuilder()->getLib($name)) { + logger()->info("Building library [{$this->library->getName()}] with {$name} support"); $args = $true_args instanceof \Closure ? $true_args($get) : $true_args; } else { + logger()->info("Building library [{$this->library->getName()}] without {$name} support"); $args = $false_args; } $this->addConfigureArgs($args); @@ -137,6 +139,7 @@ private function getDefaultCMakeArgs(): string '-DCMAKE_INSTALL_BINDIR=bin', '-DCMAKE_INSTALL_LIBDIR=lib', '-DCMAKE_INSTALL_INCLUDEDIR=include', + '-DPOSITION_INDEPENDENT_CODE=ON', '-DBUILD_SHARED_LIBS=OFF', "-DCMAKE_TOOLCHAIN_FILE={$this->makeCmakeToolchainFile()}", ]); @@ -192,6 +195,7 @@ private function makeCmakeToolchainFile(): string SET(CMAKE_INSTALL_LIBDIR "lib") set(PKG_CONFIG_EXECUTABLE "{$root}/bin/pkg-config") +list(APPEND PKG_CONFIG_EXECUTABLE "--static") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/src/globals/ext-tests/brotli.php b/src/globals/ext-tests/brotli.php new file mode 100644 index 000000000..bfe9f2592 --- /dev/null +++ b/src/globals/ext-tests/brotli.php @@ -0,0 +1,15 @@ + 'curl', + 'Linux', 'Darwin' => 'dom,mongodb', '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' => '', - 'Windows', 'Darwin' => '', + 'Darwin' => '', + 'Windows' => '', }; -// If you want to test lib-suggests feature with extension, add them below (comma separated, example `libwebp,libavif`). +// If you want to test lib-suggests for all extensions and libraries, set it to true. +$with_suggested_libs = true; + +// If you want to test extra libs for extensions, add them below (comma separated, example `libwebp,libavif`). Unnecessary, when $with_suggested_libs is true. $with_libs = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'brotli,curl,freetype,gmssl,libaom,libavif,libde265,libevent,libheif,libjpeg,librabbitmq,libssh2,libuuid,libuv,libwebp,libxml2,libyaml,libzip,mimalloc,snappy,tidy,zstd', + 'Linux', 'Darwin' => '', 'Windows' => '', }; @@ -168,6 +172,7 @@ function quote2(string $param): string $build_cmd = 'build '; $build_cmd .= quote2($final_extensions) . ' '; $build_cmd .= $shared_cmd; + $build_cmd .= $with_suggested_libs ? '--with-suggested-libs ' : ''; $build_cmd .= $zts ? '--enable-zts ' : ''; $build_cmd .= $no_strip ? '--no-strip ' : ''; $build_cmd .= $upx ? '--with-upx-pack ' : ''; diff --git a/yarn.lock b/yarn.lock index 1e18c1b2d..3e357ce9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,819 +2,969 @@ # yarn lockfile v1 -"@algolia/autocomplete-core@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7" - integrity sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw== - dependencies: - "@algolia/autocomplete-plugin-algolia-insights" "1.9.3" - "@algolia/autocomplete-shared" "1.9.3" - -"@algolia/autocomplete-plugin-algolia-insights@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz#9b7f8641052c8ead6d66c1623d444cbe19dde587" - integrity sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg== - dependencies: - "@algolia/autocomplete-shared" "1.9.3" - -"@algolia/autocomplete-preset-algolia@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz#64cca4a4304cfcad2cf730e83067e0c1b2f485da" - integrity sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA== - dependencies: - "@algolia/autocomplete-shared" "1.9.3" - -"@algolia/autocomplete-shared@1.9.3": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz#2e22e830d36f0a9cf2c0ccd3c7f6d59435b77dfa" - integrity sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ== - -"@algolia/cache-browser-local-storage@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.24.0.tgz#97bc6d067a9fd932b9c922faa6b7fd6e546e1348" - integrity sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww== - dependencies: - "@algolia/cache-common" "4.24.0" - -"@algolia/cache-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.24.0.tgz#81a8d3a82ceb75302abb9b150a52eba9960c9744" - integrity sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g== - -"@algolia/cache-in-memory@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.24.0.tgz#ffcf8872f3a10cb85c4f4641bdffd307933a6e44" - integrity sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w== - dependencies: - "@algolia/cache-common" "4.24.0" - -"@algolia/client-account@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.24.0.tgz#eba7a921d828e7c8c40a32d4add21206c7fe12f1" - integrity sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA== - dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/client-analytics@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.24.0.tgz#9d2576c46a9093a14e668833c505ea697a1a3e30" - integrity sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg== - dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/client-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.24.0.tgz#77c46eee42b9444a1d1c1583a83f7df4398a649d" - integrity sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA== - dependencies: - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/client-personalization@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.24.0.tgz#8b47789fb1cb0f8efbea0f79295b7c5a3850f6ae" - integrity sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w== - dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/client-search@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.24.0.tgz#75e6c02d33ef3e0f34afd9962c085b856fc4a55f" - integrity sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA== - dependencies: - "@algolia/client-common" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/logger-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.24.0.tgz#28d439976019ec0a46ba7a1a739ef493d4ef8123" - integrity sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA== - -"@algolia/logger-console@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.24.0.tgz#c6ff486036cd90b81d07a95aaba04461da7e1c65" - integrity sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg== - dependencies: - "@algolia/logger-common" "4.24.0" - -"@algolia/recommend@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-4.24.0.tgz#8a3f78aea471ee0a4836b78fd2aad4e9abcaaf34" - integrity sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw== - dependencies: - "@algolia/cache-browser-local-storage" "4.24.0" - "@algolia/cache-common" "4.24.0" - "@algolia/cache-in-memory" "4.24.0" - "@algolia/client-common" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/logger-common" "4.24.0" - "@algolia/logger-console" "4.24.0" - "@algolia/requester-browser-xhr" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/requester-node-http" "4.24.0" - "@algolia/transporter" "4.24.0" - -"@algolia/requester-browser-xhr@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.24.0.tgz#313c5edab4ed73a052e75803855833b62dd19c16" - integrity sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA== - dependencies: - "@algolia/requester-common" "4.24.0" - -"@algolia/requester-common@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.24.0.tgz#1c60c198031f48fcdb9e34c4057a3ea987b9a436" - integrity sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA== - -"@algolia/requester-node-http@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.24.0.tgz#4461593714031d02aa7da221c49df675212f482f" - integrity sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw== - dependencies: - "@algolia/requester-common" "4.24.0" - -"@algolia/transporter@4.24.0": - version "4.24.0" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.24.0.tgz#226bb1f8af62430374c1972b2e5c8580ab275102" - integrity sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA== - dependencies: - "@algolia/cache-common" "4.24.0" - "@algolia/logger-common" "4.24.0" - "@algolia/requester-common" "4.24.0" - -"@babel/parser@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" - integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== - -"@docsearch/css@3.6.0", "@docsearch/css@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.6.0.tgz#0e9f56f704b3a34d044d15fd9962ebc1536ba4fb" - integrity sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ== - -"@docsearch/js@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docsearch/js/-/js-3.6.0.tgz#f9e46943449b9092d874944f7a80bcc071004cfb" - integrity sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ== - dependencies: - "@docsearch/react" "3.6.0" +"@algolia/autocomplete-core@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.9.tgz" + integrity sha512-O7BxrpLDPJWWHv/DLA9DRFWs+iY1uOJZkqUwjS5HSZAGcl0hIVCQ97LTLewiZmZ402JYUrun+8NqFP+hCknlbQ== + dependencies: + "@algolia/autocomplete-plugin-algolia-insights" "1.17.9" + "@algolia/autocomplete-shared" "1.17.9" + +"@algolia/autocomplete-plugin-algolia-insights@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.9.tgz" + integrity sha512-u1fEHkCbWF92DBeB/KHeMacsjsoI0wFhjZtlCq2ddZbAehshbZST6Hs0Avkc0s+4UyBGbMDnSuXHLuvRWK5iDQ== + dependencies: + "@algolia/autocomplete-shared" "1.17.9" + +"@algolia/autocomplete-preset-algolia@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.9.tgz" + integrity sha512-Na1OuceSJeg8j7ZWn5ssMu/Ax3amtOwk76u4h5J4eK2Nx2KB5qt0Z4cOapCsxot9VcEN11ADV5aUSlQF4RhGjQ== + dependencies: + "@algolia/autocomplete-shared" "1.17.9" + +"@algolia/autocomplete-shared@1.17.9": + version "1.17.9" + resolved "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.9.tgz" + integrity sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ== + +"@algolia/client-abtesting@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.25.0.tgz" + integrity sha512-1pfQulNUYNf1Tk/svbfjfkLBS36zsuph6m+B6gDkPEivFmso/XnRgwDvjAx80WNtiHnmeNjIXdF7Gos8+OLHqQ== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/client-analytics@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.25.0.tgz" + integrity sha512-AFbG6VDJX/o2vDd9hqncj1B6B4Tulk61mY0pzTtzKClyTDlNP0xaUiEKhl6E7KO9I/x0FJF5tDCm0Hn6v5x18A== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/client-common@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.25.0.tgz" + integrity sha512-il1zS/+Rc6la6RaCdSZ2YbJnkQC6W1wiBO8+SH+DE6CPMWBU6iDVzH0sCKSAtMWl9WBxoN6MhNjGBnCv9Yy2bA== + +"@algolia/client-insights@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.25.0.tgz" + integrity sha512-blbjrUH1siZNfyCGeq0iLQu00w3a4fBXm0WRIM0V8alcAPo7rWjLbMJMrfBtzL9X5ic6wgxVpDADXduGtdrnkw== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/client-personalization@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.25.0.tgz" + integrity sha512-aywoEuu1NxChBcHZ1pWaat0Plw7A8jDMwjgRJ00Mcl7wGlwuPt5dJ/LTNcg3McsEUbs2MBNmw0ignXBw9Tbgow== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/client-query-suggestions@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.25.0.tgz" + integrity sha512-a/W2z6XWKjKjIW1QQQV8PTTj1TXtaKx79uR3NGBdBdGvVdt24KzGAaN7sCr5oP8DW4D3cJt44wp2OY/fZcPAVA== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/client-search@>= 4.9.1 < 6", "@algolia/client-search@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.25.0.tgz" + integrity sha512-9rUYcMIBOrCtYiLX49djyzxqdK9Dya/6Z/8sebPn94BekT+KLOpaZCuc6s0Fpfq7nx5J6YY5LIVFQrtioK9u0g== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/ingestion@1.25.0": + version "1.25.0" + resolved "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.25.0.tgz" + integrity sha512-jJeH/Hk+k17Vkokf02lkfYE4A+EJX+UgnMhTLR/Mb+d1ya5WhE+po8p5a/Nxb6lo9OLCRl6w3Hmk1TX1e9gVbQ== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/monitoring@1.25.0": + version "1.25.0" + resolved "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.25.0.tgz" + integrity sha512-Ls3i1AehJ0C6xaHe7kK9vPmzImOn5zBg7Kzj8tRYIcmCWVyuuFwCIsbuIIz/qzUf1FPSWmw0TZrGeTumk2fqXg== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/recommend@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.25.0.tgz" + integrity sha512-79sMdHpiRLXVxSjgw7Pt4R1aNUHxFLHiaTDnN2MQjHwJ1+o3wSseb55T9VXU4kqy3m7TUme3pyRhLk5ip/S4Mw== + dependencies: + "@algolia/client-common" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +"@algolia/requester-browser-xhr@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.25.0.tgz" + integrity sha512-JLaF23p1SOPBmfEqozUAgKHQrGl3z/Z5RHbggBu6s07QqXXcazEsub5VLonCxGVqTv6a61AAPr8J1G5HgGGjEw== + dependencies: + "@algolia/client-common" "5.25.0" + +"@algolia/requester-fetch@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.25.0.tgz" + integrity sha512-rtzXwqzFi1edkOF6sXxq+HhmRKDy7tz84u0o5t1fXwz0cwx+cjpmxu/6OQKTdOJFS92JUYHsG51Iunie7xbqfQ== + dependencies: + "@algolia/client-common" "5.25.0" + +"@algolia/requester-node-http@5.25.0": + version "5.25.0" + resolved "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.25.0.tgz" + integrity sha512-ZO0UKvDyEFvyeJQX0gmZDQEvhLZ2X10K+ps6hViMo1HgE2V8em00SwNsQ+7E/52a+YiBkVWX61pJJJE44juDMQ== + dependencies: + "@algolia/client-common" "5.25.0" + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + +"@babel/parser@^7.27.2": + version "7.27.3" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.27.3.tgz" + integrity sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw== + dependencies: + "@babel/types" "^7.27.3" + +"@babel/types@^7.27.3": + version "7.27.3" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.27.3.tgz" + integrity sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + +"@docsearch/css@^3.9.0", "@docsearch/css@3.9.0": + version "3.9.0" + resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.9.0.tgz" + integrity sha512-cQbnVbq0rrBwNAKegIac/t6a8nWoUAn8frnkLFW6YARaRmAQr5/Eoe6Ln2fqkUCZ40KpdrKbpSAmgrkviOxuWA== + +"@docsearch/js@^3.9.0": + version "3.9.0" + resolved "https://registry.npmjs.org/@docsearch/js/-/js-3.9.0.tgz" + integrity sha512-4bKHcye6EkLgRE8ze0vcdshmEqxeiJM77M0JXjef7lrYZfSlMunrDOCqyLjiZyo1+c0BhUqA2QpFartIjuHIjw== + dependencies: + "@docsearch/react" "3.9.0" preact "^10.0.0" -"@docsearch/react@3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.6.0.tgz#b4f25228ecb7fc473741aefac592121e86dd2958" - integrity sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w== - dependencies: - "@algolia/autocomplete-core" "1.9.3" - "@algolia/autocomplete-preset-algolia" "1.9.3" - "@docsearch/css" "3.6.0" - algoliasearch "^4.19.1" - -"@esbuild/aix-ppc64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" - integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== - -"@esbuild/android-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" - integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== - -"@esbuild/android-arm@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" - integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== - -"@esbuild/android-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" - integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== - -"@esbuild/darwin-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" - integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== - -"@esbuild/darwin-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" - integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== - -"@esbuild/freebsd-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" - integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== - -"@esbuild/freebsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" - integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== - -"@esbuild/linux-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" - integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== - -"@esbuild/linux-arm@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" - integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== - -"@esbuild/linux-ia32@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" - integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== - -"@esbuild/linux-loong64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" - integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== - -"@esbuild/linux-mips64el@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" - integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== - -"@esbuild/linux-ppc64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" - integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== - -"@esbuild/linux-riscv64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" - integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== - -"@esbuild/linux-s390x@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" - integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== - -"@esbuild/linux-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" - integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== - -"@esbuild/netbsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" - integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== - -"@esbuild/openbsd-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" - integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== - -"@esbuild/sunos-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" - integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== - -"@esbuild/win32-arm64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" - integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== - -"@esbuild/win32-ia32@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" - integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== - -"@esbuild/win32-x64@0.21.5": - version "0.21.5" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" - integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== - -"@jridgewell/sourcemap-codec@^1.4.15": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@rollup/rollup-android-arm-eabi@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz#bbd0e616b2078cd2d68afc9824d1fadb2f2ffd27" - integrity sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ== - -"@rollup/rollup-android-arm64@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz#97255ef6384c5f73f4800c0de91f5f6518e21203" - integrity sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA== - -"@rollup/rollup-darwin-arm64@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz#b6dd74e117510dfe94541646067b0545b42ff096" - integrity sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w== - -"@rollup/rollup-darwin-x64@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz#e07d76de1cec987673e7f3d48ccb8e106d42c05c" - integrity sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA== - -"@rollup/rollup-linux-arm-gnueabihf@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz#9f1a6d218b560c9d75185af4b8bb42f9f24736b8" - integrity sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA== - -"@rollup/rollup-linux-arm-musleabihf@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz#53618b92e6ffb642c7b620e6e528446511330549" - integrity sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A== - -"@rollup/rollup-linux-arm64-gnu@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz#99a7ba5e719d4f053761a698f7b52291cefba577" - integrity sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw== - -"@rollup/rollup-linux-arm64-musl@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz#f53db99a45d9bc00ce94db8a35efa7c3c144a58c" - integrity sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ== - -"@rollup/rollup-linux-powerpc64le-gnu@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz#cbb0837408fe081ce3435cf3730e090febafc9bf" - integrity sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA== - -"@rollup/rollup-linux-riscv64-gnu@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz#8ed09c1d1262ada4c38d791a28ae0fea28b80cc9" - integrity sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg== - -"@rollup/rollup-linux-s390x-gnu@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz#938138d3c8e0c96f022252a28441dcfb17afd7ec" - integrity sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg== - -"@rollup/rollup-linux-x64-gnu@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz#1a7481137a54740bee1ded4ae5752450f155d942" - integrity sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w== - -"@rollup/rollup-linux-x64-musl@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz#f1186afc601ac4f4fc25fac4ca15ecbee3a1874d" - integrity sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg== - -"@rollup/rollup-win32-arm64-msvc@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz#ed6603e93636a96203c6915be4117245c1bd2daf" - integrity sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA== - -"@rollup/rollup-win32-ia32-msvc@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz#14e0b404b1c25ebe6157a15edb9c46959ba74c54" - integrity sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg== - -"@rollup/rollup-win32-x64-msvc@4.18.0": - version "4.18.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz#5d694d345ce36b6ecf657349e03eb87297e68da4" - integrity sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g== - -"@shikijs/core@1.10.0", "@shikijs/core@^1.6.2": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@shikijs/core/-/core-1.10.0.tgz#ec3356ace7cb8b41f6baee0116f036fca85054cc" - integrity sha512-BZcr6FCmPfP6TXaekvujZcnkFmJHZ/Yglu97r/9VjzVndQA56/F4WjUKtJRQUnK59Wi7p/UTAOekMfCJv7jnYg== - -"@shikijs/transformers@^1.6.2": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@shikijs/transformers/-/transformers-1.10.0.tgz#327a8d63d0d0fd5237ee41c4444376723b7c5a2c" - integrity sha512-5Eu/kuJu7/CzAjFlTJkyyPoLTLSVQZ31Ps81cjIeR/3PDJ2RUuX1/R8d0qFziBKToym1LXbNiXoJQq0mg5+Cwg== - dependencies: - shiki "1.10.0" - -"@types/estree@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== - -"@types/linkify-it@^5": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-5.0.0.tgz#21413001973106cda1c3a9b91eedd4ccd5469d76" - integrity sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q== +"@docsearch/react@3.9.0": + version "3.9.0" + resolved "https://registry.npmjs.org/@docsearch/react/-/react-3.9.0.tgz" + integrity sha512-mb5FOZYZIkRQ6s/NWnM98k879vu5pscWqTLubLFBO87igYYT4VzVazh4h5o/zCvTIZgEt3PvsCOMOswOUo9yHQ== + dependencies: + "@algolia/autocomplete-core" "1.17.9" + "@algolia/autocomplete-preset-algolia" "1.17.9" + "@docsearch/css" "3.9.0" + algoliasearch "^5.14.2" + +"@esbuild/darwin-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz" + integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ== -"@types/markdown-it@^14.1.1": - version "14.1.1" - resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.1.tgz#06bafb7a4e3f77b62b1f308acf7df76687887e0b" - integrity sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg== +"@iconify-json/simple-icons@^1.2.32": + version "1.2.36" + resolved "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.36.tgz" + integrity sha512-ZMpVdoW/7hhbt2aHVSvudjH8eSVNNjKkAAjwAQHgiuPUiIfbvNakVin+H9uhUz4N9TbDT/nanzV/4Slb+6dDXw== dependencies: - "@types/linkify-it" "^5" - "@types/mdurl" "^2" + "@iconify/types" "*" -"@types/mdurl@^2": +"@iconify/types@*": version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-2.0.0.tgz#d43878b5b20222682163ae6f897b20447233bdfd" - integrity sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg== - -"@types/web-bluetooth@^0.0.20": - version "0.0.20" - resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597" - integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow== - -"@vitejs/plugin-vue@^5.0.5": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz#e3dc11e427d4b818b7e3202766ad156e3d5e2eaa" - integrity sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ== - -"@vue/compiler-core@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.4.31.tgz#b51a76f1b30e9b5eba0553264dff0f171aedb7c6" - integrity sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg== - dependencies: - "@babel/parser" "^7.24.7" - "@vue/shared" "3.4.31" + resolved "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz" + integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== + +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@rollup/rollup-darwin-arm64@4.41.1": + version "4.41.1" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz" + integrity sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w== + +"@shikijs/core@^3.2.2", "@shikijs/core@3.4.2": + version "3.4.2" + resolved "https://registry.npmjs.org/@shikijs/core/-/core-3.4.2.tgz" + integrity sha512-AG8vnSi1W2pbgR2B911EfGqtLE9c4hQBYkv/x7Z+Kt0VxhgQKcW7UNDVYsu9YxwV6u+OJrvdJrMq6DNWoBjihQ== + dependencies: + "@shikijs/types" "3.4.2" + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + hast-util-to-html "^9.0.5" + +"@shikijs/engine-javascript@3.4.2": + version "3.4.2" + resolved "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-3.4.2.tgz" + integrity sha512-1/adJbSMBOkpScCE/SB6XkjJU17ANln3Wky7lOmrnpl+zBdQ1qXUJg2GXTYVHRq+2j3hd1DesmElTXYDgtfSOQ== + dependencies: + "@shikijs/types" "3.4.2" + "@shikijs/vscode-textmate" "^10.0.2" + oniguruma-to-es "^4.3.3" + +"@shikijs/engine-oniguruma@3.4.2": + version "3.4.2" + resolved "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.4.2.tgz" + integrity sha512-zcZKMnNndgRa3ORja6Iemsr3DrLtkX3cAF7lTJkdMB6v9alhlBsX9uNiCpqofNrXOvpA3h6lHcLJxgCIhVOU5Q== + dependencies: + "@shikijs/types" "3.4.2" + "@shikijs/vscode-textmate" "^10.0.2" + +"@shikijs/langs@3.4.2": + version "3.4.2" + resolved "https://registry.npmjs.org/@shikijs/langs/-/langs-3.4.2.tgz" + integrity sha512-H6azIAM+OXD98yztIfs/KH5H4PU39t+SREhmM8LaNXyUrqj2mx+zVkr8MWYqjceSjDw9I1jawm1WdFqU806rMA== + dependencies: + "@shikijs/types" "3.4.2" + +"@shikijs/themes@3.4.2": + version "3.4.2" + resolved "https://registry.npmjs.org/@shikijs/themes/-/themes-3.4.2.tgz" + integrity sha512-qAEuAQh+brd8Jyej2UDDf+b4V2g1Rm8aBIdvt32XhDPrHvDkEnpb7Kzc9hSuHUxz0Iuflmq7elaDuQAP9bHIhg== + dependencies: + "@shikijs/types" "3.4.2" + +"@shikijs/transformers@^3.2.2": + version "3.4.2" + resolved "https://registry.npmjs.org/@shikijs/transformers/-/transformers-3.4.2.tgz" + integrity sha512-I5baLVi/ynLEOZoWSAMlACHNnG+yw5HDmse0oe+GW6U1u+ULdEB3UHiVWaHoJSSONV7tlcVxuaMy74sREDkSvg== + dependencies: + "@shikijs/core" "3.4.2" + "@shikijs/types" "3.4.2" + +"@shikijs/types@^3.2.2", "@shikijs/types@3.4.2": + version "3.4.2" + resolved "https://registry.npmjs.org/@shikijs/types/-/types-3.4.2.tgz" + integrity sha512-zHC1l7L+eQlDXLnxvM9R91Efh2V4+rN3oMVS2swCBssbj2U/FBwybD1eeLaq8yl/iwT+zih8iUbTBCgGZOYlVg== + dependencies: + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + +"@shikijs/vscode-textmate@^10.0.2": + version "10.0.2" + resolved "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz" + integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg== + +"@types/estree@1.0.7": + version "1.0.7" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz" + integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== + +"@types/hast@^3.0.0", "@types/hast@^3.0.4": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" + +"@types/mdast@^4.0.0": + version "4.0.4" + resolved "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== + dependencies: + "@types/unist" "*" + +"@types/unist@*", "@types/unist@^3.0.0": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz" + integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== + +"@types/web-bluetooth@^0.0.21": + version "0.0.21" + resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz" + integrity sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA== + +"@ungap/structured-clone@^1.0.0": + version "1.3.0" + resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" + integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== + +"@vitejs/plugin-vue@^5.2.3": + version "5.2.4" + resolved "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz" + integrity sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA== + +"@vue/compiler-core@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.16.tgz" + integrity sha512-AOQS2eaQOaaZQoL1u+2rCJIKDruNXVBZSiUD3chnUrsoX5ZTQMaCvXlWNIfxBJuU15r1o7+mpo5223KVtIhAgQ== + dependencies: + "@babel/parser" "^7.27.2" + "@vue/shared" "3.5.16" entities "^4.5.0" estree-walker "^2.0.2" - source-map-js "^1.2.0" - -"@vue/compiler-dom@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz#30961ca847f5d6ad18ffa26236c219f61b195f6b" - integrity sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ== - dependencies: - "@vue/compiler-core" "3.4.31" - "@vue/shared" "3.4.31" - -"@vue/compiler-sfc@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.4.31.tgz#cc6bfccda17df8268cc5440842277f61623c591f" - integrity sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ== - dependencies: - "@babel/parser" "^7.24.7" - "@vue/compiler-core" "3.4.31" - "@vue/compiler-dom" "3.4.31" - "@vue/compiler-ssr" "3.4.31" - "@vue/shared" "3.4.31" + source-map-js "^1.2.1" + +"@vue/compiler-dom@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.16.tgz" + integrity sha512-SSJIhBr/teipXiXjmWOVWLnxjNGo65Oj/8wTEQz0nqwQeP75jWZ0n4sF24Zxoht1cuJoWopwj0J0exYwCJ0dCQ== + dependencies: + "@vue/compiler-core" "3.5.16" + "@vue/shared" "3.5.16" + +"@vue/compiler-sfc@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.16.tgz" + integrity sha512-rQR6VSFNpiinDy/DVUE0vHoIDUF++6p910cgcZoaAUm3POxgNOOdS/xgoll3rNdKYTYPnnbARDCZOyZ+QSe6Pw== + dependencies: + "@babel/parser" "^7.27.2" + "@vue/compiler-core" "3.5.16" + "@vue/compiler-dom" "3.5.16" + "@vue/compiler-ssr" "3.5.16" + "@vue/shared" "3.5.16" estree-walker "^2.0.2" - magic-string "^0.30.10" - postcss "^8.4.38" - source-map-js "^1.2.0" + magic-string "^0.30.17" + postcss "^8.5.3" + source-map-js "^1.2.1" -"@vue/compiler-ssr@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.4.31.tgz#f62ffecdf15bacb883d0099780cf9a1e3654bfc4" - integrity sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA== +"@vue/compiler-ssr@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.16.tgz" + integrity sha512-d2V7kfxbdsjrDSGlJE7my1ZzCXViEcqN6w14DOsDrUCHEA6vbnVCpRFfrc4ryCP/lCKzX2eS1YtnLE/BuC9f/A== dependencies: - "@vue/compiler-dom" "3.4.31" - "@vue/shared" "3.4.31" + "@vue/compiler-dom" "3.5.16" + "@vue/shared" "3.5.16" -"@vue/devtools-api@^7.2.1": - version "7.3.5" - resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.3.5.tgz#afd9f3bca50cfff96aebeea3cc3853fd127267f7" - integrity sha512-BSdBBu5hOIv+gBJC9jzYMh5bC27FQwjWLSb8fVAniqlL9gvsqvK27xTgczMf+hgctlszMYQnRm3bpY/j8vhPqw== +"@vue/devtools-api@^7.7.5": + version "7.7.6" + resolved "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.6.tgz" + integrity sha512-b2Xx0KvXZObePpXPYHvBRRJLDQn5nhKjXh7vUhMEtWxz1AYNFOVIsh5+HLP8xDGL7sy+Q7hXeUxPHB/KgbtsPw== dependencies: - "@vue/devtools-kit" "^7.3.5" + "@vue/devtools-kit" "^7.7.6" -"@vue/devtools-kit@^7.3.5": - version "7.3.5" - resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.3.5.tgz#66669ee94da6c927fc28255477f65aae3f616316" - integrity sha512-wwfi10gJ1HMtjzcd8aIOnzBHlIRqsYDgcDyrKvkeyc0Gbcoe7UrkXRVHZUOtcxxoplHA0PwpT6wFg0uUCmi8Ww== +"@vue/devtools-kit@^7.7.6": + version "7.7.6" + resolved "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.6.tgz" + integrity sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA== dependencies: - "@vue/devtools-shared" "^7.3.5" - birpc "^0.2.17" + "@vue/devtools-shared" "^7.7.6" + birpc "^2.3.0" hookable "^5.5.3" mitt "^3.0.1" perfect-debounce "^1.0.0" speakingurl "^14.0.1" - superjson "^2.2.1" + superjson "^2.2.2" -"@vue/devtools-shared@^7.3.5": - version "7.3.5" - resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.3.5.tgz#4c4020df6d71ab058518a8f3a272fc7f2682c5d8" - integrity sha512-Rqii3VazmWTi67a86rYopi61n5Ved05EybJCwyrfoO9Ok3MaS/4yRFl706ouoISMlyrASJFEzM0/AiDA6w4f9A== +"@vue/devtools-shared@^7.7.6": + version "7.7.6" + resolved "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.6.tgz" + integrity sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA== dependencies: rfdc "^1.4.1" -"@vue/reactivity@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.4.31.tgz#eda80e90c4f9d7659efe1f5ed99c2dfdc9e93d77" - integrity sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q== +"@vue/reactivity@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.16.tgz" + integrity sha512-FG5Q5ee/kxhIm1p2bykPpPwqiUBV3kFySsHEQha5BJvjXdZTUfmya7wP7zC39dFuZAcf/PD5S4Lni55vGLMhvA== dependencies: - "@vue/shared" "3.4.31" + "@vue/shared" "3.5.16" -"@vue/runtime-core@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.4.31.tgz#ad3a41ad76385c0429e3e4dbefb81918494e10cf" - integrity sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw== +"@vue/runtime-core@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.16.tgz" + integrity sha512-bw5Ykq6+JFHYxrQa7Tjr+VSzw7Dj4ldR/udyBZbq73fCdJmyy5MPIFR9IX/M5Qs+TtTjuyUTCnmK3lWWwpAcFQ== dependencies: - "@vue/reactivity" "3.4.31" - "@vue/shared" "3.4.31" + "@vue/reactivity" "3.5.16" + "@vue/shared" "3.5.16" -"@vue/runtime-dom@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.4.31.tgz#bae7ad844f944af33699c73581bc36125bab96ce" - integrity sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw== +"@vue/runtime-dom@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.16.tgz" + integrity sha512-T1qqYJsG2xMGhImRUV9y/RseB9d0eCYZQ4CWca9ztCuiPj/XWNNN+lkNBuzVbia5z4/cgxdL28NoQCvC0Xcfww== dependencies: - "@vue/reactivity" "3.4.31" - "@vue/runtime-core" "3.4.31" - "@vue/shared" "3.4.31" + "@vue/reactivity" "3.5.16" + "@vue/runtime-core" "3.5.16" + "@vue/shared" "3.5.16" csstype "^3.1.3" -"@vue/server-renderer@3.4.31": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.4.31.tgz#bbe990f793c36d62d05bdbbaf142511d53e159fd" - integrity sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA== - dependencies: - "@vue/compiler-ssr" "3.4.31" - "@vue/shared" "3.4.31" - -"@vue/shared@3.4.31", "@vue/shared@^3.4.27": - version "3.4.31" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.4.31.tgz#af9981f57def2c3f080c14bf219314fc0dc808a0" - integrity sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA== - -"@vueuse/core@10.11.0", "@vueuse/core@^10.10.0": - version "10.11.0" - resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.11.0.tgz#b042585a8bf98bb29c177b33999bd0e3fcd9e65d" - integrity sha512-x3sD4Mkm7PJ+pcq3HX8PLPBadXCAlSDR/waK87dz0gQE+qJnaaFhc/dZVfJz+IUYzTMVGum2QlR7ImiJQN4s6g== - dependencies: - "@types/web-bluetooth" "^0.0.20" - "@vueuse/metadata" "10.11.0" - "@vueuse/shared" "10.11.0" - vue-demi ">=0.14.8" - -"@vueuse/integrations@^10.10.0": - version "10.11.0" - resolved "https://registry.yarnpkg.com/@vueuse/integrations/-/integrations-10.11.0.tgz#ce2746587172af9ab8faa713f42e619609ed0de1" - integrity sha512-Pp6MtWEIr+NDOccWd8j59Kpjy5YDXogXI61Kb1JxvSfVBO8NzFQkmrKmSZz47i+ZqHnIzxaT38L358yDHTncZg== - dependencies: - "@vueuse/core" "10.11.0" - "@vueuse/shared" "10.11.0" - vue-demi ">=0.14.8" - -"@vueuse/metadata@10.11.0": - version "10.11.0" - resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.11.0.tgz#27be47cf115ee98e947a1bfcd0b1b5b35d785fb6" - integrity sha512-kQX7l6l8dVWNqlqyN3ePW3KmjCQO3ZMgXuBMddIu83CmucrsBfXlH+JoviYyRBws/yLTQO8g3Pbw+bdIoVm4oQ== - -"@vueuse/shared@10.11.0": - version "10.11.0" - resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.11.0.tgz#be09262b2c5857069ed3dadd1680f22c4cb6f984" - integrity sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A== - dependencies: - vue-demi ">=0.14.8" - -algoliasearch@^4.19.1: - version "4.24.0" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.24.0.tgz#b953b3e2309ef8f25da9de311b95b994ac918275" - integrity sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g== - dependencies: - "@algolia/cache-browser-local-storage" "4.24.0" - "@algolia/cache-common" "4.24.0" - "@algolia/cache-in-memory" "4.24.0" - "@algolia/client-account" "4.24.0" - "@algolia/client-analytics" "4.24.0" - "@algolia/client-common" "4.24.0" - "@algolia/client-personalization" "4.24.0" - "@algolia/client-search" "4.24.0" - "@algolia/logger-common" "4.24.0" - "@algolia/logger-console" "4.24.0" - "@algolia/recommend" "4.24.0" - "@algolia/requester-browser-xhr" "4.24.0" - "@algolia/requester-common" "4.24.0" - "@algolia/requester-node-http" "4.24.0" - "@algolia/transporter" "4.24.0" - -birpc@^0.2.17: - version "0.2.17" - resolved "https://registry.yarnpkg.com/birpc/-/birpc-0.2.17.tgz#d0bdb90d4d063061156637f03b7b0adea1779734" - integrity sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg== +"@vue/server-renderer@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.16.tgz" + integrity sha512-BrX0qLiv/WugguGsnQUJiYOE0Fe5mZTwi6b7X/ybGB0vfrPH9z0gD/Y6WOR1sGCgX4gc25L1RYS5eYQKDMoNIg== + dependencies: + "@vue/compiler-ssr" "3.5.16" + "@vue/shared" "3.5.16" + +"@vue/shared@^3.5.13", "@vue/shared@3.5.16": + version "3.5.16" + resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.5.16.tgz" + integrity sha512-c/0fWy3Jw6Z8L9FmTyYfkpM5zklnqqa9+a6dz3DvONRKW2NEbh46BP0FHuLFSWi2TnQEtp91Z6zOWNrU6QiyPg== + +"@vueuse/core@^13.1.0", "@vueuse/core@13.3.0": + version "13.3.0" + resolved "https://registry.npmjs.org/@vueuse/core/-/core-13.3.0.tgz" + integrity sha512-uYRz5oEfebHCoRhK4moXFM3NSCd5vu2XMLOq/Riz5FdqZMy2RvBtazdtL3gEcmDyqkztDe9ZP/zymObMIbiYSg== + dependencies: + "@types/web-bluetooth" "^0.0.21" + "@vueuse/metadata" "13.3.0" + "@vueuse/shared" "13.3.0" + +"@vueuse/integrations@^13.1.0": + version "13.3.0" + resolved "https://registry.npmjs.org/@vueuse/integrations/-/integrations-13.3.0.tgz" + integrity sha512-h5mGRYPbiTZTFP/AKELLPGnUDBly7z7Qd1pgEQlT3ItQ0NlZM0vB+8SOQycpSBOBlgg72Zgw+mi2r+4O/G8RuQ== + dependencies: + "@vueuse/core" "13.3.0" + "@vueuse/shared" "13.3.0" + +"@vueuse/metadata@13.3.0": + version "13.3.0" + resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-13.3.0.tgz" + integrity sha512-42IzJIOYCKIb0Yjv1JfaKpx8JlCiTmtCWrPxt7Ja6Wzoq0h79+YVXmBV03N966KEmDEESTbp5R/qO3AB5BDnGw== + +"@vueuse/shared@13.3.0": + version "13.3.0" + resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-13.3.0.tgz" + integrity sha512-L1QKsF0Eg9tiZSFXTgodYnu0Rsa2P0En2LuLrIs/jgrkyiDuJSsPZK+tx+wU0mMsYHUYEjNsuE41uqqkuR8VhA== + +algoliasearch@^5.14.2, "algoliasearch@>= 4.9.1 < 6": + version "5.25.0" + resolved "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.25.0.tgz" + integrity sha512-n73BVorL4HIwKlfJKb4SEzAYkR3Buwfwbh+MYxg2mloFph2fFGV58E90QTzdbfzWrLn4HE5Czx/WTjI8fcHaMg== + dependencies: + "@algolia/client-abtesting" "5.25.0" + "@algolia/client-analytics" "5.25.0" + "@algolia/client-common" "5.25.0" + "@algolia/client-insights" "5.25.0" + "@algolia/client-personalization" "5.25.0" + "@algolia/client-query-suggestions" "5.25.0" + "@algolia/client-search" "5.25.0" + "@algolia/ingestion" "1.25.0" + "@algolia/monitoring" "1.25.0" + "@algolia/recommend" "5.25.0" + "@algolia/requester-browser-xhr" "5.25.0" + "@algolia/requester-fetch" "5.25.0" + "@algolia/requester-node-http" "5.25.0" + +birpc@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/birpc/-/birpc-2.3.0.tgz" + integrity sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g== + +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== copy-anything@^3.0.2: version "3.0.5" - resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-3.0.5.tgz#2d92dce8c498f790fa7ad16b01a1ae5a45b020a0" + resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz" integrity sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w== dependencies: is-what "^4.1.8" csstype@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== +dequal@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +devlop@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== + dependencies: + dequal "^2.0.0" + entities@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== -esbuild@^0.21.3: - version "0.21.5" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" - integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== +esbuild@^0.25.0: + version "0.25.5" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz" + integrity sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ== optionalDependencies: - "@esbuild/aix-ppc64" "0.21.5" - "@esbuild/android-arm" "0.21.5" - "@esbuild/android-arm64" "0.21.5" - "@esbuild/android-x64" "0.21.5" - "@esbuild/darwin-arm64" "0.21.5" - "@esbuild/darwin-x64" "0.21.5" - "@esbuild/freebsd-arm64" "0.21.5" - "@esbuild/freebsd-x64" "0.21.5" - "@esbuild/linux-arm" "0.21.5" - "@esbuild/linux-arm64" "0.21.5" - "@esbuild/linux-ia32" "0.21.5" - "@esbuild/linux-loong64" "0.21.5" - "@esbuild/linux-mips64el" "0.21.5" - "@esbuild/linux-ppc64" "0.21.5" - "@esbuild/linux-riscv64" "0.21.5" - "@esbuild/linux-s390x" "0.21.5" - "@esbuild/linux-x64" "0.21.5" - "@esbuild/netbsd-x64" "0.21.5" - "@esbuild/openbsd-x64" "0.21.5" - "@esbuild/sunos-x64" "0.21.5" - "@esbuild/win32-arm64" "0.21.5" - "@esbuild/win32-ia32" "0.21.5" - "@esbuild/win32-x64" "0.21.5" + "@esbuild/aix-ppc64" "0.25.5" + "@esbuild/android-arm" "0.25.5" + "@esbuild/android-arm64" "0.25.5" + "@esbuild/android-x64" "0.25.5" + "@esbuild/darwin-arm64" "0.25.5" + "@esbuild/darwin-x64" "0.25.5" + "@esbuild/freebsd-arm64" "0.25.5" + "@esbuild/freebsd-x64" "0.25.5" + "@esbuild/linux-arm" "0.25.5" + "@esbuild/linux-arm64" "0.25.5" + "@esbuild/linux-ia32" "0.25.5" + "@esbuild/linux-loong64" "0.25.5" + "@esbuild/linux-mips64el" "0.25.5" + "@esbuild/linux-ppc64" "0.25.5" + "@esbuild/linux-riscv64" "0.25.5" + "@esbuild/linux-s390x" "0.25.5" + "@esbuild/linux-x64" "0.25.5" + "@esbuild/netbsd-arm64" "0.25.5" + "@esbuild/netbsd-x64" "0.25.5" + "@esbuild/openbsd-arm64" "0.25.5" + "@esbuild/openbsd-x64" "0.25.5" + "@esbuild/sunos-x64" "0.25.5" + "@esbuild/win32-arm64" "0.25.5" + "@esbuild/win32-ia32" "0.25.5" + "@esbuild/win32-x64" "0.25.5" estree-walker@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== -focus-trap@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-7.5.4.tgz#6c4e342fe1dae6add9c2aa332a6e7a0bbd495ba2" - integrity sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w== +fdir@^6.4.4: + version "6.4.5" + resolved "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz" + integrity sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw== + +focus-trap@^7, focus-trap@^7.6.4: + version "7.6.5" + resolved "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.5.tgz" + integrity sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg== dependencies: tabbable "^6.2.0" fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== +hast-util-to-html@^9.0.5: + version "9.0.5" + resolved "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz" + integrity sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^3.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + property-information "^7.0.0" + space-separated-tokens "^2.0.0" + stringify-entities "^4.0.0" + zwitch "^2.0.4" + +hast-util-whitespace@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz" + integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== + dependencies: + "@types/hast" "^3.0.0" + hookable@^5.5.3: version "5.5.3" - resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d" + resolved "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz" integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ== +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + is-what@^4.1.8: version "4.1.16" - resolved "https://registry.yarnpkg.com/is-what/-/is-what-4.1.16.tgz#1ad860a19da8b4895ad5495da3182ce2acdd7a6f" + resolved "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz" integrity sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A== -magic-string@^0.30.10: - version "0.30.10" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e" - integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ== +magic-string@^0.30.17: + version "0.30.17" + resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" + "@jridgewell/sourcemap-codec" "^1.5.0" mark.js@8.11.1: version "8.11.1" - resolved "https://registry.yarnpkg.com/mark.js/-/mark.js-8.11.1.tgz#180f1f9ebef8b0e638e4166ad52db879beb2ffc5" + resolved "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz" integrity sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ== -minisearch@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/minisearch/-/minisearch-6.3.0.tgz#985a2f1ca3c73c2d65af94f0616bfe57164b0b6b" - integrity sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ== +mdast-util-to-hast@^13.0.0: + version "13.2.0" + resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz" + integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +micromark-util-character@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz" + integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-encode@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz" + integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz" + integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-symbol@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz" + integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q== + +micromark-util-types@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz" + integrity sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA== + +minisearch@^7.1.2: + version "7.1.2" + resolved "https://registry.npmjs.org/minisearch/-/minisearch-7.1.2.tgz" + integrity sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA== mitt@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" + resolved "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz" integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== -nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + +oniguruma-parser@^0.12.1: + version "0.12.1" + resolved "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.1.tgz" + integrity sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w== + +oniguruma-to-es@^4.3.3: + version "4.3.3" + resolved "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.3.tgz" + integrity sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg== + dependencies: + oniguruma-parser "^0.12.1" + regex "^6.0.1" + regex-recursion "^6.0.2" perfect-debounce@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a" + resolved "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz" integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA== -picocolors@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" - integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +"picomatch@^3 || ^4", picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== -postcss@^8.4.38: - version "8.4.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.39.tgz#aa3c94998b61d3a9c259efa51db4b392e1bde0e3" - integrity sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw== +postcss@^8, postcss@^8.5.3: + version "8.5.4" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz" + integrity sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w== dependencies: - nanoid "^3.3.7" - picocolors "^1.0.1" - source-map-js "^1.2.0" + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" preact@^10.0.0: version "10.22.0" - resolved "https://registry.yarnpkg.com/preact/-/preact-10.22.0.tgz#a50f38006ae438d255e2631cbdaf7488e6dd4e16" + resolved "https://registry.npmjs.org/preact/-/preact-10.22.0.tgz" integrity sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw== +property-information@^7.0.0: + version "7.1.0" + resolved "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz" + integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== + +regex-recursion@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz" + integrity sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg== + dependencies: + regex-utilities "^2.3.0" + +regex-utilities@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz" + integrity sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng== + +regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz" + integrity sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA== + dependencies: + regex-utilities "^2.3.0" + rfdc@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== -rollup@^4.13.0: - version "4.18.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.18.0.tgz#497f60f0c5308e4602cf41136339fbf87d5f5dda" - integrity sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg== +rollup@^4.34.9: + version "4.41.1" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz" + integrity sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw== dependencies: - "@types/estree" "1.0.5" + "@types/estree" "1.0.7" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.18.0" - "@rollup/rollup-android-arm64" "4.18.0" - "@rollup/rollup-darwin-arm64" "4.18.0" - "@rollup/rollup-darwin-x64" "4.18.0" - "@rollup/rollup-linux-arm-gnueabihf" "4.18.0" - "@rollup/rollup-linux-arm-musleabihf" "4.18.0" - "@rollup/rollup-linux-arm64-gnu" "4.18.0" - "@rollup/rollup-linux-arm64-musl" "4.18.0" - "@rollup/rollup-linux-powerpc64le-gnu" "4.18.0" - "@rollup/rollup-linux-riscv64-gnu" "4.18.0" - "@rollup/rollup-linux-s390x-gnu" "4.18.0" - "@rollup/rollup-linux-x64-gnu" "4.18.0" - "@rollup/rollup-linux-x64-musl" "4.18.0" - "@rollup/rollup-win32-arm64-msvc" "4.18.0" - "@rollup/rollup-win32-ia32-msvc" "4.18.0" - "@rollup/rollup-win32-x64-msvc" "4.18.0" + "@rollup/rollup-android-arm-eabi" "4.41.1" + "@rollup/rollup-android-arm64" "4.41.1" + "@rollup/rollup-darwin-arm64" "4.41.1" + "@rollup/rollup-darwin-x64" "4.41.1" + "@rollup/rollup-freebsd-arm64" "4.41.1" + "@rollup/rollup-freebsd-x64" "4.41.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.41.1" + "@rollup/rollup-linux-arm-musleabihf" "4.41.1" + "@rollup/rollup-linux-arm64-gnu" "4.41.1" + "@rollup/rollup-linux-arm64-musl" "4.41.1" + "@rollup/rollup-linux-loongarch64-gnu" "4.41.1" + "@rollup/rollup-linux-powerpc64le-gnu" "4.41.1" + "@rollup/rollup-linux-riscv64-gnu" "4.41.1" + "@rollup/rollup-linux-riscv64-musl" "4.41.1" + "@rollup/rollup-linux-s390x-gnu" "4.41.1" + "@rollup/rollup-linux-x64-gnu" "4.41.1" + "@rollup/rollup-linux-x64-musl" "4.41.1" + "@rollup/rollup-win32-arm64-msvc" "4.41.1" + "@rollup/rollup-win32-ia32-msvc" "4.41.1" + "@rollup/rollup-win32-x64-msvc" "4.41.1" fsevents "~2.3.2" -shiki@1.10.0, shiki@^1.6.2: - version "1.10.0" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-1.10.0.tgz#304ab080a12458abc78eb0cb83eb0f7ace546215" - integrity sha512-YD2sXQ+TMD/F9BimV9Jn0wj35pqOvywvOG/3PB6hGHyGKlM7TJ9tyJ02jOb2kF8F0HfJwKNYrh3sW7jEcuRlXA== - dependencies: - "@shikijs/core" "1.10.0" - -source-map-js@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" - integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== +"search-insights@>= 1 < 3": + version "2.17.3" + resolved "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz" + integrity sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ== + +shiki@^3.2.2: + version "3.4.2" + resolved "https://registry.npmjs.org/shiki/-/shiki-3.4.2.tgz" + integrity sha512-wuxzZzQG8kvZndD7nustrNFIKYJ1jJoWIPaBpVe2+KHSvtzMi4SBjOxrigs8qeqce/l3U0cwiC+VAkLKSunHQQ== + dependencies: + "@shikijs/core" "3.4.2" + "@shikijs/engine-javascript" "3.4.2" + "@shikijs/engine-oniguruma" "3.4.2" + "@shikijs/langs" "3.4.2" + "@shikijs/themes" "3.4.2" + "@shikijs/types" "3.4.2" + "@shikijs/vscode-textmate" "^10.0.2" + "@types/hast" "^3.0.4" + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== speakingurl@^14.0.1: version "14.0.1" - resolved "https://registry.yarnpkg.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53" + resolved "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz" integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ== -superjson@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/superjson/-/superjson-2.2.1.tgz#9377a7fa80fedb10c851c9dbffd942d4bcf79733" - integrity sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA== +stringify-entities@^4.0.0: + version "4.0.4" + resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz" + integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + +superjson@^2.2.2: + version "2.2.2" + resolved "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz" + integrity sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q== dependencies: copy-anything "^3.0.2" tabbable@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" + resolved "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz" integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== -vite@^5.2.12: - version "5.3.2" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.3.2.tgz#2f0a8531c71060467ed3e0a205a203f269b6d9c8" - integrity sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA== +tinyglobby@^0.2.13: + version "0.2.14" + resolved "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz" + integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== + dependencies: + fdir "^6.4.4" + picomatch "^4.0.2" + +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== dependencies: - esbuild "^0.21.3" - postcss "^8.4.38" - rollup "^4.13.0" + "@types/unist" "^3.0.0" + +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + +vfile-message@^4.0.0: + version "4.0.2" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz" + integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + +vfile@^6.0.0: + version "6.0.3" + resolved "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz" + integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== + dependencies: + "@types/unist" "^3.0.0" + vfile-message "^4.0.0" + +"vite@^5.0.0 || ^6.0.0", vite@^6.3.2: + version "6.3.5" + resolved "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz" + integrity sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ== + dependencies: + esbuild "^0.25.0" + fdir "^6.4.4" + picomatch "^4.0.2" + postcss "^8.5.3" + rollup "^4.34.9" + tinyglobby "^0.2.13" optionalDependencies: fsevents "~2.3.3" -vitepress@^1.0.0-rc.35: - version "1.2.3" - resolved "https://registry.yarnpkg.com/vitepress/-/vitepress-1.2.3.tgz#a507d2f5e86c1fbcdb5ec2212f1db4828504df34" - integrity sha512-GvEsrEeNLiDE1+fuwDAYJCYLNZDAna+EtnXlPajhv/MYeTjbNK6Bvyg6NoTdO1sbwuQJ0vuJR99bOlH53bo6lg== - dependencies: - "@docsearch/css" "^3.6.0" - "@docsearch/js" "^3.6.0" - "@shikijs/core" "^1.6.2" - "@shikijs/transformers" "^1.6.2" - "@types/markdown-it" "^14.1.1" - "@vitejs/plugin-vue" "^5.0.5" - "@vue/devtools-api" "^7.2.1" - "@vue/shared" "^3.4.27" - "@vueuse/core" "^10.10.0" - "@vueuse/integrations" "^10.10.0" - focus-trap "^7.5.4" +vitepress@^2.0.0-alpha.5: + version "2.0.0-alpha.5" + resolved "https://registry.npmjs.org/vitepress/-/vitepress-2.0.0-alpha.5.tgz" + integrity sha512-fhuGpJ4CETS/lrAHjKu3m88HwesZvAjZLFeIRr9Jejmewyogn1tm2L6lsVg7PWxPmOGoMfihzl3+L6jg6hrTnA== + dependencies: + "@docsearch/css" "^3.9.0" + "@docsearch/js" "^3.9.0" + "@iconify-json/simple-icons" "^1.2.32" + "@shikijs/core" "^3.2.2" + "@shikijs/transformers" "^3.2.2" + "@shikijs/types" "^3.2.2" + "@vitejs/plugin-vue" "^5.2.3" + "@vue/devtools-api" "^7.7.5" + "@vue/shared" "^3.5.13" + "@vueuse/core" "^13.1.0" + "@vueuse/integrations" "^13.1.0" + focus-trap "^7.6.4" mark.js "8.11.1" - minisearch "^6.3.0" - shiki "^1.6.2" - vite "^5.2.12" - vue "^3.4.27" - -vue-demi@>=0.14.8: - version "0.14.8" - resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.8.tgz#00335e9317b45e4a68d3528aaf58e0cec3d5640a" - integrity sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q== - -vue@^3.2.47, vue@^3.4.27: - version "3.4.31" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.4.31.tgz#83a3c4dab8302b0e974b0d4b92a2f6a6378ae797" - integrity sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ== - dependencies: - "@vue/compiler-dom" "3.4.31" - "@vue/compiler-sfc" "3.4.31" - "@vue/runtime-dom" "3.4.31" - "@vue/server-renderer" "3.4.31" - "@vue/shared" "3.4.31" + minisearch "^7.1.2" + shiki "^3.2.2" + vite "^6.3.2" + vue "^3.5.13" + +vue@^3.2.25, vue@^3.2.47, vue@^3.5.0, vue@^3.5.13, vue@3.5.16: + version "3.5.16" + resolved "https://registry.npmjs.org/vue/-/vue-3.5.16.tgz" + integrity sha512-rjOV2ecxMd5SiAmof2xzh2WxntRcigkX/He4YFJ6WdRvVUrbt6DxC1Iujh10XLl8xCDRDtGKMeO3D+pRQ1PP9w== + dependencies: + "@vue/compiler-dom" "3.5.16" + "@vue/compiler-sfc" "3.5.16" + "@vue/runtime-dom" "3.5.16" + "@vue/server-renderer" "3.5.16" + "@vue/shared" "3.5.16" + +zwitch@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==