mirror of
https://github.com/crazywhalecc/static-php-cli.git
synced 2026-07-10 10:25:36 +08:00
use resolved dependency tree instead of asking for with_suggests everywhere
This commit is contained in:
@@ -20,7 +20,7 @@ class pgsql extends PhpExtensionPackage
|
|||||||
public function getUnixConfigureArg(bool $shared, PackageBuilder $builder, PackageInstaller $installer): string
|
public function getUnixConfigureArg(bool $shared, PackageBuilder $builder, PackageInstaller $installer): string
|
||||||
{
|
{
|
||||||
if (php::getPHPVersionID() >= 80400) {
|
if (php::getPHPVersionID() >= 80400) {
|
||||||
$libfiles = new SPCConfigUtil(['libs_only_deps' => true, 'absolute_libs' => true])->getPackageDepsConfig('postgresql', array_keys($installer->getResolvedPackages()), $builder->getOption('with-suggests'))['libs'];
|
$libfiles = new SPCConfigUtil(['libs_only_deps' => true, 'absolute_libs' => true])->getPackageDepsConfig('postgresql', array_keys($installer->getResolvedPackages()))['libs'];
|
||||||
$libfiles = str_replace("{$builder->getLibDir()}/lib", '-l', $libfiles);
|
$libfiles = str_replace("{$builder->getLibDir()}/lib", '-l', $libfiles);
|
||||||
$libfiles = str_replace('.a', '', $libfiles);
|
$libfiles = str_replace('.a', '', $libfiles);
|
||||||
return '--with-pgsql' . ($shared ? '=shared' : '') .
|
return '--with-pgsql' . ($shared ? '=shared' : '') .
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class krb5
|
|||||||
|
|
||||||
$resolved = array_keys($installer->getResolvedPackages());
|
$resolved = array_keys($installer->getResolvedPackages());
|
||||||
$spc = new SPCConfigUtil(['no_php' => true, 'libs_only_deps' => true]);
|
$spc = new SPCConfigUtil(['no_php' => true, 'libs_only_deps' => true]);
|
||||||
$config = $spc->getPackageDepsConfig($lib->getName(), $resolved, include_suggests: true);
|
$config = $spc->getPackageDepsConfig($lib->getName(), $resolved);
|
||||||
$extraEnv = [
|
$extraEnv = [
|
||||||
'CFLAGS' => '-fcommon',
|
'CFLAGS' => '-fcommon',
|
||||||
'LIBS' => $config['libs'],
|
'LIBS' => $config['libs'],
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ class postgresql extends LibraryPackage
|
|||||||
public function buildUnix(PackageInstaller $installer, PackageBuilder $builder): void
|
public function buildUnix(PackageInstaller $installer, PackageBuilder $builder): void
|
||||||
{
|
{
|
||||||
$spc_config = new SPCConfigUtil(['no_php' => true, 'libs_only_deps' => true]);
|
$spc_config = new SPCConfigUtil(['no_php' => true, 'libs_only_deps' => true]);
|
||||||
$config = $spc_config->getPackageDepsConfig('postgresql', array_keys($installer->getResolvedPackages()), include_suggests: $builder->getOption('with-suggests', false));
|
$config = $spc_config->getPackageDepsConfig('postgresql', array_keys($installer->getResolvedPackages()));
|
||||||
|
|
||||||
$env_vars = [
|
$env_vars = [
|
||||||
'CFLAGS' => $config['cflags'] . ' -std=c17',
|
'CFLAGS' => $config['cflags'] . ' -std=c17',
|
||||||
|
|||||||
@@ -274,8 +274,7 @@ class PhpExtensionPackage extends Package
|
|||||||
$compiler_extra = trim($compiler_extra . ' -lcompiler_rt');
|
$compiler_extra = trim($compiler_extra . ' -lcompiler_rt');
|
||||||
GlobalEnvManager::putenv("SPC_COMPILER_EXTRA={$compiler_extra}");
|
GlobalEnvManager::putenv("SPC_COMPILER_EXTRA={$compiler_extra}");
|
||||||
}
|
}
|
||||||
// include_suggests so transitive optional libs (e.g. librdkafka → lz4/zstd/ssl) are in the link line
|
$config = (new SPCConfigUtil())->getExtensionConfig($this);
|
||||||
$config = (new SPCConfigUtil())->getExtensionConfig($this, include_suggests: true);
|
|
||||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||||
$preStatic = PHP_OS_FAMILY === 'Darwin' ? '' : '-Wl,--start-group ';
|
$preStatic = PHP_OS_FAMILY === 'Darwin' ? '' : '-Wl,--start-group ';
|
||||||
$postStatic = PHP_OS_FAMILY === 'Darwin' ? '' : ' -Wl,--end-group ';
|
$postStatic = PHP_OS_FAMILY === 'Darwin' ? '' : ' -Wl,--end-group ';
|
||||||
@@ -336,8 +335,7 @@ class PhpExtensionPackage extends Package
|
|||||||
|
|
||||||
public function patchSharedLibAdd(): void
|
public function patchSharedLibAdd(): void
|
||||||
{
|
{
|
||||||
// include_suggests so transitive optional libs (e.g. librdkafka → lz4/zstd/ssl) are in the link line
|
$config = (new SPCConfigUtil())->getExtensionConfig($this);
|
||||||
$config = (new SPCConfigUtil())->getExtensionConfig($this, include_suggests: true);
|
|
||||||
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
[$staticLibs, $sharedLibs] = $this->splitLibsIntoStaticAndShared($config['libs']);
|
||||||
$lstdcpp = str_contains($sharedLibs, '-l:libstdc++.a')
|
$lstdcpp = str_contains($sharedLibs, '-l:libstdc++.a')
|
||||||
? '-l:libstdc++.a'
|
? '-l:libstdc++.a'
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ class PackageLoader
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach ($conditionals as $class) {
|
foreach ($conditionals as $class) {
|
||||||
if (!ApplicationContext::has($class)) {
|
if (ApplicationContext::tryGet($class) === null) {
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,7 +394,7 @@ class PackageLoader
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach ($conditionals as $class) {
|
foreach ($conditionals as $class) {
|
||||||
if (!ApplicationContext::has($class)) {
|
if (ApplicationContext::tryGet($class) === null) {
|
||||||
continue 2;
|
continue 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ declare(strict_types=1);
|
|||||||
namespace StaticPHP\Util;
|
namespace StaticPHP\Util;
|
||||||
|
|
||||||
use StaticPHP\Config\PackageConfig;
|
use StaticPHP\Config\PackageConfig;
|
||||||
|
use StaticPHP\DI\ApplicationContext;
|
||||||
use StaticPHP\Exception\WrongUsageException;
|
use StaticPHP\Exception\WrongUsageException;
|
||||||
use StaticPHP\Package\LibraryPackage;
|
use StaticPHP\Package\LibraryPackage;
|
||||||
|
use StaticPHP\Package\PackageInstaller;
|
||||||
use StaticPHP\Package\PhpExtensionPackage;
|
use StaticPHP\Package\PhpExtensionPackage;
|
||||||
use StaticPHP\Runtime\SystemTarget;
|
use StaticPHP\Runtime\SystemTarget;
|
||||||
|
|
||||||
@@ -118,6 +120,10 @@ class SPCConfigUtil
|
|||||||
* [Helper function]
|
* [Helper function]
|
||||||
* Get configuration for a specific extension(s) dependencies.
|
* Get configuration for a specific extension(s) dependencies.
|
||||||
*
|
*
|
||||||
|
* Uses the installer's resolved package set as the source of truth — only libraries that
|
||||||
|
* are actually enabled in this build appear in the result. The resolved set already
|
||||||
|
* reflects the user's `--with-suggests` choice.
|
||||||
|
*
|
||||||
* @param array|PhpExtensionPackage $extension_packages Extension instance or list
|
* @param array|PhpExtensionPackage $extension_packages Extension instance or list
|
||||||
* @return array{
|
* @return array{
|
||||||
* cflags: string,
|
* cflags: string,
|
||||||
@@ -125,30 +131,30 @@ class SPCConfigUtil
|
|||||||
* libs: string
|
* libs: string
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
public function getExtensionConfig(array|PhpExtensionPackage $extension_packages, bool $include_suggests = false): array
|
public function getExtensionConfig(array|PhpExtensionPackage $extension_packages): array
|
||||||
{
|
{
|
||||||
if (!is_array($extension_packages)) {
|
if (!is_array($extension_packages)) {
|
||||||
$extension_packages = [$extension_packages];
|
$extension_packages = [$extension_packages];
|
||||||
}
|
}
|
||||||
return $this->config(
|
$names = array_map(fn ($y) => $y->getName(), $extension_packages);
|
||||||
packages: array_map(fn ($y) => $y->getName(), $extension_packages),
|
return $this->configWithResolvedPackages($this->collectEnabledLinkPackages($names));
|
||||||
include_suggests: $include_suggests,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Helper function]
|
* [Helper function]
|
||||||
* Get configuration for a specific library(s) dependencies.
|
* Get configuration for a specific library(s) dependencies.
|
||||||
*
|
*
|
||||||
* @param array|LibraryPackage $lib Library instance or list
|
* Like {@see getExtensionConfig()}, draws from the resolved package set so we never
|
||||||
* @param bool $include_suggests Whether to include suggested libraries
|
* link against a library that wasn't built.
|
||||||
|
*
|
||||||
|
* @param array|LibraryPackage $lib Library instance or list
|
||||||
* @return array{
|
* @return array{
|
||||||
* cflags: string,
|
* cflags: string,
|
||||||
* ldflags: string,
|
* ldflags: string,
|
||||||
* libs: string
|
* libs: string
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
public function getLibraryConfig(array|LibraryPackage $lib, bool $include_suggests = false): array
|
public function getLibraryConfig(array|LibraryPackage $lib): array
|
||||||
{
|
{
|
||||||
if (!is_array($lib)) {
|
if (!is_array($lib)) {
|
||||||
$lib = [$lib];
|
$lib = [$lib];
|
||||||
@@ -157,35 +163,31 @@ class SPCConfigUtil
|
|||||||
$this->no_php = true;
|
$this->no_php = true;
|
||||||
$save_libs_only_deps = $this->libs_only_deps;
|
$save_libs_only_deps = $this->libs_only_deps;
|
||||||
$this->libs_only_deps = true;
|
$this->libs_only_deps = true;
|
||||||
$ret = $this->config(
|
$names = array_map(fn ($y) => $y->getName(), $lib);
|
||||||
packages: array_map(fn ($y) => $y->getName(), $lib),
|
$ret = $this->configWithResolvedPackages($this->collectEnabledLinkPackages($names));
|
||||||
include_suggests: $include_suggests,
|
|
||||||
);
|
|
||||||
$this->no_php = $save_no_php;
|
$this->no_php = $save_no_php;
|
||||||
$this->libs_only_deps = $save_libs_only_deps;
|
$this->libs_only_deps = $save_libs_only_deps;
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get build configuration for a package and its sub-dependencies within a resolved set.
|
* Get build configuration for a package's sub-dependencies within a resolved set.
|
||||||
*
|
*
|
||||||
* This is useful when you need to statically link something against a specific
|
* Walks both depends and suggests edges — the resolved set is the filter, so anything
|
||||||
* library and all its transitive dependencies. It properly handles optional
|
* reachable but unbuilt is naturally excluded. No `include_suggests` knob is needed.
|
||||||
* dependencies by only including those that were actually resolved.
|
|
||||||
*
|
*
|
||||||
* @param string $package_name The package to get config for
|
* @param string $package_name The package to get config for
|
||||||
* @param string[] $resolved_packages The full resolved package list
|
* @param string[] $resolved_packages The full resolved package list
|
||||||
* @param bool $include_suggests Whether to include resolved suggests
|
|
||||||
* @return array{
|
* @return array{
|
||||||
* cflags: string,
|
* cflags: string,
|
||||||
* ldflags: string,
|
* ldflags: string,
|
||||||
* libs: string
|
* libs: string
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
public function getPackageDepsConfig(string $package_name, array $resolved_packages, bool $include_suggests = false): array
|
public function getPackageDepsConfig(string $package_name, array $resolved_packages): array
|
||||||
{
|
{
|
||||||
// Get sub-dependencies within the resolved set
|
// Get sub-dependencies within the resolved set
|
||||||
$sub_deps = DependencyResolver::getSubDependencies($package_name, $resolved_packages, $include_suggests);
|
$sub_deps = DependencyResolver::getSubDependencies($package_name, $resolved_packages, include_suggests: true);
|
||||||
|
|
||||||
if (empty($sub_deps)) {
|
if (empty($sub_deps)) {
|
||||||
return [
|
return [
|
||||||
@@ -299,6 +301,24 @@ class SPCConfigUtil
|
|||||||
return implode(' ', $list);
|
return implode(' ', $list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For each input package name, gather its transitive deps within the installer's resolved
|
||||||
|
* set (walking depends + suggests edges), plus the package itself, deduped and in build order.
|
||||||
|
*
|
||||||
|
* @param string[] $package_names Input package names
|
||||||
|
* @return string[] Resolved packages to link against
|
||||||
|
*/
|
||||||
|
private function collectEnabledLinkPackages(array $package_names): array
|
||||||
|
{
|
||||||
|
$resolved = array_keys(ApplicationContext::get(PackageInstaller::class)->getResolvedPackages());
|
||||||
|
$out = [];
|
||||||
|
foreach ($package_names as $name) {
|
||||||
|
$sub = DependencyResolver::getSubDependencies($name, $resolved, include_suggests: true);
|
||||||
|
$out = [...$out, ...$sub, $name];
|
||||||
|
}
|
||||||
|
return array_values(array_unique($out));
|
||||||
|
}
|
||||||
|
|
||||||
private function hasCpp(array $packages): bool
|
private function hasCpp(array $packages): bool
|
||||||
{
|
{
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
|
|||||||
Reference in New Issue
Block a user