From 694fd2f1e051ecdaf2a6c0712999d335b294f058 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 14:33:39 +0700 Subject: [PATCH 01/10] 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) From 2551772de46abdec8515f6aa0a881d6caee643f6 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 16:34:29 +0700 Subject: [PATCH 02/10] use system cc --- src/SPC/store/pkg/PkgConfig.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SPC/store/pkg/PkgConfig.php b/src/SPC/store/pkg/PkgConfig.php index 72058021..4272218a 100644 --- a/src/SPC/store/pkg/PkgConfig.php +++ b/src/SPC/store/pkg/PkgConfig.php @@ -73,9 +73,9 @@ class PkgConfig extends CustomPackage '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'); + $shell->exec("CC=cc ./configure --prefix='{$prefix}' --with-internal-glib --disable-host-tool --without-sysroot --without-system-include-path --without-system-library-path --without-pc-path"); + $shell->exec('CC=cc make -j' . (getenv('SPC_CONCURRENCY') ?: '1')); + $shell->exec('CC=cc make install-exec'); if (is_file($bin)) { @shell()->exec('strip ' . $bin); } From a66abfa583c04e5454855c7e45c41df1b1d2cfe0 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 16:35:24 +0700 Subject: [PATCH 03/10] test all OS --- src/globals/test-extensions.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index d311962d..f49d3185 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -18,16 +18,16 @@ $test_php_version = [ // '8.3', '8.4', // '8.5', - 'git', + // 'git', ]; // test os (macos-13, macos-14, macos-15, ubuntu-latest, windows-latest are available) $test_os = [ - // 'macos-13', // bin/spc for x86_64 + 'macos-13', // bin/spc for x86_64 // 'macos-14', // bin/spc for arm64 - // 'macos-15', // bin/spc for arm64 + 'macos-15', // bin/spc for arm64 'ubuntu-latest', // bin/spc-alpine-docker for x86_64 - // 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 + 'ubuntu-22.04', // bin/spc-gnu-docker for x86_64 'ubuntu-24.04', // bin/spc for x86_64 'ubuntu-22.04-arm', // bin/spc-gnu-docker for arm64 'ubuntu-24.04-arm', // bin/spc for arm64 @@ -50,7 +50,7 @@ $prefer_pre_built = false; // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pdo,pdo_mysql,pdo_sqlite,phar,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip', + 'Linux', 'Darwin' => 'gd', 'Windows' => 'bcmath,bz2,calendar,ctype,curl,dom,exif,fileinfo,filter,ftp,iconv,xml,mbstring,mbregex,mysqlnd,openssl,pdo,pdo_mysql,pdo_sqlite,phar,session,simplexml,soap,sockets,sqlite3,tokenizer,xmlwriter,xmlreader,zlib,zip', }; From d32bdb2825d2c849966e9ffe6995dfc88bef2392 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 16:45:47 +0700 Subject: [PATCH 04/10] all env vars --- src/SPC/store/pkg/PkgConfig.php | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/SPC/store/pkg/PkgConfig.php b/src/SPC/store/pkg/PkgConfig.php index 4272218a..2821d68a 100644 --- a/src/SPC/store/pkg/PkgConfig.php +++ b/src/SPC/store/pkg/PkgConfig.php @@ -67,15 +67,29 @@ class PkgConfig extends CustomPackage // build from source into package prefix $env = [ - 'CFLAGS' => getenv('SPC_DEFAULT_C_FLAGS') ?: '-Os', + 'CFLAGS' => getenv('SPC_DEFAULT_C_FLAGS') ?: '-Os -Wno-int-conversion', 'LDFLAGS' => (SPCTarget::isStatic() ? '--static' : ''), 'PKG_CONFIG' => 'pkg-config', 'PKG_CONFIG_PATH' => BUILD_ROOT_PATH . '/lib/pkgconfig', ]; - $shell = shell()->appendEnv($env)->cd($srcdir); - $shell->exec("CC=cc ./configure --prefix='{$prefix}' --with-internal-glib --disable-host-tool --without-sysroot --without-system-include-path --without-system-library-path --without-pc-path"); - $shell->exec('CC=cc make -j' . (getenv('SPC_CONCURRENCY') ?: '1')); - $shell->exec('CC=cc make install-exec'); + $shell = shell() + ->setEnv([ + 'CC' => 'cc', + 'CXX' => 'c++', + 'AR' => 'ar', + 'LD' => 'ld', + ]) + ->appendEnv($env)->cd($srcdir); + $shell->exec( + '--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); } From c7141003dbfb986696749d09262c17003eb7e02c Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 16:46:09 +0700 Subject: [PATCH 05/10] oops --- src/SPC/store/pkg/PkgConfig.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SPC/store/pkg/PkgConfig.php b/src/SPC/store/pkg/PkgConfig.php index 2821d68a..eb8690c3 100644 --- a/src/SPC/store/pkg/PkgConfig.php +++ b/src/SPC/store/pkg/PkgConfig.php @@ -81,6 +81,7 @@ class PkgConfig extends CustomPackage ]) ->appendEnv($env)->cd($srcdir); $shell->exec( + "./configure --prefix='{$prefix}' " . '--with-internal-glib '. '--disable-host-tool '. '--without-sysroot '. From 6f0310e8f7a8b609d748ce003e4e3b1ebb1a6ec9 Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 16:46:58 +0700 Subject: [PATCH 06/10] cs fix --- src/SPC/store/pkg/PkgConfig.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SPC/store/pkg/PkgConfig.php b/src/SPC/store/pkg/PkgConfig.php index eb8690c3..6935a8fc 100644 --- a/src/SPC/store/pkg/PkgConfig.php +++ b/src/SPC/store/pkg/PkgConfig.php @@ -82,11 +82,11 @@ class PkgConfig extends CustomPackage ->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 '. + '--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')); From f2c131a2cc3685867d19e3f7bba8781ece80673d Mon Sep 17 00:00:00 2001 From: DubbleClick Date: Wed, 27 Aug 2025 17:01:07 +0700 Subject: [PATCH 07/10] wno-int-conversion --- src/SPC/store/pkg/PkgConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SPC/store/pkg/PkgConfig.php b/src/SPC/store/pkg/PkgConfig.php index 6935a8fc..cc5d3dcd 100644 --- a/src/SPC/store/pkg/PkgConfig.php +++ b/src/SPC/store/pkg/PkgConfig.php @@ -67,7 +67,7 @@ class PkgConfig extends CustomPackage // build from source into package prefix $env = [ - 'CFLAGS' => getenv('SPC_DEFAULT_C_FLAGS') ?: '-Os -Wno-int-conversion', + 'CFLAGS' => '-Wno-int-conversion ' . (getenv('SPC_DEFAULT_C_FLAGS') ?: '-Os'), 'LDFLAGS' => (SPCTarget::isStatic() ? '--static' : ''), 'PKG_CONFIG' => 'pkg-config', 'PKG_CONFIG_PATH' => BUILD_ROOT_PATH . '/lib/pkgconfig', From 0fa38bad6d85de6b86a0b2a00aedb3f8c68079de Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 31 Aug 2025 15:04:34 +0800 Subject: [PATCH 08/10] Use existing pkg-config builds and pre-built contents for packages --- config/lib.json | 7 ++ config/pkg.json | 28 ++++- config/source.json | 9 ++ src/SPC/builder/freebsd/BSDBuilder.php | 5 - 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 | 21 ++-- src/SPC/store/pkg/PkgConfig.php | 111 ------------------ src/SPC/toolchain/ToolchainManager.php | 6 - src/SPC/util/GlobalEnvManager.php | 11 +- src/SPC/util/PkgConfigUtil.php | 22 ++++ src/SPC/util/executor/UnixCMakeExecutor.php | 6 +- 14 files changed, 157 insertions(+), 145 deletions(-) create mode 100644 src/SPC/builder/freebsd/library/pkgconfig.php create mode 100644 src/SPC/builder/linux/library/pkgconfig.php create mode 100644 src/SPC/builder/macos/library/pkgconfig.php create mode 100644 src/SPC/builder/unix/library/pkgconfig.php delete mode 100644 src/SPC/store/pkg/PkgConfig.php diff --git a/config/lib.json b/config/lib.json index ead0ecc6..6d414b9f 100644 --- a/config/lib.json +++ b/config/lib.json @@ -19,6 +19,13 @@ "watcher" ] }, + "pkg-config": { + "type": "package", + "source": "pkg-config", + "bin-unix": [ + "pkg-config" + ] + }, "micro": { "type": "target", "source": "micro" diff --git a/config/pkg.json b/config/pkg.json index ce4d6546..942b1dbd 100644 --- a/config/pkg.json +++ b/config/pkg.json @@ -71,15 +71,35 @@ "type": "custom" }, "pkg-config-x86_64-linux": { - "type": "custom" + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-x86_64-linux-musl-1.2.5.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } }, "pkg-config-aarch64-linux": { - "type": "custom" + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-aarch64-linux-musl-1.2.5.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } }, "pkg-config-x86_64-macos": { - "type": "custom" + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-x86_64-darwin.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } }, "pkg-config-aarch64-macos": { - "type": "custom" + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-aarch64-darwin.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } } } diff --git a/config/source.json b/config/source.json index 9ab020a3..565d95fd 100644 --- a/config/source.json +++ b/config/source.json @@ -7,6 +7,15 @@ }, "alt": false }, + "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" + } + }, "amqp": { "type": "url", "url": "https://pecl.php.net/get/amqp", diff --git a/src/SPC/builder/freebsd/BSDBuilder.php b/src/SPC/builder/freebsd/BSDBuilder.php index 09f31c9a..985de5d2 100644 --- a/src/SPC/builder/freebsd/BSDBuilder.php +++ b/src/SPC/builder/freebsd/BSDBuilder.php @@ -7,7 +7,6 @@ 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,10 +25,6 @@ class BSDBuilder extends UnixBuilderBase f_putenv('CXX=' . $this->getOption('cxx', 'clang++')); // set PATH f_putenv('PATH=' . BUILD_ROOT_PATH . '/bin:' . getenv('PATH')); - // set 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/'); // set arch (default: current) $this->setOptionIfNotExist('arch', php_uname('m')); diff --git a/src/SPC/builder/freebsd/library/pkgconfig.php b/src/SPC/builder/freebsd/library/pkgconfig.php new file mode 100644 index 00000000..62bd8ace --- /dev/null +++ b/src/SPC/builder/freebsd/library/pkgconfig.php @@ -0,0 +1,15 @@ +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 index 8ca1c83e..0936a606 100644 --- a/src/SPC/doctor/item/PkgConfigCheck.php +++ b/src/SPC/doctor/item/PkgConfigCheck.php @@ -9,7 +9,7 @@ use SPC\doctor\AsFixItem; use SPC\doctor\CheckResult; use SPC\doctor\OptionalCheck; use SPC\store\PackageManager; -use SPC\store\pkg\PkgConfig; +use SPC\util\PkgConfigUtil; #[OptionalCheck([self::class, 'optionalCheck'])] class PkgConfigCheck @@ -20,26 +20,19 @@ class PkgConfigCheck } /** @noinspection PhpUnused */ - #[AsCheckItem('if pkg-config is installed', level: 800)] + #[AsCheckItem('if pkg-config is installed or built', level: 800)] public function checkPkgConfig(): CheckResult { - if (PkgConfig::isInstalled()) { - return CheckResult::ok(); + if (!($pkgconf = PkgConfigUtil::findPkgConfig())) { + return CheckResult::fail('pkg-config is not installed', 'install-pkgconfig'); } - return CheckResult::fail('pkg-config is not installed', 'install-pkgconfig'); + return CheckResult::ok($pkgconf); } #[AsFixItem('install-pkgconfig')] public function installPkgConfig(): bool { - $arch = arch2gnu(php_uname('m')); - $os = match (PHP_OS_FAMILY) { - 'Windows' => 'win', - 'Darwin' => 'macos', - 'BSD' => 'freebsd', - default => 'linux', - }; - PackageManager::installPackage("pkg-config-{$arch}-{$os}"); - return PkgConfig::isInstalled(); + PackageManager::installPackage('pkg-config'); + return true; } } diff --git a/src/SPC/store/pkg/PkgConfig.php b/src/SPC/store/pkg/PkgConfig.php deleted file mode 100644 index cc5d3dcd..00000000 --- a/src/SPC/store/pkg/PkgConfig.php +++ /dev/null @@ -1,111 +0,0 @@ - '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' => '-Wno-int-conversion ' . (getenv('SPC_DEFAULT_C_FLAGS') ?: '-Os'), - 'LDFLAGS' => (SPCTarget::isStatic() ? '--static' : ''), - 'PKG_CONFIG' => 'pkg-config', - 'PKG_CONFIG_PATH' => BUILD_ROOT_PATH . '/lib/pkgconfig', - ]; - $shell = shell() - ->setEnv([ - 'CC' => 'cc', - 'CXX' => 'c++', - 'AR' => 'ar', - 'LD' => 'ld', - ]) - ->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 819bdb64..3fe48ae1 100644 --- a/src/SPC/toolchain/ToolchainManager.php +++ b/src/SPC/toolchain/ToolchainManager.php @@ -5,9 +5,7 @@ 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; @@ -58,10 +56,6 @@ 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 c979ca2c..f3af8971 100644 --- a/src/SPC/util/GlobalEnvManager.php +++ b/src/SPC/util/GlobalEnvManager.php @@ -7,7 +7,6 @@ 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; /** @@ -40,7 +39,7 @@ class GlobalEnvManager // Define env vars for unix if (is_unix()) { self::addPathIfNotExists(BUILD_BIN_PATH); - self::putenv('PKG_CONFIG=' . PkgConfig::getEnvironment()['PATH'] . '/pkg-config'); + self::addPathIfNotExists(PKG_ROOT_PATH . '/bin'); self::putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig'); } @@ -123,6 +122,14 @@ class GlobalEnvManager self::putenv("YACC={$yacc}"); } } + + // init pkg-config for unix + if (is_unix()) { + if (($found = PkgConfigUtil::findPkgConfig()) === null) { + throw new WrongUsageException('Cannot find pkg-config executable. Please run `doctor` to fix this.'); + } + self::putenv("PKG_CONFIG={$found}"); + } } private static function readIniFile(): array diff --git a/src/SPC/util/PkgConfigUtil.php b/src/SPC/util/PkgConfigUtil.php index 41a3b6e2..25e0e1f2 100644 --- a/src/SPC/util/PkgConfigUtil.php +++ b/src/SPC/util/PkgConfigUtil.php @@ -14,6 +14,28 @@ use SPC\exception\ExecutionException; */ class PkgConfigUtil { + /** + * Find the pkg-config executable which is compatible with static builds. + * + * @return null|string Path to pkg-config executable, or null if not found + */ + public static function findPkgConfig(): ?string + { + // Find pkg-config executable + $find_list = [ + PKG_ROOT_PATH . '/bin/pkg-config', + BUILD_BIN_PATH . '/pkg-config', + ]; + $found = null; + foreach ($find_list as $file) { + if (file_exists($file) && is_executable($file)) { + $found = $file; + break; + } + } + return $found; + } + /** * Returns the version of a module. * This method uses `pkg-config --modversion` to get the version of the specified module. diff --git a/src/SPC/util/executor/UnixCMakeExecutor.php b/src/SPC/util/executor/UnixCMakeExecutor.php index abcfe392..3e29addf 100644 --- a/src/SPC/util/executor/UnixCMakeExecutor.php +++ b/src/SPC/util/executor/UnixCMakeExecutor.php @@ -8,7 +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\PkgConfigUtil; use SPC\util\shell\UnixShell; /** @@ -185,7 +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']; + $pkgConfigExecutable = PkgConfigUtil::findPkgConfig(); $ccLine = ''; if ($cc) { $ccLine = 'SET(CMAKE_C_COMPILER ' . $cc . ')'; @@ -204,7 +204,7 @@ SET(CMAKE_PREFIX_PATH "{$root}") SET(CMAKE_INSTALL_PREFIX "{$root}") SET(CMAKE_INSTALL_LIBDIR "lib") -set(PKG_CONFIG_EXECUTABLE "{$pkgConfig}/pkg-config") +set(PKG_CONFIG_EXECUTABLE "{$pkgConfigExecutable}") list(APPEND PKG_CONFIG_EXECUTABLE "--static") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) From 86973e622d23e9ab8194721754186881b88e6d32 Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 31 Aug 2025 15:06:59 +0800 Subject: [PATCH 09/10] sort config --- config/lib.json | 8 ++-- config/pkg.json | 98 +++++++++++++++++++++++----------------------- config/source.json | 18 ++++----- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/config/lib.json b/config/lib.json index 6d414b9f..81e7ef3c 100644 --- a/config/lib.json +++ b/config/lib.json @@ -19,6 +19,10 @@ "watcher" ] }, + "micro": { + "type": "target", + "source": "micro" + }, "pkg-config": { "type": "package", "source": "pkg-config", @@ -26,10 +30,6 @@ "pkg-config" ] }, - "micro": { - "type": "target", - "source": "micro" - }, "attr": { "source": "attr", "static-libs-unix": [ diff --git a/config/pkg.json b/config/pkg.json index 942b1dbd..00e83595 100644 --- a/config/pkg.json +++ b/config/pkg.json @@ -1,4 +1,16 @@ { + "go-xcaddy-aarch64-linux": { + "type": "custom" + }, + "go-xcaddy-aarch64-macos": { + "type": "custom" + }, + "go-xcaddy-x86_64-linux": { + "type": "custom" + }, + "go-xcaddy-x86_64-macos": { + "type": "custom" + }, "musl-toolchain-aarch64-linux": { "type": "url", "url": "https://dl.static-php.dev/static-php-cli/deps/musl-toolchain/aarch64-musl-toolchain.tgz" @@ -15,6 +27,38 @@ "nasm-2.16.01/ndisasm.exe": "{php_sdk_path}/bin/ndisasm.exe" } }, + "pkg-config-aarch64-linux": { + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-aarch64-linux-musl-1.2.5.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } + }, + "pkg-config-aarch64-macos": { + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-aarch64-darwin.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } + }, + "pkg-config-x86_64-linux": { + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-x86_64-linux-musl-1.2.5.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } + }, + "pkg-config-x86_64-macos": { + "type": "ghrel", + "repo": "static-php/static-php-cli-hosted", + "match": "pkg-config-x86_64-darwin.txz", + "extract-files": { + "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" + } + }, "strawberry-perl-x86_64-win": { "type": "url", "url": "https://github.com/StrawberryPerl/Perl-Dist-Strawberry/releases/download/SP_5380_5361/strawberry-perl-5.38.0.1-64bit-portable.zip" @@ -43,63 +87,19 @@ "upx-*-win64/upx.exe": "{pkg_root_path}/bin/upx.exe" } }, - "go-xcaddy-x86_64-linux": { - "type": "custom" - }, - "go-xcaddy-aarch64-linux": { - "type": "custom" - }, - "go-xcaddy-x86_64-macos": { - "type": "custom" - }, - "go-xcaddy-aarch64-macos": { - "type": "custom" - }, - "zig-x86_64-linux": { - "type": "custom" - }, "zig-aarch64-linux": { "type": "custom" }, - "zig-x86_64-macos": { - "type": "custom" - }, "zig-aarch64-macos": { "type": "custom" }, - "zig-x86_64-win": { + "zig-x86_64-linux": { "type": "custom" }, - "pkg-config-x86_64-linux": { - "type": "ghrel", - "repo": "static-php/static-php-cli-hosted", - "match": "pkg-config-x86_64-linux-musl-1.2.5.txz", - "extract-files": { - "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" - } + "zig-x86_64-macos": { + "type": "custom" }, - "pkg-config-aarch64-linux": { - "type": "ghrel", - "repo": "static-php/static-php-cli-hosted", - "match": "pkg-config-aarch64-linux-musl-1.2.5.txz", - "extract-files": { - "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" - } - }, - "pkg-config-x86_64-macos": { - "type": "ghrel", - "repo": "static-php/static-php-cli-hosted", - "match": "pkg-config-x86_64-darwin.txz", - "extract-files": { - "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" - } - }, - "pkg-config-aarch64-macos": { - "type": "ghrel", - "repo": "static-php/static-php-cli-hosted", - "match": "pkg-config-aarch64-darwin.txz", - "extract-files": { - "bin/pkg-config": "{pkg_root_path}/bin/pkg-config" - } + "zig-x86_64-win": { + "type": "custom" } } diff --git a/config/source.json b/config/source.json index 565d95fd..79e4b153 100644 --- a/config/source.json +++ b/config/source.json @@ -7,15 +7,6 @@ }, "alt": false }, - "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" - } - }, "amqp": { "type": "url", "url": "https://pecl.php.net/get/amqp", @@ -877,6 +868,15 @@ "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", From 3b9efcb2d4821738781dffd61c09c6772a483d3a Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Sun, 31 Aug 2025 15:24:29 +0800 Subject: [PATCH 10/10] Put it into toolchain manager to skip in unit test --- src/SPC/toolchain/ToolchainManager.php | 10 ++++++++++ src/SPC/util/GlobalEnvManager.php | 8 -------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/SPC/toolchain/ToolchainManager.php b/src/SPC/toolchain/ToolchainManager.php index 3fe48ae1..ff22acae 100644 --- a/src/SPC/toolchain/ToolchainManager.php +++ b/src/SPC/toolchain/ToolchainManager.php @@ -7,6 +7,7 @@ namespace SPC\toolchain; use SPC\builder\linux\SystemUtil; use SPC\exception\WrongUsageException; use SPC\util\GlobalEnvManager; +use SPC\util\PkgConfigUtil; use SPC\util\SPCTarget; class ToolchainManager @@ -56,6 +57,15 @@ class ToolchainManager if (SPCTarget::getLibc() === 'glibc' && SystemUtil::isMuslDist()) { throw new WrongUsageException('You are linking against glibc dynamically, which is only supported on glibc distros.'); } + + // init pkg-config for unix + if (is_unix()) { + if (($found = PkgConfigUtil::findPkgConfig()) === null) { + throw new WrongUsageException('Cannot find pkg-config executable. Please run `doctor` to fix this.'); + } + GlobalEnvManager::putenv("PKG_CONFIG={$found}"); + } + $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 f3af8971..9f74d2df 100644 --- a/src/SPC/util/GlobalEnvManager.php +++ b/src/SPC/util/GlobalEnvManager.php @@ -122,14 +122,6 @@ class GlobalEnvManager self::putenv("YACC={$yacc}"); } } - - // init pkg-config for unix - if (is_unix()) { - if (($found = PkgConfigUtil::findPkgConfig()) === null) { - throw new WrongUsageException('Cannot find pkg-config executable. Please run `doctor` to fix this.'); - } - self::putenv("PKG_CONFIG={$found}"); - } } private static function readIniFile(): array