From 694fd2f1e051ecdaf2a6c0712999d335b294f058 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 14:33:39 +0700 Subject: [PATCH] turn pkg-config into a package instead of a library --- config/lib.json | 12 +-- config/pkg.json | 12 +++ config/source.json | 9 -- src/SPC/builder/freebsd/BSDBuilder.php | 3 +- src/SPC/builder/freebsd/library/pkgconfig.php | 15 --- src/SPC/builder/linux/library/pkgconfig.php | 15 --- src/SPC/builder/macos/library/pkgconfig.php | 15 --- src/SPC/builder/unix/library/pkgconfig.php | 31 ------ src/SPC/doctor/item/PkgConfigCheck.php | 45 +++++++++ src/SPC/store/pkg/PkgConfig.php | 96 +++++++++++++++++++ src/SPC/toolchain/ToolchainManager.php | 6 ++ src/SPC/util/GlobalEnvManager.php | 5 +- src/SPC/util/executor/UnixCMakeExecutor.php | 4 +- 13 files changed, 168 insertions(+), 100 deletions(-) delete mode 100644 src/SPC/builder/freebsd/library/pkgconfig.php delete mode 100644 src/SPC/builder/linux/library/pkgconfig.php delete mode 100644 src/SPC/builder/macos/library/pkgconfig.php delete mode 100644 src/SPC/builder/unix/library/pkgconfig.php create mode 100644 src/SPC/doctor/item/PkgConfigCheck.php create mode 100644 src/SPC/store/pkg/PkgConfig.php diff --git a/config/lib.json b/config/lib.json index 1c366743..ead0ecc6 100644 --- a/config/lib.json +++ b/config/lib.json @@ -1,9 +1,6 @@ { "lib-base": { - "type": "root", - "lib-depends-unix": [ - "pkg-config" - ] + "type": "root" }, "php": { "type": "root", @@ -26,13 +23,6 @@ "type": "target", "source": "micro" }, - "pkg-config": { - "type": "package", - "source": "pkg-config", - "bin-unix": [ - "pkg-config" - ] - }, "attr": { "source": "attr", "static-libs-unix": [ diff --git a/config/pkg.json b/config/pkg.json index 080958b4..ce4d6546 100644 --- a/config/pkg.json +++ b/config/pkg.json @@ -69,5 +69,17 @@ }, "zig-x86_64-win": { "type": "custom" + }, + "pkg-config-x86_64-linux": { + "type": "custom" + }, + "pkg-config-aarch64-linux": { + "type": "custom" + }, + "pkg-config-x86_64-macos": { + "type": "custom" + }, + "pkg-config-aarch64-macos": { + "type": "custom" } } diff --git a/config/source.json b/config/source.json index 79e4b153..9ab020a3 100644 --- a/config/source.json +++ b/config/source.json @@ -868,15 +868,6 @@ "path": "LICENSE" } }, - "pkg-config": { - "type": "url", - "url": "https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz", - "provide-pre-built": true, - "license": { - "type": "file", - "path": "COPYING" - } - }, "postgresql": { "type": "ghtagtar", "repo": "postgres/postgres", diff --git a/src/SPC/builder/freebsd/BSDBuilder.php b/src/SPC/builder/freebsd/BSDBuilder.php index dcaa5a2d..09f31c9a 100644 --- a/src/SPC/builder/freebsd/BSDBuilder.php +++ b/src/SPC/builder/freebsd/BSDBuilder.php @@ -7,6 +7,7 @@ namespace SPC\builder\freebsd; use SPC\builder\unix\UnixBuilderBase; use SPC\exception\WrongUsageException; use SPC\store\FileSystem; +use SPC\store\pkg\PkgConfig; use SPC\store\SourcePatcher; class BSDBuilder extends UnixBuilderBase @@ -26,7 +27,7 @@ class BSDBuilder extends UnixBuilderBase // set PATH f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH')); // set PKG_CONFIG - f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config'); + f_putenv('PKG_CONFIG=' . PkgConfig::getEnvironment()['PATH'] . '/bin/pkg-config'); // set PKG_CONFIG_PATH f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig/'); diff --git a/src/SPC/builder/freebsd/library/pkgconfig.php b/src/SPC/builder/freebsd/library/pkgconfig.php deleted file mode 100644 index 62bd8ace..00000000 --- a/src/SPC/builder/freebsd/library/pkgconfig.php +++ /dev/null @@ -1,15 +0,0 @@ -appendEnv([ - 'CFLAGS' => '-Wimplicit-function-declaration -Wno-int-conversion', - 'LDFLAGS' => SPCTarget::isStatic() ? '--static' : '', - ]) - ->configure( - '--with-internal-glib', - '--disable-host-tool', - '--without-sysroot', - '--without-system-include-path', - '--without-system-library-path', - '--without-pc-path', - ) - ->make(with_install: 'install-exec'); - - shell()->exec('strip ' . BUILD_ROOT_PATH . '/bin/pkg-config'); - } -} diff --git a/src/SPC/doctor/item/PkgConfigCheck.php b/src/SPC/doctor/item/PkgConfigCheck.php new file mode 100644 index 00000000..8ca1c83e --- /dev/null +++ b/src/SPC/doctor/item/PkgConfigCheck.php @@ -0,0 +1,45 @@ + 'win', + 'Darwin' => 'macos', + 'BSD' => 'freebsd', + default => 'linux', + }; + PackageManager::installPackage("pkg-config-{$arch}-{$os}"); + return PkgConfig::isInstalled(); + } +} diff --git a/src/SPC/store/pkg/PkgConfig.php b/src/SPC/store/pkg/PkgConfig.php new file mode 100644 index 00000000..72058021 --- /dev/null +++ b/src/SPC/store/pkg/PkgConfig.php @@ -0,0 +1,96 @@ + 'macos', + default => 'linux', + }; + $name = "pkg-config-{$arch}-{$os}"; + return is_file(PKG_ROOT_PATH . "/{$name}/bin/pkg-config"); + } + + public function getSupportName(): array + { + return [ + 'pkg-config-x86_64-linux', + 'pkg-config-aarch64-linux', + 'pkg-config-x86_64-macos', + 'pkg-config-aarch64-macos', + ]; + } + + public function fetch(string $name, bool $force = false, ?array $config = null): void + { + $pkgroot = PKG_ROOT_PATH; + $bin = "{$pkgroot}/{$name}/bin/pkg-config"; + if ($force) { + FileSystem::removeDir("{$pkgroot}/{$name}"); + } + if (file_exists($bin)) { + return; + } + // Use known stable pkg-config source tarball (same as config/source.json) + $pkg = [ + 'type' => 'url', + 'url' => 'https://dl.static-php.dev/static-php-cli/deps/pkg-config/pkg-config-0.29.2.tar.gz', + 'filename' => 'pkg-config-0.29.2.tar.gz', + ]; + Downloader::downloadPackage($name, $pkg, $force); + } + + public function extract(string $name): void + { + $pkgroot = PKG_ROOT_PATH; + $prefix = "{$pkgroot}/{$name}"; + $bin = "{$prefix}/bin/pkg-config"; + if (file_exists($bin)) { + return; + } + $lock = json_decode(FileSystem::readFile(LockFile::LOCK_FILE), true); + $source_type = $lock[$name]['source_type']; + $filename = DOWNLOAD_PATH . '/' . ($lock[$name]['filename'] ?? $lock[$name]['dirname']); + $srcdir = "{$pkgroot}/{$name}/src"; + FileSystem::extractPackage($name, $source_type, $filename, $srcdir); + + // build from source into package prefix + $env = [ + 'CFLAGS' => getenv('SPC_DEFAULT_C_FLAGS') ?: '-Os', + 'LDFLAGS' => (SPCTarget::isStatic() ? '--static' : ''), + 'PKG_CONFIG' => 'pkg-config', + 'PKG_CONFIG_PATH' => BUILD_ROOT_PATH . '/lib/pkgconfig', + ]; + $shell = shell()->appendEnv($env)->cd($srcdir); + $shell->exec("./configure --prefix='{$prefix}' --with-internal-glib --disable-host-tool --without-sysroot --without-system-include-path --without-system-library-path --without-pc-path"); + $shell->exec('make -j' . (getenv('SPC_CONCURRENCY') ?: '1')); + $shell->exec('make install-exec'); + if (is_file($bin)) { + @shell()->exec('strip ' . $bin); + } + } + + public static function getEnvironment(): array + { + $arch = arch2gnu(php_uname('m')); + $os = match (PHP_OS_FAMILY) { + 'Darwin' => 'macos', + default => 'linux', + }; + $name = "pkg-config-{$arch}-{$os}"; + return [ + 'PATH' => PKG_ROOT_PATH . "/{$name}/bin", + ]; + } +} diff --git a/src/SPC/toolchain/ToolchainManager.php b/src/SPC/toolchain/ToolchainManager.php index 3fe48ae1..819bdb64 100644 --- a/src/SPC/toolchain/ToolchainManager.php +++ b/src/SPC/toolchain/ToolchainManager.php @@ -5,7 +5,9 @@ declare(strict_types=1); namespace SPC\toolchain; use SPC\builder\linux\SystemUtil; +use SPC\exception\EnvironmentException; use SPC\exception\WrongUsageException; +use SPC\store\pkg\PkgConfig; use SPC\util\GlobalEnvManager; use SPC\util\SPCTarget; @@ -56,6 +58,10 @@ class ToolchainManager if (SPCTarget::getLibc() === 'glibc' && SystemUtil::isMuslDist()) { throw new WrongUsageException('You are linking against glibc dynamically, which is only supported on glibc distros.'); } + if (!is_dir(PkgConfig::getEnvironment()['PATH'])) { + throw new EnvironmentException('Please install pkg-config first. (You can use `doctor` command to install it)'); + } + GlobalEnvManager::addPathIfNotExists(PkgConfig::getEnvironment()['PATH']); $toolchain = getenv('SPC_TOOLCHAIN'); /* @var ToolchainInterface $toolchain */ $instance = new $toolchain(); diff --git a/src/SPC/util/GlobalEnvManager.php b/src/SPC/util/GlobalEnvManager.php index 59e4d06c..c979ca2c 100644 --- a/src/SPC/util/GlobalEnvManager.php +++ b/src/SPC/util/GlobalEnvManager.php @@ -7,6 +7,7 @@ namespace SPC\util; use SPC\builder\macos\SystemUtil; use SPC\exception\SPCInternalException; use SPC\exception\WrongUsageException; +use SPC\store\pkg\PkgConfig; use SPC\toolchain\ToolchainManager; /** @@ -39,8 +40,8 @@ class GlobalEnvManager // Define env vars for unix if (is_unix()) { self::addPathIfNotExists(BUILD_BIN_PATH); - self::putenv('PKG_CONFIG=' . BUILD_BIN_PATH . '/pkg-config'); - self::putenv('PKG_CONFIG_PATH=' . BUILD_ROOT_PATH . '/lib/pkgconfig'); + self::putenv('PKG_CONFIG=' . PkgConfig::getEnvironment()['PATH'] . '/pkg-config'); + self::putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig'); } $ini = self::readIniFile(); diff --git a/src/SPC/util/executor/UnixCMakeExecutor.php b/src/SPC/util/executor/UnixCMakeExecutor.php index 6bd70677..abcfe392 100644 --- a/src/SPC/util/executor/UnixCMakeExecutor.php +++ b/src/SPC/util/executor/UnixCMakeExecutor.php @@ -8,6 +8,7 @@ use SPC\builder\freebsd\library\BSDLibraryBase; use SPC\builder\linux\library\LinuxLibraryBase; use SPC\builder\macos\library\MacOSLibraryBase; use SPC\store\FileSystem; +use SPC\store\pkg\PkgConfig; use SPC\util\shell\UnixShell; /** @@ -184,6 +185,7 @@ class UnixCMakeExecutor extends Executor $cxx = getenv('CCX'); logger()->debug("making cmake tool chain file for {$os} {$target_arch} with CFLAGS='{$cflags}'"); $root = BUILD_ROOT_PATH; + $pkgConfig = PkgConfig::getEnvironment()['PATH']; $ccLine = ''; if ($cc) { $ccLine = 'SET(CMAKE_C_COMPILER ' . $cc . ')'; @@ -202,7 +204,7 @@ SET(CMAKE_PREFIX_PATH "{$root}") SET(CMAKE_INSTALL_PREFIX "{$root}") SET(CMAKE_INSTALL_LIBDIR "lib") -set(PKG_CONFIG_EXECUTABLE "{$root}/bin/pkg-config") +set(PKG_CONFIG_EXECUTABLE "{$pkgConfig}/pkg-config") list(APPEND PKG_CONFIG_EXECUTABLE "--static") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)