diff --git a/config/lib.json b/config/lib.json index 26910ec0..34104af1 100644 --- a/config/lib.json +++ b/config/lib.json @@ -36,9 +36,9 @@ "brotli": { "source": "brotli", "static-libs-unix": [ + "libbrotlicommon.a", "libbrotlidec.a", - "libbrotlienc.a", - "libbrotlicommon.a" + "libbrotlienc.a" ], "static-libs-windows": [ "brotlicommon.lib", @@ -200,11 +200,10 @@ "icu": { "source": "icu", "cpp-library": true, - "static-libs-unix": [ - "libicui18n.a", - "libicuio.a", - "libicuuc.a", - "libicudata.a" + "pkg-configs": [ + "icu-uc", + "icu-i18n", + "icu-io" ] }, "icu-static-win": { diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 8d07f2e5..13fb9b5a 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -183,8 +183,7 @@ abstract class LibraryBase } } if (!$this->isLibraryInstalled()) { - $this->tryInstall($lock, true); - return LIB_STATUS_OK; + return $this->tryInstall($lock, true); } return LIB_STATUS_ALREADY; } diff --git a/src/SPC/builder/freebsd/library/curl.php b/src/SPC/builder/freebsd/library/curl.php index 4eeab20d..2cad3ee7 100644 --- a/src/SPC/builder/freebsd/library/curl.php +++ b/src/SPC/builder/freebsd/library/curl.php @@ -9,13 +9,4 @@ class curl extends BSDLibraryBase use \SPC\builder\unix\library\curl; public const NAME = 'curl'; - - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string - { - $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'); - } - return $libs; - } } diff --git a/src/SPC/builder/linux/library/curl.php b/src/SPC/builder/linux/library/curl.php index f382773f..20ed10f2 100644 --- a/src/SPC/builder/linux/library/curl.php +++ b/src/SPC/builder/linux/library/curl.php @@ -9,13 +9,4 @@ class curl extends LinuxLibraryBase use \SPC\builder\unix\library\curl; public const NAME = 'curl'; - - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string - { - $libs = parent::getStaticLibFiles($style, $recursive, $include_self); - if ($this->builder->getLib('openssl')) { - $libs .= ' -ldl -lpthread'; - } - return $libs; - } } diff --git a/src/SPC/builder/linux/library/icu.php b/src/SPC/builder/linux/library/icu.php index c911a2fe..7b8bcf8e 100644 --- a/src/SPC/builder/linux/library/icu.php +++ b/src/SPC/builder/linux/library/icu.php @@ -38,7 +38,7 @@ class icu extends LinuxLibraryBase ->exec("make -j{$this->builder->concurrency}") ->exec('make install'); - $this->patchPkgconfPrefix(['icu-i18n.pc', 'icu-io.pc', 'icu-uc.pc'], PKGCONF_PATCH_PREFIX); + $this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX); FileSystem::removeDir(BUILD_LIB_PATH . '/icu'); } } diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index 252eb47f..1030cfb8 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -91,13 +91,4 @@ class openssl extends LinuxLibraryBase FileSystem::replaceFileRegex(BUILD_LIB_PATH . '/pkgconfig/libcrypto.pc', '/Libs.private:.*/m', 'Libs.private: ${libdir}/libz.a'); 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, bool $include_self = true): string - { - $libFiles = parent::getStaticLibFiles($style, $recursive, $include_self); - if (!str_contains('-ldl -lpthread', $libFiles)) { - $libFiles .= ' -ldl -lpthread'; - } - return $libFiles; - } } diff --git a/src/SPC/builder/macos/library/icu.php b/src/SPC/builder/macos/library/icu.php index d49f43f8..ebe1946f 100644 --- a/src/SPC/builder/macos/library/icu.php +++ b/src/SPC/builder/macos/library/icu.php @@ -21,7 +21,7 @@ class icu extends MacOSLibraryBase ->exec("make -j{$this->builder->concurrency}") ->exec('make install'); - $this->patchPkgconfPrefix(['icu-i18n.pc', 'icu-io.pc', 'icu-uc.pc'], PKGCONF_PATCH_PREFIX); + $this->patchPkgconfPrefix(patch_option: PKGCONF_PATCH_PREFIX); FileSystem::removeDir(BUILD_LIB_PATH . '/icu'); } } diff --git a/src/SPC/builder/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index e98a6f3a..21ed4a6d 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -4,11 +4,12 @@ declare(strict_types=1); namespace SPC\builder\traits; -use SPC\builder\LibraryBase; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; +use SPC\store\Config; use SPC\store\FileSystem; +use SPC\util\SPCConfigUtil; trait UnixLibraryTrait { @@ -17,44 +18,13 @@ trait UnixLibraryTrait * @throws FileSystemException * @throws WrongUsageException */ - public function getStaticLibFiles(string $style = 'autoconf', bool $recursive = true, bool $include_self = true): string + public function getStaticLibFiles(bool $include_self = true): string { $libs = $include_self ? [$this] : []; - if ($recursive) { - array_unshift($libs, ...array_values($this->getDependencies(recursive: true))); - } - - $sep = match ($style) { - 'autoconf' => ' ', - 'cmake' => ';', - default => throw new RuntimeException('style only support autoconf and cmake'), - }; - $ret = []; - /** @var LibraryBase $lib */ - foreach ($libs as $lib) { - $libFiles = []; - foreach ($lib->getStaticLibs() as $name) { - $name = str_replace(' ', '\ ', FileSystem::convertPath(BUILD_LIB_PATH . "/{$name}")); - $name = str_replace('"', '\"', $name); - $libFiles[] = $name; - } - array_unshift($ret, implode($sep, $libFiles)); - } - return implode($sep, $ret); - } - - /** - * @throws FileSystemException - * @throws RuntimeException - * @throws WrongUsageException - */ - public function makeAutoconfEnv(?string $prefix = null): string - { - if ($prefix === null) { - $prefix = str_replace('-', '_', strtoupper(static::NAME)); - } - return $prefix . '_CFLAGS="-I' . BUILD_INCLUDE_PATH . '" ' . - $prefix . '_LIBS="' . $this->getStaticLibFiles() . '"'; + array_unshift($libs, ...array_values($this->getDependencies(recursive: true))); + $config = new SPCConfigUtil($this->builder, options: ['libs_only_deps' => true, 'absolute_libs' => true]); + $res = $config->config(libraries: array_map(fn ($x) => $x->getName(), $libs)); + return $res['libs']; } /** @@ -64,9 +34,12 @@ trait UnixLibraryTrait * @throws FileSystemException * @throws RuntimeException */ - public function patchPkgconfPrefix(array $files, int $patch_option = PKGCONF_PATCH_ALL, ?array $custom_replace = null): void + public function patchPkgconfPrefix(array $files = [], int $patch_option = PKGCONF_PATCH_ALL, ?array $custom_replace = null): void { logger()->info('Patching library [' . static::NAME . '] pkgconfig'); + if ($files === [] && ($conf_pc = Config::getLib(static::NAME, 'pkg-configs', [])) !== []) { + $files = array_map(fn ($x) => "{$x}.pc", $conf_pc); + } foreach ($files as $name) { $realpath = realpath(BUILD_ROOT_PATH . '/lib/pkgconfig/' . $name); if ($realpath === false) { diff --git a/src/SPC/builder/unix/UnixBuilderBase.php b/src/SPC/builder/unix/UnixBuilderBase.php index f0e4e169..9ba6f2fd 100644 --- a/src/SPC/builder/unix/UnixBuilderBase.php +++ b/src/SPC/builder/unix/UnixBuilderBase.php @@ -5,9 +5,6 @@ declare(strict_types=1); namespace SPC\builder\unix; use SPC\builder\BuilderBase; -use SPC\builder\freebsd\library\BSDLibraryBase; -use SPC\builder\linux\library\LinuxLibraryBase; -use SPC\builder\macos\library\MacOSLibraryBase; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -27,85 +24,6 @@ abstract class UnixBuilderBase extends BuilderBase /** @var string C++ flags */ public string $arch_cxx_flags; - /** - * @throws WrongUsageException - * @throws FileSystemException - */ - public function getAllStaticLibFiles(): array - { - $libs = []; - - // reorder libs - foreach ($this->libs as $lib) { - foreach ($lib->getDependencies() as $dep) { - $libs[] = $dep; - } - $libs[] = $lib; - } - - $libFiles = []; - $libNames = []; - // merge libs - foreach ($libs as $lib) { - if (!in_array($lib::NAME, $libNames, true)) { - $libNames[] = $lib::NAME; - array_unshift($libFiles, ...$lib->getStaticLibs()); - } - } - return array_map(fn ($x) => realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles); - } - - /** - * Generate configure flags - */ - public function makeAutoconfFlags(int $flag = AUTOCONF_ALL): string - { - $extra = ''; - // TODO: add auto pkg-config support - if (($flag & AUTOCONF_LIBS) === AUTOCONF_LIBS) { - $extra .= 'LIBS="' . BUILD_LIB_PATH . '" '; - } - if (($flag & AUTOCONF_CFLAGS) === AUTOCONF_CFLAGS) { - $extra .= 'CFLAGS="-I' . BUILD_INCLUDE_PATH . '" '; - } - if (($flag & AUTOCONF_CPPFLAGS) === AUTOCONF_CPPFLAGS) { - $extra .= 'CPPFLAGS="-I' . BUILD_INCLUDE_PATH . '" '; - } - if (($flag & AUTOCONF_LDFLAGS) === AUTOCONF_LDFLAGS) { - $extra .= 'LDFLAGS="-L' . BUILD_LIB_PATH . '" '; - } - return $extra; - } - - /** - * @throws FileSystemException - * @throws RuntimeException - * @throws WrongUsageException - */ - public function makeAutoconfArgs(string $name, array $libSpecs): string - { - $ret = ''; - foreach ($libSpecs as $libName => $arr) { - $lib = $this->getLib($libName); - if ($lib === null && str_starts_with($libName, 'lib')) { - $lib = $this->getLib(substr($libName, 3)); - } - - $arr = $arr ?? []; - - $disableArgs = $arr[0] ?? null; - $prefix = $arr[1] ?? null; - if ($lib instanceof LinuxLibraryBase || $lib instanceof MacOSLibraryBase || $lib instanceof BSDLibraryBase) { - logger()->info("{$name} \033[32;1mwith\033[0;1m {$libName} support"); - $ret .= "--with-{$libName}=yes " . $lib->makeAutoconfEnv($prefix) . ' '; - } else { - logger()->info("{$name} \033[31;1mwithout\033[0;1m {$libName} support"); - $ret .= ($disableArgs ?? "--with-{$libName}=no") . ' '; - } - } - return rtrim($ret); - } - public function proveLibs(array $sorted_libraries): void { // search all supported libs diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index aabc277d..63500566 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -24,7 +24,7 @@ trait libxslt ->appendEnv([ 'CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}", - 'LIBS' => "{$static_libs} -lstdc++", + 'LIBS' => "{$static_libs}", ]) ->addConfigureArgs( '--without-python', @@ -41,7 +41,7 @@ trait libxslt } $ac->configure()->make(); - $this->patchPkgconfPrefix(['libexslt.pc']); + $this->patchPkgconfPrefix(['libxslt.pc']); $this->patchLaDependencyPrefix(); shell()->cd(BUILD_LIB_PATH) ->exec("ar -t libxslt.a | grep '\\.a$' | xargs -n1 ar d libxslt.a") diff --git a/src/SPC/builder/unix/library/ngtcp2.php b/src/SPC/builder/unix/library/ngtcp2.php index df29fba3..644bab4e 100644 --- a/src/SPC/builder/unix/library/ngtcp2.php +++ b/src/SPC/builder/unix/library/ngtcp2.php @@ -21,8 +21,6 @@ trait ngtcp2 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)) @@ -30,12 +28,8 @@ trait ngtcp2 ->optionalLib( 'brotli', fn ($lib) => implode(' ', [ - '--with-brotlidec=yes', - "LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", - "LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"", + '--with-libbrotlidec=yes', '--with-libbrotlienc=yes', - "LIBBROTLIENC_CFLAGS=\"-I{$lib->getIncludeDir()}\"", - "LIBBROTLIENC_LIBS=\"{$lib->getStaticLibFiles()}\"", ]) ) ->appendEnv(['PKG_CONFIG' => '$PKG_CONFIG --static']) diff --git a/src/SPC/builder/unix/library/xz.php b/src/SPC/builder/unix/library/xz.php index f127e59a..98f33bea 100644 --- a/src/SPC/builder/unix/library/xz.php +++ b/src/SPC/builder/unix/library/xz.php @@ -21,6 +21,7 @@ trait xz '--disable-scripts', '--disable-doc', '--with-libiconv', + '--bindir=/tmp/xz', // xz binary will corrupt `tar` command, that's really strange. ) ->make(); $this->patchPkgconfPrefix(['liblzma.pc']); diff --git a/src/SPC/util/SPCConfigUtil.php b/src/SPC/util/SPCConfigUtil.php index bb808a7c..0d165231 100644 --- a/src/SPC/util/SPCConfigUtil.php +++ b/src/SPC/util/SPCConfigUtil.php @@ -6,6 +6,7 @@ namespace SPC\util; use SPC\builder\BuilderBase; use SPC\builder\BuilderProvider; +use SPC\builder\macos\MacOSBuilder; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; @@ -78,13 +79,14 @@ class SPCConfigUtil $libs .= ' ' . trim($extra_env, '"'); } $extra_env = getenv('SPC_EXTRA_LIBS'); - if (is_string($extra_env)) { + if (is_string($extra_env) && !empty($extra_env)) { $libs .= " {$extra_env}"; } // extension frameworks if (SPCTarget::getTargetOS() === 'Darwin') { $libs .= " {$this->getFrameworksString($extensions)}"; } + $libs .= $this->builder instanceof MacOSBuilder ? ' -lc++' : ' -lstdc++'; if ($this->libs_only_deps) { return [ @@ -94,10 +96,9 @@ class SPCConfigUtil ]; } - $libs = trim("-lc {$libs}"); // embed if (!$this->no_php) { - $libs = "-lphp {$libs}"; + $libs = "-lphp -lc {$libs}"; } // mimalloc must come first if (str_contains($libs, BUILD_LIB_PATH . '/mimalloc.o')) {